@ran-sh/dsh-crew 1.3.1 → 1.3.2

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": "1.3.1",
3
+ "version": "1.3.2",
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": "1.3.1",
3
+ "version": "1.3.2",
4
4
  "type": "module",
5
5
  "main": "./src/hub/entry.mjs",
6
6
  "bin": {
@@ -13,6 +13,22 @@ function method(object, name) {
13
13
  }
14
14
  }
15
15
 
16
+ /**
17
+ * Whether one registered agent currently owns a running turn.
18
+ *
19
+ * Registration is not activity: the session controller resumes a session into
20
+ * the registry as soon as it opens it, and leaves it there after the turn ends
21
+ * with `status: 'idle'`. Treating a non-empty registry as "in use" therefore
22
+ * wedged cleanup permanently behind ACTIVE_SESSIONS on a machine whose web UI had
23
+ * ever opened a session. Only a `running` status means work is actually in
24
+ * flight; anything else (idle, or a status an older agent does not expose) is
25
+ * treated as not running, and `creating > 0` remains the independent guard for a
26
+ * creation that has not published yet.
27
+ */
28
+ function isRunning(agent) {
29
+ try { return agent?.status === 'running'; } catch { return false; }
30
+ }
31
+
16
32
  export function installHistoryAdmissionGate(agents, isMaintenancePending) {
17
33
  if (typeof agents?.create !== 'function' || typeof agents?.list !== 'function'
18
34
  || typeof isMaintenancePending !== 'function') throw new Error('HISTORY_ADMISSION_UNAVAILABLE');
@@ -40,7 +56,7 @@ export function installHistoryAdmissionGate(agents, isMaintenancePending) {
40
56
  if (entries.some(entry => method(agents, entry.name) !== entry.wrapper)) return false;
41
57
  try {
42
58
  const live = agents.list();
43
- return Array.isArray(live) && creating === 0 && live.length === 0;
59
+ return Array.isArray(live) && creating === 0 && !live.some(isRunning);
44
60
  } catch { return false; }
45
61
  },
46
62
  dispose() {
@@ -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 = '1.3.1';
39
+ export const RUNTIME_VERSION = '1.3.2';
40
40
  export const HUB_PROTOCOL_VERSION = 1;
41
41
 
42
42
  export const HUB_CAPABILITIES = Object.freeze([