oh-my-opencode 4.11.0 → 4.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/codex-qa/scripts/lib/app-server-client.mjs +132 -82
- package/.agents/skills/codex-qa/scripts/lib/app-server-client.test.js +48 -0
- package/.agents/skills/opencode-qa/scripts/serve-wake-split-probe.sh +361 -84
- package/.agents/skills/work-with-pr/SKILL.md +19 -5
- package/.opencode/skills/work-with-pr/SKILL.md +19 -5
- package/dist/agents/atlas/agent.d.ts +3 -2
- package/dist/agents/sisyphus/glm-5-2.d.ts +4 -0
- package/dist/agents/sisyphus/index.d.ts +1 -0
- package/dist/agents/sisyphus-agent-config.d.ts +1 -0
- package/dist/agents/sisyphus-junior/agent.d.ts +1 -1
- package/dist/agents/sisyphus-junior/glm-5-2.d.ts +1 -0
- package/dist/agents/sisyphus-junior/index.d.ts +1 -0
- package/dist/agents/types.d.ts +7 -6
- package/dist/cli/index.js +449 -318
- package/dist/cli-node/index.js +449 -318
- package/dist/features/background-agent/parent-wake-flush-runner.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-history-state.d.ts +1 -0
- package/dist/features/background-agent/parent-wake-session-history.d.ts +1 -47
- package/dist/features/background-agent/parent-wake-session-message.d.ts +47 -0
- package/dist/hooks/keyword-detector/ultrawork/glm.d.ts +2 -0
- package/dist/hooks/keyword-detector/ultrawork/index.d.ts +4 -2
- package/dist/hooks/keyword-detector/ultrawork/source-detector.d.ts +5 -4
- package/dist/index.js +1185 -87
- package/dist/plugin/tool-execute-before.d.ts +2 -0
- package/dist/plugin-handlers/plugin-components-loader.d.ts +1 -0
- package/dist/skills/init-deep/SKILL.md +21 -26
- package/dist/skills/programming/SKILL.md +25 -121
- package/dist/skills/programming/references/code-smells.md +390 -0
- package/dist/skills/ulw-plan/SKILL.md +2 -1
- package/dist/skills/ulw-plan/references/full-workflow.md +1 -1
- package/dist/skills/ulw-plan/references/intent-clear.md +2 -2
- package/dist/tools/delegate-task/sync-session-poller.d.ts +1 -2
- package/dist/tools/delegate-task/sync-session-turns.d.ts +3 -0
- package/dist/tui.js +16 -7
- package/package.json +13 -13
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +22 -2
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +51 -21
- 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/codegraph/dist/cli.js +18 -7
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +9 -2
- package/packages/omo-codex/plugin/components/codegraph/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +8 -7
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +7 -2
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +2 -1
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +20 -19
- package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +94 -0
- package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +33 -0
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/test/package-smoke.test.ts +2 -71
- 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/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/test/package-smoke.test.ts +26 -104
- package/packages/omo-codex/plugin/components/rules/dist/cli.js +2 -2
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/src/sparkshell-awareness.ts +2 -2
- package/packages/omo-codex/plugin/components/rules/test/package-smoke.test.ts +12 -92
- package/packages/omo-codex/plugin/components/rules/test/sparkshell-awareness.test.ts +3 -0
- package/packages/omo-codex/plugin/components/start-work-continuation/dist/cli.js +157 -234
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/src/boulder-reader.ts +227 -15
- package/packages/omo-codex/plugin/components/start-work-continuation/test/boulder-reader.test.ts +62 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/test/cli.test.ts +34 -3
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/SKILL.md +139 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-guide.mjs +111 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team-state.mjs +250 -0
- package/packages/omo-codex/plugin/components/teammode/skills/teammode/scripts/team.mjs +220 -0
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/test-support/package-smoke-fixture.ts +158 -0
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +2 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/test/package-smoke.test.ts +76 -49
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/test/package-smoke.test.ts +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +17 -0
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +17 -0
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +17 -0
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +17 -0
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +16 -0
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +16 -0
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +16 -0
- package/packages/omo-codex/plugin/hooks/stop-checking-start-work-continuation.json +16 -0
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-start-work-continuation.json +16 -0
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +17 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +16 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +16 -0
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +16 -0
- package/packages/omo-codex/plugin/package-lock.json +12 -22
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +1 -1
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +14 -11
- package/packages/omo-codex/plugin/scripts/sync-hook-status-messages.mjs +15 -4
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +37 -0
- package/packages/omo-codex/plugin/skills/ast-grep/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/comment-checker/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/debugging/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/frontend/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/git-master/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +21 -26
- package/packages/omo-codex/plugin/skills/init-deep/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/lcx-contribute-bug-fix/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-doctor/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lcx-report-bug/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/lsp/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/lsp-setup/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/programming/SKILL.md +25 -121
- package/packages/omo-codex/plugin/skills/programming/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/programming/references/code-smells.md +390 -0
- package/packages/omo-codex/plugin/skills/refactor/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/remove-ai-slops/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/review-work/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/rules/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/start-work/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/teammode/SKILL.md +139 -0
- package/packages/omo-codex/plugin/skills/teammode/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-guide.mjs +111 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team-state.mjs +250 -0
- package/packages/omo-codex/plugin/skills/teammode/scripts/team.mjs +220 -0
- package/packages/omo-codex/plugin/skills/ultraresearch/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/skills/ulw-loop/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +2 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/agents/openai.yaml +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/skills/visual-qa/agents/openai.yaml +2 -0
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +34 -33
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +5 -2
- package/packages/omo-codex/plugin/test/aggregate-plugin-fixture.mjs +13 -0
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/bootstrap-binlinks.test.mjs +1 -1
- package/packages/omo-codex/plugin/test/bootstrap-hooks.test.mjs +14 -6
- package/packages/omo-codex/plugin/test/bootstrap-ps-guard.test.mjs +7 -3
- package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +31 -0
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +3 -3
- package/packages/omo-codex/plugin/test/display-metadata.test.mjs +83 -0
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +30 -19
- package/packages/omo-codex/plugin/test/lcx-bug-skills.test.mjs +3 -3
- package/packages/omo-codex/plugin/test/sync-hook-status-messages.test.mjs +6 -6
- package/packages/omo-codex/plugin/test/sync-skills-test-support.mjs +2 -0
- package/packages/omo-codex/plugin/test/sync-skills.test.mjs +9 -4
- package/packages/omo-codex/plugin/test/teammode-safety-fixture.mjs +88 -0
- package/packages/omo-codex/plugin/test/teammode-safety.test.mjs +240 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +412 -216
- package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +24 -0
- package/packages/omo-codex/scripts/install-hook-targets.test.mjs +93 -0
- package/packages/omo-codex/scripts/install-lazycodex-version-stamp.test.mjs +2 -2
- package/packages/omo-codex/scripts/install-local-bun-global-update.test.mjs +63 -0
- package/packages/omo-codex/scripts/install-local-entrypoint.test.mjs +109 -1
- package/packages/omo-codex/scripts/install-local.mjs +1 -0
- package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +36 -0
- package/packages/shared-skills/skills/init-deep/SKILL.md +21 -26
- package/packages/shared-skills/skills/programming/SKILL.md +25 -121
- package/packages/shared-skills/skills/programming/references/code-smells.md +390 -0
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +2 -1
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +1 -1
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +2 -2
- package/packages/omo-codex/plugin/hooks/hooks.json +0 -214
|
@@ -62,6 +62,30 @@ test("#given a non-Windows install #when stamping #then the manifest stays byte-
|
|
|
62
62
|
assert.equal(await readFile(join(pluginRoot, ".mcp.json"), "utf8"), MANIFEST);
|
|
63
63
|
});
|
|
64
64
|
|
|
65
|
+
test("#given a package-relative CodeGraph MCP path #when stamping on non-Windows #then codegraph server arg becomes absolute", async (t) => {
|
|
66
|
+
const pluginRoot = await mkdtemp(join(tmpdir(), "git-bash-mcp-env-"));
|
|
67
|
+
t.after(() => rm(pluginRoot, { recursive: true, force: true }));
|
|
68
|
+
await writeFile(
|
|
69
|
+
join(pluginRoot, ".mcp.json"),
|
|
70
|
+
`${JSON.stringify(
|
|
71
|
+
{
|
|
72
|
+
mcpServers: {
|
|
73
|
+
codegraph: { args: ["components/codegraph/dist/serve.js"], command: "node" },
|
|
74
|
+
git_bash: { command: "node", args: ["../../git-bash-mcp/dist/cli.js", "mcp"] },
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
null,
|
|
78
|
+
"\t",
|
|
79
|
+
)}\n`,
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const changed = await stampGitBashMcpEnv({ pluginRoot, env: {}, platform: "darwin" });
|
|
83
|
+
|
|
84
|
+
assert.equal(changed, true);
|
|
85
|
+
const parsed = JSON.parse(await readFile(join(pluginRoot, ".mcp.json"), "utf8"));
|
|
86
|
+
assert.deepEqual(parsed.mcpServers.codegraph.args, [join(pluginRoot, "components", "codegraph", "dist", "serve.js")]);
|
|
87
|
+
});
|
|
88
|
+
|
|
65
89
|
test("#given the override already stamped #when stamping again #then nothing changes", async (t) => {
|
|
66
90
|
const pluginRoot = await createPluginRoot();
|
|
67
91
|
t.after(() => rm(pluginRoot, { recursive: true, force: true }));
|
|
@@ -56,6 +56,67 @@ async function createPluginRoot({ withGitBashDist }) {
|
|
|
56
56
|
return pluginRoot;
|
|
57
57
|
}
|
|
58
58
|
|
|
59
|
+
async function createPluginRootWithHookArray({ withGitBashDist }) {
|
|
60
|
+
const pluginRoot = await mkdtemp(join(tmpdir(), "hook-targets-array-"));
|
|
61
|
+
await mkdir(join(pluginRoot, ".codex-plugin"), { recursive: true });
|
|
62
|
+
await mkdir(join(pluginRoot, "hooks"), { recursive: true });
|
|
63
|
+
await writeFile(
|
|
64
|
+
join(pluginRoot, ".codex-plugin", "plugin.json"),
|
|
65
|
+
JSON.stringify({ name: "omo", hooks: ["./hooks/session-start.json", "./hooks/stop.json"] }, null, "\t"),
|
|
66
|
+
);
|
|
67
|
+
await writeFile(
|
|
68
|
+
join(pluginRoot, "hooks", "session-start.json"),
|
|
69
|
+
JSON.stringify({ hooks: { SessionStart: HOOKS_MANIFEST.hooks.SessionStart } }, null, "\t"),
|
|
70
|
+
);
|
|
71
|
+
await writeFile(
|
|
72
|
+
join(pluginRoot, "hooks", "stop.json"),
|
|
73
|
+
JSON.stringify({ hooks: { Stop: HOOKS_MANIFEST.hooks.Stop } }, null, "\t"),
|
|
74
|
+
);
|
|
75
|
+
const targets = [
|
|
76
|
+
"scripts/auto-update.mjs",
|
|
77
|
+
"components/ulw-loop/dist/cli.js",
|
|
78
|
+
...(withGitBashDist ? ["components/git-bash/dist/cli.js"] : []),
|
|
79
|
+
];
|
|
80
|
+
for (const target of targets) {
|
|
81
|
+
await mkdir(dirname(join(pluginRoot, target)), { recursive: true });
|
|
82
|
+
await writeFile(join(pluginRoot, target), "");
|
|
83
|
+
}
|
|
84
|
+
return pluginRoot;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function createPluginRootWithWindowsHook({ withBootstrapScript }) {
|
|
88
|
+
const pluginRoot = await mkdtemp(join(tmpdir(), "hook-targets-windows-"));
|
|
89
|
+
await mkdir(join(pluginRoot, "hooks"), { recursive: true });
|
|
90
|
+
await writeFile(
|
|
91
|
+
join(pluginRoot, "hooks", "hooks.json"),
|
|
92
|
+
JSON.stringify(
|
|
93
|
+
{
|
|
94
|
+
hooks: {
|
|
95
|
+
SessionStart: [
|
|
96
|
+
{
|
|
97
|
+
hooks: [
|
|
98
|
+
{
|
|
99
|
+
type: "command",
|
|
100
|
+
commandWindows:
|
|
101
|
+
'powershell -NoProfile -ExecutionPolicy Bypass -File "${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\bootstrap.ps1"',
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
},
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
null,
|
|
109
|
+
"\t",
|
|
110
|
+
),
|
|
111
|
+
);
|
|
112
|
+
if (withBootstrapScript) {
|
|
113
|
+
const target = join(pluginRoot, "components", "bootstrap", "scripts", "bootstrap.ps1");
|
|
114
|
+
await mkdir(dirname(target), { recursive: true });
|
|
115
|
+
await writeFile(target, "");
|
|
116
|
+
}
|
|
117
|
+
return pluginRoot;
|
|
118
|
+
}
|
|
119
|
+
|
|
59
120
|
test("#given a hook command target missing from the payload #when scanning #then exactly that path is reported", async (t) => {
|
|
60
121
|
const pluginRoot = await createPluginRoot({ withGitBashDist: false });
|
|
61
122
|
t.after(() => rm(pluginRoot, { recursive: true, force: true }));
|
|
@@ -65,6 +126,22 @@ test("#given a hook command target missing from the payload #when scanning #then
|
|
|
65
126
|
assert.deepEqual(missing, [join(pluginRoot, "components/git-bash/dist/cli.js")]);
|
|
66
127
|
});
|
|
67
128
|
|
|
129
|
+
test("#given a Windows hook command target missing from the payload #when scanning #then the backslash path is reported", async (t) => {
|
|
130
|
+
const pluginRoot = await createPluginRootWithWindowsHook({ withBootstrapScript: false });
|
|
131
|
+
t.after(() => rm(pluginRoot, { recursive: true, force: true }));
|
|
132
|
+
|
|
133
|
+
const missing = await findMissingHookCommandTargets(pluginRoot);
|
|
134
|
+
|
|
135
|
+
assert.deepEqual(missing, [join(pluginRoot, "components", "bootstrap", "scripts", "bootstrap.ps1")]);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
test("#given a Windows hook command target exists in the payload #when scanning #then nothing is missing", async (t) => {
|
|
139
|
+
const pluginRoot = await createPluginRootWithWindowsHook({ withBootstrapScript: true });
|
|
140
|
+
t.after(() => rm(pluginRoot, { recursive: true, force: true }));
|
|
141
|
+
|
|
142
|
+
assert.deepEqual(await findMissingHookCommandTargets(pluginRoot), []);
|
|
143
|
+
});
|
|
144
|
+
|
|
68
145
|
test("#given a complete payload #when scanning #then nothing is missing", async (t) => {
|
|
69
146
|
const pluginRoot = await createPluginRoot({ withGitBashDist: true });
|
|
70
147
|
t.after(() => rm(pluginRoot, { recursive: true, force: true }));
|
|
@@ -72,6 +149,22 @@ test("#given a complete payload #when scanning #then nothing is missing", async
|
|
|
72
149
|
assert.deepEqual(await findMissingHookCommandTargets(pluginRoot), []);
|
|
73
150
|
});
|
|
74
151
|
|
|
152
|
+
test("#given hook manifests declared as an array #when scanning #then missing targets are reported", async (t) => {
|
|
153
|
+
const pluginRoot = await createPluginRootWithHookArray({ withGitBashDist: false });
|
|
154
|
+
t.after(() => rm(pluginRoot, { recursive: true, force: true }));
|
|
155
|
+
|
|
156
|
+
const missing = await findMissingHookCommandTargets(pluginRoot);
|
|
157
|
+
|
|
158
|
+
assert.deepEqual(missing, [join(pluginRoot, "components/git-bash/dist/cli.js")]);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test("#given hook manifests declared as an array and complete payload #when scanning #then nothing is missing", async (t) => {
|
|
162
|
+
const pluginRoot = await createPluginRootWithHookArray({ withGitBashDist: true });
|
|
163
|
+
t.after(() => rm(pluginRoot, { recursive: true, force: true }));
|
|
164
|
+
|
|
165
|
+
assert.deepEqual(await findMissingHookCommandTargets(pluginRoot), []);
|
|
166
|
+
});
|
|
167
|
+
|
|
75
168
|
test("#given no hooks manifest #when scanning #then nothing is missing", async (t) => {
|
|
76
169
|
const pluginRoot = await mkdtemp(join(tmpdir(), "hook-targets-"));
|
|
77
170
|
t.after(() => rm(pluginRoot, { recursive: true, force: true }));
|
|
@@ -77,8 +77,8 @@ test("#given sisyphuslabs lazycodex install #when installing locally #then stamp
|
|
|
77
77
|
assert.equal(manifest.version, "4.7.6");
|
|
78
78
|
assert.equal(packageJson.version, "4.7.6");
|
|
79
79
|
assert.equal(componentPackageJson.version, "4.7.6");
|
|
80
|
-
assert.equal(hooks.hooks.PostToolUse[0].hooks[0].statusMessage, "
|
|
81
|
-
assert.equal(componentHooks.hooks.UserPromptSubmit[0].hooks[0].statusMessage, "
|
|
80
|
+
assert.equal(hooks.hooks.PostToolUse[0].hooks[0].statusMessage, "(OmO) Checking Comments");
|
|
81
|
+
assert.equal(componentHooks.hooks.UserPromptSubmit[0].hooks[0].statusMessage, "(OmO) Checking Ulw-Loop Steering");
|
|
82
82
|
assert.deepEqual(snapshot, {
|
|
83
83
|
packageName: "lazycodex-ai",
|
|
84
84
|
version: "4.7.6",
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import { execFileSync } from "node:child_process";
|
|
3
|
+
import { chmodSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { dirname, join } from "node:path";
|
|
6
|
+
import test from "node:test";
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
|
+
|
|
9
|
+
test("#given direct bun global lazycodex bin #when running update dry-run #then prints bun global update command", { skip: process.platform === "win32" }, () => {
|
|
10
|
+
// given
|
|
11
|
+
const scriptPath = fileURLToPath(new URL("./install-local.mjs", import.meta.url));
|
|
12
|
+
const tempHome = mkdtempSync(join(tmpdir(), "lazycodex-bun-global-bin-"));
|
|
13
|
+
const binDir = join(tempHome, ".bun", "bin");
|
|
14
|
+
const binPath = join(binDir, "lazycodex-ai");
|
|
15
|
+
mkdirSync(binDir, { recursive: true });
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
writeDirectBunGlobalLazyCodexBin(binPath, scriptPath);
|
|
19
|
+
|
|
20
|
+
// when
|
|
21
|
+
const output = execFileSync(process.execPath, [binPath, "--dry-run", "update"], {
|
|
22
|
+
encoding: "utf8",
|
|
23
|
+
env: {
|
|
24
|
+
...process.env,
|
|
25
|
+
HOME: tempHome,
|
|
26
|
+
LAZYCODEX_CURRENT_VERSION: "1.0.0",
|
|
27
|
+
LAZYCODEX_LATEST_VERSION: "1.0.1",
|
|
28
|
+
},
|
|
29
|
+
}).trim();
|
|
30
|
+
|
|
31
|
+
// then
|
|
32
|
+
assert.equal(output, "bun update -g lazycodex-ai@latest\nnpx --yes lazycodex-ai@latest install --no-tui --codex-autonomous");
|
|
33
|
+
} finally {
|
|
34
|
+
rmSync(tempHome, { recursive: true, force: true });
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
function writeDirectBunGlobalLazyCodexBin(binPath, scriptPath) {
|
|
39
|
+
const generatedInstallerUrl = pathToFileURL(fileURLToPath(new URL("./install-dist/install-local.mjs", import.meta.url))).href;
|
|
40
|
+
const repoRoot = join(dirname(scriptPath), "..", "..", "..");
|
|
41
|
+
writeFileSync(
|
|
42
|
+
binPath,
|
|
43
|
+
`#!/usr/bin/env node
|
|
44
|
+
import { runLazyCodexInstallLocalCli } from ${JSON.stringify(generatedInstallerUrl)};
|
|
45
|
+
|
|
46
|
+
runLazyCodexInstallLocalCli({
|
|
47
|
+
argv: process.argv.slice(2),
|
|
48
|
+
defaultRepoRoot: ${JSON.stringify(repoRoot)},
|
|
49
|
+
entrypointPath: ${JSON.stringify(scriptPath)},
|
|
50
|
+
invokedPath: process.argv[1] ?? "",
|
|
51
|
+
cwd: process.cwd(),
|
|
52
|
+
env: process.env,
|
|
53
|
+
log: console.log,
|
|
54
|
+
}).then((exitCode) => {
|
|
55
|
+
process.exitCode = exitCode;
|
|
56
|
+
}).catch((error) => {
|
|
57
|
+
console.error(error instanceof Error ? error.message : error);
|
|
58
|
+
process.exitCode = 1;
|
|
59
|
+
});
|
|
60
|
+
`,
|
|
61
|
+
);
|
|
62
|
+
chmodSync(binPath, 0o755);
|
|
63
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import assert from "node:assert/strict";
|
|
2
2
|
import { execFileSync } from "node:child_process";
|
|
3
|
-
import { mkdtempSync, readFileSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { chmodSync, mkdirSync, mkdtempSync, readFileSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { tmpdir } from "node:os";
|
|
5
5
|
import { dirname, join } from "node:path";
|
|
6
6
|
import test from "node:test";
|
|
@@ -148,6 +148,69 @@ test("#given stale lazycodex version #when running update dry-run #then prints t
|
|
|
148
148
|
assert.equal(output, "npx --yes lazycodex-ai@latest install --no-tui --codex-autonomous");
|
|
149
149
|
});
|
|
150
150
|
|
|
151
|
+
test("#given bun global lazycodex wrapper #when running update dry-run #then prints bun global update command", { skip: process.platform === "win32" }, () => {
|
|
152
|
+
// given
|
|
153
|
+
const scriptPath = fileURLToPath(new URL("./install-local.mjs", import.meta.url));
|
|
154
|
+
const tempHome = mkdtempSync(join(tmpdir(), "lazycodex-bun-global-dry-run-"));
|
|
155
|
+
const binPath = createBunGlobalLazyCodexSymlink(tempHome, scriptPath);
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
// when
|
|
159
|
+
const output = execFileSync(process.execPath, [binPath, "--dry-run", "update"], {
|
|
160
|
+
encoding: "utf8",
|
|
161
|
+
env: {
|
|
162
|
+
...process.env,
|
|
163
|
+
HOME: tempHome,
|
|
164
|
+
LAZYCODEX_CURRENT_VERSION: "1.0.0",
|
|
165
|
+
LAZYCODEX_LATEST_VERSION: "1.0.1",
|
|
166
|
+
},
|
|
167
|
+
}).trim();
|
|
168
|
+
|
|
169
|
+
// then
|
|
170
|
+
assert.equal(output, "bun update -g lazycodex-ai@latest\nnpx --yes lazycodex-ai@latest install --no-tui --codex-autonomous");
|
|
171
|
+
} finally {
|
|
172
|
+
rmSync(tempHome, { recursive: true, force: true });
|
|
173
|
+
}
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
test("#given bun global lazycodex wrapper and untrusted known scripts #when update runs noninteractively #then prints manual scoped trust command", { skip: process.platform === "win32" }, () => {
|
|
177
|
+
// given
|
|
178
|
+
const scriptPath = fileURLToPath(new URL("./install-local.mjs", import.meta.url));
|
|
179
|
+
const tempHome = mkdtempSync(join(tmpdir(), "lazycodex-bun-global-trust-"));
|
|
180
|
+
const tempBin = mkdtempSync(join(tmpdir(), "lazycodex-bun-bin-"));
|
|
181
|
+
const commandLogPath = join(tempHome, "commands.log");
|
|
182
|
+
const binPath = createBunGlobalLazyCodexSymlink(tempHome, scriptPath);
|
|
183
|
+
writeFakeBunCommand(tempBin);
|
|
184
|
+
writeFakeNpxCommand(tempBin);
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
// when
|
|
188
|
+
const output = execFileSync(process.execPath, [binPath, "update"], {
|
|
189
|
+
encoding: "utf8",
|
|
190
|
+
env: {
|
|
191
|
+
...process.env,
|
|
192
|
+
HOME: tempHome,
|
|
193
|
+
LAZYCODEX_CURRENT_VERSION: "1.0.0",
|
|
194
|
+
LAZYCODEX_LATEST_VERSION: "1.0.1",
|
|
195
|
+
LAZYCODEX_TEST_COMMAND_LOG: commandLogPath,
|
|
196
|
+
PATH: `${tempBin}:${process.env.PATH ?? ""}`,
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
const commandLog = readFileSync(commandLogPath, "utf8");
|
|
200
|
+
|
|
201
|
+
// then
|
|
202
|
+
assert.match(commandLog, /^bun update -g lazycodex-ai@latest$/m);
|
|
203
|
+
assert.match(commandLog, /^bun pm -g untrusted$/m);
|
|
204
|
+
assert.match(commandLog, /^npx --yes lazycodex-ai@latest install --no-tui --codex-autonomous$/m);
|
|
205
|
+
assert.doesNotMatch(commandLog, /^bun pm -g trust/m);
|
|
206
|
+
assert.match(output, /bun pm -g trust oh-my-openagent @code-yeongyu\/comment-checker/);
|
|
207
|
+
assert.doesNotMatch(output, /left-pad/);
|
|
208
|
+
} finally {
|
|
209
|
+
rmSync(tempHome, { recursive: true, force: true });
|
|
210
|
+
rmSync(tempBin, { recursive: true, force: true });
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
|
|
151
214
|
test("#given current lazycodex version #when running update dry-run #then reports already current", () => {
|
|
152
215
|
// given
|
|
153
216
|
const scriptPath = fileURLToPath(new URL("./install-local.mjs", import.meta.url));
|
|
@@ -166,6 +229,51 @@ test("#given current lazycodex version #when running update dry-run #then report
|
|
|
166
229
|
assert.equal(output, "lazycodex-ai 1.0.1 is already up to date.");
|
|
167
230
|
});
|
|
168
231
|
|
|
232
|
+
function createBunGlobalLazyCodexSymlink(homeDir, scriptPath) {
|
|
233
|
+
const packageBinDir = join(homeDir, ".bun", "install", "global", "node_modules", "lazycodex-ai", "bin");
|
|
234
|
+
mkdirSync(packageBinDir, { recursive: true });
|
|
235
|
+
const binPath = join(packageBinDir, "lazycodex-ai");
|
|
236
|
+
symlinkSync(scriptPath, binPath);
|
|
237
|
+
return binPath;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
function writeExecutable(path, source) {
|
|
241
|
+
writeFileSync(path, source);
|
|
242
|
+
chmodSync(path, 0o755);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function writeFakeBunCommand(binDir) {
|
|
246
|
+
writeExecutable(
|
|
247
|
+
join(binDir, "bun"),
|
|
248
|
+
`#!/bin/sh
|
|
249
|
+
printf '%s\\n' "bun $*" >> "$LAZYCODEX_TEST_COMMAND_LOG"
|
|
250
|
+
if [ "$1" = "pm" ] && [ "$2" = "-g" ] && [ "$3" = "untrusted" ]; then
|
|
251
|
+
cat <<'EOF'
|
|
252
|
+
./node_modules/oh-my-openagent @4.9.2
|
|
253
|
+
» [postinstall]: node postinstall.mjs
|
|
254
|
+
|
|
255
|
+
./node_modules/left-pad @1.0.0
|
|
256
|
+
» [postinstall]: node postinstall.js
|
|
257
|
+
|
|
258
|
+
./node_modules/@code-yeongyu/comment-checker @0.8.0
|
|
259
|
+
» [postinstall]: node postinstall.js
|
|
260
|
+
EOF
|
|
261
|
+
fi
|
|
262
|
+
exit 0
|
|
263
|
+
`,
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
function writeFakeNpxCommand(binDir) {
|
|
268
|
+
writeExecutable(
|
|
269
|
+
join(binDir, "npx"),
|
|
270
|
+
`#!/bin/sh
|
|
271
|
+
printf '%s\\n' "npx $*" >> "$LAZYCODEX_TEST_COMMAND_LOG"
|
|
272
|
+
exit 0
|
|
273
|
+
`,
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
|
|
169
277
|
test("#given dry-run ulw-loop #when running the Node installer entrypoint #then prints delegated ulw-loop command", () => {
|
|
170
278
|
// given
|
|
171
279
|
const scriptPath = fileURLToPath(new URL("./install-local.mjs", import.meta.url));
|
|
@@ -104,6 +104,42 @@ test("#given plugin-local MCP runtime #when installing cached plugin #then manif
|
|
|
104
104
|
assert.deepEqual(cachedMcp.mcpServers.omo.args, [join(result.path, "dist", "cli.js")]);
|
|
105
105
|
});
|
|
106
106
|
|
|
107
|
+
test("#given CodeGraph MCP runtime in plugin cache #when installing cached plugin #then manifest points at cached plugin before bootstrap", async () => {
|
|
108
|
+
const repoRoot = await makeTempDir();
|
|
109
|
+
const codexHome = await makeTempDir();
|
|
110
|
+
const sourceRoot = join(repoRoot, "packages", "omo-codex", "plugin");
|
|
111
|
+
|
|
112
|
+
await writeJson(join(sourceRoot, "package.json"), {
|
|
113
|
+
name: "@example/omo",
|
|
114
|
+
version: "0.1.0",
|
|
115
|
+
});
|
|
116
|
+
await writeJson(join(sourceRoot, ".mcp.json"), {
|
|
117
|
+
mcpServers: {
|
|
118
|
+
codegraph: {
|
|
119
|
+
command: "node",
|
|
120
|
+
args: ["components/codegraph/dist/serve.js"],
|
|
121
|
+
cwd: ".",
|
|
122
|
+
required: false,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
await writeJson(join(sourceRoot, "components", "codegraph", "dist", "serve.js"), { executable: true });
|
|
127
|
+
|
|
128
|
+
const result = await installCachedPlugin({
|
|
129
|
+
codexHome,
|
|
130
|
+
marketplaceName: "sisyphuslabs",
|
|
131
|
+
name: "omo",
|
|
132
|
+
runCommand: async () => {},
|
|
133
|
+
sourcePath: sourceRoot,
|
|
134
|
+
version: "0.1.0",
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const cachedMcp = JSON.parse(await readFile(join(result.path, ".mcp.json"), "utf8"));
|
|
138
|
+
|
|
139
|
+
assert.deepEqual(cachedMcp.mcpServers.codegraph.args, [join(result.path, "components", "codegraph", "dist", "serve.js")]);
|
|
140
|
+
assert.equal(Object.hasOwn(cachedMcp.mcpServers.codegraph, "cwd"), false);
|
|
141
|
+
});
|
|
142
|
+
|
|
107
143
|
test("#given external MCP package not in the generated bundled runtime set #when installing cached plugin #then manifest args point at source", async () => {
|
|
108
144
|
const repoRoot = await makeTempDir();
|
|
109
145
|
const codexHome = await makeTempDir();
|
|
@@ -20,7 +20,7 @@ Generate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.
|
|
|
20
20
|
|
|
21
21
|
1. **Discovery + Analysis** (concurrent)
|
|
22
22
|
- Fire background explore agents immediately
|
|
23
|
-
- Main session: bash structure + LSP
|
|
23
|
+
- Main session: bash structure + LSP/codegraph code map + read existing AGENTS.md
|
|
24
24
|
2. **Score & Decide** - Determine AGENTS.md locations from merged findings
|
|
25
25
|
3. **Generate** - Root first, then subdirs in parallel
|
|
26
26
|
4. **Review** - Deduplicate, trim, validate
|
|
@@ -29,7 +29,7 @@ Generate hierarchical AGENTS.md files. Root + complexity-scored subdirectories.
|
|
|
29
29
|
**TodoWrite ALL phases. Mark in_progress → completed in real-time.**
|
|
30
30
|
```
|
|
31
31
|
TodoWrite([
|
|
32
|
-
{ id: "discovery", content: "Fire explore agents + LSP
|
|
32
|
+
{ id: "discovery", content: "Fire explore agents + LSP/codegraph map + read existing", status: "pending", priority: "high" },
|
|
33
33
|
{ id: "scoring", content: "Score directories, determine locations", status: "pending", priority: "high" },
|
|
34
34
|
{ id: "generate", content: "Generate AGENTS.md files (root + subdirs)", status: "pending", priority: "high" },
|
|
35
35
|
{ id: "review", content: "Deduplicate, validate, trim", status: "pending", priority: "medium" }
|
|
@@ -45,16 +45,16 @@ TodoWrite([
|
|
|
45
45
|
|
|
46
46
|
### Fire Background Explore Agents IMMEDIATELY
|
|
47
47
|
|
|
48
|
-
Don't wait-these run async while main session works.
|
|
48
|
+
Don't wait-these run async while main session works. **Equip every agent with the code graph**: any task touching structure, entry points, dependencies, or hotspots MUST query `codegraph_*` (explore/search/callers/callees/impact) and `lsp_symbols` when present, and ground its claims in that data instead of guessing from conventions. Richer real-graph context per agent = a more accurate project map.
|
|
49
49
|
|
|
50
50
|
```
|
|
51
51
|
// Fire all at once, collect results later
|
|
52
|
-
task(subagent_type="explore", load_skills=[], description="Explore project structure", run_in_background=true, prompt="Project structure:
|
|
53
|
-
task(subagent_type="explore", load_skills=[], description="Find entry points", run_in_background=true, prompt="Entry points: FIND main files → REPORT non-standard organization")
|
|
52
|
+
task(subagent_type="explore", load_skills=[], description="Explore project structure", run_in_background=true, prompt="Project structure: map real layout via codegraph_explore/codegraph_files → REPORT deviations from standard patterns")
|
|
53
|
+
task(subagent_type="explore", load_skills=[], description="Find entry points", run_in_background=true, prompt="Entry points: FIND main files, trace reach via codegraph_callees + lsp_symbols → REPORT non-standard organization")
|
|
54
54
|
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")
|
|
55
55
|
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")
|
|
56
56
|
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")
|
|
57
|
-
task(subagent_type="explore", load_skills=[], description="Find test patterns", run_in_background=true, prompt="Test patterns: FIND test configs
|
|
57
|
+
task(subagent_type="explore", load_skills=[], description="Find test patterns", run_in_background=true, prompt="Test patterns: FIND test configs/structure; codegraph_callers on core modules to see what is covered → REPORT unique conventions")
|
|
58
58
|
```
|
|
59
59
|
|
|
60
60
|
<dynamic-agents>
|
|
@@ -116,24 +116,19 @@ For each existing file found:
|
|
|
116
116
|
|
|
117
117
|
If `--create-new`: Read all existing first (preserve context) → then delete all → regenerate.
|
|
118
118
|
|
|
119
|
-
#### 3. LSP
|
|
120
|
-
```
|
|
121
|
-
LspServers() # Check availability
|
|
119
|
+
#### 3. Code Map - drive LSP AND codegraph (do NOT skip)
|
|
122
120
|
|
|
123
|
-
|
|
124
|
-
LspDocumentSymbols(filePath="src/index.ts")
|
|
125
|
-
LspDocumentSymbols(filePath="main.py")
|
|
121
|
+
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.
|
|
126
122
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
123
|
+
**LSP** - check `lsp_status`; model-facing names are `lsp_status`/`lsp_symbols`/`lsp_find_references`/`lsp_goto_definition` (some harnesses drop the `lsp_` prefix):
|
|
124
|
+
- `lsp_symbols` scope="document" on each entry point -> file outline.
|
|
125
|
+
- `lsp_symbols` scope="workspace", query by kind (class/interface/function) -> symbol inventory.
|
|
126
|
+
- `lsp_find_references` on top exports (line/character from the symbols result) -> reference centrality.
|
|
131
127
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
```
|
|
128
|
+
**codegraph** - when `codegraph_*` tools exist (check `codegraph_status`); a first-class peer to LSP, NOT a last resort:
|
|
129
|
+
- `codegraph_explore` -> overview; `codegraph_callers`/`codegraph_callees`/`codegraph_impact` -> centrality + blast radius for the scoring matrix; `codegraph_search`/`codegraph_files` -> symbol/file inventory.
|
|
135
130
|
|
|
136
|
-
|
|
131
|
+
Only if NEITHER exists: explore agents + the ast-grep skill (`sg`), and mark centrality unmeasured in the CODE MAP.
|
|
137
132
|
|
|
138
133
|
### Collect Background Results
|
|
139
134
|
|
|
@@ -142,7 +137,7 @@ LspFindReferences(filePath="...", line=X, character=Y)
|
|
|
142
137
|
for each background task ID (`bg_...`): background_output(task_id="bg_...")
|
|
143
138
|
```
|
|
144
139
|
|
|
145
|
-
**Merge: bash + LSP + existing + explore findings. Mark "discovery" as completed.**
|
|
140
|
+
**Merge: bash + LSP/codegraph + existing + explore findings. Mark "discovery" as completed.**
|
|
146
141
|
|
|
147
142
|
---
|
|
148
143
|
|
|
@@ -159,9 +154,9 @@ for each background task ID (`bg_...`): background_output(task_id="bg_...")
|
|
|
159
154
|
| Code ratio | 2x | >70% | bash |
|
|
160
155
|
| Unique patterns | 1x | Has own config | explore |
|
|
161
156
|
| Module boundary | 2x | Has index.ts/__init__.py | bash |
|
|
162
|
-
| Symbol density | 2x | >30 symbols | LSP |
|
|
163
|
-
| Export count | 2x | >10 exports | LSP |
|
|
164
|
-
| Reference centrality | 3x | >20 refs | LSP |
|
|
157
|
+
| Symbol density | 2x | >30 symbols | LSP/cg |
|
|
158
|
+
| Export count | 2x | >10 exports | LSP/cg |
|
|
159
|
+
| Reference centrality | 3x | >20 refs | LSP/cg |
|
|
165
160
|
|
|
166
161
|
### Decision Rules
|
|
167
162
|
|
|
@@ -218,7 +213,7 @@ NEVER use Write to overwrite an existing file. ALWAYS check existence first via
|
|
|
218
213
|
|------|----------|-------|
|
|
219
214
|
|
|
220
215
|
## CODE MAP
|
|
221
|
-
{From LSP - skip if
|
|
216
|
+
{From LSP/codegraph - skip only if neither exists or project <10 files}
|
|
222
217
|
|
|
223
218
|
| Symbol | Type | Location | Refs | Role |
|
|
224
219
|
|--------|------|----------|------|------|
|
|
@@ -301,7 +296,7 @@ Hierarchy:
|
|
|
301
296
|
## Anti-Patterns
|
|
302
297
|
|
|
303
298
|
- **Static agent count**: MUST vary agents based on project size/depth
|
|
304
|
-
- **Sequential execution**: MUST parallel (explore + LSP concurrent)
|
|
299
|
+
- **Sequential execution**: MUST parallel (explore + LSP + codegraph concurrent)
|
|
305
300
|
- **Ignoring existing**: ALWAYS read existing first, even with --create-new
|
|
306
301
|
- **Over-documenting**: Not every dir needs AGENTS.md
|
|
307
302
|
- **Redundancy**: Child never repeats parent
|