oh-my-opencode 4.10.0 → 4.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/codex-qa/SKILL.md +96 -0
- package/.agents/skills/codex-qa/references/app-server.md +63 -0
- package/.agents/skills/codex-qa/references/components-hooks.md +38 -0
- package/.agents/skills/codex-qa/references/docker-qa.md +62 -0
- package/.agents/skills/codex-qa/references/install-verify.md +57 -0
- package/.agents/skills/codex-qa/references/isolation.md +57 -0
- package/.agents/skills/codex-qa/references/logging-debug.md +60 -0
- package/.agents/skills/codex-qa/scripts/app-server-drive.sh +76 -0
- package/.agents/skills/codex-qa/scripts/hook-unit-probe.sh +69 -0
- package/.agents/skills/codex-qa/scripts/install-verify.sh +60 -0
- package/.agents/skills/codex-qa/scripts/lib/app-server-client.mjs +117 -0
- package/.agents/skills/codex-qa/scripts/lib/common.sh +180 -0
- package/.agents/skills/codex-qa/scripts/lib/mock-model.mjs +56 -0
- package/.agents/skills/codex-qa/scripts/tui-smoke.sh +71 -0
- package/.agents/skills/opencode-qa/SKILL.md +8 -1
- package/.agents/skills/opencode-qa/references/docker-qa.md +72 -0
- package/.agents/skills/tech-debt-audit/SKILL.md +14 -14
- package/.agents/skills/work-with-pr/SKILL.md +77 -53
- package/.opencode/skills/work-with-pr/SKILL.md +79 -55
- package/README.ja.md +3 -3
- package/README.ko.md +3 -3
- package/README.md +2 -2
- package/README.ru.md +3 -3
- package/README.zh-cn.md +3 -3
- package/THIRD-PARTY-NOTICES.md +205 -0
- package/dist/agents/dynamic-agent-prompt-types.d.ts +1 -1
- package/dist/agents/index.d.ts +0 -1
- package/dist/agents/prometheus/index.d.ts +0 -1
- package/dist/agents/prometheus/system-prompt.d.ts +0 -2
- package/dist/cli/config-manager/add-tui-plugin-to-tui-config.d.ts +7 -0
- package/dist/cli/doctor/checks/codex-components.d.ts +4 -4
- package/dist/cli/doctor/checks/codex-runtime-wrapper.d.ts +7 -0
- package/dist/cli/doctor/checks/codex.d.ts +1 -1
- package/dist/cli/doctor/checks/config.d.ts +1 -1
- package/dist/cli/doctor/checks/dependencies.d.ts +1 -2
- package/dist/cli/doctor/checks/index.d.ts +1 -1
- package/dist/cli/doctor/checks/model-resolution.d.ts +1 -1
- package/dist/cli/doctor/checks/system.d.ts +1 -1
- package/dist/cli/doctor/checks/team-mode.d.ts +1 -1
- package/dist/cli/doctor/checks/tools-gh.d.ts +1 -1
- package/dist/cli/doctor/checks/tools-mcp.d.ts +1 -1
- package/dist/cli/doctor/checks/tools.d.ts +2 -1
- package/dist/cli/doctor/checks/tui-plugin-config.d.ts +7 -1
- package/dist/cli/doctor/framework/constants.d.ts +32 -0
- package/dist/cli/doctor/framework/spawn-with-timeout.d.ts +8 -0
- package/dist/cli/doctor/framework/types.d.ts +147 -0
- package/dist/cli/doctor/index.d.ts +4 -4
- package/dist/cli/doctor/runner.d.ts +1 -1
- package/dist/cli/index.js +9717 -7523
- package/dist/cli/install-ast-grep-sg.d.ts +10 -0
- package/dist/cli/install-codex/codex-cache-bins.d.ts +1 -21
- package/dist/cli/install-codex/codex-cache-bundled-mcps.d.ts +1 -5
- package/dist/cli/install-codex/codex-cache-command-shim.d.ts +1 -1
- package/dist/cli/install-codex/codex-cache-fs.d.ts +1 -3
- package/dist/cli/install-codex/codex-cache-install.d.ts +1 -13
- package/dist/cli/install-codex/codex-cache-legacy-bins.d.ts +1 -3
- package/dist/cli/install-codex/codex-cache-local-dependencies.d.ts +1 -1
- package/dist/cli/install-codex/codex-cache-mcp-manifest.d.ts +1 -2
- package/dist/cli/install-codex/codex-cache-paths.d.ts +1 -2
- package/dist/cli/install-codex/codex-cache-prune.d.ts +1 -10
- package/dist/cli/install-codex/codex-cache.d.ts +1 -4
- package/dist/cli/install-codex/codex-cached-marketplace-manifest.d.ts +1 -6
- package/dist/cli/install-codex/codex-cleanup-config.d.ts +1 -6
- package/dist/cli/install-codex/codex-cleanup.d.ts +1 -25
- package/dist/cli/install-codex/codex-config-agents.d.ts +1 -3
- package/dist/cli/install-codex/codex-config-features.d.ts +1 -1
- package/dist/cli/install-codex/codex-config-marketplaces.d.ts +1 -6
- package/dist/cli/install-codex/codex-config-permissions.d.ts +1 -1
- package/dist/cli/install-codex/codex-config-plugins.d.ts +1 -9
- package/dist/cli/install-codex/codex-config-reasoning.d.ts +1 -2
- package/dist/cli/install-codex/codex-config-toml-sections.d.ts +1 -9
- package/dist/cli/install-codex/codex-config-toml.d.ts +1 -13
- package/dist/cli/install-codex/codex-hook-trust.d.ts +1 -6
- package/dist/cli/install-codex/codex-installation-detection.d.ts +1 -36
- package/dist/cli/install-codex/codex-installer-bin-dir.d.ts +1 -8
- package/dist/cli/install-codex/codex-marketplace-snapshot.d.ts +1 -15
- package/dist/cli/install-codex/codex-marketplace.d.ts +1 -9
- package/dist/cli/install-codex/codex-model-catalog.d.ts +1 -13
- package/dist/cli/install-codex/codex-multi-agent-v2-config.d.ts +1 -12
- package/dist/cli/install-codex/codex-package-layout.d.ts +1 -1
- package/dist/cli/install-codex/codex-process.d.ts +1 -7
- package/dist/cli/install-codex/codex-project-local-cleanup-best-effort.d.ts +1 -7
- package/dist/cli/install-codex/codex-project-local-cleanup.d.ts +1 -35
- package/dist/cli/install-codex/git-bash.d.ts +1 -35
- package/dist/cli/install-codex/index.d.ts +1 -11
- package/dist/cli/install-codex/install-codex.d.ts +1 -10
- package/dist/cli/install-codex/lazycodex-version-stamp.d.ts +1 -19
- package/dist/cli/install-codex/link-cached-plugin-agents.d.ts +1 -20
- package/dist/cli/install-codex/lsp-daemon-reaper.d.ts +1 -5
- package/dist/cli/install-codex/toml-section-editor.d.ts +1 -11
- package/dist/cli/install-codex/types.d.ts +1 -76
- package/dist/cli/mcp-oauth/login.d.ts +1 -1
- package/dist/cli-node/index.js +9774 -7525
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schema/agent-names.d.ts +1 -1
- package/dist/config/schema/codegraph.d.ts +9 -0
- package/dist/config/schema/git-env-prefix.d.ts +1 -5
- package/dist/config/schema/hooks.d.ts +3 -0
- package/dist/config/schema/monitor.d.ts +15 -0
- package/dist/config/schema/oh-my-opencode-config.d.ts +27 -16
- package/dist/config/schema/openclaw.d.ts +5 -4
- package/dist/config/schema/team-mode.d.ts +1 -16
- package/dist/config/schema/tmux.d.ts +4 -5
- package/dist/config/schema/tui.d.ts +10 -0
- package/dist/config/schema.d.ts +2 -0
- package/dist/config/validate.d.ts +8 -0
- package/dist/create-hooks.d.ts +5 -0
- package/dist/create-managers.d.ts +7 -0
- package/dist/create-runtime-tmux-config.d.ts +1 -1
- package/dist/create-tools.d.ts +1 -1
- package/dist/features/background-agent/error-classifier.d.ts +2 -2
- package/dist/features/background-agent/manager.d.ts +29 -2
- package/dist/features/background-agent/parent-wake-dispatched-tracker.d.ts +8 -0
- package/dist/features/background-agent/parent-wake-notifier.d.ts +4 -0
- package/dist/features/background-agent/spawner/fallback-agent.d.ts +3 -2
- package/dist/features/background-agent/spawner/task-prompt-body.d.ts +5 -6
- package/dist/features/background-agent/task-snapshot.d.ts +2 -0
- package/dist/features/background-agent/types.d.ts +7 -0
- package/dist/features/builtin-commands/templates/refactor-sections/intro-and-analysis.d.ts +1 -1
- package/dist/features/builtin-commands/templates/refactor-sections/plan-and-execution.d.ts +1 -1
- package/dist/features/builtin-commands/templates/refactor-sections/team-mode-addendum.d.ts +1 -1
- package/dist/features/builtin-commands/templates/refactor-sections/verification-and-tooling.d.ts +1 -1
- package/dist/features/builtin-commands/templates/remove-ai-slops.d.ts +1 -1
- package/dist/features/builtin-skills/index.d.ts +1 -2
- package/dist/features/builtin-skills/skill-file-loader.d.ts +1 -4
- package/dist/features/builtin-skills/skills/agent-browser-skill.d.ts +1 -2
- package/dist/features/builtin-skills/skills/agent-browser-template.d.ts +1 -2
- package/dist/features/builtin-skills/skills/debugging.d.ts +1 -2
- package/dist/features/builtin-skills/skills/dev-browser.d.ts +1 -2
- package/dist/features/builtin-skills/skills/frontend.d.ts +1 -0
- package/dist/features/builtin-skills/skills/git-master-sections/commit-atomic-planning.d.ts +1 -1
- package/dist/features/builtin-skills/skills/git-master-sections/commit-context-analysis.d.ts +1 -1
- package/dist/features/builtin-skills/skills/git-master-sections/commit-execution-verification.d.ts +1 -1
- package/dist/features/builtin-skills/skills/git-master-sections/commit-workflow.d.ts +1 -1
- package/dist/features/builtin-skills/skills/git-master-sections/history-search-workflow.d.ts +1 -1
- package/dist/features/builtin-skills/skills/git-master-sections/overview.d.ts +1 -1
- package/dist/features/builtin-skills/skills/git-master-sections/quick-reference.d.ts +1 -1
- package/dist/features/builtin-skills/skills/git-master-sections/rebase-workflow.d.ts +1 -1
- package/dist/features/builtin-skills/skills/git-master-skill-metadata.d.ts +1 -2
- package/dist/features/builtin-skills/skills/git-master.d.ts +1 -2
- package/dist/features/builtin-skills/skills/index.d.ts +1 -13
- package/dist/features/builtin-skills/skills/init-deep.d.ts +1 -2
- package/dist/features/builtin-skills/skills/playwright-cli.d.ts +1 -10
- package/dist/features/builtin-skills/skills/playwright-mcp-skill.d.ts +1 -2
- package/dist/features/builtin-skills/skills/playwright.d.ts +1 -2
- package/dist/features/builtin-skills/skills/remove-ai-slops.d.ts +1 -2
- package/dist/features/builtin-skills/skills/review-work.d.ts +1 -2
- package/dist/features/builtin-skills/skills/security-research.d.ts +1 -2
- package/dist/features/builtin-skills/skills/security-review.d.ts +1 -2
- package/dist/features/builtin-skills/skills/team-mode.d.ts +1 -2
- package/dist/features/builtin-skills/skills/visual-qa.d.ts +1 -2
- package/dist/features/builtin-skills/skills.d.ts +1 -12
- package/dist/features/builtin-skills/types.d.ts +1 -15
- package/dist/features/claude-code-agent-loader/agent-definitions-loader.d.ts +1 -3
- package/dist/features/claude-code-agent-loader/claude-model-mapper.d.ts +1 -4
- package/dist/features/claude-code-agent-loader/index.d.ts +1 -5
- package/dist/features/claude-code-agent-loader/json-agent-loader.d.ts +1 -2
- package/dist/features/claude-code-agent-loader/loader.d.ts +1 -5
- package/dist/features/claude-code-agent-loader/opencode-config-agents-reader.d.ts +1 -2
- package/dist/features/claude-code-agent-loader/types.d.ts +1 -29
- package/dist/features/claude-code-command-loader/index.d.ts +1 -2
- package/dist/features/claude-code-command-loader/loader-cache.d.ts +1 -6
- package/dist/features/claude-code-command-loader/loader.d.ts +1 -8
- package/dist/features/claude-code-command-loader/types.d.ts +1 -42
- package/dist/features/claude-code-mcp-loader/configure-allowed-env-vars.d.ts +1 -5
- package/dist/features/claude-code-mcp-loader/index.d.ts +1 -11
- package/dist/features/claude-code-mcp-loader/loader.d.ts +1 -4
- package/dist/features/claude-code-mcp-loader/scope-filter.d.ts +1 -2
- package/dist/features/claude-code-mcp-loader/transformer.d.ts +1 -2
- package/dist/features/claude-code-mcp-loader/types.d.ts +1 -43
- package/dist/features/claude-code-plugin-loader/agent-loader.d.ts +1 -3
- package/dist/features/claude-code-plugin-loader/command-loader.d.ts +1 -3
- package/dist/features/claude-code-plugin-loader/discovery-core.d.ts +1 -2
- package/dist/features/claude-code-plugin-loader/discovery-paths.d.ts +1 -3
- package/dist/features/claude-code-plugin-loader/discovery.d.ts +1 -3
- package/dist/features/claude-code-plugin-loader/hook-loader.d.ts +1 -2
- package/dist/features/claude-code-plugin-loader/index.d.ts +1 -10
- package/dist/features/claude-code-plugin-loader/install-path-resolver.d.ts +1 -1
- package/dist/features/claude-code-plugin-loader/installed-plugin-database.d.ts +1 -3
- package/dist/features/claude-code-plugin-loader/loaded-plugin.d.ts +1 -2
- package/dist/features/claude-code-plugin-loader/loader.d.ts +1 -36
- package/dist/features/claude-code-plugin-loader/mcp-server-loader.d.ts +1 -3
- package/dist/features/claude-code-plugin-loader/plugin-key.d.ts +1 -1
- package/dist/features/claude-code-plugin-loader/plugin-manifest.d.ts +1 -4
- package/dist/features/claude-code-plugin-loader/plugin-path-resolver.d.ts +1 -2
- package/dist/features/claude-code-plugin-loader/plugin-settings.d.ts +1 -3
- package/dist/features/claude-code-plugin-loader/scope-filter.d.ts +1 -2
- package/dist/features/claude-code-plugin-loader/skill-loader.d.ts +1 -3
- package/dist/features/claude-code-plugin-loader/types.d.ts +1 -240
- package/dist/features/claude-tasks/types.d.ts +4 -4
- package/dist/features/hook-message-injector/sdk-message-lookup.d.ts +9 -2
- package/dist/features/mcp-oauth/callback-server.d.ts +1 -19
- package/dist/features/mcp-oauth/dcr.d.ts +1 -34
- package/dist/features/mcp-oauth/discovery.d.ts +1 -8
- package/dist/features/mcp-oauth/oauth-authorization-flow.d.ts +1 -26
- package/dist/features/mcp-oauth/provider.d.ts +1 -30
- package/dist/features/mcp-oauth/refresh-mutex.d.ts +1 -26
- package/dist/features/mcp-oauth/resource-indicator.d.ts +1 -0
- package/dist/features/mcp-oauth/schema.d.ts +1 -0
- package/dist/features/mcp-oauth/step-up.d.ts +1 -8
- package/dist/features/mcp-oauth/storage.d.ts +1 -17
- package/dist/features/monitor/batcher.d.ts +36 -0
- package/dist/features/monitor/envelope.d.ts +9 -0
- package/dist/features/monitor/filter.d.ts +10 -0
- package/dist/features/monitor/index.d.ts +2 -0
- package/dist/features/monitor/line-stream.d.ts +29 -0
- package/dist/features/monitor/manager-internals.d.ts +65 -0
- package/dist/features/monitor/manager.d.ts +35 -0
- package/dist/features/monitor/monitor-state-factory.d.ts +24 -0
- package/dist/features/monitor/output-injector-session-inspect.d.ts +9 -0
- package/dist/features/monitor/output-injector-types.d.ts +48 -0
- package/dist/features/monitor/output-injector.d.ts +21 -0
- package/dist/features/monitor/permission.d.ts +33 -0
- package/dist/features/monitor/pipeline.d.ts +26 -0
- package/dist/features/monitor/process.d.ts +21 -0
- package/dist/features/monitor/ring-buffer.d.ts +25 -0
- package/dist/features/monitor/types.d.ts +83 -0
- package/dist/features/opencode-runtime-skills/index.d.ts +1 -2
- package/dist/features/opencode-runtime-skills/runtime-skill-config.d.ts +1 -17
- package/dist/features/opencode-runtime-skills/skill-markdown.d.ts +1 -7
- package/dist/features/opencode-runtime-skills/source-server.d.ts +1 -24
- package/dist/features/opencode-skill-loader/allowed-tools-parser.d.ts +1 -1
- package/dist/features/opencode-skill-loader/config-source-discovery.d.ts +1 -7
- package/dist/features/opencode-skill-loader/git-master-template-injection.d.ts +1 -20
- package/dist/features/opencode-skill-loader/index.d.ts +1 -16
- package/dist/features/opencode-skill-loader/loaded-skill-from-path.d.ts +1 -9
- package/dist/features/opencode-skill-loader/loaded-skill-template-extractor.d.ts +1 -2
- package/dist/features/opencode-skill-loader/loader.d.ts +1 -21
- package/dist/features/opencode-skill-loader/merger/builtin-skill-converter.d.ts +1 -3
- package/dist/features/opencode-skill-loader/merger/config-skill-entry-loader.d.ts +1 -3
- package/dist/features/opencode-skill-loader/merger/scope-priority.d.ts +1 -2
- package/dist/features/opencode-skill-loader/merger/skill-definition-merger.d.ts +1 -3
- package/dist/features/opencode-skill-loader/merger/skills-config-normalizer.d.ts +1 -11
- package/dist/features/opencode-skill-loader/merger.d.ts +1 -7
- package/dist/features/opencode-skill-loader/opencode-config-skills-reader.d.ts +1 -5
- package/dist/features/opencode-skill-loader/skill-content.d.ts +1 -5
- package/dist/features/opencode-skill-loader/skill-deduplication.d.ts +1 -2
- package/dist/features/opencode-skill-loader/skill-definition-record.d.ts +1 -5
- package/dist/features/opencode-skill-loader/skill-directory-loader.d.ts +1 -8
- package/dist/features/opencode-skill-loader/skill-discovery.d.ts +1 -4
- package/dist/features/opencode-skill-loader/skill-mcp-config.d.ts +1 -3
- package/dist/features/opencode-skill-loader/skill-resolution-options.d.ts +1 -9
- package/dist/features/opencode-skill-loader/skill-template-resolver.d.ts +1 -11
- package/dist/features/opencode-skill-loader/types.d.ts +1 -34
- package/dist/features/skill-mcp-manager/cleanup.d.ts +1 -8
- package/dist/features/skill-mcp-manager/connection-type.d.ts +1 -7
- package/dist/features/skill-mcp-manager/connection.d.ts +1 -14
- package/dist/features/skill-mcp-manager/env-cleaner.d.ts +1 -2
- package/dist/features/skill-mcp-manager/error-redaction.d.ts +1 -10
- package/dist/features/skill-mcp-manager/http-client.d.ts +1 -19
- package/dist/features/skill-mcp-manager/index.d.ts +1 -2
- package/dist/features/skill-mcp-manager/manager.d.ts +1 -27
- package/dist/features/skill-mcp-manager/oauth-handler.d.ts +1 -17
- package/dist/features/skill-mcp-manager/stdio-client.d.ts +1 -16
- package/dist/features/skill-mcp-manager/types.d.ts +1 -79
- package/dist/features/team-mode/member-parser.d.ts +1 -16
- package/dist/features/team-mode/team-layout-tmux/close-team-member-pane.d.ts +1 -4
- package/dist/features/team-mode/team-layout-tmux/index.d.ts +1 -1
- package/dist/features/team-mode/team-layout-tmux/layout.d.ts +1 -37
- package/dist/features/team-mode/team-layout-tmux/rebalance-team-window.d.ts +1 -9
- package/dist/features/team-mode/team-layout-tmux/resolve-caller-tmux-session.d.ts +1 -9
- package/dist/features/team-mode/team-layout-tmux/sweep-stale-team-sessions.d.ts +1 -8
- package/dist/features/team-mode/team-mailbox/ack.d.ts +1 -2
- package/dist/features/team-mode/team-mailbox/inbox.d.ts +1 -3
- package/dist/features/team-mode/team-mailbox/index.d.ts +1 -7
- package/dist/features/team-mode/team-mailbox/pending-delivery-recovery.d.ts +1 -31
- package/dist/features/team-mode/team-mailbox/poll.d.ts +1 -10
- package/dist/features/team-mode/team-mailbox/reservation.d.ts +1 -11
- package/dist/features/team-mode/team-mailbox/send.d.ts +1 -30
- package/dist/features/team-mode/team-registry/index.d.ts +1 -3
- package/dist/features/team-mode/team-registry/loader.d.ts +1 -12
- package/dist/features/team-mode/team-registry/paths.d.ts +1 -28
- package/dist/features/team-mode/team-registry/team-spec-input-normalizer.d.ts +1 -6
- package/dist/features/team-mode/team-registry/validator.d.ts +1 -10
- package/dist/features/team-mode/team-runtime/shutdown-helpers.d.ts +1 -1
- package/dist/features/team-mode/team-state-store/active-resume.d.ts +1 -5
- package/dist/features/team-mode/team-state-store/creating-resume.d.ts +1 -4
- package/dist/features/team-mode/team-state-store/deleting-resume.d.ts +1 -4
- package/dist/features/team-mode/team-state-store/error-normalization.d.ts +1 -2
- package/dist/features/team-mode/team-state-store/index.d.ts +1 -1
- package/dist/features/team-mode/team-state-store/locks.d.ts +1 -15
- package/dist/features/team-mode/team-state-store/reservation-reconciliation.d.ts +1 -4
- package/dist/features/team-mode/team-state-store/resume-report.d.ts +1 -7
- package/dist/features/team-mode/team-state-store/resume.d.ts +1 -5
- package/dist/features/team-mode/team-state-store/runtime-cleanup.d.ts +1 -4
- package/dist/features/team-mode/team-state-store/session-liveness.d.ts +1 -9
- package/dist/features/team-mode/team-state-store/store.d.ts +1 -21
- package/dist/features/team-mode/team-state-store/worker-resume-status.d.ts +1 -9
- package/dist/features/team-mode/team-tasklist/claim.d.ts +1 -10
- package/dist/features/team-mode/team-tasklist/dependencies.d.ts +1 -2
- package/dist/features/team-mode/team-tasklist/get.d.ts +1 -3
- package/dist/features/team-mode/team-tasklist/index.d.ts +1 -6
- package/dist/features/team-mode/team-tasklist/list.d.ts +1 -8
- package/dist/features/team-mode/team-tasklist/store.d.ts +1 -3
- package/dist/features/team-mode/team-tasklist/test-support.d.ts +1 -9
- package/dist/features/team-mode/team-tasklist/update.d.ts +1 -9
- package/dist/features/team-mode/team-worktree/cleanup.d.ts +1 -3
- package/dist/features/team-mode/team-worktree/index.d.ts +1 -2
- package/dist/features/team-mode/team-worktree/manager.d.ts +1 -15
- package/dist/features/team-mode/tools/lifecycle-create-tool.d.ts +2 -2
- package/dist/features/team-mode/tools/lifecycle-inline-spec.d.ts +2 -2
- package/dist/features/team-mode/tools/lifecycle-participant.d.ts +2 -2
- package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +8 -8
- package/dist/features/team-mode/tools/messaging-live-delivery-recipient.d.ts +2 -2
- package/dist/features/team-mode/tools/messaging-live-delivery-reservation.d.ts +1 -1
- package/dist/features/team-mode/tools/messaging-live-delivery-state.d.ts +1 -1
- package/dist/features/team-mode/tools/messaging-live-delivery.d.ts +1 -1
- package/dist/features/team-mode/tools/messaging-runtime.d.ts +2 -2
- package/dist/features/team-mode/tools/query.d.ts +3 -3
- package/dist/features/team-mode/tools/tasks.d.ts +2 -2
- package/dist/features/team-mode/types.d.ts +1 -343
- package/dist/features/tui-sidebar/compute-view.d.ts +10 -0
- package/dist/features/tui-sidebar/config-validator.d.ts +2 -0
- package/dist/features/tui-sidebar/constants.d.ts +10 -0
- package/dist/features/tui-sidebar/derivers.d.ts +10 -0
- package/dist/features/tui-sidebar/element-helpers.d.ts +9 -0
- package/dist/features/tui-sidebar/loop-reader.d.ts +2 -0
- package/dist/features/tui-sidebar/mirror-io.d.ts +3 -0
- package/dist/features/tui-sidebar/mirror-manager.d.ts +28 -0
- package/dist/features/tui-sidebar/mirror-path.d.ts +3 -0
- package/dist/features/tui-sidebar/render-view.d.ts +15 -0
- package/dist/features/tui-sidebar/roster-resolver.d.ts +2 -0
- package/dist/features/tui-sidebar/snapshot-builder.d.ts +28 -0
- package/dist/features/tui-sidebar/snapshot-schema.d.ts +41 -0
- package/dist/features/tui-sidebar/state-types.d.ts +72 -0
- package/dist/hooks/ast-grep-sg-provision/hook.d.ts +19 -0
- package/dist/hooks/ast-grep-sg-provision/index.d.ts +1 -0
- package/dist/hooks/auto-slash-command/constants.d.ts +1 -5
- package/dist/hooks/auto-slash-command/detector.d.ts +1 -15
- package/dist/hooks/auto-slash-command/processed-command-store.d.ts +1 -7
- package/dist/hooks/auto-slash-command/types.d.ts +1 -48
- package/dist/hooks/auto-update-checker/constants.d.ts +3 -3
- package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +16 -0
- package/dist/hooks/codegraph-bootstrap/hook.d.ts +34 -0
- package/dist/hooks/codegraph-bootstrap/index.d.ts +1 -0
- package/dist/hooks/codegraph-bootstrap/project-root.d.ts +1 -0
- package/dist/hooks/codegraph-bootstrap/status.d.ts +11 -0
- package/dist/hooks/delegate-task-retry/guidance.d.ts +1 -2
- package/dist/hooks/delegate-task-retry/patterns.d.ts +2 -11
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/monitor-status-injector/hook.d.ts +30 -0
- package/dist/hooks/monitor-status-injector/index.d.ts +2 -0
- package/dist/hooks/runtime-fallback/auto-retry-signal.d.ts +1 -4
- package/dist/hooks/runtime-fallback/error-classifier.d.ts +7 -6
- package/dist/hooks/runtime-fallback/fallback-state.d.ts +3 -2
- package/dist/hooks/runtime-fallback/test-timeout-clock.test-support.d.ts +6 -0
- package/dist/hooks/tool-pair-validator/tool-part-ids.d.ts +2 -1
- package/dist/index.js +89513 -95172
- package/dist/interactive-bash-availability.d.ts +1 -0
- package/dist/mcp/codegraph.d.ts +16 -0
- package/dist/mcp/index.d.ts +10 -2
- package/dist/mcp/shared/ancestor-cli-resolver.d.ts +25 -0
- package/dist/mcp/types.d.ts +1 -1
- package/dist/oh-my-opencode.schema.json +139 -16
- package/dist/openclaw/config.d.ts +1 -8
- package/dist/openclaw/daemon.d.ts +1 -1
- package/dist/openclaw/dispatcher.d.ts +1 -12
- package/dist/openclaw/gateway-url-validation.d.ts +1 -1
- package/dist/openclaw/index.d.ts +1 -5
- package/dist/openclaw/reply-listener-discord.d.ts +1 -4
- package/dist/openclaw/reply-listener-injection.d.ts +1 -10
- package/dist/openclaw/reply-listener-log.d.ts +1 -2
- package/dist/openclaw/reply-listener-paths.d.ts +1 -7
- package/dist/openclaw/reply-listener-poll-loop.d.ts +1 -3
- package/dist/openclaw/reply-listener-process.d.ts +1 -4
- package/dist/openclaw/reply-listener-signature.d.ts +1 -2
- package/dist/openclaw/reply-listener-sleep.d.ts +1 -1
- package/dist/openclaw/reply-listener-spawn.d.ts +1 -5
- package/dist/openclaw/reply-listener-start.d.ts +1 -9
- package/dist/openclaw/reply-listener-startup.d.ts +1 -12
- package/dist/openclaw/reply-listener-state.d.ts +1 -29
- package/dist/openclaw/reply-listener-status.d.ts +1 -4
- package/dist/openclaw/reply-listener-stop.d.ts +1 -7
- package/dist/openclaw/reply-listener-telegram.d.ts +1 -4
- package/dist/openclaw/reply-listener.d.ts +1 -5
- package/dist/openclaw/runtime-dispatch.d.ts +1 -17
- package/dist/openclaw/session-registry-lock.d.ts +1 -2
- package/dist/openclaw/session-registry-paths.d.ts +1 -9
- package/dist/openclaw/session-registry-storage.d.ts +1 -4
- package/dist/openclaw/session-registry-types.d.ts +1 -11
- package/dist/openclaw/session-registry.d.ts +1 -8
- package/dist/openclaw/tmux.d.ts +1 -8
- package/dist/openclaw/types.d.ts +1 -42
- package/dist/plugin/event-error-utils.d.ts +2 -1
- package/dist/plugin/hooks/create-core-hooks.d.ts +5 -0
- package/dist/plugin/hooks/create-session-hooks.d.ts +3 -1
- package/dist/plugin/hooks/create-transform-hooks.d.ts +4 -1
- package/dist/plugin/messages-transform.d.ts +1 -0
- package/dist/plugin/skill-context.d.ts +2 -0
- package/dist/plugin/tool-registry-factories.d.ts +2 -1
- package/dist/plugin/tool-registry-gated-tools.d.ts +7 -0
- package/dist/plugin/tool-registry.d.ts +1 -1
- package/dist/plugin/types.d.ts +2 -9
- package/dist/plugin-handlers/prometheus-agent-config-builder.d.ts +1 -0
- package/dist/shared/archive-entry-validator.d.ts +1 -6
- package/dist/shared/bun-file-shim.d.ts +1 -8
- package/dist/shared/bun-spawn-shim.d.ts +1 -43
- package/dist/shared/bun-which-shim.d.ts +1 -1
- package/dist/shared/classify-path-environment.d.ts +1 -3
- package/dist/shared/command-executor/embedded-commands.d.ts +1 -7
- package/dist/shared/command-executor/execute-command.d.ts +1 -1
- package/dist/shared/command-executor/execute-hook-command.d.ts +1 -23
- package/dist/shared/command-executor/home-directory.d.ts +1 -1
- package/dist/shared/command-executor/resolve-commands-in-text.d.ts +1 -1
- package/dist/shared/command-executor/shell-path.d.ts +1 -2
- package/dist/shared/command-executor.d.ts +1 -4
- package/dist/shared/git-worktree/collect-git-diff-stats.d.ts +1 -2
- package/dist/shared/git-worktree/format-file-changes.d.ts +1 -2
- package/dist/shared/git-worktree/index.d.ts +1 -7
- package/dist/shared/git-worktree/parse-diff-numstat.d.ts +1 -2
- package/dist/shared/git-worktree/parse-status-porcelain-line.d.ts +1 -6
- package/dist/shared/git-worktree/parse-status-porcelain.d.ts +1 -2
- package/dist/shared/git-worktree/types.d.ts +1 -7
- package/dist/shared/internal-initiator-marker.d.ts +1 -46
- package/dist/shared/logger.d.ts +3 -11
- package/dist/shared/migration/agent-category.d.ts +1 -19
- package/dist/shared/migration/agent-names.d.ts +1 -6
- package/dist/shared/migration/config-migration.d.ts +1 -1
- package/dist/shared/migration/hook-names.d.ts +1 -6
- package/dist/shared/migration/migrations-sidecar.d.ts +1 -41
- package/dist/shared/migration/model-versions.d.ts +1 -22
- package/dist/shared/migration.d.ts +1 -5
- package/dist/shared/model-suggestion-retry.d.ts +39 -17
- package/dist/shared/plugin-identity.d.ts +8 -8
- package/dist/shared/posthog.d.ts +3 -0
- package/dist/shared/process-stream-reader.d.ts +1 -3
- package/dist/shared/prompt-async-gate/message-inspection-error.d.ts +1 -1
- package/dist/shared/prompt-async-gate/pending-tool-turn.d.ts +1 -11
- package/dist/shared/prompt-async-gate/prompt-message-state.d.ts +1 -9
- package/dist/shared/prompt-async-gate/queue.d.ts +1 -8
- package/dist/shared/prompt-async-gate/recent-dispatches.d.ts +1 -14
- package/dist/shared/prompt-async-gate/reservations.d.ts +1 -9
- package/dist/shared/prompt-async-gate/semantic-dedupe.d.ts +1 -7
- package/dist/shared/prompt-async-gate/session-idle-dispatch.d.ts +1 -16
- package/dist/shared/prompt-async-gate/timing.d.ts +1 -9
- package/dist/shared/prompt-async-gate/types.d.ts +1 -123
- package/dist/shared/prompt-async-gate.d.ts +3 -7
- package/dist/shared/prompt-failure-classifier.d.ts +1 -9
- package/dist/shared/session-idle-settle.d.ts +1 -12
- package/dist/shared/shell-env.d.ts +1 -1
- package/dist/shared/skill-path-resolver.d.ts +1 -1
- package/dist/shared/tmux/cmux-detect.d.ts +1 -8
- package/dist/shared/tmux/constants.d.ts +1 -5
- package/dist/shared/tmux/runner.d.ts +2 -13
- package/dist/shared/tmux/tmux-utils/adapter-deps.d.ts +9 -0
- package/dist/shared/tmux/tmux-utils/environment.d.ts +2 -4
- package/dist/shared/tmux/tmux-utils/layout.d.ts +4 -17
- package/dist/shared/tmux/tmux-utils/pane-close.d.ts +3 -10
- package/dist/shared/tmux/tmux-utils/pane-command.d.ts +1 -2
- package/dist/shared/tmux/tmux-utils/pane-dimensions.d.ts +2 -4
- package/dist/shared/tmux/tmux-utils/pane-replace.d.ts +1 -11
- package/dist/shared/tmux/tmux-utils/pane-spawn.d.ts +1 -13
- package/dist/shared/tmux/tmux-utils/server-health.d.ts +2 -15
- package/dist/shared/tmux/tmux-utils/session-spawn.d.ts +3 -14
- package/dist/shared/tmux/tmux-utils/spawn-process.d.ts +1 -1
- package/dist/shared/tmux/tmux-utils/stale-session-sweep.d.ts +4 -17
- package/dist/shared/tmux/tmux-utils/window-spawn.d.ts +1 -13
- package/dist/shared/tmux/types.d.ts +1 -4
- package/dist/shared/write-file-atomically.d.ts +2 -0
- package/dist/shared/zip-entry-listing/powershell-zip-entry-listing.d.ts +1 -4
- package/dist/shared/zip-entry-listing/python-zip-entry-listing.d.ts +1 -3
- package/dist/shared/zip-entry-listing/read-zip-symlink-target.d.ts +1 -1
- package/dist/shared/zip-entry-listing/tar-zip-entry-listing.d.ts +1 -3
- package/dist/shared/zip-entry-listing/zipinfo-zip-entry-listing.d.ts +1 -4
- package/dist/shared/zip-entry-listing.d.ts +1 -4
- package/dist/skills/ast-grep/LICENSE +21 -0
- package/dist/skills/ast-grep/README.md +136 -0
- package/dist/skills/ast-grep/SKILL.md +272 -0
- package/dist/skills/ast-grep/SOURCE +1 -0
- package/dist/skills/ast-grep/install.ps1 +235 -0
- package/dist/skills/ast-grep/install.sh +286 -0
- package/dist/skills/ast-grep/references/cli.md +231 -0
- package/dist/skills/ast-grep/references/install.md +166 -0
- package/dist/skills/ast-grep/references/patterns.md +147 -0
- package/dist/skills/ast-grep/references/pitfalls.md +303 -0
- package/dist/skills/ast-grep/references/recipes.md +402 -0
- package/dist/skills/ast-grep/references/sgconfig.md +248 -0
- package/dist/skills/ast-grep/references/yaml-rules.md +509 -0
- package/dist/skills/ast-grep/scripts/ast_grep_helper.py +748 -0
- package/dist/skills/ast-grep/tests/smoke.ps1 +123 -0
- package/dist/skills/ast-grep/tests/smoke.sh +212 -0
- package/dist/skills/debugging/SKILL.md +116 -0
- package/dist/skills/debugging/references/methodology/00-setup.md +108 -0
- package/dist/skills/debugging/references/methodology/02-investigate.md +130 -0
- package/dist/skills/debugging/references/methodology/04-oracle-triple.md +136 -0
- package/dist/skills/debugging/references/methodology/05-escalate.md +69 -0
- package/dist/skills/debugging/references/methodology/06-fix.md +116 -0
- package/dist/skills/debugging/references/methodology/08-qa.md +94 -0
- package/dist/skills/debugging/references/methodology/09-cleanup.md +164 -0
- package/dist/skills/debugging/references/methodology/partial-runtime-evidence.md +229 -0
- package/dist/skills/debugging/references/runtimes/bundled-js-binary.md +415 -0
- package/dist/skills/debugging/references/runtimes/go.md +252 -0
- package/dist/skills/debugging/references/runtimes/native-binary.md +484 -0
- package/dist/skills/debugging/references/runtimes/node.md +260 -0
- package/dist/skills/debugging/references/runtimes/python.md +248 -0
- package/dist/skills/debugging/references/runtimes/rust.md +234 -0
- package/dist/skills/debugging/references/tools/ghidra.md +212 -0
- package/dist/skills/debugging/references/tools/playwright-cli.md +194 -0
- package/dist/skills/debugging/references/tools/pwndbg.md +263 -0
- package/dist/skills/debugging/references/tools/pwntools.md +265 -0
- package/dist/skills/frontend/ATTRIBUTION.md +127 -0
- package/dist/skills/frontend/LICENSE-Apache-2.0.txt +201 -0
- package/dist/skills/frontend/SKILL.md +113 -0
- package/dist/skills/frontend/references/design/README.md +240 -0
- package/dist/skills/frontend/references/design/_INDEX.md +189 -0
- package/dist/skills/frontend/references/design/airbnb.md +390 -0
- package/dist/skills/frontend/references/design/airtable.md +89 -0
- package/dist/skills/frontend/references/design/apple.md +247 -0
- package/dist/skills/frontend/references/design/binance.md +345 -0
- package/dist/skills/frontend/references/design/bmw.md +180 -0
- package/dist/skills/frontend/references/design/brutalist-skill.md +92 -0
- package/dist/skills/frontend/references/design/bugatti.md +268 -0
- package/dist/skills/frontend/references/design/cal.md +259 -0
- package/dist/skills/frontend/references/design/claude.md +312 -0
- package/dist/skills/frontend/references/design/clay.md +304 -0
- package/dist/skills/frontend/references/design/clickhouse.md +281 -0
- package/dist/skills/frontend/references/design/cohere.md +266 -0
- package/dist/skills/frontend/references/design/coinbase.md +129 -0
- package/dist/skills/frontend/references/design/composio.md +307 -0
- package/dist/skills/frontend/references/design/cursor.md +309 -0
- package/dist/skills/frontend/references/design/design-system-architecture.md +217 -0
- package/dist/skills/frontend/references/design/elevenlabs.md +265 -0
- package/dist/skills/frontend/references/design/expo.md +281 -0
- package/dist/skills/frontend/references/design/ferrari.md +314 -0
- package/dist/skills/frontend/references/design/figma.md +220 -0
- package/dist/skills/frontend/references/design/framer.md +246 -0
- package/dist/skills/frontend/references/design/gpt-tasteskill.md +74 -0
- package/dist/skills/frontend/references/design/hashicorp.md +278 -0
- package/dist/skills/frontend/references/design/ibm.md +332 -0
- package/dist/skills/frontend/references/design/image-to-code-skill.md +1228 -0
- package/dist/skills/frontend/references/design/imagegen-brandkit.md +798 -0
- package/dist/skills/frontend/references/design/imagegen-frontend-mobile.md +1465 -0
- package/dist/skills/frontend/references/design/imagegen-frontend-web.md +686 -0
- package/dist/skills/frontend/references/design/intercom.md +146 -0
- package/dist/skills/frontend/references/design/kraken.md +125 -0
- package/dist/skills/frontend/references/design/lamborghini.md +288 -0
- package/dist/skills/frontend/references/design/linear.app.md +367 -0
- package/dist/skills/frontend/references/design/lovable.md +298 -0
- package/dist/skills/frontend/references/design/mastercard.md +365 -0
- package/dist/skills/frontend/references/design/meta.md +366 -0
- package/dist/skills/frontend/references/design/minimalist-skill.md +85 -0
- package/dist/skills/frontend/references/design/minimax.md +257 -0
- package/dist/skills/frontend/references/design/mintlify.md +326 -0
- package/dist/skills/frontend/references/design/miro.md +108 -0
- package/dist/skills/frontend/references/design/mistral.ai.md +261 -0
- package/dist/skills/frontend/references/design/mongodb.md +266 -0
- package/dist/skills/frontend/references/design/nike.md +363 -0
- package/dist/skills/frontend/references/design/notion.md +309 -0
- package/dist/skills/frontend/references/design/nvidia.md +293 -0
- package/dist/skills/frontend/references/design/ollama.md +267 -0
- package/dist/skills/frontend/references/design/opencode.ai.md +281 -0
- package/dist/skills/frontend/references/design/output-skill.md +49 -0
- package/dist/skills/frontend/references/design/pinterest.md +230 -0
- package/dist/skills/frontend/references/design/playstation.md +364 -0
- package/dist/skills/frontend/references/design/posthog.md +256 -0
- package/dist/skills/frontend/references/design/raycast.md +268 -0
- package/dist/skills/frontend/references/design/react-dev-tooling-skill.md +230 -0
- package/dist/skills/frontend/references/design/redesign-skill.md +178 -0
- package/dist/skills/frontend/references/design/renault.md +311 -0
- package/dist/skills/frontend/references/design/replicate.md +261 -0
- package/dist/skills/frontend/references/design/resend.md +303 -0
- package/dist/skills/frontend/references/design/revolut.md +185 -0
- package/dist/skills/frontend/references/design/runwayml.md +244 -0
- package/dist/skills/frontend/references/design/sanity.md +357 -0
- package/dist/skills/frontend/references/design/sentry.md +262 -0
- package/dist/skills/frontend/references/design/shopify.md +350 -0
- package/dist/skills/frontend/references/design/soft-skill.md +98 -0
- package/dist/skills/frontend/references/design/spacex.md +194 -0
- package/dist/skills/frontend/references/design/spotify.md +246 -0
- package/dist/skills/frontend/references/design/starbucks.md +580 -0
- package/dist/skills/frontend/references/design/stitch-skill.md +184 -0
- package/dist/skills/frontend/references/design/stripe.md +322 -0
- package/dist/skills/frontend/references/design/supabase.md +255 -0
- package/dist/skills/frontend/references/design/superhuman.md +252 -0
- package/dist/skills/frontend/references/design/taste-skill.md +226 -0
- package/dist/skills/frontend/references/design/tesla.md +286 -0
- package/dist/skills/frontend/references/design/theverge.md +339 -0
- package/dist/skills/frontend/references/design/together.ai.md +263 -0
- package/dist/skills/frontend/references/design/uber.md +295 -0
- package/dist/skills/frontend/references/design/vercel.md +310 -0
- package/dist/skills/frontend/references/design/vodafone.md +423 -0
- package/dist/skills/frontend/references/design/voltagent.md +323 -0
- package/dist/skills/frontend/references/design/warp.md +253 -0
- package/dist/skills/frontend/references/design/webflow.md +92 -0
- package/dist/skills/frontend/references/design/wired.md +278 -0
- package/dist/skills/frontend/references/design/wise.md +173 -0
- package/dist/skills/frontend/references/design/x.ai.md +257 -0
- package/dist/skills/frontend/references/design/zapier.md +328 -0
- package/dist/skills/frontend/references/perfection/README.md +160 -0
- package/dist/skills/frontend/references/perfection/react-perf-tooling.md +127 -0
- package/dist/skills/frontend/references/ui-ux-db/README.md +273 -0
- package/dist/skills/frontend/references/ui-ux-db/data/charts.csv +26 -0
- package/dist/skills/frontend/references/ui-ux-db/data/colors.csv +97 -0
- package/dist/skills/frontend/references/ui-ux-db/data/icons.csv +101 -0
- package/dist/skills/frontend/references/ui-ux-db/data/landing.csv +31 -0
- package/dist/skills/frontend/references/ui-ux-db/data/products.csv +97 -0
- package/dist/skills/frontend/references/ui-ux-db/data/react-performance.csv +45 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/astro.csv +54 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/flutter.csv +53 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/jetpack-compose.csv +53 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/nextjs.csv +53 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/nuxt-ui.csv +51 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/nuxtjs.csv +59 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/react-native.csv +52 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/react.csv +54 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/shadcn.csv +61 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/svelte.csv +54 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/swiftui.csv +51 -0
- package/dist/skills/frontend/references/ui-ux-db/data/stacks/vue.csv +50 -0
- package/dist/skills/frontend/references/ui-ux-db/data/styles.csv +68 -0
- package/dist/skills/frontend/references/ui-ux-db/data/typography.csv +58 -0
- package/dist/skills/frontend/references/ui-ux-db/data/ui-reasoning.csv +101 -0
- package/dist/skills/frontend/references/ui-ux-db/data/ux-guidelines.csv +100 -0
- package/dist/skills/frontend/references/ui-ux-db/data/web-interface.csv +31 -0
- package/dist/skills/frontend/references/ui-ux-db/scripts/core.py +253 -0
- package/dist/skills/frontend/references/ui-ux-db/scripts/design_system.py +1067 -0
- package/dist/skills/frontend/references/ui-ux-db/scripts/search.py +114 -0
- package/dist/skills/frontend/scripts/perfection/lighthouse-audit.py +201 -0
- package/dist/skills/git-master/SKILL.md +100 -0
- package/dist/skills/git-master/agents/openai.yaml +13 -0
- package/dist/skills/init-deep/SKILL.md +309 -0
- package/dist/skills/lcx-contribute-bug-fix/SKILL.md +242 -0
- package/dist/skills/lcx-contribute-bug-fix/agents/openai.yaml +12 -0
- package/dist/skills/lcx-contribute-bug-fix/scripts/create-pr-body.mjs +107 -0
- package/dist/skills/lcx-doctor/SKILL.md +93 -0
- package/dist/skills/lcx-doctor/agents/openai.yaml +11 -0
- package/dist/skills/lcx-report-bug/SKILL.md +237 -0
- package/dist/skills/lcx-report-bug/agents/openai.yaml +11 -0
- package/dist/skills/lsp-setup/SKILL.md +139 -0
- package/dist/skills/lsp-setup/references/bash/README.md +60 -0
- package/dist/skills/lsp-setup/references/c-cpp/README.md +61 -0
- package/dist/skills/lsp-setup/references/csharp/README.md +71 -0
- package/dist/skills/lsp-setup/references/dart/README.md +48 -0
- package/dist/skills/lsp-setup/references/elixir/README.md +51 -0
- package/dist/skills/lsp-setup/references/go/README.md +57 -0
- package/dist/skills/lsp-setup/references/haskell/README.md +57 -0
- package/dist/skills/lsp-setup/references/java/README.md +57 -0
- package/dist/skills/lsp-setup/references/julia/README.md +60 -0
- package/dist/skills/lsp-setup/references/kotlin/README.md +59 -0
- package/dist/skills/lsp-setup/references/lua/README.md +66 -0
- package/dist/skills/lsp-setup/references/php/README.md +62 -0
- package/dist/skills/lsp-setup/references/python/README.md +71 -0
- package/dist/skills/lsp-setup/references/ruby/README.md +53 -0
- package/dist/skills/lsp-setup/references/rust/README.md +59 -0
- package/dist/skills/lsp-setup/references/swift/README.md +51 -0
- package/dist/skills/lsp-setup/references/terraform/README.md +62 -0
- package/dist/skills/lsp-setup/references/typescript/README.md +77 -0
- package/dist/skills/lsp-setup/references/yaml/README.md +70 -0
- package/dist/skills/lsp-setup/references/zig/README.md +49 -0
- package/dist/skills/lsp-setup/scripts/detect-lsp.ts +210 -0
- package/dist/skills/lsp-setup/scripts/lsp-server-table.ts +177 -0
- package/dist/skills/lsp-setup/scripts/tsconfig.json +17 -0
- package/dist/skills/lsp-setup/scripts/verify-lsp.ts +147 -0
- package/dist/skills/programming/SKILL.md +463 -0
- package/dist/skills/programming/references/go/README.md +90 -0
- package/dist/skills/programming/references/go/backend-stack.md +641 -0
- package/dist/skills/programming/references/go/bootstrap.md +328 -0
- package/dist/skills/programming/references/go/bubbletea-v2.md +360 -0
- package/dist/skills/programming/references/go/cobra-stack.md +468 -0
- package/dist/skills/programming/references/go/concurrency.md +362 -0
- package/dist/skills/programming/references/go/data-modeling.md +329 -0
- package/dist/skills/programming/references/go/error-handling.md +359 -0
- package/dist/skills/programming/references/go/golangci-strict.md +236 -0
- package/dist/skills/programming/references/go/grpc-connect.md +375 -0
- package/dist/skills/programming/references/go/libraries.md +337 -0
- package/dist/skills/programming/references/go/one-liners.md +202 -0
- package/dist/skills/programming/references/go/sqlc-pgx.md +471 -0
- package/dist/skills/programming/references/go/testing.md +467 -0
- package/dist/skills/programming/references/go/type-patterns.md +298 -0
- package/dist/skills/programming/references/python/README.md +314 -0
- package/dist/skills/programming/references/python/async-anyio.md +442 -0
- package/dist/skills/programming/references/python/data-modeling.md +233 -0
- package/dist/skills/programming/references/python/data-processing.md +133 -0
- package/dist/skills/programming/references/python/error-handling.md +218 -0
- package/dist/skills/programming/references/python/fastapi-stack.md +316 -0
- package/dist/skills/programming/references/python/httpx2-optimization.md +360 -0
- package/dist/skills/programming/references/python/libraries.md +307 -0
- package/dist/skills/programming/references/python/one-liners.md +268 -0
- package/dist/skills/programming/references/python/orjson-stack.md +378 -0
- package/dist/skills/programming/references/python/pydantic-ai.md +285 -0
- package/dist/skills/programming/references/python/pyproject-strict.md +232 -0
- package/dist/skills/programming/references/python/textual-tui.md +201 -0
- package/dist/skills/programming/references/python/type-patterns.md +176 -0
- package/dist/skills/programming/references/rust/README.md +317 -0
- package/dist/skills/programming/references/rust/async-tokio.md +299 -0
- package/dist/skills/programming/references/rust/axum-stack.md +467 -0
- package/dist/skills/programming/references/rust/cargo-strict.md +317 -0
- package/dist/skills/programming/references/rust/clap-stack.md +409 -0
- package/dist/skills/programming/references/rust/concurrency.md +375 -0
- package/dist/skills/programming/references/rust/libraries.md +439 -0
- package/dist/skills/programming/references/rust/one-liners.md +291 -0
- package/dist/skills/programming/references/rust/proptest-insta.md +429 -0
- package/dist/skills/programming/references/rust/type-state.md +354 -0
- package/dist/skills/programming/references/rust/unsafe-discipline.md +250 -0
- package/dist/skills/programming/references/rust/zero-cost-safety.md +527 -0
- package/dist/skills/programming/references/rust-ub/README.md +289 -0
- package/dist/skills/programming/references/rust-ub/miri-sanitizers-loom.md +411 -0
- package/dist/skills/programming/references/rust-ub/ub-taxonomy.md +269 -0
- package/dist/skills/programming/references/typescript/README.md +195 -0
- package/dist/skills/programming/references/typescript/backend-hono.md +672 -0
- package/dist/skills/programming/references/typescript/bootstrap.md +199 -0
- package/dist/skills/programming/references/typescript/data-modeling.md +202 -0
- package/dist/skills/programming/references/typescript/error-handling.md +169 -0
- package/dist/skills/programming/references/typescript/tsconfig-strict.md +152 -0
- package/dist/skills/programming/references/typescript/type-patterns.md +196 -0
- package/dist/skills/programming/scripts/go/check-no-excuse-rules.sh +173 -0
- package/dist/skills/programming/scripts/go/new-project.py +138 -0
- package/dist/skills/programming/scripts/go/templates/.editorconfig +13 -0
- package/dist/skills/programming/scripts/go/templates/.golangci.yml +95 -0
- package/dist/skills/programming/scripts/go/templates/AGENTS.md.tmpl +24 -0
- package/dist/skills/programming/scripts/go/templates/README.md.tmpl +12 -0
- package/dist/skills/programming/scripts/go/templates/Taskfile.yml +40 -0
- package/dist/skills/programming/scripts/go/templates/ci.yml +37 -0
- package/dist/skills/programming/scripts/go/templates/config.go +24 -0
- package/dist/skills/programming/scripts/go/templates/gitignore +15 -0
- package/dist/skills/programming/scripts/go/templates/main.go.tmpl +22 -0
- package/dist/skills/programming/scripts/go/templates/run.go +15 -0
- package/dist/skills/programming/scripts/python/check-no-excuse-rules.py +687 -0
- package/dist/skills/programming/scripts/python/new-project.py +172 -0
- package/dist/skills/programming/scripts/python/new-script.py +116 -0
- package/dist/skills/programming/scripts/rust/check-no-excuse-rules.py +296 -0
- package/dist/skills/programming/scripts/rust/check-no-excuse-rules.sh +158 -0
- package/dist/skills/programming/scripts/rust/new-project.py +175 -0
- package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.ts +282 -0
- package/dist/skills/programming/scripts/typescript/new-project.ts +177 -0
- package/dist/skills/refactor/SKILL.md +754 -0
- package/dist/skills/remove-ai-slops/SKILL.md +317 -0
- package/dist/skills/review-work/SKILL.md +594 -0
- package/dist/skills/start-work/SKILL.md +178 -0
- package/dist/skills/ultraresearch/SKILL.md +230 -0
- package/dist/skills/ulw-plan/SKILL.md +69 -0
- package/dist/skills/ulw-plan/agents/openai.yaml +7 -0
- package/dist/skills/ulw-plan/references/full-workflow.md +99 -0
- package/dist/skills/ulw-plan/references/intent-clear.md +44 -0
- package/dist/skills/ulw-plan/references/intent-unclear.md +44 -0
- package/dist/skills/ulw-plan/scripts/scaffold-plan.mjs +301 -0
- package/dist/skills/visual-qa/SKILL.md +235 -0
- package/dist/skills/visual-qa/references/agent-browser-setup.md +44 -0
- package/dist/skills/visual-qa/scripts/ansi.test.ts +45 -0
- package/dist/skills/visual-qa/scripts/ansi.ts +17 -0
- package/dist/skills/visual-qa/scripts/cli.test.ts +73 -0
- package/dist/skills/visual-qa/scripts/cli.ts +82 -0
- package/dist/skills/visual-qa/scripts/east-asian-width.test.ts +60 -0
- package/dist/skills/visual-qa/scripts/east-asian-width.ts +72 -0
- package/dist/skills/visual-qa/scripts/image-diff.test.ts +70 -0
- package/dist/skills/visual-qa/scripts/image-diff.ts +109 -0
- package/dist/skills/visual-qa/scripts/png-crc.ts +27 -0
- package/dist/skills/visual-qa/scripts/png-decode.test.ts +44 -0
- package/dist/skills/visual-qa/scripts/png-decode.ts +206 -0
- package/dist/skills/visual-qa/scripts/png-synth.ts +57 -0
- package/dist/skills/visual-qa/scripts/skill-prompt-contract.test.ts +127 -0
- package/dist/skills/visual-qa/scripts/tui-grid.test.ts +57 -0
- package/dist/skills/visual-qa/scripts/tui-grid.ts +88 -0
- package/dist/skills/visual-qa/scripts/types.ts +54 -0
- package/dist/tools/delegate-task/background-task-description.d.ts +2 -0
- package/dist/tools/delegate-task/constants.d.ts +13 -1
- package/dist/tools/delegate-task/model-selection.d.ts +3 -17
- package/dist/tools/delegate-task/model-string-parser.d.ts +1 -9
- package/dist/tools/delegate-task/sync-result-fetcher.d.ts +1 -0
- package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -0
- package/dist/tools/delegate-task/types.d.ts +59 -2
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/monitor/create-monitor-tools.d.ts +4 -0
- package/dist/tools/monitor/index.d.ts +1 -0
- package/dist/tools/monitor/monitor-list.d.ts +7 -0
- package/dist/tools/monitor/monitor-output.d.ts +3 -0
- package/dist/tools/monitor/monitor-start.d.ts +9 -0
- package/dist/tools/monitor/monitor-stop.d.ts +16 -0
- package/dist/tools/skill/native-skills.d.ts +2 -2
- package/dist/tools/skill/scope-priority.d.ts +1 -4
- package/dist/tools/skill/skill-matcher.d.ts +1 -5
- package/dist/tools/task/types.d.ts +10 -10
- package/dist/tui.d.ts +4 -0
- package/dist/tui.js +69330 -0
- package/package.json +57 -36
- package/packages/git-bash-mcp/dist/cli.js +225 -55
- package/packages/lsp-core/package.json +41 -0
- package/packages/lsp-core/src/index.ts +28 -0
- package/packages/lsp-core/src/lsp/cleanup-errors.ts +5 -0
- package/packages/lsp-core/src/lsp/client-wrapper.ts +173 -0
- package/packages/lsp-core/src/lsp/client.ts +172 -0
- package/packages/lsp-core/src/lsp/config-loader.ts +266 -0
- package/packages/lsp-core/src/lsp/connection.ts +73 -0
- package/packages/lsp-core/src/lsp/constants.ts +11 -0
- package/packages/lsp-core/src/lsp/directory-diagnostics.ts +154 -0
- package/packages/lsp-core/src/lsp/effective-extension.ts +10 -0
- package/packages/lsp-core/src/lsp/errors.ts +63 -0
- package/packages/lsp-core/src/lsp/formatters.ts +141 -0
- package/packages/lsp-core/src/lsp/infer-extension.ts +66 -0
- package/packages/lsp-core/src/lsp/json-rpc-connection.ts +296 -0
- package/packages/lsp-core/src/lsp/language-mappings.ts +173 -0
- package/packages/lsp-core/src/lsp/manager.ts +369 -0
- package/packages/lsp-core/src/lsp/process-signal-cleanup.ts +21 -0
- package/packages/lsp-core/src/lsp/process.ts +202 -0
- package/packages/lsp-core/src/lsp/server-definitions.ts +176 -0
- package/packages/lsp-core/src/lsp/server-install-state.ts +70 -0
- package/packages/lsp-core/src/lsp/server-installation.ts +45 -0
- package/packages/lsp-core/src/lsp/server-resolution.ts +104 -0
- package/packages/lsp-core/src/lsp/startup-failure.ts +1 -0
- package/packages/lsp-core/src/lsp/transport.ts +299 -0
- package/packages/lsp-core/src/lsp/types.ts +126 -0
- package/packages/lsp-core/src/lsp/utils.test.ts +72 -0
- package/packages/lsp-core/src/lsp/utils.ts +40 -0
- package/packages/lsp-core/src/lsp/workspace-edit.ts +206 -0
- package/packages/lsp-core/src/mcp-protocol-pin.test.ts +68 -0
- package/packages/lsp-core/src/mcp.ts +95 -0
- package/packages/lsp-core/src/missing-dependency-result.ts +19 -0
- package/packages/lsp-core/src/request-context.ts +22 -0
- package/packages/lsp-core/src/tool-surface.test.ts +157 -0
- package/packages/lsp-core/src/tools/definitions.ts +141 -0
- package/packages/lsp-core/src/tools/diagnostics.ts +97 -0
- package/packages/lsp-core/src/tools/index.ts +10 -0
- package/packages/lsp-core/src/tools/install-decision.ts +39 -0
- package/packages/lsp-core/src/tools/navigation.ts +86 -0
- package/packages/lsp-core/src/tools/parameters.ts +49 -0
- package/packages/lsp-core/src/tools/rename.ts +72 -0
- package/packages/lsp-core/src/tools/result.ts +5 -0
- package/packages/lsp-core/src/tools/runtime.ts +21 -0
- package/packages/lsp-core/src/tools/schema.ts +9 -0
- package/packages/lsp-core/src/tools/status.ts +28 -0
- package/packages/lsp-core/src/tools/symbols.ts +99 -0
- package/packages/lsp-core/src/tools/types.ts +104 -0
- package/packages/lsp-core/src/tools.ts +1 -0
- package/packages/lsp-daemon/dist/cli.js +712 -527
- package/packages/lsp-daemon/dist/daemon-client.d.ts +1 -1
- package/packages/lsp-daemon/dist/daemon-server.js +1 -1
- package/packages/lsp-daemon/dist/index.d.ts +1 -1
- package/packages/lsp-daemon/dist/index.js +687 -500
- package/packages/lsp-daemon/dist/proxy.d.ts +3 -2
- package/packages/lsp-daemon/dist/proxy.js +16 -40
- package/packages/lsp-daemon/dist/request-routing.d.ts +2 -2
- package/packages/lsp-daemon/dist/request-routing.js +2 -2
- package/packages/lsp-daemon/package.json +2 -1
- package/packages/lsp-tools-mcp/dist/cli.js +3348 -15
- package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.d.ts +1 -1
- package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.d.ts +1 -13
- package/packages/lsp-tools-mcp/dist/lsp/client.d.ts +1 -20
- package/packages/lsp-tools-mcp/dist/lsp/config-loader.d.ts +1 -16
- package/packages/lsp-tools-mcp/dist/lsp/connection.d.ts +1 -4
- package/packages/lsp-tools-mcp/dist/lsp/constants.d.ts +1 -10
- package/packages/lsp-tools-mcp/dist/lsp/directory-diagnostics.d.ts +1 -3
- package/packages/lsp-tools-mcp/dist/lsp/effective-extension.d.ts +1 -1
- package/packages/lsp-tools-mcp/dist/lsp/errors.d.ts +1 -35
- package/packages/lsp-tools-mcp/dist/lsp/formatters.d.ts +1 -12
- package/packages/lsp-tools-mcp/dist/lsp/infer-extension.d.ts +1 -1
- package/packages/lsp-tools-mcp/dist/lsp/json-rpc-connection.d.ts +1 -36
- package/packages/lsp-tools-mcp/dist/lsp/language-mappings.d.ts +1 -4
- package/packages/lsp-tools-mcp/dist/lsp/manager.d.ts +1 -46
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +1390 -265
- package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.d.ts +1 -1
- package/packages/lsp-tools-mcp/dist/lsp/process.d.ts +1 -25
- package/packages/lsp-tools-mcp/dist/lsp/server-definitions.d.ts +1 -4
- package/packages/lsp-tools-mcp/dist/lsp/server-install-state.d.ts +1 -12
- package/packages/lsp-tools-mcp/dist/lsp/server-installation.d.ts +1 -1
- package/packages/lsp-tools-mcp/dist/lsp/server-resolution.d.ts +1 -11
- package/packages/lsp-tools-mcp/dist/lsp/startup-failure.d.ts +1 -3
- package/packages/lsp-tools-mcp/dist/lsp/transport.d.ts +1 -35
- package/packages/lsp-tools-mcp/dist/lsp/types.d.ts +1 -124
- package/packages/lsp-tools-mcp/dist/lsp/utils.d.ts +1 -0
- package/packages/lsp-tools-mcp/dist/lsp/workspace-edit.d.ts +1 -11
- package/packages/lsp-tools-mcp/dist/mcp.d.ts +1 -30
- package/packages/lsp-tools-mcp/dist/mcp.js +3312 -70
- package/packages/lsp-tools-mcp/dist/missing-dependency-result.d.ts +1 -2
- package/packages/lsp-tools-mcp/dist/request-context.d.ts +1 -7
- package/packages/lsp-tools-mcp/dist/request-context.js +16 -10
- package/packages/lsp-tools-mcp/dist/tools.d.ts +1 -90
- package/packages/lsp-tools-mcp/dist/tools.js +3028 -439
- package/packages/lsp-tools-mcp/package.json +3 -1
- package/packages/omo-codex/THIRD-PARTY-NOTICES.md +155 -0
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/.mcp.json +6 -5
- package/packages/omo-codex/plugin/README.md +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +1637 -1245
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/scripts/generate-manifests.mjs +8 -52
- package/packages/omo-codex/plugin/components/bootstrap/src/provision.ts +35 -143
- package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +11 -11
- package/packages/omo-codex/plugin/components/bootstrap/test/environment.test.ts +3 -2
- package/packages/omo-codex/plugin/components/bootstrap/test/provision.test.ts +37 -37
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +2205 -0
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.d.ts +32 -0
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +1603 -0
- package/packages/omo-codex/plugin/components/codegraph/package.json +27 -0
- package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +55 -0
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +83 -0
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +108 -0
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +191 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +213 -0
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +563 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +401 -0
- package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +13 -0
- package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +25 -0
- package/packages/omo-codex/plugin/components/comment-checker/dist/cli.js +610 -7
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +4 -3
- package/packages/omo-codex/plugin/components/comment-checker/src/apply-patch.ts +28 -156
- package/packages/omo-codex/plugin/components/comment-checker/src/core-values.ts +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/src/core.ts +2 -2
- package/packages/omo-codex/plugin/components/comment-checker/src/request-extractor.ts +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/src/runner.ts +6 -2
- package/packages/omo-codex/plugin/components/comment-checker/test/core.test.ts +38 -35
- package/packages/omo-codex/plugin/components/comment-checker/test/fixtures/apply-patch-mixed-requests.ts +60 -0
- package/packages/omo-codex/plugin/components/git-bash/dist/cli.js +155 -26
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +2 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/biome.json +48 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/directive.md +11 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/cli.js +223 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.d.ts +2 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/codex-hook.js +123 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/directive.d.ts +2 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/directive.js +5 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/index.d.ts +4 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/index.js +3 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/state.d.ts +9 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/state.js +45 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/types.d.ts +39 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/dist/types.js +1 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +17 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +44 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/cli.ts +56 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/codex-hook.ts +129 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/directive.ts +13 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/index.ts +4 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/state.ts +62 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/src/types.ts +38 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/cli.test.ts +124 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/test/codex-hook.test.ts +346 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/tsconfig.build.json +12 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/tsconfig.json +27 -0
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/vitest.config.ts +10 -0
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +3738 -28
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/bundled-rules/hephaestus.md +1 -1
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +4565 -89
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +4 -3
- package/packages/omo-codex/plugin/components/rules/src/cli.ts +16 -3
- package/packages/omo-codex/plugin/components/rules/src/config.ts +3 -3
- package/packages/omo-codex/plugin/components/rules/src/dynamic-target-fingerprints.ts +6 -6
- package/packages/omo-codex/plugin/components/rules/src/event-budget.ts +1 -1
- package/packages/omo-codex/plugin/components/rules/src/persistent-cache.ts +1 -1
- package/packages/omo-codex/plugin/components/rules/src/post-compact-budget.ts +1 -1
- package/packages/omo-codex/plugin/components/rules/src/rules-engine-factory.ts +9 -4
- package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +3 -3
- package/packages/omo-codex/plugin/components/rules/src/transcript-rule-filter.ts +1 -1
- package/packages/omo-codex/plugin/components/rules/test/bundled-rules-priority.test.ts +4 -4
- package/packages/omo-codex/plugin/components/rules/test/bundled-rules.test.ts +1 -1
- package/packages/omo-codex/plugin/components/rules/test/dynamic-target-fingerprints.test.ts +1 -1
- package/packages/omo-codex/plugin/components/rules/test/engine.test.ts +3 -3
- package/packages/omo-codex/plugin/components/rules/test/finder.test.ts +2 -2
- package/packages/omo-codex/plugin/components/rules/test/formatter.test.ts +2 -2
- package/packages/omo-codex/plugin/components/rules/test/matcher.test.ts +2 -2
- package/packages/omo-codex/plugin/components/rules/test/parser.test.ts +1 -1
- package/packages/omo-codex/plugin/components/rules/test/post-compact-budget.test.ts +1 -1
- package/packages/omo-codex/plugin/components/rules/test/rules-engine-consumption.test.ts +92 -0
- package/packages/omo-codex/plugin/components/rules/test/scanner.test.ts +1 -1
- package/packages/omo-codex/plugin/components/rules/test/sources.test.ts +4 -4
- package/packages/omo-codex/plugin/components/rules/test/windows-git-bash-bundled-rule.test.ts +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +394 -37
- 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 +4 -3
- package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +20 -147
- package/packages/omo-codex/plugin/components/start-work-continuation/src/codex-hook.ts +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/src/index.ts +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +151 -27
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +87 -49
- package/packages/omo-codex/plugin/components/telemetry/LICENSE +21 -0
- package/packages/omo-codex/plugin/components/telemetry/NOTICE +6 -0
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.js +5869 -42
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.js +5783 -108
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +4 -5
- package/packages/omo-codex/plugin/components/telemetry/src/codex-hook.ts +3 -3
- package/packages/omo-codex/plugin/components/telemetry/src/posthog.ts +92 -142
- package/packages/omo-codex/plugin/components/telemetry/src/product-identity.ts +59 -3
- package/packages/omo-codex/plugin/components/telemetry/test/codex-hook-diagnostics.test.ts +3 -3
- package/packages/omo-codex/plugin/components/telemetry/test/diagnostics.test.ts +13 -7
- package/packages/omo-codex/plugin/components/ultrawork/AGENTS.md +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/README.md +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/explorer.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-clone-fidelity-reviewer.toml +31 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-code-reviewer.toml +29 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-executor.toml +24 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-gate-reviewer.toml +23 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/lazycodex-qa-executor.toml +22 -0
- package/packages/omo-codex/plugin/components/ultrawork/agents/librarian.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/agents/plan.toml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +104 -156
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +162 -37
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +4 -3
- package/packages/omo-codex/plugin/components/ultrawork/scripts/sync-directive.mjs +11 -0
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +47 -20
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +55 -88
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +44 -0
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +44 -0
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/scripts/scaffold-plan.mjs +301 -0
- package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-test-helpers.ts +101 -0
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +111 -0
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook.test.ts +24 -128
- package/packages/omo-codex/plugin/components/ultrawork/test/directive-source.test.ts +16 -0
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +79 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.d.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +56 -82
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-commands.js +38 -144
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.d.ts +10 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-subcommands.js +173 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +2419 -32
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-goal-instruction.js +13 -9
- package/packages/omo-codex/plugin/components/ulw-loop/dist/domain-types.d.ts +60 -12
- package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.d.ts +3 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/evidence.js +67 -10
- package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.d.ts +3 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/goal-status.js +14 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.d.ts +2 -6
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-crud.js +49 -39
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-goal-factory.d.ts +8 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/plan-goal-factory.js +109 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-blockers.d.ts +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-blockers.js +41 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +8 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +39 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.d.ts +13 -6
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +176 -105
- 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/references/full-workflow.md +17 -17
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +100 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +162 -85
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-commands.ts +62 -136
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-subcommands.ts +250 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-goal-instruction.ts +18 -9
- package/packages/omo-codex/plugin/components/ulw-loop/src/domain-types.ts +67 -4
- package/packages/omo-codex/plugin/components/ulw-loop/src/evidence.ts +124 -18
- package/packages/omo-codex/plugin/components/ulw-loop/src/goal-status.ts +16 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-crud.ts +131 -54
- package/packages/omo-codex/plugin/components/ulw-loop/src/plan-goal-factory.ts +124 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-blockers.ts +48 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +44 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +230 -138
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +186 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-status.test.ts +85 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint.test.ts +120 -192
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-checkpoint.test.ts +215 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-commands.test.ts +1 -195
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-complete-goals.test.ts +15 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-create-goals.test.ts +172 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-helpers.test.ts +0 -6
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-goal-instruction.test.ts +39 -8
- package/packages/omo-codex/plugin/components/ulw-loop/test/evidence-criteria-gate.test.ts +29 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/artifacts/browser-screenshot.txt +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/artifacts/cli-pass.txt +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/artifacts/code-review.md +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/artifacts/data-diff.txt +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/artifacts/gate-review.md +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/artifacts/http-dump.txt +4 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/artifacts/rejection.txt +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/checkpoint-builders.ts +98 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/quality-gate-builder.ts +91 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/sample-quality-gate.json +110 -8
- package/packages/omo-codex/plugin/components/ulw-loop/test/goal-status.test.ts +35 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/plan-crud.test.ts +11 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-blockers.test.ts +102 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-doc.test.ts +38 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-roles.test.ts +131 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +150 -176
- package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +12 -0
- package/packages/omo-codex/plugin/hooks/hooks.json +38 -17
- package/packages/omo-codex/plugin/package-lock.json +144 -49
- package/packages/omo-codex/plugin/package.json +4 -2
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +2 -0
- package/packages/omo-codex/plugin/scripts/build-bundled-mcp-runtimes.mjs +0 -5
- package/packages/omo-codex/plugin/scripts/build-components.mjs +29 -5
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +2 -0
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +125 -0
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +43 -0
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +29 -0
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +121 -0
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +5 -5
- package/packages/omo-codex/plugin/shared/package.json +24 -0
- package/packages/omo-codex/plugin/shared/src/config-loader.ts +28 -0
- package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +105 -0
- package/packages/omo-codex/plugin/shared/tsconfig.build.json +9 -0
- package/packages/omo-codex/plugin/shared/tsconfig.json +16 -0
- package/packages/omo-codex/plugin/skills/ast-grep/LICENSE +21 -0
- package/packages/omo-codex/plugin/skills/ast-grep/README.md +136 -0
- package/packages/omo-codex/plugin/skills/ast-grep/SKILL.md +272 -0
- package/packages/omo-codex/plugin/skills/ast-grep/SOURCE +1 -0
- package/packages/omo-codex/plugin/skills/ast-grep/install.ps1 +235 -0
- package/packages/omo-codex/plugin/skills/ast-grep/install.sh +286 -0
- package/packages/omo-codex/plugin/skills/ast-grep/references/cli.md +231 -0
- package/packages/omo-codex/plugin/skills/ast-grep/references/install.md +166 -0
- package/packages/omo-codex/plugin/skills/ast-grep/references/patterns.md +147 -0
- package/packages/omo-codex/plugin/skills/ast-grep/references/pitfalls.md +303 -0
- package/packages/omo-codex/plugin/skills/ast-grep/references/recipes.md +402 -0
- package/packages/omo-codex/plugin/skills/ast-grep/references/sgconfig.md +248 -0
- package/packages/omo-codex/plugin/skills/ast-grep/references/yaml-rules.md +509 -0
- package/packages/omo-codex/plugin/skills/ast-grep/scripts/ast_grep_helper.py +748 -0
- package/packages/omo-codex/plugin/skills/ast-grep/tests/smoke.ps1 +123 -0
- package/packages/omo-codex/plugin/skills/ast-grep/tests/smoke.sh +212 -0
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +127 -0
- package/packages/omo-codex/plugin/skills/frontend/LICENSE-Apache-2.0.txt +201 -0
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +113 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +240 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +189 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/airbnb.md +390 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/airtable.md +89 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/apple.md +247 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/binance.md +345 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/bmw.md +180 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/brutalist-skill.md +92 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/bugatti.md +268 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/cal.md +259 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/claude.md +312 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/clay.md +304 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/clickhouse.md +281 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/cohere.md +266 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/coinbase.md +129 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/composio.md +307 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/cursor.md +309 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +217 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/elevenlabs.md +265 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/expo.md +281 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/ferrari.md +314 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/figma.md +220 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/framer.md +246 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/gpt-tasteskill.md +74 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/hashicorp.md +278 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/ibm.md +332 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/image-to-code-skill.md +1228 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/imagegen-brandkit.md +798 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/imagegen-frontend-mobile.md +1465 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/imagegen-frontend-web.md +686 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/intercom.md +146 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/kraken.md +125 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/lamborghini.md +288 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/linear.app.md +367 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/lovable.md +298 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/mastercard.md +365 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/meta.md +366 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/minimalist-skill.md +85 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/minimax.md +257 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/mintlify.md +326 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/miro.md +108 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/mistral.ai.md +261 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/mongodb.md +266 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/nike.md +363 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/notion.md +309 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/nvidia.md +293 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/ollama.md +267 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/opencode.ai.md +281 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/output-skill.md +49 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/pinterest.md +230 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/playstation.md +364 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/posthog.md +256 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/raycast.md +268 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/react-dev-tooling-skill.md +230 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/redesign-skill.md +178 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/renault.md +311 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/replicate.md +261 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/resend.md +303 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/revolut.md +185 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/runwayml.md +244 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/sanity.md +357 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/sentry.md +262 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/shopify.md +350 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/soft-skill.md +98 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/spacex.md +194 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/spotify.md +246 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/starbucks.md +580 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/stitch-skill.md +184 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/stripe.md +322 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/supabase.md +255 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/superhuman.md +252 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/taste-skill.md +226 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/tesla.md +286 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/theverge.md +339 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/together.ai.md +263 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/uber.md +295 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/vercel.md +310 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/vodafone.md +423 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/voltagent.md +323 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/warp.md +253 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/webflow.md +92 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/wired.md +278 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/wise.md +173 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/x.ai.md +257 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/zapier.md +328 -0
- package/packages/omo-codex/plugin/skills/frontend/references/perfection/README.md +160 -0
- package/packages/omo-codex/plugin/skills/frontend/references/perfection/react-perf-tooling.md +127 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/README.md +273 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/charts.csv +26 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/colors.csv +97 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/icons.csv +101 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/landing.csv +31 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/products.csv +97 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/react-performance.csv +45 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/astro.csv +54 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/flutter.csv +53 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/jetpack-compose.csv +53 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/nextjs.csv +53 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/nuxt-ui.csv +51 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/nuxtjs.csv +59 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/react-native.csv +52 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/react.csv +54 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/shadcn.csv +61 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/svelte.csv +54 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/swiftui.csv +51 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/stacks/vue.csv +50 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/styles.csv +68 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/typography.csv +58 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/ui-reasoning.csv +101 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/ux-guidelines.csv +100 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/data/web-interface.csv +31 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/core.py +253 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/design_system.py +1067 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/search.py +114 -0
- package/packages/omo-codex/plugin/skills/frontend/scripts/perfection/lighthouse-audit.py +201 -0
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +3 -3
- package/packages/omo-codex/plugin/skills/refactor/SKILL.md +14 -23
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +2 -2
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +2 -2
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +3 -3
- package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +2 -2
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +17 -17
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +47 -20
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +55 -88
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +44 -0
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +44 -0
- package/packages/omo-codex/plugin/skills/ulw-plan/scripts/scaffold-plan.mjs +301 -0
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +19 -3
- package/packages/omo-codex/plugin/skills/visual-qa/references/agent-browser-setup.md +44 -0
- package/packages/omo-codex/plugin/test/aggregate-agents.test.mjs +119 -11
- package/packages/omo-codex/plugin/test/aggregate-build.test.mjs +2 -4
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +29 -2
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +2 -0
- package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +12 -12
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +26 -0
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +287 -0
- package/packages/omo-codex/plugin/test/component-hook-contract-cases.mjs +199 -0
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +38 -2
- package/packages/omo-codex/plugin/test/index.js +13 -0
- package/packages/omo-codex/plugin/test/install-time-build-runtime.test.mjs +4 -5
- package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +5 -3
- package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +179 -0
- package/packages/omo-codex/plugin/test/payload-equivalence.test.mjs +109 -0
- package/packages/omo-codex/plugin/test/scaffold-plan.test.mjs +165 -0
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +6 -6
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -3
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +37 -1
- package/packages/omo-codex/scripts/install-bin-links.test.mjs +3 -3
- package/packages/omo-codex/scripts/install-cache-copy.test.mjs +1 -1
- package/packages/omo-codex/scripts/install-cli-args.test.mjs +1 -1
- package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +1 -1
- package/packages/omo-codex/scripts/install-config-autonomous.test.mjs +1 -1
- package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +1 -1
- package/packages/omo-codex/scripts/install-config-preservation.test.mjs +1 -1
- package/packages/omo-codex/scripts/install-config-reasoning.test.mjs +1 -2
- package/packages/omo-codex/scripts/install-config.test.mjs +8 -6
- package/packages/omo-codex/scripts/install-delegated-command.test.mjs +1 -1
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +13377 -0
- package/packages/omo-codex/scripts/install-generated-bundle.test.mjs +55 -0
- package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +3 -4
- package/packages/omo-codex/scripts/install-hook-targets.test.mjs +1 -1
- package/packages/omo-codex/scripts/install-local.mjs +54 -237
- package/packages/omo-codex/scripts/install-local.test.mjs +8 -1
- package/packages/omo-codex/scripts/install-marketplace-cache.test.mjs +3 -3
- package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +34 -77
- package/packages/omo-codex/scripts/install-packaged-local.test.mjs +8 -4
- package/packages/omo-codex/scripts/install-project-local-cleanup.test.mjs +1 -1
- package/packages/shared-skills/package.json +6 -1
- package/packages/shared-skills/skills/ast-grep/LICENSE +21 -0
- package/packages/shared-skills/skills/ast-grep/README.md +136 -0
- package/packages/shared-skills/skills/ast-grep/SKILL.md +272 -0
- package/packages/shared-skills/skills/ast-grep/SOURCE +1 -0
- package/packages/shared-skills/skills/ast-grep/install.ps1 +235 -0
- package/packages/shared-skills/skills/ast-grep/install.sh +286 -0
- package/packages/shared-skills/skills/ast-grep/references/cli.md +231 -0
- package/packages/shared-skills/skills/ast-grep/references/install.md +166 -0
- package/packages/shared-skills/skills/ast-grep/references/patterns.md +147 -0
- package/packages/shared-skills/skills/ast-grep/references/pitfalls.md +303 -0
- package/packages/shared-skills/skills/ast-grep/references/recipes.md +402 -0
- package/packages/shared-skills/skills/ast-grep/references/sgconfig.md +248 -0
- package/packages/shared-skills/skills/ast-grep/references/yaml-rules.md +509 -0
- package/packages/shared-skills/skills/ast-grep/scripts/ast_grep_helper.py +748 -0
- package/packages/shared-skills/skills/ast-grep/tests/smoke.ps1 +123 -0
- package/packages/shared-skills/skills/ast-grep/tests/smoke.sh +212 -0
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +127 -0
- package/packages/shared-skills/skills/frontend/LICENSE-Apache-2.0.txt +201 -0
- package/packages/shared-skills/skills/frontend/SKILL.md +113 -0
- package/packages/shared-skills/skills/frontend/references/design/README.md +240 -0
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +189 -0
- package/packages/shared-skills/skills/frontend/references/design/airbnb.md +390 -0
- package/packages/shared-skills/skills/frontend/references/design/airtable.md +89 -0
- package/packages/shared-skills/skills/frontend/references/design/apple.md +247 -0
- package/packages/shared-skills/skills/frontend/references/design/binance.md +345 -0
- package/packages/shared-skills/skills/frontend/references/design/bmw.md +180 -0
- package/packages/shared-skills/skills/frontend/references/design/brutalist-skill.md +92 -0
- package/packages/shared-skills/skills/frontend/references/design/bugatti.md +268 -0
- package/packages/shared-skills/skills/frontend/references/design/cal.md +259 -0
- package/packages/shared-skills/skills/frontend/references/design/claude.md +312 -0
- package/packages/shared-skills/skills/frontend/references/design/clay.md +304 -0
- package/packages/shared-skills/skills/frontend/references/design/clickhouse.md +281 -0
- package/packages/shared-skills/skills/frontend/references/design/cohere.md +266 -0
- package/packages/shared-skills/skills/frontend/references/design/coinbase.md +129 -0
- package/packages/shared-skills/skills/frontend/references/design/composio.md +307 -0
- package/packages/shared-skills/skills/frontend/references/design/cursor.md +309 -0
- package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +217 -0
- package/packages/shared-skills/skills/frontend/references/design/elevenlabs.md +265 -0
- package/packages/shared-skills/skills/frontend/references/design/expo.md +281 -0
- package/packages/shared-skills/skills/frontend/references/design/ferrari.md +314 -0
- package/packages/shared-skills/skills/frontend/references/design/figma.md +220 -0
- package/packages/shared-skills/skills/frontend/references/design/framer.md +246 -0
- package/packages/shared-skills/skills/frontend/references/design/gpt-tasteskill.md +74 -0
- package/packages/shared-skills/skills/frontend/references/design/hashicorp.md +278 -0
- package/packages/shared-skills/skills/frontend/references/design/ibm.md +332 -0
- package/packages/shared-skills/skills/frontend/references/design/image-to-code-skill.md +1228 -0
- package/packages/shared-skills/skills/frontend/references/design/imagegen-brandkit.md +798 -0
- package/packages/shared-skills/skills/frontend/references/design/imagegen-frontend-mobile.md +1465 -0
- package/packages/shared-skills/skills/frontend/references/design/imagegen-frontend-web.md +686 -0
- package/packages/shared-skills/skills/frontend/references/design/intercom.md +146 -0
- package/packages/shared-skills/skills/frontend/references/design/kraken.md +125 -0
- package/packages/shared-skills/skills/frontend/references/design/lamborghini.md +288 -0
- package/packages/shared-skills/skills/frontend/references/design/linear.app.md +367 -0
- package/packages/shared-skills/skills/frontend/references/design/lovable.md +298 -0
- package/packages/shared-skills/skills/frontend/references/design/mastercard.md +365 -0
- package/packages/shared-skills/skills/frontend/references/design/meta.md +366 -0
- package/packages/shared-skills/skills/frontend/references/design/minimalist-skill.md +85 -0
- package/packages/shared-skills/skills/frontend/references/design/minimax.md +257 -0
- package/packages/shared-skills/skills/frontend/references/design/mintlify.md +326 -0
- package/packages/shared-skills/skills/frontend/references/design/miro.md +108 -0
- package/packages/shared-skills/skills/frontend/references/design/mistral.ai.md +261 -0
- package/packages/shared-skills/skills/frontend/references/design/mongodb.md +266 -0
- package/packages/shared-skills/skills/frontend/references/design/nike.md +363 -0
- package/packages/shared-skills/skills/frontend/references/design/notion.md +309 -0
- package/packages/shared-skills/skills/frontend/references/design/nvidia.md +293 -0
- package/packages/shared-skills/skills/frontend/references/design/ollama.md +267 -0
- package/packages/shared-skills/skills/frontend/references/design/opencode.ai.md +281 -0
- package/packages/shared-skills/skills/frontend/references/design/output-skill.md +49 -0
- package/packages/shared-skills/skills/frontend/references/design/pinterest.md +230 -0
- package/packages/shared-skills/skills/frontend/references/design/playstation.md +364 -0
- package/packages/shared-skills/skills/frontend/references/design/posthog.md +256 -0
- package/packages/shared-skills/skills/frontend/references/design/raycast.md +268 -0
- package/packages/shared-skills/skills/frontend/references/design/react-dev-tooling-skill.md +230 -0
- package/packages/shared-skills/skills/frontend/references/design/redesign-skill.md +178 -0
- package/packages/shared-skills/skills/frontend/references/design/renault.md +311 -0
- package/packages/shared-skills/skills/frontend/references/design/replicate.md +261 -0
- package/packages/shared-skills/skills/frontend/references/design/resend.md +303 -0
- package/packages/shared-skills/skills/frontend/references/design/revolut.md +185 -0
- package/packages/shared-skills/skills/frontend/references/design/runwayml.md +244 -0
- package/packages/shared-skills/skills/frontend/references/design/sanity.md +357 -0
- package/packages/shared-skills/skills/frontend/references/design/sentry.md +262 -0
- package/packages/shared-skills/skills/frontend/references/design/shopify.md +350 -0
- package/packages/shared-skills/skills/frontend/references/design/soft-skill.md +98 -0
- package/packages/shared-skills/skills/frontend/references/design/spacex.md +194 -0
- package/packages/shared-skills/skills/frontend/references/design/spotify.md +246 -0
- package/packages/shared-skills/skills/frontend/references/design/starbucks.md +580 -0
- package/packages/shared-skills/skills/frontend/references/design/stitch-skill.md +184 -0
- package/packages/shared-skills/skills/frontend/references/design/stripe.md +322 -0
- package/packages/shared-skills/skills/frontend/references/design/supabase.md +255 -0
- package/packages/shared-skills/skills/frontend/references/design/superhuman.md +252 -0
- package/packages/shared-skills/skills/frontend/references/design/taste-skill.md +226 -0
- package/packages/shared-skills/skills/frontend/references/design/tesla.md +286 -0
- package/packages/shared-skills/skills/frontend/references/design/theverge.md +339 -0
- package/packages/shared-skills/skills/frontend/references/design/together.ai.md +263 -0
- package/packages/shared-skills/skills/frontend/references/design/uber.md +295 -0
- package/packages/shared-skills/skills/frontend/references/design/vercel.md +310 -0
- package/packages/shared-skills/skills/frontend/references/design/vodafone.md +423 -0
- package/packages/shared-skills/skills/frontend/references/design/voltagent.md +323 -0
- package/packages/shared-skills/skills/frontend/references/design/warp.md +253 -0
- package/packages/shared-skills/skills/frontend/references/design/webflow.md +92 -0
- package/packages/shared-skills/skills/frontend/references/design/wired.md +278 -0
- package/packages/shared-skills/skills/frontend/references/design/wise.md +173 -0
- package/packages/shared-skills/skills/frontend/references/design/x.ai.md +257 -0
- package/packages/shared-skills/skills/frontend/references/design/zapier.md +328 -0
- package/packages/shared-skills/skills/frontend/references/perfection/README.md +160 -0
- package/packages/shared-skills/skills/frontend/references/perfection/react-perf-tooling.md +127 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/README.md +273 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/charts.csv +26 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/colors.csv +97 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/icons.csv +101 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/landing.csv +31 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/products.csv +97 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/react-performance.csv +45 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/astro.csv +54 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/flutter.csv +53 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/html-tailwind.csv +56 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/jetpack-compose.csv +53 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/nextjs.csv +53 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/nuxt-ui.csv +51 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/nuxtjs.csv +59 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/react-native.csv +52 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/react.csv +54 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/shadcn.csv +61 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/svelte.csv +54 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/swiftui.csv +51 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/stacks/vue.csv +50 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/styles.csv +68 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/typography.csv +58 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/ui-reasoning.csv +101 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/ux-guidelines.csv +100 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/data/web-interface.csv +31 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/core.py +253 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/design_system.py +1067 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/search.py +114 -0
- package/packages/shared-skills/skills/frontend/scripts/perfection/lighthouse-audit.py +201 -0
- package/packages/shared-skills/skills/init-deep/SKILL.md +1 -1
- package/packages/shared-skills/skills/refactor/SKILL.md +12 -21
- package/packages/shared-skills/skills/review-work/SKILL.md +11 -9
- package/packages/shared-skills/skills/start-work/SKILL.md +5 -4
- package/packages/shared-skills/skills/ultraresearch/SKILL.md +9 -8
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +69 -0
- package/packages/shared-skills/skills/ulw-plan/agents/openai.yaml +7 -0
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +99 -0
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +44 -0
- package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +44 -0
- package/packages/shared-skills/skills/ulw-plan/scripts/scaffold-plan.mjs +301 -0
- package/packages/shared-skills/skills/visual-qa/SKILL.md +17 -1
- package/packages/shared-skills/skills/visual-qa/references/agent-browser-setup.md +44 -0
- package/packages/shared-skills/skills/visual-qa/scripts/skill-prompt-contract.test.ts +48 -4
- package/dist/cli/doctor/constants.d.ts +0 -32
- package/dist/cli/doctor/spawn-with-timeout.d.ts +0 -8
- package/dist/cli/doctor/types.d.ts +0 -148
- package/dist/features/builtin-skills/skills/frontend-ui-ux.d.ts +0 -2
- package/dist/mcp/ast-grep.d.ts +0 -11
- package/packages/ast-grep-mcp/dist/cli.js +0 -1159
- package/packages/lsp-tools-mcp/dist/lsp/cleanup-errors.js +0 -6
- package/packages/lsp-tools-mcp/dist/lsp/client-wrapper.js +0 -132
- package/packages/lsp-tools-mcp/dist/lsp/client.js +0 -131
- package/packages/lsp-tools-mcp/dist/lsp/config-loader.js +0 -220
- package/packages/lsp-tools-mcp/dist/lsp/connection.js +0 -66
- package/packages/lsp-tools-mcp/dist/lsp/constants.js +0 -10
- package/packages/lsp-tools-mcp/dist/lsp/directory-diagnostics.js +0 -125
- package/packages/lsp-tools-mcp/dist/lsp/effective-extension.js +0 -8
- package/packages/lsp-tools-mcp/dist/lsp/errors.js +0 -56
- package/packages/lsp-tools-mcp/dist/lsp/formatters.js +0 -106
- package/packages/lsp-tools-mcp/dist/lsp/infer-extension.js +0 -59
- package/packages/lsp-tools-mcp/dist/lsp/json-rpc-connection.js +0 -247
- package/packages/lsp-tools-mcp/dist/lsp/language-mappings.js +0 -170
- package/packages/lsp-tools-mcp/dist/lsp/process-signal-cleanup.js +0 -17
- package/packages/lsp-tools-mcp/dist/lsp/process.js +0 -153
- package/packages/lsp-tools-mcp/dist/lsp/server-definitions.js +0 -170
- package/packages/lsp-tools-mcp/dist/lsp/server-install-state.js +0 -51
- package/packages/lsp-tools-mcp/dist/lsp/server-installation.js +0 -40
- package/packages/lsp-tools-mcp/dist/lsp/server-resolution.js +0 -86
- package/packages/lsp-tools-mcp/dist/lsp/startup-failure.js +0 -35
- package/packages/lsp-tools-mcp/dist/lsp/transport.js +0 -241
- package/packages/lsp-tools-mcp/dist/lsp/types.js +0 -1
- package/packages/lsp-tools-mcp/dist/lsp/workspace-edit.js +0 -175
- package/packages/lsp-tools-mcp/dist/missing-dependency-result.js +0 -14
- package/packages/omo-codex/plugin/components/bootstrap/manifests/ast-grep.json +0 -22
- package/packages/omo-codex/plugin/components/comment-checker/dist/apply-patch.d.ts +0 -7
- package/packages/omo-codex/plugin/components/comment-checker/dist/apply-patch.js +0 -173
- package/packages/omo-codex/plugin/components/comment-checker/dist/codex-hook.d.ts +0 -22
- package/packages/omo-codex/plugin/components/comment-checker/dist/codex-hook.js +0 -165
- package/packages/omo-codex/plugin/components/comment-checker/dist/core-values.d.ts +0 -1
- package/packages/omo-codex/plugin/components/comment-checker/dist/core-values.js +0 -1
- package/packages/omo-codex/plugin/components/comment-checker/dist/core.d.ts +0 -5
- package/packages/omo-codex/plugin/components/comment-checker/dist/core.js +0 -4
- package/packages/omo-codex/plugin/components/comment-checker/dist/hook-input.d.ts +0 -6
- package/packages/omo-codex/plugin/components/comment-checker/dist/hook-input.js +0 -10
- package/packages/omo-codex/plugin/components/comment-checker/dist/record.d.ts +0 -2
- package/packages/omo-codex/plugin/components/comment-checker/dist/record.js +0 -11
- package/packages/omo-codex/plugin/components/comment-checker/dist/request-extractor.d.ts +0 -3
- package/packages/omo-codex/plugin/components/comment-checker/dist/request-extractor.js +0 -104
- package/packages/omo-codex/plugin/components/comment-checker/dist/runner.d.ts +0 -26
- package/packages/omo-codex/plugin/components/comment-checker/dist/runner.js +0 -144
- package/packages/omo-codex/plugin/components/comment-checker/dist/types.d.ts +0 -43
- package/packages/omo-codex/plugin/components/comment-checker/dist/types.js +0 -1
- package/packages/omo-codex/plugin/components/comment-checker/src/record.ts +0 -11
- package/packages/omo-codex/plugin/components/rules/dist/codex-hook-options.d.ts +0 -5
- package/packages/omo-codex/plugin/components/rules/dist/codex-hook-options.js +0 -1
- package/packages/omo-codex/plugin/components/rules/dist/codex-hook.d.ts +0 -47
- package/packages/omo-codex/plugin/components/rules/dist/codex-hook.js +0 -127
- package/packages/omo-codex/plugin/components/rules/dist/config.d.ts +0 -2
- package/packages/omo-codex/plugin/components/rules/dist/config.js +0 -100
- package/packages/omo-codex/plugin/components/rules/dist/context-pressure.d.ts +0 -2
- package/packages/omo-codex/plugin/components/rules/dist/context-pressure.js +0 -26
- package/packages/omo-codex/plugin/components/rules/dist/debug-log.d.ts +0 -8
- package/packages/omo-codex/plugin/components/rules/dist/debug-log.js +0 -36
- package/packages/omo-codex/plugin/components/rules/dist/dynamic-target-fingerprints.d.ts +0 -7
- package/packages/omo-codex/plugin/components/rules/dist/dynamic-target-fingerprints.js +0 -65
- package/packages/omo-codex/plugin/components/rules/dist/event-budget.d.ts +0 -3
- package/packages/omo-codex/plugin/components/rules/dist/event-budget.js +0 -14
- package/packages/omo-codex/plugin/components/rules/dist/hook-output.d.ts +0 -2
- package/packages/omo-codex/plugin/components/rules/dist/hook-output.js +0 -24
- package/packages/omo-codex/plugin/components/rules/dist/path-utils.d.ts +0 -4
- package/packages/omo-codex/plugin/components/rules/dist/path-utils.js +0 -24
- package/packages/omo-codex/plugin/components/rules/dist/persistent-cache.d.ts +0 -13
- package/packages/omo-codex/plugin/components/rules/dist/persistent-cache.js +0 -172
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-budget.d.ts +0 -6
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-budget.js +0 -74
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-claim.d.ts +0 -4
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-claim.js +0 -6
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-directive.d.ts +0 -1
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-directive.js +0 -32
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-state.d.ts +0 -13
- package/packages/omo-codex/plugin/components/rules/dist/post-compact-state.js +0 -29
- package/packages/omo-codex/plugin/components/rules/dist/rules/cache.d.ts +0 -9
- package/packages/omo-codex/plugin/components/rules/dist/rules/cache.js +0 -51
- package/packages/omo-codex/plugin/components/rules/dist/rules/constants.d.ts +0 -70
- package/packages/omo-codex/plugin/components/rules/dist/rules/constants.js +0 -101
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-cache.d.ts +0 -5
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-cache.js +0 -60
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-loader.d.ts +0 -6
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-dynamic-loader.js +0 -61
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-loader.d.ts +0 -7
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-loader.js +0 -60
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-paths.d.ts +0 -11
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-paths.js +0 -75
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-static-loader.d.ts +0 -6
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-static-loader.js +0 -29
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-types.d.ts +0 -44
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine-types.js +0 -1
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine.d.ts +0 -5
- package/packages/omo-codex/plugin/components/rules/dist/rules/engine.js +0 -85
- package/packages/omo-codex/plugin/components/rules/dist/rules/errors.d.ts +0 -6
- package/packages/omo-codex/plugin/components/rules/dist/rules/errors.js +0 -12
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-cache.d.ts +0 -14
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-cache.js +0 -51
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-paths.d.ts +0 -6
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-paths.js +0 -33
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-sources.d.ts +0 -5
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder-sources.js +0 -40
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder.d.ts +0 -28
- package/packages/omo-codex/plugin/components/rules/dist/rules/finder.js +0 -146
- package/packages/omo-codex/plugin/components/rules/dist/rules/formatter.d.ts +0 -7
- package/packages/omo-codex/plugin/components/rules/dist/rules/formatter.js +0 -112
- package/packages/omo-codex/plugin/components/rules/dist/rules/matcher.d.ts +0 -18
- package/packages/omo-codex/plugin/components/rules/dist/rules/matcher.js +0 -93
- package/packages/omo-codex/plugin/components/rules/dist/rules/ordering.d.ts +0 -3
- package/packages/omo-codex/plugin/components/rules/dist/rules/ordering.js +0 -27
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser-frontmatter.d.ts +0 -7
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser-frontmatter.js +0 -30
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser-yaml.d.ts +0 -2
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser-yaml.js +0 -237
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser.d.ts +0 -3
- package/packages/omo-codex/plugin/components/rules/dist/rules/parser.js +0 -31
- package/packages/omo-codex/plugin/components/rules/dist/rules/plugin-root.d.ts +0 -1
- package/packages/omo-codex/plugin/components/rules/dist/rules/plugin-root.js +0 -48
- package/packages/omo-codex/plugin/components/rules/dist/rules/project-root.d.ts +0 -1
- package/packages/omo-codex/plugin/components/rules/dist/rules/project-root.js +0 -23
- package/packages/omo-codex/plugin/components/rules/dist/rules/scanner.d.ts +0 -14
- package/packages/omo-codex/plugin/components/rules/dist/rules/scanner.js +0 -111
- package/packages/omo-codex/plugin/components/rules/dist/rules/sources.d.ts +0 -3
- package/packages/omo-codex/plugin/components/rules/dist/rules/sources.js +0 -9
- package/packages/omo-codex/plugin/components/rules/dist/rules/truncator.d.ts +0 -18
- package/packages/omo-codex/plugin/components/rules/dist/rules/truncator.js +0 -59
- package/packages/omo-codex/plugin/components/rules/dist/rules/types.d.ts +0 -126
- package/packages/omo-codex/plugin/components/rules/dist/rules/types.js +0 -8
- package/packages/omo-codex/plugin/components/rules/dist/rules-engine-factory.d.ts +0 -6
- package/packages/omo-codex/plugin/components/rules/dist/rules-engine-factory.js +0 -20
- package/packages/omo-codex/plugin/components/rules/dist/session-state-lock.d.ts +0 -3
- package/packages/omo-codex/plugin/components/rules/dist/session-state-lock.js +0 -41
- package/packages/omo-codex/plugin/components/rules/dist/sparkshell-awareness.d.ts +0 -10
- package/packages/omo-codex/plugin/components/rules/dist/sparkshell-awareness.js +0 -90
- package/packages/omo-codex/plugin/components/rules/dist/static-injection.d.ts +0 -3
- package/packages/omo-codex/plugin/components/rules/dist/static-injection.js +0 -128
- package/packages/omo-codex/plugin/components/rules/dist/tool-paths.d.ts +0 -6
- package/packages/omo-codex/plugin/components/rules/dist/tool-paths.js +0 -168
- package/packages/omo-codex/plugin/components/rules/dist/transcript-rule-filter.d.ts +0 -4
- package/packages/omo-codex/plugin/components/rules/dist/transcript-rule-filter.js +0 -49
- package/packages/omo-codex/plugin/components/rules/dist/transcript-search.d.ts +0 -4
- package/packages/omo-codex/plugin/components/rules/dist/transcript-search.js +0 -91
- package/packages/omo-codex/plugin/components/rules/src/rules/cache.ts +0 -64
- package/packages/omo-codex/plugin/components/rules/src/rules/constants.ts +0 -122
- package/packages/omo-codex/plugin/components/rules/src/rules/engine-dynamic-cache.ts +0 -87
- package/packages/omo-codex/plugin/components/rules/src/rules/engine-dynamic-loader.ts +0 -94
- package/packages/omo-codex/plugin/components/rules/src/rules/engine-loader.ts +0 -84
- package/packages/omo-codex/plugin/components/rules/src/rules/engine-paths.ts +0 -103
- package/packages/omo-codex/plugin/components/rules/src/rules/engine-static-loader.ts +0 -43
- package/packages/omo-codex/plugin/components/rules/src/rules/engine-types.ts +0 -45
- package/packages/omo-codex/plugin/components/rules/src/rules/engine.ts +0 -123
- package/packages/omo-codex/plugin/components/rules/src/rules/errors.ts +0 -13
- package/packages/omo-codex/plugin/components/rules/src/rules/finder-cache.ts +0 -73
- package/packages/omo-codex/plugin/components/rules/src/rules/finder-paths.ts +0 -47
- package/packages/omo-codex/plugin/components/rules/src/rules/finder-sources.ts +0 -45
- package/packages/omo-codex/plugin/components/rules/src/rules/finder.ts +0 -220
- package/packages/omo-codex/plugin/components/rules/src/rules/formatter.ts +0 -149
- package/packages/omo-codex/plugin/components/rules/src/rules/matcher.ts +0 -142
- package/packages/omo-codex/plugin/components/rules/src/rules/ordering.ts +0 -33
- package/packages/omo-codex/plugin/components/rules/src/rules/parser-frontmatter.ts +0 -39
- package/packages/omo-codex/plugin/components/rules/src/rules/parser-yaml.ts +0 -271
- package/packages/omo-codex/plugin/components/rules/src/rules/parser.ts +0 -35
- package/packages/omo-codex/plugin/components/rules/src/rules/plugin-root.ts +0 -55
- package/packages/omo-codex/plugin/components/rules/src/rules/project-root.ts +0 -30
- package/packages/omo-codex/plugin/components/rules/src/rules/scanner.ts +0 -162
- package/packages/omo-codex/plugin/components/rules/src/rules/sources.ts +0 -13
- package/packages/omo-codex/plugin/components/rules/src/rules/truncator.ts +0 -84
- package/packages/omo-codex/plugin/components/rules/src/rules/types.ts +0 -141
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/boulder-reader.d.ts +0 -16
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/boulder-reader.js +0 -146
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.d.ts +0 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/codex-hook.d.ts +0 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/codex-hook.js +0 -80
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/directive.d.ts +0 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/directive.js +0 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/index.d.ts +0 -5
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/index.js +0 -3
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/types.d.ts +0 -20
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/types.js +0 -1
- package/packages/omo-codex/plugin/components/telemetry/dist/atomic-write.d.ts +0 -1
- package/packages/omo-codex/plugin/components/telemetry/dist/atomic-write.js +0 -18
- package/packages/omo-codex/plugin/components/telemetry/dist/cli.d.ts +0 -2
- package/packages/omo-codex/plugin/components/telemetry/dist/codex-hook.d.ts +0 -15
- package/packages/omo-codex/plugin/components/telemetry/dist/codex-hook.js +0 -42
- package/packages/omo-codex/plugin/components/telemetry/dist/data-path.d.ts +0 -10
- package/packages/omo-codex/plugin/components/telemetry/dist/data-path.js +0 -35
- package/packages/omo-codex/plugin/components/telemetry/dist/diagnostics.d.ts +0 -12
- package/packages/omo-codex/plugin/components/telemetry/dist/diagnostics.js +0 -108
- package/packages/omo-codex/plugin/components/telemetry/dist/env-flags.d.ts +0 -4
- package/packages/omo-codex/plugin/components/telemetry/dist/env-flags.js +0 -31
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog-activity-state.d.ts +0 -8
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog-activity-state.js +0 -68
- package/packages/omo-codex/plugin/components/telemetry/dist/posthog.d.ts +0 -21
- package/packages/omo-codex/plugin/components/telemetry/dist/product-identity.d.ts +0 -8
- package/packages/omo-codex/plugin/components/telemetry/dist/product-identity.js +0 -29
- package/packages/omo-codex/plugin/components/telemetry/src/atomic-write.ts +0 -22
- package/packages/omo-codex/plugin/components/telemetry/src/data-path.ts +0 -45
- package/packages/omo-codex/plugin/components/telemetry/src/diagnostics.ts +0 -154
- package/packages/omo-codex/plugin/components/telemetry/src/env-flags.ts +0 -43
- package/packages/omo-codex/plugin/components/telemetry/src/posthog-activity-state.ts +0 -97
- package/packages/omo-codex/plugin/components/ultrawork/agents/codex-ultrawork-reviewer.toml +0 -21
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.d.ts +0 -2
- package/packages/omo-codex/plugin/components/ultrawork/dist/codex-hook.d.ts +0 -7
- package/packages/omo-codex/plugin/components/ultrawork/dist/codex-hook.js +0 -122
- package/packages/omo-codex/plugin/components/ultrawork/dist/directive.d.ts +0 -1
- package/packages/omo-codex/plugin/components/ultrawork/dist/directive.js +0 -2
- package/packages/omo-codex/plugin/skills/frontend-ui-ux/SKILL.md +0 -77
- package/packages/omo-codex/plugin/test/start-work-skill.test.mjs +0 -85
- package/packages/omo-codex/plugin/test/ulw-plan-skill.test.mjs +0 -89
- package/packages/omo-codex/scripts/atomic-write.test.mjs +0 -82
- package/packages/omo-codex/scripts/install/agent-source-roots.mjs +0 -13
- package/packages/omo-codex/scripts/install/agents.d.mts +0 -18
- package/packages/omo-codex/scripts/install/agents.mjs +0 -227
- package/packages/omo-codex/scripts/install/atomic-write.mjs +0 -59
- package/packages/omo-codex/scripts/install/bin-dir.d.mts +0 -7
- package/packages/omo-codex/scripts/install/bin-dir.mjs +0 -20
- package/packages/omo-codex/scripts/install/bin-links.d.mts +0 -18
- package/packages/omo-codex/scripts/install/bin-links.mjs +0 -276
- package/packages/omo-codex/scripts/install/cache.mjs +0 -295
- package/packages/omo-codex/scripts/install/cached-marketplace-manifest.mjs +0 -21
- package/packages/omo-codex/scripts/install/cli-args.mjs +0 -149
- package/packages/omo-codex/scripts/install/command-shim.mjs +0 -1
- package/packages/omo-codex/scripts/install/config.d.mts +0 -35
- package/packages/omo-codex/scripts/install/config.mjs +0 -267
- package/packages/omo-codex/scripts/install/delegated-command.mjs +0 -29
- package/packages/omo-codex/scripts/install/git-bash-mcp-env.d.mts +0 -5
- package/packages/omo-codex/scripts/install/git-bash-mcp-env.mjs +0 -28
- package/packages/omo-codex/scripts/install/git-bash.d.mts +0 -23
- package/packages/omo-codex/scripts/install/git-bash.mjs +0 -107
- package/packages/omo-codex/scripts/install/git-bash.test.mjs +0 -209
- package/packages/omo-codex/scripts/install/hook-targets.mjs +0 -46
- package/packages/omo-codex/scripts/install/hook-trust.d.mts +0 -10
- package/packages/omo-codex/scripts/install/hook-trust.mjs +0 -84
- package/packages/omo-codex/scripts/install/lazycodex-version-stamp.mjs +0 -102
- package/packages/omo-codex/scripts/install/legacy-bins.mjs +0 -66
- package/packages/omo-codex/scripts/install/marketplace.mjs +0 -104
- package/packages/omo-codex/scripts/install/mcp-runtime-cache.mjs +0 -81
- package/packages/omo-codex/scripts/install/model-catalog.mjs +0 -74
- package/packages/omo-codex/scripts/install/multi-agent-v2-config.mjs +0 -50
- package/packages/omo-codex/scripts/install/permissions.d.mts +0 -1
- package/packages/omo-codex/scripts/install/permissions.mjs +0 -37
- package/packages/omo-codex/scripts/install/process.mjs +0 -22
- package/packages/omo-codex/scripts/install/project-local-cleanup.mjs +0 -228
- package/packages/omo-codex/scripts/install/reasoning-config.mjs +0 -72
- package/packages/omo-codex/scripts/install/snapshot.mjs +0 -53
- package/packages/omo-codex/scripts/install/source-package-build.mjs +0 -20
- package/packages/omo-codex/scripts/install/toml-editor.mjs +0 -64
- package/packages/omo-codex/scripts/install/utils.mjs +0 -15
- package/packages/omo-codex/scripts/sync-telemetry-component.mjs +0 -116
- package/packages/omo-codex/scripts/sync-telemetry-component.test.mjs +0 -94
- package/packages/shared-skills/skills/frontend-ui-ux/SKILL.md +0 -77
- /package/dist/cli/doctor/{doctor-target.d.ts → framework/doctor-target.d.ts} +0 -0
- /package/dist/cli/doctor/{format-default.d.ts → framework/format-default.d.ts} +0 -0
- /package/dist/cli/doctor/{format-shared.d.ts → framework/format-shared.d.ts} +0 -0
- /package/dist/cli/doctor/{format-status.d.ts → framework/format-status.d.ts} +0 -0
- /package/dist/cli/doctor/{format-verbose.d.ts → framework/format-verbose.d.ts} +0 -0
- /package/dist/cli/doctor/{formatter.d.ts → framework/formatter.d.ts} +0 -0
- /package/packages/omo-codex/plugin/components/{comment-checker → codegraph}/dist/cli.d.ts +0 -0
- /package/packages/omo-codex/plugin/components/{rules → lazycodex-executor-verify}/dist/cli.d.ts +0 -0
|
@@ -1,39 +1,2426 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
|
|
3
|
+
// components/ulw-loop/src/cli-arg-parser.ts
|
|
4
|
+
import { readFile } from "node:fs/promises";
|
|
5
|
+
// components/ulw-loop/src/constants.ts
|
|
6
|
+
var ULW_LOOP_DIR = ".omo/ulw-loop";
|
|
7
|
+
var ULW_LOOP_BRIEF = "brief.md";
|
|
8
|
+
var ULW_LOOP_GOALS = "goals.json";
|
|
9
|
+
var ULW_LOOP_LEDGER = "ledger.jsonl";
|
|
10
|
+
var ULW_LOOP_STEERING_MUTATION_KINDS = [
|
|
11
|
+
"add_subgoal",
|
|
12
|
+
"split_subgoal",
|
|
13
|
+
"reorder_pending",
|
|
14
|
+
"revise_pending_wording",
|
|
15
|
+
"revise_criterion",
|
|
16
|
+
"annotate_ledger",
|
|
17
|
+
"mark_blocked_superseded"
|
|
18
|
+
];
|
|
19
|
+
var ULW_LOOP_SUCCESS_CRITERION_USER_MODELS = [
|
|
20
|
+
"happy",
|
|
21
|
+
"edge",
|
|
22
|
+
"regression",
|
|
23
|
+
"adversarial"
|
|
24
|
+
];
|
|
25
|
+
// components/ulw-loop/src/runtime.ts
|
|
26
|
+
class UlwLoopError extends Error {
|
|
27
|
+
code;
|
|
28
|
+
details;
|
|
29
|
+
constructor(message, code, opts) {
|
|
30
|
+
super(message, opts?.cause === undefined ? undefined : { cause: opts.cause });
|
|
31
|
+
this.name = "UlwLoopError";
|
|
32
|
+
this.code = code;
|
|
33
|
+
if (opts?.details !== undefined) {
|
|
34
|
+
this.details = opts.details;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
function iso() {
|
|
39
|
+
return new Date().toISOString();
|
|
40
|
+
}
|
|
41
|
+
// components/ulw-loop/src/cli-arg-parser.ts
|
|
42
|
+
var 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(" "));
|
|
43
|
+
var SUBCOMMANDS = new Set("create-goals status complete-goals criteria record-evidence checkpoint steer add-goal record-review-blockers".split(" "));
|
|
44
|
+
function hasFlag(argv, flag) {
|
|
45
|
+
return argv.includes(flag);
|
|
46
|
+
}
|
|
47
|
+
function readValue(argv, flag) {
|
|
48
|
+
const index = argv.indexOf(flag);
|
|
49
|
+
if (index >= 0) {
|
|
50
|
+
const next = argv[index + 1];
|
|
51
|
+
return next === undefined || next.startsWith("--") ? undefined : next;
|
|
52
|
+
}
|
|
53
|
+
const prefix = `${flag}=`;
|
|
54
|
+
return argv.find((arg) => arg.startsWith(prefix))?.slice(prefix.length);
|
|
55
|
+
}
|
|
56
|
+
function parseGoalArg(argv) {
|
|
57
|
+
return readValue(argv, "--goal-id") ?? readValue(argv, "--goal");
|
|
58
|
+
}
|
|
59
|
+
async function readStdin() {
|
|
60
|
+
const chunks = [];
|
|
61
|
+
for await (const chunk of process.stdin)
|
|
62
|
+
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
|
|
63
|
+
return Buffer.concat(chunks).toString("utf8");
|
|
64
|
+
}
|
|
65
|
+
function positionalText(argv) {
|
|
66
|
+
const words = [];
|
|
67
|
+
for (let index = SUBCOMMANDS.has(argv[0] ?? "") ? 1 : 0;index < argv.length; index += 1) {
|
|
68
|
+
const arg = argv[index];
|
|
69
|
+
if (arg === undefined)
|
|
70
|
+
continue;
|
|
71
|
+
if (VALUE_FLAGS.has(arg)) {
|
|
72
|
+
index += 1;
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
if (arg.startsWith("--"))
|
|
76
|
+
continue;
|
|
77
|
+
words.push(arg);
|
|
78
|
+
}
|
|
79
|
+
return words.join(" ").trim();
|
|
80
|
+
}
|
|
81
|
+
function looksLikeJson(value) {
|
|
82
|
+
const trimmed = value.trim();
|
|
83
|
+
return trimmed.startsWith("{") || trimmed.startsWith("[");
|
|
84
|
+
}
|
|
85
|
+
async function readJsonInput(value) {
|
|
86
|
+
if (value === undefined)
|
|
87
|
+
return;
|
|
88
|
+
try {
|
|
89
|
+
return JSON.parse(looksLikeJson(value) ? value : await readFile(value, "utf8"));
|
|
90
|
+
} catch (error) {
|
|
91
|
+
const message = error instanceof Error ? error.message : "unknown error";
|
|
92
|
+
throw new UlwLoopError(`Invalid JSON input: ${message}`, "ULW_LOOP_JSON_INPUT_INVALID", { cause: error });
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async function parseCodexGoalJson(value) {
|
|
96
|
+
if (value === undefined)
|
|
97
|
+
return;
|
|
98
|
+
const raw = looksLikeJson(value) ? value : await readFile(value, "utf8");
|
|
99
|
+
try {
|
|
100
|
+
JSON.parse(raw);
|
|
101
|
+
return raw;
|
|
102
|
+
} catch (error) {
|
|
103
|
+
const message = error instanceof Error ? error.message : "unknown error";
|
|
104
|
+
throw new UlwLoopError(`Invalid --codex-goal-json: ${message}`, "ULW_LOOP_CODEX_GOAL_JSON_INVALID", { cause: error });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function required(argv, flag, code) {
|
|
108
|
+
const value = readValue(argv, flag)?.trim();
|
|
109
|
+
if (value)
|
|
110
|
+
return value;
|
|
111
|
+
throw new UlwLoopError(`Missing ${flag}.`, code, { details: { flag } });
|
|
112
|
+
}
|
|
113
|
+
function evidenceStatus(value) {
|
|
114
|
+
switch (value) {
|
|
115
|
+
case "pass":
|
|
116
|
+
return "pass";
|
|
117
|
+
case "fail":
|
|
118
|
+
return "fail";
|
|
119
|
+
case "blocked":
|
|
120
|
+
return "blocked";
|
|
121
|
+
default:
|
|
122
|
+
throw new UlwLoopError("Invalid --status; expected pass, fail, or blocked.", "ULW_LOOP_EVIDENCE_STATUS_INVALID", { details: { status: value } });
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
function parseRecordEvidenceArgs(argv) {
|
|
126
|
+
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") };
|
|
127
|
+
const notes = readValue(argv, "--notes")?.trim();
|
|
128
|
+
return notes ? { ...result, notes } : result;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// components/ulw-loop/src/cli-output.ts
|
|
132
|
+
var ULW_LOOP_HELP = `Usage:
|
|
133
|
+
omo ulw-loop create-goals --brief "..." [--brief-file <path>] [--from-stdin] [--codex-goal-mode aggregate|per_story] [--force] [--json]
|
|
134
|
+
omo ulw-loop status [--json]
|
|
135
|
+
omo ulw-loop complete-goals [--retry-failed] [--json]
|
|
136
|
+
omo ulw-loop criteria --goal-id <id> [--json]
|
|
137
|
+
omo ulw-loop record-evidence --goal-id <id> --criterion-id <id> --status pass|fail|blocked --evidence "..." [--notes "..."] [--json]
|
|
138
|
+
omo ulw-loop checkpoint --goal-id <id> --status complete|failed|blocked --evidence "..." --codex-goal-json <...> [--quality-gate-json <...>] [--json]
|
|
139
|
+
omo ulw-loop steer --kind <kind> ... --evidence "..." --rationale "..." [--json]
|
|
140
|
+
omo ulw-loop add-goal --title "..." --objective "..." [--json]
|
|
141
|
+
omo ulw-loop record-review-blockers --goal-id <id> --title "..." --objective "..." --evidence "..." --codex-goal-json <...> [--json]
|
|
142
|
+
|
|
143
|
+
All subcommands accept [--session-id <id>] to isolate state under .omo/ulw-loop/<id>/; without it, Codex session env is used when present.`;
|
|
144
|
+
function printJson(value) {
|
|
145
|
+
process.stdout.write(`${JSON.stringify(value, null, 2)}
|
|
146
|
+
`);
|
|
147
|
+
}
|
|
148
|
+
function printJsonError(error) {
|
|
149
|
+
if (error instanceof UlwLoopError) {
|
|
150
|
+
printJson({
|
|
151
|
+
ok: false,
|
|
152
|
+
error: {
|
|
153
|
+
code: error.code,
|
|
154
|
+
message: error.message,
|
|
155
|
+
...error.details === undefined ? {} : { details: error.details }
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
if (error instanceof Error) {
|
|
161
|
+
printJson({ ok: false, error: { code: "ULW_LOOP_UNEXPECTED", message: error.message } });
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
printJson({ ok: false, error: { code: "ULW_LOOP_UNKNOWN", message: "unknown error" } });
|
|
165
|
+
}
|
|
166
|
+
function criteriaCounts(goal) {
|
|
167
|
+
let pass = 0;
|
|
168
|
+
for (const criterion of goal.successCriteria)
|
|
169
|
+
if (criterion.status === "pass")
|
|
170
|
+
pass += 1;
|
|
171
|
+
return { pass, total: goal.successCriteria.length };
|
|
172
|
+
}
|
|
173
|
+
function printStatus(plan) {
|
|
174
|
+
let totalCriteria = 0;
|
|
175
|
+
let passCriteria = 0;
|
|
176
|
+
const lines = ["ulw-loop status", "", "goals:"];
|
|
177
|
+
for (const goal of plan.goals) {
|
|
178
|
+
const counts = criteriaCounts(goal);
|
|
179
|
+
totalCriteria += counts.total;
|
|
180
|
+
passCriteria += counts.pass;
|
|
181
|
+
const marker = goal.id === plan.activeGoalId ? "*" : "-";
|
|
182
|
+
lines.push(`${marker} ${goal.id} [${goal.status}] ${goal.title} (criteria: ${counts.pass}/${counts.total})`);
|
|
183
|
+
}
|
|
184
|
+
lines.push("", "summary:", `total goals: ${plan.goals.length}`, `criteria: ${passCriteria}/${totalCriteria} pass`);
|
|
185
|
+
process.stdout.write(`${lines.join(`
|
|
186
|
+
`)}
|
|
187
|
+
`);
|
|
188
|
+
}
|
|
189
|
+
function blockedDecisionHandoff(plan) {
|
|
190
|
+
const blocked = plan.goals.find((goal) => goal.status === "needs_user_decision" && goal.nonRetriable);
|
|
191
|
+
if (blocked === undefined)
|
|
192
|
+
return "";
|
|
193
|
+
return [
|
|
194
|
+
"ulw-loop: blocked on repeated external authorization; no retryable failed goals remain.",
|
|
195
|
+
`Goal: ${blocked.id} - ${blocked.title}`,
|
|
196
|
+
`Required external decision: ${blocked.requiredExternalDecision ?? "provide the missing authorization or choose a different unblock path"}.`,
|
|
197
|
+
"Do not run complete-goals --retry-failed again until external state changes or the user authorizes an unblock path."
|
|
198
|
+
].join(`
|
|
199
|
+
`);
|
|
200
|
+
}
|
|
201
|
+
function normalizeCodexGoalMode(value) {
|
|
202
|
+
if (value === undefined)
|
|
203
|
+
return "aggregate";
|
|
204
|
+
if (value === "aggregate" || value === "per_story")
|
|
205
|
+
return value;
|
|
206
|
+
throw new UlwLoopError("Invalid --codex-goal-mode; expected aggregate or per_story.", "ULW_LOOP_CODEX_GOAL_MODE_INVALID", { details: { value } });
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// components/ulw-loop/src/cli-subcommands.ts
|
|
210
|
+
import { readFile as readFile6 } from "node:fs/promises";
|
|
211
|
+
|
|
212
|
+
// components/ulw-loop/src/checkpoint.ts
|
|
213
|
+
import { existsSync as existsSync3, statSync } from "node:fs";
|
|
214
|
+
import { readFile as readFile5 } from "node:fs/promises";
|
|
215
|
+
import { resolve as resolve3 } from "node:path";
|
|
216
|
+
|
|
217
|
+
// components/ulw-loop/src/checkpoint-reconciliation.ts
|
|
218
|
+
import { existsSync } from "node:fs";
|
|
219
|
+
import { readFile as readFile2 } from "node:fs/promises";
|
|
220
|
+
|
|
221
|
+
// components/ulw-loop/src/paths.ts
|
|
222
|
+
import { join } from "node:path";
|
|
223
|
+
var SESSION_ENV_KEYS = ["OMO_ULW_LOOP_SESSION_ID", "CODEX_SESSION_ID", "CODEX_THREAD_ID"];
|
|
224
|
+
function normalizeUlwLoopSessionId(sessionId) {
|
|
225
|
+
const trimmed = sessionId?.trim();
|
|
226
|
+
if (!trimmed)
|
|
227
|
+
return null;
|
|
228
|
+
const pathSegments = trimmed.split(/[\\/]+/).filter((segment) => segment.length > 0 && segment !== "." && segment !== "..");
|
|
229
|
+
const candidate = (pathSegments.length > 0 ? pathSegments.join("-") : trimmed).replace(/[^A-Za-z0-9._-]+/g, "-").replace(/-+/g, "-").replace(/^\.+/, "").replace(/^[.-]+|[.-]+$/g, "");
|
|
230
|
+
return candidate.length > 0 ? candidate : null;
|
|
231
|
+
}
|
|
232
|
+
function resolveUlwLoopSessionIdFromEnv(env = process.env) {
|
|
233
|
+
for (const key of SESSION_ENV_KEYS) {
|
|
234
|
+
const normalized = normalizeUlwLoopSessionId(env[key]);
|
|
235
|
+
if (normalized !== null)
|
|
236
|
+
return normalized;
|
|
237
|
+
}
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
function ulwLoopRelativeDir(scope) {
|
|
241
|
+
const sessionId = normalizeUlwLoopSessionId(scope?.sessionId);
|
|
242
|
+
return sessionId === null ? ULW_LOOP_DIR : `${ULW_LOOP_DIR}/${sessionId}`;
|
|
243
|
+
}
|
|
244
|
+
function ulwLoopDir(repoRoot, scope) {
|
|
245
|
+
return join(repoRoot, ulwLoopRelativeDir(scope));
|
|
246
|
+
}
|
|
247
|
+
function ulwLoopBriefRelativePath(scope) {
|
|
248
|
+
return `${ulwLoopRelativeDir(scope)}/${ULW_LOOP_BRIEF}`;
|
|
249
|
+
}
|
|
250
|
+
function ulwLoopGoalsRelativePath(scope) {
|
|
251
|
+
return `${ulwLoopRelativeDir(scope)}/${ULW_LOOP_GOALS}`;
|
|
252
|
+
}
|
|
253
|
+
function ulwLoopLedgerRelativePath(scope) {
|
|
254
|
+
return `${ulwLoopRelativeDir(scope)}/${ULW_LOOP_LEDGER}`;
|
|
255
|
+
}
|
|
256
|
+
function ulwLoopBriefPath(repoRoot, scope) {
|
|
257
|
+
return join(ulwLoopDir(repoRoot, scope), ULW_LOOP_BRIEF);
|
|
258
|
+
}
|
|
259
|
+
function ulwLoopGoalsPath(repoRoot, scope) {
|
|
260
|
+
return join(ulwLoopDir(repoRoot, scope), ULW_LOOP_GOALS);
|
|
261
|
+
}
|
|
262
|
+
function ulwLoopLedgerPath(repoRoot, scope) {
|
|
263
|
+
return join(ulwLoopDir(repoRoot, scope), ULW_LOOP_LEDGER);
|
|
264
|
+
}
|
|
265
|
+
function repoRelative(absolutePath, repoRoot) {
|
|
266
|
+
const slashPrefix = `${repoRoot}/`;
|
|
267
|
+
const backslashPrefix = `${repoRoot}\\`;
|
|
268
|
+
if (absolutePath.startsWith(slashPrefix))
|
|
269
|
+
return absolutePath.slice(slashPrefix.length).split("\\").join("/");
|
|
270
|
+
if (absolutePath.startsWith(backslashPrefix))
|
|
271
|
+
return absolutePath.slice(backslashPrefix.length).split("\\").join("/");
|
|
272
|
+
return absolutePath.split("\\").join("/");
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
// components/ulw-loop/src/goal-status.ts
|
|
276
|
+
var ULW_LOOP_AGGREGATE_CODEX_OBJECTIVE = aggregateCodexObjectiveForScope();
|
|
277
|
+
function aggregateCodexObjectiveForScope(scope) {
|
|
278
|
+
return `Complete the durable ulw-loop plan in ${ulwLoopGoalsRelativePath(scope)}, including later accepted/appended stories, under the original brief constraints; use ${ulwLoopLedgerRelativePath(scope)} as the audit trail.`;
|
|
279
|
+
}
|
|
280
|
+
function codexGoalMode(plan) {
|
|
281
|
+
return plan.codexGoalMode ?? "per_story";
|
|
282
|
+
}
|
|
283
|
+
function isResolvedStatus(status) {
|
|
284
|
+
return status === "complete";
|
|
285
|
+
}
|
|
286
|
+
function isSupersededResolved(goal, plan) {
|
|
287
|
+
if (goal.steeringStatus !== "superseded")
|
|
288
|
+
return false;
|
|
289
|
+
const replacements = goal.supersededBy ?? [];
|
|
290
|
+
if (replacements.length === 0)
|
|
291
|
+
return false;
|
|
292
|
+
return replacements.every((id) => {
|
|
293
|
+
const replacement = plan.goals.find((candidate) => candidate.id === id);
|
|
294
|
+
return replacement !== undefined && isResolvedStatus(replacement.status);
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
function isCompletionBlocking(goal, plan) {
|
|
298
|
+
if (goal.steeringStatus === "superseded")
|
|
299
|
+
return !isSupersededResolved(goal, plan);
|
|
300
|
+
if (goal.steeringStatus === "blocked")
|
|
301
|
+
return true;
|
|
302
|
+
return !isResolvedStatus(goal.status);
|
|
303
|
+
}
|
|
304
|
+
function isCompletionBlockingForFinalCandidate(candidate, finalCandidate, plan) {
|
|
305
|
+
if (candidate.id === finalCandidate.id)
|
|
306
|
+
return false;
|
|
307
|
+
if (candidate.steeringStatus === "superseded") {
|
|
308
|
+
const replacements = candidate.supersededBy ?? [];
|
|
309
|
+
if (replacements.length === 0)
|
|
310
|
+
return true;
|
|
311
|
+
return !replacements.every((id) => {
|
|
312
|
+
if (id === finalCandidate.id)
|
|
313
|
+
return true;
|
|
314
|
+
const replacement = plan.goals.find((goal) => goal.id === id);
|
|
315
|
+
return replacement !== undefined && isResolvedStatus(replacement.status);
|
|
316
|
+
});
|
|
317
|
+
}
|
|
318
|
+
return isCompletionBlocking(candidate, plan);
|
|
319
|
+
}
|
|
320
|
+
function isUlwLoopDone(plan) {
|
|
321
|
+
if (plan.aggregateCompletion?.status === "complete")
|
|
322
|
+
return true;
|
|
323
|
+
return plan.goals.every((goal) => !isCompletionBlocking(goal, plan));
|
|
324
|
+
}
|
|
325
|
+
function isFinalRunCompletionCandidate(plan, goal) {
|
|
326
|
+
return isCompletionBlocking(goal, plan) && plan.goals.every((candidate) => !isCompletionBlockingForFinalCandidate(candidate, goal, plan));
|
|
327
|
+
}
|
|
328
|
+
function aggregateCodexObjective(plan) {
|
|
329
|
+
return plan.codexObjective ?? ULW_LOOP_AGGREGATE_CODEX_OBJECTIVE;
|
|
330
|
+
}
|
|
331
|
+
function expectedCodexObjective(plan, goal) {
|
|
332
|
+
return codexGoalMode(plan) === "aggregate" ? aggregateCodexObjective(plan) : goal.objective;
|
|
333
|
+
}
|
|
334
|
+
function compatibleCodexObjectives(plan) {
|
|
335
|
+
return [aggregateCodexObjective(plan), ...plan.codexObjectiveAliases ?? []];
|
|
336
|
+
}
|
|
337
|
+
function hasAllCriteriaPass(goal) {
|
|
338
|
+
return goal.successCriteria.length > 0 && goal.successCriteria.every((criterion) => criterion.status === "pass");
|
|
339
|
+
}
|
|
340
|
+
function isEssentialCriterion(criterion) {
|
|
341
|
+
return criterion.essential ?? true;
|
|
342
|
+
}
|
|
343
|
+
function essentialCriteriaOf(goal) {
|
|
344
|
+
const explicit = goal.successCriteria.filter(isEssentialCriterion);
|
|
345
|
+
if (explicit.length > 0)
|
|
346
|
+
return explicit;
|
|
347
|
+
const happy = goal.successCriteria.find((criterion) => criterion.userModel === "happy");
|
|
348
|
+
return happy === undefined ? [] : [happy];
|
|
349
|
+
}
|
|
350
|
+
function hasEssentialCriteriaPass(goal) {
|
|
351
|
+
const criteria = essentialCriteriaOf(goal);
|
|
352
|
+
return criteria.length > 0 && criteria.every((criterion) => criterion.status === "pass");
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// components/ulw-loop/src/checkpoint-reconciliation.ts
|
|
356
|
+
function normalizeObjective(value) {
|
|
357
|
+
return value.replace(/\s+/g, " ").trim();
|
|
358
|
+
}
|
|
359
|
+
function textMentionsUlwLoopPlanArtifact(value) {
|
|
360
|
+
const normalized = (value ?? "").toLowerCase();
|
|
361
|
+
return normalized.includes(ULW_LOOP_DIR.toLowerCase()) || normalized.includes(ULW_LOOP_GOALS.toLowerCase()) || normalized.includes(ULW_LOOP_LEDGER.toLowerCase());
|
|
362
|
+
}
|
|
363
|
+
function textMentionsGoalId(value, goalId) {
|
|
364
|
+
return (value ?? "").toLowerCase().includes(goalId.toLowerCase());
|
|
365
|
+
}
|
|
366
|
+
function textHasCompletionValidationEvidence(value) {
|
|
367
|
+
const normalized = (value ?? "").toLowerCase();
|
|
368
|
+
const done = /\b(?:planned work|implementation|deliverables?|scope|task|work)\b/.test(normalized) && /\b(?:done|complete|completed|finished|shipped)\b/.test(normalized);
|
|
369
|
+
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);
|
|
370
|
+
return done && verified;
|
|
371
|
+
}
|
|
372
|
+
async function snapshotObjectiveMapsToUlwLoopPlan(repoRoot, snapshotObjective, scope) {
|
|
373
|
+
const actual = normalizeObjective(snapshotObjective).toLowerCase();
|
|
374
|
+
if (textMentionsUlwLoopPlanArtifact(actual))
|
|
375
|
+
return true;
|
|
376
|
+
if (actual.length < 24 || !existsSync(ulwLoopBriefPath(repoRoot, scope)))
|
|
377
|
+
return false;
|
|
378
|
+
try {
|
|
379
|
+
const brief = normalizeObjective(await readFile2(ulwLoopBriefPath(repoRoot, scope), "utf8")).toLowerCase();
|
|
380
|
+
return brief.length >= 24 && (brief.includes(actual) || actual.includes(brief));
|
|
381
|
+
} catch (error) {
|
|
382
|
+
if (error instanceof Error)
|
|
383
|
+
return false;
|
|
384
|
+
throw error;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
async function canReconcileCompletedTaskScopedAggregateSnapshot(repoRoot, plan, goal, snapshotObjective, evidence, scope) {
|
|
388
|
+
if (codexGoalMode(plan) !== "aggregate")
|
|
389
|
+
return false;
|
|
390
|
+
if (goal.status !== "in_progress" || plan.activeGoalId !== goal.id)
|
|
391
|
+
return false;
|
|
392
|
+
if (isFinalRunCompletionCandidate(plan, goal)) {
|
|
393
|
+
return snapshotObjectiveMapsToUlwLoopPlan(repoRoot, snapshotObjective, scope);
|
|
394
|
+
}
|
|
395
|
+
if (!textMentionsUlwLoopPlanArtifact(evidence) || !textMentionsGoalId(evidence, goal.id))
|
|
396
|
+
return false;
|
|
397
|
+
if (!textHasCompletionValidationEvidence(evidence))
|
|
398
|
+
return false;
|
|
399
|
+
return snapshotObjectiveMapsToUlwLoopPlan(repoRoot, snapshotObjective, scope);
|
|
400
|
+
}
|
|
401
|
+
async function canReconcileActiveFinalTaskScopedAggregateSnapshot(repoRoot, plan, goal, snapshotObjective, evidence, scope) {
|
|
402
|
+
if (codexGoalMode(plan) !== "aggregate")
|
|
403
|
+
return false;
|
|
404
|
+
if (goal.status !== "in_progress" || plan.activeGoalId !== goal.id)
|
|
405
|
+
return false;
|
|
406
|
+
if (!isFinalRunCompletionCandidate(plan, goal))
|
|
407
|
+
return false;
|
|
408
|
+
if (!textHasCompletionValidationEvidence(evidence))
|
|
409
|
+
return false;
|
|
410
|
+
return snapshotObjectiveMapsToUlwLoopPlan(repoRoot, snapshotObjective, scope);
|
|
411
|
+
}
|
|
412
|
+
function buildCompletedLegacyGoalRemediation(goal) {
|
|
413
|
+
return [
|
|
414
|
+
"If get_goal returns a different completed legacy/thread objective, do not repeat --status complete in this thread.",
|
|
415
|
+
`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>".`,
|
|
416
|
+
"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."
|
|
417
|
+
].join(" ");
|
|
418
|
+
}
|
|
419
|
+
function buildTaskScopedAggregateReconciliationHint(goal, final) {
|
|
420
|
+
if (final) {
|
|
421
|
+
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)}`;
|
|
422
|
+
}
|
|
423
|
+
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)}`;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// components/ulw-loop/src/codex-goal-snapshot.ts
|
|
427
|
+
import { existsSync as existsSync2 } from "node:fs";
|
|
428
|
+
import { readFile as readFile3 } from "node:fs/promises";
|
|
429
|
+
import { resolve } from "node:path";
|
|
430
|
+
|
|
431
|
+
class CodexGoalSnapshotError extends Error {
|
|
432
|
+
}
|
|
433
|
+
function safeObject(value) {
|
|
434
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
435
|
+
}
|
|
436
|
+
function safeString(value) {
|
|
437
|
+
return typeof value === "string" ? value.trim() : "";
|
|
438
|
+
}
|
|
439
|
+
function normalizeStatus(value) {
|
|
440
|
+
const status = safeString(value).toLowerCase();
|
|
441
|
+
if (status === "complete" || status === "completed" || status === "done")
|
|
442
|
+
return "complete";
|
|
443
|
+
if (status === "cancelled" || status === "canceled")
|
|
444
|
+
return "cancelled";
|
|
445
|
+
if (status === "failed" || status === "failure")
|
|
446
|
+
return "failed";
|
|
447
|
+
if (status === "active" || status === "in_progress" || status === "pending" || status === "running")
|
|
448
|
+
return "active";
|
|
449
|
+
return "unknown";
|
|
450
|
+
}
|
|
451
|
+
function normalizeObjective2(value) {
|
|
452
|
+
return value.replace(/\s+/g, " ").trim();
|
|
453
|
+
}
|
|
454
|
+
function parseCodexGoalSnapshot(value) {
|
|
455
|
+
const root = safeObject(value);
|
|
456
|
+
const goalValue = Object.hasOwn(root, "goal") ? root["goal"] : value;
|
|
457
|
+
if (goalValue === null || goalValue === undefined || goalValue === false) {
|
|
458
|
+
return { available: false, raw: value };
|
|
459
|
+
}
|
|
460
|
+
const goal = safeObject(goalValue);
|
|
461
|
+
const objective = safeString(goal["objective"] ?? goal["goal"] ?? goal["description"] ?? root["objective"]);
|
|
462
|
+
const status = normalizeStatus(goal["status"] ?? root["status"]);
|
|
463
|
+
return {
|
|
464
|
+
available: Boolean(objective || status !== "unknown"),
|
|
465
|
+
...objective ? { objective } : {},
|
|
466
|
+
status,
|
|
467
|
+
raw: value
|
|
468
|
+
};
|
|
469
|
+
}
|
|
470
|
+
async function readCodexGoalSnapshotInput(raw, cwd = process.cwd()) {
|
|
471
|
+
if (!raw?.trim())
|
|
472
|
+
return null;
|
|
473
|
+
const trimmed = raw.trim();
|
|
474
|
+
try {
|
|
475
|
+
return parseCodexGoalSnapshot(JSON.parse(trimmed));
|
|
476
|
+
} catch {
|
|
477
|
+
const path = resolve(cwd, trimmed);
|
|
478
|
+
if (!existsSync2(path)) {
|
|
479
|
+
throw new CodexGoalSnapshotError(`Codex goal snapshot is neither valid JSON nor a readable path: ${trimmed}`);
|
|
480
|
+
}
|
|
481
|
+
try {
|
|
482
|
+
return parseCodexGoalSnapshot(JSON.parse(await readFile3(path, "utf-8")));
|
|
483
|
+
} catch (error) {
|
|
484
|
+
throw new CodexGoalSnapshotError(`Codex goal snapshot path does not contain valid JSON: ${trimmed}${error instanceof Error ? ` (${error.message})` : ""}`);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
function reconcileCodexGoalSnapshot(snapshot, options) {
|
|
489
|
+
const effectiveSnapshot = snapshot ?? { available: false, raw: null };
|
|
490
|
+
const errors = [];
|
|
491
|
+
const warnings = [];
|
|
492
|
+
if (!effectiveSnapshot.available) {
|
|
493
|
+
const message = "Codex goal snapshot is absent or reports no active goal; call get_goal and pass its JSON with --codex-goal-json.";
|
|
494
|
+
if (options.requireSnapshot)
|
|
495
|
+
errors.push(message);
|
|
496
|
+
else
|
|
497
|
+
warnings.push(message);
|
|
498
|
+
return { ok: errors.length === 0, snapshot: effectiveSnapshot, warnings, errors };
|
|
499
|
+
}
|
|
500
|
+
const expected = normalizeObjective2(options.expectedObjective);
|
|
501
|
+
const accepted = new Set([expected, ...(options.acceptedObjectives ?? []).map((objective) => normalizeObjective2(objective))].filter(Boolean));
|
|
502
|
+
const actual = normalizeObjective2(effectiveSnapshot.objective ?? "");
|
|
503
|
+
if (!actual) {
|
|
504
|
+
errors.push("Codex goal snapshot is missing objective text.");
|
|
505
|
+
} else if (!accepted.has(actual)) {
|
|
506
|
+
errors.push(`Codex goal objective mismatch: expected "${expected}", got "${actual}".`);
|
|
507
|
+
}
|
|
508
|
+
const allowed = options.allowedStatuses ?? (options.requireComplete ? ["complete"] : ["active", "complete"]);
|
|
509
|
+
const actualStatus = effectiveSnapshot.status ?? "unknown";
|
|
510
|
+
if (!allowed.includes(actualStatus)) {
|
|
511
|
+
errors.push(`Codex goal status mismatch: expected ${allowed.join(" or ")}, got ${actualStatus}.`);
|
|
512
|
+
}
|
|
513
|
+
if (options.requireComplete && actualStatus !== "complete") {
|
|
514
|
+
errors.push('Codex goal is not complete; call update_goal({status: "complete"}) only after the objective is actually complete, then pass the fresh get_goal JSON.');
|
|
515
|
+
}
|
|
516
|
+
return { ok: errors.length === 0, snapshot: effectiveSnapshot, warnings, errors };
|
|
517
|
+
}
|
|
518
|
+
function formatCodexGoalReconciliation(reconciliation) {
|
|
519
|
+
const parts = [...reconciliation.errors, ...reconciliation.warnings];
|
|
520
|
+
return parts.join(" ");
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
// components/ulw-loop/src/plan-io.ts
|
|
524
|
+
import { appendFile, mkdir, readFile as readFile4, rename, writeFile } from "node:fs/promises";
|
|
525
|
+
var LEGACY_OBJECTIVE_PREFIX = `Complete all ulw-loop stories in ${ULW_LOOP_DIR}/${ULW_LOOP_GOALS}: `;
|
|
526
|
+
var LEGACY_OBJECTIVE = `Complete all ulw-loop stories listed in ${ULW_LOOP_DIR}/${ULW_LOOP_GOALS}. Use ${ULW_LOOP_DIR}/${ULW_LOOP_LEDGER} as the durable audit trail.`;
|
|
527
|
+
var locks = new Map;
|
|
528
|
+
function hasCode(error, code) {
|
|
529
|
+
return error instanceof Error && "code" in error && error.code === code;
|
|
530
|
+
}
|
|
531
|
+
function isLegacyEnumeratedAggregateObjective(objective) {
|
|
532
|
+
return objective === LEGACY_OBJECTIVE || Boolean(objective?.startsWith(LEGACY_OBJECTIVE_PREFIX));
|
|
533
|
+
}
|
|
534
|
+
function isSteeringKind(value) {
|
|
535
|
+
return value === "steering_accepted" || value === "steering_rejected" || value === "criteria_revised";
|
|
536
|
+
}
|
|
537
|
+
async function withUlwLoopMutationLock(repoRoot, scopeOrFn, maybeFn) {
|
|
538
|
+
const scope = typeof scopeOrFn === "function" ? undefined : scopeOrFn;
|
|
539
|
+
const fn = typeof scopeOrFn === "function" ? scopeOrFn : maybeFn;
|
|
540
|
+
if (fn === undefined)
|
|
541
|
+
throw new UlwLoopError("Missing ulw-loop mutation body.", "ULW_LOOP_LOCK_BODY_MISSING");
|
|
542
|
+
const lockKey = `${repoRoot}\x00${ulwLoopRelativeDir(scope)}`;
|
|
543
|
+
const prior = locks.get(lockKey) ?? Promise.resolve();
|
|
544
|
+
const run = prior.then(fn, fn);
|
|
545
|
+
locks.set(lockKey, run.catch(() => {
|
|
546
|
+
return;
|
|
547
|
+
}));
|
|
548
|
+
return run;
|
|
549
|
+
}
|
|
550
|
+
async function readUlwLoopPlan(repoRoot, scope) {
|
|
551
|
+
const path = ulwLoopGoalsPath(repoRoot, scope);
|
|
552
|
+
let raw;
|
|
553
|
+
try {
|
|
554
|
+
raw = await readFile4(path, "utf8");
|
|
555
|
+
} catch (error) {
|
|
556
|
+
if (!hasCode(error, "ENOENT"))
|
|
557
|
+
throw error;
|
|
558
|
+
throw new UlwLoopError(`No ulw-loop plan found at ${repoRelative(path, repoRoot)}. Run \`omo ulw-loop create-goals ...\` first.`, "ULW_LOOP_PLAN_MISSING", { cause: error });
|
|
559
|
+
}
|
|
560
|
+
const parsed = JSON.parse(raw);
|
|
561
|
+
if (parsed.version !== 1 || !Array.isArray(parsed.goals)) {
|
|
562
|
+
throw new UlwLoopError(`Invalid ulw-loop plan at ${repoRelative(path, repoRoot)}.`, "ULW_LOOP_PLAN_INVALID");
|
|
563
|
+
}
|
|
564
|
+
const previousObjective = parsed.codexObjective;
|
|
565
|
+
if ((parsed.codexGoalMode ?? "per_story") === "aggregate" && isLegacyEnumeratedAggregateObjective(previousObjective)) {
|
|
566
|
+
const now = iso();
|
|
567
|
+
parsed.codexObjective = aggregateCodexObjectiveForScope(scope);
|
|
568
|
+
parsed.codexObjectiveAliases = [...new Set([...parsed.codexObjectiveAliases ?? [], previousObjective])];
|
|
569
|
+
parsed.updatedAt = now;
|
|
570
|
+
await writePlan(repoRoot, parsed, scope);
|
|
571
|
+
await appendLedger(repoRoot, {
|
|
572
|
+
at: now,
|
|
573
|
+
kind: "aggregate_objective_migrated",
|
|
574
|
+
message: "Migrated legacy enumerated aggregate Codex objective to the stable pointer objective.",
|
|
575
|
+
before: { codexObjective: previousObjective },
|
|
576
|
+
after: { codexObjective: parsed.codexObjective }
|
|
577
|
+
}, scope);
|
|
578
|
+
}
|
|
579
|
+
return parsed;
|
|
580
|
+
}
|
|
581
|
+
async function writePlan(repoRoot, plan, scope) {
|
|
582
|
+
await mkdir(ulwLoopDir(repoRoot, scope), { recursive: true });
|
|
583
|
+
const path = ulwLoopGoalsPath(repoRoot, scope);
|
|
584
|
+
const tmpPath = `${path}.${process.pid}.${Date.now()}.tmp`;
|
|
585
|
+
await writeFile(tmpPath, `${JSON.stringify(plan, null, 2)}
|
|
586
|
+
`, "utf8");
|
|
587
|
+
await rename(tmpPath, path);
|
|
588
|
+
}
|
|
589
|
+
async function appendLedger(repoRoot, entry, scope) {
|
|
590
|
+
await mkdir(ulwLoopDir(repoRoot, scope), { recursive: true });
|
|
591
|
+
await appendFile(ulwLoopLedgerPath(repoRoot, scope), `${JSON.stringify(entry)}
|
|
592
|
+
`, "utf8");
|
|
593
|
+
}
|
|
594
|
+
async function readSteeringLedgerEntries(repoRoot, scope) {
|
|
595
|
+
let raw;
|
|
596
|
+
try {
|
|
597
|
+
raw = await readFile4(ulwLoopLedgerPath(repoRoot, scope), "utf8");
|
|
598
|
+
} catch (error) {
|
|
599
|
+
if (hasCode(error, "ENOENT"))
|
|
600
|
+
return [];
|
|
601
|
+
throw error;
|
|
602
|
+
}
|
|
603
|
+
const entries = [];
|
|
604
|
+
for (const line of raw.split(/\r?\n/).filter(Boolean)) {
|
|
605
|
+
const entry = JSON.parse(line);
|
|
606
|
+
if (isSteeringKind(entry.kind))
|
|
607
|
+
entries.push(entry);
|
|
608
|
+
}
|
|
609
|
+
return entries;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// components/ulw-loop/src/evidence.ts
|
|
613
|
+
function ulwLoopFail(message, code, details) {
|
|
614
|
+
throw new UlwLoopError(message, code, { details });
|
|
615
|
+
}
|
|
616
|
+
function ledgerKind(status) {
|
|
617
|
+
switch (status) {
|
|
618
|
+
case "pass":
|
|
619
|
+
return "evidence_captured";
|
|
620
|
+
case "fail":
|
|
621
|
+
return "criterion_failed";
|
|
622
|
+
case "blocked":
|
|
623
|
+
return "criterion_blocked";
|
|
624
|
+
default:
|
|
625
|
+
return ulwLoopFail("Invalid criterion status.", "ULW_LOOP_CRITERION_STATUS_INVALID", { status });
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
function findGoal(plan, goalId) {
|
|
629
|
+
const goal = plan.goals.find((candidate) => candidate.id === goalId);
|
|
630
|
+
return goal ?? ulwLoopFail(`UlwLoop goal not found: ${goalId}.`, "ULW_LOOP_GOAL_NOT_FOUND", { goalId });
|
|
631
|
+
}
|
|
632
|
+
function findCriterion(goal, criterionId) {
|
|
633
|
+
const criterion = goal.successCriteria.find((candidate) => candidate.id === criterionId);
|
|
634
|
+
return criterion ?? ulwLoopFail(`Success criterion not found: ${criterionId}.`, "ULW_LOOP_CRITERION_NOT_FOUND", {
|
|
635
|
+
goalId: goal.id,
|
|
636
|
+
criterionId
|
|
637
|
+
});
|
|
638
|
+
}
|
|
639
|
+
function nonEmptyEvidence(evidence) {
|
|
640
|
+
const trimmed = evidence.trim();
|
|
641
|
+
return trimmed || ulwLoopFail("Evidence must be a non-empty string.", "ULW_LOOP_EVIDENCE_REQUIRED", {});
|
|
642
|
+
}
|
|
643
|
+
async function recordEvidence(repoRoot, args, scope) {
|
|
644
|
+
return withUlwLoopMutationLock(repoRoot, scope, async () => {
|
|
645
|
+
const plan = await readUlwLoopPlan(repoRoot, scope);
|
|
646
|
+
const goal = findGoal(plan, args.goalId);
|
|
647
|
+
const criterion = findCriterion(goal, args.criterionId);
|
|
648
|
+
const evidence = nonEmptyEvidence(args.evidence);
|
|
649
|
+
const kind = ledgerKind(args.status);
|
|
650
|
+
const prevStatus = criterion.status;
|
|
651
|
+
const capturedAt = iso();
|
|
652
|
+
criterion.status = args.status;
|
|
653
|
+
criterion.capturedEvidence = evidence;
|
|
654
|
+
criterion.capturedAt = capturedAt;
|
|
655
|
+
if (args.notes !== undefined)
|
|
656
|
+
criterion.notes = args.notes;
|
|
657
|
+
goal.updatedAt = capturedAt;
|
|
658
|
+
plan.updatedAt = capturedAt;
|
|
659
|
+
await writePlan(repoRoot, plan, scope);
|
|
660
|
+
const ledgerEntry = {
|
|
661
|
+
at: capturedAt,
|
|
662
|
+
kind,
|
|
663
|
+
goalId: goal.id,
|
|
664
|
+
criterionId: criterion.id,
|
|
665
|
+
criterionStatus: args.status,
|
|
666
|
+
evidence,
|
|
667
|
+
capturedEvidence: evidence,
|
|
668
|
+
before: { status: prevStatus },
|
|
669
|
+
after: { goalId: goal.id, criterionId: criterion.id, status: args.status, evidence, capturedAt, prevStatus }
|
|
670
|
+
};
|
|
671
|
+
await appendLedger(repoRoot, ledgerEntry, scope);
|
|
672
|
+
return { plan, goal, criterion, ledgerEntry };
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
function unresolvedCriteriaOf(goal) {
|
|
676
|
+
return goal.successCriteria.filter((criterion) => criterion.status !== "pass");
|
|
677
|
+
}
|
|
678
|
+
function unresolvedEssentialCriteriaOf(goal) {
|
|
679
|
+
const essentialCriteria = new Set(essentialCriteriaOf(goal).map((criterion) => criterion.id));
|
|
680
|
+
return goal.successCriteria.filter((criterion) => essentialCriteria.has(criterion.id) && criterion.status !== "pass");
|
|
681
|
+
}
|
|
682
|
+
function requireAllCriteriaPass(goal) {
|
|
683
|
+
if (hasAllCriteriaPass(goal))
|
|
684
|
+
return;
|
|
685
|
+
throw new UlwLoopError(`Goal ${goal.id} has unresolved success criteria.`, "ulw_loop_criteria_not_all_pass", {
|
|
686
|
+
details: {
|
|
687
|
+
goalId: goal.id,
|
|
688
|
+
unresolved: unresolvedCriteriaOf(goal).map((criterion) => ({ id: criterion.id, status: criterion.status }))
|
|
689
|
+
}
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
function requireAllPlanCriteriaPass(plan) {
|
|
693
|
+
const unresolved = plan.goals.flatMap((goal) => unresolvedCriteriaOf(goal).map((criterion) => ({
|
|
694
|
+
goalId: goal.id,
|
|
695
|
+
id: criterion.id,
|
|
696
|
+
status: criterion.status
|
|
697
|
+
})));
|
|
698
|
+
if (unresolved.length === 0)
|
|
699
|
+
return;
|
|
700
|
+
throw new UlwLoopError("Ulw-loop aggregate has unresolved success criteria.", "ulw_loop_criteria_not_all_pass", {
|
|
701
|
+
details: { unresolved }
|
|
702
|
+
});
|
|
703
|
+
}
|
|
704
|
+
function requireEssentialCriteriaPass(goal) {
|
|
705
|
+
if (hasEssentialCriteriaPass(goal))
|
|
706
|
+
return;
|
|
707
|
+
throw new UlwLoopError(`Goal ${goal.id} has unresolved essential success criteria.`, "ulw_loop_criteria_not_all_pass", {
|
|
708
|
+
details: {
|
|
709
|
+
goalId: goal.id,
|
|
710
|
+
unresolved: unresolvedEssentialCriteriaOf(goal).map((criterion) => ({
|
|
711
|
+
id: criterion.id,
|
|
712
|
+
status: criterion.status
|
|
713
|
+
}))
|
|
714
|
+
}
|
|
715
|
+
});
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
// components/ulw-loop/src/quality-gate.ts
|
|
719
|
+
import { resolve as resolve2 } from "node:path";
|
|
720
|
+
|
|
721
|
+
// components/ulw-loop/src/quality-gate-fields.ts
|
|
722
|
+
var PLACEHOLDER_PATTERN = /^(?:placeholder|todo|tbd|n\/a|stub)$/i;
|
|
723
|
+
function invalid(message, field) {
|
|
724
|
+
throw new UlwLoopError(message, "ULW_LOOP_QUALITY_GATE_INVALID", { details: { field } });
|
|
725
|
+
}
|
|
726
|
+
function isRecord(value) {
|
|
727
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
728
|
+
}
|
|
729
|
+
function section(value, field) {
|
|
730
|
+
return isRecord(value) ? value : invalid(`Final quality gate is missing ${field} evidence.`, field);
|
|
731
|
+
}
|
|
732
|
+
function textField(value, field) {
|
|
733
|
+
if (typeof value !== "string" || value.trim() === "")
|
|
734
|
+
invalid(`Final quality gate requires non-empty ${field}.`, field);
|
|
735
|
+
const trimmed = value.trim();
|
|
736
|
+
if (PLACEHOLDER_PATTERN.test(trimmed))
|
|
737
|
+
invalid(`Final quality gate rejects placeholder ${field}.`, field);
|
|
738
|
+
return trimmed;
|
|
739
|
+
}
|
|
740
|
+
function numberField(value, field) {
|
|
741
|
+
return typeof value === "number" && Number.isFinite(value) ? value : invalid(`Final quality gate requires numeric ${field}.`, field);
|
|
742
|
+
}
|
|
743
|
+
function stringArray(value, field) {
|
|
744
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
745
|
+
return invalid(`Final quality gate requires ${field}.`, field);
|
|
746
|
+
return value.map((item) => textField(item, field));
|
|
747
|
+
}
|
|
748
|
+
function emptyBlockers(value, field) {
|
|
749
|
+
if (Array.isArray(value) && value.length === 0)
|
|
750
|
+
return [];
|
|
751
|
+
invalid(`${field} must be empty.`, field);
|
|
752
|
+
}
|
|
753
|
+
function literal(value, expected, field) {
|
|
754
|
+
if (value === expected)
|
|
755
|
+
return expected;
|
|
756
|
+
invalid(`${field} must be ${String(expected)}.`, field);
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
// components/ulw-loop/src/quality-gate-blockers.ts
|
|
760
|
+
var BLOCKER_FIELD_KEYS = "blocker blockerSignature blockerEvidence blockerOccurrences blockedAt".split(" ");
|
|
761
|
+
var URL_PATTERN = /https?:\/\/\S+/g;
|
|
762
|
+
var PUNCTUATION_PATTERN = /[`"'()[\]{}:,;]/g;
|
|
763
|
+
var WHITESPACE_PATTERN = /\s+/g;
|
|
764
|
+
var AUTH_PATTERN = /\b(auth\w*|credential\w*|token|permission\w*|scope\w*|access|unauthorized|forbidden|401|403)\b/;
|
|
765
|
+
var MISSING_PATTERN = /\b(unset|missing|required|requires|without|omit\w*|not set|not available|no read packages|read packages)\b/;
|
|
766
|
+
var GHCR_PATTERN = /\b(ghcr|github container registry|read packages|imagepullsecret|package api|anonymous|container image)\b/;
|
|
767
|
+
var GHCR_401_PATTERN = /\b(401|unauthorized|anonymous pull|authentication required)\b/;
|
|
768
|
+
var GHCR_403_PATTERN = /\b(403|forbidden|read packages|package api)\b/;
|
|
769
|
+
function isRecord2(value) {
|
|
770
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
771
|
+
}
|
|
772
|
+
function normalizeBlockerEvidence(evidence) {
|
|
773
|
+
const withoutUrls = evidence.toLowerCase().replace(URL_PATTERN, " ");
|
|
774
|
+
const withoutPunctuation = withoutUrls.replace(PUNCTUATION_PATTERN, " ");
|
|
775
|
+
return withoutPunctuation.replace(WHITESPACE_PATTERN, " ").trim();
|
|
776
|
+
}
|
|
777
|
+
function classifyExternalAuthorizationBlocker(evidence) {
|
|
778
|
+
const normalized = normalizeBlockerEvidence(evidence);
|
|
779
|
+
if (!normalized || !AUTH_PATTERN.test(normalized) || !MISSING_PATTERN.test(normalized))
|
|
780
|
+
return null;
|
|
781
|
+
if (!GHCR_PATTERN.test(normalized))
|
|
782
|
+
return "EXTERNAL_AUTHORIZATION_REQUIRED";
|
|
783
|
+
const status401 = GHCR_401_PATTERN.test(normalized) ? "HTTP_401_ANONYMOUS" : null;
|
|
784
|
+
const status403 = GHCR_403_PATTERN.test(normalized) ? "HTTP_403_NO_READ_PACKAGES" : null;
|
|
785
|
+
const status = [status401, status403].filter((part) => part !== null).join("+");
|
|
786
|
+
return `GHCR_PULL_ACCESS:${status || "AUTHORIZATION_REQUIRED"}:GHCR_VISIBILITY_OR_CREDENTIAL_REQUIRED`;
|
|
787
|
+
}
|
|
788
|
+
function nestedBlockerSignature(goal) {
|
|
789
|
+
const blocker = Reflect.get(goal, "blocker");
|
|
790
|
+
const signature = isRecord2(blocker) ? blocker["signature"] : null;
|
|
791
|
+
return typeof signature === "string" ? signature : null;
|
|
792
|
+
}
|
|
793
|
+
function sameBlockerOccurrences(plan, signature) {
|
|
794
|
+
return plan.goals.filter((goal) => goal.blockerSignature === signature || nestedBlockerSignature(goal) === signature).length;
|
|
795
|
+
}
|
|
796
|
+
function clearGoalBlockerFields(goal) {
|
|
797
|
+
for (const key of BLOCKER_FIELD_KEYS)
|
|
798
|
+
Reflect.deleteProperty(goal, key);
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// components/ulw-loop/src/quality-gate.ts
|
|
802
|
+
var REVIEWER_ROLES = {
|
|
803
|
+
codeReview: "lazycodex-code-reviewer",
|
|
804
|
+
manualQa: "lazycodex-qa-executor",
|
|
805
|
+
gateReview: "lazycodex-gate-reviewer"
|
|
806
|
+
};
|
|
807
|
+
function reviewerRoleField(value, expected, field) {
|
|
808
|
+
const actual = textField(value, field);
|
|
809
|
+
if (actual !== expected)
|
|
810
|
+
invalid(`${field} must be ${expected}.`, field);
|
|
811
|
+
return expected;
|
|
812
|
+
}
|
|
813
|
+
function surfaceField(value, field) {
|
|
814
|
+
if (value === "cli" || value === "http" || value === "tmux" || value === "browser" || value === "gui" || value === "data")
|
|
815
|
+
return value;
|
|
816
|
+
invalid(`${field} must be a supported manual QA surface.`, field);
|
|
817
|
+
}
|
|
818
|
+
function kindField(value, field) {
|
|
819
|
+
if (value === "cli-transcript" || value === "log" || value === "screenshot" || value === "image" || value === "http-dump" || value === "data-diff")
|
|
820
|
+
return value;
|
|
821
|
+
invalid(`${field} must be a supported artifact kind.`, field);
|
|
822
|
+
}
|
|
823
|
+
function passedVerdict(value, field) {
|
|
824
|
+
if (value === "not_applicable")
|
|
825
|
+
invalid(`${field} must not be not_applicable.`, field);
|
|
826
|
+
return literal(value, "passed", field);
|
|
827
|
+
}
|
|
828
|
+
function artifactCompatible(surface, kind) {
|
|
829
|
+
switch (surface) {
|
|
830
|
+
case "cli":
|
|
831
|
+
case "tmux":
|
|
832
|
+
return kind === "cli-transcript" || kind === "log";
|
|
833
|
+
case "http":
|
|
834
|
+
return kind === "http-dump";
|
|
835
|
+
case "browser":
|
|
836
|
+
case "gui":
|
|
837
|
+
return kind === "screenshot" || kind === "image";
|
|
838
|
+
case "data":
|
|
839
|
+
return kind === "data-diff";
|
|
840
|
+
default:
|
|
841
|
+
invalid("manualQa.surfaceEvidence has an unsupported surface.", "manualQa.surfaceEvidence.surface");
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
function checkFile(path, field, opts) {
|
|
845
|
+
if (opts === undefined)
|
|
846
|
+
return;
|
|
847
|
+
const absolute = resolve2(opts.repoRoot, path);
|
|
848
|
+
if (!opts.fs.existsSync(absolute))
|
|
849
|
+
invalid(`${field} must point to an existing artifact.`, field);
|
|
850
|
+
const stat = opts.fs.statSync(absolute);
|
|
851
|
+
if (stat.size <= 0)
|
|
852
|
+
invalid(`${field} must point to a non-empty artifact.`, field);
|
|
853
|
+
}
|
|
854
|
+
function artifactMap(refs) {
|
|
855
|
+
const byId = new Map;
|
|
856
|
+
for (const ref of refs) {
|
|
857
|
+
if (byId.has(ref.id))
|
|
858
|
+
invalid(`manualQa.artifactRefs contains duplicate ${ref.id}.`, "manualQa.artifactRefs");
|
|
859
|
+
byId.set(ref.id, ref);
|
|
860
|
+
}
|
|
861
|
+
return byId;
|
|
862
|
+
}
|
|
863
|
+
function parseArtifactRefs(value, opts) {
|
|
864
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
865
|
+
invalid("manualQa.artifactRefs must not be empty.", "manualQa.artifactRefs");
|
|
866
|
+
return value.map((item, index) => {
|
|
867
|
+
const ref = section(item, `manualQa.artifactRefs[${index}]`);
|
|
868
|
+
const path = textField(ref["path"], `manualQa.artifactRefs[${index}].path`);
|
|
869
|
+
checkFile(path, `manualQa.artifactRefs[${index}].path`, opts);
|
|
870
|
+
return {
|
|
871
|
+
id: textField(ref["id"], `manualQa.artifactRefs[${index}].id`),
|
|
872
|
+
kind: kindField(ref["kind"], `manualQa.artifactRefs[${index}].kind`),
|
|
873
|
+
description: textField(ref["description"], `manualQa.artifactRefs[${index}].description`),
|
|
874
|
+
path
|
|
875
|
+
};
|
|
876
|
+
});
|
|
877
|
+
}
|
|
878
|
+
function referencedArtifacts(value, field, byId) {
|
|
879
|
+
return stringArray(value, field).map((id) => {
|
|
880
|
+
const artifact = byId.get(id);
|
|
881
|
+
if (artifact === undefined)
|
|
882
|
+
invalid(`${field} references unknown artifact ${id}.`, field);
|
|
883
|
+
return artifact;
|
|
884
|
+
});
|
|
885
|
+
}
|
|
886
|
+
function validateQualityGate(input, opts) {
|
|
887
|
+
const gate = section(input, "qualityGate");
|
|
888
|
+
const codeReview = section(gate["codeReview"], "codeReview");
|
|
889
|
+
const manualQa = section(gate["manualQa"], "manualQa");
|
|
890
|
+
const gateReview = section(gate["gateReview"], "gateReview");
|
|
891
|
+
const iteration = section(gate["iteration"], "iteration");
|
|
892
|
+
const coverage = section(gate["criteriaCoverage"], "criteriaCoverage");
|
|
893
|
+
const totalCriteria = numberField(coverage["totalCriteria"], "criteriaCoverage.totalCriteria");
|
|
894
|
+
const passCount = numberField(coverage["passCount"], "criteriaCoverage.passCount");
|
|
895
|
+
if (passCount < totalCriteria)
|
|
896
|
+
invalid("criteriaCoverage.passCount must cover totalCriteria.", "criteriaCoverage.passCount");
|
|
897
|
+
const artifactRefs = parseArtifactRefs(manualQa["artifactRefs"], opts);
|
|
898
|
+
const byId = artifactMap(artifactRefs);
|
|
899
|
+
const surfaceEvidence = parseSurfaceEvidence(manualQa["surfaceEvidence"], byId);
|
|
900
|
+
const adversarialCases = parseAdversarialCases(manualQa["adversarialCases"], byId);
|
|
901
|
+
const codeReportPath = textField(codeReview["reportPath"], "codeReview.reportPath");
|
|
902
|
+
const gateReportPath = textField(gateReview["reportPath"], "gateReview.reportPath");
|
|
903
|
+
checkFile(codeReportPath, "codeReview.reportPath", opts);
|
|
904
|
+
checkFile(gateReportPath, "gateReview.reportPath", opts);
|
|
905
|
+
return {
|
|
906
|
+
codeReview: {
|
|
907
|
+
by: reviewerRoleField(codeReview["by"], REVIEWER_ROLES.codeReview, "codeReview.by"),
|
|
908
|
+
recommendation: literal(codeReview["recommendation"], "APPROVE", "codeReview.recommendation"),
|
|
909
|
+
codeQualityStatus: literal(codeReview["codeQualityStatus"], "CLEAR", "codeReview.codeQualityStatus"),
|
|
910
|
+
reportPath: codeReportPath,
|
|
911
|
+
evidence: textField(codeReview["evidence"], "codeReview.evidence"),
|
|
912
|
+
blockers: emptyBlockers(codeReview["blockers"], "codeReview.blockers")
|
|
913
|
+
},
|
|
914
|
+
manualQa: {
|
|
915
|
+
by: reviewerRoleField(manualQa["by"], REVIEWER_ROLES.manualQa, "manualQa.by"),
|
|
916
|
+
status: literal(manualQa["status"], "passed", "manualQa.status"),
|
|
917
|
+
evidence: textField(manualQa["evidence"], "manualQa.evidence"),
|
|
918
|
+
surfaceEvidence,
|
|
919
|
+
adversarialCases,
|
|
920
|
+
artifactRefs
|
|
921
|
+
},
|
|
922
|
+
gateReview: {
|
|
923
|
+
by: reviewerRoleField(gateReview["by"], REVIEWER_ROLES.gateReview, "gateReview.by"),
|
|
924
|
+
recommendation: literal(gateReview["recommendation"], "APPROVE", "gateReview.recommendation"),
|
|
925
|
+
reportPath: gateReportPath,
|
|
926
|
+
evidence: textField(gateReview["evidence"], "gateReview.evidence"),
|
|
927
|
+
blockers: emptyBlockers(gateReview["blockers"], "gateReview.blockers")
|
|
928
|
+
},
|
|
929
|
+
iteration: {
|
|
930
|
+
fullRerun: literal(iteration["fullRerun"], true, "iteration.fullRerun"),
|
|
931
|
+
status: literal(iteration["status"], "passed", "iteration.status"),
|
|
932
|
+
rerunCommands: stringArray(iteration["rerunCommands"], "iteration.rerunCommands"),
|
|
933
|
+
evidence: textField(iteration["evidence"], "iteration.evidence")
|
|
934
|
+
},
|
|
935
|
+
criteriaCoverage: {
|
|
936
|
+
totalCriteria,
|
|
937
|
+
passCount,
|
|
938
|
+
originalIntent: textField(coverage["originalIntent"], "criteriaCoverage.originalIntent"),
|
|
939
|
+
desiredOutcome: textField(coverage["desiredOutcome"], "criteriaCoverage.desiredOutcome"),
|
|
940
|
+
userOutcomeReview: textField(coverage["userOutcomeReview"], "criteriaCoverage.userOutcomeReview"),
|
|
941
|
+
adversarialClassesCovered: stringArray(coverage["adversarialClassesCovered"], "criteriaCoverage.adversarialClassesCovered")
|
|
942
|
+
}
|
|
943
|
+
};
|
|
944
|
+
}
|
|
945
|
+
function parseSurfaceEvidence(value, byId) {
|
|
946
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
947
|
+
invalid("manualQa.surfaceEvidence must not be empty.", "manualQa.surfaceEvidence");
|
|
948
|
+
return value.map((item, index) => {
|
|
949
|
+
const row = section(item, `manualQa.surfaceEvidence[${index}]`);
|
|
950
|
+
const surface = surfaceField(row["surface"], `manualQa.surfaceEvidence[${index}].surface`);
|
|
951
|
+
const artifacts = referencedArtifacts(row["artifactRefs"], `manualQa.surfaceEvidence[${index}].artifactRefs`, byId);
|
|
952
|
+
for (const artifact of artifacts) {
|
|
953
|
+
if (!artifactCompatible(surface, artifact.kind)) {
|
|
954
|
+
invalid(`manualQa.surfaceEvidence ${surface} artifact ${artifact.kind} is incompatible.`, "manualQa.surfaceEvidence");
|
|
955
|
+
}
|
|
956
|
+
}
|
|
957
|
+
return {
|
|
958
|
+
id: textField(row["id"], `manualQa.surfaceEvidence[${index}].id`),
|
|
959
|
+
criterionRef: textField(row["criterionRef"], `manualQa.surfaceEvidence[${index}].criterionRef`),
|
|
960
|
+
surface,
|
|
961
|
+
invocation: textField(row["invocation"], `manualQa.surfaceEvidence[${index}].invocation`),
|
|
962
|
+
verdict: passedVerdict(row["verdict"], `manualQa.surfaceEvidence[${index}].verdict`),
|
|
963
|
+
artifactRefs: artifacts.map((artifact) => artifact.id)
|
|
964
|
+
};
|
|
965
|
+
});
|
|
966
|
+
}
|
|
967
|
+
function parseAdversarialCases(value, byId) {
|
|
968
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
969
|
+
invalid("manualQa.adversarialCases must not be empty.", "manualQa.adversarialCases");
|
|
970
|
+
return value.map((item, index) => {
|
|
971
|
+
const row = section(item, `manualQa.adversarialCases[${index}]`);
|
|
972
|
+
const artifacts = referencedArtifacts(row["artifactRefs"], `manualQa.adversarialCases[${index}].artifactRefs`, byId);
|
|
973
|
+
return {
|
|
974
|
+
id: textField(row["id"], `manualQa.adversarialCases[${index}].id`),
|
|
975
|
+
criterionRef: textField(row["criterionRef"], `manualQa.adversarialCases[${index}].criterionRef`),
|
|
976
|
+
scenario: textField(row["scenario"], `manualQa.adversarialCases[${index}].scenario`),
|
|
977
|
+
expectedBehavior: textField(row["expectedBehavior"], `manualQa.adversarialCases[${index}].expectedBehavior`),
|
|
978
|
+
verdict: passedVerdict(row["verdict"], `manualQa.adversarialCases[${index}].verdict`),
|
|
979
|
+
artifactRefs: artifacts.map((artifact) => artifact.id)
|
|
980
|
+
};
|
|
981
|
+
});
|
|
982
|
+
}
|
|
983
|
+
|
|
984
|
+
// components/ulw-loop/src/checkpoint.ts
|
|
985
|
+
var QUALITY_GATE_FS = { existsSync: existsSync3, statSync };
|
|
986
|
+
function ulwLoopFail2(message, code) {
|
|
987
|
+
throw new UlwLoopError(message, code);
|
|
988
|
+
}
|
|
989
|
+
function normalizeObjective3(value) {
|
|
990
|
+
return value.replace(/\s+/g, " ").trim();
|
|
991
|
+
}
|
|
992
|
+
function nonEmptyEvidence2(value) {
|
|
993
|
+
const trimmed = value.trim();
|
|
994
|
+
return trimmed || ulwLoopFail2("Evidence must be a non-empty string.", "ulw_loop_evidence_required");
|
|
995
|
+
}
|
|
996
|
+
function findGoal2(plan, goalId) {
|
|
997
|
+
const goal = plan.goals.find((candidate) => candidate.id === goalId);
|
|
998
|
+
return goal ?? ulwLoopFail2(`Unknown ulw-loop id: ${goalId}.`, "ulw_loop_goal_not_found");
|
|
999
|
+
}
|
|
1000
|
+
async function readJsonInput2(raw, repoRoot) {
|
|
1001
|
+
if (raw === undefined || raw.trim() === "")
|
|
1002
|
+
return;
|
|
1003
|
+
const trimmed = raw.trim();
|
|
1004
|
+
try {
|
|
1005
|
+
return JSON.parse(trimmed);
|
|
1006
|
+
} catch (error) {
|
|
1007
|
+
if (!(error instanceof SyntaxError))
|
|
1008
|
+
throw error;
|
|
1009
|
+
}
|
|
1010
|
+
const path = resolve3(repoRoot, trimmed);
|
|
1011
|
+
if (!existsSync3(path))
|
|
1012
|
+
return ulwLoopFail2("Quality gate JSON is neither valid JSON nor a readable path.", "ulw_loop_json_input_invalid");
|
|
1013
|
+
try {
|
|
1014
|
+
return JSON.parse(await readFile5(path, "utf8"));
|
|
1015
|
+
} catch (error) {
|
|
1016
|
+
return ulwLoopFail2(`Quality gate path does not contain valid JSON${error instanceof Error ? `: ${error.message}` : "."}`, "ulw_loop_json_input_invalid");
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1019
|
+
function makeAggregateCompletion(now, evidence, codexGoal) {
|
|
1020
|
+
return { status: "complete", completedAt: now, evidence, codexGoal };
|
|
1021
|
+
}
|
|
1022
|
+
function applyBlockedOrFailed(goal, plan, status, evidence, now) {
|
|
1023
|
+
const signature = classifyExternalAuthorizationBlocker(evidence);
|
|
1024
|
+
const occurrences = signature === null ? 0 : sameBlockerOccurrences(plan, signature) + 1;
|
|
1025
|
+
const needsDecision = signature !== null && occurrences >= 3;
|
|
1026
|
+
goal.status = needsDecision ? "needs_user_decision" : status;
|
|
1027
|
+
goal.updatedAt = now;
|
|
1028
|
+
if (status === "failed" || needsDecision) {
|
|
1029
|
+
goal.failedAt = now;
|
|
1030
|
+
goal.failureReason = evidence;
|
|
1031
|
+
}
|
|
1032
|
+
if (status === "blocked" || needsDecision)
|
|
1033
|
+
goal.blockedReason = evidence;
|
|
1034
|
+
if (signature !== null) {
|
|
1035
|
+
goal.blockerSignature = signature;
|
|
1036
|
+
goal.blockerOccurrenceCount = occurrences;
|
|
1037
|
+
goal.requiredExternalDecision = `Resolve external authorization: ${signature}`;
|
|
1038
|
+
}
|
|
1039
|
+
if (needsDecision)
|
|
1040
|
+
goal.nonRetriable = true;
|
|
1041
|
+
if (plan.activeGoalId === goal.id)
|
|
1042
|
+
delete plan.activeGoalId;
|
|
1043
|
+
}
|
|
1044
|
+
function ledgerKind2(status, goal, aggregateCompletion) {
|
|
1045
|
+
if (aggregateCompletion !== undefined)
|
|
1046
|
+
return "aggregate_completed";
|
|
1047
|
+
if (status === "complete")
|
|
1048
|
+
return "goal_completed";
|
|
1049
|
+
if (goal.status === "needs_user_decision")
|
|
1050
|
+
return "goal_needs_user_decision";
|
|
1051
|
+
return status === "blocked" ? "goal_blocked" : "goal_failed";
|
|
1052
|
+
}
|
|
1053
|
+
function buildLedger(now, args, goal, qualityGate, codexGoal, aggregateCompletion) {
|
|
1054
|
+
const entry = {
|
|
1055
|
+
at: now,
|
|
1056
|
+
kind: ledgerKind2(args.status, goal, aggregateCompletion),
|
|
1057
|
+
goalId: goal.id,
|
|
1058
|
+
status: goal.status,
|
|
1059
|
+
evidence: args.evidence
|
|
1060
|
+
};
|
|
1061
|
+
if (codexGoal !== undefined)
|
|
1062
|
+
entry.codexGoal = codexGoal;
|
|
1063
|
+
if (qualityGate !== undefined)
|
|
1064
|
+
entry.qualityGate = qualityGate;
|
|
1065
|
+
if (goal.blockerSignature !== undefined)
|
|
1066
|
+
entry.blockerSignature = goal.blockerSignature;
|
|
1067
|
+
if (goal.blockerOccurrenceCount !== undefined)
|
|
1068
|
+
entry.blockerOccurrenceCount = goal.blockerOccurrenceCount;
|
|
1069
|
+
if (goal.requiredExternalDecision !== undefined)
|
|
1070
|
+
entry.requiredExternalDecision = goal.requiredExternalDecision;
|
|
1071
|
+
return entry;
|
|
1072
|
+
}
|
|
1073
|
+
async function checkpointUlwLoop(repoRoot, args, scope) {
|
|
1074
|
+
return withUlwLoopMutationLock(repoRoot, scope, async () => {
|
|
1075
|
+
const plan = await readUlwLoopPlan(repoRoot, scope);
|
|
1076
|
+
const goal = findGoal2(plan, args.goalId);
|
|
1077
|
+
const evidence = nonEmptyEvidence2(args.evidence);
|
|
1078
|
+
const now = iso();
|
|
1079
|
+
let aggregateCompletion;
|
|
1080
|
+
let qualityGate;
|
|
1081
|
+
let codexGoal;
|
|
1082
|
+
if (args.status === "complete") {
|
|
1083
|
+
const aggregate = codexGoalMode(plan) === "aggregate";
|
|
1084
|
+
const final = isFinalRunCompletionCandidate(plan, goal);
|
|
1085
|
+
if (final) {
|
|
1086
|
+
requireAllCriteriaPass(goal);
|
|
1087
|
+
requireAllPlanCriteriaPass(plan);
|
|
1088
|
+
} else if (aggregate)
|
|
1089
|
+
requireEssentialCriteriaPass(goal);
|
|
1090
|
+
else
|
|
1091
|
+
requireAllCriteriaPass(goal);
|
|
1092
|
+
const snapshot = await readCodexGoalSnapshotInput(args.codexGoalJson, repoRoot);
|
|
1093
|
+
const reconciliation = reconcileCodexGoalSnapshot(snapshot, {
|
|
1094
|
+
expectedObjective: expectedCodexObjective(plan, goal),
|
|
1095
|
+
...aggregate ? { acceptedObjectives: compatibleCodexObjectives(plan) } : {},
|
|
1096
|
+
allowedStatuses: aggregate ? final ? ["complete"] : ["active"] : ["complete"],
|
|
1097
|
+
requireSnapshot: true,
|
|
1098
|
+
requireComplete: !aggregate || final
|
|
1099
|
+
});
|
|
1100
|
+
codexGoal = reconciliation.snapshot.raw;
|
|
1101
|
+
if (!reconciliation.ok) {
|
|
1102
|
+
const objective = snapshot?.objective;
|
|
1103
|
+
const mismatchedTaskObjective = snapshot?.available === true && objective !== undefined && normalizeObjective3(objective) !== normalizeObjective3(expectedCodexObjective(plan, goal));
|
|
1104
|
+
const completedTaskScoped = mismatchedTaskObjective && snapshot.status === "complete" && await canReconcileCompletedTaskScopedAggregateSnapshot(repoRoot, plan, goal, objective, evidence, scope);
|
|
1105
|
+
const activeFinalTaskScoped = mismatchedTaskObjective && snapshot.status === "active" && await canReconcileActiveFinalTaskScopedAggregateSnapshot(repoRoot, plan, goal, objective, evidence, scope);
|
|
1106
|
+
const taskScoped = completedTaskScoped || activeFinalTaskScoped;
|
|
1107
|
+
if (!taskScoped)
|
|
1108
|
+
throw new UlwLoopError(`${formatCodexGoalReconciliation(reconciliation)}${aggregate && snapshot?.status === "complete" && objective !== undefined ? buildTaskScopedAggregateReconciliationHint(goal, final) : ""}`, "ulw_loop_codex_snapshot_mismatch");
|
|
1109
|
+
}
|
|
1110
|
+
if (final)
|
|
1111
|
+
aggregateCompletion = makeAggregateCompletion(now, evidence, codexGoal);
|
|
1112
|
+
if (final || aggregateCompletion !== undefined)
|
|
1113
|
+
qualityGate = validateQualityGate(await readJsonInput2(args.qualityGateJson, repoRoot), {
|
|
1114
|
+
repoRoot,
|
|
1115
|
+
fs: QUALITY_GATE_FS
|
|
1116
|
+
});
|
|
1117
|
+
goal.status = "complete";
|
|
1118
|
+
goal.completedAt = now;
|
|
1119
|
+
goal.evidence = evidence;
|
|
1120
|
+
delete goal.failedAt;
|
|
1121
|
+
delete goal.failureReason;
|
|
1122
|
+
clearGoalBlockerFields(goal);
|
|
1123
|
+
if (plan.activeGoalId === goal.id)
|
|
1124
|
+
delete plan.activeGoalId;
|
|
1125
|
+
} else
|
|
1126
|
+
applyBlockedOrFailed(goal, plan, args.status, evidence, now);
|
|
1127
|
+
goal.updatedAt = now;
|
|
1128
|
+
if (aggregateCompletion !== undefined)
|
|
1129
|
+
plan.aggregateCompletion = aggregateCompletion;
|
|
1130
|
+
plan.updatedAt = now;
|
|
1131
|
+
await writePlan(repoRoot, plan, scope);
|
|
1132
|
+
const ledgerEntry = buildLedger(now, args, goal, qualityGate, codexGoal, aggregateCompletion);
|
|
1133
|
+
await appendLedger(repoRoot, ledgerEntry, scope);
|
|
1134
|
+
return aggregateCompletion === undefined ? { plan, goal, ledgerEntry } : { plan, goal, ledgerEntry, aggregateCompletion };
|
|
1135
|
+
});
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
// components/ulw-loop/src/cli-steering.ts
|
|
1139
|
+
var SOURCES = ["user_prompt_submit", "finding", "cli"];
|
|
1140
|
+
function isKind(value) {
|
|
1141
|
+
return value !== undefined && ULW_LOOP_STEERING_MUTATION_KINDS.some((kind) => kind === value);
|
|
1142
|
+
}
|
|
1143
|
+
function isSource(value) {
|
|
1144
|
+
return value !== undefined && SOURCES.some((source) => source === value);
|
|
1145
|
+
}
|
|
1146
|
+
function isModel(value) {
|
|
1147
|
+
return ULW_LOOP_SUCCESS_CRITERION_USER_MODELS.some((model) => model === value);
|
|
1148
|
+
}
|
|
1149
|
+
function fail(message, code, details) {
|
|
1150
|
+
throw new UlwLoopError(message, code, { details });
|
|
1151
|
+
}
|
|
1152
|
+
function text(value, field) {
|
|
1153
|
+
if (value === undefined)
|
|
1154
|
+
return;
|
|
1155
|
+
const trimmed = value.trim();
|
|
1156
|
+
if (trimmed.length > 0)
|
|
1157
|
+
return trimmed;
|
|
1158
|
+
return fail(`Empty ${field}.`, "ULW_LOOP_STEERING_FIELD_EMPTY", { field });
|
|
1159
|
+
}
|
|
1160
|
+
function required2(argv, flag) {
|
|
1161
|
+
const value = text(readValue(argv, flag), flag);
|
|
1162
|
+
return value ?? fail(`Missing ${flag}.`, "ULW_LOOP_STEERING_FIELD_REQUIRED", { flag });
|
|
1163
|
+
}
|
|
1164
|
+
function requiredGoal(argv) {
|
|
1165
|
+
const value = text(parseGoalArg(argv), "--goal-id");
|
|
1166
|
+
return value ?? fail("Missing --goal-id.", "ULW_LOOP_GOAL_ID_REQUIRED", { flag: "--goal-id" });
|
|
1167
|
+
}
|
|
1168
|
+
function readObject(value, key) {
|
|
1169
|
+
return Object.entries(value).find(([name]) => name === key)?.[1];
|
|
1170
|
+
}
|
|
1171
|
+
function isPlain(value) {
|
|
1172
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1173
|
+
}
|
|
1174
|
+
function objectText(value, key) {
|
|
1175
|
+
const candidate = readObject(value, key);
|
|
1176
|
+
return typeof candidate === "string" ? candidate : undefined;
|
|
1177
|
+
}
|
|
1178
|
+
function parseSteeringKind(argv) {
|
|
1179
|
+
const value = readValue(argv, "--kind");
|
|
1180
|
+
if (isKind(value))
|
|
1181
|
+
return value;
|
|
1182
|
+
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 });
|
|
1183
|
+
}
|
|
1184
|
+
function parseSteeringSource(argv) {
|
|
1185
|
+
const value = readValue(argv, "--source");
|
|
1186
|
+
if (value === undefined)
|
|
1187
|
+
return "cli";
|
|
1188
|
+
return isSource(value) ? value : fail(`Invalid --source: ${value}.`, "ULW_LOOP_STEERING_SOURCE_INVALID", { value, expected: SOURCES });
|
|
1189
|
+
}
|
|
1190
|
+
function child(value) {
|
|
1191
|
+
if (!isPlain(value))
|
|
1192
|
+
return null;
|
|
1193
|
+
const title = text(objectText(value, "title"), "title");
|
|
1194
|
+
const objective = text(objectText(value, "objective"), "objective");
|
|
1195
|
+
if (title === undefined || objective === undefined)
|
|
1196
|
+
return null;
|
|
1197
|
+
return { title, objective };
|
|
1198
|
+
}
|
|
1199
|
+
async function children(argv, flag, needed) {
|
|
1200
|
+
const input = needed ? required2(argv, flag) : text(readValue(argv, flag), flag);
|
|
1201
|
+
if (input === undefined)
|
|
1202
|
+
return [];
|
|
1203
|
+
const raw = await readJsonInput(input);
|
|
1204
|
+
if (!Array.isArray(raw))
|
|
1205
|
+
return fail(`${flag} must be a JSON array.`, "ULW_LOOP_STEERING_JSON_ARRAY_REQUIRED", { flag });
|
|
1206
|
+
const parsed = [];
|
|
1207
|
+
for (const item of raw) {
|
|
1208
|
+
const next = child(item);
|
|
1209
|
+
if (next === null)
|
|
1210
|
+
return fail(`${flag} entries require title/objective.`, "ULW_LOOP_STEERING_CHILD_INVALID", { flag });
|
|
1211
|
+
parsed.push(next);
|
|
1212
|
+
}
|
|
1213
|
+
return parsed;
|
|
1214
|
+
}
|
|
1215
|
+
async function stringArray2(argv, flag) {
|
|
1216
|
+
const raw = await readJsonInput(required2(argv, flag));
|
|
1217
|
+
if (!Array.isArray(raw))
|
|
1218
|
+
return fail(`${flag} must be a JSON array.`, "ULW_LOOP_STEERING_JSON_ARRAY_REQUIRED", { flag });
|
|
1219
|
+
const values = [];
|
|
1220
|
+
for (const item of raw) {
|
|
1221
|
+
if (typeof item !== "string")
|
|
1222
|
+
return fail(`${flag} entries must be strings.`, "ULW_LOOP_STEERING_STRING_ARRAY_REQUIRED", { flag });
|
|
1223
|
+
values.push(text(item, flag) ?? "");
|
|
1224
|
+
}
|
|
1225
|
+
return values;
|
|
1226
|
+
}
|
|
1227
|
+
function model(value) {
|
|
1228
|
+
const trimmed = text(value, "--user-model");
|
|
1229
|
+
if (trimmed === undefined)
|
|
1230
|
+
return;
|
|
1231
|
+
return isModel(trimmed) ? trimmed : fail(`Invalid --user-model: ${trimmed}.`, "ULW_LOOP_STEERING_USER_MODEL_INVALID", { value: trimmed, expected: ULW_LOOP_SUCCESS_CRITERION_USER_MODELS });
|
|
1232
|
+
}
|
|
1233
|
+
function neverKind(kind) {
|
|
1234
|
+
return fail(`Unsupported steering kind: ${String(kind)}.`, "ULW_LOOP_STEERING_KIND_UNSUPPORTED", { kind });
|
|
1235
|
+
}
|
|
1236
|
+
async function parseSteeringProposal(argv) {
|
|
1237
|
+
const kind = parseSteeringKind(argv);
|
|
1238
|
+
const source = parseSteeringSource(argv);
|
|
1239
|
+
const base = { kind, source, evidence: required2(argv, "--evidence"), rationale: required2(argv, "--rationale") };
|
|
1240
|
+
switch (kind) {
|
|
1241
|
+
case "add_subgoal":
|
|
1242
|
+
return normalizeSteeringProposal({ ...base, title: required2(argv, "--title"), objective: required2(argv, "--objective") });
|
|
1243
|
+
case "split_subgoal": {
|
|
1244
|
+
const goalId = requiredGoal(argv);
|
|
1245
|
+
return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, childGoals: await children(argv, "--children", true) });
|
|
1246
|
+
}
|
|
1247
|
+
case "reorder_pending":
|
|
1248
|
+
return normalizeSteeringProposal({ ...base, pendingOrder: await stringArray2(argv, "--order") });
|
|
1249
|
+
case "revise_pending_wording": {
|
|
1250
|
+
const goalId = requiredGoal(argv);
|
|
1251
|
+
const revisedTitle = readValue(argv, "--title");
|
|
1252
|
+
const revisedObjective = readValue(argv, "--objective");
|
|
1253
|
+
if (revisedTitle === undefined && revisedObjective === undefined)
|
|
1254
|
+
return fail("revise_pending_wording requires --title or --objective.", "ULW_LOOP_STEERING_UPDATE_REQUIRED", { kind });
|
|
1255
|
+
return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, ...revisedTitle === undefined ? {} : { revisedTitle }, ...revisedObjective === undefined ? {} : { revisedObjective } });
|
|
1256
|
+
}
|
|
1257
|
+
case "revise_criterion": {
|
|
1258
|
+
const goalId = requiredGoal(argv);
|
|
1259
|
+
const criterionId = required2(argv, "--criterion-id");
|
|
1260
|
+
const scenario = readValue(argv, "--scenario");
|
|
1261
|
+
const expectedEvidence = readValue(argv, "--expected-evidence");
|
|
1262
|
+
const userModel = model(readValue(argv, "--user-model"));
|
|
1263
|
+
if (scenario === undefined && expectedEvidence === undefined && userModel === undefined)
|
|
1264
|
+
return fail("revise_criterion requires scenario, expected-evidence, or user-model.", "ULW_LOOP_STEERING_UPDATE_REQUIRED", { kind });
|
|
1265
|
+
return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, criterionId, ...scenario === undefined ? {} : { scenario }, ...expectedEvidence === undefined ? {} : { expectedEvidence }, ...userModel === undefined ? {} : { userModel } });
|
|
1266
|
+
}
|
|
1267
|
+
case "annotate_ledger":
|
|
1268
|
+
return normalizeSteeringProposal(base);
|
|
1269
|
+
case "mark_blocked_superseded": {
|
|
1270
|
+
const goalId = requiredGoal(argv);
|
|
1271
|
+
const childGoals = await children(argv, "--replacements", false);
|
|
1272
|
+
return normalizeSteeringProposal({ ...base, goalId, targetGoalId: goalId, ...childGoals.length === 0 ? {} : { childGoals } });
|
|
1273
|
+
}
|
|
1274
|
+
default:
|
|
1275
|
+
return neverKind(kind);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
function normalizedChildren(values) {
|
|
1279
|
+
if (values === undefined)
|
|
1280
|
+
return;
|
|
1281
|
+
return values.map((item) => ({ title: text(item.title, "child.title") ?? "", objective: text(item.objective, "child.objective") ?? "" }));
|
|
1282
|
+
}
|
|
1283
|
+
function normalizedStrings(values, field) {
|
|
1284
|
+
if (values === undefined)
|
|
1285
|
+
return;
|
|
1286
|
+
return values.map((value) => text(value, field) ?? "");
|
|
1287
|
+
}
|
|
1288
|
+
function normalizeSteeringProposal(proposal) {
|
|
1289
|
+
const evidence = text(proposal.evidence, "evidence") ?? "";
|
|
1290
|
+
const rationale = text(proposal.rationale, "rationale") ?? "";
|
|
1291
|
+
const goalId = text(proposal.goalId, "goalId");
|
|
1292
|
+
const targetGoalId = text(proposal.targetGoalId, "targetGoalId");
|
|
1293
|
+
const targetGoalIds = normalizedStrings(proposal.targetGoalIds, "targetGoalIds");
|
|
1294
|
+
const criterionId = text(proposal.criterionId, "criterionId");
|
|
1295
|
+
const title = text(proposal.title, "title");
|
|
1296
|
+
const objective = text(proposal.objective, "objective");
|
|
1297
|
+
const revisedTitle = text(proposal.revisedTitle, "revisedTitle");
|
|
1298
|
+
const revisedObjective = text(proposal.revisedObjective, "revisedObjective");
|
|
1299
|
+
const blockedReason = text(proposal.blockedReason, "blockedReason");
|
|
1300
|
+
const directiveText = text(proposal.directiveText, "directiveText");
|
|
1301
|
+
const promptSignature = text(proposal.promptSignature, "promptSignature");
|
|
1302
|
+
const idempotencyKey = text(proposal.idempotencyKey, "idempotencyKey");
|
|
1303
|
+
const scenario = text(proposal.scenario, "scenario");
|
|
1304
|
+
const expectedEvidence = text(proposal.expectedEvidence, "expectedEvidence");
|
|
1305
|
+
const childGoals = normalizedChildren(proposal.childGoals);
|
|
1306
|
+
const pendingOrder = normalizedStrings(proposal.pendingOrder, "pendingOrder");
|
|
1307
|
+
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 } };
|
|
1308
|
+
}
|
|
1309
|
+
function printSteerResult(result, json) {
|
|
1310
|
+
if (json) {
|
|
1311
|
+
printJson({ ok: result.accepted, accepted: result.accepted, rejectedReasons: result.rejectedReasons, deduped: result.deduped, audit: result.audit, plan: result.plan });
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1314
|
+
const outcome = result.deduped ? "deduped" : result.accepted ? "accepted" : "rejected";
|
|
1315
|
+
process.stdout.write(`ulw-loop steer: ${outcome} ${result.audit.kind}
|
|
1316
|
+
`);
|
|
1317
|
+
if (result.rejectedReasons.length > 0)
|
|
1318
|
+
process.stdout.write(`rejected: ${result.rejectedReasons.join("; ")}
|
|
1319
|
+
`);
|
|
1320
|
+
if (result.audit.idempotencyKey !== undefined)
|
|
1321
|
+
process.stdout.write(`idempotency-key: ${result.audit.idempotencyKey}
|
|
1322
|
+
`);
|
|
1323
|
+
printStatus(result.plan);
|
|
1324
|
+
}
|
|
1325
|
+
|
|
1326
|
+
// components/ulw-loop/src/codex-goal-instruction.ts
|
|
1327
|
+
function buildCodexGoalInstruction(args) {
|
|
1328
|
+
const mode = codexGoalMode(args.plan);
|
|
1329
|
+
const createGoal = buildCreateGoalPayload(args.plan, args.goal);
|
|
1330
|
+
const isFinal = args.isFinal ?? isFinalRunCompletionCandidate(args.plan, args.goal);
|
|
1331
|
+
return { text: buildText(mode, args.plan, args.goal, createGoal, isFinal), json: createGoal };
|
|
1332
|
+
}
|
|
1333
|
+
function buildCreateGoalPayload(plan, goal) {
|
|
1334
|
+
return { objective: expectedCodexObjective(plan, goal) };
|
|
1335
|
+
}
|
|
1336
|
+
function buildText(mode, plan, goal, createGoal, isFinal) {
|
|
1337
|
+
return joinLines([
|
|
1338
|
+
mode === "aggregate" ? "UlwLoop aggregate-goal handoff" : "UlwLoop active-goal handoff",
|
|
1339
|
+
`Mode: ${mode}`,
|
|
1340
|
+
`Plan: ${plan.goalsPath}`,
|
|
1341
|
+
`Ledger: ${plan.ledgerPath}`,
|
|
1342
|
+
`Goal: ${goal.id} — ${goal.title}`,
|
|
1343
|
+
"",
|
|
1344
|
+
...activeGoalLines(goal),
|
|
1345
|
+
"",
|
|
1346
|
+
...successCriteriaLines(goal.successCriteria),
|
|
1347
|
+
"",
|
|
1348
|
+
"Codex goal integration constraints:",
|
|
1349
|
+
"- Use the create_goal payload exactly as rendered: objective only.",
|
|
1350
|
+
"- Goals are unlimited. Do not add numeric limits.",
|
|
1351
|
+
...modeConstraintLines(mode, isFinal),
|
|
1352
|
+
finalSection(plan, goal, isFinal, mode === "aggregate"),
|
|
1353
|
+
...checkpointLines(plan, mode),
|
|
1354
|
+
"",
|
|
1355
|
+
"create_goal payload:",
|
|
1356
|
+
JSON.stringify(createGoal, null, 2)
|
|
1357
|
+
]);
|
|
1358
|
+
}
|
|
1359
|
+
function modeConstraintLines(mode, isFinal) {
|
|
1360
|
+
if (mode === "per_story") {
|
|
1361
|
+
return [
|
|
1362
|
+
"- First call get_goal. If no active goal exists, call create_goal with the payload below.",
|
|
1363
|
+
"- If a different active Codex goal exists, finish/checkpoint that goal before starting this ulw-loop.",
|
|
1364
|
+
"- Work only this goal until its completion audit passes."
|
|
1365
|
+
];
|
|
1366
|
+
}
|
|
1367
|
+
return [
|
|
1368
|
+
"- Codex goal = the whole omo ulw-loop run; OMO G001/G002/etc. = ledger stories.",
|
|
1369
|
+
"- First call get_goal. If no active goal exists, call create_goal with the aggregate payload below.",
|
|
1370
|
+
"- If get_goal reports the same aggregate objective as active, continue this OMO story without creating a new Codex goal.",
|
|
1371
|
+
"- If a different active or incomplete Codex goal exists, finish/checkpoint that goal before starting this ulw-loop.",
|
|
1372
|
+
isFinal ? "- This is the final story; update_goal is allowed only after the mandatory quality gate passes." : "- This is not the final story: do not call update_goal mid-aggregate; checkpoint this OMO ledger story and continue the remaining stories. update_goal is reserved for the final story after the mandatory quality gate passes."
|
|
1373
|
+
];
|
|
1374
|
+
}
|
|
1375
|
+
function checkpointLines(plan, mode) {
|
|
1376
|
+
const failureLine = `- If blocked or failed, checkpoint with --status failed and the failure evidence; rerun complete-goals${sessionOption(plan)} --retry-failed to resume.`;
|
|
1377
|
+
if (mode === "per_story")
|
|
1378
|
+
return [failureLine];
|
|
1379
|
+
return [
|
|
1380
|
+
"- Checkpoint this OMO story with a fresh get_goal snapshot whose objective matches the aggregate payload.",
|
|
1381
|
+
failureLine
|
|
1382
|
+
];
|
|
1383
|
+
}
|
|
1384
|
+
function activeGoalLines(goal) {
|
|
1385
|
+
return ["Active goal:", `- id: ${goal.id}`, `- title: ${goal.title}`, `- objective: ${goal.objective}`];
|
|
1386
|
+
}
|
|
1387
|
+
function successCriteriaLines(criteria) {
|
|
1388
|
+
if (criteria.length === 0)
|
|
1389
|
+
return ["Success criteria:", "- No success criteria recorded for this goal."];
|
|
1390
|
+
return ["Success criteria:", ...criteria.map(formatCriterionLine)];
|
|
1391
|
+
}
|
|
1392
|
+
function formatCriterionLine(criterion) {
|
|
1393
|
+
const remainingWork = criterion.status === "pending" ? " remaining work:" : "";
|
|
1394
|
+
const marker = isEssentialCriterion(criterion) ? "essential" : "non-essential";
|
|
1395
|
+
return `-${remainingWork} [${criterion.id}] [${marker}] (${criterion.userModel}) ${criterion.scenario} — expect: ${criterion.expectedEvidence} — status: ${criterion.status}`;
|
|
1396
|
+
}
|
|
1397
|
+
function finalSection(plan, goal, isFinal, aggregate) {
|
|
1398
|
+
if (!isFinal)
|
|
1399
|
+
return "- This is not the final ulw-loop story; do not run the final reviewer/manual-QA/gate-review quality gate yet.";
|
|
1400
|
+
const option = sessionOption(plan);
|
|
1401
|
+
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>"`;
|
|
1402
|
+
const checkpointCommand = `omo ulw-loop checkpoint${option} --goal-id ${goal.id} --status complete --evidence "<targeted verification/manualQa/gateReview evidence>" --codex-goal-json "<fresh complete get_goal JSON or path>" --quality-gate-json "<quality gate JSON or path>"`;
|
|
1403
|
+
return joinLines([
|
|
1404
|
+
"Final story — run mandatory quality gate before update_goal:",
|
|
1405
|
+
"- Run targeted verification for changed behavior.",
|
|
1406
|
+
"- Confirm every manualQa artifact path exists and has non-zero size.",
|
|
1407
|
+
"- Spawn final reviewers with fork_context=false: lazycodex-code-reviewer, lazycodex-qa-executor, and lazycodex-gate-reviewer. Include the original brief, goal objectives, desired user-visible outcome, diff, and evidence.",
|
|
1408
|
+
"- Require clean codeReview, manualQa, gateReview, iteration, and criteriaCoverage. criteriaCoverage must summarize originalIntent, desiredOutcome, and userOutcomeReview; counts alone are not approval.",
|
|
1409
|
+
"- If any reviewer is blocked/inconclusive or the quality gate is not clean, do not call update_goal. Record blocker work first:",
|
|
1410
|
+
` ${blockerCommand}`,
|
|
1411
|
+
aggregate ? '- If the quality gate is clean, call update_goal({status: "complete"}), call get_goal again, then checkpoint the aggregate story:' : '- If the quality gate is clean, call update_goal({status: "complete"}), call get_goal again, then checkpoint:',
|
|
1412
|
+
` ${checkpointCommand}`
|
|
1413
|
+
]);
|
|
1414
|
+
}
|
|
1415
|
+
function sessionOption(plan) {
|
|
1416
|
+
const prefix = ".omo/ulw-loop/";
|
|
1417
|
+
const suffix = "/goals.json";
|
|
1418
|
+
if (!plan.goalsPath.startsWith(prefix) || !plan.goalsPath.endsWith(suffix))
|
|
1419
|
+
return "";
|
|
1420
|
+
const sessionId = plan.goalsPath.slice(prefix.length, -suffix.length);
|
|
1421
|
+
return sessionId.length === 0 ? "" : ` --session-id ${sessionId}`;
|
|
1422
|
+
}
|
|
1423
|
+
function joinLines(lines) {
|
|
1424
|
+
return lines.join(`
|
|
1425
|
+
`);
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
// components/ulw-loop/src/plan-crud.ts
|
|
1429
|
+
import { existsSync as existsSync4 } from "node:fs";
|
|
1430
|
+
import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
|
|
1431
|
+
|
|
1432
|
+
// components/ulw-loop/src/plan-goal-factory.ts
|
|
1433
|
+
function cleanLine(line) {
|
|
1434
|
+
return line.replace(/^\s*(?:[-*+]\s+|\d+[.)]\s+)/, "").trim();
|
|
1435
|
+
}
|
|
1436
|
+
function normalizeObjective4(value) {
|
|
1437
|
+
return value.replace(/\s+/g, " ").trim();
|
|
1438
|
+
}
|
|
1439
|
+
function titleFromObjective(objective, fallback) {
|
|
1440
|
+
const firstLine = objective.split(/\r?\n/).map((line) => line.trim()).find(Boolean) ?? fallback;
|
|
1441
|
+
return firstLine.length > 72 ? `${firstLine.slice(0, 69).trimEnd()}...` : firstLine;
|
|
1442
|
+
}
|
|
1443
|
+
function normalizeGoalId(title, index) {
|
|
1444
|
+
const slug = title.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 36).replace(/-+$/g, "");
|
|
1445
|
+
return `G${String(index + 1).padStart(3, "0")}${slug ? `-${slug}` : ""}`;
|
|
1446
|
+
}
|
|
1447
|
+
function assertNonEmpty(value, label) {
|
|
1448
|
+
const trimmed = value?.trim();
|
|
1449
|
+
if (!trimmed)
|
|
1450
|
+
throw new UlwLoopError(`Missing ${label}.`, "ULW_LOOP_ARGUMENT_MISSING");
|
|
1451
|
+
return trimmed;
|
|
1452
|
+
}
|
|
1453
|
+
function truncateObjective(objective) {
|
|
1454
|
+
return objective.length > 80 ? `${objective.slice(0, 77).trimEnd()}...` : objective;
|
|
1455
|
+
}
|
|
1456
|
+
function seedDefaultSuccessCriteria(goalIndex, objective) {
|
|
1457
|
+
const subject = truncateObjective(normalizeObjective4(objective) || `Goal ${goalIndex + 1}`);
|
|
1458
|
+
const rows = [
|
|
1459
|
+
[
|
|
1460
|
+
"C001",
|
|
1461
|
+
"happy",
|
|
1462
|
+
`happy path for: ${subject}`,
|
|
1463
|
+
`Replace via revise_criterion with observable happy-path proof for goal ${goalIndex + 1}.`,
|
|
1464
|
+
true
|
|
1465
|
+
],
|
|
1466
|
+
[
|
|
1467
|
+
"C002",
|
|
1468
|
+
"edge",
|
|
1469
|
+
"edge case (boundary/empty/malformed)",
|
|
1470
|
+
`Replace via revise_criterion with boundary or malformed-input proof for: ${subject}.`,
|
|
1471
|
+
true
|
|
1472
|
+
],
|
|
1473
|
+
[
|
|
1474
|
+
"C003",
|
|
1475
|
+
"regression",
|
|
1476
|
+
"regression: adjacent surface still works",
|
|
1477
|
+
`Replace via revise_criterion with regression proof for neighboring behavior after: ${subject}.`,
|
|
1478
|
+
false
|
|
1479
|
+
]
|
|
1480
|
+
];
|
|
1481
|
+
return rows.map(([id, userModel, scenario, expectedEvidence, essential]) => ({
|
|
1482
|
+
id,
|
|
1483
|
+
scenario,
|
|
1484
|
+
userModel,
|
|
1485
|
+
expectedEvidence,
|
|
1486
|
+
essential,
|
|
1487
|
+
capturedEvidence: null,
|
|
1488
|
+
status: "pending"
|
|
1489
|
+
}));
|
|
1490
|
+
}
|
|
1491
|
+
function deriveGoalCandidates(brief) {
|
|
1492
|
+
const bulletGoals = brief.split(/\r?\n/).map((line) => ({ original: line, cleaned: normalizeObjective4(cleanLine(line)) })).filter(({ cleaned }) => cleaned.length > 0 && cleaned.length <= 1200).filter(({ original, cleaned }, index, all) => /^\s*(?:[-*+]\s+|\d+[.)]\s+)/.test(original) && all.findIndex((candidate) => candidate.cleaned === cleaned) === index).map(({ cleaned }) => cleaned);
|
|
1493
|
+
const paragraphs = brief.split(/\n\s*\n/).map(normalizeObjective4).filter((paragraph) => paragraph.length > 0 && !paragraph.startsWith("#"));
|
|
1494
|
+
const selected = (bulletGoals.length > 0 ? bulletGoals : paragraphs).length > 0 ? bulletGoals.length > 0 ? bulletGoals : paragraphs : ["Complete the requested project objective."];
|
|
1495
|
+
return selected.map((objective, index) => ({
|
|
1496
|
+
title: titleFromObjective(objective, `Goal ${index + 1}`),
|
|
1497
|
+
objective
|
|
1498
|
+
}));
|
|
1499
|
+
}
|
|
1500
|
+
function makeGoal(title, objective, index, now) {
|
|
1501
|
+
const cleanTitle = assertNonEmpty(title, "title");
|
|
1502
|
+
const cleanObjective = assertNonEmpty(objective, "objective");
|
|
1503
|
+
return {
|
|
1504
|
+
id: normalizeGoalId(cleanTitle, index),
|
|
1505
|
+
title: cleanTitle,
|
|
1506
|
+
objective: cleanObjective,
|
|
1507
|
+
status: "pending",
|
|
1508
|
+
successCriteria: seedDefaultSuccessCriteria(index, cleanObjective),
|
|
1509
|
+
attempt: 0,
|
|
1510
|
+
createdAt: now,
|
|
1511
|
+
updatedAt: now
|
|
1512
|
+
};
|
|
1513
|
+
}
|
|
1514
|
+
function appendGoalToPlan(plan, title, objective, now) {
|
|
1515
|
+
const goal = makeGoal(title, objective, plan.goals.length, now);
|
|
1516
|
+
plan.goals.push(goal);
|
|
1517
|
+
plan.updatedAt = now;
|
|
1518
|
+
return goal;
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
// components/ulw-loop/src/plan-crud.ts
|
|
1522
|
+
function isScheduleEligible(goal) {
|
|
1523
|
+
return goal.steeringStatus !== "superseded" && goal.steeringStatus !== "blocked";
|
|
1524
|
+
}
|
|
1525
|
+
function clearGoalBlockerFields2(goal) {
|
|
1526
|
+
for (const key of [
|
|
1527
|
+
"blockedReason",
|
|
1528
|
+
"blockerSignature",
|
|
1529
|
+
"blockerOccurrenceCount",
|
|
1530
|
+
"requiredExternalDecision",
|
|
1531
|
+
"nonRetriable",
|
|
1532
|
+
"failedAt",
|
|
1533
|
+
"failureReason"
|
|
1534
|
+
])
|
|
1535
|
+
delete goal[key];
|
|
1536
|
+
}
|
|
1537
|
+
async function createUlwLoopPlan(repoRoot, args, scope) {
|
|
1538
|
+
return withUlwLoopMutationLock(repoRoot, scope, async () => {
|
|
1539
|
+
if (!args.force && existsSync4(ulwLoopGoalsPath(repoRoot, scope))) {
|
|
1540
|
+
const existing = await readUlwLoopPlan(repoRoot, scope);
|
|
1541
|
+
if (isUlwLoopDone(existing))
|
|
1542
|
+
throw completedPlanExistsError(scope);
|
|
1543
|
+
throw new UlwLoopError(`Refusing to overwrite existing ${ulwLoopGoalsRelativePath(scope)}; pass --force to recreate it.`, "ULW_LOOP_PLAN_EXISTS");
|
|
11
1544
|
}
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1545
|
+
const now = iso();
|
|
1546
|
+
const goals = deriveGoalCandidates(args.brief).map((goal, index) => makeGoal(goal.title, goal.objective, index, now));
|
|
1547
|
+
const plan = {
|
|
1548
|
+
version: 1,
|
|
1549
|
+
createdAt: now,
|
|
1550
|
+
updatedAt: now,
|
|
1551
|
+
briefPath: ulwLoopBriefRelativePath(scope),
|
|
1552
|
+
goalsPath: ulwLoopGoalsRelativePath(scope),
|
|
1553
|
+
ledgerPath: ulwLoopLedgerRelativePath(scope),
|
|
1554
|
+
codexGoalMode: args.codexGoalMode ?? "aggregate",
|
|
1555
|
+
goals
|
|
1556
|
+
};
|
|
1557
|
+
if (plan.codexGoalMode === "aggregate")
|
|
1558
|
+
plan.codexObjective = aggregateCodexObjectiveForScope(scope);
|
|
1559
|
+
await mkdir2(ulwLoopDir(repoRoot, scope), { recursive: true });
|
|
1560
|
+
await writeFile2(ulwLoopBriefPath(repoRoot, scope), args.brief.endsWith(`
|
|
1561
|
+
`) ? args.brief : `${args.brief}
|
|
1562
|
+
`, "utf8");
|
|
1563
|
+
await writePlan(repoRoot, plan, scope);
|
|
1564
|
+
await writeFile2(ulwLoopLedgerPath(repoRoot, scope), "", "utf8");
|
|
1565
|
+
await appendLedger(repoRoot, { at: now, kind: "plan_created", message: `${goals.length} goal(s) created` }, scope);
|
|
1566
|
+
return plan;
|
|
1567
|
+
});
|
|
1568
|
+
}
|
|
1569
|
+
function completedPlanExistsError(scope) {
|
|
1570
|
+
return new UlwLoopError([
|
|
1571
|
+
`Existing ulw-loop aggregate is already complete at ${ulwLoopGoalsRelativePath(scope)}.`,
|
|
1572
|
+
"Start a new run with `omo ulw-loop create-goals --session-id <new-id> ...` to isolate fresh state.",
|
|
1573
|
+
"Use --force only when you intentionally want to overwrite the completed evidence."
|
|
1574
|
+
].join(" "), "ULW_LOOP_PLAN_EXISTS_COMPLETE");
|
|
1575
|
+
}
|
|
1576
|
+
async function addUlwLoopGoal(repoRoot, args, scope) {
|
|
1577
|
+
return withUlwLoopMutationLock(repoRoot, scope, async () => {
|
|
1578
|
+
const plan = await readUlwLoopPlan(repoRoot, scope);
|
|
1579
|
+
const now = iso();
|
|
1580
|
+
const goal = appendGoalToPlan(plan, args.title, args.objective, now);
|
|
1581
|
+
await writePlan(repoRoot, plan, scope);
|
|
1582
|
+
await appendLedger(repoRoot, { at: now, kind: "goal_added", goalId: goal.id, status: goal.status, message: goal.title }, scope);
|
|
1583
|
+
return { plan, goal };
|
|
1584
|
+
});
|
|
1585
|
+
}
|
|
1586
|
+
async function startNextUlwLoop(repoRoot, args = {}, scope) {
|
|
1587
|
+
return withUlwLoopMutationLock(repoRoot, scope, async () => {
|
|
1588
|
+
const plan = await readUlwLoopPlan(repoRoot, scope);
|
|
1589
|
+
const now = iso();
|
|
1590
|
+
if (plan.aggregateCompletion?.status === "complete")
|
|
1591
|
+
return { done: true, plan };
|
|
1592
|
+
const existing = plan.goals.find((goal) => goal.status === "in_progress" && isScheduleEligible(goal));
|
|
1593
|
+
if (existing)
|
|
1594
|
+
return { plan, goal: existing, resumed: true };
|
|
1595
|
+
let next = plan.goals.find((goal) => goal.status === "pending" && isScheduleEligible(goal));
|
|
1596
|
+
if (!next && args.retryFailed) {
|
|
1597
|
+
next = plan.goals.find((goal) => goal.status === "failed" && !goal.nonRetriable && isScheduleEligible(goal));
|
|
1598
|
+
if (next)
|
|
1599
|
+
await appendLedger(repoRoot, {
|
|
1600
|
+
at: now,
|
|
1601
|
+
kind: "goal_retried",
|
|
1602
|
+
goalId: next.id,
|
|
1603
|
+
status: "pending",
|
|
1604
|
+
...next.failureReason ? { message: next.failureReason } : {}
|
|
1605
|
+
}, scope);
|
|
1606
|
+
}
|
|
1607
|
+
if (!next)
|
|
1608
|
+
return { done: true, plan };
|
|
1609
|
+
next.status = "in_progress";
|
|
1610
|
+
next.attempt += 1;
|
|
1611
|
+
next.startedAt = now;
|
|
1612
|
+
clearGoalBlockerFields2(next);
|
|
1613
|
+
next.updatedAt = now;
|
|
1614
|
+
plan.activeGoalId = next.id;
|
|
1615
|
+
plan.updatedAt = now;
|
|
1616
|
+
await writePlan(repoRoot, plan, scope);
|
|
1617
|
+
await appendLedger(repoRoot, { at: now, kind: "goal_started", goalId: next.id, status: next.status, message: `Attempt ${next.attempt}` }, scope);
|
|
1618
|
+
return { plan, goal: next, resumed: false };
|
|
1619
|
+
});
|
|
1620
|
+
}
|
|
1621
|
+
function summarizeUlwLoopPlan(plan) {
|
|
1622
|
+
const countStatus = (status) => plan.goals.filter((goal) => goal.status === status).length;
|
|
1623
|
+
const countCriteria = (status) => plan.goals.reduce((sum, goal) => sum + goal.successCriteria.filter((criterion) => criterion.status === status).length, 0);
|
|
1624
|
+
return {
|
|
1625
|
+
total: plan.goals.length,
|
|
1626
|
+
pending: countStatus("pending"),
|
|
1627
|
+
in_progress: countStatus("in_progress"),
|
|
1628
|
+
complete: countStatus("complete"),
|
|
1629
|
+
failed: countStatus("failed"),
|
|
1630
|
+
blocked: countStatus("blocked"),
|
|
1631
|
+
review_blocked: countStatus("review_blocked"),
|
|
1632
|
+
needs_user_decision: countStatus("needs_user_decision"),
|
|
1633
|
+
superseded: plan.goals.filter((goal) => goal.steeringStatus === "superseded").length,
|
|
1634
|
+
criteria: {
|
|
1635
|
+
total: plan.goals.reduce((sum, goal) => sum + goal.successCriteria.length, 0),
|
|
1636
|
+
pass: countCriteria("pass"),
|
|
1637
|
+
pending: countCriteria("pending"),
|
|
1638
|
+
fail: countCriteria("fail"),
|
|
1639
|
+
blocked: countCriteria("blocked")
|
|
1640
|
+
}
|
|
1641
|
+
};
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1644
|
+
// components/ulw-loop/src/review-blockers.ts
|
|
1645
|
+
var BLOCKER_FIELDS = "blockedReason blockerSignature blockerOccurrenceCount requiredExternalDecision nonRetriable failedAt failureReason completedAt blocker blockerEvidence blockerOccurrences blockedAt".split(" ");
|
|
1646
|
+
function ulwLoopError(message, code) {
|
|
1647
|
+
throw new UlwLoopError(message, code);
|
|
1648
|
+
}
|
|
1649
|
+
function nextGoalId(plan) {
|
|
1650
|
+
const max = plan.goals.reduce((current, goal) => {
|
|
1651
|
+
const digits = /^G(\d+)/u.exec(goal.id)?.[1];
|
|
1652
|
+
return digits === undefined ? current : Math.max(current, Number(digits));
|
|
1653
|
+
}, 0);
|
|
1654
|
+
return `G${String(max + 1).padStart(3, "0")}`;
|
|
1655
|
+
}
|
|
1656
|
+
function appendBlockerGoal(plan, args, now) {
|
|
1657
|
+
const index = plan.goals.length;
|
|
1658
|
+
const goal = {
|
|
1659
|
+
id: nextGoalId(plan),
|
|
1660
|
+
title: args.title,
|
|
1661
|
+
objective: args.objective,
|
|
1662
|
+
status: "pending",
|
|
1663
|
+
successCriteria: seedDefaultSuccessCriteria(index, args.objective),
|
|
1664
|
+
attempt: 0,
|
|
1665
|
+
createdAt: now,
|
|
1666
|
+
updatedAt: now
|
|
1667
|
+
};
|
|
1668
|
+
plan.goals.push(goal);
|
|
1669
|
+
return goal;
|
|
1670
|
+
}
|
|
1671
|
+
async function recordFinalReviewBlockers(repoRoot, args, scope) {
|
|
1672
|
+
return withUlwLoopMutationLock(repoRoot, scope, async () => {
|
|
1673
|
+
const plan = await readUlwLoopPlan(repoRoot, scope);
|
|
1674
|
+
const goal = plan.goals.find((candidate) => candidate.id === args.goalId);
|
|
1675
|
+
if (goal === undefined)
|
|
1676
|
+
ulwLoopError(`Unknown ulw-loop id: ${args.goalId}`, "ulw_loop_goal_not_found");
|
|
1677
|
+
if (goal.status !== "in_progress")
|
|
1678
|
+
ulwLoopError(`${goal.id} is ${goal.status}.`, "ulw_loop_goal_not_in_progress");
|
|
1679
|
+
if (!isFinalRunCompletionCandidate(plan, goal))
|
|
1680
|
+
ulwLoopError(`${goal.id} is not final.`, "ulw_loop_not_final_story");
|
|
1681
|
+
const snapshot = await readCodexGoalSnapshotInput(args.codexGoalJson, repoRoot);
|
|
1682
|
+
const aggregate = codexGoalMode(plan) === "aggregate";
|
|
1683
|
+
const reconciliation = reconcileCodexGoalSnapshot(snapshot, { expectedObjective: expectedCodexObjective(plan, goal), ...aggregate ? { acceptedObjectives: compatibleCodexObjectives(plan) } : {}, allowedStatuses: ["active"], requireSnapshot: true, requireComplete: false });
|
|
1684
|
+
if (!reconciliation.ok)
|
|
1685
|
+
ulwLoopError(reconciliation.errors.join(" "), "ulw_loop_codex_snapshot_mismatch");
|
|
1686
|
+
const now = iso();
|
|
1687
|
+
for (const field of BLOCKER_FIELDS)
|
|
1688
|
+
Reflect.deleteProperty(goal, field);
|
|
1689
|
+
goal.status = "review_blocked";
|
|
1690
|
+
goal.reviewBlockedAt = now;
|
|
1691
|
+
goal.evidence = args.evidence;
|
|
1692
|
+
goal.updatedAt = now;
|
|
1693
|
+
if (plan.activeGoalId === goal.id)
|
|
1694
|
+
delete plan.activeGoalId;
|
|
1695
|
+
const newGoal = appendBlockerGoal(plan, args, now);
|
|
1696
|
+
plan.updatedAt = now;
|
|
1697
|
+
const codexGoal = reconciliation.snapshot.raw;
|
|
1698
|
+
const blockedEntry = { at: now, kind: "goal_review_blocked", goalId: goal.id, status: goal.status, evidence: args.evidence, codexGoal };
|
|
1699
|
+
const addedEntry = { at: now, kind: "goal_added", goalId: newGoal.id, status: newGoal.status, evidence: args.evidence, message: newGoal.title };
|
|
1700
|
+
const summaryEntry = { at: now, kind: "goal_review_blocked", goalId: goal.id, status: goal.status, evidence: args.evidence, codexGoal, message: `Review blockers recorded; appended ${newGoal.id}.` };
|
|
1701
|
+
Reflect.set(summaryEntry, "kind", "blocker_recorded");
|
|
1702
|
+
const ledgerEntries = [blockedEntry, addedEntry, summaryEntry];
|
|
1703
|
+
await writePlan(repoRoot, plan, scope);
|
|
1704
|
+
for (const entry of ledgerEntries)
|
|
1705
|
+
await appendLedger(repoRoot, entry, scope);
|
|
1706
|
+
return { plan, blockedGoal: goal, newGoal, ledgerEntries };
|
|
1707
|
+
});
|
|
1708
|
+
}
|
|
1709
|
+
|
|
1710
|
+
// components/ulw-loop/src/steering.ts
|
|
1711
|
+
var SOURCES2 = ["user_prompt_submit", "finding", "cli"];
|
|
1712
|
+
var PROTECTED = new Set(["aggregateCompletion", "codexObjective", "codexObjectiveAliases", "originalConstraints", "qualityGate", "status", "completedAt", "completionStatus"]);
|
|
1713
|
+
var isObject = (value) => typeof value === "object" && value !== null;
|
|
1714
|
+
var isPlain2 = (value) => isObject(value) && !Array.isArray(value);
|
|
1715
|
+
var read = (value, key) => Object.entries(value).find(([name]) => name === key)?.[1];
|
|
1716
|
+
var isText = (value) => typeof value === "string" && value.trim().length > 0;
|
|
1717
|
+
var text2 = (value, key) => {
|
|
1718
|
+
const candidate = read(value, key);
|
|
1719
|
+
return isText(candidate) ? candidate.trim() : undefined;
|
|
1720
|
+
};
|
|
1721
|
+
var isKind2 = (value) => typeof value === "string" && ULW_LOOP_STEERING_MUTATION_KINDS.some((kind) => kind === value);
|
|
1722
|
+
var isSource2 = (value) => typeof value === "string" && SOURCES2.some((source) => source === value);
|
|
1723
|
+
var isModel2 = (value) => typeof value === "string" && ULW_LOOP_SUCCESS_CRITERION_USER_MODELS.some((model2) => model2 === value);
|
|
1724
|
+
var texts = (value, key) => {
|
|
1725
|
+
const candidate = read(value, key);
|
|
1726
|
+
return Array.isArray(candidate) && candidate.every((item) => typeof item === "string") ? candidate : [];
|
|
1727
|
+
};
|
|
1728
|
+
function targets(proposal) {
|
|
1729
|
+
const many = texts(proposal, "targetGoalIds");
|
|
1730
|
+
const one = text2(proposal, "targetGoalId") ?? text2(proposal, "goalId");
|
|
1731
|
+
return many.length > 0 ? many : one === undefined ? [] : [one];
|
|
1732
|
+
}
|
|
1733
|
+
var after = (proposal) => {
|
|
1734
|
+
const candidate = read(proposal, "after");
|
|
1735
|
+
return isPlain2(candidate) ? candidate : undefined;
|
|
1736
|
+
};
|
|
1737
|
+
var revised = (proposal, direct, nested) => text2(proposal, direct) ?? text2(after(proposal) ?? proposal, nested);
|
|
1738
|
+
function child2(value) {
|
|
1739
|
+
if (!isPlain2(value))
|
|
1740
|
+
return null;
|
|
1741
|
+
const title = text2(value, "title");
|
|
1742
|
+
const objective = text2(value, "objective");
|
|
1743
|
+
if (title === undefined || objective === undefined)
|
|
1744
|
+
return null;
|
|
1745
|
+
return { title, objective };
|
|
1746
|
+
}
|
|
1747
|
+
function childValues(proposal) {
|
|
1748
|
+
const direct = read(proposal, "childGoals");
|
|
1749
|
+
if (Array.isArray(direct) && direct.length > 0)
|
|
1750
|
+
return direct;
|
|
1751
|
+
const nested = after(proposal);
|
|
1752
|
+
const fromAfter = nested === undefined ? undefined : read(nested, "children");
|
|
1753
|
+
return Array.isArray(fromAfter) ? fromAfter : [];
|
|
1754
|
+
}
|
|
1755
|
+
var children2 = (proposal) => childValues(proposal).map(child2).filter((item) => item !== null);
|
|
1756
|
+
var pendingOrder = (proposal) => {
|
|
1757
|
+
const direct = texts(proposal, "pendingOrder");
|
|
1758
|
+
return direct.length > 0 ? direct : texts(after(proposal) ?? proposal, "pendingGoalIds");
|
|
1759
|
+
};
|
|
1760
|
+
function hasProtected(value) {
|
|
1761
|
+
if (!isObject(value))
|
|
1762
|
+
return false;
|
|
1763
|
+
for (const [key, childValue] of Object.entries(value))
|
|
1764
|
+
if (PROTECTED.has(key) || key.toLowerCase().includes("complete") || hasProtected(childValue))
|
|
1765
|
+
return true;
|
|
1766
|
+
return false;
|
|
1767
|
+
}
|
|
1768
|
+
function allText(value) {
|
|
1769
|
+
if (typeof value === "string")
|
|
1770
|
+
return value;
|
|
1771
|
+
return isObject(value) ? Object.values(value).map(allText).filter(Boolean).join(`
|
|
1772
|
+
`) : "";
|
|
1773
|
+
}
|
|
1774
|
+
function weakens(value) {
|
|
1775
|
+
const valueText = allText(value).toLowerCase();
|
|
1776
|
+
return /\b(skip|bypass|weaken|remove|omit|auto[-\s]?complete|mark complete|complete faster)\b/.test(valueText) && /\b(test|tests|verification|review|quality gate|complete|completion)\b/.test(valueText);
|
|
1777
|
+
}
|
|
1778
|
+
function auditFor(proposal, reasons) {
|
|
1779
|
+
const object = isPlain2(proposal) ? proposal : undefined;
|
|
1780
|
+
const kindRaw = object === undefined ? undefined : read(object, "kind");
|
|
1781
|
+
const sourceRaw = object === undefined ? undefined : read(object, "source");
|
|
1782
|
+
const evidence = object === undefined ? "" : text2(object, "evidence") ?? "";
|
|
1783
|
+
const rationale = object === undefined ? "" : text2(object, "rationale") ?? "";
|
|
1784
|
+
const audit = { kind: isKind2(kindRaw) ? kindRaw : "annotate_ledger", source: isSource2(sourceRaw) ? sourceRaw : "cli", targetGoalIds: object === undefined ? [] : targets(object), evidence, rationale, invariant: { accepted: reasons.length === 0, structuralInvariantAccepted: reasons.length === 0, evidenceBackedNecessity: evidence.length > 0 && rationale.length > 0, noEasierCompletion: !weakens(proposal), rejectedReasons: reasons, reasons } };
|
|
1785
|
+
if (object === undefined)
|
|
1786
|
+
return audit;
|
|
1787
|
+
const criterionId = text2(object, "criterionId");
|
|
1788
|
+
const directiveText = text2(object, "directiveText");
|
|
1789
|
+
const promptSignature = text2(object, "promptSignature");
|
|
1790
|
+
const idempotencyKey = text2(object, "idempotencyKey");
|
|
1791
|
+
if (criterionId !== undefined)
|
|
1792
|
+
audit.criterionId = criterionId;
|
|
1793
|
+
if (directiveText !== undefined)
|
|
1794
|
+
audit.directiveText = directiveText;
|
|
1795
|
+
if (promptSignature !== undefined)
|
|
1796
|
+
audit.promptSignature = promptSignature;
|
|
1797
|
+
if (idempotencyKey !== undefined)
|
|
1798
|
+
audit.idempotencyKey = idempotencyKey;
|
|
1799
|
+
return audit;
|
|
1800
|
+
}
|
|
1801
|
+
function validateUlwLoopSteeringProposal(plan, proposal) {
|
|
1802
|
+
const reasons = [];
|
|
1803
|
+
if (!isPlain2(proposal))
|
|
1804
|
+
reasons.push("proposal must be an object");
|
|
1805
|
+
const object = isPlain2(proposal) ? proposal : {};
|
|
1806
|
+
const kind = read(object, "kind");
|
|
1807
|
+
if (!isKind2(kind))
|
|
1808
|
+
reasons.push(`invalid kind: ${String(kind)}`);
|
|
1809
|
+
if (!isSource2(read(object, "source")))
|
|
1810
|
+
reasons.push(`invalid source: ${String(read(object, "source"))}`);
|
|
1811
|
+
if (text2(object, "evidence") === undefined)
|
|
1812
|
+
reasons.push("missing evidence");
|
|
1813
|
+
if (text2(object, "rationale") === undefined)
|
|
1814
|
+
reasons.push("missing rationale");
|
|
1815
|
+
if (hasProtected(proposal))
|
|
1816
|
+
reasons.push("protected payload");
|
|
1817
|
+
if (weakens(proposal))
|
|
1818
|
+
reasons.push("weakened completion");
|
|
1819
|
+
if (isUlwLoopDone(plan))
|
|
1820
|
+
reasons.push("plan already complete");
|
|
1821
|
+
if (isKind2(kind))
|
|
1822
|
+
validateKind(plan, object, kind, reasons);
|
|
1823
|
+
return auditFor(proposal, reasons);
|
|
1824
|
+
}
|
|
1825
|
+
function goal(plan, id) {
|
|
1826
|
+
return id === undefined ? undefined : plan.goals.find((item) => item.id === id);
|
|
1827
|
+
}
|
|
1828
|
+
function validateKind(plan, proposal, kind, reasons) {
|
|
1829
|
+
const target = goal(plan, targets(proposal)[0]);
|
|
1830
|
+
if (kind === "add_subgoal" && (text2(proposal, "title") === undefined || text2(proposal, "objective") === undefined))
|
|
1831
|
+
reasons.push("add_subgoal requires title/objective");
|
|
1832
|
+
if ((kind === "split_subgoal" || kind === "revise_pending_wording" || kind === "mark_blocked_superseded") && target === undefined)
|
|
1833
|
+
reasons.push(`${kind} requires target`);
|
|
1834
|
+
if ((kind === "split_subgoal" || kind === "revise_pending_wording") && target !== undefined && target.status !== "pending")
|
|
1835
|
+
reasons.push(`${kind} requires pending target`);
|
|
1836
|
+
const rawChildren = childValues(proposal);
|
|
1837
|
+
if (kind === "split_subgoal" && rawChildren.length === 0)
|
|
1838
|
+
reasons.push("split_subgoal requires children");
|
|
1839
|
+
if ((kind === "split_subgoal" || kind === "mark_blocked_superseded") && rawChildren.some((item) => child2(item) === null))
|
|
1840
|
+
reasons.push(`${kind} children require title/objective`);
|
|
1841
|
+
if (kind === "reorder_pending")
|
|
1842
|
+
validateOrder(plan, proposal, reasons);
|
|
1843
|
+
if (kind === "revise_pending_wording" && revised(proposal, "revisedTitle", "title") === undefined && revised(proposal, "revisedObjective", "objective") === undefined)
|
|
1844
|
+
reasons.push("revise_pending_wording requires update");
|
|
1845
|
+
if (kind === "revise_criterion")
|
|
1846
|
+
validateCriterion(plan, proposal, reasons);
|
|
1847
|
+
}
|
|
1848
|
+
function validateOrder(plan, proposal, reasons) {
|
|
1849
|
+
const requested = pendingOrder(proposal);
|
|
1850
|
+
const pending = plan.goals.filter((item) => item.status === "pending" && item.steeringStatus === undefined).map((item) => item.id);
|
|
1851
|
+
if (requested.length === 0)
|
|
1852
|
+
reasons.push("reorder_pending requires ids");
|
|
1853
|
+
if (new Set(requested).size !== requested.length)
|
|
1854
|
+
reasons.push("duplicate pending id");
|
|
1855
|
+
if (requested.some((id) => !pending.includes(id)))
|
|
1856
|
+
reasons.push("unknown pending id");
|
|
1857
|
+
}
|
|
1858
|
+
function validateCriterion(plan, proposal, reasons) {
|
|
1859
|
+
const target = goal(plan, targets(proposal)[0]);
|
|
1860
|
+
const criterionId = text2(proposal, "criterionId");
|
|
1861
|
+
if (target === undefined)
|
|
1862
|
+
reasons.push("revise_criterion requires goalId");
|
|
1863
|
+
else if (criterionId === undefined || target.successCriteria.every((item) => item.id !== criterionId))
|
|
1864
|
+
reasons.push("revise_criterion requires criterionId");
|
|
1865
|
+
const model2 = read(proposal, "userModel");
|
|
1866
|
+
if (read(proposal, "scenario") === undefined && read(proposal, "expectedEvidence") === undefined && model2 === undefined)
|
|
1867
|
+
reasons.push("revise_criterion requires update");
|
|
1868
|
+
if (model2 !== undefined && !isModel2(model2))
|
|
1869
|
+
reasons.push("invalid userModel");
|
|
1870
|
+
}
|
|
1871
|
+
function nextId(plan, offset) {
|
|
1872
|
+
const max = plan.goals.reduce((current, item) => {
|
|
1873
|
+
const digits = /^G(\d+)(?:-|$)/u.exec(item.id)?.[1];
|
|
1874
|
+
return digits === undefined ? current : Math.max(current, Number(digits));
|
|
1875
|
+
}, 0);
|
|
1876
|
+
return `G${String(max + offset).padStart(3, "0")}`;
|
|
1877
|
+
}
|
|
1878
|
+
function makeGoal2(plan, childGoal, evidence, now, offset) {
|
|
1879
|
+
const id = nextId(plan, offset);
|
|
1880
|
+
const digits = /^G(\d+)/u.exec(id)?.[1];
|
|
1881
|
+
const goalIndex = digits === undefined ? plan.goals.length + offset - 1 : Number(digits) - 1;
|
|
1882
|
+
return { id, title: childGoal.title, objective: childGoal.objective, status: "pending", successCriteria: seedDefaultSuccessCriteria(goalIndex, childGoal.objective), attempt: 0, createdAt: now, updatedAt: now, evidence };
|
|
1883
|
+
}
|
|
1884
|
+
function applySteeringMutation(plan, proposal, audit) {
|
|
1885
|
+
const next = structuredClone(plan);
|
|
1886
|
+
if (!audit.invariant.accepted)
|
|
1887
|
+
return next;
|
|
1888
|
+
const now = proposal.now?.toISOString() ?? iso();
|
|
1889
|
+
if (proposal.kind === "add_subgoal")
|
|
1890
|
+
next.goals.push(makeGoal2(next, { title: proposal.title ?? "", objective: proposal.objective ?? "" }, proposal.evidence, now, 1));
|
|
1891
|
+
if (proposal.kind === "reorder_pending") {
|
|
1892
|
+
const order = pendingOrder(proposal);
|
|
1893
|
+
next.goals = [...order.map((id) => goal(next, id)).filter((item) => item !== undefined), ...next.goals.filter((item) => !order.includes(item.id))];
|
|
1894
|
+
}
|
|
1895
|
+
if (proposal.kind === "revise_pending_wording")
|
|
1896
|
+
reviseWording(next, proposal, now);
|
|
1897
|
+
if (proposal.kind === "split_subgoal" || proposal.kind === "mark_blocked_superseded")
|
|
1898
|
+
splitOrBlock(next, proposal, now);
|
|
1899
|
+
if (proposal.kind === "revise_criterion")
|
|
1900
|
+
reviseCriterion(next, proposal, now);
|
|
1901
|
+
if (proposal.kind !== "annotate_ledger")
|
|
1902
|
+
next.updatedAt = now;
|
|
1903
|
+
return next;
|
|
1904
|
+
}
|
|
1905
|
+
function reviseWording(plan, proposal, now) {
|
|
1906
|
+
const target = goal(plan, targets(proposal)[0]);
|
|
1907
|
+
if (target === undefined)
|
|
1908
|
+
return;
|
|
1909
|
+
target.title = revised(proposal, "revisedTitle", "title") ?? target.title;
|
|
1910
|
+
target.objective = revised(proposal, "revisedObjective", "objective") ?? target.objective;
|
|
1911
|
+
target.steeringEvidence = proposal.evidence;
|
|
1912
|
+
target.steeringRationale = proposal.rationale;
|
|
1913
|
+
target.updatedAt = now;
|
|
1914
|
+
}
|
|
1915
|
+
function splitOrBlock(plan, proposal, now) {
|
|
1916
|
+
const target = goal(plan, targets(proposal)[0]);
|
|
1917
|
+
if (target === undefined)
|
|
1918
|
+
return;
|
|
1919
|
+
const replacements = children2(proposal).map((item, index) => makeGoal2(plan, item, proposal.evidence, now, index + 1));
|
|
1920
|
+
target.steeringEvidence = proposal.evidence;
|
|
1921
|
+
target.steeringRationale = proposal.rationale;
|
|
1922
|
+
target.updatedAt = now;
|
|
1923
|
+
if (replacements.length === 0) {
|
|
1924
|
+
target.status = "blocked";
|
|
1925
|
+
target.steeringStatus = "blocked";
|
|
1926
|
+
target.blockedReason = proposal.blockedReason ?? proposal.rationale;
|
|
1927
|
+
} else {
|
|
1928
|
+
target.steeringStatus = "superseded";
|
|
1929
|
+
target.supersededBy = replacements.map((item) => item.id);
|
|
1930
|
+
for (const item of replacements)
|
|
1931
|
+
item.supersedes = [target.id];
|
|
1932
|
+
plan.goals.splice(plan.goals.indexOf(target) + 1, 0, ...replacements);
|
|
1933
|
+
}
|
|
1934
|
+
if (plan.activeGoalId === target.id)
|
|
1935
|
+
delete plan.activeGoalId;
|
|
1936
|
+
}
|
|
1937
|
+
function reviseCriterion(plan, proposal, now) {
|
|
1938
|
+
const target = goal(plan, targets(proposal)[0]);
|
|
1939
|
+
const index = target?.successCriteria.findIndex((item) => item.id === proposal.criterionId) ?? -1;
|
|
1940
|
+
const current = target?.successCriteria[index];
|
|
1941
|
+
if (target === undefined || current === undefined)
|
|
1942
|
+
return;
|
|
1943
|
+
const model2 = read(proposal, "userModel");
|
|
1944
|
+
target.successCriteria[index] = { ...current, scenario: text2(proposal, "scenario") ?? current.scenario, expectedEvidence: text2(proposal, "expectedEvidence") ?? current.expectedEvidence, userModel: isModel2(model2) ? model2 : current.userModel };
|
|
1945
|
+
target.updatedAt = now;
|
|
1946
|
+
}
|
|
1947
|
+
function isProposal(value) {
|
|
1948
|
+
return isPlain2(value) && isKind2(read(value, "kind")) && isSource2(read(value, "source")) && isText(read(value, "evidence")) && isText(read(value, "rationale"));
|
|
1949
|
+
}
|
|
1950
|
+
function parseUlwLoopSteeringDirective(text3) {
|
|
1951
|
+
const match = /(?:^|\s)(?:OMO_ULW_LOOP_STEER|omo\.ulw-loop\.steer|omo ulw-loop steer):\s*([\s\S]+)$/u.exec(text3);
|
|
1952
|
+
if (match?.[1] === undefined)
|
|
1953
|
+
return null;
|
|
1954
|
+
try {
|
|
1955
|
+
const parsed = JSON.parse(match[1].trim());
|
|
1956
|
+
return isProposal(parsed) ? parsed : null;
|
|
1957
|
+
} catch (error) {
|
|
1958
|
+
if (error instanceof SyntaxError)
|
|
1959
|
+
return null;
|
|
1960
|
+
throw error;
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
async function steerUlwLoop(repoRoot, proposal, scope) {
|
|
1964
|
+
return withUlwLoopMutationLock(repoRoot, scope, async () => {
|
|
1965
|
+
const plan = await readUlwLoopPlan(repoRoot, scope);
|
|
1966
|
+
const key = proposal.idempotencyKey ?? proposal.promptSignature;
|
|
1967
|
+
const prior = key === undefined ? undefined : (await readSteeringLedgerEntries(repoRoot, scope)).find((entry) => entry.steering?.invariant.accepted === true && (entry.idempotencyKey === key || entry.steering.idempotencyKey === key || entry.steering.promptSignature === key));
|
|
1968
|
+
if (prior?.steering !== undefined)
|
|
1969
|
+
return { plan, accepted: true, audit: { ...prior.steering, deduped: true }, rejectedReasons: [], deduped: true };
|
|
1970
|
+
const audit = validateUlwLoopSteeringProposal(plan, proposal);
|
|
1971
|
+
const accepted = audit.invariant.accepted;
|
|
1972
|
+
const next = accepted ? applySteeringMutation(plan, proposal, audit) : plan;
|
|
1973
|
+
const finalAudit = { ...audit, before: plan };
|
|
1974
|
+
if (accepted)
|
|
1975
|
+
finalAudit.after = next;
|
|
1976
|
+
if (accepted)
|
|
1977
|
+
await writePlan(repoRoot, next, scope);
|
|
1978
|
+
await appendLedger(repoRoot, ledgerEntry(proposal, finalAudit, proposal.now?.toISOString() ?? iso()), scope);
|
|
1979
|
+
return { plan: next, accepted, audit: finalAudit, rejectedReasons: audit.invariant.rejectedReasons, deduped: false };
|
|
1980
|
+
});
|
|
1981
|
+
}
|
|
1982
|
+
function ledgerEntry(proposal, audit, at) {
|
|
1983
|
+
const entry = { at, kind: audit.invariant.accepted ? proposal.kind === "revise_criterion" ? "criteria_revised" : "steering_accepted" : "steering_rejected", evidence: proposal.evidence, message: proposal.rationale, steering: audit, mutationKind: proposal.kind };
|
|
1984
|
+
const goalId = audit.targetGoalIds[0];
|
|
1985
|
+
if (goalId !== undefined)
|
|
1986
|
+
entry.goalId = goalId;
|
|
1987
|
+
if (proposal.criterionId !== undefined)
|
|
1988
|
+
entry.criterionId = proposal.criterionId;
|
|
1989
|
+
if (proposal.idempotencyKey !== undefined)
|
|
1990
|
+
entry.idempotencyKey = proposal.idempotencyKey;
|
|
1991
|
+
if (audit.before !== undefined)
|
|
1992
|
+
entry.before = audit.before;
|
|
1993
|
+
if (audit.after !== undefined)
|
|
1994
|
+
entry.after = audit.after;
|
|
1995
|
+
return entry;
|
|
1996
|
+
}
|
|
1997
|
+
|
|
1998
|
+
// components/ulw-loop/src/cli-subcommands.ts
|
|
1999
|
+
async function createGoals(repoRoot, argv, json, scope) {
|
|
2000
|
+
const briefFile = readValue(argv, "--brief-file");
|
|
2001
|
+
const brief = readValue(argv, "--brief") ?? (briefFile === undefined ? undefined : await readFile6(briefFile, "utf8")) ?? (hasFlag(argv, "--from-stdin") ? await readStdin() : undefined) ?? positionalText(argv);
|
|
2002
|
+
if (!brief.trim()) {
|
|
2003
|
+
throw new UlwLoopError("Missing brief text. Pass --brief, --brief-file, --from-stdin, or positional text.", "ULW_LOOP_BRIEF_REQUIRED");
|
|
2004
|
+
}
|
|
2005
|
+
const plan = await createUlwLoopPlan(repoRoot, {
|
|
2006
|
+
brief,
|
|
2007
|
+
codexGoalMode: normalizeCodexGoalMode(readValue(argv, "--codex-goal-mode")),
|
|
2008
|
+
force: hasFlag(argv, "--force")
|
|
2009
|
+
}, scope);
|
|
2010
|
+
if (json)
|
|
2011
|
+
printJson({ ok: true, plan, summary: summarizeUlwLoopPlan(plan) });
|
|
2012
|
+
else {
|
|
2013
|
+
process.stdout.write(`ulw-loop plan created: ${plan.goals.length} goal(s)
|
|
2014
|
+
brief: ${plan.briefPath}
|
|
2015
|
+
goals: ${plan.goalsPath}
|
|
2016
|
+
ledger: ${plan.ledgerPath}
|
|
2017
|
+
`);
|
|
2018
|
+
}
|
|
2019
|
+
return 0;
|
|
2020
|
+
}
|
|
2021
|
+
async function status(repoRoot, json, scope) {
|
|
2022
|
+
const plan = await readUlwLoopPlan(repoRoot, scope);
|
|
2023
|
+
if (json)
|
|
2024
|
+
printJson({ ok: true, plan, summary: summarizeUlwLoopPlan(plan) });
|
|
2025
|
+
else
|
|
2026
|
+
printStatus(plan);
|
|
2027
|
+
return 0;
|
|
2028
|
+
}
|
|
2029
|
+
async function completeGoals(repoRoot, argv, json, scope) {
|
|
2030
|
+
const result = await startNextUlwLoop(repoRoot, { retryFailed: hasFlag(argv, "--retry-failed") }, scope);
|
|
2031
|
+
if ("done" in result) {
|
|
2032
|
+
const handoff = blockedDecisionHandoff(result.plan);
|
|
2033
|
+
if (json) {
|
|
2034
|
+
printJson({
|
|
2035
|
+
ok: true,
|
|
2036
|
+
done: true,
|
|
2037
|
+
blocked: handoff.length > 0,
|
|
2038
|
+
handoff,
|
|
2039
|
+
summary: summarizeUlwLoopPlan(result.plan),
|
|
2040
|
+
plan: result.plan
|
|
2041
|
+
});
|
|
2042
|
+
} else
|
|
2043
|
+
process.stdout.write(`${handoff || "ulw-loop: all goals complete"}
|
|
2044
|
+
`);
|
|
2045
|
+
return 0;
|
|
2046
|
+
}
|
|
2047
|
+
const instruction = buildCodexGoalInstruction({ plan: result.plan, goal: result.goal });
|
|
2048
|
+
if (json)
|
|
2049
|
+
printJson({ ok: true, resumed: result.resumed, goal: result.goal, instruction, plan: result.plan });
|
|
2050
|
+
else
|
|
2051
|
+
process.stdout.write(`${instruction.text}
|
|
2052
|
+
`);
|
|
2053
|
+
return 0;
|
|
2054
|
+
}
|
|
2055
|
+
async function checkpoint(repoRoot, argv, json, scope) {
|
|
2056
|
+
const goalId = required3(argv, "--goal-id");
|
|
2057
|
+
const statusValue = checkpointStatus(required3(argv, "--status"));
|
|
2058
|
+
const evidence = required3(argv, "--evidence");
|
|
2059
|
+
const codexGoalJson = await parseCodexGoalJson(statusValue === "complete" ? required3(argv, "--codex-goal-json") : readValue(argv, "--codex-goal-json"));
|
|
2060
|
+
if (statusValue === "complete" && codexGoalJson === undefined) {
|
|
2061
|
+
throw new UlwLoopError("Missing --codex-goal-json.", "ULW_LOOP_CODEX_GOAL_JSON_REQUIRED");
|
|
2062
|
+
}
|
|
2063
|
+
const qualityGateJson = readValue(argv, "--quality-gate-json");
|
|
2064
|
+
const args = {
|
|
2065
|
+
goalId,
|
|
2066
|
+
status: statusValue,
|
|
2067
|
+
evidence,
|
|
2068
|
+
...codexGoalJson === undefined ? {} : { codexGoalJson },
|
|
2069
|
+
...qualityGateJson === undefined ? {} : { qualityGateJson }
|
|
2070
|
+
};
|
|
2071
|
+
const result = await checkpointUlwLoop(repoRoot, args, scope);
|
|
2072
|
+
if (json)
|
|
2073
|
+
printJson({ ok: true, ...result, summary: summarizeUlwLoopPlan(result.plan) });
|
|
2074
|
+
else
|
|
2075
|
+
process.stdout.write(`ulw-loop checkpoint: ${result.goal.id} -> ${result.goal.status}
|
|
2076
|
+
`);
|
|
2077
|
+
return 0;
|
|
2078
|
+
}
|
|
2079
|
+
async function steer(repoRoot, argv, json, scope) {
|
|
2080
|
+
const proposal = await parseSteeringProposal(argv);
|
|
2081
|
+
const result = await steerUlwLoop(repoRoot, proposal, scope);
|
|
2082
|
+
printSteerResult(result, json);
|
|
2083
|
+
return result.accepted ? 0 : 1;
|
|
2084
|
+
}
|
|
2085
|
+
async function addGoal(repoRoot, argv, json, scope) {
|
|
2086
|
+
const result = await addUlwLoopGoal(repoRoot, { title: required3(argv, "--title"), objective: required3(argv, "--objective") }, scope);
|
|
2087
|
+
if (json)
|
|
2088
|
+
printJson({ ok: true, plan: result.plan, goal: result.goal, summary: summarizeUlwLoopPlan(result.plan) });
|
|
2089
|
+
else {
|
|
2090
|
+
process.stdout.write(`ulw-loop added goal: ${result.goal.id}
|
|
2091
|
+
`);
|
|
2092
|
+
printStatus(result.plan);
|
|
2093
|
+
}
|
|
2094
|
+
return 0;
|
|
2095
|
+
}
|
|
2096
|
+
async function criteria(repoRoot, argv, json, scope) {
|
|
2097
|
+
const goalId = required3(argv, "--goal-id");
|
|
2098
|
+
const goal2 = findGoal3(await readUlwLoopPlan(repoRoot, scope), goalId);
|
|
2099
|
+
if (json)
|
|
2100
|
+
printJson({ ok: true, goalId: goal2.id, criteria: goal2.successCriteria });
|
|
2101
|
+
else {
|
|
2102
|
+
process.stdout.write(`criteria for ${goal2.id}:
|
|
2103
|
+
${goal2.successCriteria.map(formatCriterionForCli).join(`
|
|
2104
|
+
`)}
|
|
2105
|
+
`);
|
|
2106
|
+
}
|
|
2107
|
+
return 0;
|
|
2108
|
+
}
|
|
2109
|
+
async function captureEvidence(repoRoot, argv, json, scope) {
|
|
2110
|
+
const result = await recordEvidence(repoRoot, parseRecordEvidenceArgs(argv), scope);
|
|
2111
|
+
if (json)
|
|
2112
|
+
printJson({ ok: true, ...result, summary: summarizeUlwLoopPlan(result.plan) });
|
|
2113
|
+
else {
|
|
2114
|
+
process.stdout.write(`ulw-loop evidence recorded: ${result.goal.id}/${result.criterion.id} -> ${result.criterion.status}
|
|
2115
|
+
`);
|
|
2116
|
+
}
|
|
2117
|
+
return 0;
|
|
2118
|
+
}
|
|
2119
|
+
async function reviewBlockers(repoRoot, argv, json, scope) {
|
|
2120
|
+
const codexGoalJson = await parseCodexGoalJson(required3(argv, "--codex-goal-json"));
|
|
2121
|
+
if (codexGoalJson === undefined) {
|
|
2122
|
+
throw new UlwLoopError("Missing --codex-goal-json.", "ULW_LOOP_CODEX_GOAL_JSON_REQUIRED");
|
|
2123
|
+
}
|
|
2124
|
+
const result = await recordFinalReviewBlockers(repoRoot, {
|
|
2125
|
+
goalId: required3(argv, "--goal-id"),
|
|
2126
|
+
title: required3(argv, "--title"),
|
|
2127
|
+
objective: required3(argv, "--objective"),
|
|
2128
|
+
evidence: required3(argv, "--evidence"),
|
|
2129
|
+
codexGoalJson
|
|
2130
|
+
}, scope);
|
|
2131
|
+
if (json) {
|
|
2132
|
+
printJson({
|
|
2133
|
+
ok: true,
|
|
2134
|
+
plan: result.plan,
|
|
2135
|
+
blockedGoal: result.blockedGoal,
|
|
2136
|
+
goal: result.newGoal,
|
|
2137
|
+
ledgerEntries: result.ledgerEntries,
|
|
2138
|
+
summary: summarizeUlwLoopPlan(result.plan)
|
|
2139
|
+
});
|
|
2140
|
+
} else {
|
|
2141
|
+
process.stdout.write(`ulw-loop final review blockers recorded: ${result.blockedGoal.id} -> review_blocked; added ${result.newGoal.id}
|
|
2142
|
+
`);
|
|
2143
|
+
}
|
|
2144
|
+
return 0;
|
|
2145
|
+
}
|
|
2146
|
+
function formatCriterionForCli(criterion) {
|
|
2147
|
+
const marker = isEssentialCriterion(criterion) ? "essential" : "non-essential";
|
|
2148
|
+
return `- ${criterion.id} [${criterion.status}] [${marker}] (${criterion.userModel}) ${criterion.scenario} evidence: ${criterion.capturedEvidence ?? "pending"}`;
|
|
2149
|
+
}
|
|
2150
|
+
function required3(argv, flag) {
|
|
2151
|
+
const value = readValue(argv, flag)?.trim();
|
|
2152
|
+
if (value)
|
|
2153
|
+
return value;
|
|
2154
|
+
throw new UlwLoopError(`Missing ${flag}.`, "ULW_LOOP_ARGUMENT_MISSING", { details: { flag } });
|
|
2155
|
+
}
|
|
2156
|
+
function checkpointStatus(value) {
|
|
2157
|
+
if (value === "complete" || value === "failed" || value === "blocked")
|
|
2158
|
+
return value;
|
|
2159
|
+
throw new UlwLoopError("Missing or invalid --status; expected complete, failed, or blocked.", "ULW_LOOP_STATUS_INVALID", { details: { status: value } });
|
|
2160
|
+
}
|
|
2161
|
+
function findGoal3(plan, goalId) {
|
|
2162
|
+
const goal2 = plan.goals.find((candidate) => candidate.id === goalId);
|
|
2163
|
+
if (goal2 !== undefined)
|
|
2164
|
+
return goal2;
|
|
2165
|
+
throw new UlwLoopError(`Unknown ulw-loop id: ${goalId}.`, "ULW_LOOP_GOAL_NOT_FOUND", { details: { goalId } });
|
|
2166
|
+
}
|
|
2167
|
+
|
|
2168
|
+
// components/ulw-loop/src/cli-commands.ts
|
|
2169
|
+
var ULW_LOOP_SUBCOMMANDS = [
|
|
2170
|
+
"help",
|
|
2171
|
+
"create-goals",
|
|
2172
|
+
"status",
|
|
2173
|
+
"complete-goals",
|
|
2174
|
+
"checkpoint",
|
|
2175
|
+
"steer",
|
|
2176
|
+
"add-goal",
|
|
2177
|
+
"criteria",
|
|
2178
|
+
"record-evidence",
|
|
2179
|
+
"record-review-blockers"
|
|
2180
|
+
];
|
|
2181
|
+
function isUlwLoopSubcommand(value) {
|
|
2182
|
+
return ULW_LOOP_SUBCOMMANDS.includes(value);
|
|
2183
|
+
}
|
|
2184
|
+
async function ulwLoopCommand(argv) {
|
|
2185
|
+
const head = argv[0] ?? "help";
|
|
2186
|
+
const command = head === "--help" || head === "-h" ? "help" : head;
|
|
2187
|
+
const rest = argv.slice(1);
|
|
2188
|
+
const repoRoot = process.cwd();
|
|
2189
|
+
const json = hasFlag(rest, "--json");
|
|
2190
|
+
const scope = commandScope(rest);
|
|
2191
|
+
try {
|
|
2192
|
+
if (!isUlwLoopSubcommand(command)) {
|
|
2193
|
+
if (json) {
|
|
2194
|
+
printJsonError(new UlwLoopError(`Unknown ulw-loop subcommand: ${command}.`, "ULW_LOOP_SUBCOMMAND_UNKNOWN", {
|
|
2195
|
+
details: { command }
|
|
2196
|
+
}));
|
|
25
2197
|
return 1;
|
|
2198
|
+
}
|
|
2199
|
+
process.stdout.write(`${ULW_LOOP_HELP}
|
|
2200
|
+
`);
|
|
2201
|
+
return 1;
|
|
2202
|
+
}
|
|
2203
|
+
switch (command) {
|
|
2204
|
+
case "help":
|
|
2205
|
+
process.stdout.write(`${ULW_LOOP_HELP}
|
|
2206
|
+
`);
|
|
2207
|
+
return 0;
|
|
2208
|
+
case "create-goals":
|
|
2209
|
+
return await createGoals(repoRoot, rest, json, scope);
|
|
2210
|
+
case "status":
|
|
2211
|
+
return await status(repoRoot, json, scope);
|
|
2212
|
+
case "complete-goals":
|
|
2213
|
+
return await completeGoals(repoRoot, rest, json, scope);
|
|
2214
|
+
case "checkpoint":
|
|
2215
|
+
return await checkpoint(repoRoot, rest, json, scope);
|
|
2216
|
+
case "steer":
|
|
2217
|
+
return await steer(repoRoot, rest, json, scope);
|
|
2218
|
+
case "add-goal":
|
|
2219
|
+
return await addGoal(repoRoot, rest, json, scope);
|
|
2220
|
+
case "criteria":
|
|
2221
|
+
return await criteria(repoRoot, rest, json, scope);
|
|
2222
|
+
case "record-evidence":
|
|
2223
|
+
return await captureEvidence(repoRoot, rest, json, scope);
|
|
2224
|
+
case "record-review-blockers":
|
|
2225
|
+
return await reviewBlockers(repoRoot, rest, json, scope);
|
|
2226
|
+
default:
|
|
2227
|
+
return unhandledSubcommand(command);
|
|
2228
|
+
}
|
|
2229
|
+
} catch (error) {
|
|
2230
|
+
if (json) {
|
|
2231
|
+
printJsonError(error);
|
|
2232
|
+
return 1;
|
|
2233
|
+
}
|
|
2234
|
+
if (error instanceof UlwLoopError)
|
|
2235
|
+
process.stderr.write(`[ulw-loop] ${error.message}
|
|
2236
|
+
`);
|
|
2237
|
+
else if (error instanceof Error)
|
|
2238
|
+
process.stderr.write(`[ulw-loop] unexpected: ${error.message}
|
|
2239
|
+
`);
|
|
2240
|
+
else
|
|
2241
|
+
process.stderr.write(`[ulw-loop] unknown error
|
|
2242
|
+
`);
|
|
2243
|
+
return 1;
|
|
2244
|
+
}
|
|
2245
|
+
}
|
|
2246
|
+
function unhandledSubcommand(command) {
|
|
2247
|
+
throw new UlwLoopError(`Unhandled ulw-loop subcommand: ${String(command)}.`, "ULW_LOOP_SUBCOMMAND_UNHANDLED");
|
|
2248
|
+
}
|
|
2249
|
+
function commandScope(argv) {
|
|
2250
|
+
const sessionId = readValue(argv, "--session-id") ?? resolveUlwLoopSessionIdFromEnv();
|
|
2251
|
+
return sessionId === null ? undefined : { sessionId };
|
|
2252
|
+
}
|
|
2253
|
+
|
|
2254
|
+
// components/ulw-loop/src/codex-hook.ts
|
|
2255
|
+
var CREATE_GOAL_TOOL_NAME = "create_goal";
|
|
2256
|
+
var CREATE_GOAL_PAYLOAD_WARNING = "Use create_goal with objective only. Omit token_budget so the goal stays unlimited, and put lifecycle status changes on update_goal.";
|
|
2257
|
+
function parseUserPromptSubmitPayload(raw) {
|
|
2258
|
+
if (raw.trim().length === 0)
|
|
2259
|
+
return null;
|
|
2260
|
+
try {
|
|
2261
|
+
const parsed = JSON.parse(raw);
|
|
2262
|
+
return isUserPromptSubmitPayload(parsed) ? parsed : null;
|
|
2263
|
+
} catch (error) {
|
|
2264
|
+
if (error instanceof SyntaxError)
|
|
2265
|
+
return null;
|
|
2266
|
+
return null;
|
|
2267
|
+
}
|
|
2268
|
+
}
|
|
2269
|
+
function parsePreToolUsePayload(raw) {
|
|
2270
|
+
if (raw.trim().length === 0)
|
|
2271
|
+
return null;
|
|
2272
|
+
try {
|
|
2273
|
+
const parsed = JSON.parse(raw);
|
|
2274
|
+
return isPreToolUsePayload(parsed) ? parsed : null;
|
|
2275
|
+
} catch (error) {
|
|
2276
|
+
if (error instanceof SyntaxError)
|
|
2277
|
+
return null;
|
|
2278
|
+
return null;
|
|
2279
|
+
}
|
|
2280
|
+
}
|
|
2281
|
+
async function applyUserPromptUlwLoopSteering(payload) {
|
|
2282
|
+
try {
|
|
2283
|
+
if (payload.hook_event_name !== "UserPromptSubmit")
|
|
2284
|
+
return "";
|
|
2285
|
+
const proposal = parseUlwLoopSteeringDirective(payload.prompt);
|
|
2286
|
+
if (proposal === null)
|
|
2287
|
+
return "";
|
|
2288
|
+
const result = await steerUlwLoop(payload.cwd, proposal, payloadScope(payload));
|
|
2289
|
+
if (!result.accepted)
|
|
2290
|
+
return "";
|
|
2291
|
+
return JSON.stringify({
|
|
2292
|
+
status: "accepted",
|
|
2293
|
+
kind: result.audit.kind,
|
|
2294
|
+
source: result.audit.source,
|
|
2295
|
+
deduped: result.deduped
|
|
2296
|
+
});
|
|
2297
|
+
} catch (error) {
|
|
2298
|
+
if (error instanceof Error)
|
|
2299
|
+
return "";
|
|
2300
|
+
return "";
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
function payloadScope(payload) {
|
|
2304
|
+
return { sessionId: payload.session_id };
|
|
2305
|
+
}
|
|
2306
|
+
function applyPreToolUseGoalBudgetGuard(payload) {
|
|
2307
|
+
if (payload.hook_event_name !== "PreToolUse")
|
|
2308
|
+
return "";
|
|
2309
|
+
if (payload.tool_name !== CREATE_GOAL_TOOL_NAME)
|
|
2310
|
+
return "";
|
|
2311
|
+
if (!hasInvalidCreateGoalInput(payload.tool_input))
|
|
2312
|
+
return "";
|
|
2313
|
+
const output = {
|
|
2314
|
+
hookSpecificOutput: {
|
|
2315
|
+
hookEventName: "PreToolUse",
|
|
2316
|
+
permissionDecision: "deny",
|
|
2317
|
+
permissionDecisionReason: CREATE_GOAL_PAYLOAD_WARNING,
|
|
2318
|
+
additionalContext: CREATE_GOAL_PAYLOAD_WARNING
|
|
2319
|
+
}
|
|
2320
|
+
};
|
|
2321
|
+
return `${JSON.stringify(output)}
|
|
2322
|
+
`;
|
|
2323
|
+
}
|
|
2324
|
+
async function runUlwLoopHookCli(stdin, stdout) {
|
|
2325
|
+
try {
|
|
2326
|
+
const payload = parseUserPromptSubmitPayload(await readAll(stdin));
|
|
2327
|
+
if (payload === null)
|
|
2328
|
+
return;
|
|
2329
|
+
const output = await applyUserPromptUlwLoopSteering(payload);
|
|
2330
|
+
if (output.length > 0)
|
|
2331
|
+
stdout.write(output);
|
|
2332
|
+
} catch (error) {
|
|
2333
|
+
if (error instanceof Error)
|
|
2334
|
+
return;
|
|
2335
|
+
return;
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
async function runPreToolUseGoalBudgetGuardCli(stdin, stdout) {
|
|
2339
|
+
try {
|
|
2340
|
+
const payload = parsePreToolUsePayload(await readAll(stdin));
|
|
2341
|
+
if (payload === null)
|
|
2342
|
+
return;
|
|
2343
|
+
const output = applyPreToolUseGoalBudgetGuard(payload);
|
|
2344
|
+
if (output.length > 0)
|
|
2345
|
+
stdout.write(output);
|
|
2346
|
+
} catch (error) {
|
|
2347
|
+
if (error instanceof Error)
|
|
2348
|
+
return;
|
|
2349
|
+
return;
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
function isUserPromptSubmitPayload(value) {
|
|
2353
|
+
if (!isRecord3(value))
|
|
2354
|
+
return false;
|
|
2355
|
+
return value["hook_event_name"] === "UserPromptSubmit" && typeof value["cwd"] === "string" && typeof value["prompt"] === "string" && typeof value["session_id"] === "string" && ["model", "permission_mode", "transcript_path", "turn_id"].every((key) => optionalString(value[key]));
|
|
2356
|
+
}
|
|
2357
|
+
function isPreToolUsePayload(value) {
|
|
2358
|
+
if (!isRecord3(value))
|
|
2359
|
+
return false;
|
|
2360
|
+
return value["hook_event_name"] === "PreToolUse" && typeof value["cwd"] === "string" && typeof value["model"] === "string" && typeof value["permission_mode"] === "string" && typeof value["session_id"] === "string" && typeof value["tool_name"] === "string" && typeof value["tool_use_id"] === "string" && (value["transcript_path"] === null || typeof value["transcript_path"] === "string") && typeof value["turn_id"] === "string" && Object.hasOwn(value, "tool_input");
|
|
2361
|
+
}
|
|
2362
|
+
function hasInvalidCreateGoalInput(value) {
|
|
2363
|
+
return isRecord3(value) && Object.keys(value).some((key) => key !== "objective");
|
|
2364
|
+
}
|
|
2365
|
+
function isRecord3(value) {
|
|
2366
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2367
|
+
}
|
|
2368
|
+
function optionalString(value) {
|
|
2369
|
+
return value === undefined || typeof value === "string";
|
|
2370
|
+
}
|
|
2371
|
+
function readAll(stdin) {
|
|
2372
|
+
return new Promise((resolve4, reject) => {
|
|
2373
|
+
let data = "";
|
|
2374
|
+
stdin.setEncoding("utf8");
|
|
2375
|
+
stdin.on("data", (chunk) => {
|
|
2376
|
+
data += chunk instanceof Buffer ? chunk.toString() : String(chunk);
|
|
2377
|
+
});
|
|
2378
|
+
stdin.once("error", reject);
|
|
2379
|
+
stdin.once("end", () => resolve4(data));
|
|
2380
|
+
});
|
|
2381
|
+
}
|
|
2382
|
+
|
|
2383
|
+
// components/ulw-loop/src/cli.ts
|
|
2384
|
+
var TOP_LEVEL_HELP = `Usage:
|
|
2385
|
+
omo ulw-loop <subcommand> [args]
|
|
2386
|
+
omo hook user-prompt-submit (Codex UserPromptSubmit hook)
|
|
2387
|
+
omo help | --help | -h (this message)
|
|
2388
|
+
|
|
2389
|
+
Run \`omo ulw-loop help\` for ulw-loop subcommands.
|
|
2390
|
+
`;
|
|
2391
|
+
async function main() {
|
|
2392
|
+
const argv = process.argv.slice(2);
|
|
2393
|
+
const command = argv[0];
|
|
2394
|
+
if (command === undefined || command === "help" || command === "--help" || command === "-h") {
|
|
2395
|
+
process.stdout.write(TOP_LEVEL_HELP);
|
|
2396
|
+
return 0;
|
|
2397
|
+
}
|
|
2398
|
+
if (command === "ulw-loop")
|
|
2399
|
+
return ulwLoopCommand(argv.slice(1));
|
|
2400
|
+
if (command === "hook") {
|
|
2401
|
+
const sub = argv[1];
|
|
2402
|
+
if (sub === "user-prompt-submit") {
|
|
2403
|
+
await runUlwLoopHookCli(process.stdin, process.stdout);
|
|
2404
|
+
return 0;
|
|
2405
|
+
}
|
|
2406
|
+
if (sub === "pre-tool-use") {
|
|
2407
|
+
await runPreToolUseGoalBudgetGuardCli(process.stdin, process.stdout);
|
|
2408
|
+
return 0;
|
|
26
2409
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
process.stderr.write(`[omo] unknown command: ${command}\n${TOP_LEVEL_HELP}`);
|
|
2410
|
+
process.stderr.write(`[omo] unknown hook subcommand: ${sub ?? "(none)"}
|
|
2411
|
+
`);
|
|
30
2412
|
return 1;
|
|
2413
|
+
}
|
|
2414
|
+
if (isUlwLoopSubcommand(command))
|
|
2415
|
+
return ulwLoopCommand(argv);
|
|
2416
|
+
process.stderr.write(`[omo] unknown command: ${command}
|
|
2417
|
+
${TOP_LEVEL_HELP}`);
|
|
2418
|
+
return 1;
|
|
31
2419
|
}
|
|
32
|
-
main()
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
process.exit(1);
|
|
2420
|
+
main().then((code) => {
|
|
2421
|
+
process.exit(code);
|
|
2422
|
+
}).catch((error) => {
|
|
2423
|
+
process.stderr.write(`[omo] ${error instanceof Error ? error.message : String(error)}
|
|
2424
|
+
`);
|
|
2425
|
+
process.exit(1);
|
|
39
2426
|
});
|