@delete101020/aidlc 4.0.41 → 4.0.44

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.
Files changed (2) hide show
  1. package/dist/bundle.js +146 -80
  2. package/package.json +1 -1
package/dist/bundle.js CHANGED
@@ -19962,8 +19962,9 @@ var require_WorkspaceSchema = __commonJS({
19962
19962
  * The target is a step name (or agent id) before this one, without
19963
19963
  * `human_review` — work a human gate approved goes back through a human.
19964
19964
  * A validator can name the same target in its verdict (`sendBackTo`), or
19965
- * name this step / `null` to stop here instead. Bounded by the
19966
- * pipeline's `max_send_backs`.
19965
+ * name this step / `null` to stop here instead. Naming any other earlier
19966
+ * step — a `human_review` one included — sends the work back there and
19967
+ * stops the run for a person. Bounded by the pipeline's `max_send_backs`.
19967
19968
  */
19968
19969
  on_reject: zod_1.z.object({ send_back_to: zod_1.z.string().min(1) }).optional(),
19969
19970
  /**
@@ -19993,6 +19994,12 @@ var require_WorkspaceSchema = __commonJS({
19993
19994
  pause_between_batches: zod_1.z.boolean().optional(),
19994
19995
  /** When true, the runner pauses for human approval before advancing. */
19995
19996
  human_review: zod_1.z.boolean().default(false),
19997
+ /**
19998
+ * A step only a person can run — the unattended `run exec` loop stops
19999
+ * before it, as a clean stop rather than an error, and leaves it
20000
+ * `awaiting_work` for someone to run by hand.
20001
+ */
20002
+ attended: zod_1.z.boolean().optional(),
19996
20003
  /**
19997
20004
  * Command run once after a batch of follow-up epics is opened from the
19998
20005
  * `followups.json` this step produces. See `schema/FollowUpHookSchema.ts`,
@@ -20173,6 +20180,7 @@ var require_WorkspaceSchema = __commonJS({
20173
20180
  }
20174
20181
  } : {},
20175
20182
  human_review: obj.human_review === true,
20183
+ ...obj.attended === true && { attended: true },
20176
20184
  ...git && { git }
20177
20185
  };
20178
20186
  }
@@ -20665,6 +20673,9 @@ var require_PipelineAssembler = __commonJS({
20665
20673
  if (norm.model) {
20666
20674
  step.model = norm.model;
20667
20675
  }
20676
+ if (norm.attended) {
20677
+ step.attended = true;
20678
+ }
20668
20679
  if (auto_review_runner) {
20669
20680
  step.auto_review_runner = auto_review_runner;
20670
20681
  }
@@ -21484,6 +21495,7 @@ var require_PipelineRunner = __commonJS({
21484
21495
  exports2.rerunStep = rerunStep3;
21485
21496
  exports2.chooseStepSkill = chooseStepSkill;
21486
21497
  exports2.chooseStepModel = chooseStepModel;
21498
+ exports2.recordLaunchFeedback = recordLaunchFeedback;
21487
21499
  exports2.requestStepUpdate = requestStepUpdate2;
21488
21500
  exports2.dirtyUpstreamOf = dirtyUpstreamOf2;
21489
21501
  exports2.canRerunApprovedStep = canRerunApprovedStep;
@@ -21809,7 +21821,6 @@ ${route.note}` : verdict.reason;
21809
21821
  return advance(next, idx, pipeline);
21810
21822
  }
21811
21823
  function autoRejectRoute(state, pipeline, idx, norm, verdict) {
21812
- const label = (i) => `"${(0, RunState_1.stepIdentity)(state.steps[i])}" (step ${i + 1})`;
21813
21824
  const configured = norm.on_reject?.send_back_to;
21814
21825
  const cfgIdx = configured ? (0, WorkspaceSchema_1.findStepIndex)(pipeline.steps.map(WorkspaceSchema_1.normalizeStep), configured) : -1;
21815
21826
  if (configured && !(cfgIdx >= 0 && cfgIdx < idx)) {
@@ -21829,13 +21840,7 @@ ${route.note}` : verdict.reason;
21829
21840
  if (v < 0 || v > idx) {
21830
21841
  return { note: `The validator asked to send this back to "${asked}", which is not a step before this one.` };
21831
21842
  }
21832
- if (v !== cfgIdx) {
21833
- const allowed = cfgIdx >= 0 ? `only ${label(cfgIdx)} is` : "no step is (see `on_reject.send_back_to`)";
21834
- return {
21835
- note: `The validator suggests sending this back to ${label(v)}; ${allowed} sent back automatically. Send it back by hand if you agree.`
21836
- };
21837
- }
21838
- return { targetIdx: v, source: "verdict" };
21843
+ return { targetIdx: v, source: v === cfgIdx ? "verdict" : "handoff" };
21839
21844
  }
21840
21845
  function retryAutoReview(args) {
21841
21846
  const { pipeline } = args;
@@ -21988,6 +21993,29 @@ ${route.note}` : verdict.reason;
21988
21993
  next.steps[stepIdx] = { ...target, chosenModel: model };
21989
21994
  return next;
21990
21995
  }
21996
+ function recordLaunchFeedback(args) {
21997
+ const { state, stepIdx } = args;
21998
+ if (!Number.isInteger(stepIdx) || stepIdx < 0 || stepIdx >= state.steps.length) {
21999
+ throw new PipelineRunError3(`Invalid stepIdx ${stepIdx}`);
22000
+ }
22001
+ const feedback = args.feedback.trim();
22002
+ const target = state.steps[stepIdx];
22003
+ if (!feedback || feedback === target.feedback?.trim()) {
22004
+ return state;
22005
+ }
22006
+ const next = clone(state);
22007
+ next.steps[stepIdx] = {
22008
+ ...target,
22009
+ feedback,
22010
+ history: [...target.history ?? [], {
22011
+ kind: "feedback",
22012
+ at: (/* @__PURE__ */ new Date()).toISOString(),
22013
+ revision: target.revision,
22014
+ feedback
22015
+ }]
22016
+ };
22017
+ return next;
22018
+ }
21991
22019
  function requestStepUpdate2(args) {
21992
22020
  const { state, pipeline, stepIdx, feedback } = args;
21993
22021
  if (!Number.isInteger(stepIdx) || stepIdx < 0 || stepIdx >= state.steps.length) {
@@ -22294,7 +22322,7 @@ ${route.note}` : verdict.reason;
22294
22322
  const { idx, targetIdx, reason, at: now, pipeline, source } = args;
22295
22323
  const before = clone(next);
22296
22324
  const step = next.steps[idx];
22297
- const blame = `Rejected at step ${idx + 1} (${step.agent})${reason ? `: ${reason}` : ""}`;
22325
+ const blame = `Rejected at step ${idx + 1} (${(0, RunState_1.stepIdentity)(step)})${reason ? `: ${reason}` : ""}`;
22298
22326
  const rejectedHistory = pushHistory(step.history, {
22299
22327
  kind: "reject",
22300
22328
  at: now,
@@ -29101,7 +29129,7 @@ var require_DefaultRunner = __commonJS({
29101
29129
  if (evt.type === "assistant" && evt.message?.content) {
29102
29130
  for (const block of evt.message.content) {
29103
29131
  if (block.type === "text" && typeof block.text === "string") {
29104
- ctx.onOutput(block.text);
29132
+ ctx.onOutput(block.text.replace(/\s*$/, "\n\n"));
29105
29133
  }
29106
29134
  }
29107
29135
  } else if (evt.type === "result") {
@@ -32339,6 +32367,7 @@ var require_execEngine = __commonJS({
32339
32367
  };
32340
32368
  }();
32341
32369
  Object.defineProperty(exports2, "__esModule", { value: true });
32370
+ exports2.stepLabel = stepLabel3;
32342
32371
  exports2.runExecLoop = runExecLoop2;
32343
32372
  var path17 = __importStar(require("path"));
32344
32373
  var WorkspaceLoader_1 = require_WorkspaceLoader();
@@ -32366,6 +32395,9 @@ var require_execEngine = __commonJS({
32366
32395
  var promptComposer_1 = require_promptComposer();
32367
32396
  var projectInstructions_1 = require_projectInstructions();
32368
32397
  var types_1 = require_types();
32398
+ function stepLabel3(s) {
32399
+ return s.name ?? s.agent;
32400
+ }
32369
32401
  function loadPipelineForRun(root, state) {
32370
32402
  try {
32371
32403
  const ws = WorkspaceLoader_1.WorkspaceLoader.load(root);
@@ -32441,6 +32473,9 @@ var require_execEngine = __commonJS({
32441
32473
  if (!proceed) {
32442
32474
  return { kind: "error" };
32443
32475
  }
32476
+ if (proceed === "handoff") {
32477
+ return { kind: "attended" };
32478
+ }
32444
32479
  continue;
32445
32480
  }
32446
32481
  if (step.status === "awaiting_review") {
@@ -32448,7 +32483,7 @@ var require_execEngine = __commonJS({
32448
32483
  await autoApproveStep(root, state, hooks);
32449
32484
  continue;
32450
32485
  }
32451
- hooks.onAwaitingReview?.({ agent: step.agent, runId });
32486
+ hooks.onAwaitingReview?.({ agent: step.agent, label: stepLabel3(step), runId });
32452
32487
  return { kind: "awaiting_review" };
32453
32488
  }
32454
32489
  if (step.status === "rejected") {
@@ -32458,25 +32493,26 @@ var require_execEngine = __commonJS({
32458
32493
  hooks.onStepSkipped?.({
32459
32494
  stepIdx: state.currentStepIdx,
32460
32495
  agent: step.agent,
32496
+ label: stepLabel3(step),
32461
32497
  reason: step.rejectReason ?? step.autoReviewVerdict?.reason ?? "rejected",
32462
32498
  nextStepIdx: openElsewhere,
32463
32499
  runId
32464
32500
  });
32465
- RunStateStore_1.RunStateStore.save(root, { ...state, currentStepIdx: openElsewhere });
32501
+ persist(root, { ...state, currentStepIdx: openElsewhere });
32466
32502
  continue;
32467
32503
  }
32468
- hooks.onRejected?.({ agent: step.agent, runId });
32504
+ hooks.onRejected?.({ agent: step.agent, label: stepLabel3(step), runId });
32469
32505
  return { kind: "rejected" };
32470
32506
  }
32471
32507
  if (step.status === "approved") {
32472
32508
  const openElsewhere = state.steps.findIndex((s) => (0, runProgress_1.isActiveStatus)(s.status));
32473
32509
  if (openElsewhere >= 0) {
32474
- RunStateStore_1.RunStateStore.save(root, { ...state, currentStepIdx: openElsewhere });
32510
+ persist(root, { ...state, currentStepIdx: openElsewhere });
32475
32511
  continue;
32476
32512
  }
32477
32513
  const parked = state.steps.find((s) => s.status === "rejected");
32478
32514
  if (parked) {
32479
- hooks.onRejected?.({ agent: parked.agent, runId });
32515
+ hooks.onRejected?.({ agent: parked.agent, label: stepLabel3(parked), runId });
32480
32516
  return { kind: "rejected" };
32481
32517
  }
32482
32518
  }
@@ -32484,6 +32520,10 @@ var require_execEngine = __commonJS({
32484
32520
  hooks.onRunFailed?.(`Unexpected step status "${step.status}" \u2014 cannot exec.`);
32485
32521
  return { kind: "error" };
32486
32522
  }
32523
+ if (!opts.dryRun && initialPipeline.steps[state.currentStepIdx] && (0, WorkspaceSchema_1.normalizeStep)(initialPipeline.steps[state.currentStepIdx]).attended) {
32524
+ hooks.onAttendedStep?.({ stepIdx: state.currentStepIdx, agent: step.agent, label: stepLabel3(step), runId });
32525
+ return { kind: "attended" };
32526
+ }
32487
32527
  const ran = await execStep(root, state, runId, opts, hooks);
32488
32528
  if (ran === "failed") {
32489
32529
  return { kind: "error" };
@@ -32510,6 +32550,7 @@ var require_execEngine = __commonJS({
32510
32550
  hooks.onStalled?.({
32511
32551
  stepIdx: idx,
32512
32552
  agent: step.agent,
32553
+ label: stepLabel3(step),
32513
32554
  revision: step.revision,
32514
32555
  runId,
32515
32556
  reason: `"${step.agent}" ran ${n} batch${n === 1 ? "" : "es"} (\`max_batches: ${cfg.max}\`) and still says \`Status: continue\`. Read its progress before letting it carry on: running exec again allows ${cfg.max} more.`
@@ -32520,6 +32561,7 @@ var require_execEngine = __commonJS({
32520
32561
  hooks.onBatchPause?.({
32521
32562
  stepIdx: idx,
32522
32563
  agent: step.agent,
32564
+ label: stepLabel3(step),
32523
32565
  batch: batchNo,
32524
32566
  runId,
32525
32567
  report: batchReport(initialPipeline, after ?? state, idx) ?? ""
@@ -32605,17 +32647,17 @@ var require_execEngine = __commonJS({
32605
32647
  try {
32606
32648
  ws = WorkspaceLoader_1.WorkspaceLoader.load(root);
32607
32649
  } catch (err) {
32608
- hooks.onStepFailed?.({ stepIdx, agent: agentId, message: `Failed to load workspace: ${errMsg(err)}` });
32650
+ hooks.onStepFailed?.({ stepIdx, agent: agentId, label: stepLabel3(stepRec), message: `Failed to load workspace: ${errMsg(err)}` });
32609
32651
  return "failed";
32610
32652
  }
32611
32653
  const pipeline = ws.config.pipelines.find((p) => p.id === state.pipelineId);
32612
32654
  if (!pipeline) {
32613
- hooks.onStepFailed?.({ stepIdx, agent: agentId, message: `Pipeline "${state.pipelineId}" not found in workspace.yaml.` });
32655
+ hooks.onStepFailed?.({ stepIdx, agent: agentId, label: stepLabel3(stepRec), message: `Pipeline "${state.pipelineId}" not found in workspace.yaml.` });
32614
32656
  return "failed";
32615
32657
  }
32616
32658
  const agent = ws.config.agents.find((a) => a.id === agentId);
32617
32659
  if (!agent) {
32618
- hooks.onStepFailed?.({ stepIdx, agent: agentId, message: `Agent "${agentId}" not found in workspace.yaml.` });
32660
+ hooks.onStepFailed?.({ stepIdx, agent: agentId, label: stepLabel3(stepRec), message: `Agent "${agentId}" not found in workspace.yaml.` });
32619
32661
  return "failed";
32620
32662
  }
32621
32663
  const stepCfg = pipeline.steps[stepIdx];
@@ -32630,13 +32672,13 @@ var require_execEngine = __commonJS({
32630
32672
  try {
32631
32673
  runner = ws.runners.resolve(agent);
32632
32674
  } catch (err) {
32633
- hooks.onStepFailed?.({ stepIdx, agent: agentId, message: `Failed to resolve runner for agent "${agentId}": ${errMsg(err)}` });
32675
+ hooks.onStepFailed?.({ stepIdx, agent: agentId, label: stepLabel3(stepRec), message: `Failed to resolve runner for agent "${agentId}": ${errMsg(err)}` });
32634
32676
  return "failed";
32635
32677
  }
32636
32678
  try {
32637
32679
  prompt2 = buildStepPrompt(ws, agent, skillIds, runner, root, state.runId, stepRec, stepIdx);
32638
32680
  } catch (err) {
32639
- hooks.onStepFailed?.({ stepIdx, agent: agentId, message: `Failed to load skills for agent "${agentId}": ${errMsg(err)}` });
32681
+ hooks.onStepFailed?.({ stepIdx, agent: agentId, label: stepLabel3(stepRec), message: `Failed to load skills for agent "${agentId}": ${errMsg(err)}` });
32640
32682
  return "failed";
32641
32683
  }
32642
32684
  const skillText = prompt2.text;
@@ -32656,6 +32698,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32656
32698
  hooks.onStepFailed?.({
32657
32699
  stepIdx,
32658
32700
  agent: agentId,
32701
+ label: stepLabel3(stepRec),
32659
32702
  message: `Step "${agentId}" has \`batches: true\` but no \`produces\` file to write its \`Status:\` line in.`
32660
32703
  });
32661
32704
  return "failed";
@@ -32676,6 +32719,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32676
32719
  hooks.onStepStart?.({
32677
32720
  stepIdx,
32678
32721
  agent: agentId,
32722
+ label: stepLabel3(stepRec),
32679
32723
  revision: stepRec.revision,
32680
32724
  skills: skillIds,
32681
32725
  model: agentModel,
@@ -32727,15 +32771,16 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32727
32771
  hooks.onStepFailed?.({
32728
32772
  stepIdx,
32729
32773
  agent: agentId,
32774
+ label: stepLabel3(stepRec),
32730
32775
  message: `Step "${agentId}" ran past its ${minutes}-minute limit (\`timeout_minutes\`) and was stopped. It is still awaiting work on revision ${stepRec.revision}; nothing was sent back. Whatever it half-wrote is still in the working tree.`
32731
32776
  });
32732
32777
  return "failed";
32733
32778
  }
32734
- hooks.onStepStopped?.({ stepIdx, agent: agentId, revision: stepRec.revision, runId });
32779
+ hooks.onStepStopped?.({ stepIdx, agent: agentId, label: stepLabel3(stepRec), revision: stepRec.revision, runId });
32735
32780
  return "stopped";
32736
32781
  }
32737
32782
  if (!result || !result.success) {
32738
- hooks.onStepFailed?.({ stepIdx, agent: agentId, message: `Step "${agentId}" failed (non-zero exit).` });
32783
+ hooks.onStepFailed?.({ stepIdx, agent: agentId, label: stepLabel3(stepRec), message: `Step "${agentId}" failed (non-zero exit).` });
32739
32784
  return "failed";
32740
32785
  }
32741
32786
  const codeUnchanged = codeBefore !== null && (0, codeFingerprint_1.codeFingerprint)(root, codeExclude) === codeBefore;
@@ -32743,6 +32788,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32743
32788
  hooks.onStalled?.({
32744
32789
  stepIdx,
32745
32790
  agent: agentId,
32791
+ label: stepLabel3(stepRec),
32746
32792
  revision: stepRec.revision,
32747
32793
  runId,
32748
32794
  reason: `Revision ${stepRec.revision} of "${agentId}" changed no code \u2014 the working tree is what it was before it ran (its report aside). Sent back ${state.sendBacks} time${state.sendBacks === 1 ? "" : "s"}; stopping rather than have the same code reviewed again.`
@@ -32754,6 +32800,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32754
32800
  hooks.onStepFailed?.({
32755
32801
  stepIdx,
32756
32802
  agent: agentId,
32803
+ label: stepLabel3(stepRec),
32757
32804
  message: `Step "${agentId}" reported success but left its artifacts unchanged: ${stale.join(", ")}. The agent may have failed to write them. Check its output, then rerun the step.`
32758
32805
  });
32759
32806
  return "failed";
@@ -32764,6 +32811,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32764
32811
  hooks.onStepFailed?.({
32765
32812
  stepIdx,
32766
32813
  agent: agentId,
32814
+ label: stepLabel3(stepRec),
32767
32815
  message: `Step "${agentId}" runs in batches and its report cannot say whether it is done: ${read.error} Add the line, then run exec again.`
32768
32816
  });
32769
32817
  return "failed";
@@ -32773,6 +32821,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32773
32821
  hooks.onStalled?.({
32774
32822
  stepIdx,
32775
32823
  agent: agentId,
32824
+ label: stepLabel3(stepRec),
32776
32825
  revision: stepRec.revision,
32777
32826
  runId,
32778
32827
  reason: `Batch ${batchNo} of "${agentId}" asked for another session but changed no code \u2014 the working tree is what it was before it ran (its report aside). Stopping rather than start the same batch again.`
@@ -32782,7 +32831,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32782
32831
  const fresh = RunStateStore_1.RunStateStore.load(root, runId);
32783
32832
  const rec = fresh?.steps[stepIdx];
32784
32833
  if (!fresh || !rec) {
32785
- hooks.onStepFailed?.({ stepIdx, agent: agentId, message: `Run "${runId}" disappeared.` });
32834
+ hooks.onStepFailed?.({ stepIdx, agent: agentId, label: stepLabel3(stepRec), message: `Run "${runId}" disappeared.` });
32786
32835
  return "failed";
32787
32836
  }
32788
32837
  recordProvenance(rec, { agent, resolvedModel, agentModel, skillIds, alternatives, modelOpts });
@@ -32798,6 +32847,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32798
32847
  hooks.onBatchDone?.({
32799
32848
  stepIdx,
32800
32849
  agent: agentId,
32850
+ label: stepLabel3(stepRec),
32801
32851
  revision: rec.revision,
32802
32852
  batch: batchNo,
32803
32853
  costUsd: cost,
@@ -32817,9 +32867,9 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32817
32867
  next = (0, PipelineRunner_1.markStepDone)({ state: freshState, pipeline, workspaceRoot: root });
32818
32868
  } catch (err) {
32819
32869
  if (err instanceof PipelineRunner_1.PipelineRunError && err.missing?.length) {
32820
- hooks.onStepFailed?.({ stepIdx, agent: agentId, missing: err.missing });
32870
+ hooks.onStepFailed?.({ stepIdx, agent: agentId, label: stepLabel3(stepRec), missing: err.missing });
32821
32871
  } else {
32822
- hooks.onStepFailed?.({ stepIdx, agent: agentId, message: errMsg(err) });
32872
+ hooks.onStepFailed?.({ stepIdx, agent: agentId, label: stepLabel3(stepRec), message: errMsg(err) });
32823
32873
  }
32824
32874
  return "failed";
32825
32875
  }
@@ -32828,6 +32878,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32828
32878
  hooks.onStepResult?.({
32829
32879
  stepIdx,
32830
32880
  agent: agentId,
32881
+ label: stepLabel3(stepRec),
32831
32882
  status: doneStep.status,
32832
32883
  costUsd: doneStep.costUsd,
32833
32884
  costEstimated: doneStep.costEstimated,
@@ -32952,19 +33003,19 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32952
33003
  return false;
32953
33004
  }
32954
33005
  const step = state.steps[state.currentStepIdx];
32955
- hooks.onAutoReviewStart?.({ agent: step.agent });
33006
+ hooks.onAutoReviewStart?.({ agent: step.agent, label: stepLabel3(step) });
32956
33007
  let verdict;
32957
33008
  try {
32958
33009
  verdict = await (0, AutoReviewer_1.runAutoReview)({ workspaceRoot: root, state, pipeline });
32959
33010
  } catch (err) {
32960
- hooks.onStepFailed?.({ stepIdx: state.currentStepIdx, agent: step.agent, message: `Auto-review could not run: ${errMsg(err)}` });
33011
+ hooks.onStepFailed?.({ stepIdx: state.currentStepIdx, agent: step.agent, label: stepLabel3(step), message: `Auto-review could not run: ${errMsg(err)}` });
32961
33012
  return false;
32962
33013
  }
32963
33014
  let next;
32964
33015
  try {
32965
33016
  next = (0, PipelineRunner_1.submitAutoReviewVerdict)({ state, pipeline, verdict });
32966
33017
  } catch (err) {
32967
- hooks.onStepFailed?.({ stepIdx: state.currentStepIdx, agent: step.agent, message: errMsg(err) });
33018
+ hooks.onStepFailed?.({ stepIdx: state.currentStepIdx, agent: step.agent, label: stepLabel3(step), message: errMsg(err) });
32968
33019
  return false;
32969
33020
  }
32970
33021
  persist(root, next, state);
@@ -32972,6 +33023,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32972
33023
  const sentBack = verdict.decision === "reject" && next.currentStepIdx !== idx && next.steps[idx].status === "pending";
32973
33024
  hooks.onAutoReviewResult?.({
32974
33025
  agent: step.agent,
33026
+ label: stepLabel3(step),
32975
33027
  decision: verdict.decision,
32976
33028
  reason: next.steps[idx].rejectReason ?? verdict.reason,
32977
33029
  runId,
@@ -32979,12 +33031,19 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32979
33031
  sentBackTo: {
32980
33032
  stepIdx: next.currentStepIdx,
32981
33033
  agent: next.steps[next.currentStepIdx].agent,
33034
+ label: stepLabel3(next.steps[next.currentStepIdx]),
32982
33035
  revision: next.steps[next.currentStepIdx].revision,
32983
33036
  count: next.sendBacks ?? 0,
32984
33037
  max: pipeline.max_send_backs ?? WorkspaceSchema_1.DEFAULT_MAX_SEND_BACKS
32985
33038
  }
32986
33039
  } : {}
32987
33040
  });
33041
+ const last = next.steps[idx].history?.at(-1);
33042
+ if (sentBack && last?.kind === "reject" && last.source === "handoff") {
33043
+ const target = next.steps[next.currentStepIdx];
33044
+ hooks.onAttendedStep?.({ stepIdx: next.currentStepIdx, agent: target.agent, label: stepLabel3(target), runId });
33045
+ return "handoff";
33046
+ }
32988
33047
  return true;
32989
33048
  }
32990
33049
  function isAutoSendBackTarget(state, stepIdx) {
@@ -33006,13 +33065,10 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
33006
33065
  const pipeline = ws.config.pipelines.find((p) => p.id === state.pipelineId);
33007
33066
  const next = { ...(0, PipelineRunner_1.approveStep)({ state, pipeline }), sendBacks: state.sendBacks };
33008
33067
  persist(root, next, state);
33009
- hooks.onAutoApproved?.({ agent: state.steps[state.currentStepIdx].agent });
33068
+ hooks.onAutoApproved?.({ agent: state.steps[state.currentStepIdx].agent, label: stepLabel3(state.steps[state.currentStepIdx]) });
33010
33069
  }
33011
33070
  function persist(root, next, before) {
33012
33071
  RunStateStore_1.RunStateStore.save(root, next);
33013
- if (!before) {
33014
- return;
33015
- }
33016
33072
  let doc;
33017
33073
  try {
33018
33074
  doc = WorkspaceLoader_1.WorkspaceLoader.load(root).config;
@@ -33020,13 +33076,13 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
33020
33076
  return;
33021
33077
  }
33022
33078
  const cfgDoc = doc;
33023
- if ((0, EpicArtifactCommit_1.resolveArtifactCommitConfig)(cfgDoc).mode !== "on_approve") {
33024
- return;
33025
- }
33026
33079
  try {
33027
33080
  (0, EpicScaffold_1.mirrorRunStateToEpic)(root, next, cfgDoc);
33028
33081
  } catch {
33029
33082
  }
33083
+ if (!before || (0, EpicArtifactCommit_1.resolveArtifactCommitConfig)(cfgDoc).mode !== "on_approve") {
33084
+ return;
33085
+ }
33030
33086
  (0, EpicArtifactCommit_1.commitApprovedArtifacts)({ workspaceRoot: root, before, after: next, doc: cfgDoc });
33031
33087
  }
33032
33088
  function errMsg(err) {
@@ -33181,6 +33237,8 @@ var require_runReport = __commonJS({
33181
33237
  return ` - \u21B6 mark-done undone (rev ${h.revision}, was ${h.from})`;
33182
33238
  case "interrupted":
33183
33239
  return h.why === "timeout" ? ` - \u23F1 stopped after ${h.minutes ?? "?"} min (timeout_minutes, rev ${h.revision})` : ` - \u23F9 stopped mid-step (rev ${h.revision})`;
33240
+ case "feedback":
33241
+ return ` - \u270E launched with feedback (rev ${h.revision}): ${h.feedback}`;
33184
33242
  case "batch":
33185
33243
  return ` - \u21BB batch ${h.batch} done, more to come (rev ${h.revision}${typeof h.costUsd === "number" ? `, $${h.costUsd.toFixed(4)}` : ""})`;
33186
33244
  default:
@@ -33227,7 +33285,7 @@ var require_runReport = __commonJS({
33227
33285
  lines.push("| # | Step | Status | Rev | Engine | Duration | Cost |");
33228
33286
  lines.push("|---|------|--------|-----|--------|----------|------|");
33229
33287
  for (const step of state.steps) {
33230
- const label = stepLabel2(step, pipeline);
33288
+ const label = stepLabel3(step, pipeline);
33231
33289
  lines.push(`| ${step.stepIdx} | ${cell(label)} | ${step.status} | ${step.revision} | ${cell(formatEngine(step))} | ${formatDuration(step.startedAt, step.finishedAt)} | ${formatCost(step)} |`);
33232
33290
  }
33233
33291
  const detailed = state.steps.filter((s) => s.rejectReason || s.feedback || s.autoReviewVerdict || s.history && s.history.length > 0);
@@ -33236,7 +33294,7 @@ var require_runReport = __commonJS({
33236
33294
  lines.push("## Step details");
33237
33295
  for (const step of detailed) {
33238
33296
  lines.push("");
33239
- lines.push(`### Step ${step.stepIdx}: ${stepLabel2(step, pipeline)}`);
33297
+ lines.push(`### Step ${step.stepIdx}: ${stepLabel3(step, pipeline)}`);
33240
33298
  if (step.feedback) {
33241
33299
  lines.push(`- **Feedback:** ${step.feedback}`);
33242
33300
  }
@@ -33255,7 +33313,7 @@ var require_runReport = __commonJS({
33255
33313
  lines.push("");
33256
33314
  return lines.join("\n");
33257
33315
  }
33258
- function stepLabel2(step, pipeline) {
33316
+ function stepLabel3(step, pipeline) {
33259
33317
  const cfg = pipeline?.steps?.[step.stepIdx];
33260
33318
  if (cfg && typeof cfg === "object" && typeof cfg.name === "string") {
33261
33319
  return cfg.name;
@@ -35403,10 +35461,10 @@ var require_dist = __commonJS({
35403
35461
  exports2.generatePlan = exports2.collectContext = exports2.followUpHookFailures = exports2.pendingFollowUpDone = exports2.applyFollowUpHookRun = exports2.trackFollowUpChildren = exports2.writeFollowUpHookLedger = exports2.readFollowUpHookLedger = exports2.followUpHookLedgerPath = exports2.runFollowUpHook = exports2.fillFollowUpHookCommand = exports2.resolveFollowUpHooks = exports2.epicPipelineId = exports2.FOLLOW_UP_HOOK_TIMEOUT_MS = exports2.FOLLOW_UP_HOOKS_LEDGER = exports2.stepProducesFollowUps = exports2.collectFollowUpHookIssues = exports2.FOLLOW_UP_HOOK_PLACEHOLDERS = exports2.FOLLOW_UP_HOOK_KEYS = exports2.FOLLOW_UP_INTENT = exports2.FOLLOW_UPS_FILE = exports2.MANUAL_FOLLOW_UP_KEY_PREFIX = exports2.followUpDefaults = exports2.nextManualFollowUpKey = exports2.withFollowUpProvenance = exports2.openManifestFollowUp = exports2.combinedParentId = exports2.followUpChildId = exports2.followUpsOf = exports2.readEpicFollowUps = exports2.parseFollowUps = exports2.FollowUpsParseError = exports2.FollowUpManifestSchema = exports2.FollowUpItemSchema = exports2.SIGNAL_FILE = exports2.FOLLOW_UP_ARTIFACT = exports2.readEpicSignal = exports2.existingEpicIds = exports2.followUpIdFor = exports2.followUpEpicId = exports2.renderIntentMarkdown = exports2.openFollowUpEpic = exports2.openIncidentEpic = exports2.SignalParseError = exports2.isSignal = exports2.parseSignal = exports2.SignalSchema = exports2.EpicStepEditError = exports2.resolveStepRef = exports2.describeGateEffect = void 0;
35404
35462
  exports2.readUserConfig = exports2.readGitUserName = exports2.ensureUserConfigIgnored = exports2.USER_CONFIG_RELPATH = exports2.USER_CONFIG_IGNORE_LINE = exports2.suggestEpicId = exports2.resolveEpicIdPrefixChain = exports2.resolveEpicIdPrefix = exports2.epicIdDateStamp = exports2.deriveEpicIdPrefix = exports2.EPIC_ID_PREFIX_PATTERN = exports2.EPIC_ID_PREFIX_KEY = exports2.resolveArtifactLanguage = exports2.commandBodyPredatesArtifactLanguage = exports2.artifactLanguageSection = exports2.ARTIFACT_LANGUAGE_HEADING = exports2.stripPersonaDirectives = exports2.composeAgentPrompt = exports2.PROJECT_INSTRUCTION_FILES = exports2.findProjectInstructions = exports2.stripPersonaMetadata = exports2.PersonaLoader = exports2.SkillNotFoundError = exports2.SkillLoader = exports2.EnvVarMissingError = exports2.EnvResolver = exports2.epicPipelineReport = exports2.planEpicPipelineExtraction = exports2.epicOwningPipeline = exports2.unstageEpicPipeline = exports2.stageEpicPipeline = exports2.writeEpicPipelines = exports2.splitEpicPipelines = exports2.mergeEpicPipelines = exports2.epicPipelinePath = exports2.EPIC_PIPELINE_FILENAME = exports2.unusedAfterStepRemoval = exports2.skillReferences = exports2.agentReferences = exports2.renameSkillRefs = exports2.renameAgentRefs = exports2.dropRecipesForPipeline = exports2.dropRecipeStep = exports2.recipesDrawingFrom = exports2.WORKSPACE_DIR = exports2.WORKSPACE_FILENAME = exports2.WorkspaceParseError = exports2.WorkspaceNotFoundError = exports2.WorkspaceLoader = exports2.renderPlanMarkdown = void 0;
35405
35463
  exports2.hasEmptyCiChecks = exports2.findApprovalGate = exports2.autopilotPreflight = exports2.STOP_GRACE_MS = exports2.stopProcessTree = exports2.stopOnAbort = exports2.processGroupSpawnOptions = exports2.claudeModelArg = exports2.DefaultRunner = exports2.RunnerRegistry = exports2.targetPath = exports2.scopePaths = exports2.discoverAssets = exports2.commandBodyIsStale = exports2.readEpicTags = exports2.normalizeTags = exports2.normalizeTag = exports2.epicMatchesTags = exports2.applyTagEdit = exports2.MAX_TAG_LENGTH = exports2.EPIC_TAGS_KEY = exports2.inheritedContextNote = exports2.INHERITED_CONTEXT_MARKER = exports2.strictModeSection = exports2.resolveEpicStrictMode = exports2.epicStrictMode = exports2.commandBodyPredatesStrictMode = exports2.STRICT_MODE_KEY = exports2.STRICT_MODE_HEADING = exports2.setEpicWatched = exports2.setEpicListFlat = exports2.setEpicSort = exports2.setActiveEpic = exports2.recordEpicOpened = exports2.readEpicListFlat = exports2.readEpicSort = exports2.readEpicFocus = exports2.pushRecent = exports2.epicSortFrom = exports2.epicIdFromBranch = exports2.epicFocusFrom = exports2.WATCHED_EPICS_KEY = exports2.RECENT_EPICS_LIMIT = exports2.RECENT_EPICS_KEY = exports2.EPIC_LIST_FLAT_KEY = exports2.EPIC_SORT_KEY = exports2.ACTIVE_EPIC_KEY = exports2.writeUserEpicIdPrefix = exports2.userConfigPath = exports2.updateUserConfig = void 0;
35406
- exports2.isStepOptional = exports2.isRunComplete = exports2.deriveRunProgress = exports2.PipelineRunError = exports2.retryAutoReview = exports2.submitAutoReviewVerdict = exports2.dirtyUpstreamOf = exports2.rerunApprovedStep = exports2.canRerunApprovedStep = exports2.chooseStepModel = exports2.chooseStepSkill = exports2.requestStepUpdate = exports2.rerunStep = exports2.rejectStep = exports2.approveStep = exports2.undoStepDone = exports2.canUndoStepDone = exports2.markStepDone = exports2.canStartStep = exports2.startRun = exports2.activateBackendFromWorkspace = exports2.activateRunStateBackend = exports2.resolveRunStateBackend = exports2.GitRunStateStore = exports2.RUN_ID_PATTERN = exports2.FileRunStateStore = exports2.RunStateStore = exports2.harnessCapabilities = exports2.NO_HARNESS_CAPABILITIES = exports2.RunnerValidationError = exports2.validateRunnerExport = exports2.CustomRunnerLoader = exports2.buildClaudeSpawnEnv = exports2.hasClaudeLogin = exports2.isInsideClaudeCodeSession = exports2.createJsonSink = exports2.createLineSink = exports2.isCodexMcpConfigured = exports2.codexConfigPath = exports2.readProjectMcpServer = exports2.mcpRegistrarFor = exports2.codexMcpRegistrar = exports2.claudeMcpRegistrar = exports2.copilotMcpConfig = exports2.copilotGraphServer = exports2.CopilotRunner = exports2.CodexRunner = exports2.AUTOPILOT_ENV = exports2.APPROVAL_GATE_SCRIPT = exports2.emptyCiChecksMessage = void 0;
35407
- exports2.isClaudeTierAlias = exports2.CLAUDE_TIER_ALIASES = exports2.FAST_MODEL = exports2.CODING_MODEL = exports2.PLANNING_MODEL = exports2.isBuiltinPreset = exports2.BUILTIN_PRESET_IDS = exports2.writeBuiltinAutoReviewValidators = exports2.resolvePrimaryStack = exports2.getSdlcArtifactTemplates = exports2.getBuiltinArtifactTemplates = exports2.phaseArtifactFileName = exports2.sdlcClaudeCommand = exports2.builtinClaudeCommand = exports2.loadAllBuiltinPresets = exports2.loadBuiltinPreset = exports2.planRecipeMigration = exports2.getBuiltinRecipeSummaries = exports2.getAllBuiltinPipelineSummaries = exports2.getSdlcBuiltinPipelineSummary = exports2.getBuiltinPipelineSummary = exports2.getBuiltinWorkflowByPipelineId = exports2.getBuiltinWorkflow = exports2.workflowSlug = exports2.builtinTemplatesRoot = exports2.pipelineCommandId = exports2.PHASES = exports2.BUILTIN_WORKFLOWS = exports2.withBackfilledStepNames = exports2.describeDrift = exports2.reconcileRunSteps = exports2.RUN_STATE_SCHEMA_VERSION = exports2.migrateRunState = exports2.stepIdentity = exports2.resolvePath = exports2.AutoReviewerError = exports2.runAutoReview = exports2.renderRunReport = exports2.verifyRun = exports2.runExecLoop = exports2.estimateCostUsd = exports2.providerAliases = exports2.ratesFromConfig = exports2.mergeRates = exports2.BUILTIN_RATES = exports2.unchangedProduces = exports2.snapshotProduces = exports2.checkBudget = exports2.weighStepProgress = exports2.isActiveStatus = void 0;
35408
- exports2.defaultClaudeConfigDir = exports2.getClaudeConfigDirOverride = exports2.setClaudeConfigDir = exports2.resolveDeclaredPath = exports2.expandHome = exports2.ProfileLoadError = exports2.UnknownStandardError = exports2.builtinProfiles = exports2.loadActiveProfile = exports2.loadProfile = exports2.listProfileManifests = exports2.resolveStandard = exports2.workspaceStandard = exports2.isBuiltinProfileId = exports2.ProfileSchema = exports2.TRACE_RULES = exports2.PROFILES_DIR = exports2.DEFAULT_PROFILE_ID = exports2.BUILTIN_PROFILE_IDS = exports2.setEpicMemoryHook = exports2.isEpicMemoryHookEnabled = exports2.installAnnotationTools = exports2.relativeEpicRoot = exports2.provisionDeclaredWorkflows = exports2.provisionWorkflowFiles = exports2.writeWorkflowArtifactTemplates = exports2.writeWorkflowCommands = exports2.provisionShortcutDocs = exports2.writeTwoLayerCommands = exports2.shortcutCommandDoc = exports2.backboneCommandDoc = exports2.unprovisionedPhases = exports2.nextEligiblePhase = exports2.resolveComposition = exports2.shortcutCommandId = exports2.getCanonicalPhase = exports2.isCanonicalPhase = exports2.BACKBONE_COMMAND_ID = exports2.CANONICAL_PHASE_IDS = exports2.CANONICAL_PHASES = exports2.renderTemplate = exports2.DEFAULT_GLOBAL_WORKFLOW_IDS = exports2.detectGlobalBuiltinSource = exports2.uninstallWorkflowGlobalsByIds = exports2.isWorkflowGloballyInstalled = exports2.installWorkflowGlobalsByIds = exports2.installGlobalDefaults = exports2.stepModelOptions = exports2.pickAgentModel = exports2.resolveProviderModel = void 0;
35409
- exports2.AIDLC_CORE_VERSION = exports2.AIDLC_CLI_GUIDE_TEXT = exports2.AIDLC_KNOWLEDGE = exports2.clearResolveCommandCache = exports2.resolveCommand = exports2.remapClaudePath = exports2.claudeConfigEnv = exports2.claudeJsonPath = exports2.isDefaultClaudeConfigDir = exports2.claudeConfigDir = exports2.resolveClaudeConfigDir = void 0;
35464
+ exports2.isRunComplete = exports2.deriveRunProgress = exports2.PipelineRunError = exports2.retryAutoReview = exports2.submitAutoReviewVerdict = exports2.dirtyUpstreamOf = exports2.rerunApprovedStep = exports2.canRerunApprovedStep = exports2.recordLaunchFeedback = exports2.chooseStepModel = exports2.chooseStepSkill = exports2.requestStepUpdate = exports2.rerunStep = exports2.rejectStep = exports2.approveStep = exports2.undoStepDone = exports2.canUndoStepDone = exports2.markStepDone = exports2.canStartStep = exports2.startRun = exports2.activateBackendFromWorkspace = exports2.activateRunStateBackend = exports2.resolveRunStateBackend = exports2.GitRunStateStore = exports2.RUN_ID_PATTERN = exports2.FileRunStateStore = exports2.RunStateStore = exports2.harnessCapabilities = exports2.NO_HARNESS_CAPABILITIES = exports2.RunnerValidationError = exports2.validateRunnerExport = exports2.CustomRunnerLoader = exports2.buildClaudeSpawnEnv = exports2.hasClaudeLogin = exports2.isInsideClaudeCodeSession = exports2.createJsonSink = exports2.createLineSink = exports2.isCodexMcpConfigured = exports2.codexConfigPath = exports2.readProjectMcpServer = exports2.mcpRegistrarFor = exports2.codexMcpRegistrar = exports2.claudeMcpRegistrar = exports2.copilotMcpConfig = exports2.copilotGraphServer = exports2.CopilotRunner = exports2.CodexRunner = exports2.AUTOPILOT_ENV = exports2.APPROVAL_GATE_SCRIPT = exports2.emptyCiChecksMessage = void 0;
35465
+ exports2.FAST_MODEL = exports2.CODING_MODEL = exports2.PLANNING_MODEL = exports2.isBuiltinPreset = exports2.BUILTIN_PRESET_IDS = exports2.writeBuiltinAutoReviewValidators = exports2.resolvePrimaryStack = exports2.getSdlcArtifactTemplates = exports2.getBuiltinArtifactTemplates = exports2.phaseArtifactFileName = exports2.sdlcClaudeCommand = exports2.builtinClaudeCommand = exports2.loadAllBuiltinPresets = exports2.loadBuiltinPreset = exports2.planRecipeMigration = exports2.getBuiltinRecipeSummaries = exports2.getAllBuiltinPipelineSummaries = exports2.getSdlcBuiltinPipelineSummary = exports2.getBuiltinPipelineSummary = exports2.getBuiltinWorkflowByPipelineId = exports2.getBuiltinWorkflow = exports2.workflowSlug = exports2.builtinTemplatesRoot = exports2.pipelineCommandId = exports2.PHASES = exports2.BUILTIN_WORKFLOWS = exports2.withBackfilledStepNames = exports2.describeDrift = exports2.reconcileRunSteps = exports2.RUN_STATE_SCHEMA_VERSION = exports2.migrateRunState = exports2.stepIdentity = exports2.resolvePath = exports2.AutoReviewerError = exports2.runAutoReview = exports2.renderRunReport = exports2.verifyRun = exports2.stepLabel = exports2.runExecLoop = exports2.estimateCostUsd = exports2.providerAliases = exports2.ratesFromConfig = exports2.mergeRates = exports2.BUILTIN_RATES = exports2.unchangedProduces = exports2.snapshotProduces = exports2.checkBudget = exports2.weighStepProgress = exports2.isActiveStatus = exports2.isStepOptional = void 0;
35466
+ exports2.setClaudeConfigDir = exports2.resolveDeclaredPath = exports2.expandHome = exports2.ProfileLoadError = exports2.UnknownStandardError = exports2.builtinProfiles = exports2.loadActiveProfile = exports2.loadProfile = exports2.listProfileManifests = exports2.resolveStandard = exports2.workspaceStandard = exports2.isBuiltinProfileId = exports2.ProfileSchema = exports2.TRACE_RULES = exports2.PROFILES_DIR = exports2.DEFAULT_PROFILE_ID = exports2.BUILTIN_PROFILE_IDS = exports2.setEpicMemoryHook = exports2.isEpicMemoryHookEnabled = exports2.installAnnotationTools = exports2.relativeEpicRoot = exports2.provisionDeclaredWorkflows = exports2.provisionWorkflowFiles = exports2.writeWorkflowArtifactTemplates = exports2.writeWorkflowCommands = exports2.provisionShortcutDocs = exports2.writeTwoLayerCommands = exports2.shortcutCommandDoc = exports2.backboneCommandDoc = exports2.unprovisionedPhases = exports2.nextEligiblePhase = exports2.resolveComposition = exports2.shortcutCommandId = exports2.getCanonicalPhase = exports2.isCanonicalPhase = exports2.BACKBONE_COMMAND_ID = exports2.CANONICAL_PHASE_IDS = exports2.CANONICAL_PHASES = exports2.renderTemplate = exports2.DEFAULT_GLOBAL_WORKFLOW_IDS = exports2.detectGlobalBuiltinSource = exports2.uninstallWorkflowGlobalsByIds = exports2.isWorkflowGloballyInstalled = exports2.installWorkflowGlobalsByIds = exports2.installGlobalDefaults = exports2.stepModelOptions = exports2.pickAgentModel = exports2.resolveProviderModel = exports2.isClaudeTierAlias = exports2.CLAUDE_TIER_ALIASES = void 0;
35467
+ exports2.AIDLC_CORE_VERSION = exports2.AIDLC_CLI_GUIDE_TEXT = exports2.AIDLC_KNOWLEDGE = exports2.clearResolveCommandCache = exports2.resolveCommand = exports2.remapClaudePath = exports2.claudeConfigEnv = exports2.claudeJsonPath = exports2.isDefaultClaudeConfigDir = exports2.claudeConfigDir = exports2.resolveClaudeConfigDir = exports2.defaultClaudeConfigDir = exports2.getClaudeConfigDirOverride = void 0;
35410
35468
  var WorkspaceSchema_1 = require_WorkspaceSchema();
35411
35469
  Object.defineProperty(exports2, "WorkspaceSchema", { enumerable: true, get: function() {
35412
35470
  return WorkspaceSchema_1.WorkspaceSchema;
@@ -36179,6 +36237,9 @@ var require_dist = __commonJS({
36179
36237
  Object.defineProperty(exports2, "chooseStepModel", { enumerable: true, get: function() {
36180
36238
  return PipelineRunner_1.chooseStepModel;
36181
36239
  } });
36240
+ Object.defineProperty(exports2, "recordLaunchFeedback", { enumerable: true, get: function() {
36241
+ return PipelineRunner_1.recordLaunchFeedback;
36242
+ } });
36182
36243
  Object.defineProperty(exports2, "canRerunApprovedStep", { enumerable: true, get: function() {
36183
36244
  return PipelineRunner_1.canRerunApprovedStep;
36184
36245
  } });
@@ -36244,6 +36305,9 @@ var require_dist = __commonJS({
36244
36305
  Object.defineProperty(exports2, "runExecLoop", { enumerable: true, get: function() {
36245
36306
  return execEngine_1.runExecLoop;
36246
36307
  } });
36308
+ Object.defineProperty(exports2, "stepLabel", { enumerable: true, get: function() {
36309
+ return execEngine_1.stepLabel;
36310
+ } });
36247
36311
  var verifyRun_1 = require_verifyRun();
36248
36312
  Object.defineProperty(exports2, "verifyRun", { enumerable: true, get: function() {
36249
36313
  return verifyRun_1.verifyRun;
@@ -45228,7 +45292,7 @@ var require_package = __commonJS({
45228
45292
  "package.json"(exports2, module2) {
45229
45293
  module2.exports = {
45230
45294
  name: "@delete101020/aidlc",
45231
- version: "4.0.41",
45295
+ version: "4.0.44",
45232
45296
  description: "AIDLC Native CLI, a fork of AIDLC \u2014 drive Claude through the six-stage AI-Native SDLC Playbook: Plan \u2192 Design \u2192 Build \u2192 Test \u2192 Deploy \u2192 Maintain, with artifact gates, requirements traceability, an incident loop back to Plan, and Spec Kit support.",
45233
45297
  license: "MIT",
45234
45298
  repository: {
@@ -49034,7 +49098,7 @@ ${import_chalk5.default.bold(state.runId)} ${runColor(state.status)}`);
49034
49098
  const isCurrent = i === state.currentStepIdx && state.status === "running";
49035
49099
  const marker = isCurrent ? import_chalk5.default.yellow("\u25B6") : " ";
49036
49100
  const idxLabel = import_chalk5.default.dim(`${i}.`);
49037
- const agent = isCurrent ? import_chalk5.default.bold(step.agent) : import_chalk5.default.dim(step.agent);
49101
+ const agent = isCurrent ? import_chalk5.default.bold((0, import_core7.stepLabel)(step)) : import_chalk5.default.dim((0, import_core7.stepLabel)(step));
49038
49102
  const status = colorStatus(step.status);
49039
49103
  const rev = step.revision > 1 ? import_chalk5.default.dim(` rev${step.revision}`) : "";
49040
49104
  const feedback = step.feedback ? import_chalk5.default.dim(` [feedback: ${step.feedback.slice(0, 40)}]`) : "";
@@ -50057,7 +50121,7 @@ function registerRun(program3) {
50057
50121
  printRunSummary(state);
50058
50122
  const first = state.steps[0];
50059
50123
  if (first) {
50060
- console.log(import_chalk10.default.dim(` Current step: ${import_chalk10.default.bold(first.agent)} \u2014 awaiting_work`));
50124
+ console.log(import_chalk10.default.dim(` Current step: ${import_chalk10.default.bold((0, import_core13.stepLabel)(first))} \u2014 awaiting_work`));
50061
50125
  console.log(import_chalk10.default.dim(` When done: aidlc run mark-done ${runId}`));
50062
50126
  }
50063
50127
  });
@@ -50094,13 +50158,13 @@ function registerRun(program3) {
50094
50158
  return;
50095
50159
  }
50096
50160
  if (step.status === prevStatus) {
50097
- console.log(import_chalk10.default.dim(`\u2022 Step "${step.agent}" is already ${step.status} \u2014 nothing to do.`));
50161
+ console.log(import_chalk10.default.dim(`\u2022 Step "${(0, import_core13.stepLabel)(step)}" is already ${step.status} \u2014 nothing to do.`));
50098
50162
  } else if (step.status === "awaiting_review") {
50099
- console.log(import_chalk10.default.cyan("\u2714") + ` Step "${step.agent}" is now ${import_chalk10.default.cyan("awaiting_review")}`);
50163
+ console.log(import_chalk10.default.cyan("\u2714") + ` Step "${(0, import_core13.stepLabel)(step)}" is now ${import_chalk10.default.cyan("awaiting_review")}`);
50100
50164
  console.log(import_chalk10.default.dim(` Approve: aidlc run approve ${runId}`));
50101
50165
  console.log(import_chalk10.default.dim(` Reject: aidlc run reject ${runId} --reason "..."`));
50102
50166
  } else {
50103
- console.log(import_chalk10.default.green("\u2714") + ` Step "${step.agent}" approved, advancing\u2026`);
50167
+ console.log(import_chalk10.default.green("\u2714") + ` Step "${(0, import_core13.stepLabel)(step)}" approved, advancing\u2026`);
50104
50168
  printRunSummary(next);
50105
50169
  }
50106
50170
  });
@@ -50120,7 +50184,7 @@ function registerRun(program3) {
50120
50184
  }
50121
50185
  saveRunState(root, next, state);
50122
50186
  const approvedStep = state.steps[state.currentStepIdx];
50123
- console.log(import_chalk10.default.green("\u2714") + ` Approved "${approvedStep.agent}"`);
50187
+ console.log(import_chalk10.default.green("\u2714") + ` Approved "${(0, import_core13.stepLabel)(approvedStep)}"`);
50124
50188
  printRunSummary(next);
50125
50189
  if (next.status === "completed") {
50126
50190
  console.log(import_chalk10.default.green("\u{1F389} Run completed \u2014 all steps approved."));
@@ -50138,7 +50202,7 @@ function registerRun(program3) {
50138
50202
  targetIdx = requireStepIdx(state, opts.to);
50139
50203
  if (targetIdx >= idx) {
50140
50204
  console.error(import_chalk10.default.red(
50141
- `--to must name a step before the rejected one (${idx}:${state.steps[idx].agent}), got ${targetIdx}:${state.steps[targetIdx].agent}.`
50205
+ `--to must name a step before the rejected one (${idx}:${(0, import_core13.stepLabel)(state.steps[idx])}), got ${targetIdx}:${(0, import_core13.stepLabel)(state.steps[targetIdx])}.`
50142
50206
  ));
50143
50207
  process.exit(1);
50144
50208
  }
@@ -50154,13 +50218,13 @@ function registerRun(program3) {
50154
50218
  const step = state.steps[idx];
50155
50219
  if (targetIdx !== void 0) {
50156
50220
  const target = next.steps[targetIdx];
50157
- console.log(import_chalk10.default.red("\u2718") + ` Rejected "${step.agent}" \u2014 sent back to "${target.agent}" (rev ${target.revision})`);
50221
+ console.log(import_chalk10.default.red("\u2718") + ` Rejected "${(0, import_core13.stepLabel)(step)}" \u2014 sent back to "${(0, import_core13.stepLabel)(target)}" (rev ${target.revision})`);
50158
50222
  console.log(import_chalk10.default.dim(` Reason: ${opts.reason}`));
50159
50223
  console.log(import_chalk10.default.dim(` When done: aidlc run mark-done ${runId}`));
50160
50224
  printRunSummary(next);
50161
50225
  return;
50162
50226
  }
50163
- console.log(import_chalk10.default.red("\u2718") + ` Rejected "${step.agent}"`);
50227
+ console.log(import_chalk10.default.red("\u2718") + ` Rejected "${(0, import_core13.stepLabel)(step)}"`);
50164
50228
  console.log(import_chalk10.default.dim(` Reason: ${opts.reason}`));
50165
50229
  console.log(import_chalk10.default.dim(` Rerun: aidlc run rerun ${runId} [--feedback "..."]`));
50166
50230
  });
@@ -50181,7 +50245,7 @@ function registerRun(program3) {
50181
50245
  }
50182
50246
  saveRunState(root, next, state);
50183
50247
  const step = next.steps[stepIdx ?? next.currentStepIdx];
50184
- console.log(import_chalk10.default.yellow("\u21BA") + ` Rerunning "${step.agent}" (rev ${step.revision})`);
50248
+ console.log(import_chalk10.default.yellow("\u21BA") + ` Rerunning "${(0, import_core13.stepLabel)(step)}" (rev ${step.revision})`);
50185
50249
  if (opts.feedback) {
50186
50250
  console.log(import_chalk10.default.dim(` Feedback: ${opts.feedback}`));
50187
50251
  }
@@ -50204,7 +50268,7 @@ function registerRun(program3) {
50204
50268
  }
50205
50269
  saveRunState(root, next, state);
50206
50270
  const target = next.steps[stepIdx];
50207
- console.log(import_chalk10.default.yellow("\u21BB") + ` Reopened "${target.agent}" for update (rev ${target.revision})`);
50271
+ console.log(import_chalk10.default.yellow("\u21BB") + ` Reopened "${(0, import_core13.stepLabel)(target)}" for update (rev ${target.revision})`);
50208
50272
  if (opts.feedback) {
50209
50273
  console.log(import_chalk10.default.dim(` Feedback: ${opts.feedback}`));
50210
50274
  }
@@ -50227,7 +50291,7 @@ function registerRun(program3) {
50227
50291
  }
50228
50292
  saveRunState(root, next, state);
50229
50293
  const target = next.steps[stepIdx];
50230
- console.log(import_chalk10.default.yellow("\u21BA") + ` Rerunning "${target.agent}" (rev ${target.revision})`);
50294
+ console.log(import_chalk10.default.yellow("\u21BA") + ` Rerunning "${(0, import_core13.stepLabel)(target)}" (rev ${target.revision})`);
50231
50295
  if (opts.feedback) {
50232
50296
  console.log(import_chalk10.default.dim(` Feedback: ${opts.feedback}`));
50233
50297
  }
@@ -50235,7 +50299,7 @@ function registerRun(program3) {
50235
50299
  if (marked.length > 0) {
50236
50300
  console.log(import_chalk10.default.yellow(` \u26A0 ${marked.length} approved step(s) downstream kept and marked dirty:`));
50237
50301
  for (const m of marked) {
50238
- console.log(import_chalk10.default.dim(` ${m.stepIdx}. ${m.name ?? m.agent}`));
50302
+ console.log(import_chalk10.default.dim(` ${m.stepIdx}. ${(0, import_core13.stepLabel)(m)}`));
50239
50303
  }
50240
50304
  console.log(import_chalk10.default.dim(" They still count as done. Redo each one to clear its mark."));
50241
50305
  }
@@ -50295,7 +50359,7 @@ function registerRun(program3) {
50295
50359
  console.error(import_chalk10.default.red("\u2718") + ` Drift detected in ${report.drift.length} of ${report.checked} step(s):`);
50296
50360
  for (const d of report.drift) {
50297
50361
  console.error(import_chalk10.default.yellow(`
50298
- Step ${d.stepIdx} (${d.agent}) \u2014 ${d.status}`));
50362
+ Step ${d.stepIdx} (${(0, import_core13.stepLabel)(state.steps[d.stepIdx] ?? d)}) \u2014 ${d.status}`));
50299
50363
  for (const m of d.missing) {
50300
50364
  console.error(import_chalk10.default.dim(` \u2718 missing file: ${m}`));
50301
50365
  }
@@ -50341,7 +50405,7 @@ function execExitCode(outcome, requireComplete) {
50341
50405
  if (requireComplete) {
50342
50406
  return 1;
50343
50407
  }
50344
- if (outcome.kind === "until") {
50408
+ if (outcome.kind === "until" || outcome.kind === "attended") {
50345
50409
  return 0;
50346
50410
  }
50347
50411
  return 2;
@@ -50406,7 +50470,7 @@ async function driveAutoReview(root, runId, state) {
50406
50470
  const pipeline = requirePipelineForRun(root, state);
50407
50471
  const step = state.steps[state.currentStepIdx];
50408
50472
  console.log(import_chalk10.default.bold(`
50409
- \u{1F50D} Auto-review: "${step.agent}"`));
50473
+ \u{1F50D} Auto-review: "${(0, import_core13.stepLabel)(step)}"`));
50410
50474
  let verdict;
50411
50475
  try {
50412
50476
  verdict = await (0, import_core13.runAutoReview)({ workspaceRoot: root, state, pipeline });
@@ -50432,7 +50496,7 @@ async function driveAutoReview(root, runId, state) {
50432
50496
  console.log(import_chalk10.default.green("\u2714") + " Auto-review passed" + import_chalk10.default.dim(` \u2014 ${verdict.reason}`));
50433
50497
  const after = next.steps[state.currentStepIdx];
50434
50498
  if (after.status === "awaiting_review") {
50435
- console.log(import_chalk10.default.cyan("\u2714") + ` Step "${after.agent}" is now ${import_chalk10.default.cyan("awaiting_review")}`);
50499
+ console.log(import_chalk10.default.cyan("\u2714") + ` Step "${(0, import_core13.stepLabel)(after)}" is now ${import_chalk10.default.cyan("awaiting_review")}`);
50436
50500
  console.log(import_chalk10.default.dim(` Approve: aidlc run approve ${runId}`));
50437
50501
  console.log(import_chalk10.default.dim(` Reject: aidlc run reject ${runId} --reason "..."`));
50438
50502
  }
@@ -50448,7 +50512,7 @@ function cliExecHooks(runId, claudeOut) {
50448
50512
  ${reason}`)),
50449
50513
  onStepStart: (e) => {
50450
50514
  info(import_chalk10.default.bold(`
50451
- \u25B6 Step ${e.stepIdx}: ${e.agent}`) + import_chalk10.default.dim(` (rev ${e.revision})`));
50515
+ \u25B6 Step ${e.stepIdx}: ${e.label}`) + import_chalk10.default.dim(` (rev ${e.revision})`));
50452
50516
  info(import_chalk10.default.dim(` skills: ${e.skills.join(", ")} model: ${e.model ?? import_core13.CODING_MODEL}`));
50453
50517
  if (e.context) {
50454
50518
  info(import_chalk10.default.dim(` context: ${e.context}`));
@@ -50464,13 +50528,13 @@ ${reason}`)),
50464
50528
  sep4();
50465
50529
  if (e.status === "awaiting_auto_review") {
50466
50530
  info(import_chalk10.default.cyan(`
50467
- \u2714 Step "${e.agent}" done \u2014 auto-review pending.`));
50531
+ \u2714 Step "${e.label}" done \u2014 auto-review pending.`));
50468
50532
  } else if (e.status === "awaiting_review") {
50469
50533
  info(import_chalk10.default.cyan(`
50470
- \u2714 Step "${e.agent}" done \u2014 awaiting review.`));
50534
+ \u2714 Step "${e.label}" done \u2014 awaiting review.`));
50471
50535
  } else {
50472
50536
  info(import_chalk10.default.green(`
50473
- \u2714 Step "${e.agent}" approved.`));
50537
+ \u2714 Step "${e.label}" approved.`));
50474
50538
  }
50475
50539
  if (typeof e.costUsd === "number") {
50476
50540
  info(import_chalk10.default.dim(` cost: $${e.costUsd.toFixed(4)}`));
@@ -50485,24 +50549,24 @@ ${reason}`)),
50485
50549
  console.error(import_chalk10.default.dim("\n Produce the files above, then: aidlc run mark-done " + runId));
50486
50550
  } else {
50487
50551
  console.error(import_chalk10.default.red(`
50488
- \u2718 ${e.message ?? `Step "${e.agent}" failed.`}`));
50552
+ \u2718 ${e.message ?? `Step "${e.label}" failed.`}`));
50489
50553
  console.error(import_chalk10.default.dim(" Fix the issue then retry: aidlc run exec " + runId));
50490
50554
  }
50491
50555
  },
50492
50556
  onAwaitingReview: (e) => {
50493
50557
  info(import_chalk10.default.cyan(`
50494
- \u23F8 Step "${e.agent}" is awaiting human review.`));
50558
+ \u23F8 Step "${e.label}" is awaiting human review.`));
50495
50559
  info(import_chalk10.default.dim(` Approve: aidlc run approve ${e.runId}`));
50496
50560
  info(import_chalk10.default.dim(` Reject: aidlc run reject ${e.runId} --reason "..."`));
50497
50561
  },
50498
50562
  onRejected: (e) => {
50499
50563
  info(import_chalk10.default.red(`
50500
- \u2718 Step "${e.agent}" was rejected.`));
50564
+ \u2718 Step "${e.label}" was rejected.`));
50501
50565
  info(import_chalk10.default.dim(` Rerun: aidlc run rerun ${e.runId} [--feedback "..."]`));
50502
50566
  },
50503
50567
  onStepStopped: (e) => {
50504
50568
  info(import_chalk10.default.yellow(`
50505
- \u23F9 Stopped "${e.agent}" mid-step (rev ${e.revision}). It is still awaiting work.`));
50569
+ \u23F9 Stopped "${e.label}" mid-step (rev ${e.revision}). It is still awaiting work.`));
50506
50570
  info(import_chalk10.default.dim(" Anything it half-wrote is still in the working tree \u2014 check git status."));
50507
50571
  info(import_chalk10.default.dim(` Resume: aidlc run exec ${e.runId}`));
50508
50572
  },
@@ -50516,14 +50580,14 @@ ${reason}`)),
50516
50580
  onBatchDone: (e) => {
50517
50581
  sep4();
50518
50582
  info(import_chalk10.default.cyan(`
50519
- \u21BB Batch ${e.batch} of "${e.agent}" done \u2014 starting the next in a fresh session.`));
50583
+ \u21BB Batch ${e.batch} of "${e.label}" done \u2014 starting the next in a fresh session.`));
50520
50584
  if (typeof e.costUsd === "number") {
50521
50585
  info(import_chalk10.default.dim(` cost: $${e.costUsd.toFixed(4)}`));
50522
50586
  }
50523
50587
  },
50524
50588
  onBatchPause: (e) => {
50525
50589
  info(import_chalk10.default.cyan(`
50526
- \u23F8 Batch ${e.batch} of "${e.agent}" done; pausing (pause_between_batches).`));
50590
+ \u23F8 Batch ${e.batch} of "${e.label}" done; pausing (pause_between_batches).`));
50527
50591
  if (e.report) {
50528
50592
  info(import_chalk10.default.dim(` Progress: ${e.report}`));
50529
50593
  }
@@ -50531,23 +50595,23 @@ ${reason}`)),
50531
50595
  },
50532
50596
  onStepSkipped: (e) => {
50533
50597
  info(import_chalk10.default.yellow(`
50534
- \u2933 Step "${e.agent}" was rejected \u2014 carrying on.`) + import_chalk10.default.dim(` ${e.reason}`));
50598
+ \u2933 Step "${e.label}" was rejected \u2014 carrying on.`) + import_chalk10.default.dim(` ${e.reason}`));
50535
50599
  info(import_chalk10.default.dim(` Want it back? aidlc run rerun ${e.runId} --step ${e.stepIdx}`));
50536
50600
  },
50537
50601
  onAutoReviewStart: (e) => info(import_chalk10.default.bold(`
50538
- \u{1F50D} Auto-review: "${e.agent}"`)),
50602
+ \u{1F50D} Auto-review: "${e.label}"`)),
50539
50603
  onAutoReviewResult: (e) => {
50540
50604
  if (e.decision === "pass") {
50541
50605
  info(import_chalk10.default.green("\u2714 Auto-review passed") + import_chalk10.default.dim(` \u2014 ${e.reason}`));
50542
50606
  } else if (e.sentBackTo) {
50543
50607
  const to = e.sentBackTo;
50544
- info(import_chalk10.default.yellow(`\u21A9 Auto-review rejected \u2014 sent back to "${to.agent}" (rev ${to.revision}, send-back ${to.count} of ${to.max})`) + import_chalk10.default.dim(` \u2014 ${e.reason}`));
50608
+ info(import_chalk10.default.yellow(`\u21A9 Auto-review rejected \u2014 sent back to "${to.label}" (rev ${to.revision}, send-back ${to.count} of ${to.max})`) + import_chalk10.default.dim(` \u2014 ${e.reason}`));
50545
50609
  } else {
50546
50610
  info(import_chalk10.default.red("\u2718 Auto-review rejected") + import_chalk10.default.dim(` \u2014 ${e.reason}`));
50547
50611
  info(import_chalk10.default.dim(` Fix the issue, then: aidlc run rerun ${e.runId} [--feedback "..."]`));
50548
50612
  }
50549
50613
  },
50550
- onAutoApproved: (e) => info(import_chalk10.default.green(`\u2714 Auto-approved "${e.agent}" (--auto-approve)`)),
50614
+ onAutoApproved: (e) => info(import_chalk10.default.green(`\u2714 Auto-approved "${e.label}" (--auto-approve)`)),
50551
50615
  onBudget: (e) => {
50552
50616
  const caveats = [];
50553
50617
  if (e.estimated && e.estimated > 0) {
@@ -50571,6 +50635,8 @@ ${reason}`)),
50571
50635
  },
50572
50636
  onUntilStop: (e) => info(import_chalk10.default.dim(`
50573
50637
  Stopped at step ${e.untilIdx} as requested.`)),
50638
+ onAttendedStep: (e) => info(import_chalk10.default.dim(`
50639
+ Stopped before step ${e.stepIdx + 1} \xB7 ${e.label} \u2014 a person runs it.`)),
50574
50640
  onDryRunPreview: (e) => {
50575
50641
  const layers = [
50576
50642
  e.inlined.persona ? "persona" : null,
@@ -50833,12 +50899,12 @@ function render(root, runIdFilter) {
50833
50899
  for (const run of filtered) {
50834
50900
  const stepNum = `${run.currentStepIdx + 1}/${run.steps.length}`;
50835
50901
  const current = run.steps[run.currentStepIdx];
50836
- const stepLabel2 = current ? `${stepNum} ${current.agent} ${import_chalk12.default.dim(`(${current.status})`)}` : stepNum;
50902
+ const stepLabel3 = current ? `${stepNum} ${current.agent} ${import_chalk12.default.dim(`(${current.status})`)}` : stepNum;
50837
50903
  table.push([
50838
50904
  import_chalk12.default.bold(run.runId),
50839
50905
  import_chalk12.default.dim(run.pipelineId),
50840
50906
  colorRunStatus(run.status),
50841
- stepLabel2,
50907
+ stepLabel3,
50842
50908
  import_chalk12.default.dim(humanizeTime(run.updatedAt))
50843
50909
  ]);
50844
50910
  }
@@ -51967,12 +52033,12 @@ function registerEpic(program3) {
51967
52033
  const total = epic.stepDetails.length;
51968
52034
  const done = epic.stepDetails.filter((s) => s.status === "done").length;
51969
52035
  const pct = epicProgress(epic).percent;
51970
- const stepLabel2 = total ? `${done}/${total} (${pct}%)` : "\u2014";
52036
+ const stepLabel3 = total ? `${done}/${total} (${pct}%)` : "\u2014";
51971
52037
  table.push([
51972
52038
  import_chalk15.default.bold(epic.id),
51973
52039
  truncate(epic.title || import_chalk15.default.dim("(untitled)"), 40),
51974
52040
  epic.tags.length > 0 ? import_chalk15.default.cyan(truncate(epic.tags.join(" "), 28)) : import_chalk15.default.dim("\u2014"),
51975
- stepLabel2,
52041
+ stepLabel3,
51976
52042
  colorEpicStatus(epic.status),
51977
52043
  import_chalk15.default.dim(epic.pipeline ?? "\u2014")
51978
52044
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delete101020/aidlc",
3
- "version": "4.0.41",
3
+ "version": "4.0.44",
4
4
  "description": "AIDLC Native CLI, a fork of AIDLC — drive Claude through the six-stage AI-Native SDLC Playbook: Plan → Design → Build → Test → Deploy → Maintain, with artifact gates, requirements traceability, an incident loop back to Plan, and Spec Kit support.",
5
5
  "license": "MIT",
6
6
  "repository": {