@getmarrow/install 0.1.42 → 0.1.43
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 +12 -7
- package/package.json +1 -1
- package/src/governed-runner.js +6 -6
- package/src/installer.js +77 -14
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,21 @@ 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.43
|
|
95
95
|
|
|
96
|
-
v0.1.
|
|
96
|
+
v0.1.43 hardens the MCP control path and makes stale client recovery explicit:
|
|
97
97
|
|
|
98
|
-
- `doctor` detects active stale, mixed, or version-unknown Marrow MCP
|
|
99
|
-
-
|
|
100
|
-
-
|
|
98
|
+
- `doctor` detects active and configured stale, mixed, or version-unknown Marrow MCP clients without exposing command lines, file paths, configuration contents, or credentials;
|
|
99
|
+
- every generated MCP launch and hook uses the package-explicit `npx --package ... marrow-mcp` form so npm can resolve the executable reliably;
|
|
100
|
+
- 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;
|
|
101
|
+
- certified hooks pin MCP `3.9.59` and SDK `3.7.56` so the installed runtime matches the advertised control contract;
|
|
101
102
|
- existing harnesses retain their honest coverage level: native hooks where supported, MCP calls where available, and governed wrappers or event contracts elsewhere;
|
|
102
103
|
- package upgrades remain operator-approved and never rotate keys or rewrite unrelated configuration.
|
|
103
104
|
|
|
105
|
+
## Previous: v0.1.42
|
|
106
|
+
|
|
107
|
+
v0.1.42 added deterministic active-process detection, including direct `node_modules/.bin/marrow-mcp` launches, while keeping repair operator-approved.
|
|
108
|
+
|
|
104
109
|
## Previous: v0.1.40
|
|
105
110
|
|
|
106
111
|
v0.1.40 binds governed runs to a privacy-safe workspace fingerprint and separates observed execution from verified completion:
|
|
@@ -108,7 +113,7 @@ v0.1.40 binds governed runs to a privacy-safe workspace fingerprint and separate
|
|
|
108
113
|
- ordinary prompts receive one compact context read; risky or mutating prompts receive one fresh runtime gate instead;
|
|
109
114
|
- passive prompt telemetry is buffered locally rather than delaying the agent turn;
|
|
110
115
|
- 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
|
|
116
|
+
- `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
117
|
- certified hook commands pin MCP `3.9.56` and SDK `3.7.55` so advertised behavior matches that release's deployed server contract;
|
|
113
118
|
- governed runtime requests attach a stable privacy-safe project fingerprint and harness label without sending the raw working-directory path;
|
|
114
119
|
- 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,15 @@ 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.59';
|
|
12
12
|
const SDK_ADAPTER_VERSION = '3.7.56';
|
|
13
13
|
const SDK_ADAPTER_INTEGRITY = 'sha512-5htliY4wfn8a1mbLT9N4OWXqhp9fWzMHuAQgUetc3RUKjOes5mWB3t91/leRKFRRIgCnEczJN6jHXg7Aw489Mw==';
|
|
14
14
|
const SDK_ADAPTER_TARBALL = `https://registry.npmjs.org/@getmarrow/sdk/-/sdk-${SDK_ADAPTER_VERSION}.tgz`;
|
|
15
15
|
const MCP_PACKAGE_SPEC = `@getmarrow/mcp@${MCP_ADAPTER_VERSION}`;
|
|
16
|
-
const MCP_CONTEXT_HOOK_COMMAND = `npx -y
|
|
17
|
-
const MCP_PRE_ACTION_HOOK_COMMAND = `npx -y
|
|
18
|
-
const MCP_ACTION_RESULT_HOOK_COMMAND = `npx -y
|
|
19
|
-
const MCP_SESSION_END_HOOK_COMMAND = `npx -y
|
|
16
|
+
const MCP_CONTEXT_HOOK_COMMAND = `npx -y --package=${MCP_PACKAGE_SPEC} marrow-mcp context-hook`;
|
|
17
|
+
const MCP_PRE_ACTION_HOOK_COMMAND = `npx -y --package=${MCP_PACKAGE_SPEC} marrow-mcp pre-action-hook`;
|
|
18
|
+
const MCP_ACTION_RESULT_HOOK_COMMAND = `npx -y --package=${MCP_PACKAGE_SPEC} marrow-mcp hook`;
|
|
19
|
+
const MCP_SESSION_END_HOOK_COMMAND = `npx -y --package=${MCP_PACKAGE_SPEC} marrow-mcp session-hook`;
|
|
20
20
|
const NATIVE_HOOK_MATCHER = 'Bash|Edit|Write|MultiEdit|mcp__(?!marrow_).*';
|
|
21
21
|
const NATIVE_EXPECTED_HOOKS = ['prompt', 'pre_action', 'action_result', 'session_end'];
|
|
22
22
|
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 +101,7 @@ function isMcpProcessCommand(command) {
|
|
|
101
101
|
const packageManagers = new Set(['bun', 'bunx', 'npm', 'npm-cli.js', 'npx', 'npx-cli.js', 'pnpm', 'pnpx', 'yarn']);
|
|
102
102
|
const runner = executable === 'node' && args[1] ? path.basename(args[1]) : executable;
|
|
103
103
|
return packageManagers.has(runner)
|
|
104
|
-
&& args.some((arg) =>
|
|
104
|
+
&& args.some((arg) => /^(?:--package=)?@getmarrow\/mcp(?:@[^\s]+)?$/.test(arg));
|
|
105
105
|
}
|
|
106
106
|
|
|
107
107
|
function readLinuxProcessCommands(procRoot = '/proc') {
|
|
@@ -135,7 +135,7 @@ function inspectMcpProcesses(options = {}) {
|
|
|
135
135
|
const mixedVersions = versions.length > 1 || (versions.length > 0 && unknownVersionProcesses > 0);
|
|
136
136
|
const stale = staleVersions.length > 0;
|
|
137
137
|
const needsRepair = stale || mixedVersions || unknownVersionProcesses > 0;
|
|
138
|
-
const repairCommand = `npx -y
|
|
138
|
+
const repairCommand = `npx -y --package=@getmarrow/mcp@${MCP_ADAPTER_VERSION} marrow-mcp setup`;
|
|
139
139
|
return {
|
|
140
140
|
available: process.platform === 'linux' || Array.isArray(options.commands),
|
|
141
141
|
expected_version: MCP_ADAPTER_VERSION,
|
|
@@ -148,7 +148,59 @@ function inspectMcpProcesses(options = {}) {
|
|
|
148
148
|
exact_fix: needsRepair ? repairCommand : null,
|
|
149
149
|
restart_required: needsRepair,
|
|
150
150
|
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,
|
|
151
|
+
verification_command: needsRepair ? 'npx -y @getmarrow/install@latest doctor --self-test' : null,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
function inspectMcpConfigurations(detection, options = {}) {
|
|
156
|
+
const home = options.home || process.env.HOME || process.env.USERPROFILE || os.homedir();
|
|
157
|
+
const configuredPaths = Array.isArray(options.paths) ? options.paths : [
|
|
158
|
+
detection?.paths?.claudeSettings,
|
|
159
|
+
detection?.paths?.cursorMcp,
|
|
160
|
+
detection?.paths?.mcpJson,
|
|
161
|
+
path.join(home, '.claude', 'settings.json'),
|
|
162
|
+
path.join(home, '.claude.json'),
|
|
163
|
+
path.join(home, '.cursor', 'mcp.json'),
|
|
164
|
+
path.join(home, '.mcp.json'),
|
|
165
|
+
];
|
|
166
|
+
const versions = [];
|
|
167
|
+
let filesChecked = 0;
|
|
168
|
+
let configurationsFound = 0;
|
|
169
|
+
let unknownVersionConfigurations = 0;
|
|
170
|
+
for (const filePath of [...new Set(configuredPaths.filter(Boolean).map((entry) => path.resolve(String(entry))))]) {
|
|
171
|
+
try {
|
|
172
|
+
if (!fs.existsSync(filePath)) continue;
|
|
173
|
+
const stat = fs.lstatSync(filePath);
|
|
174
|
+
if (!stat.isFile() || stat.isSymbolicLink() || stat.size > 2 * 1024 * 1024) continue;
|
|
175
|
+
filesChecked += 1;
|
|
176
|
+
const raw = fs.readFileSync(filePath, 'utf8');
|
|
177
|
+
const specs = [...raw.matchAll(/@getmarrow\/mcp@(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)/g)]
|
|
178
|
+
.map((match) => match[1]);
|
|
179
|
+
if (/@getmarrow\/mcp(?:@|["'\s])/.test(raw)) {
|
|
180
|
+
configurationsFound += 1;
|
|
181
|
+
if (specs.length === 0) unknownVersionConfigurations += 1;
|
|
182
|
+
}
|
|
183
|
+
versions.push(...specs);
|
|
184
|
+
} catch {
|
|
185
|
+
// Doctor remains read-only and ignores inaccessible or malformed owner configuration.
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
const configuredVersions = [...new Set(versions)].sort();
|
|
189
|
+
const staleVersions = configuredVersions.filter((version) => version !== MCP_ADAPTER_VERSION);
|
|
190
|
+
const mixedVersions = configuredVersions.length > 1
|
|
191
|
+
|| (configuredVersions.length > 0 && unknownVersionConfigurations > 0);
|
|
192
|
+
const healthy = staleVersions.length === 0 && !mixedVersions && unknownVersionConfigurations === 0;
|
|
193
|
+
return {
|
|
194
|
+
expected_version: MCP_ADAPTER_VERSION,
|
|
195
|
+
files_checked: filesChecked,
|
|
196
|
+
configurations_found: configurationsFound,
|
|
197
|
+
configured_versions: configuredVersions,
|
|
198
|
+
unknown_version_configurations: unknownVersionConfigurations,
|
|
199
|
+
stale_versions: staleVersions,
|
|
200
|
+
mixed_versions: mixedVersions,
|
|
201
|
+
healthy,
|
|
202
|
+
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.`,
|
|
203
|
+
verification_command: healthy ? null : 'npx -y @getmarrow/install@latest doctor --self-test',
|
|
152
204
|
};
|
|
153
205
|
}
|
|
154
206
|
|
|
@@ -549,7 +601,7 @@ function passiveInstructions() {
|
|
|
549
601
|
|
|
550
602
|
Marrow should run passively after install:
|
|
551
603
|
|
|
552
|
-
- Use MCP hooks when available: \`npx -y
|
|
604
|
+
- Use MCP hooks when available: \`npx -y --package=@getmarrow/mcp@latest marrow-mcp setup\`.
|
|
553
605
|
- Use SDK passive runtime in owned Node processes: \`createPassiveRuntime().install()\`.
|
|
554
606
|
- Keep passive token/model usage proof enabled so Marrow can show token, cost, latency, and workflow savings after real work completes.
|
|
555
607
|
- Before risky work, use Marrow's decision brief or passive prompt hook.
|
|
@@ -674,7 +726,7 @@ function exactHookDescriptors(settings, eventName, command, matcher) {
|
|
|
674
726
|
function marrowHookSubcommand(command) {
|
|
675
727
|
if (typeof command !== 'string') return null;
|
|
676
728
|
const match = command.trim().match(
|
|
677
|
-
/^npx\s+(?:-y\s+)
|
|
729
|
+
/^npx\s+(?:-y\s+)?(?:--package=@getmarrow\/mcp(?:@[^\s]+)?\s+marrow-mcp|@getmarrow\/mcp(?:@[^\s]+)?)\s+(context-hook|pre-action-hook|hook|session-hook)$/,
|
|
678
730
|
);
|
|
679
731
|
return match?.[1] || null;
|
|
680
732
|
}
|
|
@@ -839,7 +891,7 @@ function activationProfile(detection, plan, changes, client) {
|
|
|
839
891
|
if (capabilityLevel === 'mcp' && mcpConfigs.some((config) => (
|
|
840
892
|
config?.mcpServers?.marrow?.command === 'npx'
|
|
841
893
|
&& Array.isArray(config.mcpServers.marrow.args)
|
|
842
|
-
&& config.mcpServers.marrow.args.join(' ') === `-y
|
|
894
|
+
&& config.mcpServers.marrow.args.join(' ') === `-y --package=${MCP_PACKAGE_SPEC} marrow-mcp`
|
|
843
895
|
))) observedHooks.push('mcp_tool_calls');
|
|
844
896
|
const fingerprintMaterial = changes
|
|
845
897
|
.filter((change) => change.applied || change.already_present)
|
|
@@ -877,7 +929,7 @@ function upsertMcpServerConfig(filePath) {
|
|
|
877
929
|
: {};
|
|
878
930
|
servers.marrow = {
|
|
879
931
|
command: 'npx',
|
|
880
|
-
args: ['-y', MCP_PACKAGE_SPEC],
|
|
932
|
+
args: ['-y', `--package=${MCP_PACKAGE_SPEC}`, 'marrow-mcp'],
|
|
881
933
|
env: {
|
|
882
934
|
MARROW_API_KEY: '${MARROW_API_KEY}',
|
|
883
935
|
MARROW_BASE_URL: '${MARROW_BASE_URL}',
|
|
@@ -1647,6 +1699,11 @@ function printReport(report) {
|
|
|
1647
1699
|
if (processes.restart_instruction) process.stdout.write(`- restart required: ${processes.restart_instruction}\n`);
|
|
1648
1700
|
if (processes.verification_command) process.stdout.write(`- verify repair: ${processes.verification_command}\n`);
|
|
1649
1701
|
}
|
|
1702
|
+
if (report.doctor.mcpConfigurations) {
|
|
1703
|
+
const configurations = report.doctor.mcpConfigurations;
|
|
1704
|
+
process.stdout.write(`- configured MCP versions: ${configurations.configured_versions.length ? configurations.configured_versions.join(', ') : 'none pinned'}\n`);
|
|
1705
|
+
process.stdout.write(`- stale/mixed/version-unknown MCP configuration: ${configurations.healthy ? 'no' : 'yes'}\n`);
|
|
1706
|
+
}
|
|
1650
1707
|
if (report.doctor.recommendedFix) process.stdout.write(`- recommended fix: ${report.doctor.recommendedFix}\n`);
|
|
1651
1708
|
process.stdout.write(`- live health: ${report.doctor.healthCommand}\n`);
|
|
1652
1709
|
}
|
|
@@ -1708,6 +1765,7 @@ async function install(options) {
|
|
|
1708
1765
|
: [];
|
|
1709
1766
|
const envHints = options.apiKey ? [] : findLikelyEnvFiles(detection);
|
|
1710
1767
|
const mcpProcesses = inspectMcpProcesses({ commands: options.processCommands });
|
|
1768
|
+
const mcpConfigurations = inspectMcpConfigurations(detection, { paths: options.mcpConfigPaths });
|
|
1711
1769
|
let selfTest;
|
|
1712
1770
|
try {
|
|
1713
1771
|
selfTest = await runSelfTest(options);
|
|
@@ -1800,12 +1858,13 @@ async function install(options) {
|
|
|
1800
1858
|
envHints,
|
|
1801
1859
|
missingHooks: changes.filter((change) => change.changed).map((change) => change.label),
|
|
1802
1860
|
mcpProcesses,
|
|
1803
|
-
|
|
1861
|
+
mcpConfigurations,
|
|
1862
|
+
recommendedFix: mcpProcesses.exact_fix || mcpConfigurations.exact_fix || configDiagnostics.npm_token.recommended_fix || (!options.apiKey
|
|
1804
1863
|
? envHints.length
|
|
1805
1864
|
? `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
1865
|
: 'Set MARROW_API_KEY, then run npx @getmarrow/install --repair.'
|
|
1807
1866
|
: controller.exact_fix || selfTest.recommended_fix || null),
|
|
1808
|
-
healthCommand: 'npx -y
|
|
1867
|
+
healthCommand: 'npx -y --package=@getmarrow/mcp@latest marrow-mcp ping',
|
|
1809
1868
|
},
|
|
1810
1869
|
remediation,
|
|
1811
1870
|
configDiagnostics,
|
|
@@ -1820,6 +1879,9 @@ async function install(options) {
|
|
|
1820
1879
|
...(!mcpProcesses.healthy
|
|
1821
1880
|
? ['Stale, mixed, or version-unknown Marrow MCP clients are active. Run the exact repair command, then restart every owning harness.']
|
|
1822
1881
|
: []),
|
|
1882
|
+
...(!mcpConfigurations.healthy
|
|
1883
|
+
? ['Stale, mixed, or version-unknown Marrow MCP versions remain in owner configuration. Repair each owning workspace and restart its harness.']
|
|
1884
|
+
: []),
|
|
1823
1885
|
],
|
|
1824
1886
|
};
|
|
1825
1887
|
}
|
|
@@ -1850,6 +1912,7 @@ module.exports = {
|
|
|
1850
1912
|
inspectNpmTokenConfig,
|
|
1851
1913
|
inspectSdkDependency,
|
|
1852
1914
|
inspectMcpProcesses,
|
|
1915
|
+
inspectMcpConfigurations,
|
|
1853
1916
|
buildInstallValueMoment,
|
|
1854
1917
|
buildTokenValueProof,
|
|
1855
1918
|
stableAgentId,
|