oh-my-opencode 4.13.0 → 4.14.1
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 +15 -0
- package/.agents/skills/codex-qa/references/isolation.md +1 -1
- package/.agents/skills/codex-qa/references/logging-debug.md +12 -0
- package/.agents/skills/opencode-qa/SKILL.md +17 -0
- package/.agents/skills/opencode-qa/references/tui-tmux.md +17 -0
- package/.agents/skills/work-with-pr/SKILL.md +18 -10
- package/.opencode/skills/work-with-pr/SKILL.md +18 -10
- package/README.md +3 -3
- package/dist/cli/doctor/checks/telemetry.d.ts +2 -0
- package/dist/cli/doctor/framework/constants.d.ts +1 -0
- package/dist/cli/doctor/framework/doctor-target.d.ts +1 -1
- package/dist/cli/doctor/framework/types.d.ts +2 -0
- package/dist/cli/index.js +24779 -17857
- package/dist/cli-node/index.js +24779 -17857
- package/dist/config/schema/oh-my-opencode-config.d.ts +1 -0
- package/dist/features/team-mode/test-support/async-test-helpers.d.ts +19 -0
- package/dist/hooks/atlas/final-wave-approval-gate.d.ts +1 -0
- package/dist/hooks/atlas/subagent-completion-reminder.d.ts +30 -0
- package/dist/hooks/atlas/types.d.ts +2 -0
- package/dist/hooks/atlas/verification-reminders.d.ts +3 -0
- package/dist/hooks/team-session-events/team-idle-wake-hint.d.ts +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +43845 -26631
- package/dist/mcp/context7.d.ts +9 -8
- package/dist/oh-my-opencode.schema.json +4 -0
- package/dist/plugin/native-skills.d.ts +9 -0
- package/dist/plugin/system-transform.d.ts +1 -1
- package/dist/shared/posthog.d.ts +17 -10
- package/dist/shared/telemetry-product-identity.d.ts +2 -0
- package/dist/skills/coding-agent-sessions/SKILL.md +128 -0
- package/dist/skills/coding-agent-sessions/agents/openai.yaml +4 -0
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +71 -0
- package/dist/skills/coding-agent-sessions/references/claude.md +32 -0
- package/dist/skills/coding-agent-sessions/references/codex.md +30 -0
- package/dist/skills/coding-agent-sessions/references/opencode.md +43 -0
- package/dist/skills/coding-agent-sessions/references/senpi.md +17 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
- package/dist/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
- package/dist/skills/frontend/ATTRIBUTION.md +52 -8
- package/dist/skills/frontend/SKILL.md +29 -8
- package/dist/skills/frontend/references/design/README.md +29 -12
- package/dist/skills/frontend/references/design/_INDEX.md +3 -3
- package/dist/skills/frontend/references/design/design-system-architecture.md +22 -19
- package/dist/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
- package/dist/skills/frontend/references/designpowers/README.md +48 -0
- package/dist/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
- package/dist/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
- package/dist/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
- package/dist/skills/frontend/references/designpowers/lane-c-review.md +65 -0
- package/dist/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
- package/dist/skills/frontend/references/designpowers/orchestration.md +80 -0
- package/dist/skills/frontend/references/designpowers/routing.md +79 -0
- package/dist/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
- package/dist/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
- package/dist/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
- package/dist/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
- package/dist/skills/git-master/SKILL.md +4 -0
- package/dist/skills/lcx-contribute-bug-fix/SKILL.md +44 -13
- package/dist/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/dist/skills/lcx-doctor/SKILL.md +48 -13
- package/dist/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/dist/skills/lcx-report-bug/SKILL.md +44 -13
- package/dist/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/dist/skills/review-work/SKILL.md +3 -3
- package/dist/skills/start-work/SKILL.md +7 -5
- package/dist/skills/ultraresearch/SKILL.md +4 -252
- package/dist/skills/ulw-plan/SKILL.md +8 -6
- package/dist/skills/ulw-plan/references/full-workflow.md +11 -6
- package/dist/skills/ulw-plan/references/intent-clear.md +3 -3
- package/dist/skills/ulw-plan/references/intent-unclear.md +1 -1
- package/{packages/shared-skills/skills/ultraresearch → dist/skills/ulw-research}/ATTRIBUTION.md +1 -1
- package/dist/skills/ulw-research/SKILL.md +260 -0
- package/dist/skills/visual-qa/SKILL.md +109 -18
- package/dist/skills/visual-qa/references/agent-browser-setup.md +5 -4
- package/dist/skills/visual-qa/scripts/cli.test.ts +7 -2
- package/dist/skills/visual-qa/scripts/skill-prompt-contract.test.ts +130 -3
- package/dist/skills/visual-qa/scripts/visual-qa.mjs +530 -0
- package/dist/testing/create-plugin-module.d.ts +2 -0
- package/dist/tools/delegate-task/skill-resolver.d.ts +1 -0
- package/dist/tools/delegate-task/types.d.ts +2 -0
- package/dist/tools/skill/types.d.ts +1 -0
- package/dist/tui.js +23917 -16117
- package/docs/reference/github-attachment-upload.md +51 -0
- package/docs/reference/web-terminal-visual-qa.md +81 -0
- package/package.json +33 -14
- package/packages/git-bash-mcp/dist/cli.js +2 -0
- package/packages/lsp-core/src/lsp/process.ts +4 -1
- package/packages/lsp-core/src/mcp.ts +1 -0
- package/packages/lsp-daemon/dist/cli.js +20 -5
- package/packages/lsp-daemon/dist/ensure-daemon.d.ts +1 -0
- package/packages/lsp-daemon/dist/ensure-daemon.js +9 -3
- package/packages/lsp-daemon/dist/index.js +20 -5
- package/packages/lsp-daemon/dist/paths.d.ts +1 -0
- package/packages/lsp-daemon/dist/paths.js +6 -1
- package/packages/lsp-daemon/dist/proxy.js +1 -0
- package/packages/lsp-tools-mcp/dist/cli.js +5 -1
- package/packages/lsp-tools-mcp/dist/lsp/manager.js +4 -1
- package/packages/lsp-tools-mcp/dist/mcp.js +5 -1
- package/packages/lsp-tools-mcp/dist/tools.js +4 -1
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +327 -69
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/scripts/bootstrap.ps1 +37 -68
- package/packages/omo-codex/plugin/components/bootstrap/scripts/node-dispatch.ps1 +75 -0
- package/packages/omo-codex/plugin/components/bootstrap/src/cli.ts +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/src/setup.ts +3 -19
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +688 -334
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +317 -39
- package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +7 -1
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +103 -3
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +231 -0
- package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +29 -0
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +31 -57
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +7 -4
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +43 -9
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +287 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +12 -7
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +71 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/cli.js +94 -26
- package/packages/omo-codex/plugin/components/lsp/dist/codex-hook.js +2 -0
- package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.d.ts +2 -0
- package/packages/omo-codex/plugin/components/lsp/dist/daemon-cli-path.js +56 -0
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/lsp/src/cli.ts +2 -5
- package/packages/omo-codex/plugin/components/lsp/src/codex-hook.ts +2 -0
- package/packages/omo-codex/plugin/components/lsp/src/daemon-cli-path.ts +65 -0
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +6 -1
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +8 -106
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/src/static-injection.ts +4 -17
- package/packages/omo-codex/plugin/components/start-work-continuation/directive.md +6 -6
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/test/codex-hook.test.ts +23 -0
- package/packages/omo-codex/plugin/components/teammode/dist/cli.js +22 -4
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +57 -7
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +32 -5
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +63 -1
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +87 -53
- package/packages/omo-codex/plugin/components/teammode/src/codex-hook.ts +19 -4
- package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +32 -2
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- 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/plan.toml +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +18 -10
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +6 -4
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +11 -6
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +3 -3
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-unclear.md +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/src/codex-hook.ts +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/test/codex-hook-trigger-policy.test.ts +24 -0
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +7 -28
- package/packages/omo-codex/plugin/components/ulw-loop/AGENTS.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +25 -21
- package/packages/omo-codex/plugin/components/ulw-loop/biome.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +373 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli-steering.js +14 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +145 -14
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.d.ts +6 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/codex-hook.js +16 -6
- package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.d.ts +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/ultrawork-directive.js +104 -0
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +5 -2
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/SKILL.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +22 -14
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli-steering.ts +14 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/cli.ts +4 -2
- package/packages/omo-codex/plugin/components/ulw-loop/src/codex-hook.ts +28 -6
- package/packages/omo-codex/plugin/components/ulw-loop/src/ultrawork-directive.ts +113 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-entrypoint.test.ts +33 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/cli-steering-kind-guidance.test.ts +31 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/codex-hook.test.ts +13 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/fixtures/sample-quality-gate.json +7 -7
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +39 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-doc.test.ts +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate.test.ts +7 -6
- package/packages/omo-codex/plugin/components/ulw-loop/test/skill-contract.test.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/ultrawork-directive.test.ts +64 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +2 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +2 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +2 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +2 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +2 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +2 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +2 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +2 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +2 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +2 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +2 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +2 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +2 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +2 -1
- package/packages/omo-codex/plugin/package-lock.json +16 -56
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +9 -5
- package/packages/omo-codex/plugin/scripts/materialize-shared-upstreams.mjs +1 -0
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/context7-placeholder-guard.mjs +131 -0
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-mode-guard.mjs +60 -0
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/multi-agent-v2-guard.mjs +3 -10
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/root-settings.mjs +31 -1
- package/packages/omo-codex/plugin/scripts/migrate-codex-config/subagent-limit-guard.mjs +73 -0
- package/packages/omo-codex/plugin/scripts/migrate-codex-config.mjs +20 -3
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +30 -8
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +128 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/agents/openai.yaml +4 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +71 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/claude.md +32 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/codex.md +30 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/opencode.md +43 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +17 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +52 -8
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +29 -8
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +29 -12
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +3 -3
- package/packages/omo-codex/plugin/skills/frontend/references/design/design-system-architecture.md +22 -19
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/README.md +48 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-c-review.md +65 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/orchestration.md +80 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/routing.md +79 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
- package/packages/omo-codex/plugin/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
- package/packages/omo-codex/plugin/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
- package/packages/omo-codex/plugin/skills/git-master/SKILL.md +4 -0
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +4 -0
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/SKILL.md +44 -13
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +48 -13
- package/packages/omo-codex/plugin/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-report-bug/SKILL.md +44 -13
- package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/refactor/SKILL.md +4 -0
- package/packages/omo-codex/plugin/skills/remove-ai-slops/SKILL.md +4 -0
- package/packages/omo-codex/plugin/skills/review-work/SKILL.md +12 -4
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +14 -8
- package/packages/omo-codex/plugin/skills/teammode/SKILL.md +57 -7
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +32 -5
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +63 -1
- package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +87 -53
- package/packages/omo-codex/plugin/skills/ultraresearch/SKILL.md +4 -250
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +22 -14
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +6 -4
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +11 -6
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +3 -3
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-unclear.md +1 -1
- package/{dist/skills/ultraresearch → packages/omo-codex/plugin/skills/ulw-research}/ATTRIBUTION.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-research/SKILL.md +262 -0
- package/packages/omo-codex/plugin/skills/ulw-research/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/visual-qa/SKILL.md +113 -18
- package/packages/omo-codex/plugin/skills/visual-qa/references/agent-browser-setup.md +5 -4
- package/packages/omo-codex/plugin/skills/visual-qa/scripts/visual-qa.mjs +530 -0
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +23 -0
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -0
- package/packages/omo-codex/plugin/test/auto-update-release-notes.test.mjs +1 -0
- package/packages/omo-codex/plugin/test/auto-update-restart-notice.test.mjs +24 -1
- package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +61 -7
- package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +38 -0
- package/packages/omo-codex/plugin/test/bootstrap-ps-guard.test.mjs +25 -0
- package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +1 -7
- package/packages/omo-codex/plugin/test/component-bin-names.test.mjs +12 -11
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +99 -1
- package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +62 -8
- package/packages/omo-codex/plugin/test/migrate-codex-config.test.mjs +206 -6
- package/packages/omo-codex/plugin/test/node-install-surface.test.mjs +1 -0
- package/packages/omo-codex/plugin/test/subagent-limit-migration.test.mjs +44 -0
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +50 -1
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +10 -7
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +28 -2
- package/packages/omo-codex/plugin/test/teammode-archive-ambiguity.test.mjs +102 -0
- package/packages/omo-codex/plugin/test/teammode-communication.test.mjs +20 -0
- package/packages/omo-codex/plugin/test/teammode-safety-fixture.mjs +41 -1
- package/packages/omo-codex/plugin/test/teammode-safety.test.mjs +93 -0
- package/packages/omo-codex/plugin/test/teammode-thread-links.test.mjs +117 -0
- package/packages/omo-codex/plugin/test/teammode-worktree.test.mjs +5 -2
- package/packages/omo-codex/plugin/test/ulw-research-skill-contract.test.mjs +285 -0
- package/packages/omo-codex/scripts/install-bin-links.test.mjs +12 -1
- package/packages/omo-codex/scripts/install-cache-copy.test.mjs +79 -0
- package/packages/omo-codex/scripts/install-config-autonomous-features.test.mjs +43 -3
- package/packages/omo-codex/scripts/install-config.test.mjs +198 -17
- package/packages/omo-codex/scripts/install-delegated-command.test.mjs +93 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +803 -309
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +21 -2
- package/packages/omo-codex/scripts/install-local-git-bash-preflight.test.mjs +24 -15
- package/packages/omo-codex/scripts/install-local.test.mjs +5 -2
- package/packages/omo-codex/scripts/install-mcp-context7-runtime.test.mjs +84 -0
- package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +128 -0
- package/packages/shared-skills/skills/coding-agent-sessions/agents/openai.yaml +4 -0
- package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +71 -0
- package/packages/shared-skills/skills/coding-agent-sessions/references/claude.md +32 -0
- package/packages/shared-skills/skills/coding-agent-sessions/references/codex.md +30 -0
- package/packages/shared-skills/skills/coding-agent-sessions/references/opencode.md +43 -0
- package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +17 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/__init__.py +1 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/claude.py +66 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/cli.py +283 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/codex.py +105 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/file_scanners.py +275 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/jsonio.py +55 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/kiro_scanner.py +91 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/opencode.py +289 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +92 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_optional_scanners.py +203 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/sqlite_scanners.py +177 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/timeparse.py +51 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/transcript.py +149 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/types.py +57 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/find-agent-sessions.py +19 -0
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +52 -8
- package/packages/shared-skills/skills/frontend/SKILL.md +29 -8
- package/packages/shared-skills/skills/frontend/references/design/README.md +29 -12
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +3 -3
- package/packages/shared-skills/skills/frontend/references/design/design-system-architecture.md +22 -19
- package/packages/shared-skills/skills/frontend/references/designpowers/EVIDENCE.md +89 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/README.md +48 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/UPSTREAM.md +80 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-a-direction.md +64 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-b-execution.md +65 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-c-review.md +65 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/lane-d-memory.md +83 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/orchestration.md +80 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/routing.md +79 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/LICENSE +21 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/accessibility-reviewer.md +83 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/content-writer.md +132 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-builder.md +109 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-critic.md +89 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-lead.md +113 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-scout.md +78 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/design-strategist.md +121 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/heuristic-evaluator.md +268 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/inspiration-scout.md +107 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/agents/motion-designer.md +120 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/accessible-content/SKILL.md +101 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/adaptive-interfaces/SKILL.md +109 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/cognitive-accessibility/SKILL.md +107 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debate/SKILL.md +199 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-debt-tracker/SKILL.md +174 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-handoff/SKILL.md +125 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-md/SKILL.md +106 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-retrospective/SKILL.md +266 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-review/SKILL.md +123 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/design-system-alignment/SKILL.md +120 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/designpowers-critique/SKILL.md +164 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/heuristic-evaluation/SKILL.md +85 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inclusive-personas/SKILL.md +98 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/inspiration-scouting/SKILL.md +165 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/interaction-design/SKILL.md +122 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/motion-choreography/SKILL.md +81 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/research-planning/SKILL.md +96 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/responsive-patterns/SKILL.md +77 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/synthetic-user-testing/SKILL.md +192 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-feedback/SKILL.md +165 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/taste-report/SKILL.md +78 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/token-architecture/SKILL.md +75 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/ui-composition/SKILL.md +117 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/usability-testing/SKILL.md +78 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/verification-before-shipping/SKILL.md +125 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/voice-and-tone/SKILL.md +79 -0
- package/packages/shared-skills/skills/frontend/references/designpowers/vendor/skills/writing-design-plans/SKILL.md +119 -0
- package/packages/shared-skills/skills/frontend/references/ui-ux-db/scripts/core.py +0 -0
- package/packages/shared-skills/skills/git-master/SKILL.md +4 -0
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/SKILL.md +44 -13
- package/packages/shared-skills/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/shared-skills/skills/lcx-doctor/SKILL.md +48 -13
- package/packages/shared-skills/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/packages/shared-skills/skills/lcx-report-bug/SKILL.md +44 -13
- package/packages/shared-skills/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/shared-skills/skills/review-work/SKILL.md +3 -3
- package/packages/shared-skills/skills/start-work/SKILL.md +7 -5
- package/packages/shared-skills/skills/ultraresearch/SKILL.md +4 -252
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +8 -6
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +11 -6
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +3 -3
- package/packages/shared-skills/skills/ulw-plan/references/intent-unclear.md +1 -1
- package/packages/{omo-codex/plugin/skills/ultraresearch → shared-skills/skills/ulw-research}/ATTRIBUTION.md +1 -1
- package/packages/shared-skills/skills/ulw-research/SKILL.md +260 -0
- package/packages/shared-skills/skills/visual-qa/SKILL.md +109 -18
- package/packages/shared-skills/skills/visual-qa/references/agent-browser-setup.md +5 -4
- package/packages/shared-skills/skills/visual-qa/scripts/cli.test.ts +7 -2
- package/packages/shared-skills/skills/visual-qa/scripts/skill-prompt-contract.test.ts +130 -3
- package/packages/shared-skills/skills/visual-qa/scripts/visual-qa.mjs +530 -0
- package/script/qa/web-terminal-redaction.d.mts +13 -0
- package/script/qa/web-terminal-redaction.mjs +43 -0
- package/script/qa/web-terminal-renderer.mjs +218 -0
- package/script/qa/web-terminal-visual-qa.mjs +264 -0
- package/dist/cli/sparkshell-appserver-websocket.d.ts +0 -4
- package/dist/cli/sparkshell-appserver.d.ts +0 -16
- package/dist/cli/sparkshell-condense.d.ts +0 -10
- package/dist/cli/sparkshell-parse.d.ts +0 -24
- package/dist/cli/sparkshell-session-context.d.ts +0 -20
- package/dist/cli/sparkshell-spark.d.ts +0 -23
- package/dist/cli/sparkshell.d.ts +0 -33
- package/dist/shared/sparkshell-awareness.d.ts +0 -5
- package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +0 -106
- package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +0 -346
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_cookie_domain_filter.py +0 -110
- package/packages/omo-codex/plugin/skills/ultimate-browsing/scripts/tests/test_extract_cookies.py +0 -245
- package/packages/omo-codex/plugin/test/ultraresearch-skill-contract.test.mjs +0 -204
package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs
CHANGED
|
@@ -9,8 +9,9 @@
|
|
|
9
9
|
// this file stays the state concern only.
|
|
10
10
|
|
|
11
11
|
import { randomUUID } from "node:crypto";
|
|
12
|
-
import { lstat, mkdir, readFile, rename, writeFile } from "node:fs/promises";
|
|
12
|
+
import { lstat, mkdir, readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
13
13
|
import { dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
14
|
+
import { setTimeout as delay } from "node:timers/promises";
|
|
14
15
|
|
|
15
16
|
export const LENSES = ["area", "ownership", "perspective"];
|
|
16
17
|
export const MEMBER_STATUSES = ["pending", "active", "reported", "blocked", "archived"];
|
|
@@ -24,6 +25,8 @@ export function isUnderstaffed(team) {
|
|
|
24
25
|
// A team dir is a single child of .omo/teams. This pattern alone blocks "/", "\", and a
|
|
25
26
|
// leading "." so ".." and "a/b" can never name a team dir (the escape guard).
|
|
26
27
|
const SESSION_ID_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
28
|
+
const LOCK_TIMEOUT_MS = Number.parseInt(process.env.OMO_TEAMMODE_LOCK_TIMEOUT_MS ?? "10000", 10);
|
|
29
|
+
const LOCK_RETRY_MS = Number.parseInt(process.env.OMO_TEAMMODE_LOCK_RETRY_MS ?? "25", 10);
|
|
27
30
|
|
|
28
31
|
function isoNow(now) {
|
|
29
32
|
return now ?? new Date().toISOString();
|
|
@@ -233,6 +236,65 @@ async function lstatOrNull(p) {
|
|
|
233
236
|
});
|
|
234
237
|
}
|
|
235
238
|
|
|
239
|
+
function positiveIntegerOrFallback(value, fallback) {
|
|
240
|
+
return Number.isInteger(value) && value > 0 ? value : fallback;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async function readLockOwner(lockDir) {
|
|
244
|
+
return readFile(join(lockDir, "owner.json"), "utf8")
|
|
245
|
+
.then((content) => JSON.parse(content))
|
|
246
|
+
.catch(() => null);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
async function describeLockOwner(lockDir) {
|
|
250
|
+
const owner = await readLockOwner(lockDir);
|
|
251
|
+
if (!owner || typeof owner !== "object") return "another team.mjs command";
|
|
252
|
+
const parts = [];
|
|
253
|
+
if (owner.command) parts.push(String(owner.command));
|
|
254
|
+
if (owner.pid) parts.push(`pid ${owner.pid}`);
|
|
255
|
+
if (owner.createdAt) parts.push(`since ${owner.createdAt}`);
|
|
256
|
+
return parts.length > 0 ? parts.join(", ") : "another team.mjs command";
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
export async function withTeamLock(dir, command, fn, options = {}) {
|
|
260
|
+
const timeoutMs = positiveIntegerOrFallback(options.timeoutMs ?? LOCK_TIMEOUT_MS, 10000);
|
|
261
|
+
const retryMs = positiveIntegerOrFallback(options.retryMs ?? LOCK_RETRY_MS, 25);
|
|
262
|
+
const lockDir = join(dir, ".team.lock");
|
|
263
|
+
const deadline = Date.now() + timeoutMs;
|
|
264
|
+
let acquired = false;
|
|
265
|
+
for (;;) {
|
|
266
|
+
try {
|
|
267
|
+
await mkdir(lockDir, { mode: 0o700 });
|
|
268
|
+
acquired = true;
|
|
269
|
+
await writeFile(
|
|
270
|
+
join(lockDir, "owner.json"),
|
|
271
|
+
`${JSON.stringify({ pid: process.pid, command, createdAt: new Date().toISOString() }, null, 2)}\n`,
|
|
272
|
+
{ encoding: "utf8", flag: "wx" },
|
|
273
|
+
);
|
|
274
|
+
break;
|
|
275
|
+
} catch (error) {
|
|
276
|
+
if (acquired) {
|
|
277
|
+
await rm(lockDir, { recursive: true, force: true });
|
|
278
|
+
throw error;
|
|
279
|
+
}
|
|
280
|
+
if (!error || error.code !== "EEXIST") throw error;
|
|
281
|
+
const st = await lstatOrNull(lockDir);
|
|
282
|
+
if (st?.isSymbolicLink()) throw new Error(`refused: team lock path is a symlink: ${lockDir}`);
|
|
283
|
+
if (st && !st.isDirectory()) throw new Error(`refused: team lock path is not a directory: ${lockDir}`);
|
|
284
|
+
if (Date.now() >= deadline) {
|
|
285
|
+
const owner = await describeLockOwner(lockDir);
|
|
286
|
+
throw new Error(`team state is locked by ${owner}; retry after that command completes`);
|
|
287
|
+
}
|
|
288
|
+
await delay(Math.min(retryMs, Math.max(1, deadline - Date.now())));
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
return await fn();
|
|
293
|
+
} finally {
|
|
294
|
+
await rm(lockDir, { recursive: true, force: true });
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
|
|
236
298
|
// Create a directory chain refusing any symlinked component, so team state can never be
|
|
237
299
|
// written through a symlink that escapes the workspace.
|
|
238
300
|
async function mkdirNoSymlink(dir, stopAt) {
|
|
@@ -20,7 +20,7 @@ import { randomUUID } from "node:crypto";
|
|
|
20
20
|
import { realpathSync } from "node:fs";
|
|
21
21
|
import { rm } from "node:fs/promises";
|
|
22
22
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
23
|
-
import { buildGuide, buildMemberPrompt } from "./team-guide.mjs";
|
|
23
|
+
import { buildGuide, buildMemberPrompt, codexThreadLink } from "./team-guide.mjs";
|
|
24
24
|
import {
|
|
25
25
|
addMember,
|
|
26
26
|
archive,
|
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
setMemberStatus,
|
|
36
36
|
setMemberWorktree,
|
|
37
37
|
teamExists,
|
|
38
|
+
withTeamLock,
|
|
38
39
|
writeGuideAtomic,
|
|
39
40
|
writeTeamAtomic,
|
|
40
41
|
} from "./team-state.mjs";
|
|
@@ -82,57 +83,71 @@ async function persist(team, dir) {
|
|
|
82
83
|
await writeGuideAtomic(team, buildGuide(team), dir);
|
|
83
84
|
}
|
|
84
85
|
|
|
86
|
+
async function mutateTeam(cwd, sessionId, command, fn) {
|
|
87
|
+
const dir = await assertSafeTeamDir(cwd, sessionId);
|
|
88
|
+
return withTeamLock(dir, command, async () => {
|
|
89
|
+
const team = await readTeam(dir);
|
|
90
|
+
return fn(team, dir);
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
|
|
85
94
|
const handlers = {
|
|
86
95
|
async init(cwd, flags) {
|
|
87
96
|
const teamName = requireFlag(flags, "name");
|
|
88
97
|
const sessionName = requireFlag(flags, "session-name");
|
|
89
98
|
const sessionId = typeof flags.session === "string" ? flags.session : `team-${randomUUID().slice(0, 8)}`;
|
|
90
99
|
const dir = await ensureTeamDir(cwd, sessionId);
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
await withTeamLock(dir, "init", async () => {
|
|
101
|
+
if (await teamExists(dir)) {
|
|
102
|
+
process.stdout.write(`exists: ${dir} (left untouched; re-init is a safe no-op)\n`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
const team = buildTeam({
|
|
106
|
+
teamName,
|
|
107
|
+
sessionName,
|
|
108
|
+
sessionId,
|
|
109
|
+
dir,
|
|
110
|
+
worktreeEnabled: flags.worktree === true,
|
|
111
|
+
baseBranch: typeof flags["base-branch"] === "string" ? flags["base-branch"] : "dev",
|
|
112
|
+
});
|
|
113
|
+
await persist(team, dir);
|
|
114
|
+
process.stdout.write(`created: ${dir}\n`);
|
|
115
|
+
process.stdout.write(`team.json + guide.md written; artifacts/ ready. session id: ${sessionId}\n`);
|
|
116
|
+
process.stdout.write(`next: add-member --team ${sessionId} --id A --name "<short role>" --focus "<part/ownership/perspective>" --lens area|ownership|perspective --deliverable "<...>"\n`);
|
|
102
117
|
});
|
|
103
|
-
await persist(team, dir);
|
|
104
|
-
process.stdout.write(`created: ${dir}\n`);
|
|
105
|
-
process.stdout.write(`team.json + guide.md written; artifacts/ ready. session id: ${sessionId}\n`);
|
|
106
|
-
process.stdout.write(`next: add-member --team ${sessionId} --id A --name "<short role>" --focus "<part/ownership/perspective>" --lens area|ownership|perspective --deliverable "<...>"\n`);
|
|
107
118
|
},
|
|
108
119
|
|
|
109
120
|
async "add-member"(cwd, flags) {
|
|
110
121
|
const sessionId = requireFlag(flags, "team");
|
|
111
|
-
const { dir, team } = await loadTeam(cwd, sessionId);
|
|
112
122
|
const memberId = requireFlag(flags, "id").trim();
|
|
113
|
-
|
|
123
|
+
const memberInput = {
|
|
114
124
|
id: memberId,
|
|
115
125
|
name: typeof flags.name === "string" ? flags.name : null,
|
|
116
126
|
focus: requireFlag(flags, "focus"),
|
|
117
127
|
lens: requireFlag(flags, "lens"),
|
|
118
128
|
deliverable: typeof flags.deliverable === "string" ? flags.deliverable : "",
|
|
119
129
|
branch: typeof flags.branch === "string" ? flags.branch : null,
|
|
130
|
+
};
|
|
131
|
+
const { team, member } = await mutateTeam(cwd, sessionId, "add-member", async (team, dir) => {
|
|
132
|
+
addMember(team, memberInput);
|
|
133
|
+
await persist(team, dir);
|
|
134
|
+
return { team, member: team.members.find((m) => m.id === memberId) };
|
|
120
135
|
});
|
|
121
|
-
await persist(team, dir);
|
|
122
|
-
const member = team.members.find((m) => m.id === memberId);
|
|
123
136
|
process.stdout.write(`added member ${memberId} to team ${sessionId}.\n\nSend this as the new thread's first message (title the thread "${member.threadTitle}"):\n---\n${buildMemberPrompt(team, memberId)}\n---\n`);
|
|
124
137
|
},
|
|
125
138
|
|
|
126
139
|
async "bind-thread"(cwd, flags) {
|
|
127
140
|
const sessionId = requireFlag(flags, "team");
|
|
128
|
-
const
|
|
129
|
-
bindThread(team, {
|
|
141
|
+
const input = {
|
|
130
142
|
id: requireFlag(flags, "id"),
|
|
131
143
|
threadId: requireFlag(flags, "thread"),
|
|
132
144
|
cwd: typeof flags.cwd === "string" ? flags.cwd : null,
|
|
133
145
|
worktreePath: typeof flags["worktree-path"] === "string" ? flags["worktree-path"] : null,
|
|
146
|
+
};
|
|
147
|
+
await mutateTeam(cwd, sessionId, "bind-thread", async (team, dir) => {
|
|
148
|
+
bindThread(team, input);
|
|
149
|
+
await persist(team, dir);
|
|
134
150
|
});
|
|
135
|
-
await persist(team, dir);
|
|
136
151
|
process.stdout.write(`bound member ${flags.id} to thread ${flags.thread}.\n`);
|
|
137
152
|
},
|
|
138
153
|
|
|
@@ -144,38 +159,49 @@ const handlers = {
|
|
|
144
159
|
|
|
145
160
|
async "set-status"(cwd, flags) {
|
|
146
161
|
const sessionId = requireFlag(flags, "team");
|
|
147
|
-
const
|
|
148
|
-
setMemberStatus(team, {
|
|
162
|
+
const input = {
|
|
149
163
|
id: requireFlag(flags, "id"),
|
|
150
164
|
status: requireFlag(flags, "status"),
|
|
151
165
|
note: typeof flags.note === "string" ? flags.note : "",
|
|
166
|
+
};
|
|
167
|
+
await mutateTeam(cwd, sessionId, "set-status", async (team, dir) => {
|
|
168
|
+
setMemberStatus(team, input);
|
|
169
|
+
await persist(team, dir);
|
|
152
170
|
});
|
|
153
|
-
await persist(team, dir);
|
|
154
171
|
process.stdout.write(`member ${flags.id} -> ${flags.status}\n`);
|
|
155
172
|
},
|
|
156
173
|
|
|
157
174
|
async "worktree-add"(cwd, flags) {
|
|
158
175
|
const sessionId = requireFlag(flags, "team");
|
|
159
|
-
const
|
|
160
|
-
const
|
|
161
|
-
const result =
|
|
162
|
-
|
|
176
|
+
const memberId = requireFlag(flags, "id");
|
|
177
|
+
const baseBranch = typeof flags["base-branch"] === "string" ? flags["base-branch"] : null;
|
|
178
|
+
const { member, result } = await mutateTeam(cwd, sessionId, "worktree-add", async (team, dir) => {
|
|
179
|
+
const member = memberOrThrow(team, memberId);
|
|
180
|
+
const result = addMemberWorktree(cwd, team, member, { baseBranch });
|
|
181
|
+
setMemberWorktree(team, { id: member.id, path: result.path, branch: result.branch });
|
|
182
|
+
await persist(team, dir);
|
|
183
|
+
return { member, result };
|
|
163
184
|
});
|
|
164
|
-
setMemberWorktree(team, { id: member.id, path: result.path, branch: result.branch });
|
|
165
|
-
await persist(team, dir);
|
|
166
185
|
const note = result.created ? "" : " (already exists)";
|
|
186
|
+
const thread = member.threadId
|
|
187
|
+
? `\nMember thread: ${codexThreadLink(member.threadId)}\nTell that member to: cd "${result.path}"`
|
|
188
|
+
: "\nMember thread is not bound yet; wait for the real Codex thread id, then bind-thread before sending bootstrap. After binding, send the member this worktree path.";
|
|
167
189
|
process.stdout.write(
|
|
168
|
-
`worktree for member ${member.id}${note}: ${result.path} on branch ${result.branch} (off ${result.base})
|
|
190
|
+
`worktree for member ${member.id}${note}: ${result.path} on branch ${result.branch} (off ${result.base}).${thread}\n`,
|
|
169
191
|
);
|
|
170
192
|
},
|
|
171
193
|
|
|
172
194
|
async "worktree-remove"(cwd, flags) {
|
|
173
195
|
const sessionId = requireFlag(flags, "team");
|
|
174
|
-
const
|
|
175
|
-
const
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
196
|
+
const memberId = requireFlag(flags, "id");
|
|
197
|
+
const force = flags.force === true;
|
|
198
|
+
const member = await mutateTeam(cwd, sessionId, "worktree-remove", async (team, dir) => {
|
|
199
|
+
const member = memberOrThrow(team, memberId);
|
|
200
|
+
removeMemberWorktree(cwd, team, member, { force });
|
|
201
|
+
clearMemberWorktree(team, { id: member.id });
|
|
202
|
+
await persist(team, dir);
|
|
203
|
+
return member;
|
|
204
|
+
});
|
|
179
205
|
process.stdout.write(`removed worktree for member ${member.id}\n`);
|
|
180
206
|
},
|
|
181
207
|
|
|
@@ -205,25 +231,30 @@ const handlers = {
|
|
|
205
231
|
|
|
206
232
|
async archive(cwd, flags) {
|
|
207
233
|
const sessionId = requireFlag(flags, "team");
|
|
208
|
-
const
|
|
209
|
-
archive(team, {
|
|
234
|
+
const input = {
|
|
210
235
|
id: typeof flags.id === "string" ? flags.id : null,
|
|
211
236
|
note: typeof flags.note === "string" ? flags.note : "",
|
|
237
|
+
};
|
|
238
|
+
await mutateTeam(cwd, sessionId, "archive", async (team, dir) => {
|
|
239
|
+
archive(team, input);
|
|
240
|
+
await persist(team, dir);
|
|
212
241
|
});
|
|
213
|
-
await persist(team, dir);
|
|
214
242
|
process.stdout.write(flags.id ? `archived member ${flags.id}\n` : `archived team ${sessionId} and closed all members\n`);
|
|
215
243
|
},
|
|
216
244
|
|
|
217
245
|
async delete(cwd, flags) {
|
|
218
246
|
const sessionId = requireFlag(flags, "team");
|
|
219
|
-
const
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
247
|
+
const dir = await assertSafeTeamDir(cwd, sessionId);
|
|
248
|
+
await withTeamLock(dir, "delete", async () => {
|
|
249
|
+
const team = await readTeam(dir);
|
|
250
|
+
const active = team.members.filter((m) => m.status !== "archived");
|
|
251
|
+
if (flags.force !== true && (team.status !== "archived" || active.length > 0)) {
|
|
252
|
+
throw new Error(
|
|
253
|
+
`refused: team "${sessionId}" is not archived or still has ${active.length} active member(s). Archive first, or pass --force to delete anyway.`,
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
await rm(dir, { recursive: true, force: true });
|
|
257
|
+
});
|
|
227
258
|
process.stdout.write(`deleted team state: ${dir}\n`);
|
|
228
259
|
},
|
|
229
260
|
|
|
@@ -232,7 +263,8 @@ const handlers = {
|
|
|
232
263
|
const { team } = await loadTeam(cwd, sessionId);
|
|
233
264
|
process.stdout.write(`Team ${team.teamName} [${team.status}] - leader: main session - ${team.members.length} member(s)\n`);
|
|
234
265
|
for (const m of team.members) {
|
|
235
|
-
|
|
266
|
+
const thread = m.threadId ? ` thread=${m.threadId} link=${codexThreadLink(m.threadId)}` : "";
|
|
267
|
+
process.stdout.write(` ${m.id} (${m.lens}) ${m.focus} -> ${m.deliverable || "(no deliverable)"} [${m.status}]${thread}${m.cwd ? ` cwd=${m.cwd}` : ""}\n`);
|
|
236
268
|
}
|
|
237
269
|
if (isUnderstaffed(team)) {
|
|
238
270
|
process.stdout.write(
|
|
@@ -243,9 +275,11 @@ const handlers = {
|
|
|
243
275
|
|
|
244
276
|
async guide(cwd, flags) {
|
|
245
277
|
const sessionId = requireFlag(flags, "team");
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
278
|
+
const guidePath = await mutateTeam(cwd, sessionId, "guide", async (team, dir) => {
|
|
279
|
+
await writeGuideAtomic(team, buildGuide(team), dir);
|
|
280
|
+
return team.paths.guide;
|
|
281
|
+
});
|
|
282
|
+
process.stdout.write(`${guidePath}\n`);
|
|
249
283
|
},
|
|
250
284
|
};
|
|
251
285
|
|
|
@@ -64,7 +64,7 @@ function threadTitleReminder(threadReference: ThreadCreationReference): string {
|
|
|
64
64
|
const id = formatIdentifier(threadReference.id);
|
|
65
65
|
return threadReference.kind === "thread"
|
|
66
66
|
? `THREAD ID ${id}: CALL codex_app.set_thread_title NOW. USE THE REAL TASK/ROLE.`
|
|
67
|
-
: `PENDING WORKTREE ID ${id}:
|
|
67
|
+
: `PENDING WORKTREE ID ${id}: WORKTREE THREAD IS NOT READY YET. DO NOT bind-thread OR SEND THE MEMBER BOOTSTRAP UNTIL A REAL THREAD ID EXISTS. THEN CALL codex_app.set_thread_title USING THE REAL TASK/ROLE.`;
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
function formatIdentifier(value: string): string {
|
|
@@ -73,18 +73,33 @@ function formatIdentifier(value: string): string {
|
|
|
73
73
|
}
|
|
74
74
|
|
|
75
75
|
function extractThreadCreationReference(toolResponse: unknown): ThreadCreationReference | null {
|
|
76
|
-
|
|
77
|
-
|
|
76
|
+
const response = parseToolResponseRecord(toolResponse);
|
|
77
|
+
if (response === null) return null;
|
|
78
|
+
const threadId = response["threadId"];
|
|
78
79
|
if (typeof threadId === "string" && threadId.trim().length > 0) {
|
|
79
80
|
return { kind: "thread", id: threadId };
|
|
80
81
|
}
|
|
81
|
-
const pendingWorktreeId =
|
|
82
|
+
const pendingWorktreeId = response["pendingWorktreeId"];
|
|
82
83
|
if (typeof pendingWorktreeId === "string" && pendingWorktreeId.trim().length > 0) {
|
|
83
84
|
return { kind: "pendingWorktree", id: pendingWorktreeId };
|
|
84
85
|
}
|
|
85
86
|
return null;
|
|
86
87
|
}
|
|
87
88
|
|
|
89
|
+
function parseToolResponseRecord(toolResponse: unknown): Record<string, unknown> | null {
|
|
90
|
+
if (isRecord(toolResponse)) return toolResponse;
|
|
91
|
+
if (typeof toolResponse !== "string") return null;
|
|
92
|
+
const trimmed = toolResponse.trim();
|
|
93
|
+
if (trimmed.length === 0) return null;
|
|
94
|
+
try {
|
|
95
|
+
const parsed: unknown = JSON.parse(trimmed);
|
|
96
|
+
return isRecord(parsed) ? parsed : null;
|
|
97
|
+
} catch (error) {
|
|
98
|
+
if (error instanceof SyntaxError) return null;
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
88
103
|
function isPostToolUsePayload(value: unknown): value is PostToolUsePayload {
|
|
89
104
|
if (!isRecord(value)) return false;
|
|
90
105
|
return (
|
|
@@ -34,6 +34,36 @@ describe("thread title PostToolUse guidance", () => {
|
|
|
34
34
|
);
|
|
35
35
|
});
|
|
36
36
|
|
|
37
|
+
it("#given Codex reports create_thread output as a JSON string #when the hook runs #then it still extracts the thread id", () => {
|
|
38
|
+
// given
|
|
39
|
+
const output = runPostToolUseHook({
|
|
40
|
+
hook_event_name: "PostToolUse",
|
|
41
|
+
session_id: "s-team",
|
|
42
|
+
turn_id: "t-team",
|
|
43
|
+
transcript_path: null,
|
|
44
|
+
cwd: "/repo",
|
|
45
|
+
model: "gpt-5.5",
|
|
46
|
+
permission_mode: "default",
|
|
47
|
+
tool_name: "codex_app.create_thread",
|
|
48
|
+
tool_use_id: "tool-create-thread",
|
|
49
|
+
tool_input: {
|
|
50
|
+
prompt: "Review a worktree PR",
|
|
51
|
+
target: { type: "project", projectId: "/repo", environment: { type: "local" } },
|
|
52
|
+
},
|
|
53
|
+
tool_response: '{"threadId":"019ef350-ee78-72a3-bd5e-e40cebc3d814"}',
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
// when
|
|
57
|
+
const parsed: unknown = JSON.parse(output);
|
|
58
|
+
|
|
59
|
+
// then
|
|
60
|
+
expect(isHookOutput(parsed)).toBe(true);
|
|
61
|
+
if (!isHookOutput(parsed)) return;
|
|
62
|
+
expect(parsed.hookSpecificOutput.additionalContext).toBe(
|
|
63
|
+
"THREAD ID 019ef350-ee78-72a3-bd5e-e40cebc3d814: CALL codex_app.set_thread_title NOW. USE THE REAL TASK/ROLE.",
|
|
64
|
+
);
|
|
65
|
+
});
|
|
66
|
+
|
|
37
67
|
it("#given an unrelated tool completed #when the hook runs #then it stays silent", () => {
|
|
38
68
|
// given
|
|
39
69
|
const output = runPostToolUseHook({
|
|
@@ -57,7 +87,7 @@ describe("thread title PostToolUse guidance", () => {
|
|
|
57
87
|
expect(actual).toBe("");
|
|
58
88
|
});
|
|
59
89
|
|
|
60
|
-
it("#given worktree-backed thread creation is pending #when the hook runs #then it tells Codex to
|
|
90
|
+
it("#given worktree-backed thread creation is pending #when the hook runs #then it tells Codex to wait for the real thread before bootstrapping", () => {
|
|
61
91
|
// given
|
|
62
92
|
const output = runPostToolUseHook({
|
|
63
93
|
hook_event_name: "PostToolUse",
|
|
@@ -89,7 +119,7 @@ describe("thread title PostToolUse guidance", () => {
|
|
|
89
119
|
expect(isHookOutput(parsed)).toBe(true);
|
|
90
120
|
if (!isHookOutput(parsed)) return;
|
|
91
121
|
expect(parsed.hookSpecificOutput.additionalContext).toBe(
|
|
92
|
-
"PENDING WORKTREE ID remote-control:env:test-worktree:
|
|
122
|
+
"PENDING WORKTREE ID remote-control:env:test-worktree: WORKTREE THREAD IS NOT READY YET. DO NOT bind-thread OR SEND THE MEMBER BOOTSTRAP UNTIL A REAL THREAD ID EXISTS. THEN CALL codex_app.set_thread_title USING THE REAL TASK/ROLE.",
|
|
93
123
|
);
|
|
94
124
|
});
|
|
95
125
|
});
|
|
@@ -9,7 +9,7 @@ Bundled Codex agent role TOMLs in `agents/` are installed into `CODEX_HOME/agent
|
|
|
9
9
|
| Mandate | Behavior |
|
|
10
10
|
|---|---|
|
|
11
11
|
| Goal + binding success criteria | Call `create_goal` (or open with a `# Goal` block) listing the deliverable + **3+ realistic QA scenarios** (happy path, edge cases, adjacent-surface regression). Each scenario MUST name which **Manual-QA channel** it will use. "Tests pass" is supporting signal, NEVER completion proof. |
|
|
12
|
-
| Manual-QA channels (TESTS ALONE NEVER PROVE DONE) | A dedicated top-level section enumerates the **four** channels you can use to verify a criterion in reality: **(1) HTTP call** (`curl -i` / Playwright APIRequestContext), **(2) tmux** (`tmux new-session` + `send-keys` + `capture-pane`), **(3) Browser use** (Playwright / puppeteer / Chromium driving the real page), **(4) Computer use** (OS-level GUI automation against the running app). Every criterion picks one channel, builds a real-usage scenario, runs it, and captures the artifact — every time. Aux surfaces (CLI stdout / DB diff / parsed config) only count for genuinely CLI- or data-shaped criteria. |
|
|
12
|
+
| Manual-QA channels (TESTS ALONE NEVER PROVE DONE) | A dedicated top-level section enumerates the **four** channels you can use to verify a criterion in reality: **(1) HTTP call** (`curl -i` / Playwright APIRequestContext), **(2) tmux** (`tmux new-session` + `send-keys` + `capture-pane`), **(3) Browser use** (in Codex, `browser:control-in-app-browser` first when no authenticated/persistent browser profile is needed; otherwise Playwright / puppeteer / Chromium driving the real page), **(4) Computer use** (OS-level GUI automation against the running app). Every criterion picks one channel, builds a real-usage scenario, runs it, and captures the artifact — every time. Aux surfaces (CLI stdout / DB diff / parsed config) only count for genuinely CLI- or data-shaped criteria. |
|
|
13
13
|
| Surface + paired cleanup | Execution loop step 4 (**SURFACE-AS-SCENARIO**) runs the chosen channel scenario end-to-end. Step 5 (**CLEANUP, PAIRED**) tears down every QA-spawned process / tmux session / browser context / container / port / temp dir, with a one-line receipt appended to the notepad. Leftover state → NOT done. |
|
|
14
14
|
| Durable /tmp notepad | `mktemp -t ulw-$(date +%Y%m%d-%H%M%S).XXXXXX.md` with sections `Plan`, `Success criteria + QA scenarios`, `Now`, `Todo`, `Findings`, `Learnings`. **Append**, never rewrite. |
|
|
15
15
|
| Obsessive atomic todos | Every action — even one-line edits, `ls`, single test runs — becomes a todo. Format: `path: <action> for <criterion> — verify by <check>`. One in_progress at a time, mark completed immediately. |
|
|
@@ -46,7 +46,7 @@ If asked "where is auth?", explain the auth flow you found.]
|
|
|
46
46
|
</results>
|
|
47
47
|
|
|
48
48
|
# Tool strategy (parallel, flood the first wave)
|
|
49
|
-
-
|
|
49
|
+
- Repo-wide inspection, CLI smoke tests, git/history checks, and bounded command output -> use native shell commands directly: `rg`, `rg --files`, `cat`, and `git`. Narrow huge output before reading it.
|
|
50
50
|
- Symbol questions -> `lsp_goto_definition`, `lsp_find_references`, `lsp_symbols`, `lsp_diagnostics`.
|
|
51
51
|
- Structural shapes -> the `ast-grep` skill helper or `sg` CLI with `$VAR` / `$$$` metavars.
|
|
52
52
|
- Text / strings / comments / logs -> `rg` (grep).
|
|
@@ -107,10 +107,10 @@ Critical path: Task 1 -> Task 2 -> Task 6
|
|
|
107
107
|
- [ ] <verifiable condition with the exact command or assertion>
|
|
108
108
|
|
|
109
109
|
QA scenarios (MANDATORY - task incomplete without these):
|
|
110
|
-
> Name the exact tool AND its exact invocation - not "verify it works". Browser use: use
|
|
110
|
+
> Name the exact tool AND its exact invocation - not "verify it works". Browser use: in Codex, use `browser:control-in-app-browser` first when available and no authenticated/persistent user browser profile is required; otherwise use Chrome to drive the page, or agent-browser (https://github.com/vercel-labs/agent-browser) when Chrome is unavailable. Computer use: OS-level GUI automation for a non-browser desktop app.
|
|
111
111
|
```
|
|
112
112
|
Scenario: <happy path>
|
|
113
|
-
Tool: <bash | curl | tmux | playwright(real Chrome) | agent-browser | computer-use>
|
|
113
|
+
Tool: <bash | curl | tmux | browser:control-in-app-browser | playwright(real Chrome) | agent-browser | computer-use>
|
|
114
114
|
Steps: <exact command / API call / page action with concrete inputs - URL, payload, keystrokes, selectors>
|
|
115
115
|
Expected: <concrete, binary pass/fail observable>
|
|
116
116
|
Evidence: .omo/evidence/task-<N>-<slug>.<ext>
|
|
@@ -52,8 +52,10 @@ exercises the surface; capture the artifact.
|
|
|
52
52
|
2. tmux — `tmux new-session -d -s ulw-qa-<criterion>`, drive with
|
|
53
53
|
`send-keys`, dump via `tmux capture-pane -pS -E -`; transcript
|
|
54
54
|
is the artifact.
|
|
55
|
-
3. Browser use —
|
|
56
|
-
|
|
55
|
+
3. Browser use — in Codex, use `browser:control-in-app-browser`
|
|
56
|
+
first when available and no authenticated/persistent user browser
|
|
57
|
+
profile is required. Otherwise use Chrome to drive the REAL page;
|
|
58
|
+
if Chrome is not available, download and use agent-browser
|
|
57
59
|
(https://github.com/vercel-labs/agent-browser). Capture action
|
|
58
60
|
log + screenshot path. Never downgrade to a non-browser surface
|
|
59
61
|
for a browser-facing criterion.
|
|
@@ -68,7 +70,8 @@ upfront: the literal command / API call / page action with its concrete
|
|
|
68
70
|
inputs (URL, payload, keystrokes, selectors) and the single binary
|
|
69
71
|
observable that decides PASS vs FAIL. "run the endpoint", "open the
|
|
70
72
|
page", "check it works" are NOT scenarios — write the `curl ...`, the
|
|
71
|
-
`send-keys ...`, the `page.click(...)`, the
|
|
73
|
+
`send-keys ...`, the Browser plugin action, the `page.click(...)`, the
|
|
74
|
+
expected status/text.
|
|
72
75
|
|
|
73
76
|
Auxiliary surfaces (CLI stdout / DB state diff / parsed config dump)
|
|
74
77
|
are first-class evidence for CLI- or data-shaped criteria; use a
|
|
@@ -76,6 +79,14 @@ channel scenario when the behavior is user-facing. `--dry-run`,
|
|
|
76
79
|
printing the command, "should respond", and "looks correct" never
|
|
77
80
|
count.
|
|
78
81
|
|
|
82
|
+
For TUI visual QA, terminal transcripts alone are not enough when a
|
|
83
|
+
visual surface is being evaluated. In this repo, prefer
|
|
84
|
+
`node script/qa/web-terminal-visual-qa.mjs --title "<surface>" --from-file <capture.txt> --evidence-dir <dir>`
|
|
85
|
+
or the helper's `--command` tmux-backed PTY connector when available.
|
|
86
|
+
Outside this repo, capture equivalent browser/computer-use rendered
|
|
87
|
+
terminal evidence: screenshot, plain transcript, rendered HTML or action
|
|
88
|
+
log, and cleanup receipt.
|
|
89
|
+
|
|
79
90
|
# Bootstrap (DO ALL FOUR BEFORE ANY OTHER WORK — NO SKIPPING)
|
|
80
91
|
|
|
81
92
|
## 0. Survey the skills, then size the work
|
|
@@ -143,8 +154,8 @@ artifact path the moment it happens. Update `## Now` and
|
|
|
143
154
|
is your durable memory and it OUTLIVES the context window. After any
|
|
144
155
|
compaction or context loss (a `Context compacted` notice, a summarized
|
|
145
156
|
history, or you no longer see your own earlier steps), STOP and re-read
|
|
146
|
-
the WHOLE notepad FIRST
|
|
147
|
-
|
|
157
|
+
the WHOLE notepad FIRST before any other action, then resume from
|
|
158
|
+
`## Now`. Recover
|
|
148
159
|
state from the notepad; do not re-plan from scratch or re-run completed
|
|
149
160
|
steps.
|
|
150
161
|
|
|
@@ -178,11 +189,8 @@ serialize only when one output strictly feeds the next.
|
|
|
178
189
|
inactive/uninitialized, or cold-start unavailable, keep moving with
|
|
179
190
|
Read/Grep/Glob/LSP and the ast-grep skill.
|
|
180
191
|
- Repo-wide inspection, CLI smoke tests, git/history, bounded command
|
|
181
|
-
output → use
|
|
182
|
-
`
|
|
183
|
-
or too narrow. `--shell` is only for shell metacharacters or
|
|
184
|
-
pipelines; `--tmux-pane` is only for inspecting an existing pane,
|
|
185
|
-
never for launching ordinary commands. Sparkshell is your default lens.
|
|
192
|
+
output → use native shell commands directly: `rg`, `rg --files`,
|
|
193
|
+
`cat`, and `git`. Narrow huge output before reading it.
|
|
186
194
|
- Symbols — definitions, references, rename impact, diagnostics →
|
|
187
195
|
`lsp_goto_definition`, `lsp_find_references`, `lsp_symbols`,
|
|
188
196
|
`lsp_diagnostics`. Use the LSP, not text search, for anything
|
|
@@ -80,7 +80,7 @@ function isContextPressureTranscript(transcriptPath) {
|
|
|
80
80
|
if (transcriptPath === undefined || transcriptPath === null)
|
|
81
81
|
return false;
|
|
82
82
|
try {
|
|
83
|
-
return isContextPressureRecoveryPrompt(
|
|
83
|
+
return isContextPressureRecoveryPrompt(readTranscriptTail(transcriptPath));
|
|
84
84
|
} catch (error) {
|
|
85
85
|
if (error instanceof Error)
|
|
86
86
|
return false;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@code-yeongyu/codex-ultrawork",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.14.1",
|
|
4
4
|
"description": "Codex plugin that injects the ultrawork orchestration directive and ships LazyCodex planning, review, QA, and gate agent roles.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "npm@11.12.1",
|
|
@@ -15,10 +15,12 @@ Outcome-first: explore a lot, ask few sharp questions - or none, when the intent
|
|
|
15
15
|
|
|
16
16
|
## INTENT ROUTING - pick ONE intent reference
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Before routing, parse review modifiers separately. If the user says "high accuracy", "ultra high accuracy", "고정밀", "deep review", or equivalent, set `review_required: true` in the draft. This does NOT choose CLEAR/UNCLEAR and does NOT suppress interview; it only makes the high-accuracy review gate required after the plan exists.
|
|
19
|
+
|
|
20
|
+
After grounding, make ONE judgment, record `intent: clear|unclear` plus `review_required`, and load ONE intent reference (you ALSO read `references/full-workflow.md` for the shared mechanics - see below). The test keys on whether the desired **OUTCOME** is clear, NOT on request length.
|
|
19
21
|
|
|
20
22
|
- **OVERRIDE - explicit ask wins:** if the user explicitly asks to be questioned or interviewed ("ask me", "interview me", "why aren't you asking me" - in any language), route **CLEAR**, run the interview, and turn the adopt-default filter OFF: the user has claimed the forks, so every surviving one is ASKED, not defaulted. This beats the OUTCOME test below, even on a fuzzy brief.
|
|
21
|
-
- **CLEAR** - the user knows the outcome; the only open items are preferences/tradeoffs the repo cannot answer (genuine owner-decisions). Read **`references/intent-clear.md`**: ask the surviving forks with WHY, run the normal approval gate, high-accuracy review
|
|
23
|
+
- **CLEAR** - the user knows the outcome; the only open items are preferences/tradeoffs the repo cannot answer (genuine owner-decisions). Read **`references/intent-clear.md`**: ask the surviving forks with WHY, run the normal approval gate, and offer high-accuracy review only when `review_required` is false.
|
|
22
24
|
- **UNCLEAR** - the outcome itself is fuzzy (a vague brief, a bootstrap, `$start-work` with no selectable plan, a goal the user cannot yet articulate). Asking would offload your own job onto the user. Read **`references/intent-unclear.md`**: research maximally, adopt and ANNOUNCE best-practice defaults, do NOT ask the user extra questions, and run high-accuracy review AUTOMATICALLY (unless Classify sized the work Trivial).
|
|
23
25
|
- **ON THE FENCE** - when CLEAR vs UNCLEAR is genuinely ambiguous, treat it as CLEAR and ask exactly ONE question. A user wrongly silenced is worse than one extra question. The dominant failure to guard against is mis-routing a CLEAR request to UNCLEAR, which silently applies defaults and overrides forks the user wanted to own.
|
|
24
26
|
|
|
@@ -47,7 +49,7 @@ Run it ONCE at plan generation. A plain re-run on an existing plan is a safe no-
|
|
|
47
49
|
- **Explore to sufficiency, then STOP.** One research wave per open question; stop when the clearance check is answerable; never re-explore to double-check.
|
|
48
50
|
- **Parallel-dispatch** independent research in ONE turn and keep working while it runs. Subagent outputs are CLAIMS until you independently verify them.
|
|
49
51
|
- **Approval is not execution.** Approval authorizes writing the plan ONLY, never implementation. ONE request -> ONE plan, however large.
|
|
50
|
-
- **The durable draft is the resume point.** Record decisions, the approval gate, and the ledgers to `.omo/drafts/<slug>.md` as you go; on any later turn read it and resume
|
|
52
|
+
- **The durable draft is the resume point.** Record `intent`, `review_required`, decisions, the approval gate, and the ledgers to `.omo/drafts/<slug>.md` as you go; on any later turn read it and resume from those fields instead of rerouting from memory.
|
|
51
53
|
- **Agent-executed QA per todo** (happy + failure, exact tool + invocation, evidence path). Zero human-intervention verification. Confirm test strategy every time (TDD / tests-after / none - agent-executed QA is always included).
|
|
52
54
|
|
|
53
55
|
## Approval gate
|
|
@@ -66,5 +68,5 @@ Roles: `explorer` (internal patterns/conventions/tests), `librarian` (external d
|
|
|
66
68
|
|
|
67
69
|
## Stop rules
|
|
68
70
|
|
|
69
|
-
- Plan file exists, template filled, every todo has references + acceptance + QA + commit, dependency matrix consistent: present the summary, then (CLEAR) ask the start-or-high-accuracy question, or (UNCLEAR)
|
|
71
|
+
- Plan file exists, template filled, every todo has references + acceptance + QA + commit, dependency matrix consistent, and any required high-accuracy receipts are recorded: present the summary, then (CLEAR without `review_required`) ask the start-or-high-accuracy question, or (CLEAR with `review_required` / UNCLEAR) report the review result - and stop. **Never begin execution yourself.**
|
|
70
72
|
- Brief presented and `status: awaiting-approval` recorded: wait. Do not re-explore unless the user changes scope.
|