oh-my-opencode 5.0.0-beta.33 → 5.0.0-beta.35
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 +48350 -48559
- package/dist/cli-node/index.js +48480 -48689
- 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 -13742
- 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-plan/SKILL.md +0 -1
- package/dist/tui.js +44809 -44910
- package/package.json +16 -18
- 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/canonical-ultrawork-directive.mjs +17 -0
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +2 -8
- 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-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/canonical-ultrawork-directive.test.mjs +53 -0
- 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-cache-copy.test.mjs +27 -1
- package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +238 -431
- 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-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
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
|
|
6
|
-
import { runCodegraphCli } from "../src/cli.ts";
|
|
7
|
-
|
|
8
|
-
describe("CodeGraph sweep CLI", () => {
|
|
9
|
-
it("#given sweep dry-run args with an injected root #when invoked #then it reports candidates as JSON and does not kill", async () => {
|
|
10
|
-
// given
|
|
11
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-sweep-cli-home-"));
|
|
12
|
-
const root = join(homeDir, ".codex", "plugins", "cache", "sisyphuslabs", "omo", "4.15.1");
|
|
13
|
-
const stdout: string[] = [];
|
|
14
|
-
const killed: string[] = [];
|
|
15
|
-
try {
|
|
16
|
-
// when
|
|
17
|
-
const exitCode = await runCodegraphCli({
|
|
18
|
-
argv: ["node", "cli.js", "sweep", "--dry-run", "--force", "--root", root],
|
|
19
|
-
env: { HOME: homeDir },
|
|
20
|
-
stdout: { write: (chunk) => stdout.push(chunk) },
|
|
21
|
-
sweepOptions: {
|
|
22
|
-
killer: {
|
|
23
|
-
isAlive: () => true,
|
|
24
|
-
kill: (pid) => {
|
|
25
|
-
killed.push(`kill:${pid}`);
|
|
26
|
-
return Promise.resolve();
|
|
27
|
-
},
|
|
28
|
-
terminate: (pid) => {
|
|
29
|
-
killed.push(`term:${pid}`);
|
|
30
|
-
return Promise.resolve();
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
processProvider: () => Promise.resolve([
|
|
34
|
-
{
|
|
35
|
-
command: `${process.execPath} ${root}/components/codegraph/dist/serve.js`,
|
|
36
|
-
pid: 601,
|
|
37
|
-
ppid: 1,
|
|
38
|
-
},
|
|
39
|
-
]),
|
|
40
|
-
},
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
// then
|
|
44
|
-
expect(exitCode).toBe(0);
|
|
45
|
-
expect(killed).toEqual([]);
|
|
46
|
-
expect(JSON.parse(stdout.join(""))).toMatchObject({
|
|
47
|
-
action: "swept",
|
|
48
|
-
candidates: [{ pid: 601 }],
|
|
49
|
-
dryRun: true,
|
|
50
|
-
killed: [],
|
|
51
|
-
});
|
|
52
|
-
} finally {
|
|
53
|
-
rmSync(homeDir, { force: true, recursive: true });
|
|
54
|
-
}
|
|
55
|
-
});
|
|
56
|
-
});
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"extends": "./tsconfig.json",
|
|
3
|
-
"compilerOptions": {
|
|
4
|
-
"allowImportingTsExtensions": false,
|
|
5
|
-
"declaration": true,
|
|
6
|
-
"outDir": "dist",
|
|
7
|
-
"rootDir": "src",
|
|
8
|
-
"noEmit": false,
|
|
9
|
-
"types": ["node"]
|
|
10
|
-
},
|
|
11
|
-
"include": ["src/**/*"],
|
|
12
|
-
"exclude": ["test/**/*"]
|
|
13
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "ESNext",
|
|
5
|
-
"moduleResolution": "Bundler",
|
|
6
|
-
"lib": ["ES2022"],
|
|
7
|
-
"strict": true,
|
|
8
|
-
"exactOptionalPropertyTypes": true,
|
|
9
|
-
"noUncheckedIndexedAccess": true,
|
|
10
|
-
"noPropertyAccessFromIndexSignature": true,
|
|
11
|
-
"verbatimModuleSyntax": true,
|
|
12
|
-
"noImplicitOverride": true,
|
|
13
|
-
"noImplicitReturns": true,
|
|
14
|
-
"noFallthroughCasesInSwitch": true,
|
|
15
|
-
"noUnusedLocals": true,
|
|
16
|
-
"noUnusedParameters": true,
|
|
17
|
-
"esModuleInterop": true,
|
|
18
|
-
"allowImportingTsExtensions": true,
|
|
19
|
-
"skipLibCheck": true,
|
|
20
|
-
"forceConsistentCasingInFileNames": true,
|
|
21
|
-
"types": ["node", "bun-types"],
|
|
22
|
-
"noEmit": true
|
|
23
|
-
},
|
|
24
|
-
"include": ["src/**/*", "test/**/*"]
|
|
25
|
-
}
|
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { existsSync, statSync } from "node:fs";
|
|
2
|
-
import { describe, expect, it } from "vitest";
|
|
3
|
-
import { validateQualityGate } from "../src/quality-gate.js";
|
|
4
|
-
import { UlwLoopError } from "../src/types.js";
|
|
5
|
-
|
|
6
|
-
const opts = { repoRoot: process.cwd(), fs: { existsSync, statSync }, reviewerSurface: "omo-senpi" as const };
|
|
7
|
-
|
|
8
|
-
describe("aggregated quality gate validation", () => {
|
|
9
|
-
it("#given four independent defects #when validating #then reports all defects in one error", () => {
|
|
10
|
-
const gate = {
|
|
11
|
-
manualQa: {
|
|
12
|
-
by: "main-session",
|
|
13
|
-
status: "passed",
|
|
14
|
-
evidence: "placeholder",
|
|
15
|
-
surfaceEvidence: [],
|
|
16
|
-
adversarialCases: [],
|
|
17
|
-
artifactRefs: [
|
|
18
|
-
{ id: "missing", kind: "cli-transcript", description: "artifact", path: "does-not-exist.txt" },
|
|
19
|
-
],
|
|
20
|
-
},
|
|
21
|
-
gateReview: {
|
|
22
|
-
by: "category:deep",
|
|
23
|
-
recommendation: "REJECT",
|
|
24
|
-
reportPath: "test/fixtures/artifacts/gate-review.md",
|
|
25
|
-
blockers: [],
|
|
26
|
-
},
|
|
27
|
-
iteration: { fullRerun: true, status: "passed", rerunCommands: ["test"], evidence: "rerun" },
|
|
28
|
-
criteriaCoverage: {
|
|
29
|
-
totalCriteria: 1,
|
|
30
|
-
passCount: 1,
|
|
31
|
-
originalIntent: "intent",
|
|
32
|
-
desiredOutcome: "outcome",
|
|
33
|
-
userOutcomeReview: "review",
|
|
34
|
-
adversarialClassesCovered: ["none"],
|
|
35
|
-
},
|
|
36
|
-
};
|
|
37
|
-
try {
|
|
38
|
-
validateQualityGate(gate, opts);
|
|
39
|
-
throw new Error("expected validation failure");
|
|
40
|
-
} catch (error) {
|
|
41
|
-
expect(error).toBeInstanceOf(UlwLoopError);
|
|
42
|
-
if (!(error instanceof UlwLoopError)) throw error;
|
|
43
|
-
expect(error.code).toBe("ULW_LOOP_QUALITY_GATE_INVALID");
|
|
44
|
-
expect(error.details?.["field"]).toBe("manualQa.evidence");
|
|
45
|
-
expect(error.details?.["fields"]).toEqual(
|
|
46
|
-
expect.arrayContaining([
|
|
47
|
-
{ field: "manualQa.evidence", message: expect.stringContaining("placeholder") },
|
|
48
|
-
{ field: "gateReview.evidence", message: expect.stringContaining("non-empty") },
|
|
49
|
-
{ field: "gateReview.recommendation", message: expect.stringContaining("APPROVE") },
|
|
50
|
-
{ field: "manualQa.artifactRefs[0].path", message: expect.stringContaining("existing") },
|
|
51
|
-
]),
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it("#given more than twenty-five defects #when validating #then caps the list and flags truncation", () => {
|
|
57
|
-
const refs = Array.from({ length: 30 }, (_, index) => ({
|
|
58
|
-
id: `ref-${index}`,
|
|
59
|
-
kind: "cli-transcript",
|
|
60
|
-
description: "artifact",
|
|
61
|
-
path: `does-not-exist-${index}.txt`,
|
|
62
|
-
}));
|
|
63
|
-
const gate = {
|
|
64
|
-
manualQa: {
|
|
65
|
-
by: "main-session",
|
|
66
|
-
status: "passed",
|
|
67
|
-
evidence: "real evidence",
|
|
68
|
-
surfaceEvidence: [],
|
|
69
|
-
adversarialCases: [],
|
|
70
|
-
artifactRefs: refs,
|
|
71
|
-
},
|
|
72
|
-
gateReview: {
|
|
73
|
-
by: "category:deep",
|
|
74
|
-
recommendation: "APPROVE",
|
|
75
|
-
reportPath: "test/fixtures/artifacts/gate-review.md",
|
|
76
|
-
evidence: "gate evidence",
|
|
77
|
-
blockers: [],
|
|
78
|
-
},
|
|
79
|
-
iteration: { fullRerun: true, status: "passed", rerunCommands: ["test"], evidence: "rerun" },
|
|
80
|
-
criteriaCoverage: {
|
|
81
|
-
totalCriteria: 1,
|
|
82
|
-
passCount: 1,
|
|
83
|
-
originalIntent: "intent",
|
|
84
|
-
desiredOutcome: "outcome",
|
|
85
|
-
userOutcomeReview: "review",
|
|
86
|
-
adversarialClassesCovered: ["none"],
|
|
87
|
-
},
|
|
88
|
-
};
|
|
89
|
-
try {
|
|
90
|
-
validateQualityGate(gate, opts);
|
|
91
|
-
throw new Error("expected validation failure");
|
|
92
|
-
} catch (error) {
|
|
93
|
-
expect(error).toBeInstanceOf(UlwLoopError);
|
|
94
|
-
if (!(error instanceof UlwLoopError)) throw error;
|
|
95
|
-
const fields = error.details?.["fields"];
|
|
96
|
-
expect(Array.isArray(fields) && fields.length).toBe(25);
|
|
97
|
-
expect(error.details?.["truncated"]).toBe(true);
|
|
98
|
-
expect(error.message).toContain("25+");
|
|
99
|
-
}
|
|
100
|
-
});
|
|
101
|
-
});
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"hooks": {
|
|
3
|
-
"PostToolUse": [
|
|
4
|
-
{
|
|
5
|
-
"hooks": [
|
|
6
|
-
{
|
|
7
|
-
"type": "command",
|
|
8
|
-
"command": "node \"${PLUGIN_ROOT}/components/codegraph/dist/cli.js\" hook post-tool-use",
|
|
9
|
-
"timeout": 5,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.33) Checking CodeGraph Init Guidance",
|
|
11
|
-
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\codegraph\\dist\\cli.js\" hook post-tool-use"
|
|
12
|
-
}
|
|
13
|
-
],
|
|
14
|
-
"matcher": "^(codegraph[._].*|mcp__codegraph__.*)$"
|
|
15
|
-
}
|
|
16
|
-
]
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"hooks": {
|
|
3
|
-
"SessionStart": [
|
|
4
|
-
{
|
|
5
|
-
"hooks": [
|
|
6
|
-
{
|
|
7
|
-
"type": "command",
|
|
8
|
-
"command": "node \"${PLUGIN_ROOT}/components/codegraph/dist/cli.js\" hook session-start",
|
|
9
|
-
"timeout": 15,
|
|
10
|
-
"statusMessage": "(OmO 5.0.0-beta.33) Checking CodeGraph Bootstrap",
|
|
11
|
-
"commandWindows": "powershell -NoProfile -ExecutionPolicy Bypass -File \"${PLUGIN_ROOT}\\components\\bootstrap\\scripts\\node-dispatch.ps1\" \"${PLUGIN_ROOT}\\components\\codegraph\\dist\\cli.js\" hook session-start"
|
|
12
|
-
}
|
|
13
|
-
]
|
|
14
|
-
}
|
|
15
|
-
]
|
|
16
|
-
}
|
|
17
|
-
}
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
import { stringEnd, stripJsonComments } from "./jsonc.mjs";
|
|
2
|
-
|
|
3
|
-
export function addCodexCodegraphValues(content, config, additions) {
|
|
4
|
-
const codex = recordAt(config, "[codex]");
|
|
5
|
-
const codexRange = findObjectPropertyRange(content, 0, "[codex]");
|
|
6
|
-
if (!isRecord(codex) || codexRange === null) {
|
|
7
|
-
return insertPropertiesIntoObject(content, 0, {
|
|
8
|
-
"[codex]": {
|
|
9
|
-
codegraph: additions,
|
|
10
|
-
},
|
|
11
|
-
});
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const codegraph = recordAt(codex, "codegraph");
|
|
15
|
-
const codegraphRange = findObjectPropertyRange(content, codexRange.valueStart, "codegraph");
|
|
16
|
-
if (!isRecord(codegraph) || codegraphRange === null) {
|
|
17
|
-
return insertPropertiesIntoObject(content, codexRange.valueStart, { codegraph: additions });
|
|
18
|
-
}
|
|
19
|
-
return insertPropertiesIntoObject(content, codegraphRange.valueStart, additions);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function recordAt(value, key) {
|
|
23
|
-
return isRecord(value) ? value[key] : undefined;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export function isRecord(value) {
|
|
27
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function hasOwn(value, key) {
|
|
31
|
-
return isRecord(value) && Object.prototype.hasOwnProperty.call(value, key);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
function findObjectPropertyRange(content, objectStart, name) {
|
|
35
|
-
const open = content.indexOf("{", objectStart);
|
|
36
|
-
if (open < 0) return null;
|
|
37
|
-
let index = open + 1;
|
|
38
|
-
while (index < content.length) {
|
|
39
|
-
index = skipTrivia(content, index);
|
|
40
|
-
if (content[index] === "}") return null;
|
|
41
|
-
if (content[index] !== "\"") return null;
|
|
42
|
-
const end = stringEnd(content, index);
|
|
43
|
-
const key = JSON.parse(content.slice(index, end));
|
|
44
|
-
index = skipTrivia(content, end);
|
|
45
|
-
if (content[index] !== ":") return null;
|
|
46
|
-
const valueStart = skipTrivia(content, index + 1);
|
|
47
|
-
const valueEnd = valueRangeEnd(content, valueStart);
|
|
48
|
-
if (key === name) return { valueEnd, valueStart };
|
|
49
|
-
index = skipTrivia(content, valueEnd);
|
|
50
|
-
if (content[index] === ",") index += 1;
|
|
51
|
-
}
|
|
52
|
-
return null;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function insertPropertiesIntoObject(content, objectStart, properties) {
|
|
56
|
-
const open = content.indexOf("{", objectStart);
|
|
57
|
-
const close = matchingBrace(content, open);
|
|
58
|
-
if (open < 0 || close < 0) return content;
|
|
59
|
-
const entries = Object.entries(properties);
|
|
60
|
-
if (entries.length === 0) return content;
|
|
61
|
-
const parentIndent = lineIndent(content, open);
|
|
62
|
-
const childIndent = `${parentIndent} `;
|
|
63
|
-
const body = entries.map(([key, value]) => `${childIndent}${JSON.stringify(key)}: ${formatJsoncValue(value, childIndent)}`).join(",\n");
|
|
64
|
-
const hasProperty = /"[^"]+"\s*:/.test(stripJsonComments(content.slice(open + 1, close)));
|
|
65
|
-
const beforeClose = content.slice(0, close).replace(/\s*$/, "");
|
|
66
|
-
const suffix = content.slice(close);
|
|
67
|
-
const comma = hasProperty && !beforeClose.endsWith(",") && !beforeClose.endsWith("{") ? "," : "";
|
|
68
|
-
return `${beforeClose}${comma}\n${body}\n${parentIndent}${suffix}`;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function formatJsoncValue(value, indent) {
|
|
72
|
-
if (!isRecord(value)) return JSON.stringify(value);
|
|
73
|
-
const nextIndent = `${indent} `;
|
|
74
|
-
const entries = Object.entries(value).map(([key, entry]) => `${nextIndent}${JSON.stringify(key)}: ${formatJsoncValue(entry, nextIndent)}`);
|
|
75
|
-
return `{\n${entries.join(",\n")}\n${indent}}`;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function valueRangeEnd(content, start) {
|
|
79
|
-
const char = content[start];
|
|
80
|
-
if (char === "{" || char === "[") return matchingBrace(content, start) + 1;
|
|
81
|
-
if (char === "\"") return stringEnd(content, start);
|
|
82
|
-
let index = start;
|
|
83
|
-
while (index < content.length && content[index] !== "," && content[index] !== "}") index += 1;
|
|
84
|
-
return index;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function matchingBrace(content, start) {
|
|
88
|
-
const open = content[start];
|
|
89
|
-
const close = open === "{" ? "}" : "]";
|
|
90
|
-
let depth = 0;
|
|
91
|
-
for (let index = start; index < content.length; index += 1) {
|
|
92
|
-
const char = content[index];
|
|
93
|
-
if (char === "\"") index = stringEnd(content, index) - 1;
|
|
94
|
-
else if (char === "/" && content[index + 1] === "/") while (index < content.length && content[index] !== "\n") index += 1;
|
|
95
|
-
else if (char === "/" && content[index + 1] === "*") {
|
|
96
|
-
index += 2;
|
|
97
|
-
while (index < content.length && !(content[index] === "*" && content[index + 1] === "/")) index += 1;
|
|
98
|
-
index += 1;
|
|
99
|
-
} else if (char === open) depth += 1;
|
|
100
|
-
else if (char === close) {
|
|
101
|
-
depth -= 1;
|
|
102
|
-
if (depth === 0) return index;
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
return -1;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
function skipTrivia(content, index) {
|
|
109
|
-
while (index < content.length) {
|
|
110
|
-
if (/\s/.test(content[index])) index += 1;
|
|
111
|
-
else if (content[index] === "/" && content[index + 1] === "/") while (index < content.length && content[index] !== "\n") index += 1;
|
|
112
|
-
else if (content[index] === "/" && content[index + 1] === "*") {
|
|
113
|
-
index += 2;
|
|
114
|
-
while (index < content.length && !(content[index] === "*" && content[index + 1] === "/")) index += 1;
|
|
115
|
-
index += 2;
|
|
116
|
-
} else return index;
|
|
117
|
-
}
|
|
118
|
-
return index;
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function lineIndent(content, index) {
|
|
122
|
-
const lineStart = content.lastIndexOf("\n", index) + 1;
|
|
123
|
-
const match = /^[ \t]*/.exec(content.slice(lineStart, index));
|
|
124
|
-
return match?.[0] ?? "";
|
|
125
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
export function parseJsonc(content) {
|
|
2
|
-
try {
|
|
3
|
-
return { ok: true, value: JSON.parse(stripTrailingCommas(stripJsonComments(content))) };
|
|
4
|
-
} catch (error) {
|
|
5
|
-
if (error instanceof Error) return { ok: false, error };
|
|
6
|
-
throw error;
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function stripJsonComments(content) {
|
|
11
|
-
let result = "";
|
|
12
|
-
for (let index = 0; index < content.length; index += 1) {
|
|
13
|
-
const char = content[index];
|
|
14
|
-
const next = content[index + 1];
|
|
15
|
-
if (char === "\"") {
|
|
16
|
-
const end = stringEnd(content, index);
|
|
17
|
-
result += content.slice(index, end);
|
|
18
|
-
index = end - 1;
|
|
19
|
-
} else if (char === "/" && next === "/") {
|
|
20
|
-
while (index < content.length && content[index] !== "\n") index += 1;
|
|
21
|
-
result += "\n";
|
|
22
|
-
} else if (char === "/" && next === "*") {
|
|
23
|
-
index += 2;
|
|
24
|
-
while (index < content.length && !(content[index] === "*" && content[index + 1] === "/")) index += 1;
|
|
25
|
-
index += 1;
|
|
26
|
-
} else {
|
|
27
|
-
result += char;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
return result;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
export function stringEnd(content, start) {
|
|
34
|
-
for (let index = start + 1; index < content.length; index += 1) {
|
|
35
|
-
if (content[index] === "\\") index += 1;
|
|
36
|
-
else if (content[index] === "\"") return index + 1;
|
|
37
|
-
}
|
|
38
|
-
return content.length;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function stripTrailingCommas(content) {
|
|
42
|
-
return content.replace(/,\s*([}\]])/g, "$1");
|
|
43
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
export const SCAFFOLD = `{
|
|
2
|
-
// Shared OMO settings. Harness override blocks below are additive.
|
|
3
|
-
"codegraph": {
|
|
4
|
-
// "enabled": true,
|
|
5
|
-
// "auto_provision": true,
|
|
6
|
-
// "telemetry": false,
|
|
7
|
-
// "install_dir": "~/.omo/codegraph"
|
|
8
|
-
},
|
|
9
|
-
|
|
10
|
-
"[codex]": {
|
|
11
|
-
"codegraph": {
|
|
12
|
-
// "enabled": true,
|
|
13
|
-
// "auto_provision": true,
|
|
14
|
-
// "install_dir": "~/.omo/codegraph",
|
|
15
|
-
// "telemetry": false
|
|
16
|
-
}
|
|
17
|
-
},
|
|
18
|
-
|
|
19
|
-
"[opencode]": {
|
|
20
|
-
"codegraph": {
|
|
21
|
-
// "enabled": true,
|
|
22
|
-
// "auto_provision": true,
|
|
23
|
-
// "install_dir": "~/.omo/codegraph",
|
|
24
|
-
// "telemetry": false,
|
|
25
|
-
// "watch_debounce_ms": 250
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
`;
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { access, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
4
|
-
import { homedir } from "node:os";
|
|
5
|
-
import { dirname, join } from "node:path";
|
|
6
|
-
|
|
7
|
-
import { isCliEntry } from "./entry-guard.mjs";
|
|
8
|
-
import { addCodexCodegraphValues, hasOwn, isRecord, recordAt } from "./migrate-omo-sot/editor.mjs";
|
|
9
|
-
import { parseJsonc } from "./migrate-omo-sot/jsonc.mjs";
|
|
10
|
-
import { SCAFFOLD } from "./migrate-omo-sot/scaffold.mjs";
|
|
11
|
-
|
|
12
|
-
const CODEGRAPH_KEYS = ["auto_provision", "enabled", "install_dir", "telemetry"];
|
|
13
|
-
const ENV_MAPPINGS = [
|
|
14
|
-
["auto_provision", "OMO_CODEGRAPH_AUTO_PROVISION", "boolean"],
|
|
15
|
-
["auto_provision", "CODEX_CODEGRAPH_AUTO_PROVISION", "boolean"],
|
|
16
|
-
["enabled", "OMO_CODEGRAPH_ENABLED", "boolean"],
|
|
17
|
-
["enabled", "CODEX_CODEGRAPH_ENABLED", "boolean"],
|
|
18
|
-
["install_dir", "OMO_CODEGRAPH_INSTALL_DIR", "string"],
|
|
19
|
-
["install_dir", "CODEX_CODEGRAPH_INSTALL_DIR", "string"],
|
|
20
|
-
["telemetry", "OMO_CODEGRAPH_TELEMETRY", "boolean"],
|
|
21
|
-
["telemetry", "CODEX_CODEGRAPH_TELEMETRY", "boolean"],
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
export async function migrateOmoSotConfig({ env = process.env, seed = false, configPath } = {}) {
|
|
25
|
-
const targetPath = configPath ?? join(resolveHomeDir(env), ".omo", "config.jsonc");
|
|
26
|
-
if (!(await pathExists(targetPath))) {
|
|
27
|
-
if (!seed) return { changed: false, configPath: targetPath, seeded: false, warnings: [] };
|
|
28
|
-
const parsedScaffold = parseJsonc(SCAFFOLD);
|
|
29
|
-
if (!parsedScaffold.ok) throw parsedScaffold.error;
|
|
30
|
-
const additions = collectCodexAdditions(parsedScaffold.value, env);
|
|
31
|
-
const content = addCodexCodegraphValues(SCAFFOLD, parsedScaffold.value, additions);
|
|
32
|
-
await mkdir(dirname(targetPath), { recursive: true });
|
|
33
|
-
await writeFile(targetPath, content);
|
|
34
|
-
return { changed: true, configPath: targetPath, seeded: true, warnings: [] };
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
const content = await readFile(targetPath, "utf8");
|
|
38
|
-
const parsed = parseJsonc(content);
|
|
39
|
-
if (!parsed.ok) {
|
|
40
|
-
return {
|
|
41
|
-
changed: false,
|
|
42
|
-
configPath: targetPath,
|
|
43
|
-
seeded: false,
|
|
44
|
-
warnings: [`Could not parse ${targetPath}; left existing OMO SOT untouched: ${parsed.error.message}`],
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const additions = collectCodexAdditions(parsed.value, env);
|
|
49
|
-
if (Object.keys(additions).length === 0) {
|
|
50
|
-
return { changed: false, configPath: targetPath, seeded: false, warnings: [] };
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const edited = addCodexCodegraphValues(content, parsed.value, additions);
|
|
54
|
-
if (edited === content) return { changed: false, configPath: targetPath, seeded: false, warnings: [] };
|
|
55
|
-
await writeFile(targetPath, edited);
|
|
56
|
-
return { changed: true, configPath: targetPath, seeded: false, warnings: [] };
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
function resolveHomeDir(env) {
|
|
60
|
-
const candidate = env.HOME ?? env.USERPROFILE;
|
|
61
|
-
return candidate?.trim() ? candidate : homedir();
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
async function pathExists(path) {
|
|
65
|
-
try {
|
|
66
|
-
await access(path);
|
|
67
|
-
return true;
|
|
68
|
-
} catch (error) {
|
|
69
|
-
if (error instanceof Error && "code" in error && error.code === "ENOENT") return false;
|
|
70
|
-
throw error;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function collectCodexAdditions(config, env) {
|
|
75
|
-
const codexCodegraph = recordAt(recordAt(config, "[codex]"), "codegraph");
|
|
76
|
-
const additions = {};
|
|
77
|
-
addSupportedCodegraphValues(additions, recordAt(config, "codegraph"), codexCodegraph);
|
|
78
|
-
for (const [key, envKey, kind] of ENV_MAPPINGS) {
|
|
79
|
-
const raw = env[envKey];
|
|
80
|
-
if (raw === undefined || hasOwn(codexCodegraph, key)) continue;
|
|
81
|
-
const parsed = parseEnvValue(raw, kind);
|
|
82
|
-
if (parsed !== null) additions[key] = parsed;
|
|
83
|
-
}
|
|
84
|
-
for (const key of Object.keys(additions)) {
|
|
85
|
-
if (hasOwn(codexCodegraph, key)) delete additions[key];
|
|
86
|
-
}
|
|
87
|
-
return additions;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
function addSupportedCodegraphValues(additions, baseCodegraph, codexCodegraph) {
|
|
91
|
-
if (!isRecord(baseCodegraph)) return;
|
|
92
|
-
for (const key of CODEGRAPH_KEYS) {
|
|
93
|
-
if (hasOwn(codexCodegraph, key) || !hasOwn(baseCodegraph, key)) continue;
|
|
94
|
-
const value = baseCodegraph[key];
|
|
95
|
-
if (isValidCodegraphValue(key, value)) additions[key] = value;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
function parseEnvValue(value, kind) {
|
|
100
|
-
if (kind === "string") return value;
|
|
101
|
-
const normalized = value.trim().toLowerCase();
|
|
102
|
-
if (["1", "true", "yes", "on"].includes(normalized)) return true;
|
|
103
|
-
if (["0", "false", "no", "off"].includes(normalized)) return false;
|
|
104
|
-
return null;
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
function isValidCodegraphValue(key, value) {
|
|
108
|
-
if (key === "install_dir") return typeof value === "string";
|
|
109
|
-
return typeof value === "boolean";
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
if (isCliEntry(import.meta.url)) {
|
|
113
|
-
migrateOmoSotConfig({ seed: process.argv.includes("--seed") })
|
|
114
|
-
.then((result) => {
|
|
115
|
-
for (const warning of result.warnings) process.stderr.write(`${warning}\n`);
|
|
116
|
-
})
|
|
117
|
-
.catch((error) => {
|
|
118
|
-
console.error(error instanceof Error ? error.message : String(error));
|
|
119
|
-
process.exitCode = 1;
|
|
120
|
-
});
|
|
121
|
-
}
|
|
@@ -1,76 +0,0 @@
|
|
|
1
|
-
import assert from "node:assert/strict";
|
|
2
|
-
import { chmodSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { spawnSync } from "node:child_process";
|
|
6
|
-
import test from "node:test";
|
|
7
|
-
|
|
8
|
-
import { root } from "./aggregate-plugin-fixture.mjs";
|
|
9
|
-
|
|
10
|
-
const MCP_SMOKE_TIMEOUT_MS = 45_000;
|
|
11
|
-
|
|
12
|
-
test("#given built CodeGraph MCP wrapper #when an MCP client initializes #then the resolved child responds over stdio", () => {
|
|
13
|
-
const tempRoot = mkdtempSync(join(tmpdir(), "omo-codex-codegraph-mcp-smoke-"));
|
|
14
|
-
try {
|
|
15
|
-
const fakeBinaryPath = join(tempRoot, "codegraph-fake.cjs");
|
|
16
|
-
writeFileSync(
|
|
17
|
-
fakeBinaryPath,
|
|
18
|
-
[
|
|
19
|
-
"#!/usr/bin/env node",
|
|
20
|
-
"const readline = require('node:readline');",
|
|
21
|
-
"const rl = readline.createInterface({ input: process.stdin });",
|
|
22
|
-
"rl.on('line', (line) => {",
|
|
23
|
-
" const request = JSON.parse(line);",
|
|
24
|
-
" if (request.method !== 'initialize') return;",
|
|
25
|
-
" process.stdout.write(JSON.stringify({",
|
|
26
|
-
" jsonrpc: '2.0',",
|
|
27
|
-
" id: request.id,",
|
|
28
|
-
" result: {",
|
|
29
|
-
" protocolVersion: request.params?.protocolVersion ?? '2024-11-05',",
|
|
30
|
-
" capabilities: { tools: { listChanged: false } },",
|
|
31
|
-
" serverInfo: { name: 'fake-codegraph', version: '0.0.0' }",
|
|
32
|
-
" }",
|
|
33
|
-
" }) + '\\n');",
|
|
34
|
-
"});",
|
|
35
|
-
"",
|
|
36
|
-
].join("\n"),
|
|
37
|
-
);
|
|
38
|
-
chmodSync(fakeBinaryPath, 0o755);
|
|
39
|
-
|
|
40
|
-
const result = spawnSync(process.execPath, [join(root, "components", "codegraph", "dist", "serve.js")], {
|
|
41
|
-
cwd: root,
|
|
42
|
-
encoding: "utf8",
|
|
43
|
-
env: {
|
|
44
|
-
...process.env,
|
|
45
|
-
HOME: tempRoot,
|
|
46
|
-
OMO_CODEGRAPH_BIN: fakeBinaryPath,
|
|
47
|
-
},
|
|
48
|
-
input: `${JSON.stringify({
|
|
49
|
-
jsonrpc: "2.0",
|
|
50
|
-
id: 1,
|
|
51
|
-
method: "initialize",
|
|
52
|
-
params: {
|
|
53
|
-
capabilities: {},
|
|
54
|
-
clientInfo: { name: "lazycodex-smoke", version: "0.0.0" },
|
|
55
|
-
protocolVersion: "2024-11-05",
|
|
56
|
-
},
|
|
57
|
-
})}\n`,
|
|
58
|
-
timeout: MCP_SMOKE_TIMEOUT_MS,
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
assert.equal(result.status, 0, `stderr: ${result.stderr}`);
|
|
62
|
-
assert.equal(result.stderr, "");
|
|
63
|
-
const response = JSON.parse(result.stdout.trim());
|
|
64
|
-
assert.deepEqual(response, {
|
|
65
|
-
jsonrpc: "2.0",
|
|
66
|
-
id: 1,
|
|
67
|
-
result: {
|
|
68
|
-
capabilities: { tools: { listChanged: false } },
|
|
69
|
-
protocolVersion: "2024-11-05",
|
|
70
|
-
serverInfo: { name: "fake-codegraph", version: "0.0.0" },
|
|
71
|
-
},
|
|
72
|
-
});
|
|
73
|
-
} finally {
|
|
74
|
-
rmSync(tempRoot, { recursive: true, force: true });
|
|
75
|
-
}
|
|
76
|
-
});
|