oh-my-codex 0.12.4 → 0.12.6
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 +27 -3
- package/dist/cli/__tests__/ask.test.js +26 -0
- package/dist/cli/__tests__/ask.test.js.map +1 -1
- package/dist/cli/__tests__/doctor-warning-copy.test.js +28 -0
- package/dist/cli/__tests__/doctor-warning-copy.test.js.map +1 -1
- package/dist/cli/__tests__/explore.test.js +95 -8
- package/dist/cli/__tests__/explore.test.js.map +1 -1
- package/dist/cli/__tests__/index.test.js +102 -4
- package/dist/cli/__tests__/index.test.js.map +1 -1
- package/dist/cli/__tests__/launch-fallback.test.js +169 -0
- package/dist/cli/__tests__/launch-fallback.test.js.map +1 -1
- package/dist/cli/__tests__/mcp-parity.test.js +31 -0
- package/dist/cli/__tests__/mcp-parity.test.js.map +1 -1
- package/dist/cli/__tests__/setup-agents-overwrite.test.js +66 -2
- package/dist/cli/__tests__/setup-agents-overwrite.test.js.map +1 -1
- package/dist/cli/__tests__/setup-refresh.test.js +51 -1
- package/dist/cli/__tests__/setup-refresh.test.js.map +1 -1
- package/dist/cli/__tests__/team.test.js +148 -3
- package/dist/cli/__tests__/team.test.js.map +1 -1
- package/dist/cli/__tests__/uninstall.test.js +14 -1
- package/dist/cli/__tests__/uninstall.test.js.map +1 -1
- package/dist/cli/cleanup.js +1 -1
- package/dist/cli/cleanup.js.map +1 -1
- package/dist/cli/constants.d.ts +1 -0
- package/dist/cli/constants.d.ts.map +1 -1
- package/dist/cli/constants.js +1 -0
- package/dist/cli/constants.js.map +1 -1
- package/dist/cli/doctor.d.ts.map +1 -1
- package/dist/cli/doctor.js +15 -0
- package/dist/cli/doctor.js.map +1 -1
- package/dist/cli/explore.d.ts +1 -0
- package/dist/cli/explore.d.ts.map +1 -1
- package/dist/cli/explore.js +49 -1
- package/dist/cli/explore.js.map +1 -1
- package/dist/cli/index.d.ts +2 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +127 -14
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/mcp-parity.d.ts +1 -1
- package/dist/cli/mcp-parity.d.ts.map +1 -1
- package/dist/cli/mcp-parity.js +24 -0
- package/dist/cli/mcp-parity.js.map +1 -1
- package/dist/cli/setup.d.ts.map +1 -1
- package/dist/cli/setup.js +17 -5
- package/dist/cli/setup.js.map +1 -1
- package/dist/cli/team.d.ts.map +1 -1
- package/dist/cli/team.js +80 -6
- package/dist/cli/team.js.map +1 -1
- package/dist/cli/uninstall.d.ts.map +1 -1
- package/dist/cli/uninstall.js +1 -0
- package/dist/cli/uninstall.js.map +1 -1
- package/dist/config/__tests__/generator-idempotent.test.js +60 -0
- package/dist/config/__tests__/generator-idempotent.test.js.map +1 -1
- package/dist/config/__tests__/mcp-registry.test.js +61 -0
- package/dist/config/__tests__/mcp-registry.test.js.map +1 -1
- package/dist/config/__tests__/wiki-config-contract.test.d.ts +2 -0
- package/dist/config/__tests__/wiki-config-contract.test.d.ts.map +1 -0
- package/dist/config/__tests__/wiki-config-contract.test.js +19 -0
- package/dist/config/__tests__/wiki-config-contract.test.js.map +1 -0
- package/dist/config/generator.d.ts +1 -0
- package/dist/config/generator.d.ts.map +1 -1
- package/dist/config/generator.js +88 -3
- package/dist/config/generator.js.map +1 -1
- package/dist/config/mcp-registry.d.ts +2 -0
- package/dist/config/mcp-registry.d.ts.map +1 -1
- package/dist/config/mcp-registry.js +12 -0
- package/dist/config/mcp-registry.js.map +1 -1
- package/dist/hooks/__tests__/agents-overlay.test.js +39 -0
- package/dist/hooks/__tests__/agents-overlay.test.js.map +1 -1
- package/dist/hooks/__tests__/keyword-detector.test.js +297 -4
- package/dist/hooks/__tests__/keyword-detector.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js +392 -22
- package/dist/hooks/__tests__/notify-fallback-watcher.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js +166 -67
- package/dist/hooks/__tests__/notify-hook-auto-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js +112 -2
- package/dist/hooks/__tests__/notify-hook-managed-tmux.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-modules.test.js +52 -12
- package/dist/hooks/__tests__/notify-hook-modules.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.d.ts +2 -3
- package/dist/hooks/__tests__/notify-hook-regression-205.test.d.ts.map +1 -1
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js +18 -23
- package/dist/hooks/__tests__/notify-hook-regression-205.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js +33 -0
- package/dist/hooks/__tests__/notify-hook-session-scope.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js +176 -1
- package/dist/hooks/__tests__/notify-hook-team-dispatch.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js +355 -7
- package/dist/hooks/__tests__/notify-hook-team-leader-nudge.test.js.map +1 -1
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js +90 -2
- package/dist/hooks/__tests__/notify-hook-tmux-heal.test.js.map +1 -1
- package/dist/hooks/__tests__/session.test.js +142 -2
- package/dist/hooks/__tests__/session.test.js.map +1 -1
- package/dist/hooks/__tests__/wiki-docs-contract.test.d.ts +2 -0
- package/dist/hooks/__tests__/wiki-docs-contract.test.d.ts.map +1 -0
- package/dist/hooks/__tests__/wiki-docs-contract.test.js +34 -0
- package/dist/hooks/__tests__/wiki-docs-contract.test.js.map +1 -0
- package/dist/hooks/agents-overlay.d.ts.map +1 -1
- package/dist/hooks/agents-overlay.js +0 -1
- package/dist/hooks/agents-overlay.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js +32 -0
- package/dist/hooks/extensibility/__tests__/dispatcher.test.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/runtime.test.js +31 -0
- package/dist/hooks/extensibility/__tests__/runtime.test.js.map +1 -1
- package/dist/hooks/extensibility/__tests__/sdk.test.js +33 -3
- package/dist/hooks/extensibility/__tests__/sdk.test.js.map +1 -1
- package/dist/hooks/extensibility/dispatcher.d.ts.map +1 -1
- package/dist/hooks/extensibility/dispatcher.js +41 -0
- package/dist/hooks/extensibility/dispatcher.js.map +1 -1
- package/dist/hooks/extensibility/sdk/runtime-state.d.ts.map +1 -1
- package/dist/hooks/extensibility/sdk/runtime-state.js +7 -1
- package/dist/hooks/extensibility/sdk/runtime-state.js.map +1 -1
- package/dist/hooks/extensibility/types.d.ts +1 -0
- package/dist/hooks/extensibility/types.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.d.ts +6 -1
- package/dist/hooks/keyword-detector.d.ts.map +1 -1
- package/dist/hooks/keyword-detector.js +207 -10
- package/dist/hooks/keyword-detector.js.map +1 -1
- package/dist/hooks/keyword-registry.d.ts.map +1 -1
- package/dist/hooks/keyword-registry.js +3 -0
- package/dist/hooks/keyword-registry.js.map +1 -1
- package/dist/hooks/session.d.ts +14 -2
- package/dist/hooks/session.d.ts.map +1 -1
- package/dist/hooks/session.js +120 -16
- package/dist/hooks/session.js.map +1 -1
- package/dist/hud/__tests__/state.test.js +111 -2
- package/dist/hud/__tests__/state.test.js.map +1 -1
- package/dist/hud/state.d.ts.map +1 -1
- package/dist/hud/state.js +18 -21
- package/dist/hud/state.js.map +1 -1
- package/dist/mcp/__tests__/bootstrap.test.js +88 -1
- package/dist/mcp/__tests__/bootstrap.test.js.map +1 -1
- package/dist/mcp/__tests__/server-lifecycle.test.js +3 -0
- package/dist/mcp/__tests__/server-lifecycle.test.js.map +1 -1
- package/dist/mcp/__tests__/state-paths.test.js +30 -2
- package/dist/mcp/__tests__/state-paths.test.js.map +1 -1
- package/dist/mcp/__tests__/state-server.test.js +415 -0
- package/dist/mcp/__tests__/state-server.test.js.map +1 -1
- package/dist/mcp/__tests__/wiki-server.test.d.ts +2 -0
- package/dist/mcp/__tests__/wiki-server.test.d.ts.map +1 -0
- package/dist/mcp/__tests__/wiki-server.test.js +30 -0
- package/dist/mcp/__tests__/wiki-server.test.js.map +1 -0
- package/dist/mcp/bootstrap.d.ts +19 -1
- package/dist/mcp/bootstrap.d.ts.map +1 -1
- package/dist/mcp/bootstrap.js +185 -0
- package/dist/mcp/bootstrap.js.map +1 -1
- package/dist/mcp/state-paths.d.ts +5 -0
- package/dist/mcp/state-paths.d.ts.map +1 -1
- package/dist/mcp/state-paths.js +41 -11
- package/dist/mcp/state-paths.js.map +1 -1
- package/dist/mcp/state-server.d.ts +4 -4
- package/dist/mcp/state-server.d.ts.map +1 -1
- package/dist/mcp/state-server.js +49 -2
- package/dist/mcp/state-server.js.map +1 -1
- package/dist/mcp/wiki-server.d.ts +181 -0
- package/dist/mcp/wiki-server.d.ts.map +1 -0
- package/dist/mcp/wiki-server.js +235 -0
- package/dist/mcp/wiki-server.js.map +1 -0
- package/dist/modes/__tests__/base-autoresearch-contract.test.js +74 -2
- package/dist/modes/__tests__/base-autoresearch-contract.test.js.map +1 -1
- package/dist/modes/__tests__/base-multi-state-compat.test.d.ts +2 -0
- package/dist/modes/__tests__/base-multi-state-compat.test.d.ts.map +1 -0
- package/dist/modes/__tests__/base-multi-state-compat.test.js +38 -0
- package/dist/modes/__tests__/base-multi-state-compat.test.js.map +1 -0
- package/dist/modes/__tests__/base-tmux-pane.test.js +1 -1
- package/dist/modes/__tests__/base-tmux-pane.test.js.map +1 -1
- package/dist/modes/base.d.ts +2 -1
- package/dist/modes/base.d.ts.map +1 -1
- package/dist/modes/base.js +55 -31
- package/dist/modes/base.js.map +1 -1
- package/dist/notifications/__tests__/formatter.test.js +11 -0
- package/dist/notifications/__tests__/formatter.test.js.map +1 -1
- package/dist/notifications/__tests__/idle-cooldown.test.js +32 -1
- package/dist/notifications/__tests__/idle-cooldown.test.js.map +1 -1
- package/dist/notifications/__tests__/index.test.d.ts +2 -0
- package/dist/notifications/__tests__/index.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/index.test.js +113 -0
- package/dist/notifications/__tests__/index.test.js.map +1 -0
- package/dist/notifications/__tests__/lifecycle-dedupe.test.d.ts +2 -0
- package/dist/notifications/__tests__/lifecycle-dedupe.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/lifecycle-dedupe.test.js +86 -0
- package/dist/notifications/__tests__/lifecycle-dedupe.test.js.map +1 -0
- package/dist/notifications/__tests__/reply-listener.test.js +174 -0
- package/dist/notifications/__tests__/reply-listener.test.js.map +1 -1
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.d.ts +2 -0
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js +93 -0
- package/dist/notifications/__tests__/session-idle-tail-dedupe.test.js.map +1 -0
- package/dist/notifications/__tests__/session-registry.test.js +48 -1
- package/dist/notifications/__tests__/session-registry.test.js.map +1 -1
- package/dist/notifications/__tests__/session-status.test.d.ts +2 -0
- package/dist/notifications/__tests__/session-status.test.d.ts.map +1 -0
- package/dist/notifications/__tests__/session-status.test.js +159 -0
- package/dist/notifications/__tests__/session-status.test.js.map +1 -0
- package/dist/notifications/__tests__/tmux.test.js +58 -1
- package/dist/notifications/__tests__/tmux.test.js.map +1 -1
- package/dist/notifications/idle-cooldown.d.ts +11 -0
- package/dist/notifications/idle-cooldown.d.ts.map +1 -1
- package/dist/notifications/idle-cooldown.js +42 -8
- package/dist/notifications/idle-cooldown.js.map +1 -1
- package/dist/notifications/index.d.ts +1 -1
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +41 -8
- package/dist/notifications/index.js.map +1 -1
- package/dist/notifications/lifecycle-dedupe.d.ts +8 -0
- package/dist/notifications/lifecycle-dedupe.d.ts.map +1 -0
- package/dist/notifications/lifecycle-dedupe.js +112 -0
- package/dist/notifications/lifecycle-dedupe.js.map +1 -0
- package/dist/notifications/reply-listener.d.ts +10 -1
- package/dist/notifications/reply-listener.d.ts.map +1 -1
- package/dist/notifications/reply-listener.js +49 -11
- package/dist/notifications/reply-listener.js.map +1 -1
- package/dist/notifications/session-registry.d.ts.map +1 -1
- package/dist/notifications/session-registry.js +7 -1
- package/dist/notifications/session-registry.js.map +1 -1
- package/dist/notifications/session-status.d.ts +23 -0
- package/dist/notifications/session-status.d.ts.map +1 -0
- package/dist/notifications/session-status.js +187 -0
- package/dist/notifications/session-status.js.map +1 -0
- package/dist/notifications/tmux.d.ts +10 -0
- package/dist/notifications/tmux.d.ts.map +1 -1
- package/dist/notifications/tmux.js +59 -5
- package/dist/notifications/tmux.js.map +1 -1
- package/dist/notifications/types.d.ts +2 -0
- package/dist/notifications/types.d.ts.map +1 -1
- package/dist/openclaw/__tests__/index.test.js +84 -0
- package/dist/openclaw/__tests__/index.test.js.map +1 -1
- package/dist/openclaw/index.d.ts.map +1 -1
- package/dist/openclaw/index.js +7 -14
- package/dist/openclaw/index.js.map +1 -1
- package/dist/openclaw/types.d.ts +2 -2
- package/dist/openclaw/types.d.ts.map +1 -1
- package/dist/scripts/__tests__/codex-native-hook.test.js +692 -40
- package/dist/scripts/__tests__/codex-native-hook.test.js.map +1 -1
- package/dist/scripts/__tests__/hook-derived-watcher.test.d.ts +2 -0
- package/dist/scripts/__tests__/hook-derived-watcher.test.d.ts.map +1 -0
- package/dist/scripts/__tests__/hook-derived-watcher.test.js +87 -0
- package/dist/scripts/__tests__/hook-derived-watcher.test.js.map +1 -0
- package/dist/scripts/codex-native-hook.d.ts.map +1 -1
- package/dist/scripts/codex-native-hook.js +309 -77
- package/dist/scripts/codex-native-hook.js.map +1 -1
- package/dist/scripts/hook-derived-watcher.js +43 -1
- package/dist/scripts/hook-derived-watcher.js.map +1 -1
- package/dist/scripts/notify-fallback-watcher.js +95 -21
- package/dist/scripts/notify-fallback-watcher.js.map +1 -1
- package/dist/scripts/notify-hook/active-team.d.ts +9 -0
- package/dist/scripts/notify-hook/active-team.d.ts.map +1 -0
- package/dist/scripts/notify-hook/active-team.js +44 -0
- package/dist/scripts/notify-hook/active-team.js.map +1 -0
- package/dist/scripts/notify-hook/auto-nudge.d.ts +5 -3
- package/dist/scripts/notify-hook/auto-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/auto-nudge.js +121 -78
- package/dist/scripts/notify-hook/auto-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.d.ts.map +1 -1
- package/dist/scripts/notify-hook/managed-tmux.js +18 -4
- package/dist/scripts/notify-hook/managed-tmux.js.map +1 -1
- package/dist/scripts/notify-hook/operational-events.d.ts.map +1 -1
- package/dist/scripts/notify-hook/operational-events.js +21 -0
- package/dist/scripts/notify-hook/operational-events.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 +3 -2
- package/dist/scripts/notify-hook/ralph-session-resume.js.map +1 -1
- package/dist/scripts/notify-hook/state-io.d.ts +10 -1
- package/dist/scripts/notify-hook/state-io.d.ts.map +1 -1
- package/dist/scripts/notify-hook/state-io.js +56 -12
- package/dist/scripts/notify-hook/state-io.js.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-dispatch.js +305 -167
- package/dist/scripts/notify-hook/team-dispatch.js.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.d.ts.map +1 -1
- package/dist/scripts/notify-hook/team-leader-nudge.js +87 -15
- package/dist/scripts/notify-hook/team-leader-nudge.js.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.d.ts.map +1 -1
- package/dist/scripts/notify-hook/tmux-injection.js +11 -2
- package/dist/scripts/notify-hook/tmux-injection.js.map +1 -1
- package/dist/scripts/notify-hook.js +26 -16
- package/dist/scripts/notify-hook.js.map +1 -1
- package/dist/scripts/run-provider-advisor.js +20 -2
- package/dist/scripts/run-provider-advisor.js.map +1 -1
- package/dist/scripts/smoke-packed-install.d.ts +1 -8
- package/dist/scripts/smoke-packed-install.d.ts.map +1 -1
- package/dist/scripts/smoke-packed-install.js +12 -68
- package/dist/scripts/smoke-packed-install.js.map +1 -1
- package/dist/state/__tests__/operations.test.js +113 -0
- package/dist/state/__tests__/operations.test.js.map +1 -1
- package/dist/state/__tests__/skill-active.test.js +35 -0
- package/dist/state/__tests__/skill-active.test.js.map +1 -1
- package/dist/state/__tests__/workflow-transition.test.d.ts +2 -0
- package/dist/state/__tests__/workflow-transition.test.d.ts.map +1 -0
- package/dist/state/__tests__/workflow-transition.test.js +56 -0
- package/dist/state/__tests__/workflow-transition.test.js.map +1 -0
- package/dist/state/operations.d.ts +1 -1
- package/dist/state/operations.d.ts.map +1 -1
- package/dist/state/operations.js +88 -2
- package/dist/state/operations.js.map +1 -1
- package/dist/state/skill-active.d.ts +2 -2
- package/dist/state/skill-active.d.ts.map +1 -1
- package/dist/state/skill-active.js +119 -33
- package/dist/state/skill-active.js.map +1 -1
- package/dist/state/workflow-transition-reconcile.d.ts +15 -0
- package/dist/state/workflow-transition-reconcile.d.ts.map +1 -0
- package/dist/state/workflow-transition-reconcile.js +100 -0
- package/dist/state/workflow-transition-reconcile.js.map +1 -0
- package/dist/state/workflow-transition.d.ts +22 -0
- package/dist/state/workflow-transition.d.ts.map +1 -0
- package/dist/state/workflow-transition.js +188 -0
- package/dist/state/workflow-transition.js.map +1 -0
- package/dist/team/__tests__/api-interop.test.js +90 -0
- package/dist/team/__tests__/api-interop.test.js.map +1 -1
- package/dist/team/__tests__/current-task-baseline.test.d.ts +2 -0
- package/dist/team/__tests__/current-task-baseline.test.d.ts.map +1 -0
- package/dist/team/__tests__/current-task-baseline.test.js +87 -0
- package/dist/team/__tests__/current-task-baseline.test.js.map +1 -0
- package/dist/team/__tests__/hardening-e2e.test.js +17 -0
- package/dist/team/__tests__/hardening-e2e.test.js.map +1 -1
- package/dist/team/__tests__/runtime.test.js +673 -65
- package/dist/team/__tests__/runtime.test.js.map +1 -1
- package/dist/team/__tests__/shutdown-fallback.test.js +11 -1
- package/dist/team/__tests__/shutdown-fallback.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +447 -4
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/api-interop.d.ts.map +1 -1
- package/dist/team/api-interop.js +10 -1
- package/dist/team/api-interop.js.map +1 -1
- package/dist/team/current-task-baseline.d.ts +32 -0
- package/dist/team/current-task-baseline.d.ts.map +1 -0
- package/dist/team/current-task-baseline.js +85 -0
- package/dist/team/current-task-baseline.js.map +1 -0
- package/dist/team/delivery-log.d.ts +1 -1
- package/dist/team/delivery-log.d.ts.map +1 -1
- package/dist/team/delivery-log.js.map +1 -1
- package/dist/team/leader-activity.d.ts +1 -0
- package/dist/team/leader-activity.d.ts.map +1 -1
- package/dist/team/leader-activity.js +4 -2
- package/dist/team/leader-activity.js.map +1 -1
- package/dist/team/progress-evidence.d.ts +2 -0
- package/dist/team/progress-evidence.d.ts.map +1 -0
- package/dist/team/progress-evidence.js +77 -0
- package/dist/team/progress-evidence.js.map +1 -0
- package/dist/team/runtime.d.ts.map +1 -1
- package/dist/team/runtime.js +269 -64
- package/dist/team/runtime.js.map +1 -1
- package/dist/team/scaling.d.ts.map +1 -1
- package/dist/team/scaling.js +1 -1
- package/dist/team/scaling.js.map +1 -1
- package/dist/team/state.d.ts.map +1 -1
- package/dist/team/state.js +2 -13
- package/dist/team/state.js.map +1 -1
- package/dist/team/tmux-session.d.ts +12 -3
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +174 -20
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/worktree.d.ts +6 -1
- package/dist/team/worktree.d.ts.map +1 -1
- package/dist/team/worktree.js +28 -4
- package/dist/team/worktree.js.map +1 -1
- package/dist/utils/__tests__/agents-md.test.js +21 -1
- package/dist/utils/__tests__/agents-md.test.js.map +1 -1
- package/dist/utils/__tests__/repo-deps.test.d.ts +2 -0
- package/dist/utils/__tests__/repo-deps.test.d.ts.map +1 -0
- package/dist/utils/__tests__/repo-deps.test.js +71 -0
- package/dist/utils/__tests__/repo-deps.test.js.map +1 -0
- package/dist/utils/agents-md.d.ts +1 -0
- package/dist/utils/agents-md.d.ts.map +1 -1
- package/dist/utils/agents-md.js +7 -3
- package/dist/utils/agents-md.js.map +1 -1
- package/dist/utils/paths.d.ts +4 -0
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +20 -0
- package/dist/utils/paths.js.map +1 -1
- package/dist/utils/repo-deps.d.ts +20 -0
- package/dist/utils/repo-deps.d.ts.map +1 -0
- package/dist/utils/repo-deps.js +78 -0
- package/dist/utils/repo-deps.js.map +1 -0
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.d.ts +2 -0
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.d.ts.map +1 -0
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js +54 -0
- package/dist/verification/__tests__/dev-merge-issue-close-workflow.test.js.map +1 -0
- package/dist/wiki/__tests__/cjk-tokenize.test.d.ts +12 -0
- package/dist/wiki/__tests__/cjk-tokenize.test.d.ts.map +1 -0
- package/dist/wiki/__tests__/cjk-tokenize.test.js +139 -0
- package/dist/wiki/__tests__/cjk-tokenize.test.js.map +1 -0
- package/dist/wiki/__tests__/crlf-parse.test.d.ts +2 -0
- package/dist/wiki/__tests__/crlf-parse.test.d.ts.map +1 -0
- package/dist/wiki/__tests__/crlf-parse.test.js +24 -0
- package/dist/wiki/__tests__/crlf-parse.test.js.map +1 -0
- package/dist/wiki/__tests__/escape-newline.test.d.ts +2 -0
- package/dist/wiki/__tests__/escape-newline.test.d.ts.map +1 -0
- package/dist/wiki/__tests__/escape-newline.test.js +45 -0
- package/dist/wiki/__tests__/escape-newline.test.js.map +1 -0
- package/dist/wiki/__tests__/ingest.test.d.ts +5 -0
- package/dist/wiki/__tests__/ingest.test.d.ts.map +1 -0
- package/dist/wiki/__tests__/ingest.test.js +181 -0
- package/dist/wiki/__tests__/ingest.test.js.map +1 -0
- package/dist/wiki/__tests__/lint.test.d.ts +5 -0
- package/dist/wiki/__tests__/lint.test.d.ts.map +1 -0
- package/dist/wiki/__tests__/lint.test.js +163 -0
- package/dist/wiki/__tests__/lint.test.js.map +1 -0
- package/dist/wiki/__tests__/query.test.d.ts +5 -0
- package/dist/wiki/__tests__/query.test.d.ts.map +1 -0
- package/dist/wiki/__tests__/query.test.js +141 -0
- package/dist/wiki/__tests__/query.test.js.map +1 -0
- package/dist/wiki/__tests__/reserved-file-guard.test.d.ts +2 -0
- package/dist/wiki/__tests__/reserved-file-guard.test.d.ts.map +1 -0
- package/dist/wiki/__tests__/reserved-file-guard.test.js +44 -0
- package/dist/wiki/__tests__/reserved-file-guard.test.js.map +1 -0
- package/dist/wiki/__tests__/session-hooks.test.d.ts +5 -0
- package/dist/wiki/__tests__/session-hooks.test.d.ts.map +1 -0
- package/dist/wiki/__tests__/session-hooks.test.js +36 -0
- package/dist/wiki/__tests__/session-hooks.test.js.map +1 -0
- package/dist/wiki/__tests__/slug-nonascii.test.d.ts +2 -0
- package/dist/wiki/__tests__/slug-nonascii.test.d.ts.map +1 -0
- package/dist/wiki/__tests__/slug-nonascii.test.js +24 -0
- package/dist/wiki/__tests__/slug-nonascii.test.js.map +1 -0
- package/dist/wiki/__tests__/storage.test.d.ts +5 -0
- package/dist/wiki/__tests__/storage.test.d.ts.map +1 -0
- package/dist/wiki/__tests__/storage.test.js +278 -0
- package/dist/wiki/__tests__/storage.test.js.map +1 -0
- package/dist/wiki/__tests__/test-helpers.d.ts +31 -0
- package/dist/wiki/__tests__/test-helpers.d.ts.map +1 -0
- package/dist/wiki/__tests__/test-helpers.js +108 -0
- package/dist/wiki/__tests__/test-helpers.js.map +1 -0
- package/dist/wiki/index.d.ts +14 -0
- package/dist/wiki/index.d.ts.map +1 -0
- package/dist/wiki/index.js +17 -0
- package/dist/wiki/index.js.map +1 -0
- package/dist/wiki/ingest.d.ts +20 -0
- package/dist/wiki/ingest.d.ts.map +1 -0
- package/dist/wiki/ingest.js +115 -0
- package/dist/wiki/ingest.js.map +1 -0
- package/dist/wiki/lifecycle.d.ts +20 -0
- package/dist/wiki/lifecycle.d.ts.map +1 -0
- package/dist/wiki/lifecycle.js +212 -0
- package/dist/wiki/lifecycle.js.map +1 -0
- package/dist/wiki/lint.d.ts +25 -0
- package/dist/wiki/lint.d.ts.map +1 -0
- package/dist/wiki/lint.js +166 -0
- package/dist/wiki/lint.js.map +1 -0
- package/dist/wiki/query.d.ts +36 -0
- package/dist/wiki/query.d.ts.map +1 -0
- package/dist/wiki/query.js +138 -0
- package/dist/wiki/query.js.map +1 -0
- package/dist/wiki/storage.d.ts +33 -0
- package/dist/wiki/storage.d.ts.map +1 -0
- package/dist/wiki/storage.js +321 -0
- package/dist/wiki/storage.js.map +1 -0
- package/dist/wiki/types.d.ts +83 -0
- package/dist/wiki/types.d.ts.map +1 -0
- package/dist/wiki/types.js +15 -0
- package/dist/wiki/types.js.map +1 -0
- package/package.json +3 -1
- package/skills/configure-notifications/SKILL.md +1 -0
- package/skills/doctor/SKILL.md +11 -0
- package/skills/omx-setup/SKILL.md +1 -1
- package/skills/wiki/SKILL.md +57 -0
- package/src/scripts/__tests__/codex-native-hook.test.ts +920 -56
- package/src/scripts/__tests__/hook-derived-watcher.test.ts +111 -0
- package/src/scripts/codex-native-hook.ts +377 -83
- package/src/scripts/hook-derived-watcher.ts +43 -1
- package/src/scripts/notify-fallback-watcher.ts +99 -20
- package/src/scripts/notify-hook/active-team.ts +54 -0
- package/src/scripts/notify-hook/auto-nudge.ts +132 -79
- package/src/scripts/notify-hook/managed-tmux.ts +22 -4
- package/src/scripts/notify-hook/operational-events.ts +21 -0
- package/src/scripts/notify-hook/ralph-session-resume.ts +3 -2
- package/src/scripts/notify-hook/state-io.ts +89 -12
- package/src/scripts/notify-hook/team-dispatch.ts +326 -168
- package/src/scripts/notify-hook/team-leader-nudge.ts +91 -14
- package/src/scripts/notify-hook/tmux-injection.ts +11 -2
- package/src/scripts/notify-hook.ts +36 -22
- package/src/scripts/run-provider-advisor.ts +20 -2
- package/src/scripts/smoke-packed-install.ts +16 -83
- package/templates/AGENTS.md +3 -4
|
@@ -97,6 +97,7 @@ async function writeJsonAtomic(path, value) {
|
|
|
97
97
|
|
|
98
98
|
// Keep stale-timeout semantics aligned with src/team/state.ts LOCK_STALE_MS.
|
|
99
99
|
const DISPATCH_LOCK_STALE_MS = 5 * 60 * 1000;
|
|
100
|
+
const DISPATCH_REQUEST_LEASE_STALE_MS = 30 * 1000;
|
|
100
101
|
const DEFAULT_ISSUE_DISPATCH_COOLDOWN_MS = 15 * 60 * 1000;
|
|
101
102
|
const ISSUE_DISPATCH_COOLDOWN_ENV = 'OMX_TEAM_DISPATCH_ISSUE_COOLDOWN_MS';
|
|
102
103
|
const DEFAULT_DISPATCH_TRIGGER_COOLDOWN_MS = 30 * 1000;
|
|
@@ -183,6 +184,31 @@ function parseTriggerCooldownEntry(entry) {
|
|
|
183
184
|
};
|
|
184
185
|
}
|
|
185
186
|
|
|
187
|
+
function reserveDispatchCooldowns({
|
|
188
|
+
issueCooldownMs,
|
|
189
|
+
triggerCooldownMs,
|
|
190
|
+
issueCooldownByIssue,
|
|
191
|
+
triggerCooldownByKey,
|
|
192
|
+
issueKey,
|
|
193
|
+
triggerKey,
|
|
194
|
+
requestId,
|
|
195
|
+
reservedAt = Date.now(),
|
|
196
|
+
}) {
|
|
197
|
+
let mutated = false;
|
|
198
|
+
if (issueKey && issueCooldownMs > 0) {
|
|
199
|
+
issueCooldownByIssue[issueKey] = reservedAt;
|
|
200
|
+
mutated = true;
|
|
201
|
+
}
|
|
202
|
+
if (triggerKey && triggerCooldownMs > 0) {
|
|
203
|
+
triggerCooldownByKey[triggerKey] = {
|
|
204
|
+
at: reservedAt,
|
|
205
|
+
last_request_id: safeString(requestId).trim(),
|
|
206
|
+
};
|
|
207
|
+
mutated = true;
|
|
208
|
+
}
|
|
209
|
+
return mutated;
|
|
210
|
+
}
|
|
211
|
+
|
|
186
212
|
async function withLockDirectory(lockDir, timeoutError, fn) {
|
|
187
213
|
const ownerPath = join(lockDir, 'owner');
|
|
188
214
|
const ownerToken = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`;
|
|
@@ -245,6 +271,49 @@ async function withMailboxLock(teamDirPath, workerName, fn) {
|
|
|
245
271
|
);
|
|
246
272
|
}
|
|
247
273
|
|
|
274
|
+
function dispatchRequestLeaseDir(teamDirPath, requestId) {
|
|
275
|
+
return join(teamDirPath, 'dispatch', `.processing-${safeString(requestId).trim()}`);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
async function tryAcquireDispatchRequestLease(teamDirPath, requestId) {
|
|
279
|
+
const lockDir = dispatchRequestLeaseDir(teamDirPath, requestId);
|
|
280
|
+
const ownerPath = join(lockDir, 'owner');
|
|
281
|
+
const ownerToken = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`;
|
|
282
|
+
await mkdir(dirname(lockDir), { recursive: true });
|
|
283
|
+
|
|
284
|
+
while (true) {
|
|
285
|
+
try {
|
|
286
|
+
await mkdir(lockDir, { recursive: false });
|
|
287
|
+
await writeFile(ownerPath, ownerToken, 'utf8');
|
|
288
|
+
return { lockDir, ownerPath, ownerToken, requestId };
|
|
289
|
+
} catch (error) {
|
|
290
|
+
if (error?.code !== 'EEXIST') throw error;
|
|
291
|
+
try {
|
|
292
|
+
const info = await stat(lockDir);
|
|
293
|
+
if (Date.now() - info.mtimeMs > DISPATCH_REQUEST_LEASE_STALE_MS) {
|
|
294
|
+
await rm(lockDir, { recursive: true, force: true });
|
|
295
|
+
continue;
|
|
296
|
+
}
|
|
297
|
+
} catch {
|
|
298
|
+
// best effort
|
|
299
|
+
}
|
|
300
|
+
return null;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
async function releaseDispatchRequestLease(lease) {
|
|
306
|
+
if (!lease?.lockDir || !lease?.ownerPath || !lease?.ownerToken) return;
|
|
307
|
+
try {
|
|
308
|
+
const currentOwner = await readFile(lease.ownerPath, 'utf8');
|
|
309
|
+
if (currentOwner.trim() === lease.ownerToken) {
|
|
310
|
+
await rm(lease.lockDir, { recursive: true, force: true });
|
|
311
|
+
}
|
|
312
|
+
} catch {
|
|
313
|
+
// best effort
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
|
|
248
317
|
function resolveLeaderPaneId(config) {
|
|
249
318
|
return safeString(config?.leader_pane_id).trim();
|
|
250
319
|
}
|
|
@@ -336,6 +405,213 @@ async function appendLeaderNotificationDeferredEvent({
|
|
|
336
405
|
await appendFile(eventsPath, JSON.stringify(event) + '\n').catch(() => {});
|
|
337
406
|
}
|
|
338
407
|
|
|
408
|
+
async function finalizeClaimedDispatchRequest({
|
|
409
|
+
claim,
|
|
410
|
+
result,
|
|
411
|
+
teamName,
|
|
412
|
+
teamDirPath,
|
|
413
|
+
config,
|
|
414
|
+
cwd,
|
|
415
|
+
stateDir,
|
|
416
|
+
logsDir,
|
|
417
|
+
issueCooldownMs,
|
|
418
|
+
triggerCooldownMs,
|
|
419
|
+
}) {
|
|
420
|
+
const requestsPath = join(teamDirPath, 'dispatch', 'requests.json');
|
|
421
|
+
const issueKey = extractIssueKey(claim.request.trigger_message);
|
|
422
|
+
const triggerKey = normalizeTriggerKey(claim.request.trigger_message);
|
|
423
|
+
let summary = { processed: 0, skipped: 0, failed: 0 };
|
|
424
|
+
|
|
425
|
+
await withDispatchLock(teamDirPath, async () => {
|
|
426
|
+
const bridgeRequests = await readBridgeDispatchRequests(stateDir, teamName);
|
|
427
|
+
const usingLegacyRequests = bridgeRequests === null;
|
|
428
|
+
const requests = usingLegacyRequests ? await readJson(requestsPath, []) : bridgeRequests;
|
|
429
|
+
if (!Array.isArray(requests)) return;
|
|
430
|
+
|
|
431
|
+
const index = requests.findIndex((entry) => safeString(entry?.request_id).trim() === claim.request.request_id);
|
|
432
|
+
if (index < 0) return;
|
|
433
|
+
|
|
434
|
+
const request = requests[index];
|
|
435
|
+
if (!request || typeof request !== 'object' || shouldSkipRequest(request) || request.status !== 'pending') return;
|
|
436
|
+
|
|
437
|
+
const issueCooldownState = await readIssueCooldownState(teamDirPath);
|
|
438
|
+
const triggerCooldownState = await readTriggerCooldownState(teamDirPath);
|
|
439
|
+
const issueCooldownByIssue = issueCooldownState.by_issue || {};
|
|
440
|
+
const triggerCooldownByKey = triggerCooldownState.by_trigger || {};
|
|
441
|
+
const nowIso = new Date().toISOString();
|
|
442
|
+
let mutated = false;
|
|
443
|
+
|
|
444
|
+
mutated = reserveDispatchCooldowns({
|
|
445
|
+
issueCooldownMs,
|
|
446
|
+
triggerCooldownMs,
|
|
447
|
+
issueCooldownByIssue,
|
|
448
|
+
triggerCooldownByKey,
|
|
449
|
+
issueKey,
|
|
450
|
+
triggerKey,
|
|
451
|
+
requestId: request.request_id,
|
|
452
|
+
}) || mutated;
|
|
453
|
+
|
|
454
|
+
request.attempt_count = Number.isFinite(request.attempt_count) ? Math.max(0, request.attempt_count + 1) : 1;
|
|
455
|
+
request.updated_at = nowIso;
|
|
456
|
+
|
|
457
|
+
if (result.ok) {
|
|
458
|
+
const MAX_UNCONFIRMED_ATTEMPTS = 3;
|
|
459
|
+
if (result.reason === 'tmux_send_keys_unconfirmed' && request.attempt_count < MAX_UNCONFIRMED_ATTEMPTS) {
|
|
460
|
+
request.last_reason = result.reason;
|
|
461
|
+
summary.skipped += 1;
|
|
462
|
+
mutated = true;
|
|
463
|
+
await appendDispatchLog(logsDir, {
|
|
464
|
+
type: 'dispatch_unconfirmed_retry',
|
|
465
|
+
team: teamName,
|
|
466
|
+
request_id: request.request_id,
|
|
467
|
+
worker: request.to_worker,
|
|
468
|
+
attempt: request.attempt_count,
|
|
469
|
+
reason: result.reason,
|
|
470
|
+
...buildDispatchAttemptEvidence(result),
|
|
471
|
+
});
|
|
472
|
+
await appendDeliveryTelemetry(logsDir, {
|
|
473
|
+
event: 'dispatch_result',
|
|
474
|
+
team: teamName,
|
|
475
|
+
request_id: request.request_id,
|
|
476
|
+
message_id: request.message_id || null,
|
|
477
|
+
to_worker: request.to_worker,
|
|
478
|
+
transport: 'send-keys',
|
|
479
|
+
result: 'retry',
|
|
480
|
+
reason: result.reason,
|
|
481
|
+
});
|
|
482
|
+
await emitOperationalHookEvent(cwd, 'retry-needed', {
|
|
483
|
+
team: teamName,
|
|
484
|
+
worker: request.to_worker,
|
|
485
|
+
request_id: request.request_id,
|
|
486
|
+
attempt: request.attempt_count,
|
|
487
|
+
command: request.trigger_message,
|
|
488
|
+
reason: result.reason,
|
|
489
|
+
status: 'retry-needed',
|
|
490
|
+
});
|
|
491
|
+
} else if (result.reason === 'tmux_send_keys_unconfirmed') {
|
|
492
|
+
request.status = 'failed';
|
|
493
|
+
request.failed_at = nowIso;
|
|
494
|
+
request.last_reason = 'unconfirmed_after_max_retries';
|
|
495
|
+
runtimeExec({ command: 'MarkFailed', request_id: request.request_id, reason: 'unconfirmed_after_max_retries' }, stateDir);
|
|
496
|
+
summary.processed += 1;
|
|
497
|
+
summary.failed += 1;
|
|
498
|
+
mutated = true;
|
|
499
|
+
await appendDispatchLog(logsDir, {
|
|
500
|
+
type: 'dispatch_failed',
|
|
501
|
+
team: teamName,
|
|
502
|
+
request_id: request.request_id,
|
|
503
|
+
worker: request.to_worker,
|
|
504
|
+
message_id: request.message_id || null,
|
|
505
|
+
reason: request.last_reason,
|
|
506
|
+
...buildDispatchAttemptEvidence(result),
|
|
507
|
+
});
|
|
508
|
+
await appendDeliveryTelemetry(logsDir, {
|
|
509
|
+
event: 'dispatch_result',
|
|
510
|
+
team: teamName,
|
|
511
|
+
request_id: request.request_id,
|
|
512
|
+
message_id: request.message_id || null,
|
|
513
|
+
to_worker: request.to_worker,
|
|
514
|
+
transport: 'send-keys',
|
|
515
|
+
result: 'failed',
|
|
516
|
+
reason: request.last_reason,
|
|
517
|
+
});
|
|
518
|
+
await emitOperationalHookEvent(cwd, 'failed', {
|
|
519
|
+
team: teamName,
|
|
520
|
+
worker: request.to_worker,
|
|
521
|
+
request_id: request.request_id,
|
|
522
|
+
message_id: request.message_id || null,
|
|
523
|
+
command: request.trigger_message,
|
|
524
|
+
reason: request.last_reason,
|
|
525
|
+
error_summary: request.last_reason,
|
|
526
|
+
status: 'failed',
|
|
527
|
+
});
|
|
528
|
+
} else {
|
|
529
|
+
request.status = 'notified';
|
|
530
|
+
request.notified_at = nowIso;
|
|
531
|
+
request.last_reason = result.reason;
|
|
532
|
+
runtimeExec({ command: 'MarkNotified', request_id: request.request_id, channel: 'tmux' }, stateDir);
|
|
533
|
+
if (request.kind === 'mailbox' && request.message_id) {
|
|
534
|
+
runtimeExec({ command: 'MarkMailboxNotified', message_id: request.message_id }, stateDir);
|
|
535
|
+
if (usingLegacyRequests) {
|
|
536
|
+
await updateMailboxNotified(stateDir, teamName, request.to_worker, request.message_id).catch(() => {});
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
summary.processed += 1;
|
|
540
|
+
mutated = true;
|
|
541
|
+
await appendDispatchLog(logsDir, {
|
|
542
|
+
type: 'dispatch_notified',
|
|
543
|
+
team: teamName,
|
|
544
|
+
request_id: request.request_id,
|
|
545
|
+
worker: request.to_worker,
|
|
546
|
+
message_id: request.message_id || null,
|
|
547
|
+
reason: result.reason,
|
|
548
|
+
...buildDispatchAttemptEvidence(result),
|
|
549
|
+
});
|
|
550
|
+
await appendDeliveryTelemetry(logsDir, {
|
|
551
|
+
event: 'dispatch_result',
|
|
552
|
+
team: teamName,
|
|
553
|
+
request_id: request.request_id,
|
|
554
|
+
message_id: request.message_id || null,
|
|
555
|
+
to_worker: request.to_worker,
|
|
556
|
+
transport: 'send-keys',
|
|
557
|
+
result: 'notified',
|
|
558
|
+
reason: result.reason,
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
} else {
|
|
562
|
+
request.status = 'failed';
|
|
563
|
+
request.failed_at = nowIso;
|
|
564
|
+
request.last_reason = result.reason;
|
|
565
|
+
runtimeExec({ command: 'MarkFailed', request_id: request.request_id, reason: result.reason }, stateDir);
|
|
566
|
+
summary.processed += 1;
|
|
567
|
+
summary.failed += 1;
|
|
568
|
+
mutated = true;
|
|
569
|
+
await appendDispatchLog(logsDir, {
|
|
570
|
+
type: 'dispatch_failed',
|
|
571
|
+
team: teamName,
|
|
572
|
+
request_id: request.request_id,
|
|
573
|
+
worker: request.to_worker,
|
|
574
|
+
message_id: request.message_id || null,
|
|
575
|
+
reason: result.reason,
|
|
576
|
+
...buildDispatchAttemptEvidence(result),
|
|
577
|
+
});
|
|
578
|
+
await appendDeliveryTelemetry(logsDir, {
|
|
579
|
+
event: 'dispatch_result',
|
|
580
|
+
team: teamName,
|
|
581
|
+
request_id: request.request_id,
|
|
582
|
+
message_id: request.message_id || null,
|
|
583
|
+
to_worker: request.to_worker,
|
|
584
|
+
transport: 'send-keys',
|
|
585
|
+
result: 'failed',
|
|
586
|
+
reason: result.reason,
|
|
587
|
+
});
|
|
588
|
+
await emitOperationalHookEvent(cwd, result.reason === LEADER_PANE_MISSING_DEFERRED_REASON ? 'handoff-needed' : 'failed', {
|
|
589
|
+
team: teamName,
|
|
590
|
+
worker: request.to_worker,
|
|
591
|
+
request_id: request.request_id,
|
|
592
|
+
message_id: request.message_id || null,
|
|
593
|
+
command: request.trigger_message,
|
|
594
|
+
reason: result.reason,
|
|
595
|
+
...(result.reason === LEADER_PANE_MISSING_DEFERRED_REASON
|
|
596
|
+
? { status: 'handoff-needed' }
|
|
597
|
+
: { status: 'failed', error_summary: result.reason }),
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
if (!mutated) return;
|
|
602
|
+
issueCooldownState.by_issue = issueCooldownByIssue;
|
|
603
|
+
await writeJsonAtomic(issueCooldownStatePath(teamDirPath), issueCooldownState);
|
|
604
|
+
triggerCooldownState.by_trigger = triggerCooldownByKey;
|
|
605
|
+
await writeJsonAtomic(triggerCooldownStatePath(teamDirPath), triggerCooldownState);
|
|
606
|
+
await writeJsonAtomic(requestsPath, requests);
|
|
607
|
+
if (!usingLegacyRequests) {
|
|
608
|
+
await writeBridgeDispatchCompat(stateDir, teamName, requests);
|
|
609
|
+
}
|
|
610
|
+
});
|
|
611
|
+
|
|
612
|
+
return summary;
|
|
613
|
+
}
|
|
614
|
+
|
|
339
615
|
function resolveWorkerCliForRequest(request, config) {
|
|
340
616
|
const workers = Array.isArray(config?.workers) ? config.workers : [];
|
|
341
617
|
const idx = Number.isFinite(request?.worker_index) ? Number(request.worker_index) : null;
|
|
@@ -602,8 +878,8 @@ export async function drainPendingTeamDispatch({
|
|
|
602
878
|
const manifestPath = join(teamDirPath, 'manifest.v2.json');
|
|
603
879
|
const configPath = join(teamDirPath, 'config.json');
|
|
604
880
|
const requestsPath = join(teamDirPath, 'dispatch', 'requests.json');
|
|
605
|
-
|
|
606
881
|
const config = await readJson(existsSync(manifestPath) ? manifestPath : configPath, {});
|
|
882
|
+
const claims = [];
|
|
607
883
|
await withDispatchLock(teamDirPath, async () => {
|
|
608
884
|
const bridgeRequests = await readBridgeDispatchRequests(stateDir, teamName);
|
|
609
885
|
const usingLegacyRequests = bridgeRequests === null;
|
|
@@ -617,7 +893,7 @@ export async function drainPendingTeamDispatch({
|
|
|
617
893
|
|
|
618
894
|
let mutated = false;
|
|
619
895
|
for (const request of requests) {
|
|
620
|
-
if (processed >= maxPerTick) break;
|
|
896
|
+
if (processed + claims.length >= maxPerTick) break;
|
|
621
897
|
if (!request || typeof request !== 'object') continue;
|
|
622
898
|
if (shouldSkipRequest(request)) {
|
|
623
899
|
skipped += 1;
|
|
@@ -660,9 +936,6 @@ export async function drainPendingTeamDispatch({
|
|
|
660
936
|
result: 'deferred',
|
|
661
937
|
reason: LEADER_PANE_MISSING_DEFERRED_REASON,
|
|
662
938
|
});
|
|
663
|
-
// On the legacy fallback lane, requests.json still carries the queue
|
|
664
|
-
// state for this deferred request; this event stays a progress
|
|
665
|
-
// artifact for hook/watcher readers.
|
|
666
939
|
await appendLeaderNotificationDeferredEvent({
|
|
667
940
|
stateDir,
|
|
668
941
|
teamName,
|
|
@@ -697,170 +970,24 @@ export async function drainPendingTeamDispatch({
|
|
|
697
970
|
}
|
|
698
971
|
}
|
|
699
972
|
|
|
700
|
-
const
|
|
701
|
-
if (
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
}
|
|
705
|
-
if (triggerKey && triggerCooldownMs > 0) {
|
|
706
|
-
triggerCooldownByKey[triggerKey] = {
|
|
707
|
-
at: Date.now(),
|
|
708
|
-
last_request_id: safeString(request.request_id).trim(),
|
|
709
|
-
};
|
|
710
|
-
mutated = true;
|
|
711
|
-
}
|
|
712
|
-
const nowIso = new Date().toISOString();
|
|
713
|
-
request.attempt_count = Number.isFinite(request.attempt_count) ? Math.max(0, request.attempt_count + 1) : 1;
|
|
714
|
-
request.updated_at = nowIso;
|
|
715
|
-
|
|
716
|
-
if (result.ok) {
|
|
717
|
-
// Unconfirmed sends: trigger text was still visible after retry
|
|
718
|
-
// rounds. Leave as pending for the next tick to retry (up to 3
|
|
719
|
-
// total attempts) rather than marking notified. Fixes #391.
|
|
720
|
-
const MAX_UNCONFIRMED_ATTEMPTS = 3;
|
|
721
|
-
if (result.reason === 'tmux_send_keys_unconfirmed' && request.attempt_count < MAX_UNCONFIRMED_ATTEMPTS) {
|
|
722
|
-
request.last_reason = result.reason;
|
|
723
|
-
mutated = true;
|
|
724
|
-
skipped += 1;
|
|
725
|
-
await appendDispatchLog(logsDir, {
|
|
726
|
-
type: 'dispatch_unconfirmed_retry',
|
|
727
|
-
team: teamName,
|
|
728
|
-
request_id: request.request_id,
|
|
729
|
-
worker: request.to_worker,
|
|
730
|
-
attempt: request.attempt_count,
|
|
731
|
-
reason: result.reason,
|
|
732
|
-
...buildDispatchAttemptEvidence(result),
|
|
733
|
-
});
|
|
734
|
-
await appendDeliveryTelemetry(logsDir, {
|
|
735
|
-
event: 'dispatch_result',
|
|
736
|
-
team: teamName,
|
|
737
|
-
request_id: request.request_id,
|
|
738
|
-
message_id: request.message_id || null,
|
|
739
|
-
to_worker: request.to_worker,
|
|
740
|
-
transport: 'send-keys',
|
|
741
|
-
result: 'retry',
|
|
742
|
-
reason: result.reason,
|
|
743
|
-
});
|
|
744
|
-
await emitOperationalHookEvent(cwd, 'retry-needed', {
|
|
745
|
-
team: teamName,
|
|
746
|
-
worker: request.to_worker,
|
|
747
|
-
request_id: request.request_id,
|
|
748
|
-
attempt: request.attempt_count,
|
|
749
|
-
command: request.trigger_message,
|
|
750
|
-
reason: result.reason,
|
|
751
|
-
status: 'retry-needed',
|
|
752
|
-
});
|
|
753
|
-
continue;
|
|
754
|
-
}
|
|
755
|
-
if (result.reason === 'tmux_send_keys_unconfirmed') {
|
|
756
|
-
request.status = 'failed';
|
|
757
|
-
request.failed_at = nowIso;
|
|
758
|
-
request.last_reason = 'unconfirmed_after_max_retries';
|
|
759
|
-
runtimeExec({ command: 'MarkFailed', request_id: request.request_id, reason: 'unconfirmed_after_max_retries' }, stateDir);
|
|
760
|
-
processed += 1;
|
|
761
|
-
failed += 1;
|
|
762
|
-
mutated = true;
|
|
763
|
-
await appendDispatchLog(logsDir, {
|
|
764
|
-
type: 'dispatch_failed',
|
|
765
|
-
team: teamName,
|
|
766
|
-
request_id: request.request_id,
|
|
767
|
-
worker: request.to_worker,
|
|
768
|
-
message_id: request.message_id || null,
|
|
769
|
-
reason: request.last_reason,
|
|
770
|
-
...buildDispatchAttemptEvidence(result),
|
|
771
|
-
});
|
|
772
|
-
await appendDeliveryTelemetry(logsDir, {
|
|
773
|
-
event: 'dispatch_result',
|
|
774
|
-
team: teamName,
|
|
775
|
-
request_id: request.request_id,
|
|
776
|
-
message_id: request.message_id || null,
|
|
777
|
-
to_worker: request.to_worker,
|
|
778
|
-
transport: 'send-keys',
|
|
779
|
-
result: 'failed',
|
|
780
|
-
reason: request.last_reason,
|
|
781
|
-
});
|
|
782
|
-
await emitOperationalHookEvent(cwd, 'failed', {
|
|
783
|
-
team: teamName,
|
|
784
|
-
worker: request.to_worker,
|
|
785
|
-
request_id: request.request_id,
|
|
786
|
-
message_id: request.message_id || null,
|
|
787
|
-
command: request.trigger_message,
|
|
788
|
-
reason: request.last_reason,
|
|
789
|
-
error_summary: request.last_reason,
|
|
790
|
-
status: 'failed',
|
|
791
|
-
});
|
|
792
|
-
continue;
|
|
793
|
-
}
|
|
794
|
-
request.status = 'notified';
|
|
795
|
-
request.notified_at = nowIso;
|
|
796
|
-
request.last_reason = result.reason;
|
|
797
|
-
runtimeExec({ command: 'MarkNotified', request_id: request.request_id, channel: 'tmux' }, stateDir);
|
|
798
|
-
if (request.kind === 'mailbox' && request.message_id) {
|
|
799
|
-
runtimeExec({ command: 'MarkMailboxNotified', message_id: request.message_id }, stateDir);
|
|
800
|
-
if (usingLegacyRequests) {
|
|
801
|
-
await updateMailboxNotified(stateDir, teamName, request.to_worker, request.message_id).catch(() => {});
|
|
802
|
-
}
|
|
803
|
-
}
|
|
804
|
-
processed += 1;
|
|
805
|
-
mutated = true;
|
|
806
|
-
await appendDispatchLog(logsDir, {
|
|
807
|
-
type: 'dispatch_notified',
|
|
808
|
-
team: teamName,
|
|
809
|
-
request_id: request.request_id,
|
|
810
|
-
worker: request.to_worker,
|
|
811
|
-
message_id: request.message_id || null,
|
|
812
|
-
reason: result.reason,
|
|
813
|
-
...buildDispatchAttemptEvidence(result),
|
|
814
|
-
});
|
|
815
|
-
await appendDeliveryTelemetry(logsDir, {
|
|
816
|
-
event: 'dispatch_result',
|
|
817
|
-
team: teamName,
|
|
818
|
-
request_id: request.request_id,
|
|
819
|
-
message_id: request.message_id || null,
|
|
820
|
-
to_worker: request.to_worker,
|
|
821
|
-
transport: 'send-keys',
|
|
822
|
-
result: 'notified',
|
|
823
|
-
reason: result.reason,
|
|
824
|
-
});
|
|
825
|
-
} else {
|
|
826
|
-
request.status = 'failed';
|
|
827
|
-
request.failed_at = nowIso;
|
|
828
|
-
request.last_reason = result.reason;
|
|
829
|
-
runtimeExec({ command: 'MarkFailed', request_id: request.request_id, reason: result.reason }, stateDir);
|
|
830
|
-
processed += 1;
|
|
831
|
-
failed += 1;
|
|
832
|
-
mutated = true;
|
|
833
|
-
await appendDispatchLog(logsDir, {
|
|
834
|
-
type: 'dispatch_failed',
|
|
835
|
-
team: teamName,
|
|
836
|
-
request_id: request.request_id,
|
|
837
|
-
worker: request.to_worker,
|
|
838
|
-
message_id: request.message_id || null,
|
|
839
|
-
reason: result.reason,
|
|
840
|
-
...buildDispatchAttemptEvidence(result),
|
|
841
|
-
});
|
|
842
|
-
await appendDeliveryTelemetry(logsDir, {
|
|
843
|
-
event: 'dispatch_result',
|
|
844
|
-
team: teamName,
|
|
845
|
-
request_id: request.request_id,
|
|
846
|
-
message_id: request.message_id || null,
|
|
847
|
-
to_worker: request.to_worker,
|
|
848
|
-
transport: 'send-keys',
|
|
849
|
-
result: 'failed',
|
|
850
|
-
reason: result.reason,
|
|
851
|
-
});
|
|
852
|
-
await emitOperationalHookEvent(cwd, result.reason === LEADER_PANE_MISSING_DEFERRED_REASON ? 'handoff-needed' : 'failed', {
|
|
853
|
-
team: teamName,
|
|
854
|
-
worker: request.to_worker,
|
|
855
|
-
request_id: request.request_id,
|
|
856
|
-
message_id: request.message_id || null,
|
|
857
|
-
command: request.trigger_message,
|
|
858
|
-
reason: result.reason,
|
|
859
|
-
...(result.reason === LEADER_PANE_MISSING_DEFERRED_REASON
|
|
860
|
-
? { status: 'handoff-needed' }
|
|
861
|
-
: { status: 'failed', error_summary: result.reason }),
|
|
862
|
-
});
|
|
973
|
+
const lease = await tryAcquireDispatchRequestLease(teamDirPath, request.request_id);
|
|
974
|
+
if (!lease) {
|
|
975
|
+
skipped += 1;
|
|
976
|
+
continue;
|
|
863
977
|
}
|
|
978
|
+
mutated = reserveDispatchCooldowns({
|
|
979
|
+
issueCooldownMs,
|
|
980
|
+
triggerCooldownMs,
|
|
981
|
+
issueCooldownByIssue,
|
|
982
|
+
triggerCooldownByKey,
|
|
983
|
+
issueKey,
|
|
984
|
+
triggerKey,
|
|
985
|
+
requestId: request.request_id,
|
|
986
|
+
}) || mutated;
|
|
987
|
+
claims.push({
|
|
988
|
+
request: { ...request },
|
|
989
|
+
lease,
|
|
990
|
+
});
|
|
864
991
|
}
|
|
865
992
|
|
|
866
993
|
if (mutated) {
|
|
@@ -874,6 +1001,37 @@ export async function drainPendingTeamDispatch({
|
|
|
874
1001
|
}
|
|
875
1002
|
}
|
|
876
1003
|
});
|
|
1004
|
+
|
|
1005
|
+
try {
|
|
1006
|
+
for (const claim of claims) {
|
|
1007
|
+
try {
|
|
1008
|
+
const result = await injector(claim.request, config, resolve(cwd), stateDir);
|
|
1009
|
+
const delta = await finalizeClaimedDispatchRequest({
|
|
1010
|
+
claim,
|
|
1011
|
+
result,
|
|
1012
|
+
teamName,
|
|
1013
|
+
teamDirPath,
|
|
1014
|
+
config,
|
|
1015
|
+
cwd,
|
|
1016
|
+
stateDir,
|
|
1017
|
+
logsDir,
|
|
1018
|
+
issueCooldownMs,
|
|
1019
|
+
triggerCooldownMs,
|
|
1020
|
+
});
|
|
1021
|
+
processed += delta.processed;
|
|
1022
|
+
skipped += delta.skipped;
|
|
1023
|
+
failed += delta.failed;
|
|
1024
|
+
} finally {
|
|
1025
|
+
claim.released = true;
|
|
1026
|
+
await releaseDispatchRequestLease(claim.lease);
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
} finally {
|
|
1030
|
+
for (const claim of claims) {
|
|
1031
|
+
if (claim.released) continue;
|
|
1032
|
+
await releaseDispatchRequestLease(claim.lease);
|
|
1033
|
+
}
|
|
1034
|
+
}
|
|
877
1035
|
}
|
|
878
1036
|
|
|
879
1037
|
return { processed, skipped, failed };
|