@ran-sh/dsh-crew 2.1.7 → 2.1.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.1.7",
3
+ "version": "2.1.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.1.7",
3
+ "version": "2.1.8",
4
4
  "type": "module",
5
5
  "main": "./src/hub/entry.mjs",
6
6
  "bin": {
@@ -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.1.7';
39
+ export const RUNTIME_VERSION = '2.1.8';
40
40
  export const HUB_PROTOCOL_VERSION = 1;
41
41
 
42
42
  export const HUB_CAPABILITIES = Object.freeze([
@@ -408,9 +408,7 @@ export function createWorkflowRuntime(adapters, {
408
408
  source: job.source,
409
409
  model_class_hint: job.model_class_hint,
410
410
  escalation_reason: escalationReason,
411
- onAttemptStarted: (actualId) => {
412
- if (typeof actualId === 'string' && actualId) job.current_attempt_id = actualId;
413
- },
411
+ onAttemptStarted: (actualId) => adoptAttemptId(job, actualId),
414
412
  });
415
413
  job.current_attempt_id = null;
416
414
  if (job.cancelling) { await cancelWorkflow(job); return; }
@@ -602,9 +600,7 @@ export function createWorkflowRuntime(adapters, {
602
600
  source: job.source,
603
601
  model_class_hint: 'pro',
604
602
  escalation_reason: null,
605
- onAttemptStarted: (actualId) => {
606
- if (typeof actualId === 'string' && actualId) job.current_attempt_id = actualId;
607
- },
603
+ onAttemptStarted: (actualId) => adoptAttemptId(job, actualId),
608
604
  });
609
605
  job.current_attempt_id = null;
610
606
  const attemptView = { ...attemptRecord(ar, 0), phase: 'review' };
@@ -665,6 +661,31 @@ export function createWorkflowRuntime(adapters, {
665
661
  : `${workflowId}-a${suffix || '0'}`;
666
662
  }
667
663
 
664
+ /**
665
+ * Record the id the executor actually started, and honour a cancel that
666
+ * arrived while it was still being dispatched.
667
+ *
668
+ * `cancelWorkflow` can only stop what `current_attempt_id` names. During
669
+ * dispatch that is the workflow-scoped placeholder, which the transport does
670
+ * not recognise as a runnable attempt, so a cancel landing in that window
671
+ * stops nothing — and the job the executor starts a moment later runs to
672
+ * completion while the workflow reports itself cancelled. Re-cancelling after
673
+ * the attempt returns does not help: `cancelWorkflow` returns the promise it
674
+ * already made. This is the one moment the real id becomes known, so the
675
+ * cancel that already happened is applied here.
676
+ */
677
+ function adoptAttemptId(job, actualId) {
678
+ if (typeof actualId !== 'string' || actualId === '') return;
679
+ job.current_attempt_id = actualId;
680
+ if (!job.cancelling) return;
681
+ try {
682
+ Promise.resolve(adapters.cancelAttempt?.(actualId)).catch(() => {});
683
+ } catch {
684
+ // A transport that throws synchronously is still a cancel that did not
685
+ // land; the workflow's own terminal state is unchanged by it.
686
+ }
687
+ }
688
+
668
689
  function cancelWorkflow(job) {
669
690
  if (job.cancelPromise) return job.cancelPromise;
670
691
  if (job.status !== 'running') return;