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
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { describe, expect, it } from "bun:test";
|
|
2
|
+
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
2
4
|
import { join } from "node:path";
|
|
3
5
|
|
|
4
6
|
import { runCodegraphServe } from "../src/serve.ts";
|
|
5
7
|
|
|
6
8
|
describe("runCodegraphServe provisioning", () => {
|
|
7
|
-
it("#given CodeGraph is unresolved and daemon is
|
|
9
|
+
it("#given CodeGraph is unresolved and daemon is omitted #when serving MCP #then provisions CodeGraph with daemon-on", async () => {
|
|
8
10
|
// given
|
|
9
11
|
const binPath = join("/tmp/home/.omo/codegraph", "bin", "codegraph");
|
|
10
12
|
const calls: Array<{
|
|
@@ -42,7 +44,6 @@ describe("runCodegraphServe provisioning", () => {
|
|
|
42
44
|
command: binPath,
|
|
43
45
|
env: {
|
|
44
46
|
CODEGRAPH_INSTALL_DIR: join("/tmp/home", ".omo", "codegraph"),
|
|
45
|
-
CODEGRAPH_NO_DAEMON: "1",
|
|
46
47
|
CODEGRAPH_NO_DOWNLOAD: "1",
|
|
47
48
|
CODEGRAPH_TELEMETRY: "0",
|
|
48
49
|
DO_NOT_TRACK: "1",
|
|
@@ -52,7 +53,50 @@ describe("runCodegraphServe provisioning", () => {
|
|
|
52
53
|
]);
|
|
53
54
|
});
|
|
54
55
|
|
|
55
|
-
it("#given
|
|
56
|
+
it("#given a bundled runtime and a stale managed install #when serving MCP #then it upgrades and uses the managed runtime", async () => {
|
|
57
|
+
// given
|
|
58
|
+
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-serve-managed-upgrade-"));
|
|
59
|
+
const installDir = join(homeDir, ".omo", "codegraph");
|
|
60
|
+
const binPath = join(installDir, "bin", "codegraph");
|
|
61
|
+
mkdirSync(join(installDir, "bin"), { recursive: true });
|
|
62
|
+
mkdirSync(join(installDir, ".provisioned"), { recursive: true });
|
|
63
|
+
writeFileSync(binPath, "stale codegraph\n");
|
|
64
|
+
writeFileSync(
|
|
65
|
+
join(installDir, ".provisioned", "codegraph-1.4.1.json"),
|
|
66
|
+
`${JSON.stringify({ binPath, version: "1.4.1" })}\n`,
|
|
67
|
+
);
|
|
68
|
+
const provisionCalls: unknown[] = [];
|
|
69
|
+
const processCalls: Array<{ readonly args: readonly string[]; readonly command: string }> = [];
|
|
70
|
+
|
|
71
|
+
try {
|
|
72
|
+
// when
|
|
73
|
+
const exitCode = await runCodegraphServe({
|
|
74
|
+
config: { codegraph: { enabled: true }, sources: [], warnings: [] },
|
|
75
|
+
homeDir,
|
|
76
|
+
managedInstallExists: () => true,
|
|
77
|
+
nodeVersion: "22.14.0",
|
|
78
|
+
resolve: () => ({ argsPrefix: ["codegraph.js"], command: "/opt/node22/bin/node", exists: true, source: "bundled" }),
|
|
79
|
+
resolveManagedBin: () => null,
|
|
80
|
+
ensureProvisioned: (options) => {
|
|
81
|
+
provisionCalls.push(options);
|
|
82
|
+
return Promise.resolve({ binPath, provisioned: true });
|
|
83
|
+
},
|
|
84
|
+
runProcess: (command, args) => {
|
|
85
|
+
processCalls.push({ args, command });
|
|
86
|
+
return Promise.resolve(0);
|
|
87
|
+
},
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
// then
|
|
91
|
+
expect(exitCode).toBe(0);
|
|
92
|
+
expect(provisionCalls).toEqual([{ installDir, lockDir: join(installDir, ".locks"), version: "1.5.0" }]);
|
|
93
|
+
expect(processCalls).toEqual([{ args: ["serve", "--mcp"], command: binPath }]);
|
|
94
|
+
} finally {
|
|
95
|
+
rmSync(homeDir, { force: true, recursive: true });
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("#given CodeGraph is unresolved and codegraph.daemon=false #when serving MCP #then provisions CodeGraph with daemon-off", async () => {
|
|
56
100
|
// given
|
|
57
101
|
const binPath = join("/tmp/home/.omo/codegraph", "bin", "codegraph");
|
|
58
102
|
const calls: Array<{
|
|
@@ -64,7 +108,7 @@ describe("runCodegraphServe provisioning", () => {
|
|
|
64
108
|
|
|
65
109
|
// when
|
|
66
110
|
const exitCode = await runCodegraphServe({
|
|
67
|
-
config: { codegraph: { daemon:
|
|
111
|
+
config: { codegraph: { daemon: false, enabled: true }, sources: [], warnings: [] },
|
|
68
112
|
env: { PATH: "/bin" },
|
|
69
113
|
homeDir: "/tmp/home",
|
|
70
114
|
nodeVersion: "22.14.0",
|
|
@@ -90,6 +134,7 @@ describe("runCodegraphServe provisioning", () => {
|
|
|
90
134
|
command: binPath,
|
|
91
135
|
env: {
|
|
92
136
|
CODEGRAPH_INSTALL_DIR: join("/tmp/home", ".omo", "codegraph"),
|
|
137
|
+
CODEGRAPH_NO_DAEMON: "1",
|
|
93
138
|
CODEGRAPH_NO_DOWNLOAD: "1",
|
|
94
139
|
CODEGRAPH_TELEMETRY: "0",
|
|
95
140
|
DO_NOT_TRACK: "1",
|
|
@@ -97,6 +142,6 @@ describe("runCodegraphServe provisioning", () => {
|
|
|
97
142
|
},
|
|
98
143
|
},
|
|
99
144
|
]);
|
|
100
|
-
expect(calls[0]?.env["CODEGRAPH_NO_DAEMON"]).
|
|
145
|
+
expect(calls[0]?.env["CODEGRAPH_NO_DAEMON"]).toBe("1");
|
|
101
146
|
});
|
|
102
147
|
});
|
|
@@ -17,6 +17,7 @@ describe("runCodegraphServe unavailable CodeGraph paths", () => {
|
|
|
17
17
|
...closedMcpStdio(),
|
|
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
|
runProcess: (command: string) => {
|
|
@@ -96,8 +97,8 @@ describe("runCodegraphServe unavailable CodeGraph paths", () => {
|
|
|
96
97
|
try {
|
|
97
98
|
mkdirSync(join(homeDir, ".omo"), { recursive: true });
|
|
98
99
|
mkdirSync(join(workspace, ".omo"), { recursive: true });
|
|
99
|
-
writeFileSync(join(homeDir, ".omo", "
|
|
100
|
-
writeFileSync(join(workspace, ".omo", "
|
|
100
|
+
writeFileSync(join(homeDir, ".omo", "omo.jsonc"), '{ "codegraph": { "enabled": true } }\n');
|
|
101
|
+
writeFileSync(join(workspace, ".omo", "omo.jsonc"), '{ "[codex]": { "codegraph": { "enabled": false } } }\n');
|
|
101
102
|
|
|
102
103
|
// when
|
|
103
104
|
const exitCode = await runCodegraphServe({
|
|
@@ -5,6 +5,7 @@ import { dirname, join, resolve } from "node:path";
|
|
|
5
5
|
import { Readable, Writable } from "node:stream";
|
|
6
6
|
import { fileURLToPath } from "node:url";
|
|
7
7
|
|
|
8
|
+
import { CODEGRAPH_PINNED_VERSION } from "../../../../../utils/src/codegraph/manifest.ts";
|
|
8
9
|
import { resolveServeProcessInvocation, runCodegraphServe } from "../src/serve.ts";
|
|
9
10
|
|
|
10
11
|
const componentRoot = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
@@ -48,7 +49,6 @@ describe("runCodegraphServe", () => {
|
|
|
48
49
|
cwd: resolve(runCwd),
|
|
49
50
|
env: {
|
|
50
51
|
CODEGRAPH_INSTALL_DIR: join("/tmp/home", ".omo", "codegraph"),
|
|
51
|
-
CODEGRAPH_NO_DAEMON: "1",
|
|
52
52
|
CODEGRAPH_NO_DOWNLOAD: "1",
|
|
53
53
|
CODEGRAPH_TELEMETRY: "0",
|
|
54
54
|
DO_NOT_TRACK: "1",
|
|
@@ -61,7 +61,7 @@ describe("runCodegraphServe", () => {
|
|
|
61
61
|
expect(calls[0]?.env["OPENAI_API_KEY"]).toBeUndefined();
|
|
62
62
|
});
|
|
63
63
|
|
|
64
|
-
it("#given codegraph.daemon=
|
|
64
|
+
it("#given codegraph.daemon=false #when serving MCP #then CODEGRAPH_NO_DAEMON pins daemon-off", async () => {
|
|
65
65
|
// given
|
|
66
66
|
const runCwd = componentRoot;
|
|
67
67
|
const calls: Array<{
|
|
@@ -74,7 +74,7 @@ describe("runCodegraphServe", () => {
|
|
|
74
74
|
|
|
75
75
|
// when
|
|
76
76
|
const exitCode = await runCodegraphServe({
|
|
77
|
-
config: { codegraph: { daemon:
|
|
77
|
+
config: { codegraph: { daemon: false, enabled: true }, sources: [], warnings: [] },
|
|
78
78
|
cwd: runCwd,
|
|
79
79
|
env: { CUSTOM: "drop", HOME: "/tmp/home", OPENAI_API_KEY: "sk-test-secret" },
|
|
80
80
|
nodeVersion: "22.14.0",
|
|
@@ -100,6 +100,7 @@ describe("runCodegraphServe", () => {
|
|
|
100
100
|
cwd: resolve(runCwd),
|
|
101
101
|
env: {
|
|
102
102
|
CODEGRAPH_INSTALL_DIR: join("/tmp/home", ".omo", "codegraph"),
|
|
103
|
+
CODEGRAPH_NO_DAEMON: "1",
|
|
103
104
|
CODEGRAPH_NO_DOWNLOAD: "1",
|
|
104
105
|
CODEGRAPH_TELEMETRY: "0",
|
|
105
106
|
DO_NOT_TRACK: "1",
|
|
@@ -108,7 +109,7 @@ describe("runCodegraphServe", () => {
|
|
|
108
109
|
stdio: "pipe",
|
|
109
110
|
},
|
|
110
111
|
]);
|
|
111
|
-
expect(calls[0]?.env["CODEGRAPH_NO_DAEMON"]).
|
|
112
|
+
expect(calls[0]?.env["CODEGRAPH_NO_DAEMON"]).toBe("1");
|
|
112
113
|
expect(calls[0]?.env["CUSTOM"]).toBeUndefined();
|
|
113
114
|
expect(calls[0]?.env["OPENAI_API_KEY"]).toBeUndefined();
|
|
114
115
|
});
|
|
@@ -182,12 +183,12 @@ describe("runCodegraphServe", () => {
|
|
|
182
183
|
expect(spawned).toEqual([{ args: ["serve", "--mcp"], command: commandPath }]);
|
|
183
184
|
});
|
|
184
185
|
|
|
185
|
-
it("#given
|
|
186
|
-
await withProcessPlatform(
|
|
186
|
+
it("#given Codex SOT install_dir has the pinned launcher and daemon is omitted #when serving MCP #then it defaults daemon-on", async () => {
|
|
187
|
+
await withProcessPlatform(process.platform, async () => {
|
|
187
188
|
// given
|
|
188
189
|
const tempRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-serve-install-dir-"));
|
|
189
190
|
const installDir = join(tempRoot, "custom-codegraph");
|
|
190
|
-
const binPath = join(installDir, "bin", "codegraph.cmd");
|
|
191
|
+
const binPath = join(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
|
|
191
192
|
const calls: Array<{
|
|
192
193
|
readonly args: readonly string[];
|
|
193
194
|
readonly command: string;
|
|
@@ -196,7 +197,12 @@ describe("runCodegraphServe", () => {
|
|
|
196
197
|
|
|
197
198
|
try {
|
|
198
199
|
mkdirSync(join(installDir, "bin"), { recursive: true });
|
|
200
|
+
mkdirSync(join(installDir, ".provisioned"), { recursive: true });
|
|
199
201
|
writeFileSync(binPath, "");
|
|
202
|
+
writeFileSync(
|
|
203
|
+
join(installDir, ".provisioned", `codegraph-${CODEGRAPH_PINNED_VERSION}.json`),
|
|
204
|
+
`${JSON.stringify({ binPath, version: CODEGRAPH_PINNED_VERSION })}\n`,
|
|
205
|
+
);
|
|
200
206
|
|
|
201
207
|
// when
|
|
202
208
|
const exitCode = await runCodegraphServe({
|
|
@@ -223,7 +229,6 @@ describe("runCodegraphServe", () => {
|
|
|
223
229
|
command: binPath,
|
|
224
230
|
env: {
|
|
225
231
|
CODEGRAPH_INSTALL_DIR: installDir,
|
|
226
|
-
CODEGRAPH_NO_DAEMON: "1",
|
|
227
232
|
CODEGRAPH_NO_DOWNLOAD: "1",
|
|
228
233
|
CODEGRAPH_TELEMETRY: "0",
|
|
229
234
|
DO_NOT_TRACK: "1",
|
|
@@ -237,12 +242,12 @@ describe("runCodegraphServe", () => {
|
|
|
237
242
|
});
|
|
238
243
|
});
|
|
239
244
|
|
|
240
|
-
it("#given
|
|
241
|
-
await withProcessPlatform(
|
|
245
|
+
it("#given Codex SOT install_dir with codegraph.daemon=false #when serving MCP #then CODEGRAPH_NO_DAEMON pins daemon-off", async () => {
|
|
246
|
+
await withProcessPlatform(process.platform, async () => {
|
|
242
247
|
// given
|
|
243
248
|
const tempRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-serve-install-dir-daemon-"));
|
|
244
249
|
const installDir = join(tempRoot, "custom-codegraph");
|
|
245
|
-
const binPath = join(installDir, "bin", "codegraph.cmd");
|
|
250
|
+
const binPath = join(installDir, "bin", process.platform === "win32" ? "codegraph.cmd" : "codegraph");
|
|
246
251
|
const calls: Array<{
|
|
247
252
|
readonly args: readonly string[];
|
|
248
253
|
readonly command: string;
|
|
@@ -251,11 +256,16 @@ describe("runCodegraphServe", () => {
|
|
|
251
256
|
|
|
252
257
|
try {
|
|
253
258
|
mkdirSync(join(installDir, "bin"), { recursive: true });
|
|
259
|
+
mkdirSync(join(installDir, ".provisioned"), { recursive: true });
|
|
254
260
|
writeFileSync(binPath, "");
|
|
261
|
+
writeFileSync(
|
|
262
|
+
join(installDir, ".provisioned", `codegraph-${CODEGRAPH_PINNED_VERSION}.json`),
|
|
263
|
+
`${JSON.stringify({ binPath, version: CODEGRAPH_PINNED_VERSION })}\n`,
|
|
264
|
+
);
|
|
255
265
|
|
|
256
266
|
// when
|
|
257
267
|
const exitCode = await runCodegraphServe({
|
|
258
|
-
config: { codegraph: { daemon:
|
|
268
|
+
config: { codegraph: { daemon: false, enabled: true, install_dir: installDir }, sources: [], trustedCodegraphInstallDir: installDir, warnings: [] },
|
|
259
269
|
env: { HOME: "/tmp/home" },
|
|
260
270
|
nodeVersion: "22.14.0",
|
|
261
271
|
homeDir: "/tmp/home",
|
|
@@ -278,6 +288,7 @@ describe("runCodegraphServe", () => {
|
|
|
278
288
|
command: binPath,
|
|
279
289
|
env: {
|
|
280
290
|
CODEGRAPH_INSTALL_DIR: installDir,
|
|
291
|
+
CODEGRAPH_NO_DAEMON: "1",
|
|
281
292
|
CODEGRAPH_NO_DOWNLOAD: "1",
|
|
282
293
|
CODEGRAPH_TELEMETRY: "0",
|
|
283
294
|
DO_NOT_TRACK: "1",
|
|
@@ -285,7 +296,7 @@ describe("runCodegraphServe", () => {
|
|
|
285
296
|
},
|
|
286
297
|
},
|
|
287
298
|
]);
|
|
288
|
-
expect(calls[0]?.env["CODEGRAPH_NO_DAEMON"]).
|
|
299
|
+
expect(calls[0]?.env["CODEGRAPH_NO_DAEMON"]).toBe("1");
|
|
289
300
|
} finally {
|
|
290
301
|
rmSync(tempRoot, { recursive: true, force: true });
|
|
291
302
|
}
|
package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import { existsSync, mkdtempSync, rmSync } from "node:fs";
|
|
2
|
+
import { existsSync, mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
3
3
|
import { tmpdir } from "node:os";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
|
|
6
6
|
import { runCodegraphSessionStartWorker } from "../src/hook.ts";
|
|
7
7
|
|
|
8
|
+
function writeProjectDatabase(workspace: string): void {
|
|
9
|
+
mkdirSync(join(workspace, ".codegraph"), { recursive: true });
|
|
10
|
+
writeFileSync(join(workspace, ".codegraph", "codegraph.db"), "fixture");
|
|
11
|
+
}
|
|
12
|
+
|
|
8
13
|
describe("CodeGraph SessionStart worker Node support", () => {
|
|
9
14
|
it("#given an unsupported local Node and a PATH CodeGraph command with auto provisioning disabled #when worker runs #then it skips without touching the workspace", async () => {
|
|
10
15
|
// given
|
|
@@ -52,7 +57,7 @@ describe("CodeGraph SessionStart worker Node support", () => {
|
|
|
52
57
|
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-node-provision-home-"));
|
|
53
58
|
const binPath = join(homeDir, ".omo", "codegraph", "bin", "codegraph");
|
|
54
59
|
const calls: Array<{ readonly args: readonly string[]; readonly command: string }> = [];
|
|
55
|
-
const provisionCalls: Array<{ readonly installDir?: string; readonly lockDir: string; readonly version: "1.
|
|
60
|
+
const provisionCalls: Array<{ readonly installDir?: string; readonly lockDir: string; readonly version: "1.5.0" }> = [];
|
|
56
61
|
const outcomes: unknown[] = [];
|
|
57
62
|
|
|
58
63
|
try {
|
|
@@ -78,19 +83,17 @@ describe("CodeGraph SessionStart worker Node support", () => {
|
|
|
78
83
|
resolveCommand: () => ({ argsPrefix: [], command: "/usr/local/bin/codegraph", exists: true, source: "path" }),
|
|
79
84
|
runCommand: (_projectRoot, command, args) => {
|
|
80
85
|
calls.push({ args, command });
|
|
81
|
-
|
|
86
|
+
writeProjectDatabase(workspace);
|
|
87
|
+
return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
|
|
82
88
|
},
|
|
83
89
|
},
|
|
84
90
|
});
|
|
85
91
|
|
|
86
92
|
// then
|
|
87
93
|
expect(result).toEqual({ action: "initialized" });
|
|
88
|
-
expect(calls).toEqual([
|
|
89
|
-
{ args: ["status", "--json"], command: binPath },
|
|
90
|
-
{ args: ["init"], command: binPath },
|
|
91
|
-
]);
|
|
94
|
+
expect(calls).toEqual([{ args: ["init"], command: binPath }]);
|
|
92
95
|
expect(provisionCalls).toEqual([
|
|
93
|
-
{ installDir: join(homeDir, ".omo", "codegraph"), lockDir: join(homeDir, ".omo", "codegraph", ".locks"), version: "1.
|
|
96
|
+
{ installDir: join(homeDir, ".omo", "codegraph"), lockDir: join(homeDir, ".omo", "codegraph", ".locks"), version: "1.5.0" },
|
|
94
97
|
]);
|
|
95
98
|
expect(outcomes).toEqual([{ action: "initialized", exitCode: 0, projectRoot: workspace, source: "provisioned", timedOut: false }]);
|
|
96
99
|
} finally {
|
|
@@ -99,6 +102,62 @@ describe("CodeGraph SessionStart worker Node support", () => {
|
|
|
99
102
|
}
|
|
100
103
|
});
|
|
101
104
|
|
|
105
|
+
it("#given bundled CodeGraph and a stale managed install #when the worker runs #then it upgrades and uses the managed runtime", async () => {
|
|
106
|
+
// given
|
|
107
|
+
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-managed-upgrade-"));
|
|
108
|
+
const homeDir = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-managed-upgrade-home-"));
|
|
109
|
+
const installDir = join(homeDir, ".omo", "codegraph");
|
|
110
|
+
const binPath = join(installDir, "bin", "codegraph");
|
|
111
|
+
mkdirSync(join(installDir, "bin"), { recursive: true });
|
|
112
|
+
mkdirSync(join(installDir, ".provisioned"), { recursive: true });
|
|
113
|
+
writeFileSync(binPath, "stale codegraph\n");
|
|
114
|
+
writeFileSync(
|
|
115
|
+
join(installDir, ".provisioned", "codegraph-1.4.1.json"),
|
|
116
|
+
`${JSON.stringify({ binPath, version: "1.4.1" })}\n`,
|
|
117
|
+
);
|
|
118
|
+
const provisionCalls: unknown[] = [];
|
|
119
|
+
const commandCalls: Array<{ readonly args: readonly string[]; readonly command: string }> = [];
|
|
120
|
+
|
|
121
|
+
try {
|
|
122
|
+
// when
|
|
123
|
+
const result = await runCodegraphSessionStartWorker({
|
|
124
|
+
cwd: workspace,
|
|
125
|
+
env: { HOME: homeDir },
|
|
126
|
+
nodeVersion: "22.14.0",
|
|
127
|
+
deps: {
|
|
128
|
+
ensureGitignored: () => true,
|
|
129
|
+
ensureProvisioned: (options) => {
|
|
130
|
+
provisionCalls.push(options);
|
|
131
|
+
return Promise.resolve({ binPath, provisioned: true });
|
|
132
|
+
},
|
|
133
|
+
managedInstallExists: () => 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: ["codegraph.js"], command: "/opt/node22/bin/node", exists: true, source: "bundled" }),
|
|
142
|
+
resolveManagedBin: () => null,
|
|
143
|
+
runCommand: (_projectRoot, command, args) => {
|
|
144
|
+
commandCalls.push({ args, command });
|
|
145
|
+
writeProjectDatabase(workspace);
|
|
146
|
+
return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// then
|
|
152
|
+
expect(result).toEqual({ action: "initialized" });
|
|
153
|
+
expect(provisionCalls).toEqual([{ installDir, lockDir: join(installDir, ".locks"), version: "1.5.0" }]);
|
|
154
|
+
expect(commandCalls).toEqual([{ args: ["init"], command: binPath }]);
|
|
155
|
+
} finally {
|
|
156
|
+
rmSync(workspace, { recursive: true, force: true });
|
|
157
|
+
rmSync(homeDir, { recursive: true, force: true });
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
102
161
|
it("#given an unsupported local Node but bundled CodeGraph resolves through CODEGRAPH_NODE_BIN #when worker runs #then it bootstraps with the compatible runtime", async () => {
|
|
103
162
|
// given
|
|
104
163
|
const workspace = mkdtempSync(join(tmpdir(), "omo-codegraph-worker-compatible-node-"));
|
|
@@ -129,17 +188,15 @@ describe("CodeGraph SessionStart worker Node support", () => {
|
|
|
129
188
|
resolveCommand: () => ({ argsPrefix: ["codegraph.js"], command: nodeBin, exists: true, source: "bundled" }),
|
|
130
189
|
runCommand: (_projectRoot, command, args) => {
|
|
131
190
|
calls.push({ args, command });
|
|
132
|
-
|
|
191
|
+
writeProjectDatabase(workspace);
|
|
192
|
+
return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
|
|
133
193
|
},
|
|
134
194
|
},
|
|
135
195
|
});
|
|
136
196
|
|
|
137
197
|
// then
|
|
138
198
|
expect(result).toEqual({ action: "initialized" });
|
|
139
|
-
expect(calls).toEqual([
|
|
140
|
-
{ args: ["codegraph.js", "status", "--json"], command: nodeBin },
|
|
141
|
-
{ args: ["codegraph.js", "init"], command: nodeBin },
|
|
142
|
-
]);
|
|
199
|
+
expect(calls).toEqual([{ args: ["codegraph.js", "init"], command: nodeBin }]);
|
|
143
200
|
expect(outcomes).toEqual([{ action: "initialized", exitCode: 0, projectRoot: workspace, source: "bundled", timedOut: false }]);
|
|
144
201
|
} finally {
|
|
145
202
|
rmSync(workspace, { recursive: true, force: true });
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { describe, expect, it } from "bun:test";
|
|
2
|
+
import { mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { tmpdir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
|
|
6
|
+
import { probeCodegraphProject } from "../src/session-start-project.ts";
|
|
7
|
+
|
|
8
|
+
describe("CodeGraph SessionStart project probe", () => {
|
|
9
|
+
it("#given the exact project directory has a CodeGraph database #when probing #then it is initialized", () => {
|
|
10
|
+
// given
|
|
11
|
+
const projectRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-probe-exact-"));
|
|
12
|
+
try {
|
|
13
|
+
mkdirSync(join(projectRoot, ".codegraph"), { recursive: true });
|
|
14
|
+
writeFileSync(join(projectRoot, ".codegraph", "codegraph.db"), "fixture");
|
|
15
|
+
|
|
16
|
+
// when
|
|
17
|
+
const result = probeCodegraphProject(projectRoot);
|
|
18
|
+
|
|
19
|
+
// then
|
|
20
|
+
expect(result).toEqual({ kind: "initialized" });
|
|
21
|
+
} finally {
|
|
22
|
+
rmSync(projectRoot, { recursive: true, force: true });
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it("#given an ancestor directory has a CodeGraph database #when probing a nested project #then the ancestor covers it", () => {
|
|
27
|
+
// given
|
|
28
|
+
const ancestorRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-probe-ancestor-"));
|
|
29
|
+
const projectRoot = join(ancestorRoot, "apps", "server");
|
|
30
|
+
try {
|
|
31
|
+
mkdirSync(join(ancestorRoot, ".codegraph"), { recursive: true });
|
|
32
|
+
mkdirSync(projectRoot, { recursive: true });
|
|
33
|
+
writeFileSync(join(ancestorRoot, ".codegraph", "codegraph.db"), "fixture");
|
|
34
|
+
|
|
35
|
+
// when
|
|
36
|
+
const result = probeCodegraphProject(projectRoot);
|
|
37
|
+
|
|
38
|
+
// then
|
|
39
|
+
expect(result).toEqual({ ancestorRoot: realpathSync(ancestorRoot), kind: "nested-root" });
|
|
40
|
+
} finally {
|
|
41
|
+
rmSync(ancestorRoot, { recursive: true, force: true });
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
it("#given neither the project nor its ancestors have a CodeGraph database #when probing #then it is definitively uninitialized", () => {
|
|
46
|
+
// given
|
|
47
|
+
const projectRoot = mkdtempSync(join(tmpdir(), "omo-codegraph-probe-missing-"));
|
|
48
|
+
try {
|
|
49
|
+
// when
|
|
50
|
+
const result = probeCodegraphProject(projectRoot);
|
|
51
|
+
|
|
52
|
+
// then
|
|
53
|
+
expect(result).toEqual({ kind: "uninitialized" });
|
|
54
|
+
} finally {
|
|
55
|
+
rmSync(projectRoot, { recursive: true, force: true });
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -0,0 +1,104 @@
|
|
|
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
CHANGED
|
@@ -15,7 +15,7 @@ describe("CodeGraph SessionStart trust boundary", () => {
|
|
|
15
15
|
const calls: Array<{ readonly env: Record<string, string>; readonly installDir?: string; readonly lockDir?: string }> = [];
|
|
16
16
|
try {
|
|
17
17
|
mkdirSync(join(workspace, ".omo"), { recursive: true });
|
|
18
|
-
writeFileSync(join(workspace, ".omo", "
|
|
18
|
+
writeFileSync(join(workspace, ".omo", "omo.jsonc"), JSON.stringify({ codegraph: { enabled: true, install_dir: attackerInstallDir } }));
|
|
19
19
|
|
|
20
20
|
// when
|
|
21
21
|
const result = await runCodegraphSessionStartWorker({
|
|
@@ -45,7 +45,9 @@ describe("CodeGraph SessionStart trust boundary", () => {
|
|
|
45
45
|
},
|
|
46
46
|
runCommand: (_projectRoot, _command, _args, options) => {
|
|
47
47
|
calls.push({ env: options.env });
|
|
48
|
-
|
|
48
|
+
mkdirSync(join(workspace, ".codegraph"), { recursive: true });
|
|
49
|
+
writeFileSync(join(workspace, ".codegraph", "codegraph.db"), "fixture");
|
|
50
|
+
return Promise.resolve({ exitCode: 0, stdout: "", timedOut: false });
|
|
49
51
|
},
|
|
50
52
|
},
|
|
51
53
|
});
|