oh-my-codex 0.16.2 → 0.16.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Cargo.lock +5 -5
- package/Cargo.toml +1 -1
- package/README.md +3 -3
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js +9 -0
- package/dist/catalog/__tests__/plugin-bundle-ssot.test.js.map +1 -1
- package/dist/cli/__tests__/cleanup.test.js +27 -0
- package/dist/cli/__tests__/cleanup.test.js.map +1 -1
- package/dist/cli/__tests__/codex-plugin-layout.test.js +7 -5
- package/dist/cli/__tests__/codex-plugin-layout.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +137 -6
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +303 -4
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +58 -0
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js +2 -0
- package/dist/cli/__tests__/ralph-goal-mode-contract.test.js.map +1 -1
- package/dist/cli/__tests__/ralph.test.js +48 -0
- package/dist/cli/__tests__/ralph.test.js.map +1 -1
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js +8 -0
- package/dist/cli/__tests__/setup-hooks-shared-ownership.test.js.map +1 -1
- package/dist/cli/__tests__/setup-install-mode.test.js +350 -27
- package/dist/cli/__tests__/setup-install-mode.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +85 -3
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/setup-scope.test.js +1 -1
- package/dist/cli/__tests__/setup-scope.test.js.map +1 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.js +2 -1
- package/dist/cli/__tests__/setup-skills-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +269 -0
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/ultragoal.test.js +69 -0
- package/dist/cli/__tests__/ultragoal.test.js.map +1 -1
- package/dist/cli/__tests__/uninstall.test.js +90 -6
- package/dist/cli/__tests__/uninstall.test.js.map +1 -1
- package/dist/cli/__tests__/update.test.js +109 -19
- package/dist/cli/__tests__/update.test.js.map +1 -1
- package/dist/cli/cleanup.d.ts.map +1 -1
- package/dist/cli/cleanup.js +8 -4
- package/dist/cli/cleanup.js.map +1 -1
- package/dist/cli/codex-feature-probe.d.ts +9 -0
- package/dist/cli/codex-feature-probe.d.ts.map +1 -0
- package/dist/cli/codex-feature-probe.js +28 -0
- package/dist/cli/codex-feature-probe.js.map +1 -0
- package/dist/cli/doctor.d.ts +1 -0
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +168 -16
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/index.d.ts +9 -2
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +168 -20
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-parity.js +8 -8
- package/dist/cli/mcp-parity.js.map +1 -1
- package/dist/cli/plugin-marketplace.d.ts +3 -0
- package/dist/cli/plugin-marketplace.d.ts.map +1 -1
- package/dist/cli/plugin-marketplace.js +88 -0
- package/dist/cli/plugin-marketplace.js.map +1 -1
- package/dist/cli/ralph.d.ts.map +1 -1
- package/dist/cli/ralph.js +21 -0
- package/dist/cli/ralph.js.map +1 -1
- package/dist/cli/setup-preferences.d.ts +4 -0
- package/dist/cli/setup-preferences.d.ts.map +1 -1
- package/dist/cli/setup-preferences.js +7 -0
- package/dist/cli/setup-preferences.js.map +1 -1
- package/dist/cli/setup.d.ts +5 -3
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +177 -43
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +54 -15
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/ultragoal.d.ts +1 -1
- package/dist/cli/ultragoal.d.ts.map +1 -1
- package/dist/cli/ultragoal.js +64 -5
- package/dist/cli/ultragoal.js.map +1 -1
- package/dist/cli/uninstall.d.ts +2 -0
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +76 -5
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/cli/update.d.ts +10 -2
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +99 -5
- package/dist/cli/update.js.map +1 -1
- package/dist/config/__tests__/codex-feature-flags.test.d.ts +2 -0
- package/dist/config/__tests__/codex-feature-flags.test.d.ts.map +1 -0
- package/dist/config/__tests__/codex-feature-flags.test.js +35 -0
- package/dist/config/__tests__/codex-feature-flags.test.js.map +1 -0
- package/dist/config/__tests__/codex-hooks.test.js +188 -4
- package/dist/config/__tests__/codex-hooks.test.js.map +1 -1
- package/dist/config/__tests__/generator-idempotent.test.js +129 -10
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/generator-notify.test.js +148 -7
- package/dist/config/__tests__/generator-notify.test.js.map +1 -1
- package/dist/config/__tests__/wiki-config-contract.test.js +6 -3
- package/dist/config/__tests__/wiki-config-contract.test.js.map +1 -1
- package/dist/config/codex-feature-flags.d.ts +21 -0
- package/dist/config/codex-feature-flags.d.ts.map +1 -0
- package/dist/config/codex-feature-flags.js +56 -0
- package/dist/config/codex-feature-flags.js.map +1 -0
- package/dist/config/codex-hooks.d.ts +40 -4
- package/dist/config/codex-hooks.d.ts.map +1 -1
- package/dist/config/codex-hooks.js +204 -18
- package/dist/config/codex-hooks.js.map +1 -1
- package/dist/config/generator.d.ts +19 -1
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +319 -83
- package/dist/config/generator.js.map +1 -1
- package/dist/config/omx-first-party-mcp.d.ts +3 -1
- package/dist/config/omx-first-party-mcp.d.ts.map +1 -1
- package/dist/config/omx-first-party-mcp.js +2 -2
- package/dist/config/omx-first-party-mcp.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +92 -2
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +29 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +10 -0
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js +1 -0
- package/dist/hooks/__tests__/notify-hook-cross-worktree-heartbeat.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.d.ts +2 -0
- package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.js +176 -0
- package/dist/hooks/__tests__/notify-hook-non-omx-guard.test.js.map +1 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js +148 -0
- package/dist/hooks/__tests__/notify-hook-ralph-resume.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +3 -0
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
- package/dist/hooks/__tests__/skill-catalog-hygiene.test.d.ts +2 -0
- package/dist/hooks/__tests__/skill-catalog-hygiene.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/skill-catalog-hygiene.test.js +84 -0
- package/dist/hooks/__tests__/skill-catalog-hygiene.test.js.map +1 -0
- package/dist/hooks/__tests__/wiki-docs-contract.test.js +1 -2
- package/dist/hooks/__tests__/wiki-docs-contract.test.js.map +1 -1
- package/dist/hooks/agents-overlay.js +2 -2
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +1 -0
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +7 -5
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +164 -0
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +4 -5
- package/dist/hud/state.js.map +1 -1
- package/dist/mcp/__tests__/state-paths.test.js +61 -0
- package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server.test.js +166 -0
- package/dist/mcp/__tests__/state-server.test.js.map +1 -1
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +23 -2
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/modes/__tests__/base-session-scope.test.js +22 -0
- package/dist/modes/__tests__/base-session-scope.test.js.map +1 -1
- package/dist/modes/__tests__/base-tmux-pane.test.js +57 -26
- package/dist/modes/__tests__/base-tmux-pane.test.js.map +1 -1
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +5 -0
- package/dist/modes/base.js.map +1 -1
- package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.d.ts +2 -0
- package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.d.ts.map +1 -0
- package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js +316 -0
- package/dist/planning/__tests__/approved-execution-lifecycle-matrix.test.js.map +1 -0
- package/dist/planning/__tests__/approved-launch-hint-lineage-matrix.test.d.ts +2 -0
- package/dist/planning/__tests__/approved-launch-hint-lineage-matrix.test.d.ts.map +1 -0
- package/dist/planning/__tests__/approved-launch-hint-lineage-matrix.test.js +481 -0
- package/dist/planning/__tests__/approved-launch-hint-lineage-matrix.test.js.map +1 -0
- package/dist/planning/__tests__/artifacts.test.js +597 -4
- package/dist/planning/__tests__/artifacts.test.js.map +1 -1
- package/dist/planning/__tests__/context-pack-status.test.js +524 -0
- package/dist/planning/__tests__/context-pack-status.test.js.map +1 -1
- package/dist/planning/__tests__/markdown-structure.test.d.ts +2 -0
- package/dist/planning/__tests__/markdown-structure.test.d.ts.map +1 -0
- package/dist/planning/__tests__/markdown-structure.test.js +459 -0
- package/dist/planning/__tests__/markdown-structure.test.js.map +1 -0
- package/dist/planning/__tests__/ready-context-pack-role-refs.test.d.ts +2 -0
- package/dist/planning/__tests__/ready-context-pack-role-refs.test.d.ts.map +1 -0
- package/dist/planning/__tests__/ready-context-pack-role-refs.test.js +612 -0
- package/dist/planning/__tests__/ready-context-pack-role-refs.test.js.map +1 -0
- package/dist/planning/artifacts.d.ts +7 -2
- package/dist/planning/artifacts.d.ts.map +1 -1
- package/dist/planning/artifacts.js +279 -26
- package/dist/planning/artifacts.js.map +1 -1
- package/dist/planning/context-pack-status.d.ts +31 -0
- package/dist/planning/context-pack-status.d.ts.map +1 -1
- package/dist/planning/context-pack-status.js +291 -25
- package/dist/planning/context-pack-status.js.map +1 -1
- package/dist/planning/markdown-structure.d.ts +20 -0
- package/dist/planning/markdown-structure.d.ts.map +1 -0
- package/dist/planning/markdown-structure.js +137 -0
- package/dist/planning/markdown-structure.js.map +1 -0
- package/dist/ralph/__tests__/completion-audit.test.d.ts +2 -0
- package/dist/ralph/__tests__/completion-audit.test.d.ts.map +1 -0
- package/dist/ralph/__tests__/completion-audit.test.js +121 -0
- package/dist/ralph/__tests__/completion-audit.test.js.map +1 -0
- package/dist/ralph/completion-audit.d.ts +8 -0
- package/dist/ralph/completion-audit.d.ts.map +1 -0
- package/dist/ralph/completion-audit.js +99 -0
- package/dist/ralph/completion-audit.js.map +1 -0
- package/dist/ralph/persistence.d.ts +1 -1
- package/dist/ralph/persistence.d.ts.map +1 -1
- package/dist/ralph/persistence.js +8 -2
- package/dist/ralph/persistence.js.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +359 -24
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/notify-dispatcher.test.d.ts +2 -0
- package/dist/scripts/__tests__/notify-dispatcher.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/notify-dispatcher.test.js +126 -0
- package/dist/scripts/__tests__/notify-dispatcher.test.js.map +1 -0
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +142 -76
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/codex-native-pre-post.d.ts.map +1 -1
- package/dist/scripts/codex-native-pre-post.js +4 -2
- package/dist/scripts/codex-native-pre-post.js.map +1 -1
- package/dist/scripts/notify-dispatcher.d.ts +7 -0
- package/dist/scripts/notify-dispatcher.d.ts.map +1 -0
- package/dist/scripts/notify-dispatcher.js +87 -0
- package/dist/scripts/notify-dispatcher.js.map +1 -0
- package/dist/scripts/notify-fallback-watcher.js +4 -0
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/ralph-session-resume.d.ts.map +1 -1
- package/dist/scripts/notify-hook/ralph-session-resume.js +96 -8
- package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -1
- package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
- package/dist/scripts/notify-hook/state-io.js +6 -2
- package/dist/scripts/notify-hook/state-io.js.map +1 -1
- package/dist/scripts/notify-hook/visual-verdict.js +3 -3
- package/dist/scripts/notify-hook/visual-verdict.js.map +1 -1
- package/dist/scripts/notify-hook.js +127 -1
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/state/__tests__/workflow-transition.test.js +102 -27
- package/dist/state/__tests__/workflow-transition.test.js.map +1 -1
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +9 -3
- package/dist/state/operations.js.map +1 -1
- package/dist/state/skill-active.d.ts +7 -0
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +25 -8
- package/dist/state/skill-active.js.map +1 -1
- package/dist/state/workflow-transition-reconcile.d.ts +1 -0
- package/dist/state/workflow-transition-reconcile.d.ts.map +1 -1
- package/dist/state/workflow-transition-reconcile.js +22 -15
- package/dist/state/workflow-transition-reconcile.js.map +1 -1
- package/dist/state/workflow-transition.js +3 -3
- package/dist/state/workflow-transition.js.map +1 -1
- package/dist/team/__tests__/approved-execution.test.js +84 -1
- package/dist/team/__tests__/approved-execution.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +178 -19
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/scaling.test.js +497 -2
- package/dist/team/__tests__/scaling.test.js.map +1 -1
- package/dist/team/__tests__/state-root.test.js +1 -1
- package/dist/team/__tests__/state-root.test.js.map +1 -1
- package/dist/team/__tests__/worker-bootstrap.test.js +45 -0
- package/dist/team/__tests__/worker-bootstrap.test.js.map +1 -1
- package/dist/team/approved-execution.d.ts +1 -0
- package/dist/team/approved-execution.d.ts.map +1 -1
- package/dist/team/approved-execution.js +53 -0
- package/dist/team/approved-execution.js.map +1 -1
- package/dist/team/delivery-log.d.ts.map +1 -1
- package/dist/team/delivery-log.js +8 -1
- package/dist/team/delivery-log.js.map +1 -1
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +104 -18
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +43 -0
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state/mailbox.d.ts +1 -0
- package/dist/team/state/mailbox.d.ts.map +1 -1
- package/dist/team/state/mailbox.js +10 -1
- package/dist/team/state/mailbox.js.map +1 -1
- package/dist/team/state-root.d.ts.map +1 -1
- package/dist/team/state-root.js +5 -1
- package/dist/team/state-root.js.map +1 -1
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +3 -7
- package/dist/team/state.js.map +1 -1
- package/dist/team/worker-bootstrap.d.ts +7 -2
- package/dist/team/worker-bootstrap.d.ts.map +1 -1
- package/dist/team/worker-bootstrap.js +17 -4
- package/dist/team/worker-bootstrap.js.map +1 -1
- package/dist/ultragoal/__tests__/artifacts.test.js +124 -1
- package/dist/ultragoal/__tests__/artifacts.test.js.map +1 -1
- package/dist/ultragoal/__tests__/docs-contract.test.js +21 -0
- package/dist/ultragoal/__tests__/docs-contract.test.js.map +1 -1
- package/dist/ultragoal/artifacts.d.ts +44 -2
- package/dist/ultragoal/artifacts.d.ts.map +1 -1
- package/dist/ultragoal/artifacts.js +197 -13
- package/dist/ultragoal/artifacts.js.map +1 -1
- package/dist/wiki/lifecycle.js +1 -1
- package/dist/wiki/lifecycle.js.map +1 -1
- package/package.json +1 -1
- package/plugins/oh-my-codex/.codex-plugin/plugin.json +1 -1
- package/plugins/oh-my-codex/.mcp.json +5 -5
- package/plugins/oh-my-codex/skills/analyze/SKILL.md +0 -2
- package/plugins/oh-my-codex/skills/autopilot/SKILL.md +2 -2
- package/plugins/oh-my-codex/skills/code-review/SKILL.md +1 -3
- package/plugins/oh-my-codex/skills/deep-interview/SKILL.md +5 -7
- package/plugins/oh-my-codex/skills/doctor/SKILL.md +2 -2
- package/plugins/oh-my-codex/skills/omx-setup/SKILL.md +3 -3
- package/plugins/oh-my-codex/skills/pipeline/SKILL.md +3 -3
- package/plugins/oh-my-codex/skills/plan/SKILL.md +3 -6
- package/plugins/oh-my-codex/skills/ralph/SKILL.md +9 -10
- package/plugins/oh-my-codex/skills/ultragoal/SKILL.md +36 -3
- package/plugins/oh-my-codex/skills/ultraqa/SKILL.md +21 -24
- package/plugins/oh-my-codex/skills/ultrawork/SKILL.md +8 -8
- package/plugins/oh-my-codex/skills/wiki/SKILL.md +13 -13
- package/skills/analyze/SKILL.md +0 -2
- package/skills/ask-claude/SKILL.md +5 -3
- package/skills/ask-gemini/SKILL.md +5 -3
- package/skills/autopilot/SKILL.md +2 -2
- package/skills/code-review/SKILL.md +1 -3
- package/skills/deep-interview/SKILL.md +5 -7
- package/skills/doctor/SKILL.md +2 -2
- package/skills/ecomode/SKILL.md +105 -1
- package/skills/frontend-ui-ux/SKILL.md +4 -26
- package/skills/git-master/SKILL.md +2 -4
- package/skills/omx-setup/SKILL.md +3 -3
- package/skills/pipeline/SKILL.md +3 -3
- package/skills/plan/SKILL.md +3 -6
- package/skills/ralph/SKILL.md +9 -10
- package/skills/swarm/SKILL.md +5 -3
- package/skills/tdd/SKILL.md +95 -1
- package/skills/ultragoal/SKILL.md +36 -3
- package/skills/ultraqa/SKILL.md +21 -24
- package/skills/ultrawork/SKILL.md +8 -8
- package/skills/web-clone/SKILL.md +348 -1
- package/skills/wiki/SKILL.md +13 -13
- package/src/scripts/__tests__/codex-native-hook.test.ts +389 -24
- package/src/scripts/__tests__/notify-dispatcher.test.ts +153 -0
- package/src/scripts/codex-native-hook.ts +168 -64
- package/src/scripts/codex-native-pre-post.ts +4 -1
- package/src/scripts/notify-dispatcher.ts +113 -0
- package/src/scripts/notify-fallback-watcher.ts +6 -2
- package/src/scripts/notify-hook/ralph-session-resume.ts +117 -8
- package/src/scripts/notify-hook/state-io.ts +4 -2
- package/src/scripts/notify-hook/visual-verdict.ts +3 -3
- package/src/scripts/notify-hook.ts +119 -1
|
@@ -4,14 +4,14 @@ import { appendFile, mkdir, readFile, readdir, writeFile } from "fs/promises";
|
|
|
4
4
|
import { extname, join, relative, resolve } from "path";
|
|
5
5
|
import { pathToFileURL } from "url";
|
|
6
6
|
import { readModeState, readModeStateForActiveDecision, readModeStateForSession, updateModeState } from "../modes/base.js";
|
|
7
|
-
import { extractSessionIdFromInitializedStatePath,
|
|
7
|
+
import { extractSessionIdFromInitializedStatePath, getSkillActiveStatePathsForStateDir, listActiveSkills, readSkillActiveState, readVisibleSkillActiveStateForStateDir, } from "../state/skill-active.js";
|
|
8
8
|
import { readSubagentSessionSummary, recordSubagentTurnForSession, } from "../subagents/tracker.js";
|
|
9
9
|
import { resolveCanonicalTeamStateRoot, resolveWorkerNotifyTeamStateRootPath } from "../team/state-root.js";
|
|
10
10
|
import { appendToLog, isSessionStateUsable, readSessionState, readUsableSessionState, reconcileNativeSessionStart, } from "../hooks/session.js";
|
|
11
11
|
import { appendTeamEvent, readTeamLeaderAttention, readTeamManifestV2, readTeamPhase, writeTeamLeaderAttention, writeTeamPhase, } from "../team/state.js";
|
|
12
12
|
import { omxNotepadPath, omxProjectMemoryPath } from "../utils/paths.js";
|
|
13
13
|
import { findGitLayout } from "../utils/git-layout.js";
|
|
14
|
-
import { getStateFilePath, getStatePath } from "../mcp/state-paths.js";
|
|
14
|
+
import { getBaseStateDir, getStateFilePath, getStatePath } from "../mcp/state-paths.js";
|
|
15
15
|
import { detectKeywords, detectPrimaryKeyword, recordSkillActivation, } from "../hooks/keyword-detector.js";
|
|
16
16
|
import { detectNativeStopStallPattern, loadAutoNudgeConfig, normalizeAutoNudgeSignatureText, resolveEffectiveAutoNudgeResponse, } from "./notify-hook/auto-nudge.js";
|
|
17
17
|
import { SLOPPY_FALLBACK_GROUNDING_PATTERNS, SLOPPY_FALLBACK_IMPLEMENTATION_CONTEXT_PATTERNS, SLOPPY_FALLBACK_PHRASE_PATTERNS, buildNativePostToolUseOutput, buildNativePreToolUseOutput, detectMcpTransportFailure, hasAnyPattern, } from "./codex-native-pre-post.js";
|
|
@@ -21,9 +21,10 @@ import { resolveCodexExecutionSurface, } from "./codex-execution-surface.js";
|
|
|
21
21
|
import { buildNativeHookEvent, } from "../hooks/extensibility/events.js";
|
|
22
22
|
import { dispatchHookEventRuntime } from "../hooks/extensibility/runtime.js";
|
|
23
23
|
import { reconcileHudForPromptSubmit } from "../hud/reconcile.js";
|
|
24
|
-
import {
|
|
24
|
+
import { onPreCompact as buildWikiPreCompactContext, onSessionStart as buildWikiSessionStartContext, } from "../wiki/lifecycle.js";
|
|
25
25
|
import { readAutoresearchCompletionStatus, readAutoresearchModeStateForActiveDecision } from "../autoresearch/skill-validation.js";
|
|
26
26
|
import { readRunState } from "../runtime/run-state.js";
|
|
27
|
+
import { evaluateRalphCompletionAuditEvidence, isRalphCompletePhase } from "../ralph/completion-audit.js";
|
|
27
28
|
import { getRunContinuationSnapshot, shouldContinueRun } from "../runtime/run-loop.js";
|
|
28
29
|
import { triagePrompt } from "../hooks/triage-heuristic.js";
|
|
29
30
|
import { readTriageConfig } from "../hooks/triage-config.js";
|
|
@@ -381,15 +382,15 @@ async function readCanonicalTerminalRunStateForStop(cwd, sessionId, mode) {
|
|
|
381
382
|
const runRecord = runState;
|
|
382
383
|
return shouldHonorCanonicalTerminalRunState(runRecord, mode) ? runRecord : null;
|
|
383
384
|
}
|
|
384
|
-
async function isVisibleRalphActiveForSession(
|
|
385
|
-
const canonicalState = await
|
|
385
|
+
async function isVisibleRalphActiveForSession(stateDir, sessionId) {
|
|
386
|
+
const canonicalState = await readVisibleSkillActiveStateForStateDir(stateDir, sessionId);
|
|
386
387
|
if (!canonicalState)
|
|
387
388
|
return false;
|
|
388
389
|
return listActiveSkills(canonicalState).some((entry) => (entry.skill === "ralph"
|
|
389
390
|
&& matchesSkillStopContext(entry, canonicalState, sessionId, "")));
|
|
390
391
|
}
|
|
391
|
-
async function hasConsistentRalphSkillActivation(
|
|
392
|
-
const canonicalState = await
|
|
392
|
+
async function hasConsistentRalphSkillActivation(stateDir, sessionId) {
|
|
393
|
+
const canonicalState = await readVisibleSkillActiveStateForStateDir(stateDir, sessionId);
|
|
393
394
|
if (!canonicalState)
|
|
394
395
|
return true;
|
|
395
396
|
const initializedMode = safeString(canonicalState.initialized_mode).trim();
|
|
@@ -400,8 +401,63 @@ async function hasConsistentRalphSkillActivation(cwd, sessionId) {
|
|
|
400
401
|
return false;
|
|
401
402
|
return true;
|
|
402
403
|
}
|
|
403
|
-
async function
|
|
404
|
-
const
|
|
404
|
+
async function readRalphCompletionAuditBlockState(cwd, stateDir, preferredSessionId, ownerContext) {
|
|
405
|
+
const [rawSessionInfo, usableSessionInfo] = await Promise.all([
|
|
406
|
+
readSessionState(cwd),
|
|
407
|
+
readUsableSessionState(cwd),
|
|
408
|
+
]);
|
|
409
|
+
const currentOmxSessionId = safeString(usableSessionInfo?.session_id).trim();
|
|
410
|
+
const currentNativeSessionId = safeString(usableSessionInfo?.native_session_id).trim();
|
|
411
|
+
const staleCurrentSessionId = rawSessionInfo && !isSessionStateUsable(rawSessionInfo, cwd)
|
|
412
|
+
? safeString(rawSessionInfo.session_id).trim()
|
|
413
|
+
: "";
|
|
414
|
+
const sessionCandidates = [...new Set([
|
|
415
|
+
safeString(preferredSessionId).trim(),
|
|
416
|
+
currentOmxSessionId,
|
|
417
|
+
].filter(Boolean))];
|
|
418
|
+
const evaluateCandidate = (state, path, sessionId) => {
|
|
419
|
+
if (!state || state.mode && safeString(state.mode) !== "ralph")
|
|
420
|
+
return null;
|
|
421
|
+
if (!isRalphCompletePhase(state.current_phase ?? state.currentPhase))
|
|
422
|
+
return null;
|
|
423
|
+
if (activeRalphStateMatchesStopOwner(state, {
|
|
424
|
+
sessionId,
|
|
425
|
+
payloadSessionId: safeString(ownerContext?.payloadSessionId).trim(),
|
|
426
|
+
threadId: safeString(ownerContext?.threadId).trim(),
|
|
427
|
+
currentNativeSessionId,
|
|
428
|
+
tmuxPaneId: safeString(ownerContext?.tmuxPaneId).trim(),
|
|
429
|
+
}) !== true)
|
|
430
|
+
return null;
|
|
431
|
+
const audit = evaluateRalphCompletionAuditEvidence(state, cwd);
|
|
432
|
+
return audit.complete ? null : { state, path, reason: audit.reason };
|
|
433
|
+
};
|
|
434
|
+
for (const sessionId of sessionCandidates) {
|
|
435
|
+
if (staleCurrentSessionId && sessionId === staleCurrentSessionId)
|
|
436
|
+
continue;
|
|
437
|
+
const sessionScopedPath = getStateFilePath("ralph-state.json", cwd, sessionId);
|
|
438
|
+
const result = evaluateCandidate(await readJsonIfExists(sessionScopedPath), sessionScopedPath, sessionId);
|
|
439
|
+
if (result)
|
|
440
|
+
return result;
|
|
441
|
+
}
|
|
442
|
+
if (sessionCandidates.length > 0)
|
|
443
|
+
return null;
|
|
444
|
+
const directPath = join(stateDir, "ralph-state.json");
|
|
445
|
+
return evaluateCandidate(await readJsonIfExists(directPath), directPath, "");
|
|
446
|
+
}
|
|
447
|
+
async function reopenRalphCompletionAuditBlock(block) {
|
|
448
|
+
const nowIso = new Date().toISOString();
|
|
449
|
+
const next = {
|
|
450
|
+
...block.state,
|
|
451
|
+
active: true,
|
|
452
|
+
current_phase: "verifying",
|
|
453
|
+
completion_audit_gate: "blocked",
|
|
454
|
+
completion_audit_missing_reason: block.reason,
|
|
455
|
+
completion_audit_blocked_at: nowIso,
|
|
456
|
+
};
|
|
457
|
+
delete next.completed_at;
|
|
458
|
+
await writeFile(block.path, JSON.stringify(next, null, 2));
|
|
459
|
+
}
|
|
460
|
+
async function readActiveRalphState(cwd, stateDir, preferredSessionId, ownerContext) {
|
|
405
461
|
const [rawSessionInfo, usableSessionInfo] = await Promise.all([
|
|
406
462
|
readSessionState(cwd),
|
|
407
463
|
readUsableSessionState(cwd),
|
|
@@ -429,7 +485,7 @@ async function readActiveRalphState(stateDir, preferredSessionId, ownerContext)
|
|
|
429
485
|
const sessionScoped = await readJsonIfExists(sessionScopedPath);
|
|
430
486
|
if (sessionScoped?.active === true
|
|
431
487
|
&& isRalphStartingPhase(sessionScoped)
|
|
432
|
-
&& !(await isVisibleRalphActiveForSession(
|
|
488
|
+
&& !(await isVisibleRalphActiveForSession(stateDir, sessionId))) {
|
|
433
489
|
continue;
|
|
434
490
|
}
|
|
435
491
|
if (sessionScoped?.active === true
|
|
@@ -441,7 +497,7 @@ async function readActiveRalphState(stateDir, preferredSessionId, ownerContext)
|
|
|
441
497
|
currentNativeSessionId,
|
|
442
498
|
tmuxPaneId: safeString(ownerContext?.tmuxPaneId).trim(),
|
|
443
499
|
})
|
|
444
|
-
&& await hasConsistentRalphSkillActivation(
|
|
500
|
+
&& await hasConsistentRalphSkillActivation(stateDir, sessionId)) {
|
|
445
501
|
return { state: sessionScoped, path: sessionScopedPath };
|
|
446
502
|
}
|
|
447
503
|
}
|
|
@@ -1030,6 +1086,9 @@ function buildNativeOutsideTmuxTeamPromptBlockState(prompt, cwd, payload, sessio
|
|
|
1030
1086
|
transition_error: "Codex App/native outside-tmux sessions cannot activate the tmux-only `team` workflow directly. Launch OMX CLI from an attached tmux shell first, then run `omx team ...` there.",
|
|
1031
1087
|
};
|
|
1032
1088
|
}
|
|
1089
|
+
function buildSkillStateCliInstruction(mode, statePath) {
|
|
1090
|
+
return `skill: ${mode} activated and initial state initialized at ${statePath}; use CLI-first state updates via \`omx state write/read/clear --input '<json>' --json\`; use omx_state MCP only when explicit MCP compatibility is enabled.`;
|
|
1091
|
+
}
|
|
1033
1092
|
function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(), payload) {
|
|
1034
1093
|
if (!prompt)
|
|
1035
1094
|
return null;
|
|
@@ -1089,7 +1148,7 @@ function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(),
|
|
|
1089
1148
|
promptPriorityMessage,
|
|
1090
1149
|
ultragoalPromptActivationNote,
|
|
1091
1150
|
skillState.initialized_mode && skillState.initialized_state_path
|
|
1092
|
-
?
|
|
1151
|
+
? buildSkillStateCliInstruction(skillState.initialized_mode, skillState.initialized_state_path)
|
|
1093
1152
|
: null,
|
|
1094
1153
|
teamDetected
|
|
1095
1154
|
? buildTeamRuntimeInstruction(cwd, payload)
|
|
@@ -1100,7 +1159,7 @@ function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(),
|
|
|
1100
1159
|
}
|
|
1101
1160
|
if (teamDetected) {
|
|
1102
1161
|
const initializedStateMessage = skillState?.initialized_mode && skillState.initialized_state_path
|
|
1103
|
-
?
|
|
1162
|
+
? buildSkillStateCliInstruction(skillState.initialized_mode, skillState.initialized_state_path)
|
|
1104
1163
|
: null;
|
|
1105
1164
|
return [
|
|
1106
1165
|
detectedKeywordMessage,
|
|
@@ -1126,7 +1185,7 @@ function buildAdditionalContextMessage(prompt, skillState, cwd = process.cwd(),
|
|
|
1126
1185
|
? `planning preserved over simultaneous execution follow-up; deferred skills: ${deferredSkills.join(", ")}.`
|
|
1127
1186
|
: null,
|
|
1128
1187
|
promptPriorityMessage,
|
|
1129
|
-
|
|
1188
|
+
buildSkillStateCliInstruction(skillState.initialized_mode, skillState.initialized_state_path),
|
|
1130
1189
|
deepInterviewPromptActivationNote,
|
|
1131
1190
|
ultraworkPromptActivationNote,
|
|
1132
1191
|
ultragoalPromptActivationNote,
|
|
@@ -1164,7 +1223,7 @@ async function resolveTeamWorkerStopDecision(cwd) {
|
|
|
1164
1223
|
|| parseTeamWorkerEnv(safeString(process.env.OMX_TEAM_WORKER));
|
|
1165
1224
|
if (!workerContext)
|
|
1166
1225
|
return { kind: "unresolved", reason: "missing_worker_context" };
|
|
1167
|
-
const blockWorkerStop = (reasonCode, detail, stateDirForDecision =
|
|
1226
|
+
const blockWorkerStop = (reasonCode, detail, stateDirForDecision = getBaseStateDir(cwd)) => ({
|
|
1168
1227
|
kind: "blocked",
|
|
1169
1228
|
stateDir: stateDirForDecision,
|
|
1170
1229
|
workerContext,
|
|
@@ -1315,7 +1374,10 @@ async function findActiveGoalWorkflowReconciliationRequirement(cwd) {
|
|
|
1315
1374
|
continue;
|
|
1316
1375
|
const mission = await readJsonIfExists(join(autoresearchRoot, entry.name, "mission.json"));
|
|
1317
1376
|
const status = safeString(mission?.status);
|
|
1318
|
-
|
|
1377
|
+
const completion = await readJsonIfExists(join(autoresearchRoot, entry.name, "completion.json"));
|
|
1378
|
+
const completionVerdict = safeString(completion?.verdict);
|
|
1379
|
+
const completionPassed = completion?.passed === true || completionVerdict === "pass";
|
|
1380
|
+
if (mission?.workflow === "autoresearch-goal" && status && status !== "complete" && completionPassed) {
|
|
1319
1381
|
return {
|
|
1320
1382
|
workflow: "autoresearch-goal",
|
|
1321
1383
|
command: `omx autoresearch-goal complete --slug ${safeString(mission.slug) || entry.name} --codex-goal-json '<get_goal JSON or path>'`,
|
|
@@ -1351,15 +1413,15 @@ async function buildGoalWorkflowReconciliationStopOutput(payload, cwd) {
|
|
|
1351
1413
|
systemMessage,
|
|
1352
1414
|
};
|
|
1353
1415
|
}
|
|
1354
|
-
async function readTeamModeStateForStop(cwd, sessionId) {
|
|
1416
|
+
async function readTeamModeStateForStop(cwd, stateDir, sessionId) {
|
|
1355
1417
|
const normalizedSessionId = safeString(sessionId).trim();
|
|
1356
1418
|
if (!normalizedSessionId) {
|
|
1357
1419
|
return await readModeState("team", cwd);
|
|
1358
1420
|
}
|
|
1359
|
-
const scopedState = await readStopSessionPinnedState("team-state.json", cwd, normalizedSessionId);
|
|
1421
|
+
const scopedState = await readStopSessionPinnedState("team-state.json", cwd, normalizedSessionId, stateDir);
|
|
1360
1422
|
if (scopedState)
|
|
1361
1423
|
return scopedState;
|
|
1362
|
-
const rootState = await readJsonIfExists(join(
|
|
1424
|
+
const rootState = await readJsonIfExists(join(stateDir, "team-state.json"));
|
|
1363
1425
|
if (rootState?.active !== true)
|
|
1364
1426
|
return null;
|
|
1365
1427
|
const ownerSessionId = safeString(rootState.session_id).trim();
|
|
@@ -1372,7 +1434,7 @@ async function buildTeamStopOutput(cwd, sessionId) {
|
|
|
1372
1434
|
if (await readCanonicalTerminalRunStateForStop(cwd, sessionId, "team")) {
|
|
1373
1435
|
return null;
|
|
1374
1436
|
}
|
|
1375
|
-
const teamState = await readTeamModeStateForStop(cwd, sessionId);
|
|
1437
|
+
const teamState = await readTeamModeStateForStop(cwd, getBaseStateDir(cwd), sessionId);
|
|
1376
1438
|
if (teamState?.active !== true)
|
|
1377
1439
|
return null;
|
|
1378
1440
|
const teamName = safeString(teamState.team_name).trim();
|
|
@@ -1422,10 +1484,10 @@ function hasReleaseReadinessMode(payload) {
|
|
|
1422
1484
|
const mode = safeString(payload.mode).trim().toLowerCase();
|
|
1423
1485
|
return mode === "release-readiness";
|
|
1424
1486
|
}
|
|
1425
|
-
async function hasReleaseReadinessStopMarker(cwd, sessionId, teamName) {
|
|
1487
|
+
async function hasReleaseReadinessStopMarker(cwd, stateDir, sessionId, teamName) {
|
|
1426
1488
|
if (!sessionId)
|
|
1427
1489
|
return false;
|
|
1428
|
-
const markerState = await readStopSessionPinnedState("release-readiness-state.json", cwd, sessionId);
|
|
1490
|
+
const markerState = await readStopSessionPinnedState("release-readiness-state.json", cwd, sessionId, stateDir);
|
|
1429
1491
|
if (markerState?.active !== true || markerState.stable_final_recommendation_emitted !== true) {
|
|
1430
1492
|
return false;
|
|
1431
1493
|
}
|
|
@@ -1460,8 +1522,10 @@ async function resolveInternalSessionIdForPayload(cwd, payloadSessionId) {
|
|
|
1460
1522
|
return canonicalSessionId;
|
|
1461
1523
|
return payloadSessionId;
|
|
1462
1524
|
}
|
|
1463
|
-
async function readStopSessionPinnedState(fileName, cwd, sessionId) {
|
|
1464
|
-
const statePath =
|
|
1525
|
+
async function readStopSessionPinnedState(fileName, cwd, sessionId, stateDir) {
|
|
1526
|
+
const statePath = stateDir && sessionId
|
|
1527
|
+
? join(stateDir, "sessions", sessionId, fileName)
|
|
1528
|
+
: getStateFilePath(fileName, cwd, sessionId || undefined);
|
|
1465
1529
|
return readJsonIfExists(statePath);
|
|
1466
1530
|
}
|
|
1467
1531
|
function matchesSkillStopContext(entry, state, sessionId, threadId) {
|
|
@@ -1496,8 +1560,8 @@ function modeStateMatchesSkillStopContext(state, cwd, sessionId) {
|
|
|
1496
1560
|
}
|
|
1497
1561
|
return true;
|
|
1498
1562
|
}
|
|
1499
|
-
async function readBlockingSkillForStop(cwd, sessionId, threadId, requiredSkill) {
|
|
1500
|
-
const canonicalState = await
|
|
1563
|
+
async function readBlockingSkillForStop(cwd, stateDir, sessionId, threadId, requiredSkill) {
|
|
1564
|
+
const canonicalState = await readVisibleSkillActiveStateForStateDir(stateDir, sessionId);
|
|
1501
1565
|
const visibleEntries = canonicalState ? listActiveSkills(canonicalState) : [];
|
|
1502
1566
|
const candidateSkills = requiredSkill
|
|
1503
1567
|
? [requiredSkill]
|
|
@@ -1506,7 +1570,7 @@ async function readBlockingSkillForStop(cwd, sessionId, threadId, requiredSkill)
|
|
|
1506
1570
|
const terminalRunState = await readCanonicalTerminalRunStateForStop(cwd, sessionId, skill);
|
|
1507
1571
|
if (terminalRunState)
|
|
1508
1572
|
continue;
|
|
1509
|
-
const modeState = await readStopSessionPinnedState(`${skill}-state.json`, cwd, sessionId);
|
|
1573
|
+
const modeState = await readStopSessionPinnedState(`${skill}-state.json`, cwd, sessionId, stateDir);
|
|
1510
1574
|
if (!modeState || modeState.active !== true)
|
|
1511
1575
|
continue;
|
|
1512
1576
|
if (!modeStateMatchesSkillStopContext(modeState, cwd, sessionId))
|
|
@@ -1554,16 +1618,16 @@ function isTerminalOrInactiveModeState(state) {
|
|
|
1554
1618
|
const phase = safeString(state.current_phase ?? state.currentPhase).trim().toLowerCase();
|
|
1555
1619
|
return phase !== "" && TERMINAL_MODE_PHASES.has(phase);
|
|
1556
1620
|
}
|
|
1557
|
-
async function readSessionScopedModeStateForRootSkill(cwd, skill, sessionIds) {
|
|
1621
|
+
async function readSessionScopedModeStateForRootSkill(cwd, stateDir, skill, sessionIds) {
|
|
1558
1622
|
for (const sessionId of sessionIds) {
|
|
1559
|
-
const state = await
|
|
1623
|
+
const state = await readStopSessionPinnedState(`${skill}-state.json`, cwd, sessionId, stateDir);
|
|
1560
1624
|
if (state)
|
|
1561
1625
|
return state;
|
|
1562
1626
|
}
|
|
1563
1627
|
return null;
|
|
1564
1628
|
}
|
|
1565
|
-
async function reconcileStaleRootSkillActiveStateForStop(cwd, sessionId) {
|
|
1566
|
-
const { rootPath } =
|
|
1629
|
+
async function reconcileStaleRootSkillActiveStateForStop(cwd, stateDir, sessionId) {
|
|
1630
|
+
const { rootPath } = getSkillActiveStatePathsForStateDir(stateDir);
|
|
1567
1631
|
const rootState = await readSkillActiveState(rootPath);
|
|
1568
1632
|
if (!rootState?.active)
|
|
1569
1633
|
return;
|
|
@@ -1590,7 +1654,7 @@ async function reconcileStaleRootSkillActiveStateForStop(cwd, sessionId) {
|
|
|
1590
1654
|
initializedSessionId,
|
|
1591
1655
|
safeString(rootState.session_id),
|
|
1592
1656
|
]);
|
|
1593
|
-
const modeState = await readSessionScopedModeStateForRootSkill(cwd, skill, candidateSessionIds);
|
|
1657
|
+
const modeState = await readSessionScopedModeStateForRootSkill(cwd, stateDir, skill, candidateSessionIds);
|
|
1594
1658
|
if (isTerminalOrInactiveModeState(modeState)) {
|
|
1595
1659
|
changed = true;
|
|
1596
1660
|
continue;
|
|
@@ -1649,17 +1713,17 @@ function buildRalplanContinuationStatus(blocker, activeSubagentCount) {
|
|
|
1649
1713
|
systemMessage: `OMX ralplan status: continue_from_artifact at phase ${phase}; continue from the current ralplan artifact and finish by stating whether ralplan is complete, paused for review, waiting for input, or still continuing.`,
|
|
1650
1714
|
};
|
|
1651
1715
|
}
|
|
1652
|
-
async function readStopAutoNudgePhase(cwd, sessionId, threadId) {
|
|
1716
|
+
async function readStopAutoNudgePhase(cwd, stateDir, sessionId, threadId) {
|
|
1653
1717
|
const normalizedSessionId = sessionId.trim();
|
|
1654
1718
|
if (normalizedSessionId) {
|
|
1655
|
-
const scopedModeState = await readStopSessionPinnedState("deep-interview-state.json", cwd, normalizedSessionId);
|
|
1719
|
+
const scopedModeState = await readStopSessionPinnedState("deep-interview-state.json", cwd, normalizedSessionId, stateDir);
|
|
1656
1720
|
if (scopedModeState?.active === true
|
|
1657
1721
|
&& safeString(scopedModeState.current_phase).trim().toLowerCase() === "intent-first") {
|
|
1658
1722
|
return "planning";
|
|
1659
1723
|
}
|
|
1660
1724
|
}
|
|
1661
1725
|
else {
|
|
1662
|
-
const rootModeState = await readJsonIfExists(join(
|
|
1726
|
+
const rootModeState = await readJsonIfExists(join(stateDir, "deep-interview-state.json"));
|
|
1663
1727
|
if (rootModeState?.active === true
|
|
1664
1728
|
&& safeString(rootModeState.current_phase).trim().toLowerCase() === "intent-first") {
|
|
1665
1729
|
return "planning";
|
|
@@ -1667,21 +1731,21 @@ async function readStopAutoNudgePhase(cwd, sessionId, threadId) {
|
|
|
1667
1731
|
}
|
|
1668
1732
|
if (!normalizedSessionId)
|
|
1669
1733
|
return "";
|
|
1670
|
-
const canonicalState = await
|
|
1734
|
+
const canonicalState = await readVisibleSkillActiveStateForStateDir(stateDir, normalizedSessionId);
|
|
1671
1735
|
const visibleEntries = canonicalState ? listActiveSkills(canonicalState) : [];
|
|
1672
1736
|
const deepInterview = visibleEntries.find((entry) => (entry.skill === "deep-interview"
|
|
1673
1737
|
&& matchesSkillStopContext(entry, canonicalState ?? {}, normalizedSessionId, threadId)));
|
|
1674
1738
|
if (!deepInterview)
|
|
1675
1739
|
return "";
|
|
1676
|
-
const modeState = await readStopSessionPinnedState("deep-interview-state.json", cwd, normalizedSessionId);
|
|
1740
|
+
const modeState = await readStopSessionPinnedState("deep-interview-state.json", cwd, normalizedSessionId, stateDir);
|
|
1677
1741
|
if (!modeState || modeState.active !== true)
|
|
1678
1742
|
return "";
|
|
1679
1743
|
const modePhase = safeString(modeState.current_phase).trim().toLowerCase();
|
|
1680
1744
|
return modePhase === "intent-first" ? "planning" : "";
|
|
1681
1745
|
}
|
|
1682
|
-
async function buildDeepInterviewQuestionStopOutput(cwd, sessionId, threadId) {
|
|
1746
|
+
async function buildDeepInterviewQuestionStopOutput(cwd, stateDir, sessionId, threadId) {
|
|
1683
1747
|
await reconcileDeepInterviewQuestionEnforcementFromAnsweredRecords(cwd, sessionId);
|
|
1684
|
-
const modeState = await readStopSessionPinnedState("deep-interview-state.json", cwd, sessionId);
|
|
1748
|
+
const modeState = await readStopSessionPinnedState("deep-interview-state.json", cwd, sessionId, stateDir);
|
|
1685
1749
|
if (!modeState)
|
|
1686
1750
|
return null;
|
|
1687
1751
|
const questionEnforcement = safeObject(modeState.question_enforcement);
|
|
@@ -1692,7 +1756,7 @@ async function buildDeepInterviewQuestionStopOutput(cwd, sessionId, threadId) {
|
|
|
1692
1756
|
if (TERMINAL_MODE_PHASES.has(phase.toLowerCase()) || phase === "completing") {
|
|
1693
1757
|
return null;
|
|
1694
1758
|
}
|
|
1695
|
-
const canonicalState = await
|
|
1759
|
+
const canonicalState = await readVisibleSkillActiveStateForStateDir(stateDir, sessionId);
|
|
1696
1760
|
if (canonicalState) {
|
|
1697
1761
|
const blocker = listActiveSkills(canonicalState).find((entry) => (entry.skill === "deep-interview"
|
|
1698
1762
|
&& matchesSkillStopContext(entry, canonicalState, sessionId, threadId)));
|
|
@@ -1833,8 +1897,8 @@ async function findCanonicalActiveTeamForSession(cwd, sessionId) {
|
|
|
1833
1897
|
}
|
|
1834
1898
|
return null;
|
|
1835
1899
|
}
|
|
1836
|
-
async function resolveActiveTeamNameForStop(cwd, sessionId) {
|
|
1837
|
-
const directState = await readTeamModeStateForStop(cwd, sessionId);
|
|
1900
|
+
async function resolveActiveTeamNameForStop(cwd, stateDir, sessionId) {
|
|
1901
|
+
const directState = await readTeamModeStateForStop(cwd, stateDir, sessionId);
|
|
1838
1902
|
const directTeamName = safeString(directState?.team_name).trim();
|
|
1839
1903
|
if (directState?.active === true && directTeamName)
|
|
1840
1904
|
return directTeamName;
|
|
@@ -1844,11 +1908,11 @@ async function resolveActiveTeamNameForStop(cwd, sessionId) {
|
|
|
1844
1908
|
async function maybeBuildReleaseReadinessFinalizeStopOutput(payload, cwd, stateDir, sessionId) {
|
|
1845
1909
|
if (!sessionId)
|
|
1846
1910
|
return { matched: false, output: null };
|
|
1847
|
-
const teamName = await resolveActiveTeamNameForStop(cwd, sessionId);
|
|
1911
|
+
const teamName = await resolveActiveTeamNameForStop(cwd, stateDir, sessionId);
|
|
1848
1912
|
if (!teamName)
|
|
1849
1913
|
return { matched: false, output: null };
|
|
1850
1914
|
const explicitReleaseReadinessContext = hasReleaseReadinessMode(payload)
|
|
1851
|
-
|| await hasReleaseReadinessStopMarker(cwd, sessionId, teamName);
|
|
1915
|
+
|| await hasReleaseReadinessStopMarker(cwd, stateDir, sessionId, teamName);
|
|
1852
1916
|
if (!explicitReleaseReadinessContext) {
|
|
1853
1917
|
return { matched: false, output: null };
|
|
1854
1918
|
}
|
|
@@ -1870,8 +1934,8 @@ async function maybeBuildReleaseReadinessFinalizeStopOutput(payload, cwd, stateD
|
|
|
1870
1934
|
}, sessionId);
|
|
1871
1935
|
return { matched: true, output };
|
|
1872
1936
|
}
|
|
1873
|
-
async function buildSkillStopOutput(cwd, sessionId, threadId) {
|
|
1874
|
-
const blocker = await readBlockingSkillForStop(cwd, sessionId, threadId);
|
|
1937
|
+
async function buildSkillStopOutput(cwd, stateDir, sessionId, threadId) {
|
|
1938
|
+
const blocker = await readBlockingSkillForStop(cwd, stateDir, sessionId, threadId);
|
|
1875
1939
|
if (!blocker)
|
|
1876
1940
|
return null;
|
|
1877
1941
|
const subagentSummary = await readSubagentSessionSummary(cwd, sessionId).catch(() => null);
|
|
@@ -1980,18 +2044,33 @@ async function buildStopHookOutput(payload, cwd, stateDir, options = {}) {
|
|
|
1980
2044
|
const canonicalSessionId = await resolveInternalSessionIdForPayload(cwd, sessionId);
|
|
1981
2045
|
const threadId = readPayloadThreadId(payload);
|
|
1982
2046
|
if (canonicalSessionId) {
|
|
1983
|
-
await reconcileStaleRootSkillActiveStateForStop(cwd, canonicalSessionId);
|
|
2047
|
+
await reconcileStaleRootSkillActiveStateForStop(cwd, stateDir, canonicalSessionId);
|
|
1984
2048
|
}
|
|
1985
2049
|
const execFollowupOutput = await buildExecFollowupStopOutput(cwd, canonicalSessionId);
|
|
1986
2050
|
if (execFollowupOutput)
|
|
1987
2051
|
return execFollowupOutput;
|
|
2052
|
+
const ralphOwnerContext = {
|
|
2053
|
+
payloadSessionId: sessionId,
|
|
2054
|
+
threadId,
|
|
2055
|
+
tmuxPaneId: safeString(process.env.TMUX_PANE).trim(),
|
|
2056
|
+
};
|
|
2057
|
+
const ralphCompletionAuditBlock = options.skipRalphStopBlock === true
|
|
2058
|
+
? null
|
|
2059
|
+
: await readRalphCompletionAuditBlockState(cwd, stateDir, canonicalSessionId, ralphOwnerContext);
|
|
2060
|
+
if (ralphCompletionAuditBlock) {
|
|
2061
|
+
await reopenRalphCompletionAuditBlock(ralphCompletionAuditBlock);
|
|
2062
|
+
const blockingPath = formatStopStatePath(cwd, ralphCompletionAuditBlock.path);
|
|
2063
|
+
const systemMessage = `OMX Ralph completion audit is missing required evidence (${ralphCompletionAuditBlock.reason}; state: ${blockingPath}); continue verification, record a prompt-to-artifact checklist plus verification evidence, and do not report complete yet.`;
|
|
2064
|
+
return await returnPersistentStopBlock(payload, stateDir, "ralph-completion-audit-stop", `${blockingPath}|${ralphCompletionAuditBlock.reason}`, {
|
|
2065
|
+
decision: "block",
|
|
2066
|
+
reason: systemMessage,
|
|
2067
|
+
stopReason: `ralph_completion_audit_${ralphCompletionAuditBlock.reason}`,
|
|
2068
|
+
systemMessage,
|
|
2069
|
+
}, canonicalSessionId, { allowRepeatDuringStopHook: true });
|
|
2070
|
+
}
|
|
1988
2071
|
const ralphState = options.skipRalphStopBlock === true
|
|
1989
2072
|
? null
|
|
1990
|
-
: await readActiveRalphState(stateDir, canonicalSessionId,
|
|
1991
|
-
payloadSessionId: sessionId,
|
|
1992
|
-
threadId,
|
|
1993
|
-
tmuxPaneId: safeString(process.env.TMUX_PANE).trim(),
|
|
1994
|
-
});
|
|
2073
|
+
: await readActiveRalphState(cwd, stateDir, canonicalSessionId, ralphOwnerContext);
|
|
1995
2074
|
if (!ralphState) {
|
|
1996
2075
|
const autoresearchState = await readActiveAutoresearchState(cwd, canonicalSessionId);
|
|
1997
2076
|
if (autoresearchState) {
|
|
@@ -2044,7 +2123,7 @@ async function buildStopHookOutput(payload, cwd, stateDir, options = {}) {
|
|
|
2044
2123
|
return await returnPersistentStopBlock(payload, stateDir, "team-stop", safeString(teamOutput.stopReason), teamOutput, canonicalSessionId);
|
|
2045
2124
|
}
|
|
2046
2125
|
if (canonicalSessionId) {
|
|
2047
|
-
const deepInterviewQuestionOutput = await buildDeepInterviewQuestionStopOutput(cwd, canonicalSessionId, threadId);
|
|
2126
|
+
const deepInterviewQuestionOutput = await buildDeepInterviewQuestionStopOutput(cwd, stateDir, canonicalSessionId, threadId);
|
|
2048
2127
|
if (deepInterviewQuestionOutput) {
|
|
2049
2128
|
return await returnPersistentStopBlock(payload, stateDir, "deep-interview-question-stop", deepInterviewQuestionOutput.obligationId, deepInterviewQuestionOutput.output, canonicalSessionId);
|
|
2050
2129
|
}
|
|
@@ -2057,7 +2136,7 @@ async function buildStopHookOutput(payload, cwd, stateDir, options = {}) {
|
|
|
2057
2136
|
if (repeatedCanonicalTeamOutput)
|
|
2058
2137
|
return repeatedCanonicalTeamOutput;
|
|
2059
2138
|
}
|
|
2060
|
-
const skillOutput = await buildSkillStopOutput(cwd, canonicalSessionId, threadId);
|
|
2139
|
+
const skillOutput = await buildSkillStopOutput(cwd, stateDir, canonicalSessionId, threadId);
|
|
2061
2140
|
if (skillOutput) {
|
|
2062
2141
|
return await returnPersistentStopBlock(payload, stateDir, "skill-stop", safeString(skillOutput.stopReason), skillOutput, canonicalSessionId);
|
|
2063
2142
|
}
|
|
@@ -2068,7 +2147,7 @@ async function buildStopHookOutput(payload, cwd, stateDir, options = {}) {
|
|
|
2068
2147
|
return await returnPersistentStopBlock(payload, stateDir, "goal-workflow-reconciliation-stop", safeString(goalWorkflowStopOutput.stopReason), goalWorkflowStopOutput, canonicalSessionId, { allowRepeatDuringStopHook: true });
|
|
2069
2148
|
}
|
|
2070
2149
|
const autoNudgeConfig = await loadAutoNudgeConfig();
|
|
2071
|
-
const autoNudgePhase = await readStopAutoNudgePhase(cwd, canonicalSessionId, threadId);
|
|
2150
|
+
const autoNudgePhase = await readStopAutoNudgePhase(cwd, stateDir, canonicalSessionId, threadId);
|
|
2072
2151
|
if (autoNudgeConfig.enabled
|
|
2073
2152
|
&& detectNativeStopStallPattern(lastAssistantMessage, autoNudgeConfig.patterns, autoNudgePhase)) {
|
|
2074
2153
|
const effectiveResponse = resolveEffectiveAutoNudgeResponse(autoNudgeConfig.response);
|
|
@@ -2106,7 +2185,9 @@ async function buildStopHookOutput(payload, cwd, stateDir, options = {}) {
|
|
|
2106
2185
|
export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
2107
2186
|
const hookEventName = readHookEventName(payload);
|
|
2108
2187
|
const cwd = options.cwd ?? (safeString(payload.cwd).trim() || process.cwd());
|
|
2109
|
-
|
|
2188
|
+
// Native hooks must use the same authoritative runtime state root as HUD/MCP
|
|
2189
|
+
// when boxed/team roots are active; do not bypass it with cwd/.omx/state.
|
|
2190
|
+
const stateDir = getBaseStateDir(cwd);
|
|
2110
2191
|
await mkdir(stateDir, { recursive: true });
|
|
2111
2192
|
const omxEventName = mapCodexHookEventToOmxEvent(hookEventName);
|
|
2112
2193
|
let skillState = null;
|
|
@@ -2176,6 +2257,7 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
2176
2257
|
if (prompt && !isSubagentPromptSubmit) {
|
|
2177
2258
|
skillState = buildNativeOutsideTmuxTeamPromptBlockState(prompt, cwd, payload, sessionIdForState, threadId || undefined, turnId || undefined) ?? await recordSkillActivation({
|
|
2178
2259
|
stateDir,
|
|
2260
|
+
sourceCwd: cwd,
|
|
2179
2261
|
text: prompt,
|
|
2180
2262
|
sessionId: sessionIdForState,
|
|
2181
2263
|
threadId,
|
|
@@ -2282,26 +2364,10 @@ export async function dispatchCodexNativeHook(payload, options = {}) {
|
|
|
2282
2364
|
});
|
|
2283
2365
|
}
|
|
2284
2366
|
if (hookEventName === "PreCompact") {
|
|
2285
|
-
|
|
2286
|
-
|
|
2287
|
-
|
|
2288
|
-
|
|
2289
|
-
hookEventName,
|
|
2290
|
-
additionalContext: compactContext.additionalContext,
|
|
2291
|
-
},
|
|
2292
|
-
};
|
|
2293
|
-
}
|
|
2294
|
-
}
|
|
2295
|
-
else if (hookEventName === "PostCompact") {
|
|
2296
|
-
const compactContext = buildWikiPostCompactContext({ cwd });
|
|
2297
|
-
if (compactContext.additionalContext) {
|
|
2298
|
-
outputJson = {
|
|
2299
|
-
hookSpecificOutput: {
|
|
2300
|
-
hookEventName,
|
|
2301
|
-
additionalContext: compactContext.additionalContext,
|
|
2302
|
-
},
|
|
2303
|
-
};
|
|
2304
|
-
}
|
|
2367
|
+
// Codex native PreCompact currently accepts only the common continuation fields.
|
|
2368
|
+
// Keep the OMX lifecycle dispatch above, but do not emit `hookSpecificOutput`
|
|
2369
|
+
// unless Codex defines a supported PreCompact output contract.
|
|
2370
|
+
buildWikiPreCompactContext({ cwd });
|
|
2305
2371
|
}
|
|
2306
2372
|
else if ((hookEventName === "SessionStart" && !skipCanonicalSessionStartContext) || hookEventName === "UserPromptSubmit") {
|
|
2307
2373
|
const additionalContext = hookEventName === "SessionStart"
|