@ran-sh/dsh-crew 2.0.4 → 2.0.6
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
|
|
|
@@ -600,7 +618,20 @@ export async function installClaudeCode({ home = homedir(), statusline = false,
|
|
|
600
618
|
} catch (err) {
|
|
601
619
|
actions.push(`cli: plugin install failed — run manually: claude plugin install ${PLUGIN_KEY} (${String(err?.message ?? err).slice(0, 120)})`);
|
|
602
620
|
}
|
|
603
|
-
|
|
621
|
+
// Report the state that resulted, not the step that was attempted. The CLI is
|
|
622
|
+
// best-effort — a machine without `claude` is a supported install, and its
|
|
623
|
+
// settings alone are correct — but a CLI that is present and slow, timed out,
|
|
624
|
+
// or failed leaves the snapshot exactly as stale as it was, and it is the
|
|
625
|
+
// snapshot that `installStatus` reads. Saying so here is what lets the caller
|
|
626
|
+
// stop printing a checkmark for a state it never verified.
|
|
627
|
+
if (claudeSnapshotReady(home, root)) return { ok: true, actions };
|
|
628
|
+
return {
|
|
629
|
+
ok: true,
|
|
630
|
+
degraded: true,
|
|
631
|
+
code: 'CLAUDE_PLUGIN_SNAPSHOT_STALE',
|
|
632
|
+
reason: `Claude Code has not loaded the plugin; run: claude plugin install ${PLUGIN_KEY}`,
|
|
633
|
+
actions,
|
|
634
|
+
};
|
|
604
635
|
}
|
|
605
636
|
|
|
606
637
|
export function installCodex({ home = homedir(), scope, root = ROOT, env = process.env } = {}) {
|
|
@@ -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';
|
|
@@ -2668,10 +2668,10 @@ async function activateRelease({ home, releaseDir, manifest, log, installer, sup
|
|
|
2668
2668
|
|
|
2669
2669
|
const claude = await installer.installClaudeCode({ home, root: integrationRoot });
|
|
2670
2670
|
if (claude.ok === false) {
|
|
2671
|
-
log(
|
|
2671
|
+
log(claudeIntegrationLine(claude));
|
|
2672
2672
|
return false;
|
|
2673
2673
|
}
|
|
2674
|
-
log(
|
|
2674
|
+
log(claudeIntegrationLine(claude));
|
|
2675
2675
|
|
|
2676
2676
|
// The official ~/.dsh/profiles/web tree is read-only: activation never
|
|
2677
2677
|
// repairs or mutates the official bridge. The isolated 3210 Crew backend
|
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.6';
|
|
40
40
|
export const HUB_PROTOCOL_VERSION = 1;
|
|
41
41
|
|
|
42
42
|
export const HUB_CAPABILITIES = Object.freeze([
|