fix(sessions): gate command:new hook emission on emitCommandHooks param in sessions.create (#76957)#77376
Conversation
|
Codex review: needs real behavior proof before merge. Summary Reproducibility: yes. source-level. Current main routes typed Control UI Real behavior proof Next step before merge Security Review detailsBest possible solution: Land the explicit hook-emission opt-in after real Control UI/Gateway behavior proof or maintainer override and exact-head CI completion. Do we have a high-confidence way to reproduce the issue? Yes, source-level. Current main routes typed Control UI Is this the best way to solve the issue? Yes, functionally. The explicit opt-in is the narrow maintainable fix because it restores Control UI hook behavior without making ordinary SDK What I checked:
Likely related people:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 0c977cd68793. |
|
Fixed clawsweeper P2: Problem: Fix: Added 61/61 UI tests + 13/13 gateway session tests pass, commit Re-review progress:
|
|
Fixed Problem: Fix: Added |
29dfcfd to
86e4b9b
Compare
|
Rebased onto current Verification:
|
|
Follow-up: |
…am in sessions.create (openclaw#76957) Control UI /new typed command was rerouted by 37aebf6 from sendChatMessageNow("/new") to host.onSlashAction("new-session") → sessions.create, which fires no lifecycle hooks. This broke session-memory and other command:new hooks for the Control UI /new path. Previous fix (openclaw#77004) gated on parentSessionKey alone, which is too broad (SDK programmatic creates also supply parentSessionKey but must not fire webchat command:new hooks per the public docs). Fix: add emitCommandHooks: boolean to SessionsCreateParams. The Control UI /new flow sets emitCommandHooks: true; SDK callers do not. Gateway only emits command:new + before_reset + session lifecycle hooks when this flag is explicitly true. Tests: - sessions.create with emitCommandHooks=true fires command:new against parent - sessions.create with parentSessionKey but no emitCommandHooks fires nothing
…penclaw#76957) The createChatSession helper now passes emitCommandHooks: true when a parentSessionKey is present. Update the exact toHaveBeenCalledWith matcher to match the new call shape. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3f74298 to
d9d9abe
Compare
|
Closing — stale past the empirical 20h ceiling with no maintainer signal. Happy to revisit if the underlying issue stays relevant. |
Fixes #76957. Restores the Control UI /new hook lifecycle through an explicit sessions.create emitCommandHooks opt-in, preserving hook-free defaults for programmatic parent-session creates. Validation: - pnpm protocol:check - pnpm test src/gateway/server.sessions.reset-hooks.test.ts ui/src/ui/app-render.helpers.node.test.ts - pnpm exec oxlint on touched TS files - pnpm exec oxfmt --check --threads=1 on touched files - git diff --check - OPENCLAW_LOCAL_CHECK=1 OPENCLAW_LOCAL_CHECK_MODE=throttled env NODE_OPTIONS=--max-old-space-size=4096 pnpm check:changed - GitHub PR checks green on 3a446ec - ClawSweeper re-review completed with no blocking findings and security cleared Duplicate triage: - #77376, #77004, and #76967 were superseded closed attempts for #76957 - #77562 is a closed duplicate issue - #77880 mentions #76957 but is not a duplicate of this hook fix
Fixes #76957. Restores the Control UI /new hook lifecycle through an explicit sessions.create emitCommandHooks opt-in, preserving hook-free defaults for programmatic parent-session creates. Validation: - pnpm protocol:check - pnpm test src/gateway/server.sessions.reset-hooks.test.ts ui/src/ui/app-render.helpers.node.test.ts - pnpm exec oxlint on touched TS files - pnpm exec oxfmt --check --threads=1 on touched files - git diff --check - OPENCLAW_LOCAL_CHECK=1 OPENCLAW_LOCAL_CHECK_MODE=throttled env NODE_OPTIONS=--max-old-space-size=4096 pnpm check:changed - GitHub PR checks green on 3a446ec - ClawSweeper re-review completed with no blocking findings and security cleared Duplicate triage: - #77376, #77004, and #76967 were superseded closed attempts for #76957 - #77562 is a closed duplicate issue - #77880 mentions #76957 but is not a duplicate of this hook fix (cherry picked from commit 49c4a13)
Fixes openclaw#76957. Restores the Control UI /new hook lifecycle through an explicit sessions.create emitCommandHooks opt-in, preserving hook-free defaults for programmatic parent-session creates. Validation: - pnpm protocol:check - pnpm test src/gateway/server.sessions.reset-hooks.test.ts ui/src/ui/app-render.helpers.node.test.ts - pnpm exec oxlint on touched TS files - pnpm exec oxfmt --check --threads=1 on touched files - git diff --check - OPENCLAW_LOCAL_CHECK=1 OPENCLAW_LOCAL_CHECK_MODE=throttled env NODE_OPTIONS=--max-old-space-size=4096 pnpm check:changed - GitHub PR checks green on 3a446ec - ClawSweeper re-review completed with no blocking findings and security cleared Duplicate triage: - openclaw#77376, openclaw#77004, and openclaw#76967 were superseded closed attempts for openclaw#76957 - openclaw#77562 is a closed duplicate issue - openclaw#77880 mentions openclaw#76957 but is not a duplicate of this hook fix
Summary
Fixes #76957. Closes PR #77004 (previous fix was incorrect).
Root cause: commit 37aebf6 changed the Control UI
/newflow fromsendChatMessageNow("/new")(which dispatched through the command handler and firedcommand:newhooks) tohost.onSlashAction("new-session")->sessions.create, which fires no lifecycle hooks.Previous fix (#77004) gated hook emission on
parentSessionKey !== undefined, butparentSessionKeyis a public SDK param used for ordinary programmatic child-session creates -- those must NOT firecommand:newwithcommandSource: "webchat".This fix: Add
emitCommandHooks?: booleantoSessionsCreateParams. The gateway only fires the full hook chain (command:new,before_reset, session lifecycle) whenemitCommandHooks === true. The Control UI/newhelper passesemitCommandHooks: true; external SDK callers do not, preserving existing behavior.Changes
src/gateway/protocol/schema/sessions.ts-- addemitCommandHooks?: booleanto schemasrc/gateway/server-methods/sessions.ts-- gate hook block onp.emitCommandHooks === true; exportcreateInternalHookEventimportsrc/gateway/session-reset-service.ts-- exportemitGatewayBeforeResetPluginHooksrc/gateway/server-methods/sessions.runtime.ts-- re-exportemitGatewayBeforeResetPluginHook+emitGatewaySessionStartPluginHookui/src/ui/controllers/sessions.ts-- addemitCommandHooks?: booleantoCreateSessionParamsui/src/ui/app-render.helpers.ts-- passemitCommandHooks: truewhenparentSessionKeypresentTests
sessions.create with emitCommandHooks=true fires command:new hook against parentsessions.create without emitCommandHooks does NOT fire command:new hookReal behavior proof
/newcan explicitly request command/session lifecycle hooks viaemitCommandHooks: true, while external SDKsessions.createcalls continue to avoid webchat/newhook emission by default.cycle-repair-77376-260505_2018, rebased ontoorigin/main0c977cd687; repository gateway/UI/protocol test shards.pnpm test src/gateway/server.sessions.reset-hooks.test.ts ui/src/ui/app-render.helpers.node.test.tspnpm protocol:checksessions.createpaths; UI helper tests passed withemitCommandHooks: true; generated protocol and Swift mirrors stayed consistent.Generated with Claude Code