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,104 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import { mkdtempSync, rmSync, utimesSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
clearSessionStartCooldown,
|
|
8
|
-
readSessionStartCooldown,
|
|
9
|
-
recordSessionStartFailure,
|
|
10
|
-
} from "../src/session-start-cooldown.ts";
|
|
11
|
-
import {
|
|
12
|
-
acquireSessionStartLock,
|
|
13
|
-
releaseSessionStartLock,
|
|
14
|
-
} from "../src/session-start-lock.ts";
|
|
15
|
-
|
|
16
|
-
describe("CodeGraph SessionStart lock", () => {
|
|
17
|
-
it("#given a live project lock #when a second hook acquires it #then the second hook is deduplicated", () => {
|
|
18
|
-
// given
|
|
19
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-lock-home-"));
|
|
20
|
-
const projectRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-lock-project-"));
|
|
21
|
-
try {
|
|
22
|
-
const first = acquireSessionStartLock({ homeDir, nowMs: 10_000, projectRoot, staleMs: 60_000 });
|
|
23
|
-
expect(first.kind).toBe("acquired");
|
|
24
|
-
|
|
25
|
-
// when
|
|
26
|
-
const second = acquireSessionStartLock({ homeDir, nowMs: 10_001, projectRoot, staleMs: 60_000 });
|
|
27
|
-
|
|
28
|
-
// then
|
|
29
|
-
expect(second).toEqual({ kind: "locked" });
|
|
30
|
-
if (first.kind === "acquired") releaseSessionStartLock(first.lock);
|
|
31
|
-
} finally {
|
|
32
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
33
|
-
rmSync(projectRoot, { recursive: true, force: true });
|
|
34
|
-
}
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
it("#given a project lock older than the stale threshold #when another hook acquires it #then the stale lock is recovered", () => {
|
|
38
|
-
// given
|
|
39
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-stale-home-"));
|
|
40
|
-
const projectRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-stale-project-"));
|
|
41
|
-
try {
|
|
42
|
-
const first = acquireSessionStartLock({ homeDir, nowMs: 1_000, projectRoot, staleMs: 500 });
|
|
43
|
-
expect(first.kind).toBe("acquired");
|
|
44
|
-
if (first.kind !== "acquired") return;
|
|
45
|
-
const staleDate = new Date(1_000);
|
|
46
|
-
utimesSync(first.lock.path, staleDate, staleDate);
|
|
47
|
-
|
|
48
|
-
// when
|
|
49
|
-
const second = acquireSessionStartLock({ homeDir, nowMs: 2_000, projectRoot, staleMs: 500 });
|
|
50
|
-
|
|
51
|
-
// then
|
|
52
|
-
expect(second.kind).toBe("acquired");
|
|
53
|
-
if (second.kind === "acquired") {
|
|
54
|
-
expect(second.recoveredStale).toBe(true);
|
|
55
|
-
releaseSessionStartLock(second.lock);
|
|
56
|
-
}
|
|
57
|
-
} finally {
|
|
58
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
59
|
-
rmSync(projectRoot, { recursive: true, force: true });
|
|
60
|
-
}
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
describe("CodeGraph SessionStart cooldown", () => {
|
|
65
|
-
it("#given a failed worker outcome #when the cooldown is checked #then retries are suppressed until expiry and the next failure backs off", () => {
|
|
66
|
-
// given
|
|
67
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-cooldown-home-"));
|
|
68
|
-
const projectRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-cooldown-project-"));
|
|
69
|
-
try {
|
|
70
|
-
const first = recordSessionStartFailure({
|
|
71
|
-
action: "failed",
|
|
72
|
-
baseCooldownMs: 1_000,
|
|
73
|
-
homeDir,
|
|
74
|
-
nowMs: 1_000,
|
|
75
|
-
projectRoot,
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
// when
|
|
79
|
-
const active = readSessionStartCooldown({ baseCooldownMs: 1_000, homeDir, nowMs: 1_999, projectRoot });
|
|
80
|
-
const expired = readSessionStartCooldown({ baseCooldownMs: 1_000, homeDir, nowMs: 2_000, projectRoot });
|
|
81
|
-
const second = recordSessionStartFailure({
|
|
82
|
-
action: "skipped-status",
|
|
83
|
-
baseCooldownMs: 1_000,
|
|
84
|
-
homeDir,
|
|
85
|
-
nowMs: 2_000,
|
|
86
|
-
projectRoot,
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// then
|
|
90
|
-
expect(first).toMatchObject({ cooldownUntil: 2_000, failureCount: 1 });
|
|
91
|
-
expect(active).toMatchObject({ cooldownUntil: 2_000, failureCount: 1, kind: "active" });
|
|
92
|
-
expect(expired).toEqual({ failureCount: 1, kind: "inactive" });
|
|
93
|
-
expect(second).toMatchObject({ cooldownUntil: 4_000, failureCount: 2 });
|
|
94
|
-
clearSessionStartCooldown({ homeDir, projectRoot });
|
|
95
|
-
expect(readSessionStartCooldown({ baseCooldownMs: 1_000, homeDir, nowMs: 2_001, projectRoot })).toEqual({
|
|
96
|
-
failureCount: 0,
|
|
97
|
-
kind: "inactive",
|
|
98
|
-
});
|
|
99
|
-
} finally {
|
|
100
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
101
|
-
rmSync(projectRoot, { recursive: true, force: true });
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
});
|
package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
|
|
6
|
-
import { runCodegraphSessionStartWorker } from "../src/hook.ts";
|
|
7
|
-
|
|
8
|
-
describe("CodeGraph SessionStart trust boundary", () => {
|
|
9
|
-
it("#given project config sets install_dir #when worker provisions CodeGraph #then it uses the trusted home install root", async () => {
|
|
10
|
-
// given
|
|
11
|
-
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-untrusted-project-"));
|
|
12
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-untrusted-project-home-"));
|
|
13
|
-
const attackerInstallDir = join(workspace, "attacker-install");
|
|
14
|
-
const trustedInstallDir = join(homeDir, ".omo", "codegraph");
|
|
15
|
-
const calls: Array<{ readonly env: Record<string, string>; readonly installDir?: string; readonly lockDir?: string }> = [];
|
|
16
|
-
try {
|
|
17
|
-
mkdirSync(join(workspace, ".omo"), { recursive: true });
|
|
18
|
-
writeFileSync(join(workspace, ".omo", "omo.jsonc"), JSON.stringify({ codegraph: { enabled: true, install_dir: attackerInstallDir } }));
|
|
19
|
-
|
|
20
|
-
// when
|
|
21
|
-
const result = await runCodegraphSessionStartWorker({
|
|
22
|
-
cwd: workspace,
|
|
23
|
-
env: { HOME: homeDir },
|
|
24
|
-
nodeVersion: "22.14.0",
|
|
25
|
-
deps: {
|
|
26
|
-
ensureGitignored: () => true,
|
|
27
|
-
ensureProvisioned: (options) => {
|
|
28
|
-
calls.push({
|
|
29
|
-
env: {},
|
|
30
|
-
...(options.installDir === undefined ? {} : { installDir: options.installDir }),
|
|
31
|
-
...(options.lockDir === undefined ? {} : { lockDir: options.lockDir }),
|
|
32
|
-
});
|
|
33
|
-
return Promise.resolve({ binPath: join(trustedInstallDir, "bin", "codegraph"), provisioned: true });
|
|
34
|
-
},
|
|
35
|
-
prepareWorkspace: () => ({
|
|
36
|
-
dataDir: join(homeDir, ".omo/codegraph/projects/test"),
|
|
37
|
-
dataRoot: join(homeDir, ".omo/codegraph"),
|
|
38
|
-
linked: true,
|
|
39
|
-
mode: "global-linked",
|
|
40
|
-
projectLink: join(workspace, ".codegraph"),
|
|
41
|
-
}),
|
|
42
|
-
resolveCommand: (options) => {
|
|
43
|
-
expect(options?.provisioned?.()).toBe(null);
|
|
44
|
-
return { argsPrefix: [], command: "missing-codegraph", exists: false, source: "path" };
|
|
45
|
-
},
|
|
46
|
-
runCommand: (_projectRoot, _command, _args, options) => {
|
|
47
|
-
calls.push({ env: options.env });
|
|
48
|
-
mkdirSync(join(workspace, ".codegraph"), { recursive: true });
|
|
49
|
-
writeFileSync(join(workspace, ".codegraph", "codegraph.db"), "fixture");
|
|
50
|
-
return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
|
|
51
|
-
},
|
|
52
|
-
},
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
// then
|
|
56
|
-
expect(result).toEqual({ action: "initialized" });
|
|
57
|
-
expect(calls[0]).toEqual({ env: {}, installDir: trustedInstallDir, lockDir: join(trustedInstallDir, ".locks") });
|
|
58
|
-
expect(calls[1]?.env["CODEGRAPH_INSTALL_DIR"]).toBe(trustedInstallDir);
|
|
59
|
-
expect(calls[1]?.env["CODEGRAPH_INSTALL_DIR"]).not.toBe(attackerInstallDir);
|
|
60
|
-
} finally {
|
|
61
|
-
rmSync(workspace, { recursive: true, force: true });
|
|
62
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
63
|
-
}
|
|
64
|
-
});
|
|
65
|
-
});
|
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import { existsSync, mkdtempSync, rmSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
|
|
6
|
-
import { runCodegraphSessionStartWorker } from "../src/hook.ts";
|
|
7
|
-
|
|
8
|
-
describe("CodeGraph SessionStart worker availability", () => {
|
|
9
|
-
it("#given CodeGraph cannot be resolved or provisioned #when worker runs #then it logs a graceful skip", async () => {
|
|
10
|
-
// given
|
|
11
|
-
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-"));
|
|
12
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-home-"));
|
|
13
|
-
const outcomes: unknown[] = [];
|
|
14
|
-
const calls: string[] = [];
|
|
15
|
-
|
|
16
|
-
try {
|
|
17
|
-
// when
|
|
18
|
-
const result = await runCodegraphSessionStartWorker({
|
|
19
|
-
cwd: workspace,
|
|
20
|
-
env: { HOME: homeDir },
|
|
21
|
-
nodeVersion: "22.14.0",
|
|
22
|
-
logOutcome: (outcome) => outcomes.push(outcome),
|
|
23
|
-
deps: {
|
|
24
|
-
ensureGitignored: () => {
|
|
25
|
-
calls.push("ensureGitignored");
|
|
26
|
-
return true;
|
|
27
|
-
},
|
|
28
|
-
ensureProvisioned: () => Promise.resolve({ error: "offline", provisioned: false }),
|
|
29
|
-
prepareWorkspace: () => {
|
|
30
|
-
calls.push("prepareWorkspace");
|
|
31
|
-
return {
|
|
32
|
-
dataDir: join(homeDir, ".omo/codegraph/projects/test"),
|
|
33
|
-
dataRoot: join(homeDir, ".omo/codegraph"),
|
|
34
|
-
linked: true,
|
|
35
|
-
mode: "global-linked",
|
|
36
|
-
projectLink: join(workspace, ".codegraph"),
|
|
37
|
-
};
|
|
38
|
-
},
|
|
39
|
-
resolveCommand: () => ({ argsPrefix: [], command: "codegraph", exists: false, source: "path" }),
|
|
40
|
-
runCommand: () => {
|
|
41
|
-
calls.push("runCommand");
|
|
42
|
-
return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
|
|
43
|
-
},
|
|
44
|
-
},
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// then
|
|
48
|
-
expect(result).toEqual({ action: "skipped-unavailable" });
|
|
49
|
-
expect(calls).toEqual([]);
|
|
50
|
-
expect(outcomes).toEqual([
|
|
51
|
-
{
|
|
52
|
-
action: "skipped-unavailable",
|
|
53
|
-
error: "offline",
|
|
54
|
-
projectRoot: workspace,
|
|
55
|
-
source: "path",
|
|
56
|
-
},
|
|
57
|
-
]);
|
|
58
|
-
} finally {
|
|
59
|
-
rmSync(workspace, { recursive: true, force: true });
|
|
60
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("#given CodeGraph is unavailable and auto provisioning is disabled #when worker runs #then it leaves the project untouched", async () => {
|
|
65
|
-
// given
|
|
66
|
-
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-unavailable-"));
|
|
67
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-unavailable-home-"));
|
|
68
|
-
const outcomes: unknown[] = [];
|
|
69
|
-
|
|
70
|
-
try {
|
|
71
|
-
// when
|
|
72
|
-
const result = await runCodegraphSessionStartWorker({
|
|
73
|
-
config: { codegraph: { auto_provision: false, enabled: true }, sources: [], warnings: [] },
|
|
74
|
-
nodeVersion: "22.14.0",
|
|
75
|
-
cwd: workspace,
|
|
76
|
-
env: { HOME: homeDir },
|
|
77
|
-
logOutcome: (outcome) => outcomes.push(outcome),
|
|
78
|
-
deps: {
|
|
79
|
-
ensureProvisioned: () => {
|
|
80
|
-
throw new Error("auto provision should not run");
|
|
81
|
-
},
|
|
82
|
-
resolveCommand: () => ({ argsPrefix: [], command: "missing-codegraph", exists: false, source: "path" }),
|
|
83
|
-
runCommand: () => {
|
|
84
|
-
throw new Error("codegraph command should not run");
|
|
85
|
-
},
|
|
86
|
-
},
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// then
|
|
90
|
-
expect(result).toEqual({ action: "skipped-unavailable" });
|
|
91
|
-
expect(existsSync(join(workspace, ".codegraph"))).toBe(false);
|
|
92
|
-
expect(existsSync(join(workspace, ".git", "info", "exclude"))).toBe(false);
|
|
93
|
-
expect(outcomes).toEqual([
|
|
94
|
-
{
|
|
95
|
-
action: "skipped-unavailable",
|
|
96
|
-
error: "codegraph binary unavailable and auto_provision is disabled",
|
|
97
|
-
projectRoot: workspace,
|
|
98
|
-
source: "path",
|
|
99
|
-
},
|
|
100
|
-
]);
|
|
101
|
-
} finally {
|
|
102
|
-
rmSync(workspace, { recursive: true, force: true });
|
|
103
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
});
|
package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts
DELETED
|
@@ -1,116 +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 type { CodegraphSessionStartOutcome } from "../src/hook.ts";
|
|
7
|
-
import { runCodegraphSessionStartWorker } from "../src/hook.ts";
|
|
8
|
-
import { readSessionStartCooldown } from "../src/session-start-cooldown.ts";
|
|
9
|
-
|
|
10
|
-
describe("CodeGraph SessionStart worker cooldown", () => {
|
|
11
|
-
it("#given codegraph init times out #when the worker finishes #then it records a failed outcome and cooldown", async () => {
|
|
12
|
-
// given
|
|
13
|
-
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-timeout-"));
|
|
14
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-timeout-home-"));
|
|
15
|
-
const outcomes: CodegraphSessionStartOutcome[] = [];
|
|
16
|
-
try {
|
|
17
|
-
// when
|
|
18
|
-
const result = await runCodegraphSessionStartWorker({
|
|
19
|
-
config: { codegraph: { enabled: true, session_start_cooldown_ms: 60_000 }, sources: [], warnings: [] },
|
|
20
|
-
cwd: workspace,
|
|
21
|
-
env: { HOME: homeDir },
|
|
22
|
-
logOutcome: (outcome) => outcomes.push(outcome),
|
|
23
|
-
nodeVersion: "22.14.0",
|
|
24
|
-
nowMs: 1_000,
|
|
25
|
-
projectProbe: () => ({ kind: "uninitialized" }),
|
|
26
|
-
deps: {
|
|
27
|
-
ensureGitignored: () => true,
|
|
28
|
-
ensureProvisioned: () => Promise.resolve({ binPath: "/tmp/codegraph", provisioned: true }),
|
|
29
|
-
prepareWorkspace: () => ({
|
|
30
|
-
dataDir: join(homeDir, ".omo/codegraph/projects/test"),
|
|
31
|
-
dataRoot: join(homeDir, ".omo/codegraph"),
|
|
32
|
-
linked: true,
|
|
33
|
-
mode: "global-linked",
|
|
34
|
-
projectLink: join(workspace, ".codegraph"),
|
|
35
|
-
}),
|
|
36
|
-
resolveCommand: () => ({ argsPrefix: [], command: "/tmp/codegraph", exists: true, source: "path" }),
|
|
37
|
-
runCommand: () => Promise.resolve({ exitCode: 1, stdout: "", timedOut: true }),
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
const cooldown = readSessionStartCooldown({
|
|
41
|
-
baseCooldownMs: 60_000,
|
|
42
|
-
homeDir,
|
|
43
|
-
nowMs: 2_000,
|
|
44
|
-
projectRoot: workspace,
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// then
|
|
48
|
-
expect(result).toEqual({ action: "failed" });
|
|
49
|
-
expect(outcomes).toEqual([{
|
|
50
|
-
action: "failed",
|
|
51
|
-
error: "codegraph init timed out",
|
|
52
|
-
exitCode: 1,
|
|
53
|
-
projectRoot: workspace,
|
|
54
|
-
source: "path",
|
|
55
|
-
timedOut: true,
|
|
56
|
-
}]);
|
|
57
|
-
expect(cooldown).toEqual({ cooldownUntil: 61_000, failureCount: 1, kind: "active" });
|
|
58
|
-
} finally {
|
|
59
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
60
|
-
rmSync(workspace, { recursive: true, force: true });
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("#given codegraph init exits zero without an exact database #when the worker verifies the result #then it records a failure cooldown", async () => {
|
|
65
|
-
// given
|
|
66
|
-
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-no-db-"));
|
|
67
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-no-db-home-"));
|
|
68
|
-
const outcomes: CodegraphSessionStartOutcome[] = [];
|
|
69
|
-
try {
|
|
70
|
-
// when
|
|
71
|
-
const result = await runCodegraphSessionStartWorker({
|
|
72
|
-
config: { codegraph: { enabled: true, session_start_cooldown_ms: 60_000 }, sources: [], warnings: [] },
|
|
73
|
-
cwd: workspace,
|
|
74
|
-
env: { HOME: homeDir },
|
|
75
|
-
logOutcome: (outcome) => outcomes.push(outcome),
|
|
76
|
-
nodeVersion: "22.14.0",
|
|
77
|
-
nowMs: 1_000,
|
|
78
|
-
projectProbe: () => ({ kind: "uninitialized" }),
|
|
79
|
-
deps: {
|
|
80
|
-
ensureGitignored: () => true,
|
|
81
|
-
ensureProvisioned: () => Promise.resolve({ binPath: "/tmp/codegraph", provisioned: true }),
|
|
82
|
-
prepareWorkspace: () => ({
|
|
83
|
-
dataDir: join(homeDir, ".omo/codegraph/projects/test"),
|
|
84
|
-
dataRoot: join(homeDir, ".omo/codegraph"),
|
|
85
|
-
linked: true,
|
|
86
|
-
mode: "global-linked",
|
|
87
|
-
projectLink: join(workspace, ".codegraph"),
|
|
88
|
-
}),
|
|
89
|
-
resolveCommand: () => ({ argsPrefix: [], command: "/tmp/codegraph", exists: true, source: "path" }),
|
|
90
|
-
runCommand: () => Promise.resolve({ exitCode: 0, stdout: "", timedOut: false }),
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
const cooldown = readSessionStartCooldown({
|
|
94
|
-
baseCooldownMs: 60_000,
|
|
95
|
-
homeDir,
|
|
96
|
-
nowMs: 2_000,
|
|
97
|
-
projectRoot: workspace,
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
// then
|
|
101
|
-
expect(result).toEqual({ action: "failed" });
|
|
102
|
-
expect(outcomes).toEqual([{
|
|
103
|
-
action: "failed",
|
|
104
|
-
error: "codegraph init completed without creating an exact project database",
|
|
105
|
-
exitCode: 0,
|
|
106
|
-
projectRoot: workspace,
|
|
107
|
-
source: "path",
|
|
108
|
-
timedOut: false,
|
|
109
|
-
}]);
|
|
110
|
-
expect(cooldown).toEqual({ cooldownUntil: 61_000, failureCount: 1, kind: "active" });
|
|
111
|
-
} finally {
|
|
112
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
113
|
-
rmSync(workspace, { recursive: true, force: true });
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
});
|
package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts
DELETED
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import { mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
-
import { tmpdir } from "node:os";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
|
|
6
|
-
import { CODEGRAPH_PINNED_VERSION } from "../../../../../utils/src/codegraph/manifest.ts";
|
|
7
|
-
import { resolveCodegraphCommandInvocation, runCodegraphSessionStartWorker } from "../src/hook.ts";
|
|
8
|
-
|
|
9
|
-
function writeProjectDatabase(workspace: string): void {
|
|
10
|
-
mkdirSync(join(workspace, ".codegraph"), { recursive: true });
|
|
11
|
-
writeFileSync(join(workspace, ".codegraph", "codegraph.db"), "fixture");
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
describe("CodeGraph SessionStart worker flow", () => {
|
|
15
|
-
it("#given install_dir has the pinned platform binary #when worker resolves provisioned CodeGraph #then it uses that launcher", async () => {
|
|
16
|
-
// given
|
|
17
|
-
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-platform-"));
|
|
18
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-platform-home-"));
|
|
19
|
-
const installDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-platform-install-"));
|
|
20
|
-
const binPath = join(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
|
|
21
|
-
const calls: { readonly args: readonly string[]; readonly command: string; readonly env: Record<string, string> }[] = [];
|
|
22
|
-
const outcomes: unknown[] = [];
|
|
23
|
-
try {
|
|
24
|
-
mkdirSync(join(installDir, "bin"), { recursive: true });
|
|
25
|
-
mkdirSync(join(installDir, ".provisioned"), { recursive: true });
|
|
26
|
-
writeFileSync(binPath, "");
|
|
27
|
-
writeFileSync(
|
|
28
|
-
join(installDir, ".provisioned", `codegraph-${CODEGRAPH_PINNED_VERSION}.json`),
|
|
29
|
-
`${JSON.stringify({ binPath, version: CODEGRAPH_PINNED_VERSION })}\n`,
|
|
30
|
-
);
|
|
31
|
-
|
|
32
|
-
// when
|
|
33
|
-
const result = await runCodegraphSessionStartWorker({
|
|
34
|
-
config: { codegraph: { enabled: true, install_dir: installDir }, sources: [], trustedCodegraphInstallDir: installDir, warnings: [] },
|
|
35
|
-
nodeVersion: "22.14.0",
|
|
36
|
-
cwd: workspace,
|
|
37
|
-
env: { HOME: homeDir },
|
|
38
|
-
logOutcome: (outcome) => outcomes.push(outcome),
|
|
39
|
-
deps: {
|
|
40
|
-
ensureGitignored: () => true,
|
|
41
|
-
ensureProvisioned: () => {
|
|
42
|
-
throw new Error("provisioning should not run when install_dir binary exists");
|
|
43
|
-
},
|
|
44
|
-
prepareWorkspace: () => ({
|
|
45
|
-
dataDir: join(homeDir, ".omo/codegraph/projects/test"),
|
|
46
|
-
dataRoot: join(homeDir, ".omo/codegraph"),
|
|
47
|
-
linked: true,
|
|
48
|
-
mode: "global-linked",
|
|
49
|
-
projectLink: join(workspace, ".codegraph"),
|
|
50
|
-
}),
|
|
51
|
-
resolveCommand: (options) => {
|
|
52
|
-
const provisioned = options?.provisioned?.() ?? null;
|
|
53
|
-
return { argsPrefix: [], command: provisioned ?? "missing-codegraph", exists: provisioned !== null, source: provisioned === null ? "path" : "provisioned" };
|
|
54
|
-
},
|
|
55
|
-
resolveManagedBin: () => binPath,
|
|
56
|
-
runCommand: (_projectRoot, command, args, options) => {
|
|
57
|
-
calls.push({ args, command, env: options.env });
|
|
58
|
-
writeProjectDatabase(workspace);
|
|
59
|
-
return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
// then
|
|
65
|
-
expect(result).toEqual({ action: "initialized" });
|
|
66
|
-
expect(calls.map((call) => ({ args: [...call.args], command: call.command }))).toEqual([
|
|
67
|
-
{ args: ["init"], command: binPath },
|
|
68
|
-
]);
|
|
69
|
-
expect(calls[0]?.env["CODEGRAPH_INSTALL_DIR"]).toBe(installDir);
|
|
70
|
-
expect(outcomes).toEqual([{ action: "initialized", exitCode: 0, projectRoot: workspace, source: "provisioned", timedOut: false }]);
|
|
71
|
-
} finally {
|
|
72
|
-
rmSync(workspace, { recursive: true, force: true });
|
|
73
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
74
|
-
rmSync(installDir, { recursive: true, force: true });
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
it("#given Windows codegraph.cmd #when default worker runner builds invocation #then it runs through cmd.exe", () => {
|
|
79
|
-
// given
|
|
80
|
-
const command = "C:\\Users\\test\\.omo\\codegraph\\bin\\codegraph.cmd";
|
|
81
|
-
|
|
82
|
-
// when
|
|
83
|
-
const invocation = resolveCodegraphCommandInvocation(command, ["init"], "win32");
|
|
84
|
-
|
|
85
|
-
// then
|
|
86
|
-
expect(invocation).toEqual({
|
|
87
|
-
args: ["/d", "/s", "/c", command, "init"],
|
|
88
|
-
command: "cmd.exe",
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it("#given Windows CodeGraph resolves to a Node script #when default worker runner builds invocation #then Node executes it", () => {
|
|
93
|
-
// given
|
|
94
|
-
const command = "C:\\Users\\test\\.omo\\codegraph\\bin\\codegraph.cjs";
|
|
95
|
-
|
|
96
|
-
// when
|
|
97
|
-
const invocation = resolveCodegraphCommandInvocation(command, ["init"], "win32");
|
|
98
|
-
|
|
99
|
-
// then
|
|
100
|
-
expect(invocation).toEqual({
|
|
101
|
-
args: [command, "init"],
|
|
102
|
-
command: process.execPath,
|
|
103
|
-
});
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it("#given non-Windows codegraph command #when default worker runner builds invocation #then it executes directly", () => {
|
|
107
|
-
// given
|
|
108
|
-
const command = "/home/test/.omo/codegraph/bin/codegraph";
|
|
109
|
-
|
|
110
|
-
// when
|
|
111
|
-
const invocation = resolveCodegraphCommandInvocation(command, ["sync"], "linux");
|
|
112
|
-
|
|
113
|
-
// then
|
|
114
|
-
expect(invocation).toEqual({ args: ["sync"], command });
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it("#given an uninitialized exact project #when worker runs #then it invokes init directly without a status command", async () => {
|
|
118
|
-
// given
|
|
119
|
-
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-init-direct-"));
|
|
120
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-init-direct-home-"));
|
|
121
|
-
const calls: { readonly args: readonly string[]; readonly env: Record<string, string> }[] = [];
|
|
122
|
-
const outcomes: unknown[] = [];
|
|
123
|
-
try {
|
|
124
|
-
// when
|
|
125
|
-
const result = await runCodegraphSessionStartWorker({
|
|
126
|
-
config: { codegraph: { enabled: true, install_dir: "/tmp/codegraph-install" }, sources: [], trustedCodegraphInstallDir: "/tmp/codegraph-install", warnings: [] },
|
|
127
|
-
nodeVersion: "22.14.0",
|
|
128
|
-
cwd: workspace,
|
|
129
|
-
env: { HOME: homeDir },
|
|
130
|
-
logOutcome: (outcome) => outcomes.push(outcome),
|
|
131
|
-
deps: {
|
|
132
|
-
ensureGitignored: () => true,
|
|
133
|
-
ensureProvisioned: () => Promise.resolve({ binPath: "/tmp/codegraph", provisioned: true }),
|
|
134
|
-
prepareWorkspace: () => ({
|
|
135
|
-
dataDir: join(homeDir, ".omo/codegraph/projects/test"),
|
|
136
|
-
dataRoot: join(homeDir, ".omo/codegraph"),
|
|
137
|
-
linked: true,
|
|
138
|
-
mode: "global-linked",
|
|
139
|
-
projectLink: join(workspace, ".codegraph"),
|
|
140
|
-
}),
|
|
141
|
-
resolveCommand: () => ({ argsPrefix: [], command: "/tmp/codegraph", exists: true, source: "path" }),
|
|
142
|
-
runCommand: (_projectRoot, _command, args, options) => {
|
|
143
|
-
calls.push({ args, env: options.env });
|
|
144
|
-
writeProjectDatabase(workspace);
|
|
145
|
-
return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
|
|
146
|
-
},
|
|
147
|
-
},
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
// then
|
|
151
|
-
expect(result).toEqual({ action: "initialized" });
|
|
152
|
-
expect(calls.map((call) => [...call.args])).toEqual([["init"]]);
|
|
153
|
-
expect(calls[0]?.env["CODEGRAPH_INSTALL_DIR"]).toBe("/tmp/codegraph-install");
|
|
154
|
-
expect(outcomes).toEqual([{ action: "initialized", exitCode: 0, projectRoot: workspace, source: "path", timedOut: false }]);
|
|
155
|
-
} finally {
|
|
156
|
-
rmSync(workspace, { recursive: true, force: true });
|
|
157
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
it("#given codegraph.daemon=true #when the indexing worker runs #then its env stays daemon-less with CODEGRAPH_NO_DAEMON=1", async () => {
|
|
162
|
-
// given
|
|
163
|
-
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-daemon-"));
|
|
164
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-daemon-home-"));
|
|
165
|
-
const calls: { readonly args: readonly string[]; readonly command: string; readonly env: Record<string, string> }[] = [];
|
|
166
|
-
try {
|
|
167
|
-
// when
|
|
168
|
-
const result = await runCodegraphSessionStartWorker({
|
|
169
|
-
config: { codegraph: { daemon: true, enabled: true, install_dir: "/tmp/codegraph-install" }, sources: [], trustedCodegraphInstallDir: "/tmp/codegraph-install", warnings: [] },
|
|
170
|
-
nodeVersion: "22.14.0",
|
|
171
|
-
cwd: workspace,
|
|
172
|
-
env: { HOME: homeDir },
|
|
173
|
-
logOutcome: () => undefined,
|
|
174
|
-
deps: {
|
|
175
|
-
ensureGitignored: () => true,
|
|
176
|
-
ensureProvisioned: () => Promise.resolve({ binPath: "/tmp/codegraph", provisioned: true }),
|
|
177
|
-
prepareWorkspace: () => ({
|
|
178
|
-
dataDir: join(homeDir, ".omo/codegraph/projects/test"),
|
|
179
|
-
dataRoot: join(homeDir, ".omo/codegraph"),
|
|
180
|
-
linked: true,
|
|
181
|
-
mode: "global-linked",
|
|
182
|
-
projectLink: join(workspace, ".codegraph"),
|
|
183
|
-
}),
|
|
184
|
-
resolveCommand: () => ({ argsPrefix: [], command: "/tmp/codegraph", exists: true, source: "path" }),
|
|
185
|
-
runCommand: (_projectRoot, command, args, options) => {
|
|
186
|
-
calls.push({ args, command, env: options.env });
|
|
187
|
-
writeProjectDatabase(workspace);
|
|
188
|
-
return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
|
|
189
|
-
},
|
|
190
|
-
},
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
// then
|
|
194
|
-
expect(result).toEqual({ action: "initialized" });
|
|
195
|
-
expect(calls.length).toBeGreaterThan(0);
|
|
196
|
-
for (const call of calls) {
|
|
197
|
-
expect(call.env["CODEGRAPH_NO_DAEMON"]).toBe("1");
|
|
198
|
-
}
|
|
199
|
-
} finally {
|
|
200
|
-
rmSync(workspace, { recursive: true, force: true });
|
|
201
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it("#given ambient provider tokens #when default worker runner spawns CodeGraph #then child env only gets safe and controlled variables", async () => {
|
|
206
|
-
// given
|
|
207
|
-
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-env-"));
|
|
208
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-env-home-"));
|
|
209
|
-
const logPath = join(homeDir, "child-env.jsonl");
|
|
210
|
-
const originalOpenAiKey = process.env["OPENAI_API_KEY"];
|
|
211
|
-
process.env["OPENAI_API_KEY"] = "sk-test-secret";
|
|
212
|
-
|
|
213
|
-
try {
|
|
214
|
-
const fakeCodegraphScript = [
|
|
215
|
-
"const fs = require('node:fs');",
|
|
216
|
-
`fs.appendFileSync(${JSON.stringify(logPath)}, JSON.stringify({install:process.env.CODEGRAPH_INSTALL_DIR,openai:process.env.OPENAI_API_KEY}) + '\\n');`,
|
|
217
|
-
"fs.mkdirSync('.codegraph', { recursive: true });",
|
|
218
|
-
"fs.writeFileSync('.codegraph/codegraph.db', 'fixture');",
|
|
219
|
-
].join("");
|
|
220
|
-
|
|
221
|
-
// when
|
|
222
|
-
const result = await runCodegraphSessionStartWorker({
|
|
223
|
-
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
224
|
-
cwd: workspace,
|
|
225
|
-
env: { HOME: homeDir },
|
|
226
|
-
logOutcome: () => undefined,
|
|
227
|
-
nodeVersion: "22.14.0",
|
|
228
|
-
deps: {
|
|
229
|
-
ensureGitignored: () => true,
|
|
230
|
-
ensureProvisioned: () => {
|
|
231
|
-
throw new Error("provisioning should not run when command is resolved");
|
|
232
|
-
},
|
|
233
|
-
prepareWorkspace: () => ({
|
|
234
|
-
dataDir: join(homeDir, ".omo/codegraph/projects/test"),
|
|
235
|
-
dataRoot: join(homeDir, ".omo/codegraph"),
|
|
236
|
-
linked: true,
|
|
237
|
-
mode: "global-linked",
|
|
238
|
-
projectLink: join(workspace, ".codegraph"),
|
|
239
|
-
}),
|
|
240
|
-
resolveCommand: () => ({ argsPrefix: ["-e", fakeCodegraphScript], command: process.execPath, exists: true, source: "bundled" }),
|
|
241
|
-
},
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
// then
|
|
245
|
-
expect(result).toEqual({ action: "initialized" });
|
|
246
|
-
const captured = readFileSync(logPath, "utf8")
|
|
247
|
-
.trim()
|
|
248
|
-
.split("\n")
|
|
249
|
-
.map((line) => JSON.parse(line));
|
|
250
|
-
expect(captured).toEqual([{ install: join(homeDir, ".omo", "codegraph") }]);
|
|
251
|
-
} finally {
|
|
252
|
-
if (originalOpenAiKey === undefined) delete process.env["OPENAI_API_KEY"];
|
|
253
|
-
else process.env["OPENAI_API_KEY"] = originalOpenAiKey;
|
|
254
|
-
rmSync(workspace, { recursive: true, force: true });
|
|
255
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
256
|
-
}
|
|
257
|
-
});
|
|
258
|
-
});
|