@ran-sh/dsh-crew 2.0.5 → 2.0.7
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/package.json
CHANGED
package/scripts/setup.mjs
CHANGED
|
@@ -11,7 +11,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
11
11
|
import { dirname, join, resolve } from 'node:path';
|
|
12
12
|
import { homedir } from 'node:os';
|
|
13
13
|
import * as realInstaller from '../src/install/install.mjs';
|
|
14
|
-
import { crewDshHome, crewProfileDir, CREW_PROFILE_NAME } from '../src/install/install.mjs';
|
|
14
|
+
import { crewDshHome, crewProfileDir, CREW_PROFILE_NAME, claudeIntegrationLine } from '../src/install/install.mjs';
|
|
15
15
|
import {
|
|
16
16
|
ensureCrewDshRuntime,
|
|
17
17
|
ensureCrewPluginRegistration,
|
|
@@ -136,6 +136,30 @@ function mark(log, ok, text) {
|
|
|
136
136
|
return ok;
|
|
137
137
|
}
|
|
138
138
|
|
|
139
|
+
/**
|
|
140
|
+
* The Claude Code step of a checkout install.
|
|
141
|
+
*
|
|
142
|
+
* Extracted so it can be exercised directly: the rest of setupInstall runs a real
|
|
143
|
+
* dependency install and client build, which a unit test must not do. Both
|
|
144
|
+
* install entries render the same result through `claudeIntegrationLine`, so a
|
|
145
|
+
* result one entry learned to handle cannot be silently checkmarked by the other.
|
|
146
|
+
*/
|
|
147
|
+
export async function runClaudeIntegrationStep({
|
|
148
|
+
dryRun = false,
|
|
149
|
+
log = console.log,
|
|
150
|
+
root = ROOT,
|
|
151
|
+
home = homedir(),
|
|
152
|
+
installer = realInstaller,
|
|
153
|
+
} = {}) {
|
|
154
|
+
if (dryRun) { mark(log, true, 'Claude Code integration (dry-run)'); return { ok: true }; }
|
|
155
|
+
const r = installer.installClaudeCode
|
|
156
|
+
? await installer.installClaudeCode({ home, root })
|
|
157
|
+
: await realInstaller.installClaudeCode({ home, root });
|
|
158
|
+
log(claudeIntegrationLine(r));
|
|
159
|
+
if (r.ok === false) return { ok: false, error: 'Claude Code integration failed' };
|
|
160
|
+
return { ok: true };
|
|
161
|
+
}
|
|
162
|
+
|
|
139
163
|
export async function setupInstall({
|
|
140
164
|
dryRun = false,
|
|
141
165
|
log = console.log,
|
|
@@ -250,13 +274,8 @@ export async function setupInstall({
|
|
|
250
274
|
}
|
|
251
275
|
|
|
252
276
|
if (commandExists('claude')) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const r = installer.installClaudeCode ? await installer.installClaudeCode({ home, root }) : await realInstaller.installClaudeCode({ home, root });
|
|
256
|
-
const ok = r.ok !== false;
|
|
257
|
-
mark(log, ok, ok ? 'Claude Code integration' : 'Claude Code integration failed');
|
|
258
|
-
if (!ok) return { ok: false, error: 'Claude Code integration failed' };
|
|
259
|
-
}
|
|
277
|
+
const r = await runClaudeIntegrationStep({ dryRun, log, root, home, installer });
|
|
278
|
+
if (!r.ok) return r;
|
|
260
279
|
} else log('- Claude Code not detected, skipped');
|
|
261
280
|
|
|
262
281
|
log('');
|
|
@@ -492,6 +492,24 @@ export function uninstallCodex({ home = homedir(), env = process.env } = {}) {
|
|
|
492
492
|
return { ok: true, actions: actions.length ? actions : ['nothing to remove'] };
|
|
493
493
|
}
|
|
494
494
|
|
|
495
|
+
/**
|
|
496
|
+
* The one line both install entries print for a Claude Code integration result.
|
|
497
|
+
*
|
|
498
|
+
* A missing `claude` CLI is a supported install, so `installClaudeCode` stays
|
|
499
|
+
* best-effort and keeps `ok: true`. A CLI that is present and fails or times out
|
|
500
|
+
* is a different thing: it leaves Claude Code without the plugin snapshot while
|
|
501
|
+
* the settings still name it, which is the state `installStatus` later reads as
|
|
502
|
+
* "needs repair". This used to be rendered separately in each entry — and only
|
|
503
|
+
* one of them learned about `degraded`, so the other kept printing a checkmark.
|
|
504
|
+
*/
|
|
505
|
+
export function claudeIntegrationLine(result) {
|
|
506
|
+
if (result?.ok === false) return '✗ Claude Code integration failed';
|
|
507
|
+
if (result?.degraded === true) {
|
|
508
|
+
return `- Claude Code integration registered, but not loaded: ${result.reason ?? 'plugin snapshot not refreshed'}`;
|
|
509
|
+
}
|
|
510
|
+
return '✓ Claude Code integration';
|
|
511
|
+
}
|
|
512
|
+
|
|
495
513
|
export async function installClaudeCode({ home = homedir(), statusline = false, root = ROOT } = {}) {
|
|
496
514
|
const actions = [];
|
|
497
515
|
|
|
@@ -581,7 +599,12 @@ export async function installClaudeCode({ home = homedir(), statusline = false,
|
|
|
581
599
|
}
|
|
582
600
|
try {
|
|
583
601
|
const { execSync } = await import('node:child_process');
|
|
584
|
-
|
|
602
|
+
// 300s, not 120: the install below runs after the uninstall, so it does a real
|
|
603
|
+
// copy of the plugin tree rather than the no-op an already-installed plugin
|
|
604
|
+
// gets. Measured on this machine: `marketplace add` 3s, `uninstall` 3s,
|
|
605
|
+
// `install` 163s (no-op install: 6s). The old ceiling killed the copy partway
|
|
606
|
+
// and left Claude Code without the plugin the same run had just removed.
|
|
607
|
+
const run = (cmd) => execSync(cmd, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 300_000 });
|
|
585
608
|
try { run(`claude plugin marketplace add ${JSON.stringify(mpDir)}`); actions.push('cli: marketplace registered'); }
|
|
586
609
|
catch { actions.push('cli: marketplace add skipped (already registered)'); }
|
|
587
610
|
// `plugin install` on an already-installed plugin is a no-op and leaves a
|
|
@@ -41,7 +41,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
41
41
|
import { homedir } from 'node:os';
|
|
42
42
|
import * as realInstaller from './install.mjs';
|
|
43
43
|
import { samePayloadContent, capturePayloadContent } from './payload-content.mjs';
|
|
44
|
-
import { crewDshHome, crewProfileDir } from './install.mjs';
|
|
44
|
+
import { crewDshHome, crewProfileDir, claudeIntegrationLine } from './install.mjs';
|
|
45
45
|
import { releaseClaimsState } from '../release-in-use.mjs';
|
|
46
46
|
import { compareProcessToken, processStartToken } from '../process-identity.mjs';
|
|
47
47
|
import { renameTree } from './tree-move.mjs';
|
|
@@ -2626,25 +2626,6 @@ function currentInstallationHealth({ home }) {
|
|
|
2626
2626
|
return { installed: true, healthy: validated.ok && registered, validated, registered, pointer };
|
|
2627
2627
|
}
|
|
2628
2628
|
|
|
2629
|
-
/**
|
|
2630
|
-
* What the operator is told about the Claude Code integration.
|
|
2631
|
-
*
|
|
2632
|
-
* A missing `claude` CLI is a supported install, so `installClaudeCode` stays
|
|
2633
|
-
* best-effort and keeps `ok: true`. A CLI that is present and fails or times out
|
|
2634
|
-
* is a different thing: it leaves Claude Code without the plugin snapshot while
|
|
2635
|
-
* the settings still name it, which is the state that later reads as "needs
|
|
2636
|
-
* repair". This line used to be `${ok === false ? '✗' : '✓'}`, and since `ok` was
|
|
2637
|
-
* never false, the failure branch could not fire and a broken integration was
|
|
2638
|
-
* reported as a checkmark.
|
|
2639
|
-
*/
|
|
2640
|
-
export function claudeIntegrationLine(result) {
|
|
2641
|
-
if (result?.ok === false) return '✗ Claude Code integration failed';
|
|
2642
|
-
if (result?.degraded === true) {
|
|
2643
|
-
return `- Claude Code integration registered, but not loaded: ${result.reason ?? 'plugin snapshot not refreshed'}`;
|
|
2644
|
-
}
|
|
2645
|
-
return '✓ Claude Code integration';
|
|
2646
|
-
}
|
|
2647
|
-
|
|
2648
2629
|
async function activateRelease({ home, releaseDir, manifest, log, installer, supervisorRoot = runningPackageRoot() }) {
|
|
2649
2630
|
const registration = ensureCrewPluginRegistration({ home, root: releaseDir, name: manifest.name });
|
|
2650
2631
|
if (!registration.ok) {
|
package/src/runtime-identity.mjs
CHANGED
|
@@ -36,7 +36,7 @@ export {
|
|
|
36
36
|
// included in the identity contract.
|
|
37
37
|
const RUNTIME_ID = randomUUID();
|
|
38
38
|
|
|
39
|
-
export const RUNTIME_VERSION = '2.0.
|
|
39
|
+
export const RUNTIME_VERSION = '2.0.7';
|
|
40
40
|
export const HUB_PROTOCOL_VERSION = 1;
|
|
41
41
|
|
|
42
42
|
export const HUB_CAPABILITIES = Object.freeze([
|