@getmarrow/install 0.1.42 → 0.1.44
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/README.md +21 -7
- package/package.json +1 -1
- package/src/governed-runner.js +6 -6
- package/src/installer.js +95 -15
package/README.md
CHANGED
|
@@ -71,7 +71,7 @@ npx -y @getmarrow/install@latest activate
|
|
|
71
71
|
npx -y @getmarrow/install@latest doctor
|
|
72
72
|
|
|
73
73
|
# Measured API read health and local backlog
|
|
74
|
-
npx -y
|
|
74
|
+
npx -y --package=@getmarrow/mcp@latest marrow-mcp ping
|
|
75
75
|
|
|
76
76
|
# Use only when doctor reports drift
|
|
77
77
|
npx -y @getmarrow/install@latest --repair
|
|
@@ -91,16 +91,30 @@ npx @getmarrow/install controller stop
|
|
|
91
91
|
|
|
92
92
|
Persistent controller lifecycle is currently Linux-only. On macOS or Windows, activation still installs and verifies the supported hooks without starting or signaling a background process; run `npx @getmarrow/install sidecar` under an owner-managed service and pass `--no-controller`. The controller does not silently upgrade packages, change governance policy, rotate credentials, or modify unrelated project configuration.
|
|
93
93
|
|
|
94
|
-
## What's New in v0.1.
|
|
94
|
+
## What's New in v0.1.44
|
|
95
95
|
|
|
96
|
-
v0.1.
|
|
96
|
+
v0.1.44 restores exact package-chain detection and current MCP setup truth:
|
|
97
97
|
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
-
|
|
98
|
+
- exact declared, locked, and installed SDK `3.7.56` dependencies are recognized using the live public registry integrity;
|
|
99
|
+
- generated MCP setup, launch, and certified hook commands pin current MCP `3.9.61`;
|
|
100
|
+
- the installer exposes the certified MCP source SHA and public registry integrity in its programmatic adapter provenance without changing credentials, policy, or unrelated configuration;
|
|
101
|
+
- regression coverage rejects stale SDK lock integrity and treats MCP versions older than `3.9.61` as stale.
|
|
102
|
+
|
|
103
|
+
## Previous: v0.1.43
|
|
104
|
+
|
|
105
|
+
v0.1.43 hardens the MCP control path and makes stale client recovery explicit:
|
|
106
|
+
|
|
107
|
+
- `doctor` detects active and configured stale, mixed, or version-unknown Marrow MCP clients without exposing command lines, file paths, configuration contents, or credentials;
|
|
108
|
+
- every generated MCP launch and hook uses the package-explicit `npx --package ... marrow-mcp` form so npm can resolve the executable reliably;
|
|
109
|
+
- when repair is needed, `doctor` reports the pinned setup command, the separate owning-harness restart requirement, and a self-test verification command; it does not terminate harness processes itself;
|
|
110
|
+
- certified hooks pinned MCP `3.9.59` and SDK `3.7.56` so the installed runtime matched that release's advertised control contract;
|
|
101
111
|
- existing harnesses retain their honest coverage level: native hooks where supported, MCP calls where available, and governed wrappers or event contracts elsewhere;
|
|
102
112
|
- package upgrades remain operator-approved and never rotate keys or rewrite unrelated configuration.
|
|
103
113
|
|
|
114
|
+
## Previous: v0.1.42
|
|
115
|
+
|
|
116
|
+
v0.1.42 added deterministic active-process detection, including direct `node_modules/.bin/marrow-mcp` launches, while keeping repair operator-approved.
|
|
117
|
+
|
|
104
118
|
## Previous: v0.1.40
|
|
105
119
|
|
|
106
120
|
v0.1.40 binds governed runs to a privacy-safe workspace fingerprint and separates observed execution from verified completion:
|
|
@@ -108,7 +122,7 @@ v0.1.40 binds governed runs to a privacy-safe workspace fingerprint and separate
|
|
|
108
122
|
- ordinary prompts receive one compact context read; risky or mutating prompts receive one fresh runtime gate instead;
|
|
109
123
|
- passive prompt telemetry is buffered locally rather than delaying the agent turn;
|
|
110
124
|
- transient read failures can use clearly labeled owner-only last-known guidance, while authentication failures never use cache;
|
|
111
|
-
- `doctor` prints the exact `npx -y
|
|
125
|
+
- `doctor` prints the exact `npx -y --package=@getmarrow/mcp@latest marrow-mcp ping` command for measured current/p50/p99 latency, last success, and backlog health;
|
|
112
126
|
- certified hook commands pin MCP `3.9.56` and SDK `3.7.55` so advertised behavior matches that release's deployed server contract;
|
|
113
127
|
- governed runtime requests attach a stable privacy-safe project fingerprint and harness label without sending the raw working-directory path;
|
|
114
128
|
- successful command exit remains observed execution, not verified business completion, unless a verification command or explicit proof file supplies evidence;
|
package/package.json
CHANGED
package/src/governed-runner.js
CHANGED
|
@@ -1387,11 +1387,11 @@ const GENERIC_GOVERNED_COMMAND = 'MARROW_API_KEY=mrw_live_xxx npx @getmarrow/ins
|
|
|
1387
1387
|
function localSupportedHarnesses() {
|
|
1388
1388
|
const harnesses = [
|
|
1389
1389
|
{ display_name: 'OpenAI Codex', client_label: 'codex', category: 'agent_harness', support_level: 'governed_runner', install_command: 'MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install run --agent codex-prod -- codex' },
|
|
1390
|
-
{ display_name: 'Claude Code', client_label: 'claude-code', category: 'agent_harness', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx
|
|
1391
|
-
{ display_name: 'Cursor', client_label: 'cursor', category: 'ide_agent', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx
|
|
1392
|
-
{ display_name: 'Cursor Composer', client_label: 'composer', category: 'ide_agent', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx
|
|
1393
|
-
{ display_name: 'Windsurf', client_label: 'windsurf', category: 'ide_agent', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx
|
|
1394
|
-
{ display_name: 'Cline', client_label: 'cline', category: 'ide_agent', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx
|
|
1390
|
+
{ display_name: 'Claude Code', client_label: 'claude-code', category: 'agent_harness', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx -y --package=@getmarrow/mcp@latest marrow-mcp setup' },
|
|
1391
|
+
{ display_name: 'Cursor', client_label: 'cursor', category: 'ide_agent', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx -y --package=@getmarrow/mcp@latest marrow-mcp setup' },
|
|
1392
|
+
{ display_name: 'Cursor Composer', client_label: 'composer', category: 'ide_agent', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx -y --package=@getmarrow/mcp@latest marrow-mcp setup' },
|
|
1393
|
+
{ display_name: 'Windsurf', client_label: 'windsurf', category: 'ide_agent', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx -y --package=@getmarrow/mcp@latest marrow-mcp setup' },
|
|
1394
|
+
{ display_name: 'Cline', client_label: 'cline', category: 'ide_agent', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx -y --package=@getmarrow/mcp@latest marrow-mcp setup' },
|
|
1395
1395
|
{ display_name: 'OpenCode', client_label: 'opencode', category: 'agent_harness', support_level: 'governed_runner', install_command: 'MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install run --agent opencode-prod -- opencode' },
|
|
1396
1396
|
{ display_name: 'Hermes Agent', client_label: 'hermes', category: 'agent_harness', support_level: 'first_class_addon', install_command: 'MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install hermes' },
|
|
1397
1397
|
{ display_name: 'OpenClaw', client_label: 'openclaw', category: 'agent_harness', support_level: 'first_class_addon', install_command: 'MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install openclaw' },
|
|
@@ -1402,7 +1402,7 @@ function localSupportedHarnesses() {
|
|
|
1402
1402
|
{ display_name: 'Kimi', client_label: 'kimi', category: 'model_cli', support_level: 'governed_runner', install_command: GENERIC_GOVERNED_COMMAND },
|
|
1403
1403
|
{ display_name: 'MiniMax', client_label: 'minimax', category: 'model_cli', support_level: 'governed_runner', install_command: GENERIC_GOVERNED_COMMAND },
|
|
1404
1404
|
{ display_name: 'GLM', client_label: 'glm', category: 'model_cli', support_level: 'governed_runner', install_command: GENERIC_GOVERNED_COMMAND },
|
|
1405
|
-
{ display_name: 'MCP-compatible clients', client_label: 'mcp', category: 'mcp_client', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx
|
|
1405
|
+
{ display_name: 'MCP-compatible clients', client_label: 'mcp', category: 'mcp_client', support_level: 'native_mcp_or_sdk', install_command: 'MARROW_API_KEY=mrw_live_xxx npx -y --package=@getmarrow/mcp@latest marrow-mcp setup' },
|
|
1406
1406
|
{ display_name: 'CI scripts and deploy runners', client_label: 'ci', category: 'ci_runner', support_level: 'governed_runner', install_command: 'MARROW_API_KEY=mrw_live_xxx npx @getmarrow/install run --agent ci-release --profile production --policy enforce -- <ci-or-deploy-command>' },
|
|
1407
1407
|
{ display_name: 'Custom shell/API harness', client_label: 'custom', category: 'custom_runner', support_level: 'event_contract', install_command: 'POST /v1/agent/integrations/events with harness, event_type, agent_id, and action' },
|
|
1408
1408
|
];
|
package/src/installer.js
CHANGED
|
@@ -8,15 +8,30 @@ const { controllerStatus, controllerSupportedPlatform, ensureGovernanceControlle
|
|
|
8
8
|
const DEFAULT_BASE_URL = 'https://api.getmarrow.ai';
|
|
9
9
|
const MARROW_BLOCK_START = '<!-- marrow:passive-start -->';
|
|
10
10
|
const MARROW_BLOCK_END = '<!-- marrow:passive-end -->';
|
|
11
|
-
const MCP_ADAPTER_VERSION = '3.9.
|
|
11
|
+
const MCP_ADAPTER_VERSION = '3.9.61';
|
|
12
|
+
const MCP_ADAPTER_SOURCE_SHA = 'ebe06a5c78895e70ceea7b7383ac31d5aaacbd41';
|
|
13
|
+
const MCP_ADAPTER_INTEGRITY = 'sha512-6ojhKztiJp8/mZecuSnt+kiEe41COPBOjrka9j+r+yFacNl4uapW9quq/wEVo5SxuDmxolFIBaqkX6xIdaD2rA==';
|
|
12
14
|
const SDK_ADAPTER_VERSION = '3.7.56';
|
|
13
|
-
const SDK_ADAPTER_INTEGRITY = 'sha512-
|
|
15
|
+
const SDK_ADAPTER_INTEGRITY = 'sha512-mllohsI4DHpcVuEL58303kpGwS/pl/HMZ99mGNo3swYLomZwwfVzcner9Bn+p0b72989NOpS1l2frY/vra1gfQ==';
|
|
14
16
|
const SDK_ADAPTER_TARBALL = `https://registry.npmjs.org/@getmarrow/sdk/-/sdk-${SDK_ADAPTER_VERSION}.tgz`;
|
|
15
17
|
const MCP_PACKAGE_SPEC = `@getmarrow/mcp@${MCP_ADAPTER_VERSION}`;
|
|
16
|
-
const
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
18
|
+
const ADAPTER_PROVENANCE = Object.freeze({
|
|
19
|
+
mcp: Object.freeze({
|
|
20
|
+
package: '@getmarrow/mcp',
|
|
21
|
+
version: MCP_ADAPTER_VERSION,
|
|
22
|
+
source_sha: MCP_ADAPTER_SOURCE_SHA,
|
|
23
|
+
integrity: MCP_ADAPTER_INTEGRITY,
|
|
24
|
+
}),
|
|
25
|
+
sdk: Object.freeze({
|
|
26
|
+
package: '@getmarrow/sdk',
|
|
27
|
+
version: SDK_ADAPTER_VERSION,
|
|
28
|
+
integrity: SDK_ADAPTER_INTEGRITY,
|
|
29
|
+
}),
|
|
30
|
+
});
|
|
31
|
+
const MCP_CONTEXT_HOOK_COMMAND = `npx -y --package=${MCP_PACKAGE_SPEC} marrow-mcp context-hook`;
|
|
32
|
+
const MCP_PRE_ACTION_HOOK_COMMAND = `npx -y --package=${MCP_PACKAGE_SPEC} marrow-mcp pre-action-hook`;
|
|
33
|
+
const MCP_ACTION_RESULT_HOOK_COMMAND = `npx -y --package=${MCP_PACKAGE_SPEC} marrow-mcp hook`;
|
|
34
|
+
const MCP_SESSION_END_HOOK_COMMAND = `npx -y --package=${MCP_PACKAGE_SPEC} marrow-mcp session-hook`;
|
|
20
35
|
const NATIVE_HOOK_MATCHER = 'Bash|Edit|Write|MultiEdit|mcp__(?!marrow_).*';
|
|
21
36
|
const NATIVE_EXPECTED_HOOKS = ['prompt', 'pre_action', 'action_result', 'session_end'];
|
|
22
37
|
const SOURCE_CLIENTS = new Set(['claude-code', 'cursor', 'composer', 'windsurf', 'openclaw', 'codex', 'gemini', 'grok', 'deepseek', 'qwen', 'kimi', 'minimax', 'cline', 'opencode', 'hermes', 'glm', 'mcp', 'ci', 'custom', 'unknown']);
|
|
@@ -101,7 +116,7 @@ function isMcpProcessCommand(command) {
|
|
|
101
116
|
const packageManagers = new Set(['bun', 'bunx', 'npm', 'npm-cli.js', 'npx', 'npx-cli.js', 'pnpm', 'pnpx', 'yarn']);
|
|
102
117
|
const runner = executable === 'node' && args[1] ? path.basename(args[1]) : executable;
|
|
103
118
|
return packageManagers.has(runner)
|
|
104
|
-
&& args.some((arg) =>
|
|
119
|
+
&& args.some((arg) => /^(?:--package=)?@getmarrow\/mcp(?:@[^\s]+)?$/.test(arg));
|
|
105
120
|
}
|
|
106
121
|
|
|
107
122
|
function readLinuxProcessCommands(procRoot = '/proc') {
|
|
@@ -135,7 +150,7 @@ function inspectMcpProcesses(options = {}) {
|
|
|
135
150
|
const mixedVersions = versions.length > 1 || (versions.length > 0 && unknownVersionProcesses > 0);
|
|
136
151
|
const stale = staleVersions.length > 0;
|
|
137
152
|
const needsRepair = stale || mixedVersions || unknownVersionProcesses > 0;
|
|
138
|
-
const repairCommand = `npx -y
|
|
153
|
+
const repairCommand = `npx -y --package=@getmarrow/mcp@${MCP_ADAPTER_VERSION} marrow-mcp setup`;
|
|
139
154
|
return {
|
|
140
155
|
available: process.platform === 'linux' || Array.isArray(options.commands),
|
|
141
156
|
expected_version: MCP_ADAPTER_VERSION,
|
|
@@ -148,7 +163,59 @@ function inspectMcpProcesses(options = {}) {
|
|
|
148
163
|
exact_fix: needsRepair ? repairCommand : null,
|
|
149
164
|
restart_required: needsRepair,
|
|
150
165
|
restart_instruction: needsRepair ? 'Restart every owning harness to replace its active Marrow MCP process.' : null,
|
|
151
|
-
verification_command: needsRepair ? 'npx -y @getmarrow/install@latest doctor' : null,
|
|
166
|
+
verification_command: needsRepair ? 'npx -y @getmarrow/install@latest doctor --self-test' : null,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function inspectMcpConfigurations(detection, options = {}) {
|
|
171
|
+
const home = options.home || process.env.HOME || process.env.USERPROFILE || os.homedir();
|
|
172
|
+
const configuredPaths = Array.isArray(options.paths) ? options.paths : [
|
|
173
|
+
detection?.paths?.claudeSettings,
|
|
174
|
+
detection?.paths?.cursorMcp,
|
|
175
|
+
detection?.paths?.mcpJson,
|
|
176
|
+
path.join(home, '.claude', 'settings.json'),
|
|
177
|
+
path.join(home, '.claude.json'),
|
|
178
|
+
path.join(home, '.cursor', 'mcp.json'),
|
|
179
|
+
path.join(home, '.mcp.json'),
|
|
180
|
+
];
|
|
181
|
+
const versions = [];
|
|
182
|
+
let filesChecked = 0;
|
|
183
|
+
let configurationsFound = 0;
|
|
184
|
+
let unknownVersionConfigurations = 0;
|
|
185
|
+
for (const filePath of [...new Set(configuredPaths.filter(Boolean).map((entry) => path.resolve(String(entry))))]) {
|
|
186
|
+
try {
|
|
187
|
+
if (!fs.existsSync(filePath)) continue;
|
|
188
|
+
const stat = fs.lstatSync(filePath);
|
|
189
|
+
if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 2 * 1024 * 1024) continue;
|
|
190
|
+
filesChecked += 1;
|
|
191
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
192
|
+
const specs = [...raw.matchAll(/@getmarrow\/mcp@(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)/g)]
|
|
193
|
+
.map((match) => match[1]);
|
|
194
|
+
if (/@getmarrow\/mcp(?:@|["'\s])/.test(raw)) {
|
|
195
|
+
configurationsFound += 1;
|
|
196
|
+
if (specs.length === 0) unknownVersionConfigurations += 1;
|
|
197
|
+
}
|
|
198
|
+
versions.push(...specs);
|
|
199
|
+
} catch {
|
|
200
|
+
// Doctor remains read-only and ignores inaccessible or malformed owner configuration.
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
const configuredVersions = [...new Set(versions)].sort();
|
|
204
|
+
const staleVersions = configuredVersions.filter((version) => version !== MCP_ADAPTER_VERSION);
|
|
205
|
+
const mixedVersions = configuredVersions.length > 1
|
|
206
|
+
|| (configuredVersions.length > 0 && unknownVersionConfigurations > 0);
|
|
207
|
+
const healthy = staleVersions.length === 0 && !mixedVersions && unknownVersionConfigurations === 0;
|
|
208
|
+
return {
|
|
209
|
+
expected_version: MCP_ADAPTER_VERSION,
|
|
210
|
+
files_checked: filesChecked,
|
|
211
|
+
configurations_found: configurationsFound,
|
|
212
|
+
configured_versions: configuredVersions,
|
|
213
|
+
unknown_version_configurations: unknownVersionConfigurations,
|
|
214
|
+
stale_versions: staleVersions,
|
|
215
|
+
mixed_versions: mixedVersions,
|
|
216
|
+
healthy,
|
|
217
|
+
exact_fix: healthy ? null : `Run npx -y --package=@getmarrow/mcp@${MCP_ADAPTER_VERSION} marrow-mcp setup in each owning workspace, update its MCP launch to npx -y --package=@getmarrow/mcp@${MCP_ADAPTER_VERSION} marrow-mcp, then restart that harness.`,
|
|
218
|
+
verification_command: healthy ? null : 'npx -y @getmarrow/install@latest doctor --self-test',
|
|
152
219
|
};
|
|
153
220
|
}
|
|
154
221
|
|
|
@@ -549,7 +616,7 @@ function passiveInstructions() {
|
|
|
549
616
|
|
|
550
617
|
Marrow should run passively after install:
|
|
551
618
|
|
|
552
|
-
- Use MCP hooks when available: \`npx -y
|
|
619
|
+
- Use MCP hooks when available: \`npx -y --package=@getmarrow/mcp@latest marrow-mcp setup\`.
|
|
553
620
|
- Use SDK passive runtime in owned Node processes: \`createPassiveRuntime().install()\`.
|
|
554
621
|
- Keep passive token/model usage proof enabled so Marrow can show token, cost, latency, and workflow savings after real work completes.
|
|
555
622
|
- Before risky work, use Marrow's decision brief or passive prompt hook.
|
|
@@ -674,7 +741,7 @@ function exactHookDescriptors(settings, eventName, command, matcher) {
|
|
|
674
741
|
function marrowHookSubcommand(command) {
|
|
675
742
|
if (typeof command !== 'string') return null;
|
|
676
743
|
const match = command.trim().match(
|
|
677
|
-
/^npx\s+(?:-y\s+)
|
|
744
|
+
/^npx\s+(?:-y\s+)?(?:--package=@getmarrow\/mcp(?:@[^\s]+)?\s+marrow-mcp|@getmarrow\/mcp(?:@[^\s]+)?)\s+(context-hook|pre-action-hook|hook|session-hook)$/,
|
|
678
745
|
);
|
|
679
746
|
return match?.[1] || null;
|
|
680
747
|
}
|
|
@@ -839,7 +906,7 @@ function activationProfile(detection, plan, changes, client) {
|
|
|
839
906
|
if (capabilityLevel === 'mcp' && mcpConfigs.some((config) => (
|
|
840
907
|
config?.mcpServers?.marrow?.command === 'npx'
|
|
841
908
|
&& Array.isArray(config.mcpServers.marrow.args)
|
|
842
|
-
&& config.mcpServers.marrow.args.join(' ') === `-y
|
|
909
|
+
&& config.mcpServers.marrow.args.join(' ') === `-y --package=${MCP_PACKAGE_SPEC} marrow-mcp`
|
|
843
910
|
))) observedHooks.push('mcp_tool_calls');
|
|
844
911
|
const fingerprintMaterial = changes
|
|
845
912
|
.filter((change) => change.applied || change.already_present)
|
|
@@ -877,7 +944,7 @@ function upsertMcpServerConfig(filePath) {
|
|
|
877
944
|
: {};
|
|
878
945
|
servers.marrow = {
|
|
879
946
|
command: 'npx',
|
|
880
|
-
args: ['-y', MCP_PACKAGE_SPEC],
|
|
947
|
+
args: ['-y', `--package=${MCP_PACKAGE_SPEC}`, 'marrow-mcp'],
|
|
881
948
|
env: {
|
|
882
949
|
MARROW_API_KEY: '${MARROW_API_KEY}',
|
|
883
950
|
MARROW_BASE_URL: '${MARROW_BASE_URL}',
|
|
@@ -1647,6 +1714,11 @@ function printReport(report) {
|
|
|
1647
1714
|
if (processes.restart_instruction) process.stdout.write(`- restart required: ${processes.restart_instruction}\n`);
|
|
1648
1715
|
if (processes.verification_command) process.stdout.write(`- verify repair: ${processes.verification_command}\n`);
|
|
1649
1716
|
}
|
|
1717
|
+
if (report.doctor.mcpConfigurations) {
|
|
1718
|
+
const configurations = report.doctor.mcpConfigurations;
|
|
1719
|
+
process.stdout.write(`- configured MCP versions: ${configurations.configured_versions.length ? configurations.configured_versions.join(', ') : 'none pinned'}\n`);
|
|
1720
|
+
process.stdout.write(`- stale/mixed/version-unknown MCP configuration: ${configurations.healthy ? 'no' : 'yes'}\n`);
|
|
1721
|
+
}
|
|
1650
1722
|
if (report.doctor.recommendedFix) process.stdout.write(`- recommended fix: ${report.doctor.recommendedFix}\n`);
|
|
1651
1723
|
process.stdout.write(`- live health: ${report.doctor.healthCommand}\n`);
|
|
1652
1724
|
}
|
|
@@ -1708,6 +1780,7 @@ async function install(options) {
|
|
|
1708
1780
|
: [];
|
|
1709
1781
|
const envHints = options.apiKey ? [] : findLikelyEnvFiles(detection);
|
|
1710
1782
|
const mcpProcesses = inspectMcpProcesses({ commands: options.processCommands });
|
|
1783
|
+
const mcpConfigurations = inspectMcpConfigurations(detection, { paths: options.mcpConfigPaths });
|
|
1711
1784
|
let selfTest;
|
|
1712
1785
|
try {
|
|
1713
1786
|
selfTest = await runSelfTest(options);
|
|
@@ -1775,6 +1848,7 @@ async function install(options) {
|
|
|
1775
1848
|
|
|
1776
1849
|
return {
|
|
1777
1850
|
root: detection.root,
|
|
1851
|
+
adapterProvenance: ADAPTER_PROVENANCE,
|
|
1778
1852
|
mode: plan.mode,
|
|
1779
1853
|
writeMode,
|
|
1780
1854
|
detected: {
|
|
@@ -1800,12 +1874,13 @@ async function install(options) {
|
|
|
1800
1874
|
envHints,
|
|
1801
1875
|
missingHooks: changes.filter((change) => change.changed).map((change) => change.label),
|
|
1802
1876
|
mcpProcesses,
|
|
1803
|
-
|
|
1877
|
+
mcpConfigurations,
|
|
1878
|
+
recommendedFix: mcpProcesses.exact_fix || mcpConfigurations.exact_fix || configDiagnostics.npm_token.recommended_fix || (!options.apiKey
|
|
1804
1879
|
? envHints.length
|
|
1805
1880
|
? `MARROW_API_KEY was found in a likely env file at ${envHints[0]}. Load that key from trusted secret storage, export only MARROW_API_KEY, then run npx @getmarrow/install --repair.`
|
|
1806
1881
|
: 'Set MARROW_API_KEY, then run npx @getmarrow/install --repair.'
|
|
1807
1882
|
: controller.exact_fix || selfTest.recommended_fix || null),
|
|
1808
|
-
healthCommand: 'npx -y
|
|
1883
|
+
healthCommand: 'npx -y --package=@getmarrow/mcp@latest marrow-mcp ping',
|
|
1809
1884
|
},
|
|
1810
1885
|
remediation,
|
|
1811
1886
|
configDiagnostics,
|
|
@@ -1820,6 +1895,9 @@ async function install(options) {
|
|
|
1820
1895
|
...(!mcpProcesses.healthy
|
|
1821
1896
|
? ['Stale, mixed, or version-unknown Marrow MCP clients are active. Run the exact repair command, then restart every owning harness.']
|
|
1822
1897
|
: []),
|
|
1898
|
+
...(!mcpConfigurations.healthy
|
|
1899
|
+
? ['Stale, mixed, or version-unknown Marrow MCP versions remain in owner configuration. Repair each owning workspace and restart its harness.']
|
|
1900
|
+
: []),
|
|
1823
1901
|
],
|
|
1824
1902
|
};
|
|
1825
1903
|
}
|
|
@@ -1850,11 +1928,13 @@ module.exports = {
|
|
|
1850
1928
|
inspectNpmTokenConfig,
|
|
1851
1929
|
inspectSdkDependency,
|
|
1852
1930
|
inspectMcpProcesses,
|
|
1931
|
+
inspectMcpConfigurations,
|
|
1853
1932
|
buildInstallValueMoment,
|
|
1854
1933
|
buildTokenValueProof,
|
|
1855
1934
|
stableAgentId,
|
|
1856
1935
|
activationProfile,
|
|
1857
1936
|
claudeNativeHookFingerprint,
|
|
1858
1937
|
printReport,
|
|
1938
|
+
ADAPTER_PROVENANCE,
|
|
1859
1939
|
HARNESS_CAPABILITY_REGISTRY,
|
|
1860
1940
|
};
|