@stanco323/oh-my-claude-code 4.10.3 → 4.11.0
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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +65 -18
- package/bridge/cli.cjs +3030 -1784
- package/bridge/mcp-server.cjs +128 -98
- package/bridge/runtime-cli.cjs +174 -136
- package/bridge/team-bridge.cjs +102 -96
- package/bridge/team-mcp.cjs +40 -29
- package/bridge/team.js +102 -88
- package/dist/__tests__/auto-update.test.js +8 -9
- package/dist/__tests__/auto-update.test.js.map +1 -1
- package/dist/__tests__/cli-config-stop-callback.test.js +26 -0
- package/dist/__tests__/cli-config-stop-callback.test.js.map +1 -1
- package/dist/__tests__/config-dir.test.d.ts +2 -0
- package/dist/__tests__/config-dir.test.d.ts.map +1 -0
- package/dist/__tests__/config-dir.test.js +184 -0
- package/dist/__tests__/config-dir.test.js.map +1 -0
- package/dist/__tests__/delegation-enforcement-levels.test.js +45 -1
- package/dist/__tests__/delegation-enforcement-levels.test.js.map +1 -1
- package/dist/__tests__/doctor-conflicts.test.js +9 -7
- package/dist/__tests__/doctor-conflicts.test.js.map +1 -1
- package/dist/__tests__/hooks-command-escaping.test.js +17 -10
- package/dist/__tests__/hooks-command-escaping.test.js.map +1 -1
- package/dist/__tests__/hud/cli-diagnostic.test.js +1 -1
- package/dist/__tests__/hud/cli-diagnostic.test.js.map +1 -1
- package/dist/__tests__/hud/usage-api-lock.test.js +5 -5
- package/dist/__tests__/hud/usage-api-lock.test.js.map +1 -1
- package/dist/__tests__/hud/usage-api-stale.test.js +2 -2
- package/dist/__tests__/hud/usage-api-stale.test.js.map +1 -1
- package/dist/__tests__/hud/usage-api.test.js +98 -0
- package/dist/__tests__/hud/usage-api.test.js.map +1 -1
- package/dist/__tests__/hud-api-key-source.test.js +2 -2
- package/dist/__tests__/hud-api-key-source.test.js.map +1 -1
- package/dist/__tests__/hud-marketplace-resolution.test.js +3 -1
- package/dist/__tests__/hud-marketplace-resolution.test.js.map +1 -1
- package/dist/__tests__/hud-windows.test.js +7 -6
- package/dist/__tests__/hud-windows.test.js.map +1 -1
- package/dist/__tests__/installer-omc-reference.test.js +122 -6
- package/dist/__tests__/installer-omc-reference.test.js.map +1 -1
- package/dist/__tests__/installer.test.js +33 -9
- package/dist/__tests__/installer.test.js.map +1 -1
- package/dist/__tests__/omc-tools-server.test.js +5 -5
- package/dist/__tests__/pre-tool-enforcer.test.js +34 -14
- package/dist/__tests__/pre-tool-enforcer.test.js.map +1 -1
- package/dist/__tests__/preemptive-compaction-hook.test.d.ts +2 -0
- package/dist/__tests__/preemptive-compaction-hook.test.d.ts.map +1 -0
- package/dist/__tests__/preemptive-compaction-hook.test.js +163 -0
- package/dist/__tests__/preemptive-compaction-hook.test.js.map +1 -0
- package/dist/__tests__/purge-stale-cache.test.js +1 -1
- package/dist/__tests__/purge-stale-cache.test.js.map +1 -1
- package/dist/__tests__/release-generation.test.d.ts +2 -0
- package/dist/__tests__/release-generation.test.d.ts.map +1 -0
- package/dist/__tests__/release-generation.test.js +79 -0
- package/dist/__tests__/release-generation.test.js.map +1 -0
- package/dist/__tests__/runtime-guidance-plan-ralph.test.d.ts +2 -0
- package/dist/__tests__/runtime-guidance-plan-ralph.test.d.ts.map +1 -0
- package/dist/__tests__/runtime-guidance-plan-ralph.test.js +87 -0
- package/dist/__tests__/runtime-guidance-plan-ralph.test.js.map +1 -0
- package/dist/__tests__/session-history-search.test.js +31 -3
- package/dist/__tests__/session-history-search.test.js.map +1 -1
- package/dist/__tests__/setup-claude-md-script.test.js +9 -1
- package/dist/__tests__/setup-claude-md-script.test.js.map +1 -1
- package/dist/__tests__/setup-no-plugin-flag.test.d.ts +2 -0
- package/dist/__tests__/setup-no-plugin-flag.test.d.ts.map +1 -0
- package/dist/__tests__/setup-no-plugin-flag.test.js +15 -0
- package/dist/__tests__/setup-no-plugin-flag.test.js.map +1 -0
- package/dist/__tests__/shared-memory.test.js +40 -2
- package/dist/__tests__/shared-memory.test.js.map +1 -1
- package/dist/__tests__/skills.test.js +45 -1
- package/dist/__tests__/skills.test.js.map +1 -1
- package/dist/cli/__tests__/launch.test.js +48 -14
- package/dist/cli/__tests__/launch.test.js.map +1 -1
- package/dist/cli/commands/__tests__/team-role-shorthand.test.d.ts +2 -0
- package/dist/cli/commands/__tests__/team-role-shorthand.test.d.ts.map +1 -0
- package/dist/cli/commands/__tests__/team-role-shorthand.test.js +63 -0
- package/dist/cli/commands/__tests__/team-role-shorthand.test.js.map +1 -0
- package/dist/cli/commands/__tests__/team.test.js +21 -0
- package/dist/cli/commands/__tests__/team.test.js.map +1 -1
- package/dist/cli/commands/adapt.d.ts.map +1 -1
- package/dist/cli/commands/adapt.js.map +1 -1
- package/dist/cli/commands/doctor-conflicts.js +1 -1
- package/dist/cli/commands/doctor-conflicts.js.map +1 -1
- package/dist/cli/commands/team.d.ts.map +1 -1
- package/dist/cli/commands/team.js +30 -17
- package/dist/cli/commands/team.js.map +1 -1
- package/dist/cli/index.js +16 -7
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/launch.d.ts.map +1 -1
- package/dist/cli/launch.js +22 -14
- package/dist/cli/launch.js.map +1 -1
- package/dist/commands/index.js +1 -1
- package/dist/commands/index.js.map +1 -1
- package/dist/constants/names.d.ts +1 -0
- package/dist/constants/names.d.ts.map +1 -1
- package/dist/constants/names.js +1 -0
- package/dist/constants/names.js.map +1 -1
- package/dist/features/auto-update.d.ts.map +1 -1
- package/dist/features/auto-update.js +4 -4
- package/dist/features/auto-update.js.map +1 -1
- package/dist/features/background-agent/manager.js +1 -1
- package/dist/features/background-agent/manager.js.map +1 -1
- package/dist/features/builtin-skills/runtime-guidance.d.ts.map +1 -1
- package/dist/features/builtin-skills/runtime-guidance.js +35 -3
- package/dist/features/builtin-skills/runtime-guidance.js.map +1 -1
- package/dist/features/builtin-skills/skills.d.ts.map +1 -1
- package/dist/features/builtin-skills/skills.js +53 -1
- package/dist/features/builtin-skills/skills.js.map +1 -1
- package/dist/features/session-history-search/index.d.ts.map +1 -1
- package/dist/features/session-history-search/index.js +1 -4
- package/dist/features/session-history-search/index.js.map +1 -1
- package/dist/hooks/__tests__/bridge-routing.test.js +4 -0
- package/dist/hooks/__tests__/bridge-routing.test.js.map +1 -1
- package/dist/hooks/__tests__/bridge.test.js +42 -1
- package/dist/hooks/__tests__/bridge.test.js.map +1 -1
- package/dist/hooks/auto-slash-command/executor.js +2 -2
- package/dist/hooks/auto-slash-command/executor.js.map +1 -1
- package/dist/hooks/autopilot/enforcement.d.ts.map +1 -1
- package/dist/hooks/autopilot/enforcement.js +20 -4
- package/dist/hooks/autopilot/enforcement.js.map +1 -1
- package/dist/hooks/bridge.d.ts +15 -0
- package/dist/hooks/bridge.d.ts.map +1 -1
- package/dist/hooks/bridge.js +38 -1
- package/dist/hooks/bridge.js.map +1 -1
- package/dist/hooks/factcheck/__tests__/factcheck.test.js +6 -5
- package/dist/hooks/factcheck/__tests__/factcheck.test.js.map +1 -1
- package/dist/hooks/factcheck/config.d.ts +2 -2
- package/dist/hooks/factcheck/config.d.ts.map +1 -1
- package/dist/hooks/factcheck/config.js +6 -4
- package/dist/hooks/factcheck/config.js.map +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/learner/auto-invoke.js +1 -1
- package/dist/hooks/learner/auto-invoke.js.map +1 -1
- package/dist/hooks/learner/config.js +1 -1
- package/dist/hooks/learner/config.js.map +1 -1
- package/dist/hooks/learner/constants.js +1 -1
- package/dist/hooks/learner/constants.js.map +1 -1
- package/dist/hooks/omc-orchestrator/constants.d.ts +1 -1
- package/dist/hooks/omc-orchestrator/constants.d.ts.map +1 -1
- package/dist/hooks/omc-orchestrator/constants.js +2 -2
- package/dist/hooks/omc-orchestrator/constants.js.map +1 -1
- package/dist/hooks/omc-orchestrator/index.d.ts.map +1 -1
- package/dist/hooks/omc-orchestrator/index.js +10 -7
- package/dist/hooks/omc-orchestrator/index.js.map +1 -1
- package/dist/hooks/permission-handler/index.js +1 -1
- package/dist/hooks/permission-handler/index.js.map +1 -1
- package/dist/hooks/persistent-mode/index.d.ts.map +1 -1
- package/dist/hooks/persistent-mode/index.js +21 -4
- package/dist/hooks/persistent-mode/index.js.map +1 -1
- package/dist/hooks/persistent-mode/stop-hook-blocking.test.js +91 -0
- package/dist/hooks/persistent-mode/stop-hook-blocking.test.js.map +1 -1
- package/dist/hooks/rules-injector/constants.d.ts +0 -2
- package/dist/hooks/rules-injector/constants.d.ts.map +1 -1
- package/dist/hooks/rules-injector/constants.js +0 -2
- package/dist/hooks/rules-injector/constants.js.map +1 -1
- package/dist/hooks/rules-injector/finder.d.ts +3 -3
- package/dist/hooks/rules-injector/finder.d.ts.map +1 -1
- package/dist/hooks/rules-injector/finder.js +7 -6
- package/dist/hooks/rules-injector/finder.js.map +1 -1
- package/dist/hooks/rules-injector/index.d.ts +1 -1
- package/dist/hooks/rules-injector/index.d.ts.map +1 -1
- package/dist/hooks/rules-injector/index.js +3 -6
- package/dist/hooks/rules-injector/index.js.map +1 -1
- package/dist/hooks/setup/__tests__/stdin-symlink.test.d.ts +2 -0
- package/dist/hooks/setup/__tests__/stdin-symlink.test.d.ts.map +1 -0
- package/dist/hooks/setup/__tests__/stdin-symlink.test.js +184 -0
- package/dist/hooks/setup/__tests__/stdin-symlink.test.js.map +1 -0
- package/dist/hooks/setup/index.d.ts +13 -0
- package/dist/hooks/setup/index.d.ts.map +1 -1
- package/dist/hooks/setup/index.js +100 -2
- package/dist/hooks/setup/index.js.map +1 -1
- package/dist/hooks/skill-bridge.cjs +19 -13
- package/dist/hooks/subagent-tracker/index.d.ts.map +1 -1
- package/dist/hooks/subagent-tracker/index.js +7 -3
- package/dist/hooks/subagent-tracker/index.js.map +1 -1
- package/dist/hooks/todo-continuation/index.js +1 -1
- package/dist/hooks/todo-continuation/index.js.map +1 -1
- package/dist/hooks/wiki/__tests__/ingest.test.d.ts +5 -0
- package/dist/hooks/wiki/__tests__/ingest.test.d.ts.map +1 -0
- package/dist/hooks/wiki/__tests__/ingest.test.js +180 -0
- package/dist/hooks/wiki/__tests__/ingest.test.js.map +1 -0
- package/dist/hooks/wiki/__tests__/lint.test.d.ts +5 -0
- package/dist/hooks/wiki/__tests__/lint.test.d.ts.map +1 -0
- package/dist/hooks/wiki/__tests__/lint.test.js +162 -0
- package/dist/hooks/wiki/__tests__/lint.test.js.map +1 -0
- package/dist/hooks/wiki/__tests__/query.test.d.ts +5 -0
- package/dist/hooks/wiki/__tests__/query.test.d.ts.map +1 -0
- package/dist/hooks/wiki/__tests__/query.test.js +119 -0
- package/dist/hooks/wiki/__tests__/query.test.js.map +1 -0
- package/dist/hooks/wiki/__tests__/session-hooks.test.d.ts +5 -0
- package/dist/hooks/wiki/__tests__/session-hooks.test.d.ts.map +1 -0
- package/dist/hooks/wiki/__tests__/session-hooks.test.js +40 -0
- package/dist/hooks/wiki/__tests__/session-hooks.test.js.map +1 -0
- package/dist/hooks/wiki/__tests__/storage.test.d.ts +5 -0
- package/dist/hooks/wiki/__tests__/storage.test.d.ts.map +1 -0
- package/dist/hooks/wiki/__tests__/storage.test.js +277 -0
- package/dist/hooks/wiki/__tests__/storage.test.js.map +1 -0
- package/dist/hooks/wiki/index.d.ts +13 -0
- package/dist/hooks/wiki/index.d.ts.map +1 -0
- package/dist/hooks/wiki/index.js +16 -0
- package/dist/hooks/wiki/index.js.map +1 -0
- package/dist/hooks/wiki/ingest.d.ts +20 -0
- package/dist/hooks/wiki/ingest.d.ts.map +1 -0
- package/dist/hooks/wiki/ingest.js +115 -0
- package/dist/hooks/wiki/ingest.js.map +1 -0
- package/dist/hooks/wiki/lint.d.ts +25 -0
- package/dist/hooks/wiki/lint.d.ts.map +1 -0
- package/dist/hooks/wiki/lint.js +166 -0
- package/dist/hooks/wiki/lint.js.map +1 -0
- package/dist/hooks/wiki/query.d.ts +27 -0
- package/dist/hooks/wiki/query.d.ts.map +1 -0
- package/dist/hooks/wiki/query.js +97 -0
- package/dist/hooks/wiki/query.js.map +1 -0
- package/dist/hooks/wiki/session-hooks.d.ts +42 -0
- package/dist/hooks/wiki/session-hooks.d.ts.map +1 -0
- package/dist/hooks/wiki/session-hooks.js +228 -0
- package/dist/hooks/wiki/session-hooks.js.map +1 -0
- package/dist/hooks/wiki/storage.d.ts +73 -0
- package/dist/hooks/wiki/storage.d.ts.map +1 -0
- package/dist/hooks/wiki/storage.js +343 -0
- package/dist/hooks/wiki/storage.js.map +1 -0
- package/dist/hooks/wiki/types.d.ts +136 -0
- package/dist/hooks/wiki/types.d.ts.map +1 -0
- package/dist/hooks/wiki/types.js +19 -0
- package/dist/hooks/wiki/types.js.map +1 -0
- package/dist/hud/custom-rate-provider.js +1 -1
- package/dist/hud/custom-rate-provider.js.map +1 -1
- package/dist/hud/elements/api-key-source.js +1 -1
- package/dist/hud/elements/api-key-source.js.map +1 -1
- package/dist/hud/index.js +1 -1
- package/dist/hud/index.js.map +1 -1
- package/dist/hud/state.js +1 -1
- package/dist/hud/state.js.map +1 -1
- package/dist/hud/usage-api.d.ts.map +1 -1
- package/dist/hud/usage-api.js +6 -2
- package/dist/hud/usage-api.js.map +1 -1
- package/dist/installer/__tests__/standalone-hook-reconcile.test.js +3 -0
- package/dist/installer/__tests__/standalone-hook-reconcile.test.js.map +1 -1
- package/dist/installer/hooks.d.ts +0 -2
- package/dist/installer/hooks.d.ts.map +1 -1
- package/dist/installer/hooks.js +1 -5
- package/dist/installer/hooks.js.map +1 -1
- package/dist/installer/index.d.ts +3 -0
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +176 -32
- package/dist/installer/index.js.map +1 -1
- package/dist/installer/mcp-registry.js +2 -2
- package/dist/installer/mcp-registry.js.map +1 -1
- package/dist/lib/release-generation.d.ts +20 -0
- package/dist/lib/release-generation.d.ts.map +1 -0
- package/dist/lib/release-generation.js +198 -0
- package/dist/lib/release-generation.js.map +1 -0
- package/dist/lib/shared-memory.d.ts +2 -1
- package/dist/lib/shared-memory.d.ts.map +1 -1
- package/dist/lib/shared-memory.js +4 -2
- package/dist/lib/shared-memory.js.map +1 -1
- package/dist/lib/worktree-paths.d.ts.map +1 -1
- package/dist/lib/worktree-paths.js +36 -10
- package/dist/lib/worktree-paths.js.map +1 -1
- package/dist/mcp/omc-tools-server.d.ts +2 -0
- package/dist/mcp/omc-tools-server.d.ts.map +1 -1
- package/dist/mcp/omc-tools-server.js +9 -2
- package/dist/mcp/omc-tools-server.js.map +1 -1
- package/dist/notifications/__tests__/config-merge.test.js +1 -1
- package/dist/notifications/__tests__/config-merge.test.js.map +1 -1
- package/dist/notifications/__tests__/profiles.test.js +1 -1
- package/dist/notifications/__tests__/profiles.test.js.map +1 -1
- package/dist/notifications/config.js +1 -1
- package/dist/notifications/config.js.map +1 -1
- package/dist/notifications/hook-config.js +1 -1
- package/dist/notifications/hook-config.js.map +1 -1
- package/dist/openclaw/__tests__/config.test.js +1 -1
- package/dist/openclaw/__tests__/config.test.js.map +1 -1
- package/dist/openclaw/config.js +1 -1
- package/dist/openclaw/config.js.map +1 -1
- package/dist/skills/__tests__/mingw-escape.test.js +1 -1
- package/dist/skills/__tests__/mingw-escape.test.js.map +1 -1
- package/dist/team/__tests__/api-interop.dispatch.test.js +2 -1
- package/dist/team/__tests__/api-interop.dispatch.test.js.map +1 -1
- package/dist/team/__tests__/bridge-integration.test.js +5 -3
- package/dist/team/__tests__/bridge-integration.test.js.map +1 -1
- package/dist/team/__tests__/edge-cases.test.js +6 -7
- package/dist/team/__tests__/edge-cases.test.js.map +1 -1
- package/dist/team/__tests__/inbox-outbox.test.js +2 -2
- package/dist/team/__tests__/inbox-outbox.test.js.map +1 -1
- package/dist/team/__tests__/message-router.test.js +6 -5
- package/dist/team/__tests__/message-router.test.js.map +1 -1
- package/dist/team/__tests__/outbox-reader.test.js +2 -2
- package/dist/team/__tests__/outbox-reader.test.js.map +1 -1
- package/dist/team/__tests__/runtime-v2.dispatch.test.js +4 -4
- package/dist/team/__tests__/runtime-v2.dispatch.test.js.map +1 -1
- package/dist/team/__tests__/shell-affinity.test.js +16 -0
- package/dist/team/__tests__/shell-affinity.test.js.map +1 -1
- package/dist/team/__tests__/team-registration.test.js +3 -2
- package/dist/team/__tests__/team-registration.test.js.map +1 -1
- package/dist/team/__tests__/team-status.test.js +3 -3
- package/dist/team/__tests__/team-status.test.js.map +1 -1
- package/dist/team/__tests__/tmux-session.test.js +6 -1
- package/dist/team/__tests__/tmux-session.test.js.map +1 -1
- package/dist/team/bridge-entry.js +1 -1
- package/dist/team/bridge-entry.js.map +1 -1
- package/dist/team/inbox-outbox.js +1 -1
- package/dist/team/inbox-outbox.js.map +1 -1
- package/dist/team/message-router.js +1 -1
- package/dist/team/message-router.js.map +1 -1
- package/dist/team/outbox-reader.js +1 -1
- package/dist/team/outbox-reader.js.map +1 -1
- package/dist/team/runtime-v2.d.ts.map +1 -1
- package/dist/team/runtime-v2.js +6 -17
- package/dist/team/runtime-v2.js.map +1 -1
- package/dist/team/task-file-ops.js +1 -1
- package/dist/team/task-file-ops.js.map +1 -1
- package/dist/team/team-registration.js +1 -1
- package/dist/team/team-registration.js.map +1 -1
- package/dist/team/team-status.js +1 -1
- package/dist/team/team-status.js.map +1 -1
- package/dist/team/tmux-session.d.ts +1 -1
- package/dist/team/tmux-session.d.ts.map +1 -1
- package/dist/team/tmux-session.js +39 -4
- package/dist/team/tmux-session.js.map +1 -1
- package/dist/team/unified-team.js +1 -1
- package/dist/team/unified-team.js.map +1 -1
- package/dist/tools/shared-memory-tools.d.ts.map +1 -1
- package/dist/tools/shared-memory-tools.js +2 -1
- package/dist/tools/shared-memory-tools.js.map +1 -1
- package/dist/tools/skills-tools.d.ts.map +1 -1
- package/dist/tools/skills-tools.js +3 -2
- package/dist/tools/skills-tools.js.map +1 -1
- package/dist/tools/wiki-tools.d.ts +74 -0
- package/dist/tools/wiki-tools.d.ts.map +1 -0
- package/dist/tools/wiki-tools.js +370 -0
- package/dist/tools/wiki-tools.js.map +1 -0
- package/dist/utils/config-dir.d.ts +21 -1
- package/dist/utils/config-dir.d.ts.map +1 -1
- package/dist/utils/config-dir.js +45 -4
- package/dist/utils/config-dir.js.map +1 -1
- package/dist/utils/paths.d.ts +0 -5
- package/dist/utils/paths.d.ts.map +1 -1
- package/dist/utils/paths.js +1 -8
- package/dist/utils/paths.js.map +1 -1
- package/docs/CLAUDE.md +1 -1
- package/hooks/hooks.json +15 -0
- package/package.json +1 -1
- package/scripts/cleanup-orphans.mjs +2 -2
- package/scripts/context-guard-stop.mjs +10 -4
- package/scripts/find-node.sh +13 -1
- package/scripts/keyword-detector.mjs +9 -2
- package/scripts/lib/config-dir.cjs +31 -0
- package/scripts/lib/config-dir.mjs +29 -0
- package/scripts/lib/config-dir.sh +18 -0
- package/scripts/lib/pre-tool-enforcer-preflight.mjs +63 -0
- package/scripts/persistent-mode.cjs +29 -6
- package/scripts/persistent-mode.mjs +24 -4
- package/scripts/plugin-setup.mjs +18 -7
- package/scripts/post-tool-verifier.mjs +200 -7
- package/scripts/pre-tool-enforcer.mjs +15 -56
- package/scripts/release.ts +158 -224
- package/scripts/session-start.mjs +6 -4
- package/scripts/session-summary.mjs +6 -1
- package/scripts/setup-claude-md.sh +4 -2
- package/scripts/setup-progress.sh +4 -1
- package/scripts/skill-injector.mjs +2 -1
- package/scripts/sync-version.sh +3 -3
- package/scripts/test-pr25.sh +9 -5
- package/scripts/uninstall.sh +5 -2
- package/scripts/wiki-pre-compact.mjs +17 -0
- package/scripts/wiki-session-end.mjs +17 -0
- package/scripts/wiki-session-start.mjs +17 -0
- package/skills/cancel/SKILL.md +4 -4
- package/skills/configure-notifications/SKILL.md +12 -12
- package/skills/hud/SKILL.md +4 -4
- package/skills/learner/SKILL.md +1 -1
- package/skills/omc-doctor/SKILL.md +25 -25
- package/skills/omc-setup/SKILL.md +1 -1
- package/skills/omc-setup/phases/02-configure.md +2 -2
- package/skills/omc-setup/phases/03-integrations.md +7 -7
- package/skills/omc-setup/phases/04-welcome.md +3 -3
- package/skills/ralph/SKILL.md +6 -2
- package/skills/skill/SKILL.md +9 -9
- package/skills/team/SKILL.md +1 -1
- package/skills/wiki/SKILL.md +67 -0
- package/templates/hooks/keyword-detector.mjs +4 -2
- package/templates/hooks/lib/config-dir.mjs +29 -0
- package/templates/hooks/persistent-mode.mjs +24 -4
- package/templates/hooks/session-start.mjs +7 -4
package/bridge/runtime-cli.cjs
CHANGED
|
@@ -124,21 +124,43 @@ function getDefaultShell() {
|
|
|
124
124
|
return process.env.COMSPEC || "cmd.exe";
|
|
125
125
|
}
|
|
126
126
|
const shell = process.env.SHELL || "/bin/bash";
|
|
127
|
-
const name = (0,
|
|
127
|
+
const name = (0, import_path7.basename)(shell.replace(/\\/g, "/")).replace(/\.(exe|cmd|bat)$/i, "");
|
|
128
128
|
if (!SUPPORTED_POSIX_SHELLS.has(name)) {
|
|
129
129
|
return "/bin/sh";
|
|
130
130
|
}
|
|
131
131
|
return shell;
|
|
132
132
|
}
|
|
133
|
+
function pathEntries(envPath) {
|
|
134
|
+
return (envPath ?? "").split(process.platform === "win32" ? ";" : ":").map((entry) => entry.trim()).filter(Boolean);
|
|
135
|
+
}
|
|
136
|
+
function pathCandidateNames(candidatePath) {
|
|
137
|
+
const base = (0, import_path7.basename)(candidatePath.replace(/\\/g, "/"));
|
|
138
|
+
const bare = base.replace(/\.(exe|cmd|bat)$/i, "");
|
|
139
|
+
if (process.platform === "win32") {
|
|
140
|
+
return Array.from(/* @__PURE__ */ new Set([`${bare}.exe`, `${bare}.cmd`, `${bare}.bat`, bare]));
|
|
141
|
+
}
|
|
142
|
+
return Array.from(/* @__PURE__ */ new Set([base, bare]));
|
|
143
|
+
}
|
|
144
|
+
function resolveShellFromPath(candidatePath) {
|
|
145
|
+
for (const dir of pathEntries(process.env.PATH)) {
|
|
146
|
+
for (const name of pathCandidateNames(candidatePath)) {
|
|
147
|
+
const full = (0, import_path7.join)(dir, name);
|
|
148
|
+
if ((0, import_fs5.existsSync)(full)) return full;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
133
153
|
function resolveShellFromCandidates(paths, rcFile) {
|
|
134
154
|
for (const p of paths) {
|
|
135
155
|
if ((0, import_fs5.existsSync)(p)) return { shell: p, rcFile };
|
|
156
|
+
const resolvedFromPath = resolveShellFromPath(p);
|
|
157
|
+
if (resolvedFromPath) return { shell: resolvedFromPath, rcFile };
|
|
136
158
|
}
|
|
137
159
|
return null;
|
|
138
160
|
}
|
|
139
161
|
function resolveSupportedShellAffinity(shellPath) {
|
|
140
162
|
if (!shellPath) return null;
|
|
141
|
-
const name = (0,
|
|
163
|
+
const name = (0, import_path7.basename)(shellPath.replace(/\\/g, "/")).replace(/\.(exe|cmd|bat)$/i, "");
|
|
142
164
|
if (name !== "zsh" && name !== "bash") return null;
|
|
143
165
|
if (!(0, import_fs5.existsSync)(shellPath)) return null;
|
|
144
166
|
const home = process.env.HOME ?? "";
|
|
@@ -164,7 +186,7 @@ function escapeForCmdSet(value) {
|
|
|
164
186
|
return value.replace(/"/g, '""');
|
|
165
187
|
}
|
|
166
188
|
function shellNameFromPath(shellPath) {
|
|
167
|
-
const shellName = (0,
|
|
189
|
+
const shellName = (0, import_path7.basename)(shellPath.replace(/\\/g, "/"));
|
|
168
190
|
return shellName.replace(/\.(exe|cmd|bat)$/i, "");
|
|
169
191
|
}
|
|
170
192
|
function shellEscape(value) {
|
|
@@ -176,7 +198,7 @@ function assertSafeEnvKey(key) {
|
|
|
176
198
|
}
|
|
177
199
|
}
|
|
178
200
|
function isAbsoluteLaunchBinaryPath(value) {
|
|
179
|
-
return (0,
|
|
201
|
+
return (0, import_path7.isAbsolute)(value) || import_path7.win32.isAbsolute(value);
|
|
180
202
|
}
|
|
181
203
|
function assertSafeLaunchBinary(launchBinary) {
|
|
182
204
|
if (launchBinary.trim().length === 0) {
|
|
@@ -527,7 +549,7 @@ function paneLooksReady(captured) {
|
|
|
527
549
|
}
|
|
528
550
|
async function waitForPaneReady(paneId, opts = {}) {
|
|
529
551
|
const envTimeout = Number.parseInt(process.env.OMC_SHELL_READY_TIMEOUT_MS ?? "", 10);
|
|
530
|
-
const timeoutMs = Number.isFinite(opts.timeoutMs) && (opts.timeoutMs ?? 0) > 0 ? Number(opts.timeoutMs) : Number.isFinite(envTimeout) && envTimeout > 0 ? envTimeout :
|
|
552
|
+
const timeoutMs = Number.isFinite(opts.timeoutMs) && (opts.timeoutMs ?? 0) > 0 ? Number(opts.timeoutMs) : Number.isFinite(envTimeout) && envTimeout > 0 ? envTimeout : 3e4;
|
|
531
553
|
const pollIntervalMs = Number.isFinite(opts.pollIntervalMs) && (opts.pollIntervalMs ?? 0) > 0 ? Number(opts.pollIntervalMs) : 250;
|
|
532
554
|
const deadline = Date.now() + timeoutMs;
|
|
533
555
|
while (Date.now() < deadline) {
|
|
@@ -644,7 +666,12 @@ async function sendToWorker(_sessionName, paneId, message) {
|
|
|
644
666
|
await sendKey("C-m");
|
|
645
667
|
await sleep2(120);
|
|
646
668
|
await sendKey("C-m");
|
|
647
|
-
|
|
669
|
+
await sleep2(140);
|
|
670
|
+
const finalCheckCapture = await capturePaneAsync(paneId, execFileAsync2);
|
|
671
|
+
if (!finalCheckCapture || finalCheckCapture.trim() === "") {
|
|
672
|
+
return false;
|
|
673
|
+
}
|
|
674
|
+
return !paneTailContainsLiteralLine(finalCheckCapture, message);
|
|
648
675
|
} catch {
|
|
649
676
|
return false;
|
|
650
677
|
}
|
|
@@ -684,7 +711,7 @@ async function isWorkerAlive(paneId) {
|
|
|
684
711
|
async function killWorkerPanes(opts) {
|
|
685
712
|
const { paneIds, leaderPaneId, teamName, cwd, graceMs = 1e4 } = opts;
|
|
686
713
|
if (!paneIds.length) return;
|
|
687
|
-
const shutdownPath = (0,
|
|
714
|
+
const shutdownPath = (0, import_path7.join)(cwd, ".omc", "state", "team", teamName, "shutdown.json");
|
|
688
715
|
try {
|
|
689
716
|
await import_promises.default.writeFile(shutdownPath, JSON.stringify({ requestedAt: Date.now() }));
|
|
690
717
|
const aliveChecks = await Promise.all(paneIds.map((id) => isWorkerAlive(id)));
|
|
@@ -769,13 +796,13 @@ async function killTeamSession(sessionName2, workerPaneIds, leaderPaneId, option
|
|
|
769
796
|
} catch {
|
|
770
797
|
}
|
|
771
798
|
}
|
|
772
|
-
var import_child_process2, import_fs5,
|
|
799
|
+
var import_child_process2, import_fs5, import_path7, import_util, import_promises, sleep, TMUX_SESSION_PREFIX, promisifiedExec, promisifiedExecFile, SUPPORTED_POSIX_SHELLS, ZSH_CANDIDATES, BASH_CANDIDATES, DANGEROUS_LAUNCH_BINARY_CHARS;
|
|
773
800
|
var init_tmux_session = __esm({
|
|
774
801
|
"src/team/tmux-session.ts"() {
|
|
775
802
|
"use strict";
|
|
776
803
|
import_child_process2 = require("child_process");
|
|
777
804
|
import_fs5 = require("fs");
|
|
778
|
-
|
|
805
|
+
import_path7 = require("path");
|
|
779
806
|
import_util = require("util");
|
|
780
807
|
import_promises = __toESM(require("fs/promises"), 1);
|
|
781
808
|
init_team_name();
|
|
@@ -977,16 +1004,16 @@ __export(runtime_cli_exports, {
|
|
|
977
1004
|
module.exports = __toCommonJS(runtime_cli_exports);
|
|
978
1005
|
var import_fs18 = require("fs");
|
|
979
1006
|
var import_promises8 = require("fs/promises");
|
|
980
|
-
var
|
|
1007
|
+
var import_path19 = require("path");
|
|
981
1008
|
|
|
982
1009
|
// src/team/runtime.ts
|
|
983
1010
|
var import_promises3 = require("fs/promises");
|
|
984
|
-
var
|
|
1011
|
+
var import_path13 = require("path");
|
|
985
1012
|
var import_fs11 = require("fs");
|
|
986
1013
|
|
|
987
1014
|
// src/team/model-contract.ts
|
|
988
1015
|
var import_child_process = require("child_process");
|
|
989
|
-
var
|
|
1016
|
+
var import_path6 = require("path");
|
|
990
1017
|
init_team_name();
|
|
991
1018
|
|
|
992
1019
|
// src/agents/utils.ts
|
|
@@ -1054,17 +1081,43 @@ Prompt unavailable.`;
|
|
|
1054
1081
|
|
|
1055
1082
|
// src/config/loader.ts
|
|
1056
1083
|
var import_fs3 = require("fs");
|
|
1057
|
-
var
|
|
1084
|
+
var import_path4 = require("path");
|
|
1058
1085
|
|
|
1059
1086
|
// src/utils/paths.ts
|
|
1060
|
-
var
|
|
1087
|
+
var import_path3 = require("path");
|
|
1061
1088
|
var import_fs2 = require("fs");
|
|
1089
|
+
var import_os2 = require("os");
|
|
1090
|
+
|
|
1091
|
+
// src/utils/config-dir.ts
|
|
1092
|
+
var import_path2 = require("path");
|
|
1062
1093
|
var import_os = require("os");
|
|
1063
|
-
function
|
|
1094
|
+
function stripTrailingSep(p) {
|
|
1095
|
+
if (!p.endsWith(import_path2.sep)) {
|
|
1096
|
+
return p;
|
|
1097
|
+
}
|
|
1098
|
+
return p === (0, import_path2.parse)(p).root ? p : p.slice(0, -1);
|
|
1099
|
+
}
|
|
1100
|
+
function getClaudeConfigDir() {
|
|
1101
|
+
const home = (0, import_os.homedir)();
|
|
1102
|
+
const configured = process.env.CLAUDE_CONFIG_DIR?.trim();
|
|
1103
|
+
if (!configured) {
|
|
1104
|
+
return stripTrailingSep((0, import_path2.normalize)((0, import_path2.join)(home, ".claude")));
|
|
1105
|
+
}
|
|
1106
|
+
if (configured === "~") {
|
|
1107
|
+
return stripTrailingSep((0, import_path2.normalize)(home));
|
|
1108
|
+
}
|
|
1109
|
+
if (configured.startsWith("~/") || configured.startsWith("~\\")) {
|
|
1110
|
+
return stripTrailingSep((0, import_path2.normalize)((0, import_path2.join)(home, configured.slice(2))));
|
|
1111
|
+
}
|
|
1112
|
+
return stripTrailingSep((0, import_path2.normalize)(configured));
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
// src/utils/paths.ts
|
|
1116
|
+
function getConfigDir() {
|
|
1064
1117
|
if (process.platform === "win32") {
|
|
1065
|
-
return process.env.APPDATA || (0,
|
|
1118
|
+
return process.env.APPDATA || (0, import_path3.join)((0, import_os2.homedir)(), "AppData", "Roaming");
|
|
1066
1119
|
}
|
|
1067
|
-
return process.env.XDG_CONFIG_HOME || (0,
|
|
1120
|
+
return process.env.XDG_CONFIG_HOME || (0, import_path3.join)((0, import_os2.homedir)(), ".config");
|
|
1068
1121
|
}
|
|
1069
1122
|
var STALE_THRESHOLD_MS = 24 * 60 * 60 * 1e3;
|
|
1070
1123
|
|
|
@@ -1509,10 +1562,10 @@ function buildDefaultConfig() {
|
|
|
1509
1562
|
}
|
|
1510
1563
|
var DEFAULT_CONFIG = buildDefaultConfig();
|
|
1511
1564
|
function getConfigPaths() {
|
|
1512
|
-
const userConfigDir =
|
|
1565
|
+
const userConfigDir = getConfigDir();
|
|
1513
1566
|
return {
|
|
1514
|
-
user: (0,
|
|
1515
|
-
project: (0,
|
|
1567
|
+
user: (0, import_path4.join)(userConfigDir, "claude-omc", "config.jsonc"),
|
|
1568
|
+
project: (0, import_path4.join)(process.cwd(), ".claude", "omc.jsonc")
|
|
1516
1569
|
};
|
|
1517
1570
|
}
|
|
1518
1571
|
function loadJsoncFile(path4) {
|
|
@@ -2184,7 +2237,7 @@ function normalizeToCcAlias(model) {
|
|
|
2184
2237
|
|
|
2185
2238
|
// src/lib/security-config.ts
|
|
2186
2239
|
var import_fs4 = require("fs");
|
|
2187
|
-
var
|
|
2240
|
+
var import_path5 = require("path");
|
|
2188
2241
|
var DEFAULTS = {
|
|
2189
2242
|
restrictToolPaths: false,
|
|
2190
2243
|
pythonSandbox: false,
|
|
@@ -2206,8 +2259,8 @@ var STRICT_OVERRIDES = {
|
|
|
2206
2259
|
var cachedConfig = null;
|
|
2207
2260
|
function loadSecurityFromConfigFiles() {
|
|
2208
2261
|
const paths = [
|
|
2209
|
-
(0,
|
|
2210
|
-
(0,
|
|
2262
|
+
(0, import_path5.join)(process.cwd(), ".claude", "omc.jsonc"),
|
|
2263
|
+
(0, import_path5.join)(getConfigDir(), "claude-omc", "config.jsonc")
|
|
2211
2264
|
];
|
|
2212
2265
|
for (const configPath of paths) {
|
|
2213
2266
|
if (!(0, import_fs4.existsSync)(configPath)) continue;
|
|
@@ -2273,13 +2326,13 @@ function getTrustedPrefixes() {
|
|
|
2273
2326
|
trusted.push(`${home}/.nvm/`);
|
|
2274
2327
|
trusted.push(`${home}/.cargo/bin`);
|
|
2275
2328
|
}
|
|
2276
|
-
const custom = (process.env.OMC_TRUSTED_CLI_DIRS ?? "").split(":").map((part) => part.trim()).filter(Boolean).filter((part) => (0,
|
|
2329
|
+
const custom = (process.env.OMC_TRUSTED_CLI_DIRS ?? "").split(":").map((part) => part.trim()).filter(Boolean).filter((part) => (0, import_path6.isAbsolute)(part));
|
|
2277
2330
|
trusted.push(...custom);
|
|
2278
2331
|
return trusted;
|
|
2279
2332
|
}
|
|
2280
2333
|
function isTrustedPrefix(resolvedPath) {
|
|
2281
|
-
const normalized = (0,
|
|
2282
|
-
return getTrustedPrefixes().some((prefix) => normalized.startsWith((0,
|
|
2334
|
+
const normalized = (0, import_path6.normalize)(resolvedPath);
|
|
2335
|
+
return getTrustedPrefixes().some((prefix) => normalized.startsWith((0, import_path6.normalize)(prefix)));
|
|
2283
2336
|
}
|
|
2284
2337
|
function assertBinaryName(binary) {
|
|
2285
2338
|
if (!/^[A-Za-z0-9._-]+$/.test(binary)) {
|
|
@@ -2303,8 +2356,8 @@ function resolveCliBinaryPath(binary) {
|
|
|
2303
2356
|
if (!firstLine) {
|
|
2304
2357
|
throw new Error(`CLI binary '${binary}' not found in PATH`);
|
|
2305
2358
|
}
|
|
2306
|
-
const resolvedPath = (0,
|
|
2307
|
-
if (!(0,
|
|
2359
|
+
const resolvedPath = (0, import_path6.normalize)(firstLine);
|
|
2360
|
+
if (!(0, import_path6.isAbsolute)(resolvedPath)) {
|
|
2308
2361
|
throw new Error(`Resolved CLI binary '${binary}' to relative path`);
|
|
2309
2362
|
}
|
|
2310
2363
|
if (UNTRUSTED_PATH_PATTERNS.some((pattern) => pattern.test(resolvedPath))) {
|
|
@@ -2391,20 +2444,20 @@ function getContract(agentType) {
|
|
|
2391
2444
|
return contract;
|
|
2392
2445
|
}
|
|
2393
2446
|
function validateBinaryRef(binary) {
|
|
2394
|
-
if ((0,
|
|
2447
|
+
if ((0, import_path6.isAbsolute)(binary)) return;
|
|
2395
2448
|
if (/^[A-Za-z0-9._-]+$/.test(binary)) return;
|
|
2396
2449
|
throw new Error(`Unsafe CLI binary reference: ${binary}`);
|
|
2397
2450
|
}
|
|
2398
2451
|
function resolveBinaryPath(binary) {
|
|
2399
2452
|
validateBinaryRef(binary);
|
|
2400
|
-
if ((0,
|
|
2453
|
+
if ((0, import_path6.isAbsolute)(binary)) return binary;
|
|
2401
2454
|
try {
|
|
2402
2455
|
const resolver = process.platform === "win32" ? "where" : "which";
|
|
2403
2456
|
const result = (0, import_child_process.spawnSync)(resolver, [binary], { timeout: 5e3, encoding: "utf8" });
|
|
2404
2457
|
if (result.status !== 0) return binary;
|
|
2405
2458
|
const lines = result.stdout?.split(/\r?\n/).map((line) => line.trim()).filter(Boolean) ?? [];
|
|
2406
2459
|
const firstPath = lines[0];
|
|
2407
|
-
const isResolvedAbsolute = !!firstPath && ((0,
|
|
2460
|
+
const isResolvedAbsolute = !!firstPath && ((0, import_path6.isAbsolute)(firstPath) || import_path6.win32.isAbsolute(firstPath));
|
|
2408
2461
|
return isResolvedAbsolute ? firstPath : binary;
|
|
2409
2462
|
} catch {
|
|
2410
2463
|
return binary;
|
|
@@ -2501,32 +2554,32 @@ init_tmux_session();
|
|
|
2501
2554
|
|
|
2502
2555
|
// src/team/worker-bootstrap.ts
|
|
2503
2556
|
var import_promises2 = require("fs/promises");
|
|
2504
|
-
var
|
|
2557
|
+
var import_path9 = require("path");
|
|
2505
2558
|
|
|
2506
2559
|
// src/agents/prompt-helpers.ts
|
|
2507
2560
|
var import_fs6 = require("fs");
|
|
2508
|
-
var
|
|
2561
|
+
var import_path8 = require("path");
|
|
2509
2562
|
var import_url2 = require("url");
|
|
2510
2563
|
var import_meta2 = {};
|
|
2511
2564
|
function getPackageDir2() {
|
|
2512
2565
|
if (typeof __dirname !== "undefined" && __dirname) {
|
|
2513
|
-
const currentDirName = (0,
|
|
2514
|
-
const parentDirName = (0,
|
|
2566
|
+
const currentDirName = (0, import_path8.basename)(__dirname);
|
|
2567
|
+
const parentDirName = (0, import_path8.basename)((0, import_path8.dirname)(__dirname));
|
|
2515
2568
|
if (currentDirName === "bridge") {
|
|
2516
|
-
return (0,
|
|
2569
|
+
return (0, import_path8.join)(__dirname, "..");
|
|
2517
2570
|
}
|
|
2518
2571
|
if (currentDirName === "agents" && (parentDirName === "src" || parentDirName === "dist")) {
|
|
2519
|
-
return (0,
|
|
2572
|
+
return (0, import_path8.join)(__dirname, "..", "..");
|
|
2520
2573
|
}
|
|
2521
2574
|
}
|
|
2522
2575
|
try {
|
|
2523
2576
|
const __filename = (0, import_url2.fileURLToPath)(import_meta2.url);
|
|
2524
|
-
const __dirname2 = (0,
|
|
2525
|
-
const currentDirName = (0,
|
|
2577
|
+
const __dirname2 = (0, import_path8.dirname)(__filename);
|
|
2578
|
+
const currentDirName = (0, import_path8.basename)(__dirname2);
|
|
2526
2579
|
if (currentDirName === "bridge") {
|
|
2527
|
-
return (0,
|
|
2580
|
+
return (0, import_path8.join)(__dirname2, "..");
|
|
2528
2581
|
}
|
|
2529
|
-
return (0,
|
|
2582
|
+
return (0, import_path8.join)(__dirname2, "..", "..");
|
|
2530
2583
|
} catch {
|
|
2531
2584
|
}
|
|
2532
2585
|
return process.cwd();
|
|
@@ -2542,9 +2595,9 @@ function getValidAgentRoles() {
|
|
|
2542
2595
|
} catch {
|
|
2543
2596
|
}
|
|
2544
2597
|
try {
|
|
2545
|
-
const agentsDir = (0,
|
|
2598
|
+
const agentsDir = (0, import_path8.join)(getPackageDir2(), "agents");
|
|
2546
2599
|
const files = (0, import_fs6.readdirSync)(agentsDir);
|
|
2547
|
-
_cachedRoles = files.filter((f) => f.endsWith(".md")).map((f) => (0,
|
|
2600
|
+
_cachedRoles = files.filter((f) => f.endsWith(".md")).map((f) => (0, import_path8.basename)(f, ".md")).sort();
|
|
2548
2601
|
} catch (err) {
|
|
2549
2602
|
console.error("[prompt-injection] CRITICAL: Could not scan agents/ directory for role discovery:", err);
|
|
2550
2603
|
_cachedRoles = [];
|
|
@@ -2600,7 +2653,7 @@ function formatOmcCliInvocation(commandSuffix, options = {}) {
|
|
|
2600
2653
|
|
|
2601
2654
|
// src/team/worker-bootstrap.ts
|
|
2602
2655
|
function buildInstructionPath(...parts) {
|
|
2603
|
-
return (0,
|
|
2656
|
+
return (0, import_path9.join)(...parts).replaceAll("\\", "/");
|
|
2604
2657
|
}
|
|
2605
2658
|
function generateTriggerMessage(teamName, workerName2, teamStateRoot2 = ".omc/state") {
|
|
2606
2659
|
const inboxPath = buildInstructionPath(teamStateRoot2, "team", teamName, "workers", workerName2, "inbox.md");
|
|
@@ -2755,23 +2808,23 @@ ${bootstrapInstructions}
|
|
|
2755
2808
|
` : ""}`;
|
|
2756
2809
|
}
|
|
2757
2810
|
async function composeInitialInbox(teamName, workerName2, content, cwd) {
|
|
2758
|
-
const inboxPath = (0,
|
|
2759
|
-
await (0, import_promises2.mkdir)((0,
|
|
2811
|
+
const inboxPath = (0, import_path9.join)(cwd, `.omc/state/team/${teamName}/workers/${workerName2}/inbox.md`);
|
|
2812
|
+
await (0, import_promises2.mkdir)((0, import_path9.dirname)(inboxPath), { recursive: true });
|
|
2760
2813
|
await (0, import_promises2.writeFile)(inboxPath, content, "utf-8");
|
|
2761
2814
|
}
|
|
2762
2815
|
async function ensureWorkerStateDir(teamName, workerName2, cwd) {
|
|
2763
|
-
const workerDir = (0,
|
|
2816
|
+
const workerDir = (0, import_path9.join)(cwd, `.omc/state/team/${teamName}/workers/${workerName2}`);
|
|
2764
2817
|
await (0, import_promises2.mkdir)(workerDir, { recursive: true });
|
|
2765
|
-
const mailboxDir = (0,
|
|
2818
|
+
const mailboxDir = (0, import_path9.join)(cwd, `.omc/state/team/${teamName}/mailbox`);
|
|
2766
2819
|
await (0, import_promises2.mkdir)(mailboxDir, { recursive: true });
|
|
2767
|
-
const tasksDir = (0,
|
|
2820
|
+
const tasksDir = (0, import_path9.join)(cwd, `.omc/state/team/${teamName}/tasks`);
|
|
2768
2821
|
await (0, import_promises2.mkdir)(tasksDir, { recursive: true });
|
|
2769
2822
|
}
|
|
2770
2823
|
async function writeWorkerOverlay(params) {
|
|
2771
2824
|
const { teamName, workerName: workerName2, cwd } = params;
|
|
2772
2825
|
const overlay = generateWorkerOverlay(params);
|
|
2773
|
-
const overlayPath = (0,
|
|
2774
|
-
await (0, import_promises2.mkdir)((0,
|
|
2826
|
+
const overlayPath = (0, import_path9.join)(cwd, `.omc/state/team/${teamName}/workers/${workerName2}/AGENTS.md`);
|
|
2827
|
+
await (0, import_promises2.mkdir)((0, import_path9.dirname)(overlayPath), { recursive: true });
|
|
2775
2828
|
await (0, import_promises2.writeFile)(overlayPath, overlay, "utf-8");
|
|
2776
2829
|
return overlayPath;
|
|
2777
2830
|
}
|
|
@@ -2783,9 +2836,9 @@ var import_node_child_process = require("node:child_process");
|
|
|
2783
2836
|
|
|
2784
2837
|
// src/team/fs-utils.ts
|
|
2785
2838
|
var import_fs7 = require("fs");
|
|
2786
|
-
var
|
|
2839
|
+
var import_path10 = require("path");
|
|
2787
2840
|
function atomicWriteJson(filePath, data, mode = 384) {
|
|
2788
|
-
const dir = (0,
|
|
2841
|
+
const dir = (0, import_path10.dirname)(filePath);
|
|
2789
2842
|
if (!(0, import_fs7.existsSync)(dir)) (0, import_fs7.mkdirSync)(dir, { recursive: true, mode: 448 });
|
|
2790
2843
|
const tmpPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
2791
2844
|
(0, import_fs7.writeFileSync)(tmpPath, JSON.stringify(data, null, 2) + "\n", { encoding: "utf-8", mode });
|
|
@@ -2798,20 +2851,20 @@ function safeRealpath(p) {
|
|
|
2798
2851
|
try {
|
|
2799
2852
|
return (0, import_fs7.realpathSync)(p);
|
|
2800
2853
|
} catch {
|
|
2801
|
-
const parent = (0,
|
|
2802
|
-
const name = (0,
|
|
2854
|
+
const parent = (0, import_path10.dirname)(p);
|
|
2855
|
+
const name = (0, import_path10.basename)(p);
|
|
2803
2856
|
try {
|
|
2804
|
-
return (0,
|
|
2857
|
+
return (0, import_path10.resolve)((0, import_fs7.realpathSync)(parent), name);
|
|
2805
2858
|
} catch {
|
|
2806
|
-
return (0,
|
|
2859
|
+
return (0, import_path10.resolve)(p);
|
|
2807
2860
|
}
|
|
2808
2861
|
}
|
|
2809
2862
|
}
|
|
2810
2863
|
function validateResolvedPath(resolvedPath, expectedBase) {
|
|
2811
2864
|
const absResolved = safeRealpath(resolvedPath);
|
|
2812
2865
|
const absBase = safeRealpath(expectedBase);
|
|
2813
|
-
const rel = (0,
|
|
2814
|
-
if (rel.startsWith("..") || (0,
|
|
2866
|
+
const rel = (0, import_path10.relative)(absBase, absResolved);
|
|
2867
|
+
if (rel.startsWith("..") || (0, import_path10.resolve)(absBase, rel) !== absResolved) {
|
|
2815
2868
|
throw new Error(`Path traversal detected: "${resolvedPath}" escapes base "${expectedBase}"`);
|
|
2816
2869
|
}
|
|
2817
2870
|
}
|
|
@@ -2881,12 +2934,12 @@ function cleanupTeamWorktrees(teamName, repoRoot) {
|
|
|
2881
2934
|
|
|
2882
2935
|
// src/team/task-file-ops.ts
|
|
2883
2936
|
var import_fs10 = require("fs");
|
|
2884
|
-
var
|
|
2937
|
+
var import_path12 = require("path");
|
|
2885
2938
|
init_tmux_session();
|
|
2886
2939
|
init_platform();
|
|
2887
2940
|
|
|
2888
2941
|
// src/team/state-paths.ts
|
|
2889
|
-
var
|
|
2942
|
+
var import_path11 = require("path");
|
|
2890
2943
|
function normalizeTaskFileStem(taskId) {
|
|
2891
2944
|
const trimmed = String(taskId).trim().replace(/\.json$/i, "");
|
|
2892
2945
|
if (/^task-\d+$/.test(trimmed)) return trimmed;
|
|
@@ -2926,16 +2979,16 @@ var TeamPaths = {
|
|
|
2926
2979
|
shutdownRequest: (teamName, workerName2) => `.omc/state/team/${teamName}/workers/${workerName2}/shutdown-request.json`
|
|
2927
2980
|
};
|
|
2928
2981
|
function absPath(cwd, relativePath) {
|
|
2929
|
-
return (0,
|
|
2982
|
+
return (0, import_path11.isAbsolute)(relativePath) ? relativePath : (0, import_path11.join)(cwd, relativePath);
|
|
2930
2983
|
}
|
|
2931
2984
|
function teamStateRoot(cwd, teamName) {
|
|
2932
|
-
return (0,
|
|
2985
|
+
return (0, import_path11.join)(cwd, TeamPaths.root(teamName));
|
|
2933
2986
|
}
|
|
2934
2987
|
function getTaskStoragePath(cwd, teamName, taskId) {
|
|
2935
2988
|
if (taskId !== void 0) {
|
|
2936
|
-
return (0,
|
|
2989
|
+
return (0, import_path11.join)(cwd, TeamPaths.taskFile(teamName, taskId));
|
|
2937
2990
|
}
|
|
2938
|
-
return (0,
|
|
2991
|
+
return (0, import_path11.join)(cwd, TeamPaths.tasks(teamName));
|
|
2939
2992
|
}
|
|
2940
2993
|
|
|
2941
2994
|
// src/team/task-file-ops.ts
|
|
@@ -2944,7 +2997,7 @@ function acquireTaskLock(teamName, taskId, opts) {
|
|
|
2944
2997
|
const staleLockMs = opts?.staleLockMs ?? DEFAULT_STALE_LOCK_MS2;
|
|
2945
2998
|
const dir = canonicalTasksDir(teamName, opts?.cwd);
|
|
2946
2999
|
ensureDirWithMode(dir);
|
|
2947
|
-
const lockPath = (0,
|
|
3000
|
+
const lockPath = (0, import_path12.join)(dir, `${sanitizeTaskId(taskId)}.lock`);
|
|
2948
3001
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
2949
3002
|
try {
|
|
2950
3003
|
const fd = (0, import_fs10.openSync)(lockPath, import_fs10.constants.O_CREAT | import_fs10.constants.O_EXCL | import_fs10.constants.O_WRONLY, 384);
|
|
@@ -3015,11 +3068,11 @@ function sanitizeTaskId(taskId) {
|
|
|
3015
3068
|
function canonicalTasksDir(teamName, cwd) {
|
|
3016
3069
|
const root = cwd ?? process.cwd();
|
|
3017
3070
|
const dir = getTaskStoragePath(root, sanitizeName(teamName));
|
|
3018
|
-
validateResolvedPath(dir, (0,
|
|
3071
|
+
validateResolvedPath(dir, (0, import_path12.join)(root, ".omc", "state", "team"));
|
|
3019
3072
|
return dir;
|
|
3020
3073
|
}
|
|
3021
3074
|
function failureSidecarPath(teamName, taskId, cwd) {
|
|
3022
|
-
return (0,
|
|
3075
|
+
return (0, import_path12.join)(canonicalTasksDir(teamName, cwd), `${sanitizeTaskId(taskId)}.failure.json`);
|
|
3023
3076
|
}
|
|
3024
3077
|
function writeTaskFailure(teamName, taskId, error, opts) {
|
|
3025
3078
|
const filePath = failureSidecarPath(teamName, taskId, opts?.cwd);
|
|
@@ -3051,10 +3104,10 @@ function workerName(index) {
|
|
|
3051
3104
|
}
|
|
3052
3105
|
function stateRoot(cwd, teamName) {
|
|
3053
3106
|
validateTeamName(teamName);
|
|
3054
|
-
return (0,
|
|
3107
|
+
return (0, import_path13.join)(cwd, `.omc/state/team/${teamName}`);
|
|
3055
3108
|
}
|
|
3056
3109
|
async function writeJson(filePath, data) {
|
|
3057
|
-
await (0, import_promises3.mkdir)((0,
|
|
3110
|
+
await (0, import_promises3.mkdir)((0, import_path13.join)(filePath, ".."), { recursive: true });
|
|
3058
3111
|
await (0, import_promises3.writeFile)(filePath, JSON.stringify(data, null, 2), "utf-8");
|
|
3059
3112
|
}
|
|
3060
3113
|
async function readJsonSafe(filePath) {
|
|
@@ -3090,13 +3143,13 @@ function parseWorkerIndex(workerNameValue) {
|
|
|
3090
3143
|
return Number.isFinite(parsed) && parsed >= 0 ? parsed : 0;
|
|
3091
3144
|
}
|
|
3092
3145
|
function taskPath(root, taskId) {
|
|
3093
|
-
return (0,
|
|
3146
|
+
return (0, import_path13.join)(root, "tasks", `${taskId}.json`);
|
|
3094
3147
|
}
|
|
3095
3148
|
async function writePanesTrackingFileIfPresent(runtime) {
|
|
3096
3149
|
const jobId = process.env.OMC_JOB_ID;
|
|
3097
3150
|
const omcJobsDir = process.env.OMC_JOBS_DIR;
|
|
3098
3151
|
if (!jobId || !omcJobsDir) return;
|
|
3099
|
-
const panesPath = (0,
|
|
3152
|
+
const panesPath = (0, import_path13.join)(omcJobsDir, `${jobId}-panes.json`);
|
|
3100
3153
|
const tempPath = `${panesPath}.tmp`;
|
|
3101
3154
|
await (0, import_promises3.writeFile)(
|
|
3102
3155
|
tempPath,
|
|
@@ -3250,12 +3303,12 @@ async function startTeam(config) {
|
|
|
3250
3303
|
resolvedBinaryPaths[agentType] = resolveValidatedBinaryPath(agentType);
|
|
3251
3304
|
}
|
|
3252
3305
|
const root = stateRoot(cwd, teamName);
|
|
3253
|
-
await (0, import_promises3.mkdir)((0,
|
|
3254
|
-
await (0, import_promises3.mkdir)((0,
|
|
3255
|
-
await writeJson((0,
|
|
3306
|
+
await (0, import_promises3.mkdir)((0, import_path13.join)(root, "tasks"), { recursive: true });
|
|
3307
|
+
await (0, import_promises3.mkdir)((0, import_path13.join)(root, "mailbox"), { recursive: true });
|
|
3308
|
+
await writeJson((0, import_path13.join)(root, "config.json"), config);
|
|
3256
3309
|
for (let i = 0; i < tasks.length; i++) {
|
|
3257
3310
|
const taskId = String(i + 1);
|
|
3258
|
-
await writeJson((0,
|
|
3311
|
+
await writeJson((0, import_path13.join)(root, "tasks", `${taskId}.json`), {
|
|
3259
3312
|
id: taskId,
|
|
3260
3313
|
subject: tasks[i].subject,
|
|
3261
3314
|
description: tasks[i].description,
|
|
@@ -3300,7 +3353,7 @@ async function startTeam(config) {
|
|
|
3300
3353
|
resolvedBinaryPaths,
|
|
3301
3354
|
ownsWindow: session.sessionMode !== "split-pane"
|
|
3302
3355
|
};
|
|
3303
|
-
await writeJson((0,
|
|
3356
|
+
await writeJson((0, import_path13.join)(root, "config.json"), runtime.config);
|
|
3304
3357
|
const maxConcurrentWorkers = agentTypes.length;
|
|
3305
3358
|
for (let i = 0; i < maxConcurrentWorkers; i++) {
|
|
3306
3359
|
const taskIndex = await nextPendingTaskIndex(runtime);
|
|
@@ -3318,9 +3371,9 @@ async function monitorTeam(teamName, cwd, workerPaneIds) {
|
|
|
3318
3371
|
const taskCounts = { pending: 0, inProgress: 0, completed: 0, failed: 0 };
|
|
3319
3372
|
try {
|
|
3320
3373
|
const { readdir: readdir2 } = await import("fs/promises");
|
|
3321
|
-
const taskFiles = await readdir2((0,
|
|
3374
|
+
const taskFiles = await readdir2((0, import_path13.join)(root, "tasks"));
|
|
3322
3375
|
for (const f of taskFiles.filter((f2) => f2.endsWith(".json"))) {
|
|
3323
|
-
const task = await readJsonSafe((0,
|
|
3376
|
+
const task = await readJsonSafe((0, import_path13.join)(root, "tasks", f));
|
|
3324
3377
|
if (task?.status === "pending") taskCounts.pending++;
|
|
3325
3378
|
else if (task?.status === "in_progress") taskCounts.inProgress++;
|
|
3326
3379
|
else if (task?.status === "completed") taskCounts.completed++;
|
|
@@ -3336,7 +3389,7 @@ async function monitorTeam(teamName, cwd, workerPaneIds) {
|
|
|
3336
3389
|
const wName = `worker-${i + 1}`;
|
|
3337
3390
|
const paneId = workerPaneIds[i];
|
|
3338
3391
|
const alive = await isWorkerAlive(paneId);
|
|
3339
|
-
const heartbeatPath = (0,
|
|
3392
|
+
const heartbeatPath = (0, import_path13.join)(root, "workers", wName, "heartbeat.json");
|
|
3340
3393
|
const heartbeat = await readJsonSafe(heartbeatPath);
|
|
3341
3394
|
let stalled = false;
|
|
3342
3395
|
if (heartbeat?.updatedAt) {
|
|
@@ -3391,14 +3444,14 @@ function watchdogCliWorkers(runtime, intervalMs) {
|
|
|
3391
3444
|
const root = stateRoot(runtime.cwd, runtime.teamName);
|
|
3392
3445
|
const [doneSignals, aliveResults] = await Promise.all([
|
|
3393
3446
|
Promise.all(workers.map(([wName]) => {
|
|
3394
|
-
const donePath = (0,
|
|
3447
|
+
const donePath = (0, import_path13.join)(root, "workers", wName, "done.json");
|
|
3395
3448
|
return readJsonSafe(donePath);
|
|
3396
3449
|
})),
|
|
3397
3450
|
Promise.all(workers.map(([, active]) => isWorkerAlive(active.paneId)))
|
|
3398
3451
|
]);
|
|
3399
3452
|
for (let i = 0; i < workers.length; i++) {
|
|
3400
3453
|
const [wName, active] = workers[i];
|
|
3401
|
-
const donePath = (0,
|
|
3454
|
+
const donePath = (0, import_path13.join)(root, "workers", wName, "done.json");
|
|
3402
3455
|
const signal = doneSignals[i];
|
|
3403
3456
|
if (signal) {
|
|
3404
3457
|
unresponsiveCounts.delete(wName);
|
|
@@ -3434,7 +3487,7 @@ function watchdogCliWorkers(runtime, intervalMs) {
|
|
|
3434
3487
|
}
|
|
3435
3488
|
continue;
|
|
3436
3489
|
}
|
|
3437
|
-
const heartbeatPath = (0,
|
|
3490
|
+
const heartbeatPath = (0, import_path13.join)(root, "workers", wName, "heartbeat.json");
|
|
3438
3491
|
const heartbeat = await readJsonSafe(heartbeatPath);
|
|
3439
3492
|
const isStalled = heartbeat?.updatedAt ? Date.now() - new Date(heartbeat.updatedAt).getTime() > 6e4 : false;
|
|
3440
3493
|
if (isStalled) {
|
|
@@ -3469,7 +3522,7 @@ function watchdogCliWorkers(runtime, intervalMs) {
|
|
|
3469
3522
|
console.warn(`[watchdog] ${consecutiveFailures} consecutive failures \u2014 marking team as failed`);
|
|
3470
3523
|
try {
|
|
3471
3524
|
const root = stateRoot(runtime.cwd, runtime.teamName);
|
|
3472
|
-
await writeJson((0,
|
|
3525
|
+
await writeJson((0, import_path13.join)(root, "watchdog-failed.json"), {
|
|
3473
3526
|
failedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3474
3527
|
consecutiveFailures,
|
|
3475
3528
|
lastError: err instanceof Error ? err.message : String(err)
|
|
@@ -3615,11 +3668,11 @@ async function killWorkerPane(runtime, workerNameValue, paneId) {
|
|
|
3615
3668
|
}
|
|
3616
3669
|
async function shutdownTeam(teamName, sessionName2, cwd, timeoutMs = 3e4, workerPaneIds, leaderPaneId, ownsWindow) {
|
|
3617
3670
|
const root = stateRoot(cwd, teamName);
|
|
3618
|
-
await writeJson((0,
|
|
3671
|
+
await writeJson((0, import_path13.join)(root, "shutdown.json"), {
|
|
3619
3672
|
requestedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3620
3673
|
teamName
|
|
3621
3674
|
});
|
|
3622
|
-
const configData = await readJsonSafe((0,
|
|
3675
|
+
const configData = await readJsonSafe((0, import_path13.join)(root, "config.json"));
|
|
3623
3676
|
const CLI_AGENT_TYPES = /* @__PURE__ */ new Set(["claude", "codex", "gemini"]);
|
|
3624
3677
|
const agentTypes = configData?.agentTypes ?? [];
|
|
3625
3678
|
const isCliWorkerTeam = agentTypes.length > 0 && agentTypes.every((t) => CLI_AGENT_TYPES.has(t));
|
|
@@ -3629,7 +3682,7 @@ async function shutdownTeam(teamName, sessionName2, cwd, timeoutMs = 3e4, worker
|
|
|
3629
3682
|
const expectedAcks = Array.from({ length: workerCount }, (_, i) => `worker-${i + 1}`);
|
|
3630
3683
|
while (Date.now() < deadline && expectedAcks.length > 0) {
|
|
3631
3684
|
for (const wName of [...expectedAcks]) {
|
|
3632
|
-
const ackPath = (0,
|
|
3685
|
+
const ackPath = (0, import_path13.join)(root, "workers", wName, "shutdown-ack.json");
|
|
3633
3686
|
if ((0, import_fs11.existsSync)(ackPath)) {
|
|
3634
3687
|
expectedAcks.splice(expectedAcks.indexOf(wName), 1);
|
|
3635
3688
|
}
|
|
@@ -3654,7 +3707,7 @@ async function shutdownTeam(teamName, sessionName2, cwd, timeoutMs = 3e4, worker
|
|
|
3654
3707
|
|
|
3655
3708
|
// src/team/events.ts
|
|
3656
3709
|
var import_crypto = require("crypto");
|
|
3657
|
-
var
|
|
3710
|
+
var import_path14 = require("path");
|
|
3658
3711
|
var import_promises4 = require("fs/promises");
|
|
3659
3712
|
var import_fs12 = require("fs");
|
|
3660
3713
|
|
|
@@ -3689,7 +3742,7 @@ async function appendTeamEvent(teamName, event, cwd) {
|
|
|
3689
3742
|
...event
|
|
3690
3743
|
};
|
|
3691
3744
|
const p = absPath(cwd, TeamPaths.events(teamName));
|
|
3692
|
-
await (0, import_promises4.mkdir)((0,
|
|
3745
|
+
await (0, import_promises4.mkdir)((0, import_path14.dirname)(p), { recursive: true });
|
|
3693
3746
|
await (0, import_promises4.appendFile)(p, `${JSON.stringify(full)}
|
|
3694
3747
|
`, "utf8");
|
|
3695
3748
|
return full;
|
|
@@ -3787,7 +3840,7 @@ function deriveTeamLeaderGuidance(input) {
|
|
|
3787
3840
|
|
|
3788
3841
|
// src/hooks/factcheck/checks.ts
|
|
3789
3842
|
var import_fs13 = require("fs");
|
|
3790
|
-
var
|
|
3843
|
+
var import_path15 = require("path");
|
|
3791
3844
|
|
|
3792
3845
|
// src/hooks/factcheck/types.ts
|
|
3793
3846
|
var REQUIRED_FIELDS = /* @__PURE__ */ new Set([
|
|
@@ -3896,8 +3949,8 @@ function checkCommands(claims, policy) {
|
|
|
3896
3949
|
function checkCwdParity(claimsCwd, runtimeCwd, mode, policy) {
|
|
3897
3950
|
const enforceCwd = policy.warn_on_cwd_mismatch && (mode !== "quick" || policy.enforce_cwd_parity_in_quick);
|
|
3898
3951
|
if (!enforceCwd || !claimsCwd) return null;
|
|
3899
|
-
const claimsCwdCanonical = (0,
|
|
3900
|
-
const runtimeCwdCanonical = (0,
|
|
3952
|
+
const claimsCwdCanonical = (0, import_path15.resolve)(claimsCwd);
|
|
3953
|
+
const runtimeCwdCanonical = (0, import_path15.resolve)(runtimeCwd);
|
|
3901
3954
|
if (claimsCwdCanonical !== runtimeCwdCanonical) {
|
|
3902
3955
|
const severity = mode === "strict" ? "FAIL" : "WARN";
|
|
3903
3956
|
return {
|
|
@@ -3910,12 +3963,12 @@ function checkCwdParity(claimsCwd, runtimeCwd, mode, policy) {
|
|
|
3910
3963
|
}
|
|
3911
3964
|
|
|
3912
3965
|
// src/hooks/factcheck/config.ts
|
|
3913
|
-
var
|
|
3966
|
+
var import_os3 = require("os");
|
|
3914
3967
|
var DEFAULT_FACTCHECK_POLICY = {
|
|
3915
3968
|
enabled: false,
|
|
3916
3969
|
mode: "quick",
|
|
3917
3970
|
strict_project_patterns: [],
|
|
3918
|
-
forbidden_path_prefixes: ["${
|
|
3971
|
+
forbidden_path_prefixes: ["${CLAUDE_CONFIG_DIR}/plugins/cache/omc/"],
|
|
3919
3972
|
forbidden_path_substrings: ["/.omc/", ".omc-config.json"],
|
|
3920
3973
|
readonly_command_prefixes: [
|
|
3921
3974
|
"ls ",
|
|
@@ -3947,9 +4000,9 @@ var DEFAULT_GUARDS_CONFIG = {
|
|
|
3947
4000
|
sentinel: { ...DEFAULT_SENTINEL_POLICY }
|
|
3948
4001
|
};
|
|
3949
4002
|
function expandTokens(value, workspace) {
|
|
3950
|
-
const home = (0,
|
|
4003
|
+
const home = (0, import_os3.homedir)();
|
|
3951
4004
|
const ws = workspace ?? process.env.OMC_WORKSPACE ?? process.cwd();
|
|
3952
|
-
return value.replace(/\$\{HOME\}/g, home).replace(/\$\{WORKSPACE\}/g, ws);
|
|
4005
|
+
return value.replace(/\$\{HOME\}/g, home).replace(/\$\{WORKSPACE\}/g, ws).replace(/\$\{CLAUDE_CONFIG_DIR\}/g, getClaudeConfigDir());
|
|
3953
4006
|
}
|
|
3954
4007
|
function expandTokensDeep(obj, workspace) {
|
|
3955
4008
|
if (typeof obj === "string") {
|
|
@@ -4303,7 +4356,7 @@ async function waitForSentinelReadiness(options = {}) {
|
|
|
4303
4356
|
|
|
4304
4357
|
// src/team/runtime-v2.ts
|
|
4305
4358
|
var import_child_process5 = require("child_process");
|
|
4306
|
-
var
|
|
4359
|
+
var import_path18 = require("path");
|
|
4307
4360
|
var import_fs17 = require("fs");
|
|
4308
4361
|
var import_promises7 = require("fs/promises");
|
|
4309
4362
|
var import_perf_hooks = require("perf_hooks");
|
|
@@ -4368,7 +4421,7 @@ function pickBestWorker(task, workers, loadMap) {
|
|
|
4368
4421
|
// src/team/monitor.ts
|
|
4369
4422
|
var import_fs15 = require("fs");
|
|
4370
4423
|
var import_promises5 = require("fs/promises");
|
|
4371
|
-
var
|
|
4424
|
+
var import_path16 = require("path");
|
|
4372
4425
|
|
|
4373
4426
|
// src/team/governance.ts
|
|
4374
4427
|
var DEFAULT_TEAM_TRANSPORT_POLICY = {
|
|
@@ -4516,7 +4569,7 @@ async function readJsonSafe2(filePath) {
|
|
|
4516
4569
|
}
|
|
4517
4570
|
async function writeAtomic(filePath, data) {
|
|
4518
4571
|
const { writeFile: writeFile6 } = await import("fs/promises");
|
|
4519
|
-
await (0, import_promises5.mkdir)((0,
|
|
4572
|
+
await (0, import_promises5.mkdir)((0, import_path16.dirname)(filePath), { recursive: true });
|
|
4520
4573
|
const tmpPath = `${filePath}.tmp.${process.pid}.${Date.now()}`;
|
|
4521
4574
|
await writeFile6(tmpPath, data, "utf-8");
|
|
4522
4575
|
const { rename: rename4 } = await import("fs/promises");
|
|
@@ -4722,7 +4775,7 @@ init_tmux_session();
|
|
|
4722
4775
|
var import_crypto2 = require("crypto");
|
|
4723
4776
|
var import_fs16 = require("fs");
|
|
4724
4777
|
var import_promises6 = require("fs/promises");
|
|
4725
|
-
var
|
|
4778
|
+
var import_path17 = require("path");
|
|
4726
4779
|
|
|
4727
4780
|
// src/team/contracts.ts
|
|
4728
4781
|
var WORKER_NAME_SAFE_PATTERN = /^[a-z0-9][a-z0-9-]{0,63}$/;
|
|
@@ -4757,12 +4810,12 @@ async function withDispatchLock(teamName, cwd, fn) {
|
|
|
4757
4810
|
const root = absPath(cwd, TeamPaths.root(teamName));
|
|
4758
4811
|
if (!(0, import_fs16.existsSync)(root)) throw new Error(`Team ${teamName} not found`);
|
|
4759
4812
|
const lockDir = absPath(cwd, TeamPaths.dispatchLockDir(teamName));
|
|
4760
|
-
const ownerPath = (0,
|
|
4813
|
+
const ownerPath = (0, import_path17.join)(lockDir, "owner");
|
|
4761
4814
|
const ownerToken = `${process.pid}.${Date.now()}.${Math.random().toString(16).slice(2)}`;
|
|
4762
4815
|
const timeoutMs = resolveDispatchLockTimeoutMs(process.env);
|
|
4763
4816
|
const deadline = Date.now() + timeoutMs;
|
|
4764
4817
|
let pollMs = DISPATCH_LOCK_INITIAL_POLL_MS;
|
|
4765
|
-
await (0, import_promises6.mkdir)((0,
|
|
4818
|
+
await (0, import_promises6.mkdir)((0, import_path17.dirname)(lockDir), { recursive: true });
|
|
4766
4819
|
while (true) {
|
|
4767
4820
|
try {
|
|
4768
4821
|
await (0, import_promises6.mkdir)(lockDir, { recursive: false });
|
|
@@ -4820,7 +4873,7 @@ async function readDispatchRequestsFromFile(teamName, cwd) {
|
|
|
4820
4873
|
}
|
|
4821
4874
|
async function writeDispatchRequestsToFile(teamName, requests, cwd) {
|
|
4822
4875
|
const path4 = absPath(cwd, TeamPaths.dispatchRequests(teamName));
|
|
4823
|
-
const dir = (0,
|
|
4876
|
+
const dir = (0, import_path17.dirname)(path4);
|
|
4824
4877
|
ensureDirWithMode(dir);
|
|
4825
4878
|
atomicWriteJson(path4, requests);
|
|
4826
4879
|
}
|
|
@@ -5283,30 +5336,15 @@ async function spawnV2Worker(opts) {
|
|
|
5283
5336
|
opts.teamName,
|
|
5284
5337
|
opts.workerName,
|
|
5285
5338
|
opts.taskId,
|
|
5286
|
-
opts.cwd
|
|
5339
|
+
opts.cwd,
|
|
5340
|
+
6
|
|
5287
5341
|
);
|
|
5288
5342
|
if (!settled) {
|
|
5289
|
-
|
|
5290
|
-
|
|
5291
|
-
|
|
5292
|
-
|
|
5293
|
-
|
|
5294
|
-
startupFailureReason: `${renotified.reason}:startup_evidence_missing`
|
|
5295
|
-
};
|
|
5296
|
-
}
|
|
5297
|
-
const settledAfterRetry = await waitForWorkerStartupEvidence(
|
|
5298
|
-
opts.teamName,
|
|
5299
|
-
opts.workerName,
|
|
5300
|
-
opts.taskId,
|
|
5301
|
-
opts.cwd
|
|
5302
|
-
);
|
|
5303
|
-
if (!settledAfterRetry) {
|
|
5304
|
-
return {
|
|
5305
|
-
paneId,
|
|
5306
|
-
startupAssigned: false,
|
|
5307
|
-
startupFailureReason: "claude_startup_evidence_missing"
|
|
5308
|
-
};
|
|
5309
|
-
}
|
|
5343
|
+
return {
|
|
5344
|
+
paneId,
|
|
5345
|
+
startupAssigned: false,
|
|
5346
|
+
startupFailureReason: "claude_startup_evidence_missing"
|
|
5347
|
+
};
|
|
5310
5348
|
}
|
|
5311
5349
|
}
|
|
5312
5350
|
if (usePromptMode) {
|
|
@@ -5331,7 +5369,7 @@ async function spawnV2Worker(opts) {
|
|
|
5331
5369
|
}
|
|
5332
5370
|
async function startTeamV2(config) {
|
|
5333
5371
|
const sanitized = sanitizeTeamName(config.teamName);
|
|
5334
|
-
const leaderCwd = (0,
|
|
5372
|
+
const leaderCwd = (0, import_path18.resolve)(config.cwd);
|
|
5335
5373
|
validateTeamName(sanitized);
|
|
5336
5374
|
const agentTypes = config.agentTypes;
|
|
5337
5375
|
const resolvedBinaryPaths = {};
|
|
@@ -5340,11 +5378,11 @@ async function startTeamV2(config) {
|
|
|
5340
5378
|
}
|
|
5341
5379
|
await (0, import_promises7.mkdir)(absPath(leaderCwd, TeamPaths.tasks(sanitized)), { recursive: true });
|
|
5342
5380
|
await (0, import_promises7.mkdir)(absPath(leaderCwd, TeamPaths.workers(sanitized)), { recursive: true });
|
|
5343
|
-
await (0, import_promises7.mkdir)((0,
|
|
5381
|
+
await (0, import_promises7.mkdir)((0, import_path18.join)(leaderCwd, ".omc", "state", "team", sanitized, "mailbox"), { recursive: true });
|
|
5344
5382
|
for (let i = 0; i < config.tasks.length; i++) {
|
|
5345
5383
|
const taskId = String(i + 1);
|
|
5346
5384
|
const taskFilePath = absPath(leaderCwd, TeamPaths.taskFile(sanitized, taskId));
|
|
5347
|
-
await (0, import_promises7.mkdir)((0,
|
|
5385
|
+
await (0, import_promises7.mkdir)((0, import_path18.join)(taskFilePath, ".."), { recursive: true });
|
|
5348
5386
|
await (0, import_promises7.writeFile)(taskFilePath, JSON.stringify({
|
|
5349
5387
|
id: taskId,
|
|
5350
5388
|
subject: config.tasks[i].subject,
|
|
@@ -5838,7 +5876,7 @@ function parseWatchdogFailedAt(marker) {
|
|
|
5838
5876
|
throw new Error("watchdog marker missing valid failedAt");
|
|
5839
5877
|
}
|
|
5840
5878
|
async function checkWatchdogFailedMarker(stateRoot2, startTime) {
|
|
5841
|
-
const markerPath = (0,
|
|
5879
|
+
const markerPath = (0, import_path19.join)(stateRoot2, "watchdog-failed.json");
|
|
5842
5880
|
let raw;
|
|
5843
5881
|
try {
|
|
5844
5882
|
raw = await (0, import_promises8.readFile)(markerPath, "utf-8");
|
|
@@ -5870,7 +5908,7 @@ async function checkWatchdogFailedMarker(stateRoot2, startTime) {
|
|
|
5870
5908
|
}
|
|
5871
5909
|
async function writeResultArtifact(output, finishedAt, jobId = process.env.OMC_JOB_ID, omcJobsDir = process.env.OMC_JOBS_DIR) {
|
|
5872
5910
|
if (!jobId || !omcJobsDir) return;
|
|
5873
|
-
const resultPath = (0,
|
|
5911
|
+
const resultPath = (0, import_path19.join)(omcJobsDir, `${jobId}-result.json`);
|
|
5874
5912
|
const tmpPath = `${resultPath}.tmp`;
|
|
5875
5913
|
await (0, import_promises8.writeFile)(
|
|
5876
5914
|
tmpPath,
|
|
@@ -5882,7 +5920,7 @@ async function writeResultArtifact(output, finishedAt, jobId = process.env.OMC_J
|
|
|
5882
5920
|
async function writePanesFile(jobId, paneIds, leaderPaneId, sessionName2, ownsWindow) {
|
|
5883
5921
|
const omcJobsDir = process.env.OMC_JOBS_DIR;
|
|
5884
5922
|
if (!jobId || !omcJobsDir) return;
|
|
5885
|
-
const panesPath = (0,
|
|
5923
|
+
const panesPath = (0, import_path19.join)(omcJobsDir, `${jobId}-panes.json`);
|
|
5886
5924
|
await (0, import_promises8.writeFile)(
|
|
5887
5925
|
panesPath + ".tmp",
|
|
5888
5926
|
JSON.stringify({ paneIds: [...paneIds], leaderPaneId, sessionName: sessionName2, ownsWindow })
|
|
@@ -5890,12 +5928,12 @@ async function writePanesFile(jobId, paneIds, leaderPaneId, sessionName2, ownsWi
|
|
|
5890
5928
|
await (0, import_promises8.rename)(panesPath + ".tmp", panesPath);
|
|
5891
5929
|
}
|
|
5892
5930
|
function collectTaskResults(stateRoot2) {
|
|
5893
|
-
const tasksDir = (0,
|
|
5931
|
+
const tasksDir = (0, import_path19.join)(stateRoot2, "tasks");
|
|
5894
5932
|
try {
|
|
5895
5933
|
const files = (0, import_fs18.readdirSync)(tasksDir).filter((f) => f.endsWith(".json"));
|
|
5896
5934
|
return files.map((f) => {
|
|
5897
5935
|
try {
|
|
5898
|
-
const raw = (0, import_fs18.readFileSync)((0,
|
|
5936
|
+
const raw = (0, import_fs18.readFileSync)((0, import_path19.join)(tasksDir, f), "utf-8");
|
|
5899
5937
|
const task = JSON.parse(raw);
|
|
5900
5938
|
return {
|
|
5901
5939
|
taskId: task.id ?? f.replace(".json", ""),
|
|
@@ -5949,7 +5987,7 @@ async function main() {
|
|
|
5949
5987
|
sentinelGatePollIntervalMs = 250
|
|
5950
5988
|
} = input;
|
|
5951
5989
|
const workerCount = input.workerCount ?? agentTypes.length;
|
|
5952
|
-
const stateRoot2 = (0,
|
|
5990
|
+
const stateRoot2 = (0, import_path19.join)(cwd, `.omc/state/team/${teamName}`);
|
|
5953
5991
|
const config = {
|
|
5954
5992
|
teamName,
|
|
5955
5993
|
workerCount,
|
|
@@ -6134,7 +6172,7 @@ async function main() {
|
|
|
6134
6172
|
if (snap.allTasksTerminal) {
|
|
6135
6173
|
const hasFailures = snap.tasks.failed > 0;
|
|
6136
6174
|
if (!hasFailures) {
|
|
6137
|
-
const sentinelLogPath = (0,
|
|
6175
|
+
const sentinelLogPath = (0, import_path19.join)(cwd, "sentinel_stop.jsonl");
|
|
6138
6176
|
const gateResult = await waitForSentinelReadiness({
|
|
6139
6177
|
workspace: cwd,
|
|
6140
6178
|
logPath: sentinelLogPath,
|
|
@@ -6211,7 +6249,7 @@ async function main() {
|
|
|
6211
6249
|
mismatchStreak = 0;
|
|
6212
6250
|
const terminalStatus = getTerminalStatus(snap.taskCounts, expectedTaskCount);
|
|
6213
6251
|
if (terminalStatus === "completed") {
|
|
6214
|
-
const sentinelLogPath = (0,
|
|
6252
|
+
const sentinelLogPath = (0, import_path19.join)(cwd, "sentinel_stop.jsonl");
|
|
6215
6253
|
const gateResult = await waitForSentinelReadiness({
|
|
6216
6254
|
workspace: cwd,
|
|
6217
6255
|
logPath: sentinelLogPath,
|