oh-my-opencode 5.0.0-beta.34 → 5.0.0-beta.36
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/scripts/lsp-e2e.sh +1 -3
- package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +1 -1
- package/.agents/skills/tech-debt-audit/SKILL.md +6 -76
- package/README.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.ru.md +1 -1
- package/README.zh-cn.md +1 -1
- package/THIRD-PARTY-NOTICES.md +27 -99
- package/dist/cli/index.js +48341 -48541
- package/dist/cli-node/index.js +49016 -49216
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schema/hooks.d.ts +0 -1
- package/dist/config/schema/oh-my-opencode-config.d.ts +0 -10
- package/dist/config/schema.d.ts +0 -1
- package/dist/create-hooks.d.ts +0 -1
- package/dist/hooks/index.d.ts +0 -1
- package/dist/index.js +11675 -13718
- package/dist/mcp/index.d.ts +0 -4
- package/dist/mcp/types.d.ts +0 -1
- package/dist/oh-my-opencode.schema.json +1 -45
- package/dist/plugin/hooks/create-core-hooks.d.ts +0 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +1 -2
- package/dist/shared/omo-process-sweep.d.ts +2 -4
- package/dist/skills/init-deep/SKILL.md +13 -13
- package/dist/skills/ulw-execute/SKILL.md +9 -9
- package/dist/skills/ulw-plan/SKILL.md +0 -1
- package/dist/tui.js +44809 -44883
- package/package.json +16 -21
- package/packages/omo-codex/THIRD-PARTY-NOTICES.md +0 -17
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -3
- package/packages/omo-codex/plugin/.mcp.json +0 -6
- package/packages/omo-codex/plugin/AGENTS.md +5 -5
- package/packages/omo-codex/plugin/README.md +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +1 -15
- 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/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
- 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/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +0 -1
- package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +11 -1
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +45 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +10 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +35 -38
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +278 -193
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +7 -51
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +39 -22
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +64 -8
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +37 -18
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- 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 +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +81 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +6 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +10 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +32 -63
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +7 -53
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +50 -31
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +67 -14
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +36 -17
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +26 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +47 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +12 -146
- package/packages/omo-codex/plugin/package.json +1 -2
- package/packages/omo-codex/plugin/scripts/AGENTS.md +0 -1
- package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +0 -1
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
- package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
- package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
- package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +13 -13
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +2 -2
- package/packages/omo-codex/plugin/skills/ulw-execute/SKILL.md +11 -19
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +2 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +0 -1
- package/packages/omo-codex/plugin/test/AGENTS.md +2 -2
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +2 -21
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -2
- package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +0 -25
- package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +0 -50
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +0 -1
- package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
- package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +227 -435
- package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
- package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
- package/packages/shared-skills/skills/init-deep/SKILL.md +13 -13
- package/packages/shared-skills/skills/ulw-execute/SKILL.md +9 -9
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +0 -1
- package/dist/config/schema/codegraph.d.ts +0 -12
- package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +0 -17
- package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
- package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
- package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
- package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
- package/dist/mcp/codegraph.d.ts +0 -16
- package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
- package/packages/omo-codex/plugin/components/codegraph/LICENSE +0 -21
- package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
- package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12326
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9908
- package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
- package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
- package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
- package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -310
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -92
- package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
- package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -22
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
- package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
- package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
- package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
- package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
- package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
- package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
- package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
- package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
- package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
- package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
- package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
- package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
- package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +0 -47
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
- package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
- package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
- package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate.test.ts +0 -101
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
- package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
- package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
|
@@ -78,9 +78,9 @@ describe("getCodexOmoConfig", () => {
|
|
|
78
78
|
writeOmoConfig(
|
|
79
79
|
homeDir,
|
|
80
80
|
JSON.stringify({
|
|
81
|
-
|
|
82
|
-
"[codex]": {
|
|
83
|
-
"[opencode]": {
|
|
81
|
+
telemetry: { enabled: true },
|
|
82
|
+
"[codex]": { telemetry: { enabled: false } },
|
|
83
|
+
"[opencode]": { telemetry: { enabled: true } },
|
|
84
84
|
}),
|
|
85
85
|
)
|
|
86
86
|
|
|
@@ -88,120 +88,36 @@ describe("getCodexOmoConfig", () => {
|
|
|
88
88
|
const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
|
|
89
89
|
|
|
90
90
|
// then
|
|
91
|
-
expect(result.
|
|
92
|
-
auto_provision: true,
|
|
93
|
-
daemon: true,
|
|
94
|
-
enabled: false,
|
|
95
|
-
install_dir: "/base",
|
|
96
|
-
telemetry: false,
|
|
97
|
-
})
|
|
98
|
-
expect(result.trustedCodegraphInstallDir).toBe("/base")
|
|
99
|
-
})
|
|
100
|
-
|
|
101
|
-
it("#given project SOT sets install_dir #when loading config #then only the effective value changes while trusted install root stays global", () => {
|
|
102
|
-
// given
|
|
103
|
-
const homeDir = createTemporaryDirectory("omo-codex-shared-trusted-home-")
|
|
104
|
-
const cwd = createTemporaryDirectory("omo-codex-shared-trusted-project-")
|
|
105
|
-
writeOmoConfig(homeDir, JSON.stringify({ codegraph: { enabled: true, install_dir: "/global-codegraph" } }))
|
|
106
|
-
writeOmoConfig(cwd, JSON.stringify({ codegraph: { install_dir: "/project-codegraph" } }))
|
|
107
|
-
|
|
108
|
-
// when
|
|
109
|
-
const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
|
|
110
|
-
|
|
111
|
-
// then
|
|
112
|
-
expect(result.codegraph?.install_dir).toBe("/project-codegraph")
|
|
113
|
-
expect(result.trustedCodegraphInstallDir).toBe("/global-codegraph")
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
it("#given codex SOT sets CodeGraph excluded roots #when loading config #then roots are returned to hooks", () => {
|
|
117
|
-
// given
|
|
118
|
-
const homeDir = createTemporaryDirectory("omo-codex-shared-excluded-home-")
|
|
119
|
-
const cwd = createTemporaryDirectory("omo-codex-shared-excluded-project-")
|
|
120
|
-
writeOmoConfig(
|
|
121
|
-
homeDir,
|
|
122
|
-
JSON.stringify({
|
|
123
|
-
"[codex]": { codegraph: { excluded_roots: ["/tmp/omo-research", "/private/tmp/omo-research"] } },
|
|
124
|
-
}),
|
|
125
|
-
)
|
|
126
|
-
|
|
127
|
-
// when
|
|
128
|
-
const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
|
|
129
|
-
|
|
130
|
-
// then
|
|
131
|
-
expect(result.codegraph?.excluded_roots).toEqual(["/tmp/omo-research", "/private/tmp/omo-research"])
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
it("#given codex SOT sets the SessionStart cooldown #when loading config #then the configured base interval is returned", () => {
|
|
135
|
-
// given
|
|
136
|
-
const homeDir = createTemporaryDirectory("omo-codex-shared-cooldown-home-")
|
|
137
|
-
const cwd = createTemporaryDirectory("omo-codex-shared-cooldown-project-")
|
|
138
|
-
writeOmoConfig(homeDir, JSON.stringify({ "[codex]": { codegraph: { session_start_cooldown_ms: 900_000 } } }))
|
|
139
|
-
|
|
140
|
-
// when
|
|
141
|
-
const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
|
|
142
|
-
|
|
143
|
-
// then
|
|
144
|
-
expect(result.codegraph?.session_start_cooldown_ms).toBe(900_000)
|
|
91
|
+
expect(result.telemetry?.enabled).toBe(false)
|
|
145
92
|
expect(result.warnings).toEqual([])
|
|
146
93
|
})
|
|
147
94
|
|
|
148
|
-
it("#given
|
|
95
|
+
it("#given a project SOT layer #when loading config #then the project value overrides the user layer", () => {
|
|
149
96
|
// given
|
|
150
|
-
const homeDir = createTemporaryDirectory("omo-codex-shared-
|
|
151
|
-
const cwd = createTemporaryDirectory("omo-codex-shared-
|
|
152
|
-
writeOmoConfig(homeDir, JSON.stringify({
|
|
97
|
+
const homeDir = createTemporaryDirectory("omo-codex-shared-project-home-")
|
|
98
|
+
const cwd = createTemporaryDirectory("omo-codex-shared-project-project-")
|
|
99
|
+
writeOmoConfig(homeDir, JSON.stringify({ task: { default_concurrency: 3 } }))
|
|
100
|
+
writeOmoConfig(cwd, JSON.stringify({ task: { default_concurrency: 7 } }))
|
|
153
101
|
|
|
154
102
|
// when
|
|
155
103
|
const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
|
|
156
104
|
|
|
157
105
|
// then
|
|
158
|
-
expect(result.
|
|
159
|
-
expect(result.warnings).toEqual([])
|
|
106
|
+
expect(result.task?.default_concurrency).toBe(7)
|
|
160
107
|
})
|
|
161
108
|
|
|
162
|
-
it("#given codex SOT
|
|
109
|
+
it("#given a codex SOT setting with the wrong type #when loading config #then the value is rejected with a warning", () => {
|
|
163
110
|
// given
|
|
164
|
-
const homeDir = createTemporaryDirectory("omo-codex-shared-
|
|
165
|
-
const cwd = createTemporaryDirectory("omo-codex-shared-
|
|
166
|
-
writeOmoConfig(homeDir, JSON.stringify({ "[codex]": {
|
|
111
|
+
const homeDir = createTemporaryDirectory("omo-codex-shared-invalid-home-")
|
|
112
|
+
const cwd = createTemporaryDirectory("omo-codex-shared-invalid-project-")
|
|
113
|
+
writeOmoConfig(homeDir, JSON.stringify({ telemetry: { enabled: true }, "[codex]": { telemetry: { enabled: "yes" } } }))
|
|
167
114
|
|
|
168
115
|
// when
|
|
169
116
|
const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
|
|
170
117
|
|
|
171
118
|
// then
|
|
172
|
-
expect(result.
|
|
173
|
-
expect(result.warnings).
|
|
174
|
-
})
|
|
175
|
-
|
|
176
|
-
it("#given codex SOT sets codegraph.daemon to a non-boolean #when loading config #then the value is rejected with a warning", () => {
|
|
177
|
-
// given
|
|
178
|
-
const homeDir = createTemporaryDirectory("omo-codex-shared-daemon-invalid-home-")
|
|
179
|
-
const cwd = createTemporaryDirectory("omo-codex-shared-daemon-invalid-project-")
|
|
180
|
-
writeOmoConfig(homeDir, JSON.stringify({ "[codex]": { codegraph: { daemon: "yes" } } }))
|
|
181
|
-
|
|
182
|
-
// when
|
|
183
|
-
const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
|
|
184
|
-
|
|
185
|
-
// then
|
|
186
|
-
expect(result.codegraph?.daemon).toBe(true)
|
|
187
|
-
expect(result.warnings).toContain(`Invalid omo config at ${join(homeDir, ".omo", "omo.jsonc")}: [codex].codegraph.daemon`)
|
|
188
|
-
})
|
|
189
|
-
|
|
190
|
-
it("#given legacy env override and SOT value #when loading config #then env wins over the SOT", () => {
|
|
191
|
-
// given
|
|
192
|
-
const homeDir = createTemporaryDirectory("omo-codex-shared-env-")
|
|
193
|
-
const cwd = createTemporaryDirectory("omo-codex-project-env-")
|
|
194
|
-
writeOmoConfig(homeDir, JSON.stringify({ codegraph: { enabled: false } }))
|
|
195
|
-
|
|
196
|
-
// when
|
|
197
|
-
const result = getCodexOmoConfig({
|
|
198
|
-
cwd,
|
|
199
|
-
homeDir,
|
|
200
|
-
env: { CODEX_CODEGRAPH_ENABLED: "1" },
|
|
201
|
-
})
|
|
202
|
-
|
|
203
|
-
// then
|
|
204
|
-
expect(result.codegraph?.enabled).toBe(true)
|
|
119
|
+
expect(result.telemetry).toBeUndefined()
|
|
120
|
+
expect(result.warnings).toContain(`Invalid omo config at ${join(homeDir, ".omo", "omo.jsonc")}: [codex].telemetry.enabled`)
|
|
205
121
|
})
|
|
206
122
|
|
|
207
123
|
it("#given no SOT files #when loading config #then returns built-in defaults and missing global source", () => {
|
|
@@ -213,12 +129,8 @@ describe("getCodexOmoConfig", () => {
|
|
|
213
129
|
const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
|
|
214
130
|
|
|
215
131
|
// then
|
|
216
|
-
expect(result.
|
|
217
|
-
|
|
218
|
-
daemon: true,
|
|
219
|
-
enabled: true,
|
|
220
|
-
telemetry: false,
|
|
221
|
-
})
|
|
132
|
+
expect(result.telemetry).toBeUndefined()
|
|
133
|
+
expect(result.warnings).toEqual([])
|
|
222
134
|
expect(result.sources).toContainEqual({
|
|
223
135
|
exists: false,
|
|
224
136
|
loaded: false,
|
|
@@ -227,23 +139,10 @@ describe("getCodexOmoConfig", () => {
|
|
|
227
139
|
})
|
|
228
140
|
})
|
|
229
141
|
|
|
230
|
-
it("#given codex-unsupported codegraph setting #when loading config #then returns loader warnings", () => {
|
|
231
|
-
// given
|
|
232
|
-
const homeDir = createTemporaryDirectory("omo-codex-shared-warnings-")
|
|
233
|
-
const cwd = createTemporaryDirectory("omo-codex-project-warnings-")
|
|
234
|
-
writeOmoConfig(homeDir, JSON.stringify({ "[codex]": { codegraph: { watch_debounce_ms: 42 } } }))
|
|
235
|
-
|
|
236
|
-
// when
|
|
237
|
-
const result = getCodexOmoConfig({ cwd, homeDir, env: {} })
|
|
238
|
-
|
|
239
|
-
// then
|
|
240
|
-
expect(result.warnings).toContain("codegraph.watch_debounce_ms is not supported for harness codex")
|
|
241
|
-
})
|
|
242
|
-
|
|
243
142
|
it("#given only legacy config.jsonc #when codex starts #then migrates once with a backup before loading the unified codex view", () => {
|
|
244
143
|
// given
|
|
245
144
|
const homeDir = createTemporaryDirectory("omo-codex-legacy-upgrade-")
|
|
246
|
-
writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": {
|
|
145
|
+
writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: false } } }))
|
|
247
146
|
const legacyPath = join(homeDir, ".omo", "config.jsonc")
|
|
248
147
|
|
|
249
148
|
// when
|
|
@@ -252,7 +151,7 @@ describe("getCodexOmoConfig", () => {
|
|
|
252
151
|
const second = getCodexOmoConfig({ cwd: homeDir, homeDir, env: {} })
|
|
253
152
|
|
|
254
153
|
// then
|
|
255
|
-
expect(first.
|
|
154
|
+
expect(first.telemetry?.enabled).toBe(false)
|
|
256
155
|
expect(first.warnings.some((warning) => warning.startsWith("omo-codex: migrated legacy configuration from ")
|
|
257
156
|
&& warning.endsWith("/.omo/config.jsonc"))).toBe(true)
|
|
258
157
|
expect(readOmoJson(homeDir)["_migrations"]).toEqual(["2026-07-codex-config-jsonc"])
|
|
@@ -266,8 +165,8 @@ describe("getCodexOmoConfig", () => {
|
|
|
266
165
|
it("#given a legacy migration conflict #when codex starts #then exposes the migration summary and conflict through loader warnings", () => {
|
|
267
166
|
// given
|
|
268
167
|
const homeDir = createTemporaryDirectory("omo-codex-legacy-conflict-")
|
|
269
|
-
writeOmoConfig(homeDir, JSON.stringify({
|
|
270
|
-
writeLegacyOmoConfig(homeDir, JSON.stringify({
|
|
168
|
+
writeOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: true } } }))
|
|
169
|
+
writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: false } } }))
|
|
271
170
|
|
|
272
171
|
// when
|
|
273
172
|
const result = getCodexOmoConfig({ cwd: homeDir, homeDir, env: {} })
|
|
@@ -275,7 +174,7 @@ describe("getCodexOmoConfig", () => {
|
|
|
275
174
|
// then
|
|
276
175
|
expect(result.warnings.some((warning) => warning.startsWith("omo-codex: migrated legacy configuration from ")
|
|
277
176
|
&& warning.endsWith("/.omo/config.jsonc"))).toBe(true)
|
|
278
|
-
expect(result.warnings).toContain("omo-codex: configuration migration: skipped:
|
|
177
|
+
expect(result.warnings).toContain("omo-codex: configuration migration: skipped: [codex].telemetry.enabled legacy=false kept=true")
|
|
279
178
|
})
|
|
280
179
|
|
|
281
180
|
it("#given overlapping [omo] and [senpi] blocks in legacy config #when Codex migrates #then the transform conflict is reported", () => {
|
|
@@ -310,7 +209,7 @@ describe("getCodexOmoConfig", () => {
|
|
|
310
209
|
it("#given codex starts before opencode #when both legacy source groups exist #then each distinct migration id is applied once", () => {
|
|
311
210
|
// given
|
|
312
211
|
const homeDir = createTemporaryDirectory("omo-codex-order-codex-first-")
|
|
313
|
-
writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": {
|
|
212
|
+
writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: false } } }))
|
|
314
213
|
writeOpenCodeConfig(homeDir)
|
|
315
214
|
const openCodeSource = join(homeDir, ".config", "opencode", "oh-my-openagent.jsonc")
|
|
316
215
|
|
|
@@ -322,13 +221,17 @@ describe("getCodexOmoConfig", () => {
|
|
|
322
221
|
// then
|
|
323
222
|
expect(remainsAfterCodexStartup).toBe(true)
|
|
324
223
|
expect(existsSync(openCodeSource)).toBe(false)
|
|
325
|
-
expect(migrationIds(homeDir)).toEqual([
|
|
224
|
+
expect(migrationIds(homeDir)).toEqual([
|
|
225
|
+
"2026-07-codex-config-jsonc",
|
|
226
|
+
"2026-07-opencode-config-unification",
|
|
227
|
+
"2026-08-reasoning-unification",
|
|
228
|
+
])
|
|
326
229
|
})
|
|
327
230
|
|
|
328
231
|
it("#given opencode starts before codex #when both legacy source groups exist #then each distinct migration id is applied once", () => {
|
|
329
232
|
// given
|
|
330
233
|
const homeDir = createTemporaryDirectory("omo-codex-order-opencode-first-")
|
|
331
|
-
writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": {
|
|
234
|
+
writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: false } } }))
|
|
332
235
|
writeOpenCodeConfig(homeDir)
|
|
333
236
|
|
|
334
237
|
// when
|
|
@@ -336,13 +239,17 @@ describe("getCodexOmoConfig", () => {
|
|
|
336
239
|
getCodexOmoConfig({ cwd: homeDir, homeDir, env: {} })
|
|
337
240
|
|
|
338
241
|
// then
|
|
339
|
-
expect(migrationIds(homeDir)).toEqual([
|
|
242
|
+
expect(migrationIds(homeDir)).toEqual([
|
|
243
|
+
"2026-07-opencode-config-unification",
|
|
244
|
+
"2026-07-codex-config-jsonc",
|
|
245
|
+
"2026-08-reasoning-unification",
|
|
246
|
+
])
|
|
340
247
|
})
|
|
341
248
|
|
|
342
249
|
it("#given concurrent codex and opencode starts #when opencode owns the shared lock #then both migration ids are applied exactly once", () => {
|
|
343
250
|
// given
|
|
344
251
|
const homeDir = createTemporaryDirectory("omo-codex-order-concurrent-")
|
|
345
|
-
writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": {
|
|
252
|
+
writeLegacyOmoConfig(homeDir, JSON.stringify({ "[codex]": { telemetry: { enabled: false } } }))
|
|
346
253
|
writeOpenCodeConfig(homeDir)
|
|
347
254
|
let codexResult: ReturnType<typeof runCodexStartupMigration> | undefined
|
|
348
255
|
|
|
@@ -355,6 +262,10 @@ describe("getCodexOmoConfig", () => {
|
|
|
355
262
|
// then
|
|
356
263
|
if (codexResult === undefined) throw new Error("Expected concurrent Codex migration attempt")
|
|
357
264
|
expect(codexResult.error).toBe("Configuration migration is already running")
|
|
358
|
-
expect(migrationIds(homeDir)).toEqual([
|
|
265
|
+
expect(migrationIds(homeDir)).toEqual([
|
|
266
|
+
"2026-07-opencode-config-unification",
|
|
267
|
+
"2026-07-codex-config-jsonc",
|
|
268
|
+
"2026-08-reasoning-unification",
|
|
269
|
+
])
|
|
359
270
|
})
|
|
360
271
|
})
|
|
@@ -42,7 +42,7 @@ Generate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.
|
|
|
42
42
|
|
|
43
43
|
1. **Discovery + Analysis** (concurrent)
|
|
44
44
|
- Fire background explore agents immediately
|
|
45
|
-
- Main session: bash structure + LSP/
|
|
45
|
+
- Main session: bash structure + LSP/ast-grep code map + read existing AGENTS.md
|
|
46
46
|
2. **Score & Decide** - Determine AGENTS.md locations from merged findings
|
|
47
47
|
3. **Generate** - Root first, then subdirs in parallel
|
|
48
48
|
4. **Review** - Deduplicate, trim, validate
|
|
@@ -51,7 +51,7 @@ Generate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.
|
|
|
51
51
|
**TodoWrite ALL phases. Mark in_progress → completed in real-time.**
|
|
52
52
|
```
|
|
53
53
|
TodoWrite([
|
|
54
|
-
{ id: "discovery", content: "Fire explore agents + LSP/
|
|
54
|
+
{ id: "discovery", content: "Fire explore agents + LSP/ast-grep map + read existing", status: "pending", priority: "high" },
|
|
55
55
|
{ id: "scoring", content: "Score directories, determine locations", status: "pending", priority: "high" },
|
|
56
56
|
{ id: "generate", content: "Generate AGENTS.md files (root + subdirs)", status: "pending", priority: "high" },
|
|
57
57
|
{ id: "review", content: "Deduplicate, validate, trim", status: "pending", priority: "medium" }
|
|
@@ -67,16 +67,16 @@ TodoWrite([
|
|
|
67
67
|
|
|
68
68
|
### Fire Background Explore Agents IMMEDIATELY
|
|
69
69
|
|
|
70
|
-
Don't wait-these run async while main session works. **
|
|
70
|
+
Don't wait-these run async while main session works. **Ground every agent in real symbol data**: any task touching structure, entry points, dependencies, or hotspots MUST query `lsp_symbols`/`lsp_find_references` and the ast-grep skill (`sg`) when present, and ground its claims in that data instead of guessing from conventions. Richer real context per agent = a more accurate project map.
|
|
71
71
|
|
|
72
72
|
```
|
|
73
73
|
// Fire all at once, collect results later
|
|
74
|
-
task(subagent_type="explore", load_skills=[], description="Explore project structure", run_in_background=true, prompt="Project structure: map real layout via
|
|
75
|
-
task(subagent_type="explore", load_skills=[], description="Find entry points", run_in_background=true, prompt="Entry points: FIND main files, trace reach via
|
|
74
|
+
task(subagent_type="explore", load_skills=[], description="Explore project structure", run_in_background=true, prompt="Project structure: map real layout via glob + lsp_symbols scope=workspace → REPORT deviations from standard patterns")
|
|
75
|
+
task(subagent_type="explore", load_skills=[], description="Find entry points", run_in_background=true, prompt="Entry points: FIND main files, trace reach via lsp_symbols + lsp_find_references → REPORT non-standard organization")
|
|
76
76
|
task(subagent_type="explore", load_skills=[], description="Find conventions", run_in_background=true, prompt="Conventions: FIND config files (.eslintrc, pyproject.toml, .editorconfig) → REPORT project-specific rules")
|
|
77
77
|
task(subagent_type="explore", load_skills=[], description="Find anti-patterns", run_in_background=true, prompt="Anti-patterns: FIND 'DO NOT', 'NEVER', 'ALWAYS', 'DEPRECATED' comments → LIST forbidden patterns")
|
|
78
78
|
task(subagent_type="explore", load_skills=[], description="Explore build/CI", run_in_background=true, prompt="Build/CI: FIND .github/workflows, Makefile → REPORT non-standard patterns")
|
|
79
|
-
task(subagent_type="explore", load_skills=[], description="Find test patterns", run_in_background=true, prompt="Test patterns: FIND test configs/structure;
|
|
79
|
+
task(subagent_type="explore", load_skills=[], description="Find test patterns", run_in_background=true, prompt="Test patterns: FIND test configs/structure; lsp_find_references on core modules to see what is covered → REPORT unique conventions")
|
|
80
80
|
```
|
|
81
81
|
|
|
82
82
|
<dynamic-agents>
|
|
@@ -138,7 +138,7 @@ For each existing file found:
|
|
|
138
138
|
|
|
139
139
|
If `--create-new`: Read all existing first (preserve context) → then delete all → regenerate.
|
|
140
140
|
|
|
141
|
-
#### 3. Code Map - drive LSP AND
|
|
141
|
+
#### 3. Code Map - drive LSP AND ast-grep (do NOT skip)
|
|
142
142
|
|
|
143
143
|
Highest-signal source for the CODE MAP and the Symbol/Export/Reference scoring rows. Complementary, not alternatives - run BOTH when present, alongside the explore agents.
|
|
144
144
|
|
|
@@ -147,10 +147,10 @@ Highest-signal source for the CODE MAP and the Symbol/Export/Reference scoring r
|
|
|
147
147
|
- `lsp_symbols` scope="workspace", query by kind (class/interface/function) -> symbol inventory.
|
|
148
148
|
- `lsp_find_references` on top exports (line/character from the symbols result) -> reference centrality.
|
|
149
149
|
|
|
150
|
-
**
|
|
151
|
-
- `
|
|
150
|
+
**ast-grep** - load the ast-grep skill; a first-class peer to LSP, NOT a last resort:
|
|
151
|
+
- `sg --pattern 'export $$$' --lang <lang>` -> export inventory; `sg --pattern 'import $$$ from "$MOD"'` -> dependency edges between modules for the scoring matrix.
|
|
152
152
|
|
|
153
|
-
Only if
|
|
153
|
+
Only if LSP is unavailable: explore agents + ast-grep alone, and mark reference centrality unmeasured in the CODE MAP.
|
|
154
154
|
|
|
155
155
|
### Collect Background Results
|
|
156
156
|
|
|
@@ -159,7 +159,7 @@ Only if NEITHER exists: explore agents + the ast-grep skill (`sg`), and mark cen
|
|
|
159
159
|
for each background task ID (`bg_...`): background_output(task_id="bg_...")
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
-
**Merge: bash + LSP/
|
|
162
|
+
**Merge: bash + LSP/ast-grep + existing + explore findings. Mark "discovery" as completed.**
|
|
163
163
|
|
|
164
164
|
---
|
|
165
165
|
|
|
@@ -235,7 +235,7 @@ NEVER use Write to overwrite an existing file. ALWAYS check existence first via
|
|
|
235
235
|
|------|----------|-------|
|
|
236
236
|
|
|
237
237
|
## CODE MAP
|
|
238
|
-
{From LSP/
|
|
238
|
+
{From LSP/ast-grep - skip only if neither exists or project <10 files}
|
|
239
239
|
|
|
240
240
|
| Symbol | Type | Location | Refs | Role |
|
|
241
241
|
|--------|------|----------|------|------|
|
|
@@ -318,7 +318,7 @@ Hierarchy:
|
|
|
318
318
|
## Anti-Patterns
|
|
319
319
|
|
|
320
320
|
- **Static agent count**: MUST vary agents based on project size/depth
|
|
321
|
-
- **Sequential execution**: MUST parallel (explore + LSP +
|
|
321
|
+
- **Sequential execution**: MUST parallel (explore + LSP + ast-grep concurrent)
|
|
322
322
|
- **Ignoring existing**: ALWAYS read existing first, even with --create-new
|
|
323
323
|
- **Over-documenting**: Not every dir needs AGENTS.md
|
|
324
324
|
- **Redundancy**: Child never repeats parent
|
|
@@ -70,7 +70,7 @@ sync_latest_source openai/codex "$LAZYCODEX_SOURCE_ROOT/openai-codex-source"
|
|
|
70
70
|
- `$CODEX_HOME/config.toml` exists and parses; LazyCodex-managed entries match what the latest installer would write.
|
|
71
71
|
- Plugin payload present and non-empty: read `.codex-plugin/plugin.json`; when that manifest declares a `hooks` array, validate every direct hook path declared by the manifest; require `hooks/hooks.json` only when the manifest declares it; do not require retired paths such as `components/workflow-selector` or `hooks/user-prompt-submit-selecting-lazycodex-workflow.json` unless the current manifest declares them.
|
|
72
72
|
- Verify the manifest-declared runtime payload, not a remembered source tree. Current payload includes `skills/`, `.mcp.json`, root CLI runtimes such as `dist/cli/index.js` and `dist/cli-node/index.js`, and every hook/MCP `components/*/dist/*.js` target referenced by installed manifests.
|
|
73
|
-
- Treat install-time materialization rewrites as expected when the rewritten target exists and is non-empty. For example, `.mcp.json` may use plugin-local or absolute installed paths for
|
|
73
|
+
- Treat install-time materialization rewrites as expected when the rewritten target exists and is non-empty. For example, `.mcp.json` may use plugin-local or absolute installed paths for MCP runtimes; that is PASS/WARN context, not payload drift. Missing or zero-byte rewritten targets are FAIL.
|
|
74
74
|
- Stale project-local leftovers the installer now removes (e.g. `.codex/hooks.json`, `.codex/skills` in the project) are flagged, not deleted.
|
|
75
75
|
4. Probe the real surface. Do not invoke `lazycodex doctor`; this skill is already running inside that doctor workflow, so calling it would recurse. Instead run non-recursive probes directly: `codex --version`, `command -v codex`, the bin-link checks above, config/plugin payload inspections, and a trivial non-interactive Codex invocation that loads the plugin. Use the configured Codex default model for the runtime probe unless the user explicitly passed a model override to the doctor surface; never force a guessed/rejected model such as `gpt-5.5-codex-mini`. Capture stderr verbatim; a clean exit with warnings is WARN, not PASS.
|
|
76
76
|
5. Compare for drift. Where installed manifest-declared bundled files differ from the same files at the installed version, or the latest source removed or renamed something the local config still references, record it with both paths. Do not report expected materialization differences, such as absolute `.mcp.json` runtime paths, as drift when their targets exist and are non-empty.
|
|
@@ -236,8 +236,8 @@ and utility functions to batch commands and reduce output. Keep direct calls
|
|
|
236
236
|
when one result chooses the next action, outputs are already small, semantic
|
|
237
237
|
judgment is required between calls, approval or side effects are involved,
|
|
238
238
|
or native artifacts / citations must be preserved.
|
|
239
|
-
- Architecture / flow / blast radius →
|
|
240
|
-
|
|
239
|
+
- Architecture / flow / blast radius → explore agents plus LSP references
|
|
240
|
+
and impact; do not guess from conventions.
|
|
241
241
|
- **SYMBOLS REQUIRE LSP** — definitions, references, rename impact,
|
|
242
242
|
workspace symbols, and diagnostics use the available `lsp_*` tools, not
|
|
243
243
|
text search. Run diagnostics after edits and treat errors as blocking.
|
|
@@ -49,17 +49,17 @@ $ulw-execute [plan-name] [--worktree <absolute-path>] [--make-pr] [--ship]
|
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
- `plan-name` (optional): a full or partial file stem under `.omo/plans/`.
|
|
52
|
-
- `--worktree` (
|
|
53
|
-
- `--make-pr` (optional): deliver
|
|
52
|
+
- `--worktree` (optional): reuse an existing task-owned worktree for the first phase instead of creating one; every phase runs in a task-owned worktree regardless.
|
|
53
|
+
- `--make-pr` (optional): deliver each phase's worktree as a pull request — push the branch, open a reviewer-readable PR, hand off with the URL, and merge only if the user asks.
|
|
54
54
|
- `--ship` (optional): full delivery lifecycle; implies `--make-pr`. After the PR opens, stay on the job until it is MERGED: watch CI and review gates, fix failures and address feedback from the worktree (fresh QA evidence for behavior changes), merge per the repository's merge policy, then remove the worktree and sync `.omo/` state back.
|
|
55
55
|
|
|
56
56
|
## Goal and todo discipline (MANDATORY)
|
|
57
57
|
|
|
58
58
|
Do ALL of this immediately after the plan is selected, BEFORE the first implementation dispatch. Skipping any step is a defect.
|
|
59
59
|
|
|
60
|
-
1. **Set the goal, in detail.** When a goal tool is available (`create_goal`), call it with a DETAILED objective: the plan name and path, the concrete end state, the phase and task counts, the delivery mode (direct, `--make-pr`, or `--ship`), and how completion will be verified. One work session = one goal. No goal tool -> record the same objective as the first ledger entry.
|
|
60
|
+
1. **Set the goal, in detail.** When a goal tool is available (`create_goal`), call it with a DETAILED objective: the plan name and path, the concrete end state, the phase and task counts, the delivery mode (direct, `--make-pr`, or `--ship`), and how completion will be verified. One work session = one registered goal (the goal tool holds one active goal); each phase then carries its own concrete goal — the ledger entry Phase 2 records before the wave's first dispatch, defined from the previous phase's landed and verified evidence. No goal tool -> record the same objective as the first ledger entry.
|
|
61
61
|
2. **Register every phase and task as todos.** Mirror the plan into the todo/plan tool of your harness: one phase per plan wave, one todo per column-zero checkbox (including the final verification wave). Register ALL of them up front - never keep tasks in memory only.
|
|
62
|
-
3. **Keep them current at every moment.** Mark a todo in_progress when its work dispatches and done immediately after its verification passes. Never batch-complete at the end, never execute work that is not a registered todo; discovered work is appended as a todo before it runs. The todo list, Boulder state, and plan checkboxes must always tell the same story.
|
|
62
|
+
3. **Keep them current at every moment.** Mark a todo in_progress when its work dispatches and done immediately after its verification passes. Never batch-complete at the end, never execute work that is not a registered todo; discovered work — a pre-existing bug, failing test, stale doc, or wrong guidance — is appended to the plan as a checkbox, mirrored as a todo before it runs, and fixed to the ideal state, never deferred as a follow-up. A worker that meets a defect outside its assigned files reports it instead of fixing it; only the orchestrator appends the checkbox and dispatches it to a correctly scoped unit. The todo list, Boulder state, and plan checkboxes must always tell the same story.
|
|
63
63
|
|
|
64
64
|
## Phase 1: Select the plan
|
|
65
65
|
|
|
@@ -102,14 +102,14 @@ Write `.omo/boulder.json` before implementation starts. Prefix session ids with
|
|
|
102
102
|
}
|
|
103
103
|
```
|
|
104
104
|
|
|
105
|
-
|
|
105
|
+
Every phase (plan wave) runs in its own task-owned worktree with its own goal: before the wave's first dispatch, record the wave's goal — its checkboxes and their acceptance criteria — as a ledger entry, then `git worktree add <repo>-wt/<plan>-<wave> <branch off the integration base>` (or verify a `--worktree` path with `git worktree list --porcelain`), store the absolute path as `worktree_path`, run every edit, command, test, and evidence capture inside it; the wave lands on the integration base once its checkboxes are verified (direct merge, or the PR under `--make-pr`/`--ship`), and the next wave branches from that landed base.
|
|
106
106
|
|
|
107
107
|
## Parallel delivery lanes (teams and worktrees)
|
|
108
108
|
|
|
109
109
|
Solo orchestration with parallel background workers is the default topology. Decide once, when the wave's lanes are known, and record the verdict in the ledger:
|
|
110
110
|
|
|
111
111
|
- **Independent lanes -> parallel workers.** Separate files, no shared contract: one parallel spawn burst; no team.
|
|
112
|
-
- **Dependency-ordered lanes ->
|
|
112
|
+
- **Dependency-ordered lanes -> one `workflow` run per wave.** Sub-tasks with real ordering between them (C needs A and B finished first) and a harness with a native `workflow` tool: dispatch the wave as ONE run (one producer node per lane plus a verification node); recover inside it with `retry`/`amend`/`send`; let node completions wake you instead of arming per-lane watchers; the next wave is a NEW run (or `amend` when only the definition changed) — never one graph for the whole plan. Read the `mass-ulw` skill's `SKILL.md` and `references/planning.md` IN FULL before defining any graph.
|
|
113
113
|
- **Overlapping lanes -> a team.** The lanes touch the same module or contract AND running them concurrently actually finishes sooner: stand up a team (where the harness has one) so one lane's discoveries relay through you mid-flight.
|
|
114
114
|
- **PR-mode independent lanes -> a worktree per lane.** Under `--make-pr`/`--ship`, when a wave holds independent checkboxes, give each lane its own branch and task-owned worktree, delivered as its own PR.
|
|
115
115
|
|
|
@@ -169,7 +169,7 @@ Each sub-task message must include:
|
|
|
169
169
|
- Terminal / TUI: drive a real pty; `tmux send-keys` is fine for a boot/behavior smoke, but color/layout/CJK evidence goes through the xterm.js web terminal below, NEVER `tmux capture-pane`.
|
|
170
170
|
- Browser use: prefer the harness's in-app browser control when available and the scenario does not need an authenticated or persistent user browser profile; otherwise drive the real page with Chrome, or agent-browser (https://github.com/vercel-labs/agent-browser) when Chrome is unavailable.
|
|
171
171
|
- Computer use: OS-level GUI automation against the running desktop app when the surface is not a page.
|
|
172
|
-
- TUI visual evidence: when a TUI claim needs visual QA or PR proof, run `
|
|
172
|
+
- TUI visual evidence: when a TUI claim needs visual QA or PR proof, run `bun script/qa/web-terminal-visual-qa.mjs --command "<cmd>" --input "{Enter}" --evidence-dir <dir>` (real pty rendered through xterm.js in Chrome) and attach `terminal.png` plus `metadata.json`.
|
|
173
173
|
6. The adversarial classes that apply to this sub-task (from the 9 ultraqa classes) and how each is probed.
|
|
174
174
|
7. Required artifact path and cleanup receipt.
|
|
175
175
|
8. Tool-use expectations: batch independent tool calls in parallel; when the harness exposes a code-execution surface (eval), use it for multi-call steps instead of one-by-one calls.
|
|
@@ -232,16 +232,9 @@ Only after verification passes:
|
|
|
232
232
|
When all top-level checkboxes in `## TODOs` and `## Final Verification Wave` are complete:
|
|
233
233
|
|
|
234
234
|
1. Run the plan's final verification commands.
|
|
235
|
-
2.
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
- Run a debugging-oriented runtime audit even when the review passes: name at least three plausible failure hypotheses for the changed surface, run the distinguishing checks against the actual artifact, and append a separate durable record with the audit name, exact full SHA, verdict, and evidence artifact/source to `.omo/ulw-execute/ledger.jsonl`. Reuse it only after re-reading an exact audit/SHA match.
|
|
239
|
-
- If any review lane or debugging hypothesis fails, invoke the `debugging` skill, confirm root cause with runtime evidence, add the minimal failing test or reproduction, fix it, rerun the affected verification, then rerun the Global Review and Debugging Gate.
|
|
240
|
-
- Evidence hygiene is mandatory: redact or mask secrets and sensitive user data before writing `.omo/ulw-execute/ledger.jsonl`, a PR body, or a handoff. Never include raw tokens, credentials, auth headers, cookies, API keys, env dumps, private logs, or PII; use concise summaries, lengths, hashes, or short non-sensitive prefixes instead.
|
|
241
|
-
- If the work includes creating, updating, or handing off a PR, refresh `git status` and the PR/branch state from the task-owned worktree after the gate, and include only redacted review/debugging evidence in the PR body or handoff.
|
|
242
|
-
3. Finish the PR/branch lifecycle from its task-owned worktree: sync `.omo/` state back to the main repo, create or update the PR when requested, wait for CI/review/Cubic gates, merge by default unless explicitly opted out, and remove the worktree only after successful merge or explicit handoff.
|
|
243
|
-
4. Remove or mark the Boulder work as completed.
|
|
244
|
-
5. Print an `ORCHESTRATION COMPLETE` block with the plan path, verification commands, Global Review and Debugging Gate verdict, artifacts, and cleanup receipts.
|
|
235
|
+
2. For PR/branch work, finish the lifecycle from the last phase's worktree: sync `.omo/` state back to the main repo, create or update the PR, wait for review/verification gates, merge by default unless explicitly opted out, and remove the worktree only after successful merge or explicit handoff.
|
|
236
|
+
3. Remove or mark the Boulder work as completed.
|
|
237
|
+
4. Print an `ORCHESTRATION COMPLETE` block with the plan path, verification commands, artifacts, and cleanup receipts.
|
|
245
238
|
|
|
246
239
|
## Hard rules
|
|
247
240
|
|
|
@@ -250,7 +243,6 @@ When all top-level checkboxes in `## TODOs` and `## Final Verification Wave` are
|
|
|
250
243
|
- No tests-only completion claim. A Manual-QA artifact is required.
|
|
251
244
|
- **NO DIRECT IMPLEMENTATION BY THE ORCHESTRATOR.** Root NEVER edits product files, writes tests, or runs QA itself — a spawned worker does.
|
|
252
245
|
- No completion claim while an applicable ultraqa adversarial class was never probed. Each applicable class needs a captured observable result; each skipped class needs a one-line not-applicable reason in the ledger.
|
|
253
|
-
- No
|
|
254
|
-
- No PR/branch implementation or review in the main worktree; create or use a task-owned git worktree first.
|
|
246
|
+
- No implementation, review, or merge in the main checkout; every phase works in its task-owned worktree.
|
|
255
247
|
- No unprefixed session ids in Boulder state. Sessions are always recorded as `codex:<session_id>`.
|
|
256
248
|
- No stale-memory execution. The plan and ledger are the durable source of truth.
|
|
@@ -190,6 +190,7 @@ omo-agent-toolkit ulw-loop record-evidence --goal-id <g> --criterion-id <c> --st
|
|
|
190
190
|
# Then use the harness update_goal tool with status complete.
|
|
191
191
|
omo-agent-toolkit ulw-loop checkpoint --goal-id <g> --print-template --json
|
|
192
192
|
# Fill the printed template: replace every placeholder and use real artifact paths under currentAttemptDir.
|
|
193
|
+
# codex-goal-json.goal.objective must equal the plan's codexObjective verbatim.
|
|
193
194
|
omo-agent-toolkit ulw-loop checkpoint --goal-id <g> --status complete --evidence "..." --codex-goal-json <path> --quality-gate-json <path>
|
|
194
195
|
omo-agent-toolkit ulw-loop complete-goals
|
|
195
196
|
```
|
|
@@ -214,7 +215,7 @@ omo-agent-toolkit ulw-loop checkpoint --goal-id <id> --status complete --evidenc
|
|
|
214
215
|
{
|
|
215
216
|
"codeReview":{"by":"lazycodex-code-reviewer","recommendation":"APPROVE","codeQualityStatus":"CLEAR","reportPath":"test/fixtures/artifacts/code-review.md","evidence":"Diff review passed.","blockers":[]},
|
|
216
217
|
"manualQa":{"by":"lazycodex-qa-executor","status":"passed","evidence":"CLI and data surfaces passed.","surfaceEvidence":[{"id":"surface-cli-pass","criterionRef":"C1","surface":"cli","invocation":"omo-agent-toolkit ulw-loop checkpoint --quality-gate-json sample-quality-gate.json --json","verdict":"passed","artifactRefs":["artifact-cli-pass"]},{"id":"surface-data-pass","criterionRef":"C2","surface":"data","invocation":"diff -u before-ledger.json after-ledger.json","verdict":"passed","artifactRefs":["artifact-data-diff"]}],"adversarialCases":[{"id":"adv-malformed-input","criterionRef":"C3","scenario":"malformed gate input omits manual QA evidence","expectedBehavior":"validator rejects ULW_LOOP_QUALITY_GATE_INVALID","verdict":"passed","artifactRefs":["artifact-cli-reject"]}],"artifactRefs":[{"id":"artifact-cli-pass","kind":"cli-transcript","description":"CLI pass artifact.","path":"test/fixtures/artifacts/cli-pass.txt"},{"id":"artifact-cli-reject","kind":"log","description":"Reject log artifact.","path":"test/fixtures/artifacts/rejection.txt"},{"id":"artifact-data-diff","kind":"data-diff","description":"Data diff artifact.","path":"test/fixtures/artifacts/data-diff.txt"}]},
|
|
217
|
-
"gateReview":{"by":"lazycodex-gate-reviewer","recommendation":"APPROVE","reportPath":"test/fixtures/artifacts/gate-review.md","evidence":"Gate review passed.","blockers":[]},
|
|
218
|
+
"gateReview":{"by":"lazycodex-gate-reviewer","recommendation":"APPROVE","reportPath":"test/fixtures/artifacts/gate-review.md","evidence":"Gate review passed.","blockers":[],"notes":[]},
|
|
218
219
|
"iteration":{"fullRerun":true,"status":"passed","rerunCommands":["bunx vitest run packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-doc.test.ts"],"evidence":"Focused rerun passed."},
|
|
219
220
|
"criteriaCoverage":{"totalCriteria":3,"passCount":3,"originalIntent":"User wanted artifact-backed completion.","desiredOutcome":"Behavior ships with review and QA evidence.","userOutcomeReview":"Result matches brief and goals.","adversarialClassesCovered":["malformed_input","stale_state"]}
|
|
220
221
|
}
|
|
@@ -71,7 +71,6 @@ When producing the plan, encode every executable item as a column-zero Markdown
|
|
|
71
71
|
- **Decision-complete is the north star.** The executor has NO interview context - spell out exact paths, "every X in Y", and an explicit Must-NOT-Have. Leave the implementer ZERO judgment calls.
|
|
72
72
|
- **Full scope is the default.** Plan the ENTIRE request; "MVP", "v1", "phase 1", or any reduced subset is never an option you invent or ask about - it exists only if the user introduces it. Scope OUT / Must-NOT-Have entries are guardrails against unrequested additions, never reductions of the request.
|
|
73
73
|
- **Explore before asking.** Discoverable facts (repo/system/docs truth) -> research and cite, never ask. Preferences/tradeoffs -> the only things you bring to the user. When unsure which, treat it as a user-decision.
|
|
74
|
-
- **CodeGraph first when present.** Use `codegraph_explore` for repo how/where/what/flow questions before wider reads; if codegraph_* tools are absent, inactive/uninitialized, or cold-start unavailable, continue with Read/Grep/Glob/LSP and the ast-grep skill.
|
|
75
74
|
- **Two filters** on every candidate question, in order: (1) Could collected evidence answer it? -> explore instead. (2) Could the user's stated intent plus a defensible default answer it? -> adopt the default, record it, do not ask - UNLESS it is an owner-decision, which always survives as a question even when a default exists: anything irreversible / destructive / safety-critical, or a cross-cutting product choice the user lives with (public config surface, distribution / packaging, external dependency or pinned SHA, data / schema shape, real budget / paid-service spend, expected scale or capacity target, target-audience / compliance limits). Extrinsic constraints (budget, mandated stack, scale, audience) leave no repo evidence, so exploration can never surface them - sweep those axes explicitly once per plan and classify each as explored, defaulted (ledger), or asked. Default the reversible internals; surface the owner-decisions.
|
|
76
75
|
- **Explore to sufficiency, then STOP.** One research wave per open question; stop when the clearance check is answerable; never re-explore to double-check.
|
|
77
76
|
- **Parallel-dispatch** independent research in ONE turn and keep working while it runs. Subagent outputs are CLAIMS until you independently verify them.
|
|
@@ -23,10 +23,10 @@
|
|
|
23
23
|
| Aggregate wiring | `aggregate-{manifest,hooks,build,mcp,agents,model-catalog}.test.mjs` |
|
|
24
24
|
| Bootstrap | `bootstrap-{hooks,setup,binlinks,orchestration,ps-guard}.test.mjs` |
|
|
25
25
|
| Update flow | `auto-update{,-state-persistence,-restart-notice,-release-notes}.test.mjs` |
|
|
26
|
-
| Migration | `migrate-codex-config.test.mjs` (1,242 LOC — densest), `
|
|
26
|
+
| Migration | `migrate-codex-config.test.mjs` (1,242 LOC — densest), `multi-agent-v2-regression`, `subagent-limit-migration` |
|
|
27
27
|
| Skills sync | `sync-skills{,-codex-compatibility}.test.mjs`, `ulw-plan`/`ulw-research`/`ulw-loop` skill contracts |
|
|
28
28
|
| Teammode | `teammode-{transport,communication,worktree,safety,thread-links,thread-title,archive-ambiguity}.test.mjs` |
|
|
29
|
-
| Component CLIs | `component-{bundled-cli,bin-names
|
|
29
|
+
| Component CLIs | `component-{bundled-cli,bin-names}.test.mjs`, `lsp-prebuild-layouts` |
|
|
30
30
|
|
|
31
31
|
## CONVENTIONS
|
|
32
32
|
|
|
@@ -30,7 +30,6 @@ test("#given isolated components #when hooks are inspected #then commands stay i
|
|
|
30
30
|
const componentMarkers = [
|
|
31
31
|
"components/comment-checker/dist/cli.js",
|
|
32
32
|
"components/lsp/dist/cli.js",
|
|
33
|
-
"components/codegraph/dist/cli.js",
|
|
34
33
|
"components/rules/dist/cli.js",
|
|
35
34
|
"components/ulw-execute-continuation/dist/cli.js",
|
|
36
35
|
"components/telemetry/dist/cli.js",
|
|
@@ -220,34 +219,16 @@ test("#given aggregate SessionStart hooks #when inspected #then cold-start-prone
|
|
|
220
219
|
const coldStartHooks = sessionStartHooks.filter(
|
|
221
220
|
({ command }) =>
|
|
222
221
|
command.includes("components/telemetry/dist/cli.js") ||
|
|
223
|
-
command.includes("scripts/auto-update.mjs")
|
|
224
|
-
command.includes("components/codegraph/dist/cli.js"),
|
|
222
|
+
command.includes("scripts/auto-update.mjs"),
|
|
225
223
|
);
|
|
226
224
|
|
|
227
225
|
// then
|
|
228
|
-
assert.equal(coldStartHooks.length,
|
|
226
|
+
assert.equal(coldStartHooks.length, 2);
|
|
229
227
|
for (const hook of coldStartHooks) {
|
|
230
228
|
assert.equal(hook.timeout, 15, `${hook.source} must carry timeout 15 for cold-start headroom`);
|
|
231
229
|
}
|
|
232
230
|
});
|
|
233
231
|
|
|
234
|
-
test("#given aggregate PostToolUse hooks #when inspected #then CodeGraph init guidance is registered for CodeGraph tools", async () => {
|
|
235
|
-
// given
|
|
236
|
-
const commandHooks = await readAggregateCommandHooks();
|
|
237
|
-
|
|
238
|
-
// when
|
|
239
|
-
const codegraphPostToolUseHooks = commandHooks.filter(
|
|
240
|
-
(hook) =>
|
|
241
|
-
hook.eventName === "PostToolUse" &&
|
|
242
|
-
hook.handler.command === 'node "${PLUGIN_ROOT}/components/codegraph/dist/cli.js" hook post-tool-use',
|
|
243
|
-
);
|
|
244
|
-
|
|
245
|
-
// then
|
|
246
|
-
assert.equal(codegraphPostToolUseHooks.length, 1);
|
|
247
|
-
assert.equal(codegraphPostToolUseHooks[0]?.matcher, "^(codegraph[._].*|mcp__codegraph__.*)$");
|
|
248
|
-
assert.match(codegraphPostToolUseHooks[0]?.handler.statusMessage ?? "", /\S/);
|
|
249
|
-
});
|
|
250
|
-
|
|
251
232
|
test("#given aggregate PostToolUse hooks #when inspected #then thread title hygiene is registered for created Codex threads", async () => {
|
|
252
233
|
// given
|
|
253
234
|
const commandHooks = await readAggregateCommandHooks();
|
|
@@ -17,7 +17,7 @@ test("#given aggregate plugin manifest #when inspected #then it owns the omo nam
|
|
|
17
17
|
// then
|
|
18
18
|
assert.equal(manifest.name, "omo");
|
|
19
19
|
assert(Array.isArray(hookPaths));
|
|
20
|
-
assert.equal(hookPaths.length,
|
|
20
|
+
assert.equal(hookPaths.length, 21);
|
|
21
21
|
assert(hookPaths.every((hookPath) => typeof hookPath === "string" && hookPath.startsWith("./hooks/")));
|
|
22
22
|
assert(!hookPaths.includes("./hooks/hooks.json"));
|
|
23
23
|
assert(!hookPaths.includes("./hooks/user-prompt-submit-selecting-lazycodex-workflow.json"));
|
|
@@ -54,7 +54,6 @@ test("#given component directories #when scanned #then only intentional resource
|
|
|
54
54
|
// then
|
|
55
55
|
assert.deepEqual(componentNames, [
|
|
56
56
|
"bootstrap",
|
|
57
|
-
"codegraph",
|
|
58
57
|
"comment-checker",
|
|
59
58
|
"git-bash",
|
|
60
59
|
"lazycodex-executor-verify",
|
|
@@ -18,14 +18,13 @@ test("#given aggregate MCP config #when inspected #then code MCPs reference pack
|
|
|
18
18
|
// when
|
|
19
19
|
const lspServer = mcp.mcpServers.lsp;
|
|
20
20
|
const gitBashServer = mcp.mcpServers.git_bash;
|
|
21
|
-
const codegraphServer = mcp.mcpServers.codegraph;
|
|
22
21
|
const codeMcpNames = Object.keys(mcp.mcpServers)
|
|
23
|
-
.filter((name) => name === "lsp" || name === "git_bash"
|
|
22
|
+
.filter((name) => name === "lsp" || name === "git_bash")
|
|
24
23
|
.sort();
|
|
25
24
|
const componentLocalMcpSources = lspSources.filter((name) => name.startsWith("lazy-mcp") || name === "lazy-lsp-mcp.ts");
|
|
26
25
|
|
|
27
26
|
// then
|
|
28
|
-
assert.deepEqual(codeMcpNames, ["
|
|
27
|
+
assert.deepEqual(codeMcpNames, ["git_bash", "lsp"]);
|
|
29
28
|
assert.equal(packageJson.workspaces.includes("components/lsp/packages/lsp-tools-mcp"), false);
|
|
30
29
|
assert.deepEqual(packageJson.dependencies, { "@oh-my-opencode/shared-skills": "file:../../shared-skills" });
|
|
31
30
|
assert.doesNotMatch(bundledMcpBuildScript, new RegExp(["ast", "grep", "mcp"].join("-")));
|
|
@@ -38,10 +37,6 @@ test("#given aggregate MCP config #when inspected #then code MCPs reference pack
|
|
|
38
37
|
assert.equal(gitBashServer.command, "node");
|
|
39
38
|
assert.deepEqual(gitBashServer.args, ["../../git-bash-mcp/dist/cli.js", "mcp"]);
|
|
40
39
|
assert.equal(gitBashServer.cwd, ".");
|
|
41
|
-
assert.equal(codegraphServer.command, "node");
|
|
42
|
-
assert.deepEqual(codegraphServer.args, ["components/codegraph/dist/serve.js"]);
|
|
43
|
-
assert.equal(codegraphServer.cwd, ".");
|
|
44
|
-
assert.equal(codegraphServer.required, false);
|
|
45
40
|
assert.deepEqual(componentLocalMcpSources, []);
|
|
46
41
|
});
|
|
47
42
|
|