Skip to content

Codex/pr69584 split#70474

Open
mmy4shadow wants to merge 20 commits intoopenclaw:mainfrom
mmy4shadow:codex/pr69584-split
Open

Codex/pr69584 split#70474
mmy4shadow wants to merge 20 commits intoopenclaw:mainfrom
mmy4shadow:codex/pr69584-split

Conversation

@mmy4shadow
Copy link
Copy Markdown

@mmy4shadow mmy4shadow commented Apr 23, 2026

Summary

  • This PR is the reviewable split extracted from original #69584.
  • It keeps the setup / provider-auth / channel-status slice that can land independently, instead of asking reviewers to wade through the full mixed original PR.
  • It fixes two real regressions that showed up during review: TUI hatch now restores terminal state on failure, and the setup wizard keeps TUI launch local when the Gateway is not actually reachable.
  • It also keeps the channel-status improvements from the original slice, while tightening the implementation so summary-only status requests do not re-run isConfigured work unnecessarily.
  • Scope boundary: this PR does not carry the loopback bootstrap-auth / Control UI bootstrap token work from original #69585; that review surface is tracked separately in #70477.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Skills / tool execution
  • Auth / tokens
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause (if applicable)

  • Root cause: original #69584 mixed multiple unrelated fixes, and one setup refactor dropped the try/finally terminal restore while also forcing the hatch TUI down the Gateway path even when the Gateway probe was not healthy.
  • Missing detection / guardrail: there was no focused test covering “failed TUI hatch restores terminal state” and no test asserting that setup keeps local hatch mode when the Gateway is unavailable.
  • Contributing context (if known): the same split also introduced channel-status summary optimization work, so setup and status changes were reviewed together even though they carry different failure modes.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
    • Unit test
    • Seam / integration test
    • End-to-end test
    • Existing coverage already sufficient
  • Target test or file:
    • src/wizard/setup.finalize.test.ts
    • src/gateway/server-methods/channels.status.test.ts
    • ui/src/ui/controllers/channels.node.test.ts
  • Scenario the test should lock in:
    • TUI hatch restores terminal state even if launch fails.
    • Setup hatch stays local when Gateway health is not available.
    • channels.status summary-only requests reuse the same configuration check instead of calling isConfigured twice.
  • Why this is the smallest reliable guardrail:
    • These tests hit the exact wizard and gateway seams that regressed without needing a full install or live Gateway run.
  • Existing test that already covers this (if any): prior wizard tests covered the happy path only.
  • If no new test is added, why not: N/A

User-visible / Behavior Changes

  • “Hatch in Terminal” no longer leaves the terminal in a broken state if TUI launch fails.
  • When setup is run without a healthy Gateway (for example --install-daemon=false or a failed startup), terminal hatch stays in embedded local mode instead of launching a disconnected Gateway-mode TUI.
  • channels.status can still return lightweight overview payloads without accounts, and stale configured default account ids fall back to the first live account.

Diagram (if applicable)

Before:
setup chooses TUI -> always launches Gateway-mode hatch -> Gateway unavailable => disconnected TUI
setup chooses TUI -> TUI crash -> terminal restore may be skipped

After:
setup chooses TUI + Gateway unavailable -> local hatch -> usable terminal session
setup chooses TUI -> TUI crash -> finally restore terminal state -> shell recovers

Security Impact (required)

  • New permissions/capabilities? (Yes/No): No
  • Secrets/tokens handling changed? (Yes/No): No
  • New/changed network calls? (Yes/No): No
  • Command/tool execution surface changed? (Yes/No): No
  • Data access scope changed? (Yes/No): No
  • If any Yes, explain risk + mitigation:

Repro + Verification

Environment

  • OS: Windows 11 (local verification)
  • Runtime/container: Node 24 / pnpm workspace
  • Model/provider: N/A
  • Integration/channel (if any): setup wizard + gateway channel status
  • Relevant config (redacted): loopback Gateway setup in test fixtures

Steps

  1. Reproduce review findings against codex/pr69584-split.
  2. Restore the wizard try/finally terminal cleanup and gate terminal hatch mode on actual Gateway reachability.
  3. Re-run typecheck, targeted tests, and lint.

Expected

  • Wizard hatch restores terminal state on failure.
  • Wizard hatch remains local when Gateway is unavailable.
  • Channel status summary path stays correct and avoids duplicate config checks.

Actual

  • Verified locally after the fixes.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)

Commands run locally:

  • pnpm tsgo:prod
  • pnpm check:test-types
  • pnpm test src/wizard/setup.finalize.test.ts src/gateway/server-methods/channels.status.test.ts ui/src/ui/controllers/channels.node.test.ts
  • pnpm lint

Human Verification (required)

  • Verified scenarios:
    • wizard TUI failure cleanup path
    • wizard local hatch fallback when Gateway probe is unhealthy
    • channel summary-only status path and stale default-account fallback
  • Edge cases checked:
    • summary-only probe+audit path only computes isConfigured once
    • local hatch assertions confirm no Gateway URL/token/password are passed when Gateway is unavailable
  • What you did not verify:
    • full interactive setup run against a real failing TUI subprocess outside the test harness

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? (Yes/No): Yes
  • Config/env changes? (Yes/No): No
  • Migration needed? (Yes/No): No
  • If yes, exact upgrade steps:

Risks and Mitigations

  • Risk: this PR still spans several independent fixes because it is a split from original #69584, not a greenfield branch.
    • Mitigation: the description narrows the intended review surface, and the new commits isolate wizard safety from channel-status cleanup.
  • Risk: local hatch fallback relies on Gateway probe health to choose mode.
    • Mitigation: explicit tests now cover the unhealthy-Gateway path and the terminal-restore failure path.

@openclaw-barnacle openclaw-barnacle Bot added channel: msteams Channel integration: msteams app: macos App: macos app: web-ui App: web-ui gateway Gateway runtime commands Command implementations extensions: minimax size: XL labels Apr 23, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Apr 23, 2026

Greptile Summary

This PR splits out several related fixes from PR #69584: it makes openUrl return a boolean signal (falling back to manual OAuth entry when the browser can't be opened), adds an includeAccounts fast-path to channels.status to speed up the overview load, fixes stale default account ID fallback in the channel status handler, moves gateway credentials out of TUI CLI args into one-shot environment variables, gates systemd linger checks on installDaemon, and adds a quickstart-specific surface to plugin-config discovery.

  • P1 — terminal not restored on TUI failure: the try/finally block that called restoreTerminalState(\"post-setup tui\", …) was removed from setup.finalize.ts; if launchTuiCli rejects the terminal can be left in raw/broken state and the test that guarded this path was deleted rather than updated.

Confidence Score: 4/5

Safe to merge after resolving the terminal-state restoration regression in setup.finalize.ts.

One P1 finding: the removal of the finally-block terminal restore in the TUI hatch path leaves users with a potentially broken terminal when TUI exits abnormally. All other changes are well-tested with clear intent. The rest of the findings are P2 style/efficiency suggestions.

src/wizard/setup.finalize.ts — TUI launch block is missing the post-launch restoreTerminalState call in a finally block.

Comments Outside Diff (1)

  1. src/gateway/server-methods/channels.ts, line 431-495 (link)

    P2 isConfigured called twice unnecessarily in buildChannelSummaryOnly

    When a channel plugin has both probeAccount and auditAccount, plugin.config.isConfigured(account, cfg) is awaited twice independently. If isConfigured has side effects or is expensive (e.g., a network call), this doubles the work. Consider computing it once and reusing the result before both blocks.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/gateway/server-methods/channels.ts
    Line: 431-495
    
    Comment:
    **`isConfigured` called twice unnecessarily in `buildChannelSummaryOnly`**
    
    When a channel plugin has both `probeAccount` and `auditAccount`, `plugin.config.isConfigured(account, cfg)` is awaited twice independently. If `isConfigured` has side effects or is expensive (e.g., a network call), this doubles the work. Consider computing it once and reusing the result before both blocks.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/wizard/setup.finalize.ts
Line: 406-416

Comment:
**Terminal state not restored on TUI failure**

The `try/finally` block that called `restoreTerminalState("post-setup tui", ...)` was removed. If `launchTuiCli` rejects (e.g., TUI exits with a non-zero code), the terminal may be left in raw mode with invisible cursor or no echo, because the child process can modify terminal state before crashing. The test that verified this recovery path ("restores terminal state after failed TUI hatch") was also removed rather than updated, meaning this regression won't be caught in CI.

Wrap the call in `try/finally` and restore terminal state in the `finally` block, mirroring the old pattern.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/gateway/server-methods/channels.ts
Line: 431-495

Comment:
**`isConfigured` called twice unnecessarily in `buildChannelSummaryOnly`**

When a channel plugin has both `probeAccount` and `auditAccount`, `plugin.config.isConfigured(account, cfg)` is awaited twice independently. If `isConfigured` has side effects or is expensive (e.g., a network call), this doubles the work. Consider computing it once and reusing the result before both blocks.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: ui/src/ui/controllers/channels.ts
Line: 65

Comment:
**Private bookkeeping fields on public state object via type casting**

`ChannelsPrivateState` extends `ChannelsState` and attaches `__channelsRequestSeq`, `__channelsInFlight`, and `__channelsPending` directly to the shared state object through `state as ChannelsPrivateState`. This can silently collide with fields added to `ChannelsState` later and makes the private invariants invisible to TypeScript consumers of `ChannelsState`. Consider a module-level `WeakMap<ChannelsState, ChannelsPrivateFields>` to keep these fully encapsulated.

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "Gateway: sync Swift channel status param..." | Re-trigger Greptile

Comment thread src/wizard/setup.finalize.ts Outdated
Comment thread ui/src/ui/controllers/channels.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 48d9e9d132

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/wizard/setup.finalize.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1b63316198

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +173 to +177
pending &&
privateState.requestSeq === seq &&
!privateState.inFlight &&
state.connected &&
state.client
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Clear queued channel refreshes after disconnect

When a stronger request is queued during an in-flight load, this branch only executes it if state.connected is still true; otherwise the stale privateState.pending value is left behind. After reconnect, a later unrelated loadChannels call can unexpectedly replay that old stronger request (for example probe:true with full accounts), adding unnecessary heavy work and potentially replacing UI state/error messages that the caller did not request. Clearing pending when it cannot be dispatched avoids this deferred stale replay.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: dcd1dc8b71

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

url: links.wsUrl,
...probeAuth,
});
if (!gatewayProbe.ok && installDaemon) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Guard missing-gateway guidance on failed probes

The else branch here is paired with if (!gatewayProbe.ok && installDaemon), so it also executes when gatewayProbe.ok is true. In successful setup runs this emits the "Gateway not detected yet" guidance even though the gateway is reachable, which is misleading in both daemon and no-daemon flows; this guidance should only run when the probe actually fails.

Useful? React with 👍 / 👎.

Comment on lines +347 to +351
const defaultAccount = await buildChannelAccountSnapshot({
plugin,
cfg,
accountId: defaultAccountId,
runtime: runtimeSnapshot,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid re-running account configuration checks in summary mode

In the summary-only channels.status path, resolveAccountConfigured(...) is already called before probe/audit, but this subsequent buildChannelAccountSnapshot(...) call can invoke plugin.config.isConfigured again for accounts without an inline configured property (see src/channels/plugins/status.ts). For probe: true + includeAccounts: false, this introduces duplicate isConfigured work and extra latency/side effects on the new lightweight path.

Useful? React with 👍 / 👎.

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 29, 2026

Codex review: needs changes before merge.

What this changes:

The PR changes setup/TUI launch behavior, provider OAuth browser-open handling, Gateway channels.status summary payloads, Control UI channel refresh loading, quickstart plugin-config prompting, Windows scheduled-task parsing, generated Swift protocol models, and related tests.

Required change before merge:

The remaining blockers are narrow, file-local repairs on an open, maintainer-modifiable PR branch plus a mechanical changelog addition; they are suitable for a ClawSweeper repair pass rather than broad product review.

Security review:

Security review cleared: The diff touches OAuth and gateway-token handoff paths, but I found no concrete security or supply-chain regression in the public PR diff.

Review findings:

  • [P2] Clear pending channel refreshes after disconnect — ui/src/ui/controllers/channels.ts:171-180
  • [P2] Gate missing-gateway guidance on failed probes — src/wizard/setup.finalize.ts:295-305
  • [P2] Reuse the configured result in summary snapshots — src/gateway/server-methods/channels.ts:347-354
Review details

Best possible solution:

Keep the useful split, but fix the three remaining behavior regressions, add the required changelog entry, rebase on current main, and then rerun the targeted setup, channel-status, UI controller, typecheck, and lint lanes before merge.

Do we have a high-confidence way to reproduce the issue?

Yes. The remaining review issues are reproducible by deterministic code paths: run setup with a successful gateway probe, queue a stronger channel load and disconnect before finally, and use a channel plugin whose isConfigured is observable in summary-only probe mode.

Is this the best way to solve the issue?

No. The overall direction is maintainable, but the proposed branch is not the best final solution until it preserves the single-configuration-check guarantee, avoids stale UI pending state, guards the gateway note correctly, and records the user-facing changes in the changelog.

Full review comments:

  • [P2] Clear pending channel refreshes after disconnect — ui/src/ui/controllers/channels.ts:171-180
    When a stronger request is queued during an in-flight load, this finally block only clears pending if the state is still connected with a client. If the UI disconnects first, the stale stronger request can replay after reconnect during an unrelated load, causing avoidable heavy status work and unexpected state replacement.
    Confidence: 0.87
  • [P2] Gate missing-gateway guidance on failed probes — src/wizard/setup.finalize.ts:295-305
    This else is paired with if (!gatewayProbe.ok && installDaemon), so it also runs when the probe succeeds. Successful setup runs can therefore show Gateway not detected yet even though the Gateway is reachable; only show this note for the failed-probe/no-daemon case.
    Confidence: 0.9
  • [P2] Reuse the configured result in summary snapshots — src/gateway/server-methods/channels.ts:347-354
    The summary-only path computes configured before probe/audit, but then calls buildChannelAccountSnapshot, whose default implementation can call plugin.config.isConfigured again for accounts without a configured field. That breaks the new lightweight status path's single configuration-check guarantee.
    Confidence: 0.8
  • [P2] Add the required changelog entry — src/wizard/setup.ts:614-620
    This PR changes user-facing setup, OAuth, channel status, and Control UI behavior and is marked as both bug fix and feature work, but the diff has no CHANGELOG.md update. Repo policy requires a user-facing fix/feat change to include an active changelog entry with contributor credit before merge.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.88

Acceptance criteria:

  • pnpm test src/wizard/setup.finalize.test.ts src/gateway/server-methods/channels.status.test.ts ui/src/ui/controllers/channels.node.test.ts
  • pnpm test src/daemon/schtasks.test.ts src/plugins/provider-openai-codex-oauth.test.ts src/wizard/setup.plugin-config.test.ts src/wizard/setup.test.ts ui/src/ui/app-settings.overview.node.test.ts ui/src/ui/app-settings.test.ts
  • pnpm tsgo:prod
  • pnpm check:test-types
  • pnpm lint

What I checked:

  • Current main lacks the new channel-status parameter: On current main, ChannelsStatusParamsSchema accepts probe and timeoutMs only; the PR's includeAccounts contract is branch-only work, not already implemented on main. (src/gateway/protocol/schema/channels.ts:230, 068b33de8717)
  • Current main keeps setup TUI local and restores terminal state: Main already has the narrow terminal cleanup/local TUI behavior: setup launches launchTuiCli({ local: true }) inside a try/finally with pre/post restoreTerminalState, so that subset alone is not enough to close the PR as implemented. (src/wizard/setup.finalize.ts:454, 068b33de8717)
  • PR head still shows missing-gateway guidance on successful probes: The PR head has an else paired only with if (!gatewayProbe.ok && installDaemon), so the 'Gateway not detected yet' note is also reachable when gatewayProbe.ok is true. (src/wizard/setup.finalize.ts:295, dcd1dc8b71a7)
  • PR head still re-enters snapshot configuration checks: The PR computes configured before probe/audit, then calls buildChannelAccountSnapshot; the current helper can call plugin.config.isConfigured again when the account does not carry an inline configured field. (src/gateway/server-methods/channels.ts:347, dcd1dc8b71a7)
  • PR head leaves queued refresh state behind on disconnect: The pending queued channel request is cleared only inside the connected/client branch, so disconnecting before finally finishes leaves privateState.pending available for a later unrelated load. (ui/src/ui/controllers/channels.ts:171, dcd1dc8b71a7)
  • Prior review comments identify the same remaining blockers: The PR discussion includes review comments for clearing queued channel refreshes, guarding missing-gateway guidance, and avoiding duplicate summary configuration checks; the latest raw PR head still matches those code paths. (dcd1dc8b71a7)

Likely related people:

  • steipete: Recent main history shows broad maintenance across the gateway channel-status path, onboarding health checks, provider OAuth prompts, and Windows task handling touched by this PR. (role: recent maintainer; confidence: high; commits: 526372ea36e3, 7f3f108521f4, 2d575bc00e90; files: src/gateway/server-methods/channels.ts, src/wizard/setup.finalize.ts, src/plugins/provider-oauth-flow.ts)
  • BunsDev: Recent Control UI/channel controller commits updated channel state synchronization and operator-read handling, adjacent to the PR's loadChannels request coalescing changes. (role: adjacent UI owner; confidence: medium; commits: 245451b6a9c5, 3e2b3bd2c572; files: ui/src/ui/controllers/channels.ts, ui/src/ui/app-settings.ts)
  • fuller-stack-dev: The local embedded TUI and setup hatch local-mode behavior appears to come from the merged local TUI work, which is directly affected by the PR's setup hatch changes. (role: introduced behavior; confidence: medium; commits: 276c00015c83; files: src/wizard/setup.finalize.ts, src/tui/tui-launch.ts, src/tui/gateway-chat.ts)
  • shakkernerd: The setup TUI hatch terminal handoff and gateway-auth relaunch behavior was recently changed in this area, making this a relevant routing candidate for the setup/TUI slice. (role: introduced adjacent behavior; confidence: medium; commits: aae4b1b29dd7; files: src/wizard/setup.finalize.ts, src/tui/tui-launch.ts)
  • Takhoffman: The channel-status state path was recently updated for auto-enable behavior in the same gateway status surface that the PR extends with summary-only responses. (role: adjacent owner; confidence: medium; commits: 0bcf07690137; files: src/gateway/server-methods/channels.ts)

Remaining risk / open question:

  • The PR is XL and based on an older base SHA, so even after the discrete findings are fixed it still needs a rebase and touched-surface validation against current main.
  • This review was read-only; I did not run the PR test matrix, so the assessment is based on source, public PR diff/API data, docs, and local main inspection.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 068b33de8717.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

app: macos App: macos app: web-ui App: web-ui channel: msteams Channel integration: msteams commands Command implementations extensions: minimax gateway Gateway runtime size: XL

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants