oh-my-opencode 4.19.1 → 4.19.3
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/command/publish.md +95 -28
- package/.agents/skills/publish/SKILL.md +20 -6
- package/.opencode/command/publish.md +95 -28
- package/README.ja.md +2 -2
- package/README.ko.md +2 -2
- package/README.md +2 -2
- package/README.ru.md +2 -2
- package/README.zh-cn.md +2 -2
- package/THIRD-PARTY-NOTICES.md +7 -7
- package/dist/agents/atlas/agent.d.ts +4 -2
- package/dist/agents/explore.d.ts +4 -2
- package/dist/agents/hephaestus/agent.d.ts +4 -2
- package/dist/agents/librarian.d.ts +4 -2
- package/dist/agents/metis.d.ts +4 -2
- package/dist/agents/momus.d.ts +3 -2
- package/dist/agents/multimodal-looker.d.ts +4 -2
- package/dist/agents/oracle.d.ts +4 -2
- package/dist/agents/sisyphus/claude-opus-5.d.ts +33 -0
- package/dist/agents/sisyphus/index.d.ts +2 -0
- package/dist/agents/sisyphus-agent-factory.d.ts +5 -2
- package/dist/agents/sisyphus-junior/agent.d.ts +4 -1
- package/dist/agents/sisyphus-runtime-prompt-reconciler.d.ts +1 -1
- package/dist/agents/types.d.ts +2 -2
- package/dist/cli/config-migrate.d.ts +8 -0
- package/dist/cli/doctor/checks/legacy-config-leftovers.d.ts +10 -0
- package/dist/cli/doctor/checks/model-resolution-config.d.ts +1 -1
- package/dist/cli/doctor/checks/tools-lsp.d.ts +1 -1
- package/dist/cli/doctor/framework/constants.d.ts +1 -1
- package/dist/cli/index.js +95391 -88524
- package/dist/cli-node/index.js +95504 -88637
- package/dist/config/schema/agent-names.d.ts +26 -26
- package/dist/config/schema/agent-overrides.d.ts +400 -400
- package/dist/config/schema/browser-automation.d.ts +2 -2
- package/dist/config/schema/categories.d.ts +36 -36
- package/dist/config/schema/commands.d.ts +2 -2
- package/dist/config/schema/dynamic-context-pruning.d.ts +1 -1
- package/dist/config/schema/experimental.d.ts +1 -1
- package/dist/config/schema/fallback-models.d.ts +25 -25
- package/dist/config/schema/hooks.d.ts +43 -43
- package/dist/config/schema/internal/permission.d.ts +9 -9
- package/dist/config/schema/keyword-detector.d.ts +6 -6
- package/dist/config/schema/oh-my-opencode-config.d.ts +402 -402
- package/dist/config/schema/tmux.d.ts +6 -6
- package/dist/config/validate.d.ts +2 -1
- package/dist/config-migration/deep-diff.d.ts +1 -0
- package/dist/config-migration/discovery-paths.d.ts +11 -0
- package/dist/config-migration/discovery-roots.d.ts +7 -0
- package/dist/config-migration/discovery.d.ts +4 -0
- package/dist/config-migration/index.d.ts +9 -0
- package/dist/config-migration/legacy-history.d.ts +3 -0
- package/dist/config-migration/migration-executor.d.ts +4 -0
- package/dist/config-migration/migration-plans.d.ts +14 -0
- package/dist/config-migration/record-values.d.ts +4 -0
- package/dist/config-migration/schema-url.d.ts +1 -0
- package/dist/config-migration/transform-config-jsonc.d.ts +2 -0
- package/dist/config-migration/transform-opencode.d.ts +2 -0
- package/dist/config-migration/transform-types.d.ts +24 -0
- package/dist/config-migration/types.d.ts +39 -0
- package/dist/create-hooks.d.ts +35 -35
- package/dist/features/background-agent/spawner/tmux-callback-invoker.d.ts +11 -0
- package/dist/features/builtin-commands/templates/hyperplan.d.ts +1 -1
- package/dist/features/builtin-commands/templates/start-work.d.ts +1 -1
- package/dist/features/claude-tasks/types.d.ts +4 -4
- package/dist/features/team-mode/team-runtime/shutdown-helpers.d.ts +1 -1
- package/dist/features/team-mode/team-runtime/shutdown-test-fixtures.d.ts +4 -4
- package/dist/features/team-mode/tools/lifecycle-test-fixture.d.ts +42 -42
- package/dist/features/tmux-subagent/environment-eligibility.d.ts +2 -0
- package/dist/features/tmux-subagent/index.d.ts +1 -0
- package/dist/features/tmux-subagent/tracked-session-state.d.ts +1 -0
- package/dist/features/tui-sidebar/snapshot-schema.d.ts +6 -6
- package/dist/help/schema/acp.d.ts +3 -3
- package/dist/help/schema/doctor.d.ts +4 -4
- package/dist/help/schema/status.d.ts +3 -3
- package/dist/hooks/auto-update-checker/constants.d.ts +3 -3
- package/dist/hooks/goal/types.d.ts +5 -5
- package/dist/hooks/non-interactive-env/constants.d.ts +4 -1
- package/dist/hooks/start-work/parse-user-request.d.ts +2 -0
- package/dist/hooks/start-work/worktree-block.d.ts +5 -0
- package/dist/index.js +35450 -28257
- package/dist/mcp/types.d.ts +3 -3
- package/dist/oh-my-opencode.schema.json +1 -1
- package/dist/plugin/chat-message/loop-commands.d.ts +1 -0
- package/dist/plugin/command-execute-before.d.ts +3 -3
- package/dist/plugin/hooks/create-core-hooks.d.ts +25 -25
- package/dist/plugin-config/omo-config-chain.d.ts +14 -0
- package/dist/plugin-config/unknown-key-diagnostics.d.ts +5 -0
- package/dist/plugin-config.d.ts +2 -2
- package/dist/shared/agent-display-names.d.ts +1 -1
- package/dist/shared/jsonc-parser.d.ts +1 -1
- package/dist/shared/migration.d.ts +5 -1
- package/dist/shared/opencode-config-dir-types.d.ts +0 -1
- package/dist/shared/plugin-identity.d.ts +6 -8
- package/dist/shared/project-discovery-dirs.d.ts +0 -1
- package/dist/shared/tmux/tmux-utils/environment.d.ts +1 -1
- package/dist/shared/tmux/tmux-utils.d.ts +1 -1
- package/dist/shared/typescript-native-source-parser.d.ts +7 -0
- package/dist/skills/coding-agent-sessions/SKILL.md +5 -2
- package/dist/skills/coding-agent-sessions/references/all-platforms.md +3 -1
- package/dist/skills/coding-agent-sessions/references/senpi.md +15 -5
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
- package/dist/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
- package/dist/skills/debugging/SKILL.md +2 -1
- package/dist/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
- package/dist/skills/frontend/ATTRIBUTION.md +7 -0
- package/dist/skills/frontend/SKILL.md +4 -1
- package/dist/skills/frontend/references/design/README.md +8 -0
- package/dist/skills/frontend/references/design/_INDEX.md +14 -1
- package/dist/skills/frontend/references/design/interaction-skill.md +144 -0
- package/dist/skills/programming/SKILL.md +11 -1
- package/dist/skills/programming/references/logging.md +6 -1
- package/dist/skills/programming/scripts/typescript/check-no-excuse-rules.ts +51 -17
- package/dist/skills/start-work/SKILL.md +12 -2
- package/dist/skills/ulw-plan/SKILL.md +1 -1
- package/dist/skills/ulw-plan/references/full-workflow.md +12 -1
- package/dist/skills/ulw-plan/references/intent-clear.md +1 -1
- package/dist/startup-migration.d.ts +28 -0
- package/dist/testing/create-plugin-module.d.ts +4 -0
- package/dist/tools/task/types.d.ts +10 -10
- package/dist/tui.js +31812 -26849
- package/package.json +14 -14
- package/packages/lsp-core/src/lsp/client-diagnostics-freshness.integration.test.ts +21 -5
- package/packages/lsp-core/src/lsp/fixtures/workspace-edit-server.mjs +11 -2
- package/packages/omo-codex/THIRD-PARTY-NOTICES.md +2 -2
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +8 -4
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +11 -5
- package/packages/omo-codex/plugin/components/codegraph/NOTICE +1 -1
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +10272 -2600
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +7341 -562
- package/packages/omo-codex/plugin/components/codegraph/package.json +2 -2
- package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +33 -0
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +36 -10
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +170 -186
- package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +34 -0
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +22 -5
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +106 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +145 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +21 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +139 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +15 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +32 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +109 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +148 -0
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +126 -186
- package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +9 -4
- package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +160 -0
- package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +12 -110
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +29 -20
- package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +3 -3
- package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +2 -2
- package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +11 -5
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +3 -3
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +2 -1
- package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +50 -5
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +3 -2
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +24 -13
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +70 -13
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +58 -0
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +104 -0
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +4 -2
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +116 -0
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +114 -119
- 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/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/dist/cli.js +31 -14
- 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/start-work-continuation/directive.md +1 -1
- package/packages/omo-codex/plugin/components/start-work-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/start-work-continuation/package.json +1 -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/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/directive.md +12 -7
- 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/ultrawork/SKILL.md +12 -7
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/full-workflow.md +12 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/references/intent-clear.md +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +12 -7
- 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/SKILL.md +19 -1
- 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-codegraph-init-guidance.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-checking-codegraph-bootstrap.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-start-work-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-start-work-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 +42 -41
- package/packages/omo-codex/plugin/package.json +1 -1
- package/packages/omo-codex/plugin/shared/src/config-loader.ts +165 -16
- package/packages/omo-codex/plugin/shared/src/config-migration.ts +162 -0
- package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +196 -18
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/SKILL.md +5 -2
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/all-platforms.md +3 -1
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/references/senpi.md +15 -5
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
- package/packages/omo-codex/plugin/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
- package/packages/omo-codex/plugin/skills/debugging/SKILL.md +2 -1
- package/packages/omo-codex/plugin/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
- package/packages/omo-codex/plugin/skills/frontend/ATTRIBUTION.md +7 -0
- package/packages/omo-codex/plugin/skills/frontend/SKILL.md +4 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/README.md +8 -0
- package/packages/omo-codex/plugin/skills/frontend/references/design/_INDEX.md +14 -1
- package/packages/omo-codex/plugin/skills/frontend/references/design/interaction-skill.md +144 -0
- package/packages/omo-codex/plugin/skills/programming/SKILL.md +11 -1
- package/packages/omo-codex/plugin/skills/programming/references/logging.md +6 -1
- package/packages/omo-codex/plugin/skills/programming/scripts/typescript/check-no-excuse-rules.ts +51 -17
- package/packages/omo-codex/plugin/skills/start-work/SKILL.md +12 -2
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +12 -7
- package/packages/omo-codex/plugin/skills/ulw-loop/SKILL.md +19 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/full-workflow.md +12 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/references/intent-clear.md +1 -1
- package/packages/omo-codex/plugin/test/sync-skills-orchestration.test.mjs +22 -0
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +1 -1
- package/packages/shared-skills/skills/coding-agent-sessions/SKILL.md +5 -2
- package/packages/shared-skills/skills/coding-agent-sessions/references/all-platforms.md +3 -1
- package/packages/shared-skills/skills/coding-agent-sessions/references/senpi.md +15 -5
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/pi_family.py +46 -0
- package/packages/shared-skills/skills/coding-agent-sessions/scripts/agent_sessions/scanners.py +19 -10
- package/packages/shared-skills/skills/debugging/SKILL.md +2 -1
- package/packages/shared-skills/skills/debugging/references/methodology/03-flaky-triage.md +47 -0
- package/packages/shared-skills/skills/frontend/ATTRIBUTION.md +7 -0
- package/packages/shared-skills/skills/frontend/SKILL.md +4 -1
- package/packages/shared-skills/skills/frontend/references/design/README.md +8 -0
- package/packages/shared-skills/skills/frontend/references/design/_INDEX.md +14 -1
- package/packages/shared-skills/skills/frontend/references/design/interaction-skill.md +144 -0
- package/packages/shared-skills/skills/programming/SKILL.md +11 -1
- package/packages/shared-skills/skills/programming/references/logging.md +6 -1
- package/packages/shared-skills/skills/programming/scripts/typescript/check-no-excuse-rules.ts +51 -17
- package/packages/shared-skills/skills/start-work/SKILL.md +12 -2
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +1 -1
- package/packages/shared-skills/skills/ulw-plan/references/full-workflow.md +12 -1
- package/packages/shared-skills/skills/ulw-plan/references/intent-clear.md +1 -1
- package/dist/plugin-config/layered-config-loader.d.ts +0 -2
- package/dist/plugin-config/single-config-loader.d.ts +0 -4
- package/dist/shared/migrate-legacy-config-file.d.ts +0 -1
- package/dist/shared/migration/config-migration.d.ts +0 -1
|
@@ -0,0 +1,160 @@
|
|
|
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, resolve } from "node:path";
|
|
5
|
+
import { Readable } from "node:stream";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
import {
|
|
9
|
+
executeCodegraphSessionStartHook,
|
|
10
|
+
type CodegraphSessionStartOutcome,
|
|
11
|
+
type WorkerSpawnInvocation,
|
|
12
|
+
} from "../src/hook.ts";
|
|
13
|
+
import { recordSessionStartFailure } from "../src/session-start-cooldown.ts";
|
|
14
|
+
|
|
15
|
+
const pluginRoot = resolve(fileURLToPath(new URL("../../..", import.meta.url)));
|
|
16
|
+
|
|
17
|
+
function createAllowedWorkspace(prefix: string): string {
|
|
18
|
+
return mkdtempSync(join(pluginRoot, `.tmp-${prefix}-`));
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
describe("CodeGraph SessionStart spawn guards", () => {
|
|
22
|
+
it("#given an inconclusive probe timeout #when SessionStart runs #then timeout is not treated as uninitialized", async () => {
|
|
23
|
+
// given
|
|
24
|
+
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-timeout-home-"));
|
|
25
|
+
const workspace = createAllowedWorkspace("codegraph-timeout-workspace");
|
|
26
|
+
const spawned: WorkerSpawnInvocation[] = [];
|
|
27
|
+
try {
|
|
28
|
+
// when
|
|
29
|
+
const result = await executeCodegraphSessionStartHook({
|
|
30
|
+
ancestorProbe: () => ({ kind: "inconclusive", reason: "status timed out" }),
|
|
31
|
+
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
32
|
+
cwd: workspace,
|
|
33
|
+
env: { HOME: homeDir },
|
|
34
|
+
spawnWorker: (invocation) => spawned.push(invocation),
|
|
35
|
+
stdin: Readable.from(["{}"]),
|
|
36
|
+
sweepZombies: () => undefined,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// then
|
|
40
|
+
expect(result).toEqual({ action: "skipped-inconclusive", exitCode: 0 });
|
|
41
|
+
expect(spawned).toEqual([]);
|
|
42
|
+
} finally {
|
|
43
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
44
|
+
rmSync(workspace, { recursive: true, force: true });
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it("#given one hook already owns the project lock #when a second SessionStart runs #then it records skipped-locked without spawning", async () => {
|
|
49
|
+
// given
|
|
50
|
+
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-dedup-home-"));
|
|
51
|
+
const workspace = createAllowedWorkspace("codegraph-dedup-workspace");
|
|
52
|
+
const outcomes: CodegraphSessionStartOutcome[] = [];
|
|
53
|
+
const spawned: WorkerSpawnInvocation[] = [];
|
|
54
|
+
const options = {
|
|
55
|
+
ancestorProbe: () => ({ kind: "uninitialized" } as const),
|
|
56
|
+
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
57
|
+
cwd: workspace,
|
|
58
|
+
env: { HOME: homeDir },
|
|
59
|
+
logOutcome: (outcome: CodegraphSessionStartOutcome) => outcomes.push(outcome),
|
|
60
|
+
spawnWorker: (invocation: WorkerSpawnInvocation) => {
|
|
61
|
+
spawned.push(invocation);
|
|
62
|
+
},
|
|
63
|
+
stdin: Readable.from(["{}"]),
|
|
64
|
+
sweepZombies: () => undefined,
|
|
65
|
+
};
|
|
66
|
+
try {
|
|
67
|
+
await executeCodegraphSessionStartHook(options);
|
|
68
|
+
|
|
69
|
+
// when
|
|
70
|
+
const second = await executeCodegraphSessionStartHook({ ...options, stdin: Readable.from(["{}"]) });
|
|
71
|
+
|
|
72
|
+
// then
|
|
73
|
+
expect(second).toEqual({ action: "skipped-locked", exitCode: 0 });
|
|
74
|
+
expect(spawned).toHaveLength(1);
|
|
75
|
+
expect(outcomes).toContainEqual({ action: "skipped-locked", projectRoot: workspace });
|
|
76
|
+
} finally {
|
|
77
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
78
|
+
rmSync(workspace, { recursive: true, force: true });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it("#given a failed worker cooldown #when SessionStart retries before and after expiry #then only the expired retry spawns", async () => {
|
|
83
|
+
// given
|
|
84
|
+
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-cooldown-hook-home-"));
|
|
85
|
+
const workspace = createAllowedWorkspace("codegraph-cooldown-hook-workspace");
|
|
86
|
+
const outcomes: CodegraphSessionStartOutcome[] = [];
|
|
87
|
+
const spawned: WorkerSpawnInvocation[] = [];
|
|
88
|
+
try {
|
|
89
|
+
recordSessionStartFailure({
|
|
90
|
+
action: "failed",
|
|
91
|
+
baseCooldownMs: 60_000,
|
|
92
|
+
homeDir,
|
|
93
|
+
nowMs: 1_000,
|
|
94
|
+
projectRoot: workspace,
|
|
95
|
+
});
|
|
96
|
+
const baseOptions = {
|
|
97
|
+
ancestorProbe: () => ({ kind: "uninitialized" } as const),
|
|
98
|
+
config: { codegraph: { enabled: true, session_start_cooldown_ms: 60_000 }, sources: [], warnings: [] },
|
|
99
|
+
cwd: workspace,
|
|
100
|
+
env: { HOME: homeDir },
|
|
101
|
+
logOutcome: (outcome: CodegraphSessionStartOutcome) => outcomes.push(outcome),
|
|
102
|
+
spawnWorker: (invocation: WorkerSpawnInvocation) => {
|
|
103
|
+
spawned.push(invocation);
|
|
104
|
+
},
|
|
105
|
+
sweepZombies: () => undefined,
|
|
106
|
+
};
|
|
107
|
+
|
|
108
|
+
// when
|
|
109
|
+
const suppressed = await executeCodegraphSessionStartHook({ ...baseOptions, nowMs: 60_999, stdin: Readable.from(["{}"]) });
|
|
110
|
+
const expired = await executeCodegraphSessionStartHook({ ...baseOptions, nowMs: 61_000, stdin: Readable.from(["{}"]) });
|
|
111
|
+
|
|
112
|
+
// then
|
|
113
|
+
expect(suppressed).toEqual({ action: "skipped-cooldown", exitCode: 0 });
|
|
114
|
+
expect(expired).toEqual({ action: "spawned", exitCode: 0 });
|
|
115
|
+
expect(spawned).toHaveLength(1);
|
|
116
|
+
expect(outcomes).toContainEqual({
|
|
117
|
+
action: "skipped-cooldown",
|
|
118
|
+
cooldownUntil: 61_000,
|
|
119
|
+
failureCount: 1,
|
|
120
|
+
projectRoot: workspace,
|
|
121
|
+
});
|
|
122
|
+
} finally {
|
|
123
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
124
|
+
rmSync(workspace, { recursive: true, force: true });
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it("#given an ancestor has a CodeGraph database #when SessionStart runs in a nested project #then it records skipped-nested-root", async () => {
|
|
129
|
+
// given
|
|
130
|
+
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-nested-home-"));
|
|
131
|
+
const ancestorRoot = createAllowedWorkspace("codegraph-nested-ancestor");
|
|
132
|
+
const workspace = join(ancestorRoot, "apps", "server");
|
|
133
|
+
const outcomes: CodegraphSessionStartOutcome[] = [];
|
|
134
|
+
const spawned: WorkerSpawnInvocation[] = [];
|
|
135
|
+
try {
|
|
136
|
+
mkdirSync(join(ancestorRoot, ".codegraph"), { recursive: true });
|
|
137
|
+
mkdirSync(workspace, { recursive: true });
|
|
138
|
+
writeFileSync(join(ancestorRoot, ".codegraph", "codegraph.db"), "fixture");
|
|
139
|
+
|
|
140
|
+
// when
|
|
141
|
+
const result = await executeCodegraphSessionStartHook({
|
|
142
|
+
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
143
|
+
cwd: workspace,
|
|
144
|
+
env: { HOME: homeDir },
|
|
145
|
+
logOutcome: (outcome) => outcomes.push(outcome),
|
|
146
|
+
spawnWorker: (invocation) => spawned.push(invocation),
|
|
147
|
+
stdin: Readable.from(["{}"]),
|
|
148
|
+
sweepZombies: () => undefined,
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// then
|
|
152
|
+
expect(result).toEqual({ action: "skipped-nested-root", exitCode: 0 });
|
|
153
|
+
expect(spawned).toEqual([]);
|
|
154
|
+
expect(outcomes).toContainEqual({ action: "skipped-nested-root", ancestorRoot, projectRoot: workspace });
|
|
155
|
+
} finally {
|
|
156
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
157
|
+
rmSync(ancestorRoot, { recursive: true, force: true });
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import {
|
|
2
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join, resolve } from "node:path";
|
|
5
5
|
import { Readable } from "node:stream";
|
|
@@ -9,94 +9,33 @@ import { executeCodegraphSessionStartHook, type WorkerSpawnInvocation } from "..
|
|
|
9
9
|
|
|
10
10
|
const pluginRoot = resolve(fileURLToPath(new URL("../../..", import.meta.url)));
|
|
11
11
|
|
|
12
|
-
// Observed verbatim from a REAL codegraph 1.4.1 binary running `status --json` (exit 0)
|
|
13
|
-
// against a project store built by a REAL codegraph 1.0.1 binary
|
|
14
|
-
// (see .omo/evidence/codegraph-daemon-process-hygiene/task-2-store-upgrade.txt).
|
|
15
|
-
const MIGRATED_1_0_1_STORE_STATUS_JSON = JSON.stringify({
|
|
16
|
-
initialized: true,
|
|
17
|
-
version: "1.4.1",
|
|
18
|
-
projectPath: "/private/tmp/cg-task2/fixture",
|
|
19
|
-
indexPath: "/private/tmp/cg-task2/fixture/.codegraph",
|
|
20
|
-
lastIndexed: "2026-07-21T04:28:09.593Z",
|
|
21
|
-
fileCount: 2,
|
|
22
|
-
nodeCount: 5,
|
|
23
|
-
edgeCount: 4,
|
|
24
|
-
dbSizeBytes: 159744,
|
|
25
|
-
backend: "node-sqlite",
|
|
26
|
-
journalMode: "wal",
|
|
27
|
-
nodesByKind: { file: 2, function: 3 },
|
|
28
|
-
languages: ["typescript"],
|
|
29
|
-
pendingChanges: { added: 0, modified: 0, removed: 0 },
|
|
30
|
-
worktreeMismatch: null,
|
|
31
|
-
index: {
|
|
32
|
-
builtWithVersion: "1.0.1",
|
|
33
|
-
builtWithExtractionVersion: 24,
|
|
34
|
-
currentExtractionVersion: 24,
|
|
35
|
-
reindexRecommended: false,
|
|
36
|
-
state: null,
|
|
37
|
-
pendingRefs: 0,
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
|
|
41
12
|
function createAllowedWorkspace(prefix: string): string {
|
|
42
13
|
return mkdtempSync(join(pluginRoot, `.tmp-${prefix}-`));
|
|
43
14
|
}
|
|
44
15
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
function createFakeCodegraphBin(scripts: { readonly posix: string; readonly win32: string }): { readonly binPath: string; readonly dir: string } {
|
|
48
|
-
const dir = mkdtempSync(join(tmpdir(), "omo-codegraph-fake-bin-"));
|
|
49
|
-
if (process.platform === "win32") {
|
|
50
|
-
const binPath = join(dir, "codegraph.cmd");
|
|
51
|
-
writeFileSync(binPath, scripts.win32);
|
|
52
|
-
return { binPath, dir };
|
|
53
|
-
}
|
|
54
|
-
const binPath = join(dir, "codegraph");
|
|
55
|
-
writeFileSync(binPath, scripts.posix, { mode: 0o755 });
|
|
56
|
-
chmodSync(binPath, 0o755);
|
|
57
|
-
return { binPath, dir };
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// Keep the probe hermetic on POSIX but viable on win32: resolveCodegraphCommandInvocation wraps
|
|
61
|
-
// the fake .cmd in `cmd.exe /d /s /c`, and Windows can only resolve cmd.exe when the child env
|
|
62
|
-
// carries the real system PATH (System32) plus SystemRoot (both whitelisted in SAFE_AMBIENT_ENV_KEYS).
|
|
63
|
-
// A POSIX-only PATH makes the probe spawn fail, so the hook reports not-initialized and spawns.
|
|
64
|
-
function probeEnv(homeDir: string, binPath: string): Record<string, string> {
|
|
65
|
-
if (process.platform === "win32") {
|
|
66
|
-
const env: Record<string, string> = {
|
|
67
|
-
HOME: homeDir,
|
|
68
|
-
OMO_CODEGRAPH_BIN: binPath,
|
|
69
|
-
};
|
|
70
|
-
if (process.env["PATH"] !== undefined) env["PATH"] = process.env["PATH"];
|
|
71
|
-
if (process.env["SystemRoot"] !== undefined) env["SystemRoot"] = process.env["SystemRoot"];
|
|
72
|
-
return env;
|
|
73
|
-
}
|
|
74
|
-
return { HOME: homeDir, OMO_CODEGRAPH_BIN: binPath, PATH: "/usr/bin:/bin" };
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
describe("CodeGraph SessionStart hook with a 1.0.1-era project store under the 1.4.1 binary", () => {
|
|
78
|
-
it("#given a real 1.4.1 status payload for a migrated 1.0.1 store #when SessionStart probes via the default probe #then it stays silent without spawning a re-init worker", async () => {
|
|
16
|
+
describe("CodeGraph SessionStart hook with a migrated 1.0.1 project store under CodeGraph 1.5.0", () => {
|
|
17
|
+
it("#given the migrated store has an exact database #when SessionStart runs #then it never invokes the CodeGraph CLI", async () => {
|
|
79
18
|
// given
|
|
80
19
|
const stdout: string[] = [];
|
|
81
20
|
const spawned: WorkerSpawnInvocation[] = [];
|
|
82
21
|
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-upgrade-home-"));
|
|
83
|
-
// The payload is a single JSON line with no cmd metacharacters (% ^ & < > |), so a plain echo is safe.
|
|
84
|
-
const fake = createFakeCodegraphBin({
|
|
85
|
-
posix: `#!/bin/sh\nprintf '%s\\n' '${MIGRATED_1_0_1_STORE_STATUS_JSON}'\n`,
|
|
86
|
-
win32: `@echo off\r\n@echo ${MIGRATED_1_0_1_STORE_STATUS_JSON}\r\n`,
|
|
87
|
-
});
|
|
88
22
|
const workspace = createAllowedWorkspace("codegraph-upgrade-workspace");
|
|
89
|
-
mkdirSync(join(workspace, ".codegraph"), { recursive: true });
|
|
90
|
-
|
|
91
23
|
try {
|
|
24
|
+
mkdirSync(join(workspace, ".codegraph"), { recursive: true });
|
|
25
|
+
writeFileSync(join(workspace, ".codegraph", "codegraph.db"), "migrated-store");
|
|
26
|
+
|
|
92
27
|
// when
|
|
93
28
|
const result = await executeCodegraphSessionStartHook({
|
|
29
|
+
ancestorProbe: () => {
|
|
30
|
+
throw new Error("the exact database check must be the complete fast path");
|
|
31
|
+
},
|
|
94
32
|
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
95
33
|
cwd: workspace,
|
|
96
|
-
env:
|
|
34
|
+
env: { HOME: homeDir },
|
|
97
35
|
stdin: Readable.from(["{}"]),
|
|
98
36
|
stdout: { write: (chunk) => stdout.push(chunk) },
|
|
99
37
|
spawnWorker: (invocation) => spawned.push(invocation),
|
|
38
|
+
sweepZombies: () => undefined,
|
|
100
39
|
});
|
|
101
40
|
|
|
102
41
|
// then
|
|
@@ -105,44 +44,7 @@ describe("CodeGraph SessionStart hook with a 1.0.1-era project store under the 1
|
|
|
105
44
|
expect(stdout.join("")).toBe("");
|
|
106
45
|
} finally {
|
|
107
46
|
rmSync(homeDir, { recursive: true, force: true });
|
|
108
|
-
rmSync(
|
|
109
|
-
rmSync(workspace, { recursive: true, force: true, maxRetries: 10, retryDelay: 500 });
|
|
110
|
-
}
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it("#given the status probe hangs past its 2s timeout #when SessionStart fires #then it exits zero promptly and spawns at most one bounded worker", async () => {
|
|
114
|
-
// given
|
|
115
|
-
const stdout: string[] = [];
|
|
116
|
-
const spawned: WorkerSpawnInvocation[] = [];
|
|
117
|
-
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-slow-home-"));
|
|
118
|
-
const fake = createFakeCodegraphBin({
|
|
119
|
-
posix: "#!/bin/sh\nsleep 30\n",
|
|
120
|
-
win32: "@echo off\r\nset /p _probe_hang=\r\n",
|
|
121
|
-
});
|
|
122
|
-
const workspace = createAllowedWorkspace("codegraph-slow-probe-workspace");
|
|
123
|
-
|
|
124
|
-
try {
|
|
125
|
-
// when
|
|
126
|
-
const startedAt = Date.now();
|
|
127
|
-
const result = await executeCodegraphSessionStartHook({
|
|
128
|
-
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
129
|
-
cwd: workspace,
|
|
130
|
-
env: probeEnv(homeDir, fake.binPath),
|
|
131
|
-
stdin: Readable.from(["{}"]),
|
|
132
|
-
stdout: { write: (chunk) => stdout.push(chunk) },
|
|
133
|
-
spawnWorker: (invocation) => spawned.push(invocation),
|
|
134
|
-
});
|
|
135
|
-
const elapsedMs = Date.now() - startedAt;
|
|
136
|
-
|
|
137
|
-
// then
|
|
138
|
-
expect(result.exitCode).toBe(0);
|
|
139
|
-
expect(result.action).toBe("spawned");
|
|
140
|
-
expect(spawned).toHaveLength(1);
|
|
141
|
-
expect(elapsedMs).toBeLessThan(15_000);
|
|
142
|
-
} finally {
|
|
143
|
-
rmSync(homeDir, { recursive: true, force: true });
|
|
144
|
-
rmSync(fake.dir, { recursive: true, force: true });
|
|
145
|
-
rmSync(workspace, { recursive: true, force: true, maxRetries: 10, retryDelay: 500 });
|
|
47
|
+
rmSync(workspace, { recursive: true, force: true });
|
|
146
48
|
}
|
|
147
49
|
});
|
|
148
50
|
});
|
|
@@ -39,8 +39,9 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
39
39
|
env: { HOME: homeDir },
|
|
40
40
|
stdin: Readable.from(["{}"]),
|
|
41
41
|
stdout: { write: (chunk) => stdout.push(chunk) },
|
|
42
|
+
ancestorProbe: () => ({ kind: "uninitialized" }),
|
|
42
43
|
spawnWorker: (invocation) => spawned.push(invocation),
|
|
43
|
-
|
|
44
|
+
sweepZombies: () => undefined,
|
|
44
45
|
});
|
|
45
46
|
|
|
46
47
|
// then
|
|
@@ -132,7 +133,7 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
132
133
|
try {
|
|
133
134
|
mkdirSync(join(homeDir, ".omo"), { recursive: true });
|
|
134
135
|
writeFileSync(
|
|
135
|
-
join(homeDir, ".omo", "
|
|
136
|
+
join(homeDir, ".omo", "omo.jsonc"),
|
|
136
137
|
'{ "codegraph": { "enabled": true }, "[codex]": { "codegraph": { "enabled": false } } }\n',
|
|
137
138
|
);
|
|
138
139
|
|
|
@@ -164,8 +165,8 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
164
165
|
try {
|
|
165
166
|
mkdirSync(join(homeDir, ".omo"), { recursive: true });
|
|
166
167
|
mkdirSync(join(workspace, ".omo"), { recursive: true });
|
|
167
|
-
writeFileSync(join(homeDir, ".omo", "
|
|
168
|
-
writeFileSync(join(workspace, ".omo", "
|
|
168
|
+
writeFileSync(join(homeDir, ".omo", "omo.jsonc"), '{ "codegraph": { "enabled": true } }\n');
|
|
169
|
+
writeFileSync(join(workspace, ".omo", "omo.jsonc"), '{ "[codex]": { "codegraph": { "enabled": false } } }\n');
|
|
169
170
|
|
|
170
171
|
// when
|
|
171
172
|
const result = await executeCodegraphSessionStartHook({
|
|
@@ -193,7 +194,7 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
193
194
|
const spawned: WorkerSpawnInvocation[] = [];
|
|
194
195
|
try {
|
|
195
196
|
mkdirSync(join(homeDir, ".omo"), { recursive: true });
|
|
196
|
-
writeFileSync(join(homeDir, ".omo", "
|
|
197
|
+
writeFileSync(join(homeDir, ".omo", "omo.jsonc"), '{ "codegraph": { "enabled": true } }\n');
|
|
197
198
|
|
|
198
199
|
// when
|
|
199
200
|
const result = await executeCodegraphSessionStartHook({
|
|
@@ -216,32 +217,32 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
216
217
|
const stdout: string[] = [];
|
|
217
218
|
const spawned: WorkerSpawnInvocation[] = [];
|
|
218
219
|
const workspace = createAllowedWorkspace("codegraph-workspace");
|
|
220
|
+
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-spawn-home-"));
|
|
219
221
|
|
|
220
222
|
try {
|
|
221
223
|
// when
|
|
222
224
|
const result = await executeCodegraphSessionStartHook({
|
|
225
|
+
ancestorProbe: () => ({ kind: "uninitialized" }),
|
|
223
226
|
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
224
227
|
cwd: workspace,
|
|
225
|
-
env: { HOME:
|
|
228
|
+
env: { HOME: homeDir, KEEP: "1", OPENAI_API_KEY: "sk-test-secret" },
|
|
226
229
|
stdin: Readable.from(["{}"]),
|
|
227
230
|
stdout: { write: (chunk) => stdout.push(chunk) },
|
|
228
|
-
spawnWorker: (invocation) =>
|
|
229
|
-
|
|
231
|
+
spawnWorker: (invocation) => {
|
|
232
|
+
spawned.push(invocation);
|
|
233
|
+
},
|
|
234
|
+
sweepZombies: () => undefined,
|
|
230
235
|
workerCliPath: "/plugin/components/codegraph/dist/cli.js",
|
|
231
236
|
});
|
|
232
237
|
|
|
233
238
|
// then
|
|
234
239
|
expect(result).toEqual({ action: "spawned", exitCode: 0 });
|
|
235
|
-
expect(spawned).
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
OMO_CODEGRAPH_SESSION_START_CWD: workspace,
|
|
242
|
-
},
|
|
243
|
-
},
|
|
244
|
-
]);
|
|
240
|
+
expect(spawned).toHaveLength(1);
|
|
241
|
+
expect(spawned[0]?.args).toEqual(["/plugin/components/codegraph/dist/cli.js", "hook", "session-start-worker"]);
|
|
242
|
+
expect(spawned[0]?.command).toBe(process.execPath);
|
|
243
|
+
expect(spawned[0]?.env["HOME"]).toBe(homeDir);
|
|
244
|
+
expect(spawned[0]?.env["OMO_CODEGRAPH_SESSION_START_CWD"]).toBe(workspace);
|
|
245
|
+
expect(spawned[0]?.env["OMO_CODEGRAPH_SESSION_START_LOCK_TOKEN"]).toMatch(/^[0-9a-f-]{36}$/);
|
|
245
246
|
expect(spawned[0]?.env["OPENAI_API_KEY"]).toBeUndefined();
|
|
246
247
|
expect(spawned[0]?.env["KEEP"]).toBeUndefined();
|
|
247
248
|
expect(JSON.parse(stdout.join(""))).toEqual({
|
|
@@ -251,6 +252,7 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
251
252
|
},
|
|
252
253
|
});
|
|
253
254
|
} finally {
|
|
255
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
254
256
|
rmSync(workspace, { recursive: true, force: true });
|
|
255
257
|
}
|
|
256
258
|
});
|
|
@@ -260,17 +262,23 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
260
262
|
const stdout: string[] = [];
|
|
261
263
|
const spawned: WorkerSpawnInvocation[] = [];
|
|
262
264
|
const workspace = createAllowedWorkspace("codegraph-initialized-workspace");
|
|
265
|
+
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-initialized-home-"));
|
|
263
266
|
|
|
264
267
|
try {
|
|
268
|
+
mkdirSync(join(workspace, ".codegraph"), { recursive: true });
|
|
269
|
+
writeFileSync(join(workspace, ".codegraph", "codegraph.db"), "fixture");
|
|
270
|
+
|
|
265
271
|
// when
|
|
266
272
|
const result = await executeCodegraphSessionStartHook({
|
|
273
|
+
ancestorProbe: () => {
|
|
274
|
+
throw new Error("an initialized exact root must not invoke any fallback probe");
|
|
275
|
+
},
|
|
267
276
|
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
268
277
|
cwd: workspace,
|
|
269
|
-
env: { HOME:
|
|
278
|
+
env: { HOME: homeDir, KEEP: "1" },
|
|
270
279
|
stdin: Readable.from(["{}"]),
|
|
271
280
|
stdout: { write: (chunk) => stdout.push(chunk) },
|
|
272
281
|
spawnWorker: (invocation) => spawned.push(invocation),
|
|
273
|
-
statusProbe: () => Promise.resolve(true),
|
|
274
282
|
});
|
|
275
283
|
|
|
276
284
|
// then
|
|
@@ -278,6 +286,7 @@ describe("CodeGraph SessionStart hook", () => {
|
|
|
278
286
|
expect(spawned).toEqual([]);
|
|
279
287
|
expect(stdout.join("")).toBe("");
|
|
280
288
|
} finally {
|
|
289
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
281
290
|
rmSync(workspace, { recursive: true, force: true });
|
|
282
291
|
}
|
|
283
292
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { chmodSync, writeFileSync } from "node:fs";
|
|
2
2
|
|
|
3
|
-
export const
|
|
3
|
+
export const CODEGRAPH_150_DEFAULT_TOOLS: readonly Record<string, unknown>[] = [
|
|
4
4
|
{
|
|
5
5
|
name: "codegraph_explore",
|
|
6
6
|
description:
|
|
@@ -41,10 +41,10 @@ export function writeFakeNewlineCodegraph(filePath: string): void {
|
|
|
41
41
|
"rl.on('line', (line) => {",
|
|
42
42
|
" const request = JSON.parse(line);",
|
|
43
43
|
" if (request.method === 'initialize') {",
|
|
44
|
-
" process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: { capabilities: { tools: { listChanged: false } }, protocolVersion: request.params.protocolVersion, serverInfo: { name: 'codegraph', version: '1.
|
|
44
|
+
" process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: { capabilities: { tools: { listChanged: false } }, protocolVersion: request.params.protocolVersion, serverInfo: { name: 'codegraph', version: '1.5.0' } } }) + '\\n');",
|
|
45
45
|
" }",
|
|
46
46
|
" if (request.method === 'tools/list') {",
|
|
47
|
-
` process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: { tools: ${JSON.stringify(
|
|
47
|
+
` process.stdout.write(JSON.stringify({ jsonrpc: '2.0', id: request.id, result: { tools: ${JSON.stringify(CODEGRAPH_150_DEFAULT_TOOLS)} } }) + '\\n');`,
|
|
48
48
|
" }",
|
|
49
49
|
"});",
|
|
50
50
|
].join("\n"),
|
|
@@ -43,7 +43,7 @@ describe("CodeGraph component runtime package metadata", () => {
|
|
|
43
43
|
const files = packageJson.files ?? [];
|
|
44
44
|
|
|
45
45
|
// then
|
|
46
|
-
expect(optionalDependencies["@colbymchenry/codegraph"]).toBe("1.
|
|
46
|
+
expect(optionalDependencies["@colbymchenry/codegraph"]).toBe("1.5.0");
|
|
47
47
|
expect(files).toContain("LICENSE");
|
|
48
48
|
expect(files).toContain("NODE-RUNTIME-LICENSES.md");
|
|
49
49
|
expect(files).toContain("NOTICE");
|
|
@@ -58,7 +58,7 @@ describe("CodeGraph component runtime package metadata", () => {
|
|
|
58
58
|
// given
|
|
59
59
|
const notice = readFileSync(resolve(componentRoot, "NOTICE"), "utf8");
|
|
60
60
|
|
|
61
|
-
expect(notice).toContain("@colbymchenry/codegraph@1.0
|
|
61
|
+
expect(notice).toContain("@colbymchenry/codegraph@1.5.0");
|
|
62
62
|
expect(notice).toContain("MIT license");
|
|
63
63
|
expect(notice).toContain("Node.js v24.16.0 runtime");
|
|
64
64
|
expect(notice).toContain("NODE-RUNTIME-LICENSES.md");
|
|
@@ -3,6 +3,7 @@ import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
|
|
6
|
+
import { CODEGRAPH_PINNED_VERSION } from "../../../../../utils/src/codegraph/manifest.ts";
|
|
6
7
|
import { runCodegraphSessionStartWorker } from "../src/hook.ts";
|
|
7
8
|
import { runCodegraphServe } from "../src/serve.ts";
|
|
8
9
|
|
|
@@ -41,7 +42,12 @@ describe("CodeGraph provisioned launcher Node guard", () => {
|
|
|
41
42
|
|
|
42
43
|
try {
|
|
43
44
|
mkdirSync(join(installDir, "bin"), { recursive: true });
|
|
45
|
+
mkdirSync(join(installDir, ".provisioned"), { recursive: true });
|
|
44
46
|
writeFileSync(binPath, "");
|
|
47
|
+
writeFileSync(
|
|
48
|
+
join(installDir, ".provisioned", `codegraph-${CODEGRAPH_PINNED_VERSION}.json`),
|
|
49
|
+
`${JSON.stringify({ binPath, version: CODEGRAPH_PINNED_VERSION })}\n`,
|
|
50
|
+
);
|
|
45
51
|
|
|
46
52
|
// when
|
|
47
53
|
const result = await runCodegraphSessionStartWorker({
|
|
@@ -71,19 +77,19 @@ describe("CodeGraph provisioned launcher Node guard", () => {
|
|
|
71
77
|
source: provisioned === null ? "path" : "provisioned",
|
|
72
78
|
};
|
|
73
79
|
},
|
|
80
|
+
resolveManagedBin: () => binPath,
|
|
74
81
|
runCommand: (_projectRoot, command, args) => {
|
|
75
82
|
calls.push({ args, command });
|
|
76
|
-
|
|
83
|
+
mkdirSync(join(workspace, ".codegraph"), { recursive: true });
|
|
84
|
+
writeFileSync(join(workspace, ".codegraph", "codegraph.db"), "fixture");
|
|
85
|
+
return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
|
|
77
86
|
},
|
|
78
87
|
},
|
|
79
88
|
});
|
|
80
89
|
|
|
81
90
|
// then
|
|
82
91
|
expect(result).toEqual({ action: "initialized" });
|
|
83
|
-
expect(calls).toEqual([
|
|
84
|
-
{ args: ["status", "--json"], command: binPath },
|
|
85
|
-
{ args: ["init"], command: binPath },
|
|
86
|
-
]);
|
|
92
|
+
expect(calls).toEqual([{ args: ["init"], command: binPath }]);
|
|
87
93
|
expect(outcomes).toEqual([{ action: "initialized", exitCode: 0, projectRoot: workspace, source: "provisioned", timedOut: false }]);
|
|
88
94
|
} finally {
|
|
89
95
|
rmSync(workspace, { recursive: true, force: true });
|
|
@@ -7,7 +7,7 @@ import { fileURLToPath } from "node:url";
|
|
|
7
7
|
import { runCodegraphServe } from "../src/serve.ts";
|
|
8
8
|
import {
|
|
9
9
|
arrayProperty,
|
|
10
|
-
|
|
10
|
+
CODEGRAPH_150_DEFAULT_TOOLS,
|
|
11
11
|
findTool,
|
|
12
12
|
frameMcpRequest,
|
|
13
13
|
parseMcpBodies,
|
|
@@ -87,14 +87,14 @@ describe("runCodegraphServe MCP protocol bridge", () => {
|
|
|
87
87
|
result: {
|
|
88
88
|
capabilities: { tools: { listChanged: false } },
|
|
89
89
|
protocolVersion: "2025-06-18",
|
|
90
|
-
serverInfo: { name: "codegraph", version: "1.
|
|
90
|
+
serverInfo: { name: "codegraph", version: "1.5.0" },
|
|
91
91
|
},
|
|
92
92
|
},
|
|
93
93
|
{
|
|
94
94
|
id: 2,
|
|
95
95
|
jsonrpc: "2.0",
|
|
96
96
|
result: {
|
|
97
|
-
tools:
|
|
97
|
+
tools: CODEGRAPH_150_DEFAULT_TOOLS,
|
|
98
98
|
},
|
|
99
99
|
},
|
|
100
100
|
]);
|
|
@@ -17,6 +17,7 @@ describe("runCodegraphServe MCP unavailable facade", () => {
|
|
|
17
17
|
const run = runCodegraphServe({
|
|
18
18
|
config: { codegraph: { auto_provision: false, enabled: true }, sources: [], warnings: [] },
|
|
19
19
|
env: { PATH: "/bin" },
|
|
20
|
+
nodeVersion: "22.14.0",
|
|
20
21
|
buildEnv: () => ({}),
|
|
21
22
|
resolve: () => ({ argsPrefix: [], command: "codegraph", exists: false, source: "path" }),
|
|
22
23
|
stderr: { write: (chunk: string) => stderr.push(chunk) },
|
|
@@ -47,7 +48,7 @@ describe("runCodegraphServe MCP unavailable facade", () => {
|
|
|
47
48
|
result: {
|
|
48
49
|
capabilities: { tools: { listChanged: false } },
|
|
49
50
|
protocolVersion: "2025-06-18",
|
|
50
|
-
serverInfo: { name: "codegraph", version: "1.
|
|
51
|
+
serverInfo: { name: "codegraph", version: "1.5.0" },
|
|
51
52
|
},
|
|
52
53
|
});
|
|
53
54
|
});
|