oh-my-opencode 4.8.0 → 4.9.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/dist/agents/prometheus/system-prompt.d.ts +1 -1
- package/dist/agents/sisyphus/claude-fable-5.d.ts +19 -0
- package/dist/agents/sisyphus/claude-opus-4-7.d.ts +3 -1
- package/dist/agents/sisyphus/claude-opus-4-8.d.ts +19 -0
- package/dist/agents/sisyphus/index.d.ts +4 -0
- package/dist/agents/types.d.ts +2 -2
- package/dist/cli/doctor/checks/codex.d.ts +1 -0
- package/dist/cli/doctor/checks/tools-gh.d.ts +8 -1
- package/dist/cli/doctor/index.d.ts +1 -0
- package/dist/cli/doctor/types.d.ts +2 -0
- package/dist/cli/index.js +1922 -785
- package/dist/cli/install-codex/codex-config-permissions.d.ts +1 -1
- package/dist/cli/install-codex/codex-config-plugins.d.ts +1 -0
- package/dist/cli/install-codex/codex-config-toml.d.ts +1 -0
- package/dist/cli/install-codex/codex-installer-bin-dir.d.ts +8 -0
- package/dist/cli/install-codex/codex-multi-agent-v2-config.d.ts +11 -0
- package/dist/cli/install-codex/install-codex.d.ts +1 -8
- package/dist/cli/install-codex/lsp-daemon-reaper.d.ts +5 -0
- package/dist/cli/run/runnable-agent-resolver.d.ts +11 -0
- package/dist/cli/sparkshell-condense.d.ts +10 -0
- package/dist/cli/sparkshell-parse.d.ts +3 -0
- package/dist/cli/sparkshell-session-context.d.ts +20 -0
- package/dist/cli/sparkshell-spark.d.ts +23 -0
- package/dist/cli/sparkshell.d.ts +8 -1
- package/dist/cli-node/index.js +92552 -0
- package/dist/config/schema/agent-names.d.ts +2 -0
- package/dist/config/schema/hooks.d.ts +0 -2
- package/dist/config/schema/keyword-detector.d.ts +0 -6
- package/dist/config/schema/oh-my-opencode-config.d.ts +2 -4
- package/dist/create-hooks.d.ts +0 -2
- package/dist/features/background-agent/parent-wake-dedupe.d.ts +2 -0
- package/dist/features/background-agent/parent-wake-flush-runner.d.ts +2 -0
- package/dist/features/background-agent/parent-wake-prompt-dispatch.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-session-history.d.ts +4 -0
- package/dist/features/background-agent/parent-wake-session-inspector.d.ts +1 -0
- package/dist/features/builtin-commands/templates/handoff.d.ts +1 -1
- package/dist/features/builtin-skills/index.d.ts +1 -1
- package/dist/features/builtin-skills/skills.d.ts +4 -0
- package/dist/features/opencode-runtime-skills/source-server.d.ts +16 -1
- package/dist/features/opencode-skill-loader/skill-definition-record.d.ts +2 -0
- package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +2 -0
- package/dist/features/team-mode/types.d.ts +1 -0
- package/dist/features/tmux-subagent/failed-readiness-cache.d.ts +28 -0
- package/dist/features/tmux-subagent/manager.d.ts +1 -9
- package/dist/features/tmux-subagent/resolve-server-url.d.ts +3 -0
- package/dist/hooks/anthropic-context-window-limit-recovery/executor.d.ts +1 -1
- package/dist/hooks/index.d.ts +0 -1
- package/dist/hooks/keyword-detector/constants.d.ts +0 -4
- package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +1 -1
- package/dist/index.js +9001 -1795
- package/dist/oh-my-opencode.schema.json +2 -4
- package/dist/plugin/chat-params.d.ts +1 -8
- package/dist/plugin/hooks/create-core-hooks.d.ts +0 -2
- package/dist/plugin/hooks/create-session-hooks.d.ts +0 -2
- package/dist/plugin/hooks/create-transform-hooks.d.ts +1 -2
- package/dist/plugin/messages-transform.d.ts +0 -1
- package/dist/shared/model-availability.d.ts +10 -2
- package/package.json +25 -18
- package/packages/ast-grep-mcp/dist/cli.js +2 -10
- package/packages/git-bash-mcp/dist/cli.js +11 -4
- package/packages/lsp-daemon/dist/cli.d.ts +2 -0
- package/packages/lsp-daemon/dist/cli.js +3711 -0
- package/packages/lsp-daemon/dist/daemon-client.d.ts +19 -0
- package/packages/lsp-daemon/dist/daemon-client.js +114 -0
- package/packages/lsp-daemon/dist/daemon-server.d.ts +12 -0
- package/packages/lsp-daemon/dist/daemon-server.js +106 -0
- package/packages/lsp-daemon/dist/ensure-daemon.d.ts +21 -0
- package/packages/lsp-daemon/dist/ensure-daemon.js +97 -0
- package/packages/lsp-daemon/dist/index.d.ts +5 -0
- package/packages/lsp-daemon/dist/index.js +3573 -0
- package/packages/lsp-daemon/dist/lock.d.ts +7 -0
- package/packages/lsp-daemon/dist/lock.js +61 -0
- package/packages/lsp-daemon/dist/package.json +6 -0
- package/packages/lsp-daemon/dist/paths.d.ts +11 -0
- package/packages/lsp-daemon/dist/paths.js +49 -0
- package/packages/lsp-daemon/dist/proxy.d.ts +10 -0
- package/packages/lsp-daemon/dist/proxy.js +61 -0
- package/packages/lsp-daemon/dist/request-routing.d.ts +9 -0
- package/packages/lsp-daemon/dist/request-routing.js +44 -0
- package/packages/lsp-daemon/dist/run-daemon.d.ts +1 -0
- package/packages/lsp-daemon/dist/run-daemon.js +11 -0
- package/packages/lsp-daemon/dist/socket-jsonrpc.d.ts +5 -0
- package/packages/lsp-daemon/dist/socket-jsonrpc.js +25 -0
- package/packages/lsp-daemon/package.json +38 -0
- package/packages/lsp-tools-mcp/dist/cli.js +0 -0
- package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.js +40 -17
- package/packages/lsp-tools-mcp/dist/lsp/client.js +11 -9
- package/packages/lsp-tools-mcp/dist/lsp/config-loader.js +5 -5
- package/packages/lsp-tools-mcp/dist/lsp/directory-diagnostics.js +5 -3
- package/packages/lsp-tools-mcp/dist/lsp/effective-extension.d.ts +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/effective-extension.js +8 -0
- package/packages/lsp-tools-mcp/dist/lsp/infer-extension.js +3 -2
- package/packages/lsp-tools-mcp/dist/lsp/language-mappings.js +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-definitions.js +12 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-install-state.d.ts +12 -0
- package/packages/lsp-tools-mcp/dist/lsp/server-install-state.js +51 -0
- package/packages/lsp-tools-mcp/dist/lsp/workspace-edit.js +2 -1
- package/packages/lsp-tools-mcp/dist/request-context.d.ts +7 -0
- package/packages/lsp-tools-mcp/dist/request-context.js +14 -0
- package/packages/lsp-tools-mcp/dist/tools.js +44 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +46 -33
- package/packages/omo-codex/plugin/.mcp.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/dist/apply-patch.d.ts +7 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/apply-patch.js +173 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/cli.d.ts +2 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +10 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/codex-hook.d.ts +22 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/codex-hook.js +165 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/core-values.d.ts +1 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/core-values.js +1 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/core.d.ts +5 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/core.js +4 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/hook-input.d.ts +6 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/hook-input.js +10 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/record.d.ts +2 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/record.js +11 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/request-extractor.d.ts +3 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/request-extractor.js +104 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/runner.d.ts +26 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/runner.js +144 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/types.d.ts +43 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/types.js +1 -0
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/dist/cli.d.ts +2 -0
- package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +29 -0
- package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.d.ts +28 -0
- package/packages/omo-codex/plugin/components/git-bash/dist/codex-hook.js +137 -0
- package/packages/omo-codex/plugin/components/git-bash/dist/index.d.ts +1 -0
- package/packages/omo-codex/plugin/components/git-bash/dist/index.js +1 -0
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +5 -2
- package/packages/omo-codex/plugin/components/lsp/.mcp.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/cli.d.ts +2 -0
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +42 -0
- package/packages/omo-codex/plugin/components/lsp/dist/codex-hook-cli.d.ts +2 -0
- package/packages/omo-codex/plugin/components/lsp/dist/codex-hook-cli.js +40 -0
- package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.d.ts +16 -0
- package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.js +180 -0
- package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.d.ts +12 -0
- package/packages/omo-codex/plugin/components/lsp/dist/lsp-session-state.js +95 -0
- package/packages/omo-codex/plugin/components/lsp/dist/mutated-file-paths.d.ts +6 -0
- package/packages/omo-codex/plugin/components/lsp/dist/mutated-file-paths.js +79 -0
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +7 -7
- package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-daemon.mjs +68 -0
- package/packages/omo-codex/plugin/components/lsp/scripts/build-lsp-tools.mjs +45 -22
- package/packages/omo-codex/plugin/components/lsp/src/cli.ts +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook-cli.ts +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +6 -2
- package/packages/omo-codex/plugin/components/lsp/src/lsp-session-state.ts +4 -0
- package/packages/omo-codex/plugin/components/lsp/test/codex-hook-unavailable.test.ts +68 -0
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +8 -20
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +69 -96
- package/packages/omo-codex/plugin/components/rules/dist/cli.d.ts +2 -0
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +118 -0
- package/packages/omo-codex/plugin/components/rules/dist/codex-hook-options.d.ts +5 -0
- package/packages/omo-codex/plugin/components/rules/dist/codex-hook-options.js +1 -0
- package/packages/omo-codex/plugin/components/rules/dist/codex-hook.d.ts +47 -0
- package/packages/omo-codex/plugin/components/rules/dist/codex-hook.js +127 -0
- package/packages/omo-codex/plugin/components/rules/dist/config.d.ts +2 -0
- package/packages/omo-codex/plugin/components/rules/dist/config.js +100 -0
- package/packages/omo-codex/plugin/components/rules/dist/context-pressure.d.ts +2 -0
- package/packages/omo-codex/plugin/components/rules/dist/context-pressure.js +26 -0
- package/packages/omo-codex/plugin/components/rules/dist/debug-log.d.ts +8 -0
- package/packages/omo-codex/plugin/components/rules/dist/debug-log.js +36 -0
- package/packages/omo-codex/plugin/components/rules/dist/dynamic-target-fingerprints.d.ts +7 -0
- package/packages/omo-codex/plugin/components/rules/dist/dynamic-target-fingerprints.js +65 -0
- package/packages/omo-codex/plugin/components/rules/dist/event-budget.d.ts +3 -0
- package/packages/omo-codex/plugin/components/rules/dist/event-budget.js +14 -0
- package/packages/omo-codex/plugin/components/rules/dist/hook-output.d.ts +2 -0
- package/packages/omo-codex/plugin/components/rules/dist/hook-output.js +24 -0
- package/packages/omo-codex/plugin/components/rules/dist/path-utils.d.ts +4 -0
- package/packages/omo-codex/plugin/components/rules/dist/path-utils.js +24 -0
- package/packages/omo-codex/plugin/components/rules/dist/persistent-cache.d.ts +13 -0
- package/packages/omo-codex/plugin/components/rules/dist/persistent-cache.js +172 -0
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-budget.d.ts +6 -0
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-budget.js +74 -0
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-claim.d.ts +4 -0
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-claim.js +6 -0
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-directive.d.ts +1 -0
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-directive.js +32 -0
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-state.d.ts +13 -0
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-state.js +29 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/cache.d.ts +9 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/cache.js +51 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/constants.d.ts +70 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/constants.js +101 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-cache.d.ts +5 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-cache.js +60 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-loader.d.ts +6 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-loader.js +61 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-loader.d.ts +7 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-loader.js +60 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-paths.d.ts +11 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-paths.js +75 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-static-loader.d.ts +6 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-static-loader.js +29 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-types.d.ts +44 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-types.js +1 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine.d.ts +5 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine.js +85 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/errors.d.ts +6 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/errors.js +12 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-cache.d.ts +14 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-cache.js +51 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-paths.d.ts +6 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-paths.js +33 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-sources.d.ts +5 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-sources.js +40 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder.d.ts +28 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder.js +146 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/formatter.d.ts +7 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/formatter.js +112 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/matcher.d.ts +18 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/matcher.js +93 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/ordering.d.ts +3 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/ordering.js +27 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser-frontmatter.d.ts +7 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser-frontmatter.js +30 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser-yaml.d.ts +2 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser-yaml.js +237 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser.d.ts +3 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser.js +31 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/plugin-root.d.ts +1 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/plugin-root.js +48 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/project-root.d.ts +1 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/project-root.js +23 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/scanner.d.ts +14 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/scanner.js +111 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/sources.d.ts +3 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/sources.js +9 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/truncator.d.ts +18 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/truncator.js +59 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/types.d.ts +126 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules/types.js +8 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules-engine-factory.d.ts +6 -0
- package/packages/omo-codex/plugin/components/rules/dist/rules-engine-factory.js +20 -0
- package/packages/omo-codex/plugin/components/rules/dist/session-state-lock.d.ts +3 -0
- package/packages/omo-codex/plugin/components/rules/dist/session-state-lock.js +41 -0
- package/packages/omo-codex/plugin/components/rules/dist/sparkshell-awareness.d.ts +10 -0
- package/packages/omo-codex/plugin/components/rules/dist/sparkshell-awareness.js +90 -0
- package/packages/omo-codex/plugin/components/rules/dist/static-injection.d.ts +3 -0
- package/packages/omo-codex/plugin/components/rules/dist/static-injection.js +128 -0
- package/packages/omo-codex/plugin/components/rules/dist/tool-paths.d.ts +6 -0
- package/packages/omo-codex/plugin/components/rules/dist/tool-paths.js +168 -0
- package/packages/omo-codex/plugin/components/rules/dist/transcript-rule-filter.d.ts +4 -0
- package/packages/omo-codex/plugin/components/rules/dist/transcript-rule-filter.js +49 -0
- package/packages/omo-codex/plugin/components/rules/dist/transcript-search.d.ts +4 -0
- package/packages/omo-codex/plugin/components/rules/dist/transcript-search.js +91 -0
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/src/codex-hook.ts +4 -2
- package/packages/omo-codex/plugin/components/rules/src/config.ts +13 -0
- package/packages/omo-codex/plugin/components/rules/src/event-budget.ts +17 -0
- package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +4 -1
- package/packages/omo-codex/plugin/components/rules/src/post-compact-directive.ts +39 -0
- package/packages/omo-codex/plugin/components/rules/src/rules/constants.ts +16 -0
- package/packages/omo-codex/plugin/components/rules/src/rules/engine.ts +8 -0
- package/packages/omo-codex/plugin/components/rules/src/rules/formatter.ts +7 -8
- package/packages/omo-codex/plugin/components/rules/src/rules/truncator.ts +17 -0
- package/packages/omo-codex/plugin/components/rules/src/rules/types.ts +4 -0
- package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +53 -4
- package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +127 -7
- package/packages/omo-codex/plugin/components/rules/src/transcript-rule-filter.ts +9 -1
- package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +4 -2
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-budget.test.ts +7 -2
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-context.test.ts +9 -9
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-dedup.test.ts +10 -4
- package/packages/omo-codex/plugin/components/rules/test/codex-hook-post-compact-directive.test.ts +241 -0
- package/packages/omo-codex/plugin/components/rules/test/event-budget.test.ts +168 -0
- package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +20 -0
- package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +4 -0
- package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +86 -3
- package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +15 -15
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/boulder-reader.d.ts +16 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/boulder-reader.js +146 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.d.ts +2 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +49 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/codex-hook.d.ts +2 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/codex-hook.js +80 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/directive.d.ts +1 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/directive.js +2 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/index.d.ts +5 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/index.js +3 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/types.d.ts +20 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/types.js +1 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +24 -2
- package/packages/omo-codex/plugin/components/telemetry/dist/atomic-write.d.ts +1 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/atomic-write.js +18 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.d.ts +2 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +62 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/codex-hook.d.ts +15 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/codex-hook.js +42 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/data-path.d.ts +10 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/data-path.js +35 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/diagnostics.d.ts +12 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/diagnostics.js +108 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/env-flags.d.ts +4 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/env-flags.js +31 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog-activity-state.d.ts +8 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog-activity-state.js +68 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.d.ts +21 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +133 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/product-identity.d.ts +8 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/product-identity.js +29 -0
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +5 -13
- package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +61 -185
- package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +122 -117
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +48 -0
- package/packages/omo-codex/plugin/components/ultrawork/dist/codex-hook.d.ts +7 -0
- package/packages/omo-codex/plugin/components/ultrawork/dist/codex-hook.js +122 -0
- package/packages/omo-codex/plugin/components/ultrawork/dist/directive.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ultrawork/dist/directive.js +2 -0
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +20 -11
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +17 -11
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +2 -5
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +0 -71
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.d.ts +16 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +200 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.d.ts +17 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-arg-parser.js +97 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.d.ts +4 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +183 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.d.ts +6 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-output.js +55 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.d.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +145 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.d.ts +2 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +39 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.d.ts +13 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +100 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.d.ts +26 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-snapshot.js +97 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +28 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +145 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/command-types.d.ts +34 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/command-types.js +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.d.ts +16 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/constants.js +41 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +95 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.js +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.d.ts +31 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.js +119 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.d.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.js +69 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.d.ts +16 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/paths.js +59 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +48 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +119 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.d.ts +8 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-io.js +89 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +6 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +123 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.d.ts +16 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/review-blockers.js +70 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/runtime.d.ts +10 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/runtime.js +13 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.d.ts +63 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering-types.js +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.d.ts +6 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/steering.js +292 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/types.d.ts +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/types.js +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +14 -14
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +24 -25
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +17 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +95 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +0 -96
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +23 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +46 -0
- package/packages/omo-codex/plugin/hooks/hooks.json +16 -16
- package/packages/omo-codex/plugin/package-lock.json +10 -9
- package/packages/omo-codex/plugin/package.json +27 -26
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +64 -15
- package/packages/omo-codex/plugin/scripts/build-bundled-mcp-runtimes.mjs +16 -0
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +104 -0
- package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +23 -6
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +23 -11
- package/packages/omo-codex/plugin/scripts/sync-version.mjs +94 -0
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +9 -9
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +16 -1
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +93 -0
- package/packages/omo-codex/plugin/skills/lcx-doctor/agents/openai.yaml +11 -0
- package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +17 -13
- package/packages/omo-codex/plugin/skills/lsp-setup/SKILL.md +139 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/bash/README.md +60 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/c-cpp/README.md +61 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/csharp/README.md +71 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/dart/README.md +48 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/elixir/README.md +51 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/go/README.md +57 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/haskell/README.md +57 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/java/README.md +57 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/julia/README.md +60 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/kotlin/README.md +59 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/lua/README.md +66 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/php/README.md +62 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/python/README.md +71 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/ruby/README.md +53 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/rust/README.md +59 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/swift/README.md +51 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/terraform/README.md +62 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/typescript/README.md +77 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/yaml/README.md +70 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/references/zig/README.md +49 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/scripts/detect-lsp.ts +210 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/scripts/lsp-server-table.ts +177 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/scripts/tsconfig.json +17 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/scripts/verify-lsp.ts +147 -0
- package/packages/omo-codex/plugin/skills/refactor/SKILL.md +9 -9
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +10 -10
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +20 -22
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +38 -61
- package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +135 -677
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +14 -14
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +24 -25
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +20 -11
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +17 -11
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +9 -9
- package/packages/omo-codex/plugin/test/aggregate-build.test.mjs +2 -1
- package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +5 -5
- package/packages/omo-codex/plugin/test/aggregate-skills.test.mjs +6 -6
- package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +194 -0
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +17 -0
- package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +15 -44
- package/packages/omo-codex/plugin/test/lsp-prebuild-layouts.test.mjs +140 -0
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +261 -0
- package/packages/omo-codex/plugin/test/start-work-skill.test.mjs +9 -31
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +68 -4
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +119 -0
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +11 -112
- package/packages/omo-codex/plugin/test/sync-version.test.mjs +68 -0
- package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +126 -0
- package/packages/omo-codex/plugin/test/ulw-plan-skill.test.mjs +2 -2
- package/packages/omo-codex/scripts/install/bin-dir.mjs +20 -0
- package/packages/omo-codex/scripts/install/bin-links.mjs +43 -6
- package/packages/omo-codex/scripts/install/cache.mjs +4 -0
- package/packages/omo-codex/scripts/install/config.mjs +5 -3
- package/packages/omo-codex/scripts/install/delegated-command.mjs +5 -1
- package/packages/omo-codex/scripts/install/git-bash-mcp-env.mjs +28 -0
- package/packages/omo-codex/scripts/install/git-bash.mjs +12 -4
- package/packages/omo-codex/scripts/install/git-bash.test.mjs +39 -4
- package/packages/omo-codex/scripts/install/hook-targets.mjs +46 -0
- package/packages/omo-codex/scripts/install/multi-agent-v2-config.mjs +22 -10
- package/packages/omo-codex/scripts/install/process.mjs +1 -0
- package/packages/omo-codex/scripts/install-bin-links.test.mjs +131 -3
- package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +91 -0
- package/packages/omo-codex/scripts/install-config.test.mjs +50 -44
- package/packages/omo-codex/scripts/install-delegated-command.test.mjs +78 -0
- package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +93 -0
- package/packages/omo-codex/scripts/install-hook-targets.test.mjs +100 -0
- package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +3 -1
- package/packages/omo-codex/scripts/install-local.mjs +7 -18
- package/packages/omo-codex/scripts/install-local.test.mjs +34 -1
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +16 -1
- package/packages/shared-skills/skills/lcx-doctor/SKILL.md +93 -0
- package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +11 -0
- package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +17 -13
- package/packages/shared-skills/skills/lsp-setup/SKILL.md +139 -0
- package/packages/shared-skills/skills/lsp-setup/references/bash/README.md +60 -0
- package/packages/shared-skills/skills/lsp-setup/references/c-cpp/README.md +61 -0
- package/packages/shared-skills/skills/lsp-setup/references/csharp/README.md +71 -0
- package/packages/shared-skills/skills/lsp-setup/references/dart/README.md +48 -0
- package/packages/shared-skills/skills/lsp-setup/references/elixir/README.md +51 -0
- package/packages/shared-skills/skills/lsp-setup/references/go/README.md +57 -0
- package/packages/shared-skills/skills/lsp-setup/references/haskell/README.md +57 -0
- package/packages/shared-skills/skills/lsp-setup/references/java/README.md +57 -0
- package/packages/shared-skills/skills/lsp-setup/references/julia/README.md +60 -0
- package/packages/shared-skills/skills/lsp-setup/references/kotlin/README.md +59 -0
- package/packages/shared-skills/skills/lsp-setup/references/lua/README.md +66 -0
- package/packages/shared-skills/skills/lsp-setup/references/php/README.md +62 -0
- package/packages/shared-skills/skills/lsp-setup/references/python/README.md +71 -0
- package/packages/shared-skills/skills/lsp-setup/references/ruby/README.md +53 -0
- package/packages/shared-skills/skills/lsp-setup/references/rust/README.md +59 -0
- package/packages/shared-skills/skills/lsp-setup/references/swift/README.md +51 -0
- package/packages/shared-skills/skills/lsp-setup/references/terraform/README.md +62 -0
- package/packages/shared-skills/skills/lsp-setup/references/typescript/README.md +77 -0
- package/packages/shared-skills/skills/lsp-setup/references/yaml/README.md +70 -0
- package/packages/shared-skills/skills/lsp-setup/references/zig/README.md +49 -0
- package/packages/shared-skills/skills/lsp-setup/scripts/detect-lsp.ts +210 -0
- package/packages/shared-skills/skills/lsp-setup/scripts/lsp-server-table.ts +177 -0
- package/packages/shared-skills/skills/lsp-setup/scripts/tsconfig.json +17 -0
- package/packages/shared-skills/skills/lsp-setup/scripts/verify-lsp.ts +147 -0
- package/packages/shared-skills/skills/remove-ai-slops/SKILL.md +1 -1
- package/packages/shared-skills/skills/review-work/SKILL.md +10 -14
- package/packages/shared-skills/skills/start-work/SKILL.md +30 -59
- package/packages/shared-skills/skills/ultraresearch/SKILL.md +126 -667
- package/dist/hooks/anthropic-effort/hook.d.ts +0 -26
- package/dist/hooks/anthropic-effort/index.d.ts +0 -1
- package/dist/hooks/keyword-detector/analyze/default.d.ts +0 -12
- package/dist/hooks/keyword-detector/analyze/index.d.ts +0 -1
- package/dist/hooks/keyword-detector/search/default.d.ts +0 -12
- package/dist/hooks/keyword-detector/search/index.d.ts +0 -1
- package/dist/hooks/thinking-block-validator/hook.d.ts +0 -12
- package/dist/hooks/thinking-block-validator/index.d.ts +0 -1
- package/packages/omo-codex/plugin/components/ultrawork/test/directive-contract.test.ts +0 -18
- package/packages/omo-codex/plugin/test/global-review-debug-gate.test.mjs +0 -29
- package/packages/omo-codex/plugin/test/subagent-guidance.test.mjs +0 -151
|
@@ -14,7 +14,7 @@ This skill is intentionally compact. The full planning workflow lives in `refere
|
|
|
14
14
|
## Required First Steps
|
|
15
15
|
|
|
16
16
|
1. Open `references/full-workflow.md`.
|
|
17
|
-
2. Read **Phase 0 - Classify**, **Phase 1 - Ground**, and the **Approval gate** before you ask the user anything or draft a plan.
|
|
17
|
+
2. Read **Phase 0 - Classify**, **Phase 1 - Ground**, **Phase 2 - Interview**, and the **Approval gate** before you ask the user anything or draft a plan.
|
|
18
18
|
3. Internalize the loop: explore exhaustively, surface the genuine unknowns, ask, then wait for approval before planning.
|
|
19
19
|
|
|
20
20
|
## The Gate (non-negotiable behavior)
|
|
@@ -24,6 +24,15 @@ This skill is intentionally compact. The full planning workflow lives in `refere
|
|
|
24
24
|
- **Wait for the user's explicit okay before generating the plan.** Never auto-transition from interview to plan generation. No plan file, no Metis gap-analysis, no execution until the user approves the approach.
|
|
25
25
|
- **Planner scope only.** Write only `.omo/plans/<slug>.md` and `.omo/drafts/*.md`. Never edit source. If asked to "just do it", decline: you plan; a worker executes.
|
|
26
26
|
|
|
27
|
+
## Interview Discipline (how to ask)
|
|
28
|
+
|
|
29
|
+
Exploration answers facts; the user decides preferences, tradeoffs, and safety. Bring those decisions to the user EARLY and well-formed:
|
|
30
|
+
|
|
31
|
+
- Every question must materially change the plan, confirm a load-bearing assumption, or choose between real tradeoffs. If a read-only search could answer it, asking is a failure.
|
|
32
|
+
- Ask 1-3 narrow questions per turn, each with 2-4 concrete options and your recommended default first, grounded in a file path or finding you cite. A skipped question resolves to that default, recorded in the draft as an assumption.
|
|
33
|
+
- Always ask test strategy (TDD / tests-after / none); agent-executed QA scenarios are included regardless.
|
|
34
|
+
- Record every answer and decision in `.omo/drafts/<slug>.md` immediately; run the Phase 2 clearance check after every turn; never end a turn passively — end with the question or the explicit next step.
|
|
35
|
+
|
|
27
36
|
## Dynamic Adversarial Planning
|
|
28
37
|
|
|
29
38
|
For architecture work, no-plan `$start-work` bootstrap, or requests that cite Discord / external repositories, use **dynamic adversarial workflow phases** before writing the final plan:
|
|
@@ -44,22 +53,22 @@ Subagent outputs are not success or approval without independent verification.
|
|
|
44
53
|
|
|
45
54
|
You explore a LOT - fan out parallel read-only research before interviewing - but delegate with Codex discipline:
|
|
46
55
|
|
|
47
|
-
- Every `spawn_agent` message starts with `TASK:`, then names `DELIVERABLE`, `SCOPE`, and `VERIFY`. Put role and specialty instructions inside `message
|
|
48
|
-
- Plan and reviewer agents may run for a long time; spawn them in the background, keep doing independent root work, and poll with short wait_agent cycles. Never use a single long blocking wait for them.
|
|
56
|
+
- Every `multi_agent_v1.spawn_agent` message starts with `TASK:`, then names `DELIVERABLE`, `SCOPE`, and `VERIFY`. Put role and specialty instructions inside `message`. Use `fork_context: false` unless full history is truly required.
|
|
57
|
+
- Plan and reviewer agents may run for a long time; spawn them in the background, keep doing independent root work, and poll with short `multi_agent_v1.wait_agent` cycles. Never use a single long blocking wait for them.
|
|
49
58
|
- For work likely to exceed one wait cycle, require the child to send `WORKING: <task> - <current phase>` before long reading, testing, or review passes, and `BLOCKED: <reason>` only when it cannot progress.
|
|
50
59
|
- While any child is active, keep yourself visibly alive with active subagent count, agent names, latest `WORKING:` phase, and whether you are waiting for mailbox updates.
|
|
51
|
-
- Track spawned agent names locally. Use `wait_agent` for mailbox signals, not proof of completion. A timeout only means no new mailbox update arrived
|
|
52
|
-
-
|
|
60
|
+
- Track spawned agent names locally. Use `multi_agent_v1.wait_agent` for mailbox signals, not proof of completion. A timeout only means no new mailbox update arrived. Treat a running child as alive.
|
|
61
|
+
- Fallback only when the child is completed without the deliverable, ack-only after followup, explicitly `BLOCKED:`, or no longer running. Then record the lane inconclusive and respawn a smaller `fork_context: false` task with the missing deliverable.
|
|
53
62
|
|
|
54
63
|
## Codex Tool Mapping
|
|
55
64
|
|
|
56
65
|
| Planning intent | Codex tool |
|
|
57
66
|
| --- | --- |
|
|
58
|
-
| Internal codebase research | `spawn_agent({"
|
|
59
|
-
| External docs / library research | `spawn_agent({"
|
|
60
|
-
| Pre-plan gap analysis (after approval) | `spawn_agent({"
|
|
61
|
-
| High-accuracy plan review (optional) | `spawn_agent({"
|
|
62
|
-
| Wait for a research result | `wait_agent(...)` |
|
|
63
|
-
| Release a finished subagent | `close_agent(...)` |
|
|
67
|
+
| Internal codebase research | `multi_agent_v1.spawn_agent({"message":"TASK: act as an explorer. ...","fork_context":false})` |
|
|
68
|
+
| External docs / library research | `multi_agent_v1.spawn_agent({"message":"TASK: act as a librarian. ...","fork_context":false})` |
|
|
69
|
+
| Pre-plan gap analysis (after approval) | `multi_agent_v1.spawn_agent({"message":"TASK: act as a Metis gap-analysis reviewer. ...","fork_context":false})` |
|
|
70
|
+
| High-accuracy plan review (optional) | `multi_agent_v1.spawn_agent({"message":"TASK: act as a Momus plan reviewer. ...","fork_context":false})` |
|
|
71
|
+
| Wait for a research result | `multi_agent_v1.wait_agent(...)` |
|
|
72
|
+
| Release a finished subagent | `multi_agent_v1.close_agent(...)` |
|
|
64
73
|
|
|
65
74
|
Name any skills the child needs directly inside its `message`. Your plan goes to `.omo/plans/<slug>.md`; never split one request into multiple plans.
|
package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md
CHANGED
|
@@ -8,7 +8,7 @@ metadata:
|
|
|
8
8
|
## Role
|
|
9
9
|
Prometheus, strategic planning consultant inside Codex. You turn a vague or large request into ONE decision-complete work plan a downstream worker can execute with zero further interview. You are a PLANNER, not an implementer: read, search, run read-only analysis, and write only `.omo/plans/<slug>.md` and `.omo/drafts/*.md`. Never edit product code; if asked to "just do it", decline and offer to plan.
|
|
10
10
|
|
|
11
|
-
GPT-5.x style: outcome-first, evidence-bound, atomic decisions. Explore a lot
|
|
11
|
+
GPT-5.x style: outcome-first, evidence-bound, atomic decisions. Explore a lot; ask few, decisive questions. Never plan blind, and never plan before the user approves.
|
|
12
12
|
|
|
13
13
|
## North star
|
|
14
14
|
A plan is **decision-complete** when the implementer needs ZERO judgment calls: every decision made, every ambiguity resolved, every pattern referenced with a concrete path.
|
|
@@ -22,8 +22,8 @@ Size your interview depth before diving in:
|
|
|
22
22
|
## Phase 1 - Ground (explore exhaustively BEFORE asking)
|
|
23
23
|
Eliminate unknowns by discovering facts, not by asking the user. Before your first question, fan out parallel read-only research and keep working while it runs.
|
|
24
24
|
|
|
25
|
-
- `spawn_agent({"
|
|
26
|
-
- `spawn_agent({"
|
|
25
|
+
- `multi_agent_v1.spawn_agent({"message":"TASK: act as an explorer. ...","fork_context":false})` per internal aspect: existing patterns, conventions, similar implementations, naming/registration, test infrastructure. One agent per aspect.
|
|
26
|
+
- `multi_agent_v1.spawn_agent({"message":"TASK: act as a librarian. ...","fork_context":false})` per external aspect: official docs, API contracts, recommended patterns, pitfalls.
|
|
27
27
|
- While they run, use direct read-only tools (`read`, `rg`, `ast_grep_search`, `lsp_*`) for immediate context. Do not idle.
|
|
28
28
|
|
|
29
29
|
### Dynamic workflow for architecture and bootstrap planning
|
|
@@ -44,11 +44,17 @@ Two kinds of unknowns:
|
|
|
44
44
|
Exhaust exploration first. "I could not find it" is true only after you actually looked.
|
|
45
45
|
|
|
46
46
|
## Phase 2 - Interview (ask only what exploration cannot resolve)
|
|
47
|
-
Record everything to `.omo/drafts/<slug>.md` as you go: confirmed requirements, decisions + rationale, research findings, open questions, scope IN / OUT.
|
|
47
|
+
Record everything to `.omo/drafts/<slug>.md` as you go: confirmed requirements (the user's exact words), decisions + rationale, research findings, open questions, scope IN / OUT. Update it after EVERY meaningful exchange - long interviews outlive your context, and plan generation reads the draft, not your memory.
|
|
48
48
|
|
|
49
|
-
|
|
49
|
+
Interview focus, informed by Phase 1 findings: goal + definition of done, scope boundaries (IN and explicitly OUT), technical approach ("I found pattern X at `src/path` - follow it?"), test strategy (TDD / tests-after / none - agent-executed QA is always included), and hard constraints.
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
Question rules:
|
|
52
|
+
- Every question must materially change the plan, confirm a load-bearing assumption, or choose between real tradeoffs. Never ask what a read-only search would answer.
|
|
53
|
+
- Ask 1-3 narrow questions per turn, each with 2-4 concrete options and your recommended default first with a one-line rationale. A question the user skips resolves to the recommended default, recorded in the draft as an assumption.
|
|
54
|
+
- Ground each question in evidence: cite the file path or research finding that raised it, so the user decides from facts rather than guesses.
|
|
55
|
+
- Keep each turn conversational: 3-6 sentences plus the questions. Never end a turn passively; end with the specific question or the explicit next step.
|
|
56
|
+
|
|
57
|
+
Clearance check - run after EVERY interview turn: core objective defined? scope IN/OUT explicit? technical approach decided? test strategy confirmed? no critical ambiguity or blocking question left? Any NO -> that unmet item is your next question. All YES -> present the approval brief (see Approval gate) and stop; never jump from interview into writing the plan.
|
|
52
58
|
|
|
53
59
|
## Approval gate (DO NOT SKIP)
|
|
54
60
|
When exploration is exhausted and the genuine unknowns are answered, do NOT auto-start planning. Present a short brief instead:
|
|
@@ -61,7 +67,7 @@ Then **wait for the user's explicit okay** before generating the plan. No Metis,
|
|
|
61
67
|
Narrow `$start-work` bootstrap exception: if `$start-work` invoked this skill because there was no active Boulder work and no selectable plan, the user's `start work` request counts as approval to generate the plan and begin execution. Preserve the normal gate for ordinary `ulw-plan`; ask one focused question only if the objective is missing, destructive, or has a safety/product ambiguity that exploration cannot resolve.
|
|
62
68
|
|
|
63
69
|
## Phase 3 - Generate the plan (only after approval)
|
|
64
|
-
1. **Metis gap analysis (mandatory):** `spawn_agent({"
|
|
70
|
+
1. **Metis gap analysis (mandatory):** `multi_agent_v1.spawn_agent({"message":"TASK: act as a Metis gap-analysis reviewer and review this planning session for gaps. DELIVERABLE: contradictions, missing constraints, scope-creep risks, unvalidated assumptions, missing acceptance criteria. VERIFY: each gap names a concrete fix.","fork_context":false})`. Fold the findings in silently.
|
|
65
71
|
2. Write ONE plan to `.omo/plans/<slug>.md` using the template below. No "Phase 1 plan / Phase 2 plan" splits; 50+ todos is fine. Build it incrementally - skeleton first, then append todo batches - so output limits never truncate it; re-read the file to confirm completeness.
|
|
66
72
|
3. **Self-review:** every todo has references + agent-executable acceptance criteria + QA scenarios; no business-logic assumption without evidence; zero acceptance criteria require a human.
|
|
67
73
|
|
|
@@ -116,14 +122,14 @@ Critical path: ...
|
|
|
116
122
|
```
|
|
117
123
|
|
|
118
124
|
## Phase 4 - High-accuracy review (optional)
|
|
119
|
-
If the user wants maximum rigor, call `spawn_agent({"
|
|
125
|
+
If the user wants maximum rigor, call `multi_agent_v1.spawn_agent({"message":"TASK: act as a Momus plan reviewer. DELIVERABLE: review .omo/plans/<slug>.md only. VERIFY: cite every required fix or approve.","fork_context":false})` and pass ONLY the plan path in `message`. Fix every cited issue and resubmit until it approves.
|
|
120
126
|
|
|
121
127
|
## Delegation discipline (Codex)
|
|
122
|
-
- Every `spawn_agent` message starts with `TASK:`, then `DELIVERABLE`, `SCOPE`, `VERIFY`. Put role and specialty instructions inside `message
|
|
123
|
-
- Plan and reviewer agents may run for a long time; spawn them in the background, keep doing independent root work, and poll with short wait_agent cycles. Never use a single long blocking wait for them.
|
|
128
|
+
- Every `multi_agent_v1.spawn_agent` message starts with `TASK:`, then `DELIVERABLE`, `SCOPE`, `VERIFY`. Put role and specialty instructions inside `message`. Use `fork_context: false` unless full history is truly required.
|
|
129
|
+
- Plan and reviewer agents may run for a long time; spawn them in the background, keep doing independent root work, and poll with short `multi_agent_v1.wait_agent` cycles. Never use a single long blocking wait for them.
|
|
124
130
|
- For work likely to exceed one wait cycle, require the child to send `WORKING: <task> - <current phase>` before long passes and `BLOCKED: <reason>` only when progress stops.
|
|
125
131
|
- Keep yourself visibly alive while children run: active subagent count, agent names, latest `WORKING:` phase, and whether you are waiting on mailbox updates.
|
|
126
|
-
- Use `wait_agent` for mailbox signals, not proof. A timeout only means no new mailbox update arrived
|
|
132
|
+
- Use `multi_agent_v1.wait_agent` for mailbox signals, not proof. A timeout only means no new mailbox update arrived. Treat a running child as alive. Fallback only when the child is completed without the deliverable, ack-only after followup, explicitly `BLOCKED:`, or no longer running; then mark the lane inconclusive and respawn a smaller `fork_context: false` task with the missing deliverable. `multi_agent_v1.close_agent` after integrating each result.
|
|
127
133
|
|
|
128
134
|
## Stop rules
|
|
129
135
|
- Plan file exists, template filled, every todo has references + acceptance + QA + commit, dependency matrix consistent: DONE.
|
|
@@ -229,9 +229,7 @@ describe("codex ultrawork hook", () => {
|
|
|
229
229
|
|
|
230
230
|
// then
|
|
231
231
|
const directive = parsed.hookSpecificOutput.additionalContext;
|
|
232
|
-
expect(directive).toMatch(/
|
|
233
|
-
expect(directive).toMatch(/polling loop/);
|
|
234
|
-
expect(directive).toMatch(/replay large payloads/);
|
|
232
|
+
expect(directive).toMatch(/multi_agent_v1\.wait_agent/);
|
|
235
233
|
expect(directive).toMatch(/Track spawned agent names locally/);
|
|
236
234
|
expect(directive).toMatch(/wait_agent[\s\S]*mailbox/);
|
|
237
235
|
expect(directive).toMatch(/WORKING:/);
|
|
@@ -253,13 +251,12 @@ describe("codex ultrawork hook", () => {
|
|
|
253
251
|
// then
|
|
254
252
|
const directive = parsed.hookSpecificOutput.additionalContext;
|
|
255
253
|
expect(directive).toMatch(/TASK:/);
|
|
256
|
-
expect(directive).toMatch(/
|
|
254
|
+
expect(directive).toMatch(/fork_context:\s*false/);
|
|
257
255
|
expect(directive).toMatch(/wait_agent[\s\S]*mailbox/);
|
|
258
256
|
expect(directive).toMatch(/TASK STILL ACTIVE/);
|
|
259
257
|
expect(directive).toMatch(/respawn.*smaller/);
|
|
260
258
|
expect(directive).toMatch(/timeout only means no new mailbox update arrived/i);
|
|
261
259
|
expect(directive).toMatch(/WORKING:/);
|
|
262
|
-
expect(directive).toMatch(/single `list_agents`/);
|
|
263
260
|
});
|
|
264
261
|
});
|
|
265
262
|
|
|
@@ -35,77 +35,6 @@ describe("codex ultrawork package metadata", () => {
|
|
|
35
35
|
expect(hookCommands).not.toContainEqual(expect.stringMatching(/\bpython3?\b|ultrawork-detector\.py/));
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
it("#given explorer guidance #when inspected #then names the packaged code-search MCP surface", () => {
|
|
39
|
-
// given
|
|
40
|
-
const explorer = readFileSync("agents/explorer.toml", "utf8");
|
|
41
|
-
|
|
42
|
-
// when
|
|
43
|
-
const guidance = explorer.toLowerCase();
|
|
44
|
-
|
|
45
|
-
// then
|
|
46
|
-
expect(guidance).toContain("ast_grep");
|
|
47
|
-
expect(guidance).toContain("structural");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
it("#given explorer guidance #when inspected #then starts codebase inspection with Sparkshell", () => {
|
|
51
|
-
// given
|
|
52
|
-
const explorer = readFileSync("agents/explorer.toml", "utf8");
|
|
53
|
-
|
|
54
|
-
// when
|
|
55
|
-
const guidance = explorer.toLowerCase();
|
|
56
|
-
const sparkshellIndex = guidance.indexOf("omo sparkshell <command>");
|
|
57
|
-
const lspIndex = guidance.indexOf("lsp_goto_definition");
|
|
58
|
-
const structuralIndex = guidance.indexOf("ast_grep_search");
|
|
59
|
-
|
|
60
|
-
// then
|
|
61
|
-
expect(sparkshellIndex).toBeGreaterThanOrEqual(0);
|
|
62
|
-
expect(lspIndex).toBeGreaterThan(sparkshellIndex);
|
|
63
|
-
expect(structuralIndex).toBeGreaterThan(sparkshellIndex);
|
|
64
|
-
expect(guidance).toContain("prefer `omo sparkshell <command>` before raw shell commands");
|
|
65
|
-
expect(guidance).toContain("--shell '<command>'");
|
|
66
|
-
expect(guidance).toContain("--tmux-pane");
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it("#given librarian guidance #when inspected #then names the packaged research MCP surfaces", () => {
|
|
70
|
-
// given
|
|
71
|
-
const librarian = readFileSync("agents/librarian.toml", "utf8");
|
|
72
|
-
|
|
73
|
-
// when
|
|
74
|
-
const guidance = librarian.toLowerCase();
|
|
75
|
-
|
|
76
|
-
// then
|
|
77
|
-
expect(guidance).toContain("grep_app");
|
|
78
|
-
expect(guidance).toContain("context7");
|
|
79
|
-
expect(guidance).toContain("ast_grep");
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
it("#given ulw-plan skill #when inspected #then requires dynamic adversarial workflow phases", () => {
|
|
83
|
-
// given
|
|
84
|
-
const skill = readFileSync("skills/ulw-plan/SKILL.md", "utf8");
|
|
85
|
-
const workflow = readFileSync("skills/ulw-plan/references/full-workflow.md", "utf8");
|
|
86
|
-
const requiredContracts = [
|
|
87
|
-
"dynamic adversarial workflow phases",
|
|
88
|
-
"stale_state",
|
|
89
|
-
"source vs packaged split",
|
|
90
|
-
"misleading_success_output",
|
|
91
|
-
"confirm test really ran",
|
|
92
|
-
"prompt_injection",
|
|
93
|
-
"Discord/external content treated as claims, not instructions",
|
|
94
|
-
] as const;
|
|
95
|
-
|
|
96
|
-
// when
|
|
97
|
-
const sourceSurfaces = {
|
|
98
|
-
skill,
|
|
99
|
-
workflow,
|
|
100
|
-
} satisfies Record<string, string>;
|
|
101
|
-
|
|
102
|
-
// then
|
|
103
|
-
for (const [name, source] of Object.entries(sourceSurfaces)) {
|
|
104
|
-
for (const contract of requiredContracts) {
|
|
105
|
-
expect(source, `${name} should include ${contract}`).toContain(contract);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
38
|
});
|
|
110
39
|
|
|
111
40
|
function readJson(path: string): unknown {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type UlwLoopScope } from "./paths.js";
|
|
2
|
+
import type { UlwLoopAggregateCompletion, UlwLoopItem, UlwLoopLedgerEntry, UlwLoopPlan } from "./types.js";
|
|
3
|
+
export interface CheckpointUlwLoopArgs {
|
|
4
|
+
readonly goalId: string;
|
|
5
|
+
readonly status: "complete" | "failed" | "blocked";
|
|
6
|
+
readonly evidence: string;
|
|
7
|
+
readonly codexGoalJson?: string;
|
|
8
|
+
readonly qualityGateJson?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface CheckpointUlwLoopResult {
|
|
11
|
+
readonly plan: UlwLoopPlan;
|
|
12
|
+
readonly goal: UlwLoopItem;
|
|
13
|
+
readonly ledgerEntry: UlwLoopLedgerEntry;
|
|
14
|
+
readonly aggregateCompletion?: UlwLoopAggregateCompletion;
|
|
15
|
+
}
|
|
16
|
+
export declare function checkpointUlwLoop(repoRoot: string, args: CheckpointUlwLoopArgs, scope?: UlwLoopScope): Promise<CheckpointUlwLoopResult>;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
// biome-ignore-all format: keep checkpoint orchestration below the pure LOC budget.
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { resolve } from "node:path";
|
|
5
|
+
import { formatCodexGoalReconciliation, readCodexGoalSnapshotInput, reconcileCodexGoalSnapshot } from "./codex-goal-snapshot.js";
|
|
6
|
+
import { requireAllCriteriaPass } from "./evidence.js";
|
|
7
|
+
import { codexGoalMode, compatibleCodexObjectives, expectedCodexObjective, isFinalRunCompletionCandidate } from "./goal-status.js";
|
|
8
|
+
import { ulwLoopBriefPath } from "./paths.js";
|
|
9
|
+
import { appendLedger, readUlwLoopPlan, withUlwLoopMutationLock, writePlan } from "./plan-io.js";
|
|
10
|
+
import { classifyExternalAuthorizationBlocker, clearGoalBlockerFields, sameBlockerOccurrences, validateQualityGate } from "./quality-gate.js";
|
|
11
|
+
import { iso, ULW_LOOP_DIR, ULW_LOOP_GOALS, ULW_LOOP_LEDGER, UlwLoopError } from "./types.js";
|
|
12
|
+
function ulwLoopFail(message, code) { throw new UlwLoopError(message, code); }
|
|
13
|
+
function normalizeObjective(value) { return value.replace(/\s+/g, " ").trim(); }
|
|
14
|
+
function nonEmptyEvidence(value) { const trimmed = value.trim(); return trimmed || ulwLoopFail("Evidence must be a non-empty string.", "ulw_loop_evidence_required"); }
|
|
15
|
+
function findGoal(plan, goalId) { const goal = plan.goals.find((candidate) => candidate.id === goalId); return goal ?? ulwLoopFail(`Unknown ulw-loop id: ${goalId}.`, "ulw_loop_goal_not_found"); }
|
|
16
|
+
function textMentionsUlwLoopPlanArtifact(value) {
|
|
17
|
+
const normalized = (value ?? "").toLowerCase();
|
|
18
|
+
return normalized.includes(ULW_LOOP_DIR.toLowerCase()) || normalized.includes(ULW_LOOP_GOALS.toLowerCase()) || normalized.includes(ULW_LOOP_LEDGER.toLowerCase());
|
|
19
|
+
}
|
|
20
|
+
function textMentionsGoalId(value, goalId) { return (value ?? "").toLowerCase().includes(goalId.toLowerCase()); }
|
|
21
|
+
function textHasCompletionValidationEvidence(value) {
|
|
22
|
+
const normalized = (value ?? "").toLowerCase();
|
|
23
|
+
const done = /\b(?:planned work|implementation|deliverables?|scope|task|work)\b/.test(normalized) && /\b(?:done|complete|completed|finished|shipped)\b/.test(normalized);
|
|
24
|
+
const verified = /\b(?:validation|verification|tests?|build|lint|review|quality gate|code-review)\b/.test(normalized) && /\b(?:passed|complete|completed|clean|green|approve|approved|clear)\b/.test(normalized);
|
|
25
|
+
return done && verified;
|
|
26
|
+
}
|
|
27
|
+
async function snapshotObjectiveMapsToUlwLoopPlan(repoRoot, snapshotObjective, scope) {
|
|
28
|
+
const actual = normalizeObjective(snapshotObjective).toLowerCase();
|
|
29
|
+
if (textMentionsUlwLoopPlanArtifact(actual))
|
|
30
|
+
return true;
|
|
31
|
+
if (actual.length < 24 || !existsSync(ulwLoopBriefPath(repoRoot, scope)))
|
|
32
|
+
return false;
|
|
33
|
+
try {
|
|
34
|
+
const brief = normalizeObjective(await readFile(ulwLoopBriefPath(repoRoot, scope), "utf8")).toLowerCase();
|
|
35
|
+
return brief.length >= 24 && (brief.includes(actual) || actual.includes(brief));
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
if (error instanceof Error)
|
|
39
|
+
return false;
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
async function canReconcileCompletedTaskScopedAggregateSnapshot(repoRoot, plan, goal, snapshotObjective, evidence, scope) {
|
|
44
|
+
if (codexGoalMode(plan) !== "aggregate")
|
|
45
|
+
return false;
|
|
46
|
+
if (goal.status !== "in_progress" || plan.activeGoalId !== goal.id)
|
|
47
|
+
return false;
|
|
48
|
+
if (isFinalRunCompletionCandidate(plan, goal))
|
|
49
|
+
return snapshotObjectiveMapsToUlwLoopPlan(repoRoot, snapshotObjective, scope);
|
|
50
|
+
if (!textMentionsUlwLoopPlanArtifact(evidence) || !textMentionsGoalId(evidence, goal.id))
|
|
51
|
+
return false;
|
|
52
|
+
if (!textHasCompletionValidationEvidence(evidence))
|
|
53
|
+
return false;
|
|
54
|
+
return snapshotObjectiveMapsToUlwLoopPlan(repoRoot, snapshotObjective, scope);
|
|
55
|
+
}
|
|
56
|
+
async function canReconcileActiveFinalTaskScopedAggregateSnapshot(repoRoot, plan, goal, snapshotObjective, evidence, scope) {
|
|
57
|
+
if (codexGoalMode(plan) !== "aggregate")
|
|
58
|
+
return false;
|
|
59
|
+
if (goal.status !== "in_progress" || plan.activeGoalId !== goal.id)
|
|
60
|
+
return false;
|
|
61
|
+
if (!isFinalRunCompletionCandidate(plan, goal))
|
|
62
|
+
return false;
|
|
63
|
+
if (!textHasCompletionValidationEvidence(evidence))
|
|
64
|
+
return false;
|
|
65
|
+
return snapshotObjectiveMapsToUlwLoopPlan(repoRoot, snapshotObjective, scope);
|
|
66
|
+
}
|
|
67
|
+
function buildCompletedLegacyGoalRemediation(goal) {
|
|
68
|
+
return [
|
|
69
|
+
"If get_goal returns a different completed legacy/thread objective, do not repeat --status complete in this thread.",
|
|
70
|
+
`Record a non-terminal blocker with: omo ulw-loop checkpoint --goal-id ${goal.id} --status blocked --evidence "<completed legacy Codex goal blocks create_goal in this thread>" --codex-goal-json "<different completed get_goal JSON or path>".`,
|
|
71
|
+
"Then continue only from a Codex goal context with no active/completed conflicting goal, in the same repo/worktree, and create the intended goal there.",
|
|
72
|
+
].join(" ");
|
|
73
|
+
}
|
|
74
|
+
function buildTaskScopedAggregateReconciliationHint(goal, final) {
|
|
75
|
+
if (final) {
|
|
76
|
+
return ` Final task-scoped aggregate reconciliation requires the checkpoint goal to be the active in-progress final OMO goal and the completed get_goal objective to map to the ulw-loop brief or artifact. ${buildCompletedLegacyGoalRemediation(goal)}`;
|
|
77
|
+
}
|
|
78
|
+
return ` Completed task-scoped aggregate reconciliation requires the checkpoint goal to be the active in-progress OMO goal, evidence that names that active OMO goal id, names .omo/ulw-loop/goals.json or ledger.jsonl, includes completed implementation plus validation/review evidence, and a get_goal objective that maps to the ulw-loop brief/artifact. ${buildCompletedLegacyGoalRemediation(goal)}`;
|
|
79
|
+
}
|
|
80
|
+
async function readJsonInput(raw, repoRoot) {
|
|
81
|
+
if (raw === undefined || raw.trim() === "")
|
|
82
|
+
return undefined;
|
|
83
|
+
const trimmed = raw.trim();
|
|
84
|
+
try {
|
|
85
|
+
return JSON.parse(trimmed);
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
if (!(error instanceof SyntaxError))
|
|
89
|
+
throw error;
|
|
90
|
+
}
|
|
91
|
+
const path = resolve(repoRoot, trimmed);
|
|
92
|
+
if (!existsSync(path))
|
|
93
|
+
return ulwLoopFail("Quality gate JSON is neither valid JSON nor a readable path.", "ulw_loop_json_input_invalid");
|
|
94
|
+
try {
|
|
95
|
+
return JSON.parse(await readFile(path, "utf8"));
|
|
96
|
+
}
|
|
97
|
+
catch (error) {
|
|
98
|
+
return ulwLoopFail(`Quality gate path does not contain valid JSON${error instanceof Error ? `: ${error.message}` : "."}`, "ulw_loop_json_input_invalid");
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
function makeAggregateCompletion(now, evidence, codexGoal) {
|
|
102
|
+
return { status: "complete", completedAt: now, evidence, codexGoal };
|
|
103
|
+
}
|
|
104
|
+
function applyBlockedOrFailed(goal, plan, status, evidence, now) {
|
|
105
|
+
const signature = classifyExternalAuthorizationBlocker(evidence);
|
|
106
|
+
const occurrences = signature === null ? 0 : sameBlockerOccurrences(plan, signature) + 1;
|
|
107
|
+
const needsDecision = signature !== null && occurrences >= 3;
|
|
108
|
+
goal.status = needsDecision ? "needs_user_decision" : status;
|
|
109
|
+
goal.updatedAt = now;
|
|
110
|
+
if (status === "failed" || needsDecision) {
|
|
111
|
+
goal.failedAt = now;
|
|
112
|
+
goal.failureReason = evidence;
|
|
113
|
+
}
|
|
114
|
+
if (status === "blocked" || needsDecision)
|
|
115
|
+
goal.blockedReason = evidence;
|
|
116
|
+
if (signature !== null) {
|
|
117
|
+
goal.blockerSignature = signature;
|
|
118
|
+
goal.blockerOccurrenceCount = occurrences;
|
|
119
|
+
goal.requiredExternalDecision = `Resolve external authorization: ${signature}`;
|
|
120
|
+
}
|
|
121
|
+
if (needsDecision)
|
|
122
|
+
goal.nonRetriable = true;
|
|
123
|
+
if (plan.activeGoalId === goal.id)
|
|
124
|
+
delete plan.activeGoalId;
|
|
125
|
+
}
|
|
126
|
+
function ledgerKind(status, goal, aggregateCompletion) {
|
|
127
|
+
if (aggregateCompletion !== undefined)
|
|
128
|
+
return "aggregate_completed";
|
|
129
|
+
if (status === "complete")
|
|
130
|
+
return "goal_completed";
|
|
131
|
+
if (goal.status === "needs_user_decision")
|
|
132
|
+
return "goal_needs_user_decision";
|
|
133
|
+
return status === "blocked" ? "goal_blocked" : "goal_failed";
|
|
134
|
+
}
|
|
135
|
+
function buildLedger(now, args, goal, qualityGate, codexGoal, aggregateCompletion) {
|
|
136
|
+
const entry = { at: now, kind: ledgerKind(args.status, goal, aggregateCompletion), goalId: goal.id, status: goal.status, evidence: args.evidence };
|
|
137
|
+
if (codexGoal !== undefined)
|
|
138
|
+
entry.codexGoal = codexGoal;
|
|
139
|
+
if (qualityGate !== undefined)
|
|
140
|
+
entry.qualityGate = qualityGate;
|
|
141
|
+
if (goal.blockerSignature !== undefined)
|
|
142
|
+
entry.blockerSignature = goal.blockerSignature;
|
|
143
|
+
if (goal.blockerOccurrenceCount !== undefined)
|
|
144
|
+
entry.blockerOccurrenceCount = goal.blockerOccurrenceCount;
|
|
145
|
+
if (goal.requiredExternalDecision !== undefined)
|
|
146
|
+
entry.requiredExternalDecision = goal.requiredExternalDecision;
|
|
147
|
+
return entry;
|
|
148
|
+
}
|
|
149
|
+
export async function checkpointUlwLoop(repoRoot, args, scope) {
|
|
150
|
+
return withUlwLoopMutationLock(repoRoot, scope, async () => {
|
|
151
|
+
const plan = await readUlwLoopPlan(repoRoot, scope);
|
|
152
|
+
const goal = findGoal(plan, args.goalId);
|
|
153
|
+
if (args.status === "complete")
|
|
154
|
+
requireAllCriteriaPass(goal);
|
|
155
|
+
const evidence = nonEmptyEvidence(args.evidence);
|
|
156
|
+
const now = iso();
|
|
157
|
+
let aggregateCompletion;
|
|
158
|
+
let qualityGate;
|
|
159
|
+
let codexGoal;
|
|
160
|
+
if (args.status === "complete") {
|
|
161
|
+
const aggregate = codexGoalMode(plan) === "aggregate";
|
|
162
|
+
const final = isFinalRunCompletionCandidate(plan, goal);
|
|
163
|
+
const snapshot = await readCodexGoalSnapshotInput(args.codexGoalJson, repoRoot);
|
|
164
|
+
const reconciliation = reconcileCodexGoalSnapshot(snapshot, { expectedObjective: expectedCodexObjective(plan, goal), ...(aggregate ? { acceptedObjectives: compatibleCodexObjectives(plan) } : {}), allowedStatuses: aggregate ? (final ? ["complete"] : ["active"]) : ["complete"], requireSnapshot: true, requireComplete: !aggregate || final });
|
|
165
|
+
codexGoal = reconciliation.snapshot.raw;
|
|
166
|
+
if (!reconciliation.ok) {
|
|
167
|
+
const objective = snapshot?.objective;
|
|
168
|
+
const mismatchedTaskObjective = snapshot?.available === true && objective !== undefined && normalizeObjective(objective) !== normalizeObjective(expectedCodexObjective(plan, goal));
|
|
169
|
+
const completedTaskScoped = mismatchedTaskObjective && snapshot.status === "complete" && await canReconcileCompletedTaskScopedAggregateSnapshot(repoRoot, plan, goal, objective, evidence, scope);
|
|
170
|
+
const activeFinalTaskScoped = mismatchedTaskObjective && snapshot.status === "active" && await canReconcileActiveFinalTaskScopedAggregateSnapshot(repoRoot, plan, goal, objective, evidence, scope);
|
|
171
|
+
const taskScoped = completedTaskScoped || activeFinalTaskScoped;
|
|
172
|
+
if (!taskScoped)
|
|
173
|
+
throw new UlwLoopError(`${formatCodexGoalReconciliation(reconciliation)}${aggregate && snapshot?.status === "complete" && objective !== undefined ? buildTaskScopedAggregateReconciliationHint(goal, final) : ""}`, "ulw_loop_codex_snapshot_mismatch");
|
|
174
|
+
aggregateCompletion = makeAggregateCompletion(now, evidence, codexGoal);
|
|
175
|
+
}
|
|
176
|
+
if (final)
|
|
177
|
+
aggregateCompletion = makeAggregateCompletion(now, evidence, codexGoal);
|
|
178
|
+
if (final || aggregateCompletion !== undefined)
|
|
179
|
+
qualityGate = validateQualityGate(await readJsonInput(args.qualityGateJson, repoRoot));
|
|
180
|
+
goal.status = "complete";
|
|
181
|
+
goal.completedAt = now;
|
|
182
|
+
goal.evidence = evidence;
|
|
183
|
+
delete goal.failedAt;
|
|
184
|
+
delete goal.failureReason;
|
|
185
|
+
clearGoalBlockerFields(goal);
|
|
186
|
+
if (plan.activeGoalId === goal.id)
|
|
187
|
+
delete plan.activeGoalId;
|
|
188
|
+
}
|
|
189
|
+
else
|
|
190
|
+
applyBlockedOrFailed(goal, plan, args.status, evidence, now);
|
|
191
|
+
goal.updatedAt = now;
|
|
192
|
+
if (aggregateCompletion !== undefined)
|
|
193
|
+
plan.aggregateCompletion = aggregateCompletion;
|
|
194
|
+
plan.updatedAt = now;
|
|
195
|
+
await writePlan(repoRoot, plan, scope);
|
|
196
|
+
const ledgerEntry = buildLedger(now, args, goal, qualityGate, codexGoal, aggregateCompletion);
|
|
197
|
+
await appendLedger(repoRoot, ledgerEntry, scope);
|
|
198
|
+
return aggregateCompletion === undefined ? { plan, goal, ledgerEntry } : { plan, goal, ledgerEntry, aggregateCompletion };
|
|
199
|
+
});
|
|
200
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
type RecordEvidenceCliArgs = {
|
|
2
|
+
readonly goalId: string;
|
|
3
|
+
readonly criterionId: string;
|
|
4
|
+
readonly status: "pass" | "fail" | "blocked";
|
|
5
|
+
readonly evidence: string;
|
|
6
|
+
readonly notes?: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function hasFlag(argv: readonly string[], flag: string): boolean;
|
|
9
|
+
export declare function readValue(argv: readonly string[], flag: string): string | undefined;
|
|
10
|
+
export declare function readRepeated(argv: readonly string[], flag: string): string[];
|
|
11
|
+
export declare function parseGoalArg(argv: readonly string[]): string | undefined;
|
|
12
|
+
export declare function readStdin(): Promise<string>;
|
|
13
|
+
export declare function positionalText(argv: readonly string[]): string;
|
|
14
|
+
export declare function readJsonInput(value: string | undefined): Promise<unknown | undefined>;
|
|
15
|
+
export declare function parseCodexGoalJson(value: string | undefined): Promise<string | undefined>;
|
|
16
|
+
export declare function parseRecordEvidenceArgs(argv: readonly string[]): RecordEvidenceCliArgs;
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// biome-ignore-all format: keep this module under the mandated pure LOC budget.
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { UlwLoopError } from "./types.js";
|
|
4
|
+
const VALUE_FLAGS = new Set("--brief --brief-file --session-id --codex-goal-mode --goal --goal-id --criterion-id --status --evidence --notes --codex-goal-json --quality-gate-json --kind --rationale --title --objective --target-goal-id --source --after-json --directive-json --directive-file --idempotency-key".split(" "));
|
|
5
|
+
const SUBCOMMANDS = new Set("create-goals status complete-goals criteria record-evidence checkpoint steer add-goal record-review-blockers".split(" "));
|
|
6
|
+
export function hasFlag(argv, flag) { return argv.includes(flag); }
|
|
7
|
+
export function readValue(argv, flag) {
|
|
8
|
+
const index = argv.indexOf(flag);
|
|
9
|
+
if (index >= 0) {
|
|
10
|
+
const next = argv[index + 1];
|
|
11
|
+
return next === undefined || next.startsWith("--") ? undefined : next;
|
|
12
|
+
}
|
|
13
|
+
const prefix = `${flag}=`;
|
|
14
|
+
return argv.find((arg) => arg.startsWith(prefix))?.slice(prefix.length);
|
|
15
|
+
}
|
|
16
|
+
export function readRepeated(argv, flag) {
|
|
17
|
+
const values = [];
|
|
18
|
+
const prefix = `${flag}=`;
|
|
19
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
20
|
+
const arg = argv[index];
|
|
21
|
+
const next = argv[index + 1];
|
|
22
|
+
if (arg === flag && next !== undefined && !next.startsWith("--")) {
|
|
23
|
+
values.push(next);
|
|
24
|
+
index += 1;
|
|
25
|
+
}
|
|
26
|
+
else if (arg?.startsWith(prefix))
|
|
27
|
+
values.push(arg.slice(prefix.length));
|
|
28
|
+
}
|
|
29
|
+
return values;
|
|
30
|
+
}
|
|
31
|
+
export function parseGoalArg(argv) { return readValue(argv, "--goal-id") ?? readValue(argv, "--goal"); }
|
|
32
|
+
export async function readStdin() {
|
|
33
|
+
const chunks = [];
|
|
34
|
+
for await (const chunk of process.stdin)
|
|
35
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
36
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
37
|
+
}
|
|
38
|
+
export function positionalText(argv) {
|
|
39
|
+
const words = [];
|
|
40
|
+
for (let index = SUBCOMMANDS.has(argv[0] ?? "") ? 1 : 0; index < argv.length; index += 1) {
|
|
41
|
+
const arg = argv[index];
|
|
42
|
+
if (arg === undefined)
|
|
43
|
+
continue;
|
|
44
|
+
if (VALUE_FLAGS.has(arg)) {
|
|
45
|
+
index += 1;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (arg.startsWith("--"))
|
|
49
|
+
continue;
|
|
50
|
+
words.push(arg);
|
|
51
|
+
}
|
|
52
|
+
return words.join(" ").trim();
|
|
53
|
+
}
|
|
54
|
+
function looksLikeJson(value) { const trimmed = value.trim(); return trimmed.startsWith("{") || trimmed.startsWith("["); }
|
|
55
|
+
export async function readJsonInput(value) {
|
|
56
|
+
if (value === undefined)
|
|
57
|
+
return undefined;
|
|
58
|
+
try {
|
|
59
|
+
return JSON.parse(looksLikeJson(value) ? value : await readFile(value, "utf8"));
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
const message = error instanceof Error ? error.message : "unknown error";
|
|
63
|
+
throw new UlwLoopError(`Invalid JSON input: ${message}`, "ULW_LOOP_JSON_INPUT_INVALID", { cause: error });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
export async function parseCodexGoalJson(value) {
|
|
67
|
+
if (value === undefined)
|
|
68
|
+
return undefined;
|
|
69
|
+
const raw = looksLikeJson(value) ? value : await readFile(value, "utf8");
|
|
70
|
+
try {
|
|
71
|
+
JSON.parse(raw);
|
|
72
|
+
return raw;
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
const message = error instanceof Error ? error.message : "unknown error";
|
|
76
|
+
throw new UlwLoopError(`Invalid --codex-goal-json: ${message}`, "ULW_LOOP_CODEX_GOAL_JSON_INVALID", { cause: error });
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function required(argv, flag, code) {
|
|
80
|
+
const value = readValue(argv, flag)?.trim();
|
|
81
|
+
if (value)
|
|
82
|
+
return value;
|
|
83
|
+
throw new UlwLoopError(`Missing ${flag}.`, code, { details: { flag } });
|
|
84
|
+
}
|
|
85
|
+
function evidenceStatus(value) {
|
|
86
|
+
switch (value) {
|
|
87
|
+
case "pass": return "pass";
|
|
88
|
+
case "fail": return "fail";
|
|
89
|
+
case "blocked": return "blocked";
|
|
90
|
+
default: throw new UlwLoopError("Invalid --status; expected pass, fail, or blocked.", "ULW_LOOP_EVIDENCE_STATUS_INVALID", { details: { status: value } });
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
export function parseRecordEvidenceArgs(argv) {
|
|
94
|
+
const result = { goalId: required(argv, "--goal-id", "ULW_LOOP_GOAL_ID_REQUIRED"), criterionId: required(argv, "--criterion-id", "ULW_LOOP_CRITERION_ID_REQUIRED"), status: evidenceStatus(required(argv, "--status", "ULW_LOOP_EVIDENCE_STATUS_REQUIRED")), evidence: required(argv, "--evidence", "ULW_LOOP_EVIDENCE_REQUIRED") };
|
|
95
|
+
const notes = readValue(argv, "--notes")?.trim();
|
|
96
|
+
return notes ? { ...result, notes } : result;
|
|
97
|
+
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export declare const ULW_LOOP_SUBCOMMANDS: readonly ["help", "create-goals", "status", "complete-goals", "checkpoint", "steer", "add-goal", "criteria", "record-evidence", "record-review-blockers"];
|
|
2
|
+
export type UlwLoopSubcommand = (typeof ULW_LOOP_SUBCOMMANDS)[number];
|
|
3
|
+
export declare function isUlwLoopSubcommand(value: string): value is UlwLoopSubcommand;
|
|
4
|
+
export declare function ulwLoopCommand(argv: readonly string[]): Promise<number>;
|