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
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
// biome-ignore-all format: keep cli-commands dispatcher under the 200 pure LOC budget.
|
|
2
|
+
import { readFile } from "node:fs/promises";
|
|
3
|
+
import { checkpointUlwLoop } from "./checkpoint.js";
|
|
4
|
+
import { hasFlag, parseCodexGoalJson, parseRecordEvidenceArgs, positionalText, readStdin, readValue } from "./cli-arg-parser.js";
|
|
5
|
+
import { blockedDecisionHandoff, normalizeCodexGoalMode, printJson, printStatus, ULW_LOOP_HELP } from "./cli-output.js";
|
|
6
|
+
import { parseSteeringProposal, printSteerResult } from "./cli-steering.js";
|
|
7
|
+
import { buildCodexGoalInstruction } from "./codex-goal-instruction.js";
|
|
8
|
+
import { recordEvidence } from "./evidence.js";
|
|
9
|
+
import { resolveUlwLoopSessionIdFromEnv } from "./paths.js";
|
|
10
|
+
import { addUlwLoopGoal, createUlwLoopPlan, startNextUlwLoop, summarizeUlwLoopPlan } from "./plan-crud.js";
|
|
11
|
+
import { readUlwLoopPlan } from "./plan-io.js";
|
|
12
|
+
import { recordFinalReviewBlockers } from "./review-blockers.js";
|
|
13
|
+
import { steerUlwLoop } from "./steering.js";
|
|
14
|
+
import { UlwLoopError } from "./types.js";
|
|
15
|
+
export const ULW_LOOP_SUBCOMMANDS = ["help", "create-goals", "status", "complete-goals", "checkpoint", "steer", "add-goal", "criteria", "record-evidence", "record-review-blockers"];
|
|
16
|
+
export function isUlwLoopSubcommand(value) {
|
|
17
|
+
return ULW_LOOP_SUBCOMMANDS.includes(value);
|
|
18
|
+
}
|
|
19
|
+
export async function ulwLoopCommand(argv) {
|
|
20
|
+
const head = argv[0] ?? "help";
|
|
21
|
+
const command = head === "--help" || head === "-h" ? "help" : head;
|
|
22
|
+
const rest = argv.slice(1);
|
|
23
|
+
const repoRoot = process.cwd();
|
|
24
|
+
const json = hasFlag(rest, "--json");
|
|
25
|
+
const scope = commandScope(rest);
|
|
26
|
+
try {
|
|
27
|
+
if (!isUlwLoopSubcommand(command)) {
|
|
28
|
+
process.stdout.write(`${ULW_LOOP_HELP}\n`);
|
|
29
|
+
return 1;
|
|
30
|
+
}
|
|
31
|
+
switch (command) {
|
|
32
|
+
case "help":
|
|
33
|
+
process.stdout.write(`${ULW_LOOP_HELP}\n`);
|
|
34
|
+
return 0;
|
|
35
|
+
case "create-goals": return await createGoals(repoRoot, rest, json, scope);
|
|
36
|
+
case "status": return await status(repoRoot, json, scope);
|
|
37
|
+
case "complete-goals": return await completeGoals(repoRoot, rest, json, scope);
|
|
38
|
+
case "checkpoint": return await checkpoint(repoRoot, rest, json, scope);
|
|
39
|
+
case "steer": return await steer(repoRoot, rest, json, scope);
|
|
40
|
+
case "add-goal": return await addGoal(repoRoot, rest, json, scope);
|
|
41
|
+
case "criteria": return await criteria(repoRoot, rest, json, scope);
|
|
42
|
+
case "record-evidence": return await captureEvidence(repoRoot, rest, json, scope);
|
|
43
|
+
case "record-review-blockers": return await reviewBlockers(repoRoot, rest, json, scope);
|
|
44
|
+
default: return unhandledSubcommand(command);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
if (error instanceof UlwLoopError)
|
|
49
|
+
process.stderr.write(`[ulw-loop] ${error.message}\n`);
|
|
50
|
+
else if (error instanceof Error)
|
|
51
|
+
process.stderr.write(`[ulw-loop] unexpected: ${error.message}\n`);
|
|
52
|
+
else
|
|
53
|
+
process.stderr.write("[ulw-loop] unknown error\n");
|
|
54
|
+
return 1;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function unhandledSubcommand(command) {
|
|
58
|
+
throw new UlwLoopError(`Unhandled ulw-loop subcommand: ${String(command)}.`, "ULW_LOOP_SUBCOMMAND_UNHANDLED");
|
|
59
|
+
}
|
|
60
|
+
function commandScope(argv) {
|
|
61
|
+
const sessionId = readValue(argv, "--session-id") ?? resolveUlwLoopSessionIdFromEnv();
|
|
62
|
+
return sessionId === null ? undefined : { sessionId };
|
|
63
|
+
}
|
|
64
|
+
async function createGoals(repoRoot, argv, json, scope) {
|
|
65
|
+
const briefFile = readValue(argv, "--brief-file");
|
|
66
|
+
const brief = readValue(argv, "--brief") ?? (briefFile === undefined ? undefined : await readFile(briefFile, "utf8")) ?? (hasFlag(argv, "--from-stdin") ? await readStdin() : undefined) ?? positionalText(argv);
|
|
67
|
+
if (!brief.trim())
|
|
68
|
+
throw new UlwLoopError("Missing brief text. Pass --brief, --brief-file, --from-stdin, or positional text.", "ULW_LOOP_BRIEF_REQUIRED");
|
|
69
|
+
const plan = await createUlwLoopPlan(repoRoot, { brief, codexGoalMode: normalizeCodexGoalMode(readValue(argv, "--codex-goal-mode")), force: hasFlag(argv, "--force") }, scope);
|
|
70
|
+
if (json)
|
|
71
|
+
printJson({ ok: true, plan, summary: summarizeUlwLoopPlan(plan) });
|
|
72
|
+
else
|
|
73
|
+
process.stdout.write(`ulw-loop plan created: ${plan.goals.length} goal(s)\nbrief: ${plan.briefPath}\ngoals: ${plan.goalsPath}\nledger: ${plan.ledgerPath}\n`);
|
|
74
|
+
return 0;
|
|
75
|
+
}
|
|
76
|
+
async function status(repoRoot, json, scope) {
|
|
77
|
+
const plan = await readUlwLoopPlan(repoRoot, scope);
|
|
78
|
+
if (json)
|
|
79
|
+
printJson({ ok: true, plan, summary: summarizeUlwLoopPlan(plan) });
|
|
80
|
+
else
|
|
81
|
+
printStatus(plan);
|
|
82
|
+
return 0;
|
|
83
|
+
}
|
|
84
|
+
async function completeGoals(repoRoot, argv, json, scope) {
|
|
85
|
+
const result = await startNextUlwLoop(repoRoot, { retryFailed: hasFlag(argv, "--retry-failed") }, scope);
|
|
86
|
+
if ("done" in result) {
|
|
87
|
+
const handoff = blockedDecisionHandoff(result.plan);
|
|
88
|
+
if (json)
|
|
89
|
+
printJson({ ok: true, done: true, blocked: handoff.length > 0, handoff, summary: summarizeUlwLoopPlan(result.plan), plan: result.plan });
|
|
90
|
+
else
|
|
91
|
+
process.stdout.write(`${handoff || "ulw-loop: all goals complete"}\n`);
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
const instruction = buildCodexGoalInstruction({ plan: result.plan, goal: result.goal });
|
|
95
|
+
if (json)
|
|
96
|
+
printJson({ ok: true, resumed: result.resumed, goal: result.goal, instruction, plan: result.plan });
|
|
97
|
+
else
|
|
98
|
+
process.stdout.write(`${instruction.text}\n`);
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
async function checkpoint(repoRoot, argv, json, scope) {
|
|
102
|
+
const goalId = required(argv, "--goal-id");
|
|
103
|
+
const statusValue = checkpointStatus(required(argv, "--status"));
|
|
104
|
+
const evidence = required(argv, "--evidence");
|
|
105
|
+
const codexGoalJson = await parseCodexGoalJson(statusValue === "complete" ? required(argv, "--codex-goal-json") : readValue(argv, "--codex-goal-json"));
|
|
106
|
+
if (statusValue === "complete" && codexGoalJson === undefined)
|
|
107
|
+
throw new UlwLoopError("Missing --codex-goal-json.", "ULW_LOOP_CODEX_GOAL_JSON_REQUIRED");
|
|
108
|
+
const qualityGateJson = readValue(argv, "--quality-gate-json");
|
|
109
|
+
const args = {
|
|
110
|
+
goalId,
|
|
111
|
+
status: statusValue,
|
|
112
|
+
evidence,
|
|
113
|
+
...(codexGoalJson === undefined ? {} : { codexGoalJson }),
|
|
114
|
+
...(qualityGateJson === undefined ? {} : { qualityGateJson }),
|
|
115
|
+
};
|
|
116
|
+
const result = await checkpointUlwLoop(repoRoot, args, scope);
|
|
117
|
+
if (json)
|
|
118
|
+
printJson({ ok: true, ...result, summary: summarizeUlwLoopPlan(result.plan) });
|
|
119
|
+
else
|
|
120
|
+
process.stdout.write(`ulw-loop checkpoint: ${result.goal.id} -> ${result.goal.status}\n`);
|
|
121
|
+
return 0;
|
|
122
|
+
}
|
|
123
|
+
async function steer(repoRoot, argv, json, scope) {
|
|
124
|
+
const proposal = await parseSteeringProposal(argv);
|
|
125
|
+
const result = await steerUlwLoop(repoRoot, proposal, scope);
|
|
126
|
+
printSteerResult(result, json);
|
|
127
|
+
return result.accepted ? 0 : 1;
|
|
128
|
+
}
|
|
129
|
+
async function addGoal(repoRoot, argv, json, scope) {
|
|
130
|
+
const result = await addUlwLoopGoal(repoRoot, { title: required(argv, "--title"), objective: required(argv, "--objective") }, scope);
|
|
131
|
+
if (json)
|
|
132
|
+
printJson({ ok: true, plan: result.plan, goal: result.goal, summary: summarizeUlwLoopPlan(result.plan) });
|
|
133
|
+
else {
|
|
134
|
+
process.stdout.write(`ulw-loop added goal: ${result.goal.id}\n`);
|
|
135
|
+
printStatus(result.plan);
|
|
136
|
+
}
|
|
137
|
+
return 0;
|
|
138
|
+
}
|
|
139
|
+
async function criteria(repoRoot, argv, json, scope) {
|
|
140
|
+
const goalId = required(argv, "--goal-id");
|
|
141
|
+
const goal = findGoal(await readUlwLoopPlan(repoRoot, scope), goalId);
|
|
142
|
+
if (json)
|
|
143
|
+
printJson({ ok: true, goalId: goal.id, criteria: goal.successCriteria });
|
|
144
|
+
else
|
|
145
|
+
process.stdout.write(`criteria for ${goal.id}:\n${goal.successCriteria.map((c) => `- ${c.id} [${c.status}] (${c.userModel}) ${c.scenario} evidence: ${c.capturedEvidence ?? "pending"}`).join("\n")}\n`);
|
|
146
|
+
return 0;
|
|
147
|
+
}
|
|
148
|
+
async function captureEvidence(repoRoot, argv, json, scope) {
|
|
149
|
+
const result = await recordEvidence(repoRoot, parseRecordEvidenceArgs(argv), scope);
|
|
150
|
+
if (json)
|
|
151
|
+
printJson({ ok: true, ...result, summary: summarizeUlwLoopPlan(result.plan) });
|
|
152
|
+
else
|
|
153
|
+
process.stdout.write(`ulw-loop evidence recorded: ${result.goal.id}/${result.criterion.id} -> ${result.criterion.status}\n`);
|
|
154
|
+
return 0;
|
|
155
|
+
}
|
|
156
|
+
async function reviewBlockers(repoRoot, argv, json, scope) {
|
|
157
|
+
const codexGoalJson = await parseCodexGoalJson(required(argv, "--codex-goal-json"));
|
|
158
|
+
if (codexGoalJson === undefined)
|
|
159
|
+
throw new UlwLoopError("Missing --codex-goal-json.", "ULW_LOOP_CODEX_GOAL_JSON_REQUIRED");
|
|
160
|
+
const result = await recordFinalReviewBlockers(repoRoot, { goalId: required(argv, "--goal-id"), title: required(argv, "--title"), objective: required(argv, "--objective"), evidence: required(argv, "--evidence"), codexGoalJson }, scope);
|
|
161
|
+
if (json)
|
|
162
|
+
printJson({ ok: true, plan: result.plan, blockedGoal: result.blockedGoal, goal: result.newGoal, ledgerEntries: result.ledgerEntries, summary: summarizeUlwLoopPlan(result.plan) });
|
|
163
|
+
else
|
|
164
|
+
process.stdout.write(`ulw-loop final review blockers recorded: ${result.blockedGoal.id} -> review_blocked; added ${result.newGoal.id}\n`);
|
|
165
|
+
return 0;
|
|
166
|
+
}
|
|
167
|
+
function required(argv, flag) {
|
|
168
|
+
const value = readValue(argv, flag)?.trim();
|
|
169
|
+
if (value)
|
|
170
|
+
return value;
|
|
171
|
+
throw new UlwLoopError(`Missing ${flag}.`, "ULW_LOOP_ARGUMENT_MISSING", { details: { flag } });
|
|
172
|
+
}
|
|
173
|
+
function checkpointStatus(value) {
|
|
174
|
+
if (value === "complete" || value === "failed" || value === "blocked")
|
|
175
|
+
return value;
|
|
176
|
+
throw new UlwLoopError("Missing or invalid --status; expected complete, failed, or blocked.", "ULW_LOOP_STATUS_INVALID", { details: { status: value } });
|
|
177
|
+
}
|
|
178
|
+
function findGoal(plan, goalId) {
|
|
179
|
+
const goal = plan.goals.find((candidate) => candidate.id === goalId);
|
|
180
|
+
if (goal !== undefined)
|
|
181
|
+
return goal;
|
|
182
|
+
throw new UlwLoopError(`Unknown ulw-loop id: ${goalId}.`, "ULW_LOOP_GOAL_NOT_FOUND", { details: { goalId } });
|
|
183
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { UlwLoopCodexGoalMode, UlwLoopPlan } from "./types.js";
|
|
2
|
+
export declare const ULW_LOOP_HELP = "Usage:\n omo ulw-loop create-goals --brief \"...\" [--brief-file <path>] [--from-stdin] [--codex-goal-mode aggregate|per_story] [--force] [--json]\n omo ulw-loop status [--json]\n omo ulw-loop complete-goals [--retry-failed] [--json]\n omo ulw-loop criteria --goal-id <id> [--json]\n omo ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status pass|fail|blocked --evidence \"...\" [--notes \"...\"] [--json]\n omo ulw-loop checkpoint --goal-id <id> --status complete|failed|blocked --evidence \"...\" --codex-goal-json <...> [--quality-gate-json <...>] [--json]\n omo ulw-loop steer --kind <kind> ... --evidence \"...\" --rationale \"...\" [--json]\n omo ulw-loop add-goal --title \"...\" --objective \"...\" [--json]\n omo ulw-loop record-review-blockers --goal-id <id> --title \"...\" --objective \"...\" --evidence \"...\" --codex-goal-json <...> [--json]\n\nAll subcommands accept [--session-id <id>] to isolate state under .omo/ulw-loop/<id>/; without it, Codex session env is used when present.";
|
|
3
|
+
export declare function printJson(value: unknown): void;
|
|
4
|
+
export declare function printStatus(plan: UlwLoopPlan): void;
|
|
5
|
+
export declare function blockedDecisionHandoff(plan: UlwLoopPlan): string;
|
|
6
|
+
export declare function normalizeCodexGoalMode(value: string | undefined): UlwLoopCodexGoalMode;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { UlwLoopError } from "./types.js";
|
|
2
|
+
export const ULW_LOOP_HELP = `Usage:
|
|
3
|
+
omo ulw-loop create-goals --brief "..." [--brief-file <path>] [--from-stdin] [--codex-goal-mode aggregate|per_story] [--force] [--json]
|
|
4
|
+
omo ulw-loop status [--json]
|
|
5
|
+
omo ulw-loop complete-goals [--retry-failed] [--json]
|
|
6
|
+
omo ulw-loop criteria --goal-id <id> [--json]
|
|
7
|
+
omo ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status pass|fail|blocked --evidence "..." [--notes "..."] [--json]
|
|
8
|
+
omo ulw-loop checkpoint --goal-id <id> --status complete|failed|blocked --evidence "..." --codex-goal-json <...> [--quality-gate-json <...>] [--json]
|
|
9
|
+
omo ulw-loop steer --kind <kind> ... --evidence "..." --rationale "..." [--json]
|
|
10
|
+
omo ulw-loop add-goal --title "..." --objective "..." [--json]
|
|
11
|
+
omo ulw-loop record-review-blockers --goal-id <id> --title "..." --objective "..." --evidence "..." --codex-goal-json <...> [--json]
|
|
12
|
+
|
|
13
|
+
All subcommands accept [--session-id <id>] to isolate state under .omo/ulw-loop/<id>/; without it, Codex session env is used when present.`;
|
|
14
|
+
export function printJson(value) {
|
|
15
|
+
process.stdout.write(`${JSON.stringify(value, null, 2)}\n`);
|
|
16
|
+
}
|
|
17
|
+
function criteriaCounts(goal) {
|
|
18
|
+
let pass = 0;
|
|
19
|
+
for (const criterion of goal.successCriteria)
|
|
20
|
+
if (criterion.status === "pass")
|
|
21
|
+
pass += 1;
|
|
22
|
+
return { pass, total: goal.successCriteria.length };
|
|
23
|
+
}
|
|
24
|
+
export function printStatus(plan) {
|
|
25
|
+
let totalCriteria = 0;
|
|
26
|
+
let passCriteria = 0;
|
|
27
|
+
const lines = ["ulw-loop status", "", "goals:"];
|
|
28
|
+
for (const goal of plan.goals) {
|
|
29
|
+
const counts = criteriaCounts(goal);
|
|
30
|
+
totalCriteria += counts.total;
|
|
31
|
+
passCriteria += counts.pass;
|
|
32
|
+
const marker = goal.id === plan.activeGoalId ? "*" : "-";
|
|
33
|
+
lines.push(`${marker} ${goal.id} [${goal.status}] ${goal.title} (criteria: ${counts.pass}/${counts.total})`);
|
|
34
|
+
}
|
|
35
|
+
lines.push("", "summary:", `total goals: ${plan.goals.length}`, `criteria: ${passCriteria}/${totalCriteria} pass`);
|
|
36
|
+
process.stdout.write(`${lines.join("\n")}\n`);
|
|
37
|
+
}
|
|
38
|
+
export function blockedDecisionHandoff(plan) {
|
|
39
|
+
const blocked = plan.goals.find((goal) => goal.status === "needs_user_decision" && goal.nonRetriable);
|
|
40
|
+
if (blocked === undefined)
|
|
41
|
+
return "";
|
|
42
|
+
return [
|
|
43
|
+
"ulw-loop: blocked on repeated external authorization; no retryable failed goals remain.",
|
|
44
|
+
`Goal: ${blocked.id} - ${blocked.title}`,
|
|
45
|
+
`Required external decision: ${blocked.requiredExternalDecision ?? "provide the missing authorization or choose a different unblock path"}.`,
|
|
46
|
+
"Do not run complete-goals --retry-failed again until external state changes or the user authorizes an unblock path.",
|
|
47
|
+
].join("\n");
|
|
48
|
+
}
|
|
49
|
+
export function normalizeCodexGoalMode(value) {
|
|
50
|
+
if (value === undefined)
|
|
51
|
+
return "aggregate";
|
|
52
|
+
if (value === "aggregate" || value === "per_story")
|
|
53
|
+
return value;
|
|
54
|
+
throw new UlwLoopError("Invalid --codex-goal-mode; expected aggregate or per_story.", "ULW_LOOP_CODEX_GOAL_MODE_INVALID", { details: { value } });
|
|
55
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SteerUlwLoopResult, UlwLoopSteeringMutationKind, UlwLoopSteeringProposal, UlwLoopSteeringSource, UlwLoopSuccessCriterionUserModel } from "./types.js";
|
|
2
|
+
export type CliSteeringProposal = UlwLoopSteeringProposal & {
|
|
3
|
+
readonly goalId?: string;
|
|
4
|
+
readonly scenario?: string;
|
|
5
|
+
readonly expectedEvidence?: string;
|
|
6
|
+
readonly userModel?: UlwLoopSuccessCriterionUserModel;
|
|
7
|
+
};
|
|
8
|
+
export declare function parseSteeringKind(argv: readonly string[]): UlwLoopSteeringMutationKind;
|
|
9
|
+
export declare function parseSteeringSource(argv: readonly string[]): UlwLoopSteeringSource;
|
|
10
|
+
export declare function parseSteeringProposal(argv: readonly string[]): Promise<CliSteeringProposal>;
|
|
11
|
+
export declare function normalizeSteeringProposal(proposal: CliSteeringProposal): CliSteeringProposal;
|
|
12
|
+
export declare function printSteerResult(result: SteerUlwLoopResult, json: boolean): void;
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
// biome-ignore-all format: keep this module under the mandated pure LOC budget.
|
|
2
|
+
import { parseGoalArg, readJsonInput, readValue } from "./cli-arg-parser.js";
|
|
3
|
+
import { printJson, printStatus } from "./cli-output.js";
|
|
4
|
+
import { ULW_LOOP_STEERING_MUTATION_KINDS, ULW_LOOP_SUCCESS_CRITERION_USER_MODELS, UlwLoopError } from "./types.js";
|
|
5
|
+
const SOURCES = ["user_prompt_submit", "finding", "cli"];
|
|
6
|
+
function isKind(value) { return value !== undefined && ULW_LOOP_STEERING_MUTATION_KINDS.some((kind) => kind === value); }
|
|
7
|
+
function isSource(value) { return value !== undefined && SOURCES.some((source) => source === value); }
|
|
8
|
+
function isModel(value) { return ULW_LOOP_SUCCESS_CRITERION_USER_MODELS.some((model) => model === value); }
|
|
9
|
+
function fail(message, code, details) { throw new UlwLoopError(message, code, { details }); }
|
|
10
|
+
function text(value, field) { if (value === undefined)
|
|
11
|
+
return undefined; const trimmed = value.trim(); if (trimmed.length > 0)
|
|
12
|
+
return trimmed; return fail(`Empty ${field}.`, "ULW_LOOP_STEERING_FIELD_EMPTY", { field }); }
|
|
13
|
+
function required(argv, flag) { const value = text(readValue(argv, flag), flag); return value ?? fail(`Missing ${flag}.`, "ULW_LOOP_STEERING_FIELD_REQUIRED", { flag }); }
|
|
14
|
+
function requiredGoal(argv) { const value = text(parseGoalArg(argv), "--goal-id"); return value ?? fail("Missing --goal-id.", "ULW_LOOP_GOAL_ID_REQUIRED", { flag: "--goal-id" }); }
|
|
15
|
+
function readObject(value, key) { return Object.entries(value).find(([name]) => name === key)?.[1]; }
|
|
16
|
+
function isPlain(value) { return typeof value === "object" && value !== null && !Array.isArray(value); }
|
|
17
|
+
function objectText(value, key) { const candidate = readObject(value, key); return typeof candidate === "string" ? candidate : undefined; }
|
|
18
|
+
export function parseSteeringKind(argv) {
|
|
19
|
+
const value = readValue(argv, "--kind");
|
|
20
|
+
if (isKind(value))
|
|
21
|
+
return value;
|
|
22
|
+
return value === undefined ? fail("Missing --kind.", "ULW_LOOP_STEERING_KIND_REQUIRED", { flag: "--kind" }) : fail(`Invalid --kind: ${value}.`, "ULW_LOOP_STEERING_KIND_INVALID", { value, expected: ULW_LOOP_STEERING_MUTATION_KINDS });
|
|
23
|
+
}
|
|
24
|
+
export function parseSteeringSource(argv) {
|
|
25
|
+
const value = readValue(argv, "--source");
|
|
26
|
+
if (value === undefined)
|
|
27
|
+
return "cli";
|
|
28
|
+
return isSource(value) ? value : fail(`Invalid --source: ${value}.`, "ULW_LOOP_STEERING_SOURCE_INVALID", { value, expected: SOURCES });
|
|
29
|
+
}
|
|
30
|
+
function child(value) {
|
|
31
|
+
if (!isPlain(value))
|
|
32
|
+
return null;
|
|
33
|
+
const title = text(objectText(value, "title"), "title");
|
|
34
|
+
const objective = text(objectText(value, "objective"), "objective");
|
|
35
|
+
if (title === undefined || objective === undefined)
|
|
36
|
+
return null;
|
|
37
|
+
return { title, objective };
|
|
38
|
+
}
|
|
39
|
+
async function children(argv, flag, needed) {
|
|
40
|
+
const input = needed ? required(argv, flag) : text(readValue(argv, flag), flag);
|
|
41
|
+
if (input === undefined)
|
|
42
|
+
return [];
|
|
43
|
+
const raw = await readJsonInput(input);
|
|
44
|
+
if (!Array.isArray(raw))
|
|
45
|
+
return fail(`${flag} must be a JSON array.`, "ULW_LOOP_STEERING_JSON_ARRAY_REQUIRED", { flag });
|
|
46
|
+
const parsed = [];
|
|
47
|
+
for (const item of raw) {
|
|
48
|
+
const next = child(item);
|
|
49
|
+
if (next === null)
|
|
50
|
+
return fail(`${flag} entries require title/objective.`, "ULW_LOOP_STEERING_CHILD_INVALID", { flag });
|
|
51
|
+
parsed.push(next);
|
|
52
|
+
}
|
|
53
|
+
return parsed;
|
|
54
|
+
}
|
|
55
|
+
async function stringArray(argv, flag) {
|
|
56
|
+
const raw = await readJsonInput(required(argv, flag));
|
|
57
|
+
if (!Array.isArray(raw))
|
|
58
|
+
return fail(`${flag} must be a JSON array.`, "ULW_LOOP_STEERING_JSON_ARRAY_REQUIRED", { flag });
|
|
59
|
+
const values = [];
|
|
60
|
+
for (const item of raw) {
|
|
61
|
+
if (typeof item !== "string")
|
|
62
|
+
return fail(`${flag} entries must be strings.`, "ULW_LOOP_STEERING_STRING_ARRAY_REQUIRED", { flag });
|
|
63
|
+
values.push(text(item, flag) ?? "");
|
|
64
|
+
}
|
|
65
|
+
return values;
|
|
66
|
+
}
|
|
67
|
+
function model(value) { const trimmed = text(value, "--user-model"); if (trimmed === undefined)
|
|
68
|
+
return undefined; return isModel(trimmed) ? trimmed : fail(`Invalid --user-model: ${trimmed}.`, "ULW_LOOP_STEERING_USER_MODEL_INVALID", { value: trimmed, expected: ULW_LOOP_SUCCESS_CRITERION_USER_MODELS }); }
|
|
69
|
+
function neverKind(kind) { return fail(`Unsupported steering kind: ${String(kind)}.`, "ULW_LOOP_STEERING_KIND_UNSUPPORTED", { kind }); }
|
|
70
|
+
export async function parseSteeringProposal(argv) {
|
|
71
|
+
const kind = parseSteeringKind(argv);
|
|
72
|
+
const source = parseSteeringSource(argv);
|
|
73
|
+
const base = { kind, source, evidence: required(argv, "--evidence"), rationale: required(argv, "--rationale") };
|
|
74
|
+
switch (kind) {
|
|
75
|
+
case "add_subgoal": return normalizeSteeringProposal({ ...base, title: required(argv, "--title"), objective: required(argv, "--objective") });
|
|
76
|
+
case "split_subgoal": {
|
|
77
|
+
const goalId = requiredGoal(argv);
|
|
78
|
+
return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, childGoals: await children(argv, "--children", true) });
|
|
79
|
+
}
|
|
80
|
+
case "reorder_pending": return normalizeSteeringProposal({ ...base, pendingOrder: await stringArray(argv, "--order") });
|
|
81
|
+
case "revise_pending_wording": {
|
|
82
|
+
const goalId = requiredGoal(argv);
|
|
83
|
+
const revisedTitle = readValue(argv, "--title");
|
|
84
|
+
const revisedObjective = readValue(argv, "--objective");
|
|
85
|
+
if (revisedTitle === undefined && revisedObjective === undefined)
|
|
86
|
+
return fail("revise_pending_wording requires --title or --objective.", "ULW_LOOP_STEERING_UPDATE_REQUIRED", { kind });
|
|
87
|
+
return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, ...(revisedTitle === undefined ? {} : { revisedTitle }), ...(revisedObjective === undefined ? {} : { revisedObjective }) });
|
|
88
|
+
}
|
|
89
|
+
case "revise_criterion": {
|
|
90
|
+
const goalId = requiredGoal(argv);
|
|
91
|
+
const criterionId = required(argv, "--criterion-id");
|
|
92
|
+
const scenario = readValue(argv, "--scenario");
|
|
93
|
+
const expectedEvidence = readValue(argv, "--expected-evidence");
|
|
94
|
+
const userModel = model(readValue(argv, "--user-model"));
|
|
95
|
+
if (scenario === undefined && expectedEvidence === undefined && userModel === undefined)
|
|
96
|
+
return fail("revise_criterion requires scenario, expected-evidence, or user-model.", "ULW_LOOP_STEERING_UPDATE_REQUIRED", { kind });
|
|
97
|
+
return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, criterionId, ...(scenario === undefined ? {} : { scenario }), ...(expectedEvidence === undefined ? {} : { expectedEvidence }), ...(userModel === undefined ? {} : { userModel }) });
|
|
98
|
+
}
|
|
99
|
+
case "annotate_ledger": return normalizeSteeringProposal(base);
|
|
100
|
+
case "mark_blocked_superseded": {
|
|
101
|
+
const goalId = requiredGoal(argv);
|
|
102
|
+
const childGoals = await children(argv, "--replacements", false);
|
|
103
|
+
return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, ...(childGoals.length === 0 ? {} : { childGoals }) });
|
|
104
|
+
}
|
|
105
|
+
default: return neverKind(kind);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
function normalizedChildren(values) { if (values === undefined)
|
|
109
|
+
return undefined; return values.map((item) => ({ title: text(item.title, "child.title") ?? "", objective: text(item.objective, "child.objective") ?? "" })); }
|
|
110
|
+
function normalizedStrings(values, field) { if (values === undefined)
|
|
111
|
+
return undefined; return values.map((value) => text(value, field) ?? ""); }
|
|
112
|
+
export function normalizeSteeringProposal(proposal) {
|
|
113
|
+
const evidence = text(proposal.evidence, "evidence") ?? "";
|
|
114
|
+
const rationale = text(proposal.rationale, "rationale") ?? "";
|
|
115
|
+
const goalId = text(proposal.goalId, "goalId");
|
|
116
|
+
const targetGoalId = text(proposal.targetGoalId, "targetGoalId");
|
|
117
|
+
const targetGoalIds = normalizedStrings(proposal.targetGoalIds, "targetGoalIds");
|
|
118
|
+
const criterionId = text(proposal.criterionId, "criterionId");
|
|
119
|
+
const title = text(proposal.title, "title");
|
|
120
|
+
const objective = text(proposal.objective, "objective");
|
|
121
|
+
const revisedTitle = text(proposal.revisedTitle, "revisedTitle");
|
|
122
|
+
const revisedObjective = text(proposal.revisedObjective, "revisedObjective");
|
|
123
|
+
const blockedReason = text(proposal.blockedReason, "blockedReason");
|
|
124
|
+
const directiveText = text(proposal.directiveText, "directiveText");
|
|
125
|
+
const promptSignature = text(proposal.promptSignature, "promptSignature");
|
|
126
|
+
const idempotencyKey = text(proposal.idempotencyKey, "idempotencyKey");
|
|
127
|
+
const scenario = text(proposal.scenario, "scenario");
|
|
128
|
+
const expectedEvidence = text(proposal.expectedEvidence, "expectedEvidence");
|
|
129
|
+
const childGoals = normalizedChildren(proposal.childGoals);
|
|
130
|
+
const pendingOrder = normalizedStrings(proposal.pendingOrder, "pendingOrder");
|
|
131
|
+
return { kind: proposal.kind, source: proposal.source, evidence, rationale, ...(goalId === undefined ? {} : { goalId }), ...(targetGoalId === undefined ? {} : { targetGoalId }), ...(targetGoalIds === undefined ? {} : { targetGoalIds }), ...(criterionId === undefined ? {} : { criterionId }), ...(title === undefined ? {} : { title }), ...(objective === undefined ? {} : { objective }), ...(childGoals === undefined ? {} : { childGoals }), ...(revisedTitle === undefined ? {} : { revisedTitle }), ...(revisedObjective === undefined ? {} : { revisedObjective }), ...(pendingOrder === undefined ? {} : { pendingOrder }), ...(blockedReason === undefined ? {} : { blockedReason }), ...(proposal.after === undefined ? {} : { after: proposal.after }), ...(directiveText === undefined ? {} : { directiveText }), ...(promptSignature === undefined ? {} : { promptSignature }), ...(idempotencyKey === undefined ? {} : { idempotencyKey }), ...(proposal.now === undefined ? {} : { now: proposal.now }), ...(scenario === undefined ? {} : { scenario }), ...(expectedEvidence === undefined ? {} : { expectedEvidence }), ...(proposal.userModel === undefined ? {} : { userModel: proposal.userModel }) };
|
|
132
|
+
}
|
|
133
|
+
export function printSteerResult(result, json) {
|
|
134
|
+
if (json) {
|
|
135
|
+
printJson({ ok: result.accepted, accepted: result.accepted, rejectedReasons: result.rejectedReasons, deduped: result.deduped, audit: result.audit, plan: result.plan });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const outcome = result.deduped ? "deduped" : result.accepted ? "accepted" : "rejected";
|
|
139
|
+
process.stdout.write(`ulw-loop steer: ${outcome} ${result.audit.kind}\n`);
|
|
140
|
+
if (result.rejectedReasons.length > 0)
|
|
141
|
+
process.stdout.write(`rejected: ${result.rejectedReasons.join("; ")}\n`);
|
|
142
|
+
if (result.audit.idempotencyKey !== undefined)
|
|
143
|
+
process.stdout.write(`idempotency-key: ${result.audit.idempotencyKey}\n`);
|
|
144
|
+
printStatus(result.plan);
|
|
145
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { isUlwLoopSubcommand, ulwLoopCommand } from "./cli-commands.js";
|
|
3
|
+
import { runPreToolUseGoalBudgetGuardCli, runUlwLoopHookCli } from "./codex-hook.js";
|
|
4
|
+
const TOP_LEVEL_HELP = "Usage:\n omo ulw-loop <subcommand> [args]\n omo hook user-prompt-submit (Codex UserPromptSubmit hook)\n omo help | --help | -h (this message)\n\nRun `omo ulw-loop help` for ulw-loop subcommands.\n";
|
|
5
|
+
async function main() {
|
|
6
|
+
const argv = process.argv.slice(2);
|
|
7
|
+
const command = argv[0];
|
|
8
|
+
if (command === undefined || command === "help" || command === "--help" || command === "-h") {
|
|
9
|
+
process.stdout.write(TOP_LEVEL_HELP);
|
|
10
|
+
return 0;
|
|
11
|
+
}
|
|
12
|
+
if (command === "ulw-loop")
|
|
13
|
+
return ulwLoopCommand(argv.slice(1));
|
|
14
|
+
if (command === "hook") {
|
|
15
|
+
const sub = argv[1];
|
|
16
|
+
if (sub === "user-prompt-submit") {
|
|
17
|
+
await runUlwLoopHookCli(process.stdin, process.stdout);
|
|
18
|
+
return 0;
|
|
19
|
+
}
|
|
20
|
+
if (sub === "pre-tool-use") {
|
|
21
|
+
await runPreToolUseGoalBudgetGuardCli(process.stdin, process.stdout);
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
process.stderr.write(`[omo] unknown hook subcommand: ${sub ?? "(none)"}\n`);
|
|
25
|
+
return 1;
|
|
26
|
+
}
|
|
27
|
+
if (isUlwLoopSubcommand(command))
|
|
28
|
+
return ulwLoopCommand(argv);
|
|
29
|
+
process.stderr.write(`[omo] unknown command: ${command}\n${TOP_LEVEL_HELP}`);
|
|
30
|
+
return 1;
|
|
31
|
+
}
|
|
32
|
+
main()
|
|
33
|
+
.then((code) => {
|
|
34
|
+
process.exit(code);
|
|
35
|
+
})
|
|
36
|
+
.catch((error) => {
|
|
37
|
+
process.stderr.write(`[omo] ${error instanceof Error ? error.message : String(error)}\n`);
|
|
38
|
+
process.exit(1);
|
|
39
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { UlwLoopItem, UlwLoopPlan } from "./types.js";
|
|
2
|
+
export interface CodexCreateGoalPayload {
|
|
3
|
+
readonly objective: string;
|
|
4
|
+
}
|
|
5
|
+
export interface UlwLoopGoalInstruction {
|
|
6
|
+
readonly text: string;
|
|
7
|
+
readonly json: CodexCreateGoalPayload;
|
|
8
|
+
}
|
|
9
|
+
export declare function buildCodexGoalInstruction(args: {
|
|
10
|
+
readonly plan: UlwLoopPlan;
|
|
11
|
+
readonly goal: UlwLoopItem;
|
|
12
|
+
readonly isFinal?: boolean;
|
|
13
|
+
}): UlwLoopGoalInstruction;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { codexGoalMode, expectedCodexObjective, isFinalRunCompletionCandidate } from "./goal-status.js";
|
|
2
|
+
export function buildCodexGoalInstruction(args) {
|
|
3
|
+
const mode = codexGoalMode(args.plan);
|
|
4
|
+
const createGoal = buildCreateGoalPayload(args.plan, args.goal);
|
|
5
|
+
const isFinal = args.isFinal ?? isFinalRunCompletionCandidate(args.plan, args.goal);
|
|
6
|
+
return { text: buildText(mode, args.plan, args.goal, createGoal, isFinal), json: createGoal };
|
|
7
|
+
}
|
|
8
|
+
function buildCreateGoalPayload(plan, goal) {
|
|
9
|
+
return { objective: expectedCodexObjective(plan, goal) };
|
|
10
|
+
}
|
|
11
|
+
function buildText(mode, plan, goal, createGoal, isFinal) {
|
|
12
|
+
return joinLines([
|
|
13
|
+
mode === "aggregate" ? "UlwLoop aggregate-goal handoff" : "UlwLoop active-goal handoff",
|
|
14
|
+
`Mode: ${mode}`,
|
|
15
|
+
`Plan: ${plan.goalsPath}`,
|
|
16
|
+
`Ledger: ${plan.ledgerPath}`,
|
|
17
|
+
`Goal: ${goal.id} — ${goal.title}`,
|
|
18
|
+
"",
|
|
19
|
+
...activeGoalLines(goal),
|
|
20
|
+
"",
|
|
21
|
+
...successCriteriaLines(goal.successCriteria),
|
|
22
|
+
"",
|
|
23
|
+
"Codex goal integration constraints:",
|
|
24
|
+
"- Use the create_goal payload exactly as rendered: objective only.",
|
|
25
|
+
"- Goals are unlimited. Do not add numeric limits.",
|
|
26
|
+
...modeConstraintLines(mode, isFinal),
|
|
27
|
+
finalSection(plan, goal, isFinal, mode === "aggregate"),
|
|
28
|
+
...checkpointLines(plan, mode),
|
|
29
|
+
"",
|
|
30
|
+
"create_goal payload:",
|
|
31
|
+
JSON.stringify(createGoal, null, 2),
|
|
32
|
+
]);
|
|
33
|
+
}
|
|
34
|
+
function modeConstraintLines(mode, isFinal) {
|
|
35
|
+
if (mode === "per_story") {
|
|
36
|
+
return [
|
|
37
|
+
"- First call get_goal. If no active goal exists, call create_goal with the payload below.",
|
|
38
|
+
"- If a different active Codex goal exists, finish/checkpoint that goal before starting this ulw-loop.",
|
|
39
|
+
"- Work only this goal until its completion audit passes.",
|
|
40
|
+
];
|
|
41
|
+
}
|
|
42
|
+
return [
|
|
43
|
+
"- Codex goal = the whole omo ulw-loop run; OMO G001/G002/etc. = ledger stories.",
|
|
44
|
+
"- First call get_goal. If no active goal exists, call create_goal with the aggregate payload below.",
|
|
45
|
+
"- If get_goal reports the same aggregate objective as active, continue this OMO story without creating a new Codex goal.",
|
|
46
|
+
"- If a different active or incomplete Codex goal exists, finish/checkpoint that goal before starting this ulw-loop.",
|
|
47
|
+
isFinal
|
|
48
|
+
? "- This is the final story; update_goal is allowed only after the mandatory quality gate passes."
|
|
49
|
+
: "- This is not the final story: do not call update_goal yet; the aggregate Codex goal must remain active while later OMO stories remain.",
|
|
50
|
+
];
|
|
51
|
+
}
|
|
52
|
+
function checkpointLines(plan, mode) {
|
|
53
|
+
const failureLine = `- If blocked or failed, checkpoint with --status failed and the failure evidence; rerun complete-goals${sessionOption(plan)} --retry-failed to resume.`;
|
|
54
|
+
if (mode === "per_story")
|
|
55
|
+
return [failureLine];
|
|
56
|
+
return [
|
|
57
|
+
"- Checkpoint this OMO story with a fresh get_goal snapshot whose objective matches the aggregate payload.",
|
|
58
|
+
failureLine,
|
|
59
|
+
];
|
|
60
|
+
}
|
|
61
|
+
function activeGoalLines(goal) {
|
|
62
|
+
return ["Active goal:", `- id: ${goal.id}`, `- title: ${goal.title}`, `- objective: ${goal.objective}`];
|
|
63
|
+
}
|
|
64
|
+
function successCriteriaLines(criteria) {
|
|
65
|
+
if (criteria.length === 0)
|
|
66
|
+
return ["Success criteria:", "- No success criteria recorded for this goal."];
|
|
67
|
+
return ["Success criteria:", ...criteria.map(formatCriterionLine)];
|
|
68
|
+
}
|
|
69
|
+
function formatCriterionLine(criterion) {
|
|
70
|
+
const remainingWork = criterion.status === "pending" ? " remaining work:" : "";
|
|
71
|
+
return `-${remainingWork} [${criterion.id}] (${criterion.userModel}) ${criterion.scenario} — expect: ${criterion.expectedEvidence} — status: ${criterion.status}`;
|
|
72
|
+
}
|
|
73
|
+
function finalSection(plan, goal, isFinal, aggregate) {
|
|
74
|
+
if (!isFinal)
|
|
75
|
+
return "- This is not the final ulw-loop story; do not run the final ai-slop-cleaner/code-review gate yet.";
|
|
76
|
+
const option = sessionOption(plan);
|
|
77
|
+
const blockerCommand = `omo ulw-loop record-review-blockers${option} --goal-id ${goal.id} --title "Resolve final code-review blockers" --objective "<blocker-resolution objective>" --evidence "<review findings>" --codex-goal-json "<active get_goal JSON or path>"`;
|
|
78
|
+
const checkpointCommand = `omo ulw-loop checkpoint${option} --goal-id ${goal.id} --status complete --evidence "<tests/files/PR evidence>" --codex-goal-json "<fresh complete get_goal JSON or path>" --quality-gate-json "<quality gate JSON or path>"`;
|
|
79
|
+
return joinLines([
|
|
80
|
+
"Final story — run mandatory quality gate before update_goal:",
|
|
81
|
+
"- Run ai-slop-cleaner on changed files even when it is a no-op, rerun verification, then run the code review (multi_agent_v1.spawn_agent(agent_type=\"codex-ultrawork-reviewer\", fork_context=false, ...); fall back to agent_type=\"worker\" with a scoped reviewer assignment if unavailable).",
|
|
82
|
+
"- If the final review is not APPROVE with architect status CLEAR, do not call update_goal. Record blocker work first:",
|
|
83
|
+
` ${blockerCommand}`,
|
|
84
|
+
aggregate
|
|
85
|
+
? '- If the final review is clean, call update_goal({status: "complete"}), call get_goal again, then checkpoint the aggregate story:'
|
|
86
|
+
: '- If the final review is clean, call update_goal({status: "complete"}), call get_goal again, then checkpoint:',
|
|
87
|
+
` ${checkpointCommand}`,
|
|
88
|
+
]);
|
|
89
|
+
}
|
|
90
|
+
function sessionOption(plan) {
|
|
91
|
+
const prefix = ".omo/ulw-loop/";
|
|
92
|
+
const suffix = "/goals.json";
|
|
93
|
+
if (!plan.goalsPath.startsWith(prefix) || !plan.goalsPath.endsWith(suffix))
|
|
94
|
+
return "";
|
|
95
|
+
const sessionId = plan.goalsPath.slice(prefix.length, -suffix.length);
|
|
96
|
+
return sessionId.length === 0 ? "" : ` --session-id ${sessionId}`;
|
|
97
|
+
}
|
|
98
|
+
function joinLines(lines) {
|
|
99
|
+
return lines.join("\n");
|
|
100
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type CodexGoalSnapshotStatus = "active" | "complete" | "cancelled" | "failed" | "unknown";
|
|
2
|
+
export interface CodexGoalSnapshot {
|
|
3
|
+
available: boolean;
|
|
4
|
+
objective?: string;
|
|
5
|
+
status?: CodexGoalSnapshotStatus;
|
|
6
|
+
raw: unknown;
|
|
7
|
+
}
|
|
8
|
+
export interface CodexGoalReconciliation {
|
|
9
|
+
ok: boolean;
|
|
10
|
+
snapshot: CodexGoalSnapshot;
|
|
11
|
+
warnings: string[];
|
|
12
|
+
errors: string[];
|
|
13
|
+
}
|
|
14
|
+
export interface ReconcileCodexGoalOptions {
|
|
15
|
+
expectedObjective: string;
|
|
16
|
+
acceptedObjectives?: readonly string[];
|
|
17
|
+
allowedStatuses?: readonly CodexGoalSnapshotStatus[];
|
|
18
|
+
requireSnapshot?: boolean;
|
|
19
|
+
requireComplete?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare class CodexGoalSnapshotError extends Error {
|
|
22
|
+
}
|
|
23
|
+
export declare function parseCodexGoalSnapshot(value: unknown): CodexGoalSnapshot;
|
|
24
|
+
export declare function readCodexGoalSnapshotInput(raw: string | undefined, cwd?: string): Promise<CodexGoalSnapshot | null>;
|
|
25
|
+
export declare function reconcileCodexGoalSnapshot(snapshot: CodexGoalSnapshot | null | undefined, options: ReconcileCodexGoalOptions): CodexGoalReconciliation;
|
|
26
|
+
export declare function formatCodexGoalReconciliation(reconciliation: CodexGoalReconciliation): string;
|