Skip to content

TUI: restore hook-visible /new resets#49945

Closed
caopulan wants to merge 2 commits into
openclaw:mainfrom
caopulan:caopulan/tui-new-hooks
Closed

TUI: restore hook-visible /new resets#49945
caopulan wants to merge 2 commits into
openclaw:mainfrom
caopulan:caopulan/tui-new-hooks

Conversation

@caopulan
Copy link
Copy Markdown

Summary

Describe the problem and fix in 2–5 bullets:

  • Problem: #49918 reported that TUI /new stopped emitting hook-visible command:new behavior after the per-client session isolation change.
  • Why it matters: hook-driven flows like command-logger and session-memory silently stop running for TUI /new, even though users still expect a normal fresh-session reset.
  • What changed: /new now resets the newly allocated per-client tui-<uuid> session through sessions.reset(reason="new") before switching the TUI to that unique key, and the command-handler test now locks that route in.
  • What did NOT change (scope boundary): /reset behavior stays in-place on the current session, and TUI session isolation still uses unique per-client keys.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor
  • 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

User-visible / Behavior Changes

TUI /new once again emits the same hook-visible reset path as other reset flows, while still creating an isolated tui-<uuid> session for the current TUI client.

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: macOS
  • Runtime/container: Node 22 + pnpm + Vitest
  • Model/provider: N/A
  • Integration/channel (if any): TUI command handling + gateway session reset hooks
  • Relevant config (redacted): test harness defaults

Steps

  1. Register a hook that listens for command:new.
  2. Open openclaw tui and run /new.
  3. Observe whether the fresh-session path goes through sessions.reset(reason="new") or only switches local session state.

Expected

  • /new keeps the isolated tui-<uuid> behavior and still emits the standard hook-visible command:new reset path.

Actual

  • Before this patch, /new only called local setSession(uniqueKey) and skipped the gateway reset path entirely.

Evidence

Attach at least one:

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

Verification commands run locally:

  • pnpm test -- src/tui/tui-command-handlers.test.ts
  • pnpm test -- src/gateway/server.sessions.gateway-server-sessions-a.test.ts -t 'sessions.reset emits internal command hook with reason'
  • pnpm exec oxfmt --check src/tui/tui-command-handlers.ts src/tui/tui-command-handlers.test.ts
  • pnpm exec oxlint src/tui/tui-command-handlers.ts src/tui/tui-command-handlers.test.ts

Human Verification (required)

What you personally verified (not just CI), and how:

  • Verified scenarios: /new now routes through gateway reset with reason new, /reset still resets the shared current session, and existing gateway coverage still confirms that sessions.reset(reason="new") emits the internal command hook.
  • Edge cases checked: canonical agent:main:tui-<uuid> session key generation for /new and preserved /reset behavior.
  • What you did not verify: a live interactive TUI session with a real installed hook script.

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.

If a bot review conversation is addressed by this PR, resolve that conversation yourself. Do not leave bot review conversation cleanup for maintainers.

Compatibility / Migration

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

Failure Recovery (if this breaks)

  • How to disable/revert this change quickly: revert commit 37d84d03f8
  • Files/config to restore: src/tui/tui-command-handlers.ts, src/tui/tui-command-handlers.test.ts, CHANGELOG.md
  • Known bad symptoms reviewers should watch for: /new no longer emitting hook-visible resets, or TUI /new falling back to the shared main session instead of a unique tui-<uuid> key

Risks and Mitigations

List only real risks for this PR. Add/remove entries as needed. If none, write None.

  • Risk: /new could accidentally stop isolating the TUI client if the canonical unique key routing regresses.
    • Mitigation: the command-handler test asserts both the unique tui-<uuid> session handoff and the gateway reset call shape.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 18, 2026

Greptile Summary

This PR restores hook-visible command:new behavior for TUI /new by calling client.resetSession(nextSessionKey, "new") on the newly generated tui-<uuid> session key before handing the client off to that session via setSession. The per-client isolation introduced in #39217 is preserved — /new still generates a unique tui-<uuid> key — and /reset is unchanged.

Key changes:

  • src/tui/tui-command-handlers.ts: Builds the full canonical key (agent:<agentId>:tui-<uuid>) and calls client.resetSession with it before calling setSession, ensuring gateway hooks observe the reset. Display message now uses formatSessionKey on the full key for cleaner output.
  • src/tui/tui-command-handlers.test.ts: Tightens the mock type (ResetSessionMock), updates the combined /new+/reset test to assert both the gateway reset call shape and the setSession call shape, and renames the test to better describe the new invariant.
  • CHANGELOG.md: Entry added under the bug-fix section with issue reference.

Confidence Score: 5/5

  • Safe to merge — minimal, well-tested bug fix with no behavioral regressions.
  • The change is small and tightly scoped: one new await call inserted before an existing await, with matching test assertions that lock in both the gateway-reset key shape and the session-switch key. The double-normalization of state.currentAgentId via normalizeAgentId is safe because the function is idempotent. The partial-failure path (reset succeeds, setSession fails) leaves the user with a clear error and a retry option, identical in UX to the previous single-failure path. Existing sanitization and isolation tests continue to pass with the new ordering.
  • No files require special attention.

Last reviewed commit: "TUI: restore /new ho..."

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: 37d84d03f8

ℹ️ 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/tui/tui-command-handlers.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: b62dde6f7a

ℹ️ 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 278 to +281
target.canonicalKey ?? params.key,
{
sessionEntry: entry,
previousSessionEntry: entry,
sessionEntry: hookSourceEntry,
previousSessionEntry: hookSourceEntry,
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 logging /new hooks under the fresh tui-* key

In the TUI /new flow, hookSourceKey now makes previousSessionEntry point at the session being left, but the emitted hook still uses sessionKey=target.canonicalKey. Bundled hooks such as src/hooks/bundled/command-logger/handler.ts:52-59 and src/hooks/bundled/session-memory/handler.ts:221-235 treat event.sessionKey as the conversation being archived, so installs with those hooks enabled will now record the old transcript under the brand-new tui-* key instead of the session that actually ended.

Useful? React with 👍 / 👎.

// to other connected TUI clients sharing the original session key.
const uniqueKey = `tui-${randomUUID()}`;
const nextSessionKey = `agent:${normalizeAgentId(state.currentAgentId)}:${uniqueKey}`;
await client.resetSession(nextSessionKey, "new", state.currentSessionKey);
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 Skip creating a persisted session row before the user sends anything

Calling sessions.reset on a brand-new tui-* key means /new now writes a fresh SessionEntry immediately, even though no message was ever sent on that session. performGatewaySessionReset always persists a new entry for the requested key, and src/gateway/session-utils.ts:868-976 lists every store row, so repeatedly pressing /new will leave behind blank tui-* sessions that clutter the session picker/history. Before this change, /new only switched the local key and did not persist an empty session.

Useful? React with 👍 / 👎.

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 28, 2026

Thanks for the context here. I swept through the related work, and this is now duplicate or superseded.

Keep this PR open but not merge-ready: it targets a real TUI hook regression, but the current branch exposes a risky reset hook-source contract, can misattribute old-session hook output to a new tui-* key, lacks real TUI hook proof, and is currently conflicting.

Canonical path: Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

So I’m closing this here because the remaining work is already tracked in the canonical issue.

Review details

Best possible solution:

Close this stale PR. The latest review rated it F, the branch still lacks merge-ready proof, and there has been no human follow-up after the durable review.

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

Yes. Source inspection gives a high-confidence reproduction path: current TUI /new only switches local session state, while docs and gateway reset code show command:new hooks are emitted through the reset path.

Is this the best way to solve the issue?

No. The PR targets the right regression, but resetting the future tui-* key plus public hookSourceKey is not the safest fix; the hook should be attributed to the session being left before the TUI switches sessions.

Security review:

Security review needs attention: No dependency or workflow supply-chain issue was found, but the diff broadens session-context selection in a public gateway RPC.

  • [medium] Public reset RPC can select a different hook source — src/gateway/protocol/schema/sessions.ts:248
    hookSourceKey allows a reset caller to target one session while loading another session entry into hook context, which can expose or archive the wrong transcript through enabled hooks unless the field is removed or tightly validated.
    Confidence: 0.84

What I checked:

  • stale F-rated PR: PR was opened 2026-03-18T17:43:40Z, is older than 60 days, and the latest review rated it F.
  • proof blocker: real behavior proof is mock_only and proof tier is F, so this branch is not merge-ready without contributor follow-up.
  • no human follow-up: live comments and timeline hydrated by apply contain no non-automation activity after the ClawSweeper review.

Likely related people:

  • steipete: Commit 46008178d1bab4a9cbb8ea270468b0f370cec370 landed the TUI /new per-client isolation path that removed the previous reset-hook route. (role: introduced isolation behavior and recent area contributor; confidence: high; commits: 46008178d1ba; files: src/tui/tui-command-handlers.ts, src/tui/tui-command-handlers.test.ts)
  • widingmarcus-cyber: GitHub PR metadata for fix(tui): isolate /new sessions to prevent cross-client broadcast #39238 shows this contributor proposed the isolated TUI /new behavior later landed in 46008178d1ba. (role: source behavior contributor; confidence: medium; commits: 46008178d1ba; files: src/tui/tui-command-handlers.ts, src/tui/tui-command-handlers.test.ts)
  • Vignesh Natarajan: Commit b08146fad6e4221ad15d62e9690b243b4f7d9d77 added TUI/Gateway internal hook emission for /new and /reset, which is the contract this PR tries to restore. (role: original hook behavior contributor; confidence: high; commits: b08146fad6e4; files: src/tui/tui-command-handlers.ts, src/tui/gateway-chat.ts, src/gateway/server-methods/sessions.ts)
  • Val Alexander: Commit 49c4a13231a3076226ecbd2e5069a029cdcc9e34 restored Control UI /new hooks with the parent-session pattern that is relevant to this TUI repair. (role: recent adjacent hook fix owner; confidence: medium; commits: 49c4a13231a3; files: src/gateway/server-methods/sessions.ts, src/gateway/protocol/schema/sessions.ts, src/gateway/server.sessions.reset-hooks.test.ts)
  • Subash Natarajan: Commit 575202b06e93874a9aad80580357723c5c72eefb recently changed gateway session reset hook context for bundled session-memory behavior in the same reset-hook surface. (role: recent reset-hook contributor; confidence: medium; commits: 575202b06e93; files: src/gateway/session-reset-service.ts, src/hooks/bundled/session-memory/handler.test.ts)

Codex review notes: model gpt-5.5, reasoning high; reviewed against 6bd430ee3517.

@clawsweeper clawsweeper Bot added P2 Normal backlog priority with limited blast radius. impact:security Security boundary, credential, authz, sandbox, or sensitive-data risk. impact:session-state Session, memory, transcript, context, or agent state can drift or corrupt. labels May 17, 2026
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 17, 2026
@clawsweeper clawsweeper Bot added rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. and removed rating: 🌊 off-meta tidepool PR readiness rating does not apply to this item. impact:session-state Session, memory, transcript, context, or agent state can drift or corrupt. impact:security Security boundary, credential, authz, sandbox, or sensitive-data risk. labels May 18, 2026
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 19, 2026

ClawSweeper PR egg

🎁 Pass real behavior proof to wake the egg and unlock a hatchable treat.

Where did the egg go?
  • The egg game starts only after the PR passes the real-behavior proof check.
  • Before that, no creature or rarity is rolled. The treat waits for real proof.
  • This is still just collectible flavor: proof affects review readiness, not creature quality.

@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented May 24, 2026

ClawSweeper applied the proposed close for this PR.

@clawsweeper clawsweeper Bot closed this May 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: TUI /new stopped emitting hook-visible new-session behavior after 46008178d

1 participant