@lannguyensi/harness 0.40.0 → 0.42.0
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/CHANGELOG.md +68 -0
- package/README.md +9 -0
- package/dist/cli/adopt/derive.d.ts +15 -0
- package/dist/cli/adopt/derive.js +34 -7
- package/dist/cli/adopt/derive.js.map +1 -1
- package/dist/cli/adopt/index.d.ts +30 -0
- package/dist/cli/adopt/index.js +23 -3
- package/dist/cli/adopt/index.js.map +1 -1
- package/dist/cli/apply/generate-settings.d.ts +14 -1
- package/dist/cli/apply/generate-settings.js +7 -3
- package/dist/cli/apply/generate-settings.js.map +1 -1
- package/dist/cli/approve/stdin-report.js +2 -0
- package/dist/cli/approve/stdin-report.js.map +1 -1
- package/dist/cli/approve/understanding.js +28 -0
- package/dist/cli/approve/understanding.js.map +1 -1
- package/dist/cli/doctor/claude-mcp.d.ts +50 -0
- package/dist/cli/doctor/claude-mcp.js +170 -0
- package/dist/cli/doctor/claude-mcp.js.map +1 -0
- package/dist/cli/doctor/codex.d.ts +8 -0
- package/dist/cli/doctor/codex.js +8 -1
- package/dist/cli/doctor/codex.js.map +1 -1
- package/dist/cli/doctor/format.js +60 -11
- package/dist/cli/doctor/format.js.map +1 -1
- package/dist/cli/doctor/index.d.ts +46 -0
- package/dist/cli/doctor/index.js +155 -29
- package/dist/cli/doctor/index.js.map +1 -1
- package/dist/cli/doctor/npm-bin-path.js +42 -0
- package/dist/cli/doctor/npm-bin-path.js.map +1 -1
- package/dist/cli/doctor/types.d.ts +37 -0
- package/dist/cli/doctor/types.js.map +1 -1
- package/dist/cli/dry-run.js +5 -0
- package/dist/cli/dry-run.js.map +1 -1
- package/dist/cli/explain.js +16 -3
- package/dist/cli/explain.js.map +1 -1
- package/dist/cli/index.js +328 -11
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/agent-tasks-auth.js +32 -0
- package/dist/cli/init/agent-tasks-auth.js.map +1 -1
- package/dist/cli/init/composer.js +13 -40
- package/dist/cli/init/composer.js.map +1 -1
- package/dist/cli/init/dependencies.js +21 -0
- package/dist/cli/init/dependencies.js.map +1 -1
- package/dist/cli/init/detect.d.ts +20 -3
- package/dist/cli/init/detect.js +34 -36
- package/dist/cli/init/detect.js.map +1 -1
- package/dist/cli/init/index.d.ts +18 -0
- package/dist/cli/init/index.js +28 -2
- package/dist/cli/init/index.js.map +1 -1
- package/dist/cli/init/interactive.d.ts +41 -0
- package/dist/cli/init/interactive.js +421 -6
- package/dist/cli/init/interactive.js.map +1 -1
- package/dist/cli/init/profiles.d.ts +2 -2
- package/dist/cli/init/profiles.js +10 -1
- package/dist/cli/init/profiles.js.map +1 -1
- package/dist/cli/init/templates.d.ts +1 -1
- package/dist/cli/init/templates.js +217 -8
- package/dist/cli/init/templates.js.map +1 -1
- package/dist/cli/list.js +3 -1
- package/dist/cli/list.js.map +1 -1
- package/dist/cli/main.js +10 -0
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/pack/hook-bootstrap.d.ts +24 -0
- package/dist/cli/pack/hook-bootstrap.js +47 -1
- package/dist/cli/pack/hook-bootstrap.js.map +1 -1
- package/dist/cli/pack/hook-branch-protection.js +9 -1
- package/dist/cli/pack/hook-branch-protection.js.map +1 -1
- package/dist/cli/pack/hook-codex-post-tool-use.d.ts +25 -0
- package/dist/cli/pack/hook-codex-post-tool-use.js +160 -0
- package/dist/cli/pack/hook-codex-post-tool-use.js.map +1 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.d.ts +1 -0
- package/dist/cli/pack/hook-codex-pre-tool-use.js +43 -10
- package/dist/cli/pack/hook-codex-pre-tool-use.js.map +1 -1
- package/dist/cli/pack/hook-codex-stop.js +1 -8
- package/dist/cli/pack/hook-codex-stop.js.map +1 -1
- package/dist/cli/pack/hook-post-merge-gate-record.d.ts +30 -0
- package/dist/cli/pack/hook-post-merge-gate-record.js +153 -0
- package/dist/cli/pack/hook-post-merge-gate-record.js.map +1 -0
- package/dist/cli/pack/hook-post-merge-gate.d.ts +28 -0
- package/dist/cli/pack/hook-post-merge-gate.js +244 -0
- package/dist/cli/pack/hook-post-merge-gate.js.map +1 -0
- package/dist/cli/pack/hook-post-tool-use.js +16 -131
- package/dist/cli/pack/hook-post-tool-use.js.map +1 -1
- package/dist/cli/pack/hook-pre-tool-use.js +54 -2
- package/dist/cli/pack/hook-pre-tool-use.js.map +1 -1
- package/dist/cli/pack/hook-solution-acceptance-writeguard.js +148 -2
- package/dist/cli/pack/hook-solution-acceptance-writeguard.js.map +1 -1
- package/dist/cli/pack/hook-stay-in-scope.js +63 -20
- package/dist/cli/pack/hook-stay-in-scope.js.map +1 -1
- package/dist/cli/pack/hook-track-active-claim.js +33 -9
- package/dist/cli/pack/hook-track-active-claim.js.map +1 -1
- package/dist/cli/pack/index.d.ts +2 -1
- package/dist/cli/pack/index.js +2 -1
- package/dist/cli/pack/index.js.map +1 -1
- package/dist/cli/pack/mutate.d.ts +19 -0
- package/dist/cli/pack/mutate.js +38 -0
- package/dist/cli/pack/mutate.js.map +1 -1
- package/dist/cli/pack/reseed.d.ts +19 -0
- package/dist/cli/pack/reseed.js +118 -0
- package/dist/cli/pack/reseed.js.map +1 -0
- package/dist/cli/pack/understanding-report-schema-hint.js +1 -1
- package/dist/cli/pack/understanding-report-schema-hint.js.map +1 -1
- package/dist/cli/pause/index.js +12 -3
- package/dist/cli/pause/index.js.map +1 -1
- package/dist/cli/record/index.d.ts +64 -0
- package/dist/cli/record/index.js +211 -0
- package/dist/cli/record/index.js.map +1 -0
- package/dist/cli/session-start/index.d.ts +21 -0
- package/dist/cli/session-start/index.js +160 -25
- package/dist/cli/session-start/index.js.map +1 -1
- package/dist/cli/session-start/toolchain-parity.d.ts +149 -0
- package/dist/cli/session-start/toolchain-parity.js +618 -0
- package/dist/cli/session-start/toolchain-parity.js.map +1 -0
- package/dist/cli/uninstall/index.d.ts +73 -1
- package/dist/cli/uninstall/index.js +134 -2
- package/dist/cli/uninstall/index.js.map +1 -1
- package/dist/cli/validate/checks.js +8 -0
- package/dist/cli/validate/checks.js.map +1 -1
- package/dist/io/claude-mcp.d.ts +258 -0
- package/dist/io/claude-mcp.js +544 -0
- package/dist/io/claude-mcp.js.map +1 -0
- package/dist/policies/ledger-client.d.ts +34 -1
- package/dist/policies/ledger-client.js +21 -16
- package/dist/policies/ledger-client.js.map +1 -1
- package/dist/policy-packs/builtin/branch-protection-runtime.d.ts +4 -2
- package/dist/policy-packs/builtin/branch-protection-runtime.js +4 -2
- package/dist/policy-packs/builtin/branch-protection-runtime.js.map +1 -1
- package/dist/policy-packs/builtin/branch-protection.d.ts +10 -1
- package/dist/policy-packs/builtin/branch-protection.js +17 -0
- package/dist/policy-packs/builtin/branch-protection.js.map +1 -1
- package/dist/policy-packs/builtin/post-merge-gate-runtime.d.ts +195 -0
- package/dist/policy-packs/builtin/post-merge-gate-runtime.js +290 -0
- package/dist/policy-packs/builtin/post-merge-gate-runtime.js.map +1 -0
- package/dist/policy-packs/builtin/post-merge-gate.d.ts +56 -0
- package/dist/policy-packs/builtin/post-merge-gate.js +291 -0
- package/dist/policy-packs/builtin/post-merge-gate.js.map +1 -0
- package/dist/policy-packs/builtin/solution-acceptance-runtime.js +28 -13
- package/dist/policy-packs/builtin/solution-acceptance-runtime.js.map +1 -1
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.d.ts +197 -24
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js +342 -40
- package/dist/policy-packs/builtin/understanding-before-execution-runtime.js.map +1 -1
- package/dist/policy-packs/builtin/understanding-before-execution.d.ts +26 -1
- package/dist/policy-packs/builtin/understanding-before-execution.js +302 -17
- package/dist/policy-packs/builtin/understanding-before-execution.js.map +1 -1
- package/dist/policy-packs/registry.d.ts +23 -2
- package/dist/policy-packs/registry.js +31 -2
- package/dist/policy-packs/registry.js.map +1 -1
- package/dist/policy-packs/ux-compare.d.ts +14 -0
- package/dist/policy-packs/ux-compare.js +58 -0
- package/dist/policy-packs/ux-compare.js.map +1 -0
- package/dist/policy-packs/ux-drift-check.d.ts +27 -0
- package/dist/policy-packs/ux-drift-check.js +78 -0
- package/dist/policy-packs/ux-drift-check.js.map +1 -0
- package/dist/probes/mcp.d.ts +13 -0
- package/dist/probes/mcp.js +57 -0
- package/dist/probes/mcp.js.map +1 -1
- package/dist/runtime/approval-signing.d.ts +82 -0
- package/dist/runtime/approval-signing.js +275 -0
- package/dist/runtime/approval-signing.js.map +1 -0
- package/dist/runtime/git-context.d.ts +50 -0
- package/dist/runtime/git-context.js +108 -1
- package/dist/runtime/git-context.js.map +1 -1
- package/dist/runtime/hermetic-spawn-guard.d.ts +25 -0
- package/dist/runtime/hermetic-spawn-guard.js +136 -0
- package/dist/runtime/hermetic-spawn-guard.js.map +1 -0
- package/dist/runtime/intercept.js +62 -5
- package/dist/runtime/intercept.js.map +1 -1
- package/dist/runtime/ledger-writer.d.ts +27 -0
- package/dist/runtime/ledger-writer.js +46 -0
- package/dist/runtime/ledger-writer.js.map +1 -0
- package/dist/runtime/pause-sentinel.js +14 -3
- package/dist/runtime/pause-sentinel.js.map +1 -1
- package/dist/runtime/read-only-bash.js +118 -0
- package/dist/runtime/read-only-bash.js.map +1 -1
- package/dist/runtime/recovery-git-commit.d.ts +22 -0
- package/dist/runtime/recovery-git-commit.js +284 -0
- package/dist/runtime/recovery-git-commit.js.map +1 -0
- package/dist/runtime/tool-name-aliases.d.ts +1 -0
- package/dist/runtime/tool-name-aliases.js +7 -1
- package/dist/runtime/tool-name-aliases.js.map +1 -1
- package/dist/schema/index.d.ts +94 -42
- package/dist/schema/index.js +5 -0
- package/dist/schema/index.js.map +1 -1
- package/dist/schema/policies.d.ts +56 -44
- package/dist/schema/policies.js +79 -9
- package/dist/schema/policies.js.map +1 -1
- package/dist/schema/toolchain-parity.d.ts +18 -0
- package/dist/schema/toolchain-parity.js +35 -0
- package/dist/schema/toolchain-parity.js.map +1 -0
- package/package.json +4 -2
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
import { spawn } from "node:child_process";
|
|
19
19
|
import { existsSync, accessSync, constants } from "node:fs";
|
|
20
20
|
import * as path from "node:path";
|
|
21
|
+
import { assertNoRealSpawnInTests } from "../../runtime/hermetic-spawn-guard.js";
|
|
21
22
|
export const PROFILE_DEPENDENCIES = {
|
|
22
23
|
solo: [
|
|
23
24
|
{
|
|
@@ -267,7 +268,27 @@ export function formatDependencyTable(profile, result) {
|
|
|
267
268
|
}
|
|
268
269
|
return lines.join("\n");
|
|
269
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* Hermetic guard (task 54739002): asserts BEFORE touching
|
|
273
|
+
* `child_process` that we are not running under vitest without a test
|
|
274
|
+
* having injected `installSpawn`. This is the `npm i -g` install path —
|
|
275
|
+
* the largest blast radius of the guarded call sites, since an
|
|
276
|
+
* accidental real spawn here would actually install packages globally
|
|
277
|
+
* on whatever machine runs the tests. See
|
|
278
|
+
* src/runtime/hermetic-spawn-guard.ts for why and the env signal used.
|
|
279
|
+
* `installPackagesGlobally` has no try/catch around this call, so the
|
|
280
|
+
* thrown `HermeticSpawnViolationError` propagates directly to the
|
|
281
|
+
* caller — nothing here can degrade it to a warning. Local
|
|
282
|
+
* "no try/catch here" is not the actual guarantee, though: the OW guard
|
|
283
|
+
* (src/cli/init/interactive.ts) proved a local absence-of-catch argument
|
|
284
|
+
* isn't enough on its own — that violation had to survive a catch
|
|
285
|
+
* further up the call chain. The real backstop is runInteractive's outer
|
|
286
|
+
* catch (src/cli/init/interactive.ts:1297), which explicitly re-throws
|
|
287
|
+
* any `HermeticSpawnViolationError` past every intermediate handler
|
|
288
|
+
* between here and the wizard's top level.
|
|
289
|
+
*/
|
|
270
290
|
function realSpawn(cmd, args) {
|
|
291
|
+
assertNoRealSpawnInTests("npm i -g", "Inject a fake `installSpawn` runner in the test instead of exercising the real spawn path.");
|
|
271
292
|
return new Promise((resolve) => {
|
|
272
293
|
const child = spawn(cmd, args, { stdio: ["ignore", "inherit", "pipe"] });
|
|
273
294
|
let stderr = "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../../src/cli/init/dependencies.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,2BAA2B;AAC3B,EAAE;AACF,oEAAoE;AACpE,sEAAsE;AACtE,uEAAuE;AACvE,wEAAwE;AACxE,mEAAmE;AACnE,uEAAuE;AACvE,oEAAoE;AACpE,iEAAiE;AACjE,EAAE;AACF,wEAAwE;AACxE,uEAAuE;AACvE,kEAAkE;AAClE,iEAAiE;AACjE,mDAAmD;AAEnD,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AA+
|
|
1
|
+
{"version":3,"file":"dependencies.js","sourceRoot":"","sources":["../../../src/cli/init/dependencies.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,12 +7,14 @@ export interface DetectedRuntime {
|
|
|
7
7
|
/** The runtime's primary config file path. */
|
|
8
8
|
settingsPath: string;
|
|
9
9
|
settingsExists: boolean;
|
|
10
|
-
/** Set when settingsExists but parsing failed. settingsExists stays true. */
|
|
11
|
-
settingsParseError?: string;
|
|
12
10
|
}
|
|
13
11
|
export interface DetectedMcpServer {
|
|
14
12
|
name: string;
|
|
15
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Which runtime this entry was read from. v1: only claude-code — read
|
|
15
|
+
* from its effective user-scope registry (~/.claude.json), not
|
|
16
|
+
* settings.json (task 83d8d03a).
|
|
17
|
+
*/
|
|
16
18
|
runtime: "claude-code";
|
|
17
19
|
command: string;
|
|
18
20
|
args: string[];
|
|
@@ -30,9 +32,24 @@ export interface DetectionResult {
|
|
|
30
32
|
runtimes: DetectedRuntime[];
|
|
31
33
|
manifest: DetectedManifest;
|
|
32
34
|
mcpServers: DetectedMcpServer[];
|
|
35
|
+
/**
|
|
36
|
+
* Set when the Claude Code user-scope MCP registry (~/.claude.json /
|
|
37
|
+
* $CLAUDE_CONFIG_DIR/.claude.json) exists but could not be read safely
|
|
38
|
+
* (malformed JSON, `mcpServers` not an object). A missing registry file
|
|
39
|
+
* is NOT an error — `mcpServers` is simply `[]` in that case; this field
|
|
40
|
+
* lets a caller distinguish "genuinely not registered" from "could not
|
|
41
|
+
* tell" instead of detect() silently guessing empty (task 83d8d03a).
|
|
42
|
+
*/
|
|
43
|
+
mcpRegistryParseError?: string;
|
|
33
44
|
}
|
|
34
45
|
export interface DetectOptions {
|
|
35
46
|
/** Override `os.homedir()` for tests. */
|
|
36
47
|
homeDir?: string;
|
|
48
|
+
/**
|
|
49
|
+
* Override for process.env (CLAUDE_CONFIG_DIR lookup) used to resolve
|
|
50
|
+
* the Claude Code user-scope MCP registry path. Defaults to
|
|
51
|
+
* `process.env`.
|
|
52
|
+
*/
|
|
53
|
+
env?: NodeJS.ProcessEnv;
|
|
37
54
|
}
|
|
38
55
|
export declare function detect(opts?: DetectOptions): Promise<DetectionResult>;
|
package/dist/cli/init/detect.js
CHANGED
|
@@ -4,12 +4,21 @@
|
|
|
4
4
|
// shape, never thrown. No writes, no network, no child processes.
|
|
5
5
|
//
|
|
6
6
|
// v1 scope (mirrors task c5287b80): Claude Code + Codex. MCP detection
|
|
7
|
-
// reads Claude Code's
|
|
8
|
-
//
|
|
9
|
-
//
|
|
7
|
+
// reads Claude Code's EFFECTIVE user-scope registration only — the
|
|
8
|
+
// top-level `mcpServers` key of `~/.claude.json` /
|
|
9
|
+
// `$CLAUDE_CONFIG_DIR/.claude.json`, read read-only via
|
|
10
|
+
// `readTopLevelMcpServers` (io/claude-mcp.ts) (task 83d8d03a). It no
|
|
11
|
+
// longer reads the `mcpServers` block in `~/.claude/settings.json`: Claude
|
|
12
|
+
// Code never consumed that block at runtime (see io/claude-mcp.ts:1-9),
|
|
13
|
+
// so `team`/`full` profile recognition (interactive.ts's
|
|
14
|
+
// `detectionHasAgentTasks`) would otherwise key off dead state. Codex's
|
|
15
|
+
// TOML parser lives in the v1.1 opencode-adapter task. The result is
|
|
16
|
+
// still useful for Codex users: `runtimes[]` flags presence so the
|
|
17
|
+
// wizard can pre-select.
|
|
10
18
|
import * as fs from "node:fs";
|
|
11
19
|
import * as os from "node:os";
|
|
12
20
|
import * as path from "node:path";
|
|
21
|
+
import { readTopLevelMcpServers, resolveClaudeUserRegistryPath } from "../../io/claude-mcp.js";
|
|
13
22
|
import { resolveHomeDir } from "../../runtime/home-dir.js";
|
|
14
23
|
import { VERSION } from "../../version.js";
|
|
15
24
|
function resolveHome(opts) {
|
|
@@ -23,14 +32,6 @@ function safeStat(p) {
|
|
|
23
32
|
return null;
|
|
24
33
|
}
|
|
25
34
|
}
|
|
26
|
-
function safeReadFile(p) {
|
|
27
|
-
try {
|
|
28
|
-
return fs.readFileSync(p, "utf8");
|
|
29
|
-
}
|
|
30
|
-
catch {
|
|
31
|
-
return null;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
35
|
function detectClaudeRuntime(home) {
|
|
35
36
|
const claudeHome = path.join(home, ".claude");
|
|
36
37
|
const settingsPath = path.join(claudeHome, "settings.json");
|
|
@@ -58,28 +59,24 @@ function detectCodexRuntime(home) {
|
|
|
58
59
|
settingsExists: settingsStat?.isFile() ?? false,
|
|
59
60
|
};
|
|
60
61
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return { servers: [], parseError: `settings.json invalid JSON: ${err.message}` };
|
|
74
|
-
}
|
|
75
|
-
const entries = parsed.mcpServers;
|
|
76
|
-
if (!entries || typeof entries !== "object")
|
|
77
|
-
return { servers: [] };
|
|
62
|
+
/**
|
|
63
|
+
* Read Claude Code's EFFECTIVE user-scope MCP registration: the top-level
|
|
64
|
+
* `mcpServers` key of `~/.claude.json` / `$CLAUDE_CONFIG_DIR/.claude.json`
|
|
65
|
+
* (task 83d8d03a), via the shared read-only primitive in io/claude-mcp.ts.
|
|
66
|
+
* Never reads `~/.claude/settings.json` for this — Claude Code does not
|
|
67
|
+
* consume that file's `mcpServers` block at runtime. A missing registry
|
|
68
|
+
* file is not an error (empty list); malformed JSON / a non-object
|
|
69
|
+
* `mcpServers` is reported via `parseError` rather than guessed at.
|
|
70
|
+
*/
|
|
71
|
+
function parseClaudeMcpServers(runtime, env) {
|
|
72
|
+
const registryPath = resolveClaudeUserRegistryPath({ homeDir: runtime.home, env });
|
|
73
|
+
const { servers: rawServers, error } = readTopLevelMcpServers(registryPath);
|
|
78
74
|
const servers = [];
|
|
79
|
-
for (const name of Object.keys(
|
|
80
|
-
const
|
|
81
|
-
if (
|
|
75
|
+
for (const name of Object.keys(rawServers).sort()) {
|
|
76
|
+
const entryRaw = rawServers[name];
|
|
77
|
+
if (typeof entryRaw !== "object" || entryRaw === null || Array.isArray(entryRaw))
|
|
82
78
|
continue;
|
|
79
|
+
const entry = entryRaw;
|
|
83
80
|
if (typeof entry.command !== "string" || entry.command.length === 0)
|
|
84
81
|
continue;
|
|
85
82
|
const args = Array.isArray(entry.args)
|
|
@@ -87,7 +84,7 @@ function parseClaudeMcpServers(runtime) {
|
|
|
87
84
|
: [];
|
|
88
85
|
servers.push({ name, runtime: "claude-code", command: entry.command, args });
|
|
89
86
|
}
|
|
90
|
-
return { servers };
|
|
87
|
+
return error !== null ? { servers, parseError: error } : { servers };
|
|
91
88
|
}
|
|
92
89
|
function detectManifest(userHome) {
|
|
93
90
|
// The harness manifest lives under the runtime-neutral harness home
|
|
@@ -111,14 +108,15 @@ export async function detect(opts = {}) {
|
|
|
111
108
|
const claude = detectClaudeRuntime(home);
|
|
112
109
|
const codex = detectCodexRuntime(home);
|
|
113
110
|
const manifest = detectManifest(home);
|
|
114
|
-
const { servers, parseError } = parseClaudeMcpServers(claude);
|
|
115
|
-
|
|
116
|
-
claude.settingsParseError = parseError;
|
|
117
|
-
return {
|
|
111
|
+
const { servers, parseError } = parseClaudeMcpServers(claude, opts.env ?? process.env);
|
|
112
|
+
const result = {
|
|
118
113
|
harness: { version: VERSION },
|
|
119
114
|
runtimes: [claude, codex],
|
|
120
115
|
manifest,
|
|
121
116
|
mcpServers: servers,
|
|
122
117
|
};
|
|
118
|
+
if (parseError !== undefined)
|
|
119
|
+
result.mcpRegistryParseError = parseError;
|
|
120
|
+
return result;
|
|
123
121
|
}
|
|
124
122
|
//# sourceMappingURL=detect.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../../src/cli/init/detect.ts"],"names":[],"mappings":"AAAA,wEAAwE;AACxE,wEAAwE;AACxE,wEAAwE;AACxE,kEAAkE;AAClE,EAAE;AACF,uEAAuE;AACvE,wEAAwE;AACxE,
|
|
1
|
+
{"version":3,"file":"detect.js","sourceRoot":"","sources":["../../../src/cli/init/detect.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/init/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { NpmExec } from "../doctor/npm-bin-path.js";
|
|
1
2
|
import { type TemplateName } from "./templates.js";
|
|
2
3
|
export interface InitOptions {
|
|
3
4
|
template?: TemplateName;
|
|
@@ -17,6 +18,13 @@ export interface InitOptions {
|
|
|
17
18
|
force?: boolean;
|
|
18
19
|
configPath?: string;
|
|
19
20
|
homeDir?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Test-injection knobs for the post-write bin-resolution check (task
|
|
23
|
+
* 7f8fb4bc). Production leaves both undefined and gets the real PATH /
|
|
24
|
+
* `npm prefix -g` spawn.
|
|
25
|
+
*/
|
|
26
|
+
pathEnv?: string;
|
|
27
|
+
npmBinExec?: NpmExec;
|
|
20
28
|
}
|
|
21
29
|
export interface InitResult {
|
|
22
30
|
path: string;
|
|
@@ -28,6 +36,16 @@ export interface InitResult {
|
|
|
28
36
|
overwrote: boolean;
|
|
29
37
|
stdout: string;
|
|
30
38
|
stderr: string;
|
|
39
|
+
/**
|
|
40
|
+
* Count of declared, enabled MCP binaries and REQUIRED CLI binaries
|
|
41
|
+
* that do not resolve on PATH right after the write (task 7f8fb4bc).
|
|
42
|
+
* Non-interactive `init` deliberately does not throw on this — a bare
|
|
43
|
+
* `harness init --template full` is expected to be followed by a
|
|
44
|
+
* separate dependency install before `harness apply` / `harness
|
|
45
|
+
* doctor`, unlike the interactive wizard which already offers to
|
|
46
|
+
* install deps first. 0 when every binary resolves (or none declared).
|
|
47
|
+
*/
|
|
48
|
+
binResolutionErrorCount: number;
|
|
31
49
|
}
|
|
32
50
|
export declare function init(opts?: InitOptions): Promise<InitResult>;
|
|
33
51
|
export declare const KNOWN_TEMPLATES: TemplateName[];
|
package/dist/cli/init/index.js
CHANGED
|
@@ -6,6 +6,8 @@ import { withFileLock } from "../../io/lock.js";
|
|
|
6
6
|
import { formatValidationErrors, validateBeforeWrite, } from "../../io/validate-before-write.js";
|
|
7
7
|
import { parse as parseYaml } from "yaml";
|
|
8
8
|
import { EX_FAIL, EX_SOFTWARE, HarnessExitError } from "../exit-codes.js";
|
|
9
|
+
import { parseManifest } from "../../schema/index.js";
|
|
10
|
+
import { checkBinResolution, formatBinResolutionIssues } from "../doctor/index.js";
|
|
9
11
|
import { getTemplate } from "./templates.js";
|
|
10
12
|
const DEFAULT_BASENAME = "harness.yaml";
|
|
11
13
|
const LOCK_BASENAME = ".harness.lock";
|
|
@@ -48,7 +50,24 @@ export async function init(opts = {}) {
|
|
|
48
50
|
}
|
|
49
51
|
atomicWriteFile(target, content);
|
|
50
52
|
});
|
|
51
|
-
|
|
53
|
+
// Bin-resolution check (task 7f8fb4bc): validateBeforeWrite only checked
|
|
54
|
+
// the manifest's shape, not whether the binaries it declares actually
|
|
55
|
+
// resolve. Re-parsing here is cheap (validateBeforeWrite already proved
|
|
56
|
+
// it parses clean) and lets a fresh `harness init` surface an
|
|
57
|
+
// unresolvable MCP/CLI binary immediately — including the PATH-shadow
|
|
58
|
+
// case (installed, but under a dir not on PATH) that used to only show
|
|
59
|
+
// up later as an opaque `harness doctor` crash.
|
|
60
|
+
const manifest = parseManifest(parseYaml(content));
|
|
61
|
+
const binReport = await checkBinResolution(manifest, {
|
|
62
|
+
...(opts.pathEnv !== undefined ? { pathEnv: opts.pathEnv } : {}),
|
|
63
|
+
...(opts.npmBinExec !== undefined ? { npmBinExec: opts.npmBinExec } : {}),
|
|
64
|
+
});
|
|
65
|
+
let stderr = exists ? `(overwriting existing manifest at ${target})\n` : "";
|
|
66
|
+
if (binReport.errorCount > 0) {
|
|
67
|
+
stderr += `${formatBinResolutionIssues(binReport).join("\n")}\n`;
|
|
68
|
+
stderr +=
|
|
69
|
+
"\nSome declared binaries are not resolvable; install them or fix PATH, then re-run `harness doctor`.\n";
|
|
70
|
+
}
|
|
52
71
|
const stdout = [
|
|
53
72
|
`harness manifest written to ${target} (template: ${templateLabel})`,
|
|
54
73
|
"",
|
|
@@ -58,7 +77,14 @@ export async function init(opts = {}) {
|
|
|
58
77
|
` harness doctor --config ${target}`,
|
|
59
78
|
"",
|
|
60
79
|
].join("\n");
|
|
61
|
-
return {
|
|
80
|
+
return {
|
|
81
|
+
path: target,
|
|
82
|
+
template: templateLabel,
|
|
83
|
+
overwrote: exists,
|
|
84
|
+
stdout,
|
|
85
|
+
stderr,
|
|
86
|
+
binResolutionErrorCount: binReport.errorCount,
|
|
87
|
+
};
|
|
62
88
|
}
|
|
63
89
|
export const KNOWN_TEMPLATES = ["minimal", "solo", "team", "full"];
|
|
64
90
|
export function isTemplate(s) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/init/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EACL,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,KAAK,IAAI,SAAS,EAAE,MAAM,MAAM,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,WAAW,EAAqB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/init/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { select, confirm, input, checkbox } from "@inquirer/prompts";
|
|
2
2
|
import { type RuntimeName } from "./detect.js";
|
|
3
3
|
import { type InitResult } from "./index.js";
|
|
4
|
+
import type { NpmExec } from "../doctor/npm-bin-path.js";
|
|
4
5
|
import { type ApplyResult } from "../apply/index.js";
|
|
6
|
+
import { type ClaudeMcpExec, type EnsureMcpServersResult } from "../../io/claude-mcp.js";
|
|
5
7
|
import { type InstallOptions } from "./dependencies.js";
|
|
6
8
|
import { type LoginSpawn, type ProbeSpawn } from "./agent-tasks-auth.js";
|
|
7
9
|
export type ProfileChoice = "solo" | "team" | "full" | "custom";
|
|
@@ -25,6 +27,20 @@ export interface RuntimeApplyOutcome {
|
|
|
25
27
|
apply?: ApplyResult;
|
|
26
28
|
/** Operator-facing recovery message when apply threw, or the manual merge command for codex. */
|
|
27
29
|
recoveryHint?: string;
|
|
30
|
+
/**
|
|
31
|
+
* claude-code only (task init-mcp-wiring-claude-code/T-002): the result
|
|
32
|
+
* of reconciling the manifest's `tools.mcp[]` servers against the live
|
|
33
|
+
* `claude mcp` user-scope registry. Present whenever the wizard reached
|
|
34
|
+
* the Ensure step for claude-code, regardless of outcome.
|
|
35
|
+
*/
|
|
36
|
+
mcpEnsure?: EnsureMcpServersResult;
|
|
37
|
+
/**
|
|
38
|
+
* claude-code only: names stripped from the dead settings.json
|
|
39
|
+
* `mcpServers` block, when the post-Ensure migration ran and changed
|
|
40
|
+
* something. Absent when migration didn't run (Ensure incomplete) or
|
|
41
|
+
* ran as a no-op.
|
|
42
|
+
*/
|
|
43
|
+
mcpMigrationRemovedNames?: string[];
|
|
28
44
|
}
|
|
29
45
|
export interface RunInteractiveOptions {
|
|
30
46
|
/** Override homedir for detection + write target. */
|
|
@@ -49,6 +65,14 @@ export interface RunInteractiveOptions {
|
|
|
49
65
|
authProbeSpawn?: ProbeSpawn;
|
|
50
66
|
/** Override the agent-tasks-mcp-bridge `login` runner (tests). */
|
|
51
67
|
authLoginSpawn?: LoginSpawn;
|
|
68
|
+
/**
|
|
69
|
+
* Override the `claude mcp` CLI exec (task init-mcp-wiring-claude-code/
|
|
70
|
+
* T-002). Tests inject a fake to drive the Ensure step (registering
|
|
71
|
+
* `tools.mcp[]` servers via `claude mcp add-json --scope user`) without
|
|
72
|
+
* a real `claude` binary on PATH. Production leaves this undefined and
|
|
73
|
+
* gets the real CLI spawn (see `io/claude-mcp.ts`).
|
|
74
|
+
*/
|
|
75
|
+
mcpExec?: ClaudeMcpExec;
|
|
52
76
|
/**
|
|
53
77
|
* Repo directory the orchestrator-workflow co-install offer scaffolds
|
|
54
78
|
* into when the operator accepts. Defaults to `process.cwd()` — the repo
|
|
@@ -62,6 +86,15 @@ export interface RunInteractiveOptions {
|
|
|
62
86
|
* can fake success / non-zero exit / throw without touching the network.
|
|
63
87
|
*/
|
|
64
88
|
owInitSpawn?: InstallOptions["spawn"];
|
|
89
|
+
/**
|
|
90
|
+
* Override the `npm prefix -g` runner used by `init()`'s post-write
|
|
91
|
+
* bin-resolution check (task 325ace29). Mirrors `dependencyPathEnv`:
|
|
92
|
+
* the wizard owns no npm spawn of its own, it just forwards this to
|
|
93
|
+
* `init()`, which already accepts it as `InitOptions.npmBinExec`.
|
|
94
|
+
* Production leaves it undefined and gets the real spawn; tests MUST
|
|
95
|
+
* inject a fake, or the hermetic-spawn guard on `realNpmExec` throws.
|
|
96
|
+
*/
|
|
97
|
+
npmBinExec?: NpmExec;
|
|
65
98
|
}
|
|
66
99
|
export interface InteractiveResult {
|
|
67
100
|
/** True if the operator (or a Ctrl-C / decline) bailed out. No write happened. */
|
|
@@ -72,6 +105,14 @@ export interface InteractiveResult {
|
|
|
72
105
|
profile?: ProfileChoice;
|
|
73
106
|
/** Whether `harness validate` reported zero errors after the write. */
|
|
74
107
|
validateClean?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Whether every declared, enabled MCP binary and every REQUIRED CLI
|
|
110
|
+
* binary resolves on PATH (task 7f8fb4bc). `undefined` when this check
|
|
111
|
+
* did not run (validate itself failed first). False does not abort the
|
|
112
|
+
* wizard — the operator may still want to wire runtimes and fix PATH
|
|
113
|
+
* afterward — but the CLI layer surfaces it as a loud, non-zero exit.
|
|
114
|
+
*/
|
|
115
|
+
binResolutionClean?: boolean;
|
|
75
116
|
/**
|
|
76
117
|
* Per-runtime apply outcome from the wire-now step. Present when the
|
|
77
118
|
* operator selected at least one runtime in the multiselect (default:
|