@ran-sh/dsh-crew 2.0.6 → 2.0.8

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-crew",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "description": "Dispatch subtasks to DeepSeek Harness (DSH) agents as native subagents with live progress",
5
5
  "author": {
6
6
  "name": "ZSeven-W"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ran-sh/dsh-crew",
3
- "version": "2.0.6",
3
+ "version": "2.0.8",
4
4
  "type": "module",
5
5
  "main": "./src/hub/entry.mjs",
6
6
  "bin": {
@@ -15,6 +15,14 @@ import { integrationRoot } from './crew-paths.mjs';
15
15
  const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..', '..');
16
16
  const MARKETPLACE_NAME = 'dsh-crew';
17
17
  const PLUGIN_KEY = `dsh-crew@${MARKETPLACE_NAME}`;
18
+ // A Claude Code plugin refresh is a real copy of the plugin tree, and its cost
19
+ // tracks machine load: 163s measured idle, ~6 minutes measured during an
20
+ // activation. The ceiling bounds the shell's patience, and the settle window
21
+ // keeps watching afterwards, because a timed-out child on Windows is not in the
22
+ // shell's process tree and goes on writing once the shell has given up.
23
+ const CLAUDE_PLUGIN_TIMEOUT_MS = 300_000;
24
+ const CLAUDE_SNAPSHOT_SETTLE_MS = 180_000;
25
+ const CLAUDE_SNAPSHOT_POLL_MS = 5_000;
18
26
  const POLICY_START = '<!-- DSH CREW MANAGED POLICY:START -->';
19
27
  const POLICY_END = '<!-- DSH CREW MANAGED POLICY:END -->';
20
28
 
@@ -599,7 +607,12 @@ export async function installClaudeCode({ home = homedir(), statusline = false,
599
607
  }
600
608
  try {
601
609
  const { execSync } = await import('node:child_process');
602
- const run = (cmd) => execSync(cmd, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: 120_000 });
610
+ // 300s, not 120: the install below runs after the uninstall, so it does a real
611
+ // copy of the plugin tree rather than the no-op an already-installed plugin
612
+ // gets. Measured on this machine: `marketplace add` 3s, `uninstall` 3s,
613
+ // `install` 163s (no-op install: 6s). The old ceiling killed the copy partway
614
+ // and left Claude Code without the plugin the same run had just removed.
615
+ const run = (cmd) => execSync(cmd, { encoding: 'utf8', stdio: ['ignore', 'pipe', 'pipe'], timeout: CLAUDE_PLUGIN_TIMEOUT_MS });
603
616
  try { run(`claude plugin marketplace add ${JSON.stringify(mpDir)}`); actions.push('cli: marketplace registered'); }
604
617
  catch { actions.push('cli: marketplace add skipped (already registered)'); }
605
618
  // `plugin install` on an already-installed plugin is a no-op and leaves a
@@ -625,6 +638,21 @@ export async function installClaudeCode({ home = homedir(), statusline = false,
625
638
  // snapshot that `installStatus` reads. Saying so here is what lets the caller
626
639
  // stop printing a checkmark for a state it never verified.
627
640
  if (claudeSnapshotReady(home, root)) return { ok: true, actions };
641
+ // The CLI can outlive the ceiling above. The install is a real copy of the
642
+ // plugin tree — 163s measured on an idle machine, and ~6 minutes measured
643
+ // during an activation, where the record landed well after any ceiling — and a
644
+ // timed-out child on Windows is not in the shell's process tree, so a copy that
645
+ // is still running keeps writing while this function has already given up on
646
+ // it. Wait for the snapshot to settle before reporting it missing, or the
647
+ // update says "not loaded" about a plugin that is loading.
648
+ const settleDeadline = Date.now() + CLAUDE_SNAPSHOT_SETTLE_MS;
649
+ const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
650
+ while (Date.now() < settleDeadline) {
651
+ await wait(CLAUDE_SNAPSHOT_POLL_MS);
652
+ if (claudeSnapshotReady(home, root)) {
653
+ return { ok: true, actions: [...actions, 'cli: snapshot confirmed current after the ceiling'] };
654
+ }
655
+ }
628
656
  return {
629
657
  ok: true,
630
658
  degraded: true,
@@ -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.6';
39
+ export const RUNTIME_VERSION = '2.0.8';
40
40
  export const HUB_PROTOCOL_VERSION = 1;
41
41
 
42
42
  export const HUB_CAPABILITIES = Object.freeze([