oh-my-opencode 5.0.0-beta.33 → 5.0.0-beta.35
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/codex-qa/scripts/lsp-e2e.sh +1 -3
- package/.agents/skills/opencode-qa/scripts/lsp-e2e.sh +1 -1
- package/.agents/skills/tech-debt-audit/SKILL.md +6 -76
- package/README.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +1 -1
- package/README.ru.md +1 -1
- package/README.zh-cn.md +1 -1
- package/THIRD-PARTY-NOTICES.md +27 -99
- package/dist/cli/index.js +48350 -48559
- package/dist/cli-node/index.js +48480 -48689
- package/dist/config/index.d.ts +1 -1
- package/dist/config/schema/hooks.d.ts +0 -1
- package/dist/config/schema/oh-my-opencode-config.d.ts +0 -10
- package/dist/config/schema.d.ts +0 -1
- package/dist/create-hooks.d.ts +0 -1
- package/dist/hooks/index.d.ts +0 -1
- package/dist/index.js +11675 -13742
- package/dist/mcp/index.d.ts +0 -4
- package/dist/mcp/types.d.ts +0 -1
- package/dist/oh-my-opencode.schema.json +1 -45
- package/dist/plugin/hooks/create-core-hooks.d.ts +0 -1
- package/dist/plugin/hooks/create-session-hooks.d.ts +1 -2
- package/dist/shared/omo-process-sweep.d.ts +2 -4
- package/dist/skills/init-deep/SKILL.md +13 -13
- package/dist/skills/ulw-plan/SKILL.md +0 -1
- package/dist/tui.js +44809 -44910
- package/package.json +16 -18
- package/packages/omo-codex/THIRD-PARTY-NOTICES.md +0 -17
- package/packages/omo-codex/plugin/.codex-plugin/plugin.json +1 -3
- package/packages/omo-codex/plugin/.mcp.json +0 -6
- package/packages/omo-codex/plugin/AGENTS.md +5 -5
- package/packages/omo-codex/plugin/README.md +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/dist/cli.js +1 -15
- package/packages/omo-codex/plugin/components/bootstrap/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/bootstrap/package.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/comment-checker/package.json +1 -1
- package/packages/omo-codex/plugin/components/git-bash/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/git-bash/package.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/lazycodex-executor-verify/package.json +1 -1
- package/packages/omo-codex/plugin/components/lcx/skills/lcx-doctor/SKILL.md +1 -1
- package/packages/omo-codex/plugin/components/lsp/dist/.omo-runtime-manifest.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/lsp/package.json +1 -1
- package/packages/omo-codex/plugin/components/rules/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/rules/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/package.json +1 -1
- package/packages/omo-codex/plugin/components/teammode/test/thread-title-hook.test.ts +1 -1
- package/packages/omo-codex/plugin/components/telemetry/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/telemetry/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/dist/cli.js +2 -2
- package/packages/omo-codex/plugin/components/ultrawork/hooks/hooks.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/package.json +1 -1
- package/packages/omo-codex/plugin/components/ultrawork/skills/ulw-plan/SKILL.md +0 -1
- package/packages/omo-codex/plugin/components/ultrawork/src/directive-content.ts +1 -1
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/hooks/hooks.json +2 -2
- package/packages/omo-codex/plugin/components/ulw-execute-continuation/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/README.md +11 -1
- package/packages/omo-codex/plugin/components/ulw-loop/directive.md +2 -2
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.d.ts +12 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-codex-validation.js +45 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.d.ts +1 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-reconciliation.js +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint-template.js +10 -3
- package/packages/omo-codex/plugin/components/ulw-loop/dist/checkpoint.js +35 -38
- package/packages/omo-codex/plugin/components/ulw-loop/dist/cli.js +278 -193
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.d.ts +5 -0
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-aggregate.js +7 -51
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-artifacts.js +39 -22
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.d.ts +13 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-fields.js +64 -8
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate-verdicts.js +5 -1
- package/packages/omo-codex/plugin/components/ulw-loop/dist/quality-gate.js +37 -18
- package/packages/omo-codex/plugin/components/ulw-loop/hooks/hooks.json +4 -4
- package/packages/omo-codex/plugin/components/ulw-loop/package.json +1 -1
- package/packages/omo-codex/plugin/components/ulw-loop/skills/ulw-loop/references/full-workflow.md +2 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-codex-validation.ts +81 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-reconciliation.ts +6 -0
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint-template.ts +10 -3
- package/packages/omo-codex/plugin/components/ulw-loop/src/checkpoint.ts +32 -63
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-aggregate.ts +7 -53
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-artifacts.ts +50 -31
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-fields.ts +67 -14
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate-verdicts.ts +6 -1
- package/packages/omo-codex/plugin/components/ulw-loop/src/quality-gate.ts +36 -17
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-final.test.ts +26 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/checkpoint-template.test.ts +47 -2
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate-basics.test.ts +258 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-cap-and-dedupe.test.ts +22 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-poisoning-cascades.test.ts +97 -0
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-single-report.test.ts +241 -0
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-git-bash-mcp-reminder.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-lsp-diagnostics-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-compact-resetting-project-rule-cache.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-comments.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-lsp-diagnostics.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-thread-title-hygiene.json +1 -1
- package/packages/omo-codex/plugin/hooks/post-tool-use-matching-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-enforcing-unlimited-goal-budget.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-guarding-ulw-loop-spawns.json +1 -1
- package/packages/omo-codex/plugin/hooks/pre-tool-use-recommending-git-bash-mcp.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-auto-update.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-checking-bootstrap-provisioning.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/hooks/session-start-recording-session-telemetry.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/stop-checking-ulw-loop-resume.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-checking-ulw-execute-continuation.json +1 -1
- package/packages/omo-codex/plugin/hooks/subagent-stop-verifying-lazycodex-executor-evidence.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ultrawork-trigger.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-checking-ulw-loop-steering.json +1 -1
- package/packages/omo-codex/plugin/hooks/user-prompt-submit-loading-project-rules.json +1 -1
- package/packages/omo-codex/plugin/package-lock.json +12 -146
- package/packages/omo-codex/plugin/package.json +1 -2
- package/packages/omo-codex/plugin/scripts/AGENTS.md +0 -1
- package/packages/omo-codex/plugin/scripts/auto-update-plan.mjs +0 -1
- package/packages/omo-codex/plugin/scripts/auto-update.mjs +0 -9
- package/packages/omo-codex/plugin/scripts/canonical-ultrawork-directive.mjs +17 -0
- package/packages/omo-codex/plugin/scripts/hook-status-message.mjs +0 -1
- package/packages/omo-codex/plugin/scripts/sync-skills.mjs +2 -8
- package/packages/omo-codex/plugin/shared/src/config-loader.ts +2 -102
- package/packages/omo-codex/plugin/shared/src/config-migration.ts +0 -1
- package/packages/omo-codex/plugin/shared/test/config-loader.test.ts +41 -130
- package/packages/omo-codex/plugin/skills/init-deep/SKILL.md +13 -13
- package/packages/omo-codex/plugin/skills/lcx-doctor/SKILL.md +1 -1
- package/packages/omo-codex/plugin/skills/ultrawork/SKILL.md +2 -2
- package/packages/omo-codex/plugin/skills/ulw-loop/references/full-workflow.md +2 -1
- package/packages/omo-codex/plugin/skills/ulw-plan/SKILL.md +0 -1
- package/packages/omo-codex/plugin/test/AGENTS.md +2 -2
- package/packages/omo-codex/plugin/test/aggregate-hooks.test.mjs +2 -21
- package/packages/omo-codex/plugin/test/aggregate-manifest.test.mjs +1 -2
- package/packages/omo-codex/plugin/test/aggregate-mcp.test.mjs +2 -7
- package/packages/omo-codex/plugin/test/auto-update.test.mjs +0 -25
- package/packages/omo-codex/plugin/test/bootstrap-setup.test.mjs +0 -31
- package/packages/omo-codex/plugin/test/canonical-ultrawork-directive.test.mjs +53 -0
- package/packages/omo-codex/plugin/test/component-bundled-cli.test.mjs +0 -50
- package/packages/omo-codex/plugin/test/hook-status-message.test.mjs +0 -1
- package/packages/omo-codex/plugin/test/mcp-research-servers.test.mjs +1 -3
- package/packages/omo-codex/scripts/install-cache-copy.test.mjs +27 -1
- package/packages/omo-codex/scripts/install-config-git-bash.test.mjs +0 -23
- package/packages/omo-codex/scripts/install-dist/install-local.mjs +238 -431
- package/packages/omo-codex/scripts/install-git-bash-mcp-env.test.mjs +1 -25
- package/packages/omo-codex/scripts/install-mcp-runtime.test.mjs +0 -36
- package/packages/shared-skills/skills/init-deep/SKILL.md +13 -13
- package/packages/shared-skills/skills/ulw-plan/SKILL.md +0 -1
- package/dist/config/schema/codegraph.d.ts +0 -12
- package/dist/hooks/codegraph-bootstrap/command-runner.d.ts +0 -17
- package/dist/hooks/codegraph-bootstrap/hook.d.ts +0 -35
- package/dist/hooks/codegraph-bootstrap/index.d.ts +0 -1
- package/dist/hooks/codegraph-bootstrap/project-root.d.ts +0 -1
- package/dist/hooks/codegraph-bootstrap/status.d.ts +0 -11
- package/dist/mcp/codegraph.d.ts +0 -16
- package/packages/omo-codex/plugin/components/codegraph/AGENTS.md +0 -58
- package/packages/omo-codex/plugin/components/codegraph/LICENSE +0 -21
- package/packages/omo-codex/plugin/components/codegraph/NODE-RUNTIME-LICENSES.md +0 -2951
- package/packages/omo-codex/plugin/components/codegraph/NOTICE +0 -16
- package/packages/omo-codex/plugin/components/codegraph/dist/cli.js +0 -12326
- package/packages/omo-codex/plugin/components/codegraph/dist/serve.js +0 -9908
- package/packages/omo-codex/plugin/components/codegraph/package.json +0 -33
- package/packages/omo-codex/plugin/components/codegraph/src/cache-gc.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/src/cli.ts +0 -79
- package/packages/omo-codex/plugin/components/codegraph/src/hook-input.ts +0 -33
- package/packages/omo-codex/plugin/components/codegraph/src/hook-sweep.ts +0 -25
- package/packages/omo-codex/plugin/components/codegraph/src/hook-types.ts +0 -131
- package/packages/omo-codex/plugin/components/codegraph/src/hook.ts +0 -258
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-bridge.ts +0 -310
- package/packages/omo-codex/plugin/components/codegraph/src/mcp-unavailable.ts +0 -92
- package/packages/omo-codex/plugin/components/codegraph/src/post-tool-use-hook.ts +0 -34
- package/packages/omo-codex/plugin/components/codegraph/src/serve-invocation.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/src/serve.ts +0 -263
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-command.ts +0 -106
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-cooldown.ts +0 -145
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-hook-runtime.ts +0 -22
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-lock.ts +0 -139
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-outcome.ts +0 -15
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-paths.ts +0 -32
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-project.ts +0 -109
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker-result.ts +0 -148
- package/packages/omo-codex/plugin/components/codegraph/src/session-start-worker.ts +0 -175
- package/packages/omo-codex/plugin/components/codegraph/src/sweep-cli.ts +0 -81
- package/packages/omo-codex/plugin/components/codegraph/test/cache-gc.test.ts +0 -34
- package/packages/omo-codex/plugin/components/codegraph/test/hook-exclusion.test.ts +0 -112
- package/packages/omo-codex/plugin/components/codegraph/test/hook-registration.test.ts +0 -26
- package/packages/omo-codex/plugin/components/codegraph/test/hook-session-start-guard.test.ts +0 -160
- package/packages/omo-codex/plugin/components/codegraph/test/hook-store-upgrade.test.ts +0 -50
- package/packages/omo-codex/plugin/components/codegraph/test/hook-sweep.test.ts +0 -29
- package/packages/omo-codex/plugin/components/codegraph/test/hook.test.ts +0 -320
- package/packages/omo-codex/plugin/components/codegraph/test/mcp-bridge-fixtures.ts +0 -172
- package/packages/omo-codex/plugin/components/codegraph/test/package-runtime.test.ts +0 -91
- package/packages/omo-codex/plugin/components/codegraph/test/provisioned-node-guard.test.ts +0 -100
- package/packages/omo-codex/plugin/components/codegraph/test/serve-built-wrapper.test.ts +0 -76
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge-lifecycle.test.ts +0 -133
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-bridge.test.ts +0 -245
- package/packages/omo-codex/plugin/components/codegraph/test/serve-mcp-facade.test.ts +0 -69
- package/packages/omo-codex/plugin/components/codegraph/test/serve-node-support.test.ts +0 -43
- package/packages/omo-codex/plugin/components/codegraph/test/serve-provision.test.ts +0 -147
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable-idle.test.ts +0 -47
- package/packages/omo-codex/plugin/components/codegraph/test/serve-unavailable.test.ts +0 -175
- package/packages/omo-codex/plugin/components/codegraph/test/serve.test.ts +0 -385
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-node-support.test.ts +0 -206
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-project.test.ts +0 -58
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-state.test.ts +0 -104
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-trust-boundary.test.ts +0 -65
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-availability.test.ts +0 -106
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-cooldown.test.ts +0 -116
- package/packages/omo-codex/plugin/components/codegraph/test/session-start-worker-flow.test.ts +0 -258
- package/packages/omo-codex/plugin/components/codegraph/test/sweep-cli.test.ts +0 -56
- package/packages/omo-codex/plugin/components/codegraph/tsconfig.build.json +0 -13
- package/packages/omo-codex/plugin/components/codegraph/tsconfig.json +0 -25
- package/packages/omo-codex/plugin/components/ulw-loop/test/quality-gate-aggregate.test.ts +0 -101
- package/packages/omo-codex/plugin/hooks/post-tool-use-checking-codegraph-init-guidance.json +0 -18
- package/packages/omo-codex/plugin/hooks/session-start-checking-codegraph-bootstrap.json +0 -17
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/editor.mjs +0 -125
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/jsonc.mjs +0 -43
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot/scaffold.mjs +0 -29
- package/packages/omo-codex/plugin/scripts/migrate-omo-sot.mjs +0 -121
- package/packages/omo-codex/plugin/test/component-codegraph-mcp-smoke.test.mjs +0 -76
- package/packages/omo-codex/plugin/test/migrate-omo-sot.test.mjs +0 -179
|
@@ -1,310 +0,0 @@
|
|
|
1
|
-
import { spawn, type ChildProcess } from "node:child_process";
|
|
2
|
-
import type { Readable, Writable } from "node:stream";
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
createParentWatchdog,
|
|
6
|
-
errorResponse,
|
|
7
|
-
isPlainRecord,
|
|
8
|
-
jsonRpcId,
|
|
9
|
-
readStdioJsonRpcMessages,
|
|
10
|
-
writeStdioJsonRpcResponse,
|
|
11
|
-
type StdioJsonRpcResponseMode,
|
|
12
|
-
} from "../../../../../mcp-stdio-core/src/index.ts";
|
|
13
|
-
import type { CodegraphServeProcessOptions } from "./serve.js";
|
|
14
|
-
import { resolveServeProcessInvocation } from "./serve-invocation.js";
|
|
15
|
-
|
|
16
|
-
class CodegraphBridgeStdioError extends Error {
|
|
17
|
-
override readonly name = "CodegraphBridgeStdioError";
|
|
18
|
-
|
|
19
|
-
constructor(readonly streamName: string) {
|
|
20
|
-
super(`CodeGraph MCP bridge missing child ${streamName}`);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
interface PendingClientResponse {
|
|
25
|
-
readonly method: string | null;
|
|
26
|
-
readonly responseMode: StdioJsonRpcResponseMode;
|
|
27
|
-
readonly toolName: string | null;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const CODEGRAPH_NODE_DESCRIPTION =
|
|
31
|
-
"Inspect one named symbol or file. In symbol mode, includeCode=true includes leaf-symbol source when available. Container symbols such as classes, interfaces, structs, enums, modules, and namespaces return structural outlines with member lists by design. For container source, request a specific member symbol or use file mode with symbolsOnly=false plus offset/limit.";
|
|
32
|
-
|
|
33
|
-
const CODEGRAPH_NODE_INCLUDE_CODE_DESCRIPTION =
|
|
34
|
-
"Symbol mode: include leaf-symbol source when available. Container symbols such as classes, interfaces, structs, enums, modules, and namespaces intentionally return structural outlines with members; request a specific member symbol or use file mode with symbolsOnly=false plus offset/limit for source.";
|
|
35
|
-
|
|
36
|
-
const CODEGRAPH_CONTAINER_OUTLINE_GUIDANCE =
|
|
37
|
-
"Container symbols intentionally return structural outlines with members. For source, request a specific member symbol or call codegraph_node in file mode with symbolsOnly=false plus offset/limit around the symbol location.";
|
|
38
|
-
|
|
39
|
-
const SIGKILL_ESCALATION_MS = 2_000;
|
|
40
|
-
|
|
41
|
-
export async function runBridgedCodegraphProcess(
|
|
42
|
-
command: string,
|
|
43
|
-
args: readonly string[],
|
|
44
|
-
options: CodegraphServeProcessOptions,
|
|
45
|
-
): Promise<number> {
|
|
46
|
-
const invocation = resolveServeProcessInvocation(command, args);
|
|
47
|
-
const child = spawn(invocation.command, invocation.args, {
|
|
48
|
-
cwd: options.cwd,
|
|
49
|
-
env: options.env,
|
|
50
|
-
stdio: ["pipe", "pipe", "inherit"],
|
|
51
|
-
windowsHide: true,
|
|
52
|
-
});
|
|
53
|
-
const childInput = child.stdin;
|
|
54
|
-
const childOutput = child.stdout;
|
|
55
|
-
if (childInput === null) throw new CodegraphBridgeStdioError("stdin");
|
|
56
|
-
if (childOutput === null) throw new CodegraphBridgeStdioError("stdout");
|
|
57
|
-
|
|
58
|
-
const pendingResponses = new Map<string, PendingClientResponse>();
|
|
59
|
-
let defaultResponseMode: StdioJsonRpcResponseMode = "framed";
|
|
60
|
-
const childExit = new Promise<number>((resolveExit, reject) => {
|
|
61
|
-
child.once("error", reject);
|
|
62
|
-
child.once("exit", (code, signal) => {
|
|
63
|
-
if (code !== null) {
|
|
64
|
-
resolveExit(code);
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
resolveExit(signal === null ? 0 : 1);
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
const destroyChildPipes = (): void => {
|
|
71
|
-
childInput.destroy();
|
|
72
|
-
childOutput.destroy();
|
|
73
|
-
};
|
|
74
|
-
void childExit.then(destroyChildPipes, destroyChildPipes);
|
|
75
|
-
// Parent-liveness watchdog: when the parent dies while holding our stdio
|
|
76
|
-
// open, the client stream never sees EOF, so the only settle path is to
|
|
77
|
-
// drop the client input, close the child pipes, and terminate the child.
|
|
78
|
-
// The bridge then resolves through the normal child-exit path, and the
|
|
79
|
-
// destroyed input releases its read handle so the process can actually
|
|
80
|
-
// exit (same teardown pattern as runJsonRpcStdioServer's own watchdog).
|
|
81
|
-
// In daemon mode the child is the upstream lightweight proxy, so killing
|
|
82
|
-
// it on parent death is correct; the detached daemon is a separate process
|
|
83
|
-
// and is never touched.
|
|
84
|
-
let parentWatchdogFired = false;
|
|
85
|
-
const parentWatchdog = createParentWatchdog(options.parentWatchdog, () => {
|
|
86
|
-
parentWatchdogFired = true;
|
|
87
|
-
options.input.destroy();
|
|
88
|
-
destroyChildPipes();
|
|
89
|
-
terminateCodegraphChild(child);
|
|
90
|
-
});
|
|
91
|
-
const clientForwardingDone = forwardClientToCodegraph(
|
|
92
|
-
options.input,
|
|
93
|
-
childInput,
|
|
94
|
-
pendingResponses,
|
|
95
|
-
(mode) => {
|
|
96
|
-
defaultResponseMode = mode;
|
|
97
|
-
},
|
|
98
|
-
() => parentWatchdogFired,
|
|
99
|
-
);
|
|
100
|
-
const responseForwardingDone = forwardCodegraphToClient(
|
|
101
|
-
childOutput,
|
|
102
|
-
options.output,
|
|
103
|
-
pendingResponses,
|
|
104
|
-
() => defaultResponseMode,
|
|
105
|
-
() => parentWatchdogFired,
|
|
106
|
-
);
|
|
107
|
-
const bridgeDone = Promise.all([clientForwardingDone, responseForwardingDone]);
|
|
108
|
-
const childAndResponsesDone = Promise.all([childExit, responseForwardingDone]).then(([exitCode]) => exitCode);
|
|
109
|
-
try {
|
|
110
|
-
return await Promise.race([childAndResponsesDone, bridgeDone.then(() => childExit)]);
|
|
111
|
-
} catch (error) {
|
|
112
|
-
destroyChildPipes();
|
|
113
|
-
if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL");
|
|
114
|
-
await childExit.catch(() => undefined);
|
|
115
|
-
throw error;
|
|
116
|
-
} finally {
|
|
117
|
-
parentWatchdog.clear();
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
function terminateCodegraphChild(child: ChildProcess): void {
|
|
122
|
-
if (child.exitCode !== null || child.signalCode !== null) return;
|
|
123
|
-
child.kill("SIGTERM");
|
|
124
|
-
const escalation = setTimeout(() => {
|
|
125
|
-
if (child.exitCode === null && child.signalCode === null) child.kill("SIGKILL");
|
|
126
|
-
}, SIGKILL_ESCALATION_MS);
|
|
127
|
-
escalation.unref();
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
// Stream errors raised by the watchdog's own teardown (input destroy, child
|
|
131
|
-
// pipe destroy) while a forwarder is parked on that stream.
|
|
132
|
-
function isWatchdogTeardownError(error: unknown): boolean {
|
|
133
|
-
if (!(error instanceof Error) || !("code" in error)) return false;
|
|
134
|
-
return (
|
|
135
|
-
error.code === "ERR_STREAM_PREMATURE_CLOSE" ||
|
|
136
|
-
error.code === "ERR_STREAM_DESTROYED" ||
|
|
137
|
-
error.code === "ERR_STREAM_WRITE_AFTER_END" ||
|
|
138
|
-
error.code === "EPIPE"
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
async function forwardClientToCodegraph(
|
|
143
|
-
input: Readable,
|
|
144
|
-
childInput: Writable,
|
|
145
|
-
pendingResponses: Map<string, PendingClientResponse>,
|
|
146
|
-
setDefaultResponseMode: (mode: StdioJsonRpcResponseMode) => void,
|
|
147
|
-
tolerateWatchdogClose: () => boolean,
|
|
148
|
-
): Promise<void> {
|
|
149
|
-
try {
|
|
150
|
-
for await (const message of readStdioJsonRpcMessages(input)) {
|
|
151
|
-
if (message.kind === "parse_error") {
|
|
152
|
-
continue;
|
|
153
|
-
}
|
|
154
|
-
const responseMode = message.responseMode;
|
|
155
|
-
setDefaultResponseMode(responseMode);
|
|
156
|
-
const key = responseModeKey(message.payload);
|
|
157
|
-
if (key !== null) {
|
|
158
|
-
pendingResponses.set(key, {
|
|
159
|
-
method: jsonRpcMethod(message.payload),
|
|
160
|
-
responseMode,
|
|
161
|
-
toolName: jsonRpcToolName(message.payload),
|
|
162
|
-
});
|
|
163
|
-
}
|
|
164
|
-
await writeLine(childInput, JSON.stringify(message.payload));
|
|
165
|
-
}
|
|
166
|
-
childInput.end();
|
|
167
|
-
} catch (error) {
|
|
168
|
-
// The parent watchdog destroys the client input and child pipes while
|
|
169
|
-
// this forwarder is parked on a read or write; that teardown is
|
|
170
|
-
// self-inflicted, so settle quietly and let the child-exit path report
|
|
171
|
-
// the outcome.
|
|
172
|
-
if (!(tolerateWatchdogClose() && isWatchdogTeardownError(error))) throw error;
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
async function forwardCodegraphToClient(
|
|
177
|
-
childOutput: Readable,
|
|
178
|
-
output: Writable,
|
|
179
|
-
pendingResponses: Map<string, PendingClientResponse>,
|
|
180
|
-
defaultResponseMode: () => StdioJsonRpcResponseMode,
|
|
181
|
-
tolerateWatchdogClose: () => boolean,
|
|
182
|
-
): Promise<void> {
|
|
183
|
-
try {
|
|
184
|
-
for await (const message of readStdioJsonRpcMessages(childOutput)) {
|
|
185
|
-
if (message.kind === "parse_error") {
|
|
186
|
-
await writeStdioJsonRpcResponse(output, errorResponse(null, -32700, "Parse error", message.message), defaultResponseMode());
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
const key = responseModeKey(message.payload);
|
|
190
|
-
const pendingResponse = key === null ? undefined : pendingResponses.get(key);
|
|
191
|
-
const responseMode = pendingResponse?.responseMode ?? defaultResponseMode();
|
|
192
|
-
if (key !== null) pendingResponses.delete(key);
|
|
193
|
-
await writeStdioJsonRpcResponse(output, clarifyCodegraphResponse(message.payload, pendingResponse), responseMode);
|
|
194
|
-
}
|
|
195
|
-
} catch (error) {
|
|
196
|
-
// The parent watchdog destroys the child pipes while this forwarder is
|
|
197
|
-
// parked on a read; that close is self-inflicted, so settle quietly and
|
|
198
|
-
// let the child-exit path report the outcome.
|
|
199
|
-
if (!(tolerateWatchdogClose() && isWatchdogTeardownError(error))) throw error;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
function responseModeKey(payload: unknown): string | null {
|
|
204
|
-
if (!isPlainRecord(payload) || !("id" in payload)) return null;
|
|
205
|
-
const id = jsonRpcId(payload["id"]);
|
|
206
|
-
return `${typeof id}:${String(id)}`;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
function jsonRpcMethod(payload: unknown): string | null {
|
|
210
|
-
if (!isPlainRecord(payload)) return null;
|
|
211
|
-
const method = payload["method"];
|
|
212
|
-
return typeof method === "string" ? method : null;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function jsonRpcToolName(payload: unknown): string | null {
|
|
216
|
-
if (jsonRpcMethod(payload) !== "tools/call" || !isPlainRecord(payload)) return null;
|
|
217
|
-
const params = payload["params"];
|
|
218
|
-
if (!isPlainRecord(params)) return null;
|
|
219
|
-
const name = params["name"];
|
|
220
|
-
return typeof name === "string" ? name : null;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
function clarifyCodegraphResponse(payload: unknown, pendingResponse: PendingClientResponse | undefined): unknown {
|
|
224
|
-
if (pendingResponse?.method === "tools/list") return clarifyCodegraphToolsList(payload);
|
|
225
|
-
if (pendingResponse?.method === "tools/call" && pendingResponse.toolName === "codegraph_node") {
|
|
226
|
-
return clarifyCodegraphNodeCallResult(payload);
|
|
227
|
-
}
|
|
228
|
-
return payload;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
function clarifyCodegraphToolsList(payload: unknown): unknown {
|
|
232
|
-
if (!isPlainRecord(payload)) return payload;
|
|
233
|
-
const result = payload["result"];
|
|
234
|
-
if (!isPlainRecord(result) || !Array.isArray(result["tools"])) return payload;
|
|
235
|
-
|
|
236
|
-
let changed = false;
|
|
237
|
-
const tools = result["tools"].map((tool) => {
|
|
238
|
-
if (!isPlainRecord(tool) || tool["name"] !== "codegraph_node") return tool;
|
|
239
|
-
if (!hasCodegraphNodeContractMetadata(tool)) return tool;
|
|
240
|
-
changed = true;
|
|
241
|
-
return clarifyCodegraphNodeTool(tool);
|
|
242
|
-
});
|
|
243
|
-
if (!changed) return payload;
|
|
244
|
-
return { ...payload, result: { ...result, tools } };
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
function clarifyCodegraphNodeTool(tool: Record<string, unknown>): Record<string, unknown> {
|
|
248
|
-
const clarified: Record<string, unknown> = {
|
|
249
|
-
...tool,
|
|
250
|
-
description: CODEGRAPH_NODE_DESCRIPTION,
|
|
251
|
-
};
|
|
252
|
-
const inputSchema = tool["inputSchema"];
|
|
253
|
-
if (isPlainRecord(inputSchema)) clarified["inputSchema"] = clarifyCodegraphNodeInputSchema(inputSchema);
|
|
254
|
-
return clarified;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
function hasCodegraphNodeContractMetadata(tool: Record<string, unknown>): boolean {
|
|
258
|
-
if (typeof tool["description"] === "string") return true;
|
|
259
|
-
const inputSchema = tool["inputSchema"];
|
|
260
|
-
if (!isPlainRecord(inputSchema)) return false;
|
|
261
|
-
const properties = inputSchema["properties"];
|
|
262
|
-
return isPlainRecord(properties) && isPlainRecord(properties["includeCode"]);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
function clarifyCodegraphNodeInputSchema(inputSchema: Record<string, unknown>): Record<string, unknown> {
|
|
266
|
-
const properties = inputSchema["properties"];
|
|
267
|
-
if (!isPlainRecord(properties)) return inputSchema;
|
|
268
|
-
const includeCode = properties["includeCode"];
|
|
269
|
-
if (!isPlainRecord(includeCode)) return inputSchema;
|
|
270
|
-
return {
|
|
271
|
-
...inputSchema,
|
|
272
|
-
properties: {
|
|
273
|
-
...properties,
|
|
274
|
-
includeCode: {
|
|
275
|
-
...includeCode,
|
|
276
|
-
description: CODEGRAPH_NODE_INCLUDE_CODE_DESCRIPTION,
|
|
277
|
-
},
|
|
278
|
-
},
|
|
279
|
-
};
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
function clarifyCodegraphNodeCallResult(payload: unknown): unknown {
|
|
283
|
-
if (!isPlainRecord(payload)) return payload;
|
|
284
|
-
const result = payload["result"];
|
|
285
|
-
if (!isPlainRecord(result) || !Array.isArray(result["content"])) return payload;
|
|
286
|
-
|
|
287
|
-
let changed = false;
|
|
288
|
-
const content = result["content"].map((item) => {
|
|
289
|
-
if (!isPlainRecord(item) || item["type"] !== "text" || typeof item["text"] !== "string") return item;
|
|
290
|
-
const text = clarifyContainerOutlineGuidance(item["text"]);
|
|
291
|
-
if (text === item["text"]) return item;
|
|
292
|
-
changed = true;
|
|
293
|
-
return { ...item, text };
|
|
294
|
-
});
|
|
295
|
-
if (!changed) return payload;
|
|
296
|
-
return { ...payload, result: { ...result, content } };
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
function clarifyContainerOutlineGuidance(text: string): string {
|
|
300
|
-
if (!text.includes("Structural outline only")) return text;
|
|
301
|
-
return text.replace(/Structural outline only[^\n]*(?:\n[^\n]*(?:Read|read)[^\n]*)?/g, CODEGRAPH_CONTAINER_OUTLINE_GUIDANCE);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
async function writeLine(output: Writable, line: string): Promise<void> {
|
|
305
|
-
if (output.write(`${line}\n`)) return;
|
|
306
|
-
await new Promise<void>((resolveDrain, reject) => {
|
|
307
|
-
output.once("drain", resolveDrain);
|
|
308
|
-
output.once("error", reject);
|
|
309
|
-
});
|
|
310
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import type { Readable, Writable } from "node:stream";
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
errorResponse,
|
|
5
|
-
isPlainRecord,
|
|
6
|
-
jsonRpcId,
|
|
7
|
-
runJsonRpcStdioServer,
|
|
8
|
-
successResponse,
|
|
9
|
-
type JsonRpcResponse,
|
|
10
|
-
type McpLifecycleLog,
|
|
11
|
-
type ParentWatchdogConfig,
|
|
12
|
-
} from "../../../../../mcp-stdio-core/src/index.ts";
|
|
13
|
-
|
|
14
|
-
export interface UnavailableCodegraphMcpOptions {
|
|
15
|
-
readonly input: Readable;
|
|
16
|
-
readonly output: Writable;
|
|
17
|
-
readonly reason: string;
|
|
18
|
-
readonly serverVersion: string;
|
|
19
|
-
// Test seam: production callers leave this unset so the watchdog uses its
|
|
20
|
-
// defaults (parentPid = process.ppid, 30s poll).
|
|
21
|
-
readonly parentWatchdog?: ParentWatchdogConfig;
|
|
22
|
-
// Test seam: surfaces the mcp-stdio-core lifecycle log so tests can pin the
|
|
23
|
-
// resolved idle timeout without waiting a real timeout out.
|
|
24
|
-
readonly lifecycleLog?: McpLifecycleLog;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
interface UnavailableCodegraphMcpHandlerOptions {
|
|
28
|
-
readonly reason: string;
|
|
29
|
-
readonly serverVersion: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export async function runUnavailableCodegraphMcpServer(
|
|
33
|
-
options: UnavailableCodegraphMcpOptions,
|
|
34
|
-
): Promise<void> {
|
|
35
|
-
await runJsonRpcStdioServer({
|
|
36
|
-
handler: handleUnavailableCodegraphMcpRequest,
|
|
37
|
-
handlerOptions: {
|
|
38
|
-
reason: options.reason.trim(),
|
|
39
|
-
serverVersion: options.serverVersion,
|
|
40
|
-
},
|
|
41
|
-
input: options.input,
|
|
42
|
-
output: options.output,
|
|
43
|
-
// Idle stays disabled: the codex host never respawns an exited stdio
|
|
44
|
-
// MCP server (codex-rs auto-reconnects only its own codex_apps server),
|
|
45
|
-
// and since #6548 the default idle timer actually destroys stdin — so an
|
|
46
|
-
// inherited 10-minute default would silently kill this stub mid-session
|
|
47
|
-
// and turn later codegraph tool calls into dead-connection errors.
|
|
48
|
-
idleTimeoutMs: 0,
|
|
49
|
-
parentWatchdog: options.parentWatchdog ?? {},
|
|
50
|
-
// Conditional spread keeps this assignable under exactOptionalPropertyTypes.
|
|
51
|
-
...(options.lifecycleLog === undefined ? {} : { log: options.lifecycleLog }),
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
async function handleUnavailableCodegraphMcpRequest(
|
|
56
|
-
input: unknown,
|
|
57
|
-
options: UnavailableCodegraphMcpHandlerOptions,
|
|
58
|
-
): Promise<JsonRpcResponse | undefined> {
|
|
59
|
-
if (!isPlainRecord(input)) {
|
|
60
|
-
return errorResponse(null, -32600, "Invalid Request");
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
const id = jsonRpcId(input["id"]);
|
|
64
|
-
const method = input["method"];
|
|
65
|
-
if (method === "notifications/initialized") return undefined;
|
|
66
|
-
if (method === "ping") return successResponse(id, {});
|
|
67
|
-
if (method === "initialize") {
|
|
68
|
-
return successResponse(id, {
|
|
69
|
-
capabilities: { tools: { listChanged: false } },
|
|
70
|
-
protocolVersion: requestedProtocolVersion(input["params"]),
|
|
71
|
-
serverInfo: { name: "codegraph", version: options.serverVersion },
|
|
72
|
-
});
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
if (method === "tools/list") {
|
|
76
|
-
return successResponse(id, { tools: [] });
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (method === "tools/call") {
|
|
80
|
-
return successResponse(id, {
|
|
81
|
-
content: [{ text: options.reason, type: "text" }],
|
|
82
|
-
isError: true,
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return errorResponse(id, -32601, `Method not found: ${String(method)}`);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
function requestedProtocolVersion(params: unknown): string {
|
|
90
|
-
if (!isPlainRecord(params) || typeof params["protocolVersion"] !== "string") return "2024-11-05";
|
|
91
|
-
return params["protocolVersion"];
|
|
92
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { env as processEnv, stdin as processStdin, stdout as processStdout } from "node:process";
|
|
2
|
-
|
|
3
|
-
import { buildCodegraphInitGuidanceForToolResult } from "../../../../../utils/src/codegraph/guidance.ts";
|
|
4
|
-
import { isRecord, readHookInput, resolveHomeDir } from "./hook-input.js";
|
|
5
|
-
import type { PostToolUseHookOptions, PostToolUseHookResult } from "./hook-types.js";
|
|
6
|
-
|
|
7
|
-
export async function runCodegraphPostToolUseHookCli(options: PostToolUseHookOptions = {}): Promise<number> {
|
|
8
|
-
return (await executeCodegraphPostToolUseHook(options)).exitCode;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export async function executeCodegraphPostToolUseHook(options: PostToolUseHookOptions = {}): Promise<PostToolUseHookResult> {
|
|
12
|
-
const env = options.env ?? processEnv;
|
|
13
|
-
const input = await readHookInput(options.stdin ?? processStdin);
|
|
14
|
-
const output = runCodegraphPostToolUseHook(input, { homeDir: resolveHomeDir(env) });
|
|
15
|
-
if (output.length === 0) return { action: "skipped", exitCode: 0 };
|
|
16
|
-
|
|
17
|
-
(options.stdout ?? processStdout).write(output);
|
|
18
|
-
return { action: "emitted-guidance", exitCode: 0 };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function runCodegraphPostToolUseHook(input: unknown, options: { readonly homeDir?: string } = {}): string {
|
|
22
|
-
const toolName = isRecord(input) ? input["tool_name"] : undefined;
|
|
23
|
-
const cwd = isRecord(input) ? input["cwd"] : undefined;
|
|
24
|
-
const toolOutput = isRecord(input) ? (input["tool_response"] ?? input["tool_output"] ?? input["response"]) : input;
|
|
25
|
-
const guidance = buildCodegraphInitGuidanceForToolResult({ cwd, toolName, toolOutput }, options);
|
|
26
|
-
if (guidance === null) return "";
|
|
27
|
-
|
|
28
|
-
return `${JSON.stringify({
|
|
29
|
-
hookSpecificOutput: {
|
|
30
|
-
hookEventName: "PostToolUse",
|
|
31
|
-
additionalContext: guidance,
|
|
32
|
-
},
|
|
33
|
-
})}\n`;
|
|
34
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { extname } from "node:path";
|
|
2
|
-
import { execPath as processExecPath } from "node:process";
|
|
3
|
-
|
|
4
|
-
export interface ServeProcessInvocation {
|
|
5
|
-
readonly args: readonly string[];
|
|
6
|
-
readonly command: string;
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
const WINDOWS_CMD_EXTENSIONS = new Set([".bat", ".cmd"]);
|
|
10
|
-
const WINDOWS_NODE_SCRIPT_EXTENSIONS = new Set([".cjs", ".js", ".mjs"]);
|
|
11
|
-
|
|
12
|
-
export function resolveServeProcessInvocation(
|
|
13
|
-
command: string,
|
|
14
|
-
args: readonly string[],
|
|
15
|
-
platform: NodeJS.Platform = process.platform,
|
|
16
|
-
): ServeProcessInvocation {
|
|
17
|
-
if (platform !== "win32") return { args: [...args], command };
|
|
18
|
-
|
|
19
|
-
const extension = extname(command).toLowerCase();
|
|
20
|
-
if (WINDOWS_NODE_SCRIPT_EXTENSIONS.has(extension)) {
|
|
21
|
-
return { args: [command, ...args], command: processExecPath };
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
if (WINDOWS_CMD_EXTENSIONS.has(extension)) {
|
|
25
|
-
return { args: ["/d", "/s", "/c", command, ...args], command: "cmd.exe" };
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return { args: [...args], command };
|
|
29
|
-
}
|