@delete101020/aidlc 4.0.46 → 4.0.47

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 (3) hide show
  1. package/README.md +9 -0
  2. package/dist/bundle.js +187 -105
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -469,6 +469,15 @@ and approval — a `pass` advances the step, a `reject` stops with a rerun hint.
469
469
  With `--auto-approve` it also clears `human_review` gates without pausing — a
470
470
  single command then drives the entire pipeline end-to-end.
471
471
 
472
+ An `autopilot: true` pipeline refuses to start on uncommitted changes, with
473
+ one exception: when a step stopped short (a non-zero exit such as the account
474
+ running out of usage, its `timeout_minutes`, a "stop now"), the run records
475
+ what it left in the working tree, and `run exec` carries on from exactly that
476
+ tree — switch accounts and run it again. The next attempt is told to finish
477
+ the half-written changes rather than start over. If the tree has changed
478
+ since, or the agent was killed before anything could be recorded, pass
479
+ `--allow-dirty` to start anyway.
480
+
472
481
  **`run request-update`** reopens an already-approved step (bumps its revision,
473
482
  resets downstream steps), mirroring the extension's "Request update" action.
474
483
 
package/dist/bundle.js CHANGED
@@ -31195,6 +31195,120 @@ var require_commandBodyFreshness = __commonJS({
31195
31195
  }
31196
31196
  });
31197
31197
 
31198
+ // ../core/dist/runs/codeFingerprint.js
31199
+ var require_codeFingerprint = __commonJS({
31200
+ "../core/dist/runs/codeFingerprint.js"(exports2) {
31201
+ "use strict";
31202
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) {
31203
+ if (k2 === void 0) k2 = k;
31204
+ var desc = Object.getOwnPropertyDescriptor(m, k);
31205
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
31206
+ desc = { enumerable: true, get: function() {
31207
+ return m[k];
31208
+ } };
31209
+ }
31210
+ Object.defineProperty(o, k2, desc);
31211
+ } : function(o, m, k, k2) {
31212
+ if (k2 === void 0) k2 = k;
31213
+ o[k2] = m[k];
31214
+ });
31215
+ var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) {
31216
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
31217
+ } : function(o, v) {
31218
+ o["default"] = v;
31219
+ });
31220
+ var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ function() {
31221
+ var ownKeys = function(o) {
31222
+ ownKeys = Object.getOwnPropertyNames || function(o2) {
31223
+ var ar = [];
31224
+ for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
31225
+ return ar;
31226
+ };
31227
+ return ownKeys(o);
31228
+ };
31229
+ return function(mod) {
31230
+ if (mod && mod.__esModule) return mod;
31231
+ var result = {};
31232
+ if (mod != null) {
31233
+ for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31234
+ }
31235
+ __setModuleDefault(result, mod);
31236
+ return result;
31237
+ };
31238
+ }();
31239
+ Object.defineProperty(exports2, "__esModule", { value: true });
31240
+ exports2.codeFingerprint = codeFingerprint;
31241
+ exports2.uncommittedPaths = uncommittedPaths;
31242
+ var child_process_1 = require("child_process");
31243
+ var fs14 = __importStar(require("fs"));
31244
+ var os3 = __importStar(require("os"));
31245
+ var path17 = __importStar(require("path"));
31246
+ function codeFingerprint(root, exclude) {
31247
+ const git = (args, env) => (0, child_process_1.execFileSync)("git", args, {
31248
+ cwd: root,
31249
+ encoding: "utf8",
31250
+ env: env ? { ...process.env, ...env } : process.env,
31251
+ stdio: ["ignore", "pipe", "ignore"],
31252
+ maxBuffer: 64 * 1024 * 1024
31253
+ }).trim();
31254
+ let realIndex;
31255
+ try {
31256
+ realIndex = path17.resolve(root, git(["rev-parse", "--git-path", "index"]));
31257
+ } catch {
31258
+ return null;
31259
+ }
31260
+ const dir = fs14.mkdtempSync(path17.join(os3.tmpdir(), "aidlc-fp-"));
31261
+ const index = path17.join(dir, "index");
31262
+ try {
31263
+ if (fs14.existsSync(realIndex)) {
31264
+ fs14.copyFileSync(realIndex, index);
31265
+ }
31266
+ const env = { GIT_INDEX_FILE: index };
31267
+ git(["add", "-A", "--", "."], env);
31268
+ const skip = exclude.filter((p) => p && !p.startsWith(".."));
31269
+ if (skip.length > 0) {
31270
+ git(["rm", "-r", "-q", "--cached", "--ignore-unmatch", "--", ...skip], env);
31271
+ }
31272
+ return git(["write-tree"], env);
31273
+ } catch {
31274
+ return null;
31275
+ } finally {
31276
+ fs14.rmSync(dir, { recursive: true, force: true });
31277
+ }
31278
+ }
31279
+ function uncommittedPaths(root, exclude) {
31280
+ let out2;
31281
+ try {
31282
+ out2 = (0, child_process_1.execFileSync)("git", ["status", "--porcelain=v1", "-z", "--untracked-files=all"], {
31283
+ cwd: root,
31284
+ encoding: "utf8",
31285
+ stdio: ["ignore", "pipe", "ignore"],
31286
+ maxBuffer: 64 * 1024 * 1024
31287
+ });
31288
+ } catch {
31289
+ return [];
31290
+ }
31291
+ const skip = exclude.map((p) => p.split(path17.sep).join("/")).filter((p) => p && !p.startsWith(".."));
31292
+ return statusPaths(out2).filter((p) => !skip.some((s) => p === s || p.startsWith(`${s}/`)));
31293
+ }
31294
+ function statusPaths(out2) {
31295
+ const parts = out2.split("\0");
31296
+ const paths = [];
31297
+ for (let i = 0; i < parts.length; i++) {
31298
+ const entry = parts[i];
31299
+ if (entry.length < 4) {
31300
+ continue;
31301
+ }
31302
+ paths.push(entry.slice(3));
31303
+ if (entry[0] === "R" || entry[0] === "C") {
31304
+ i++;
31305
+ }
31306
+ }
31307
+ return paths;
31308
+ }
31309
+ }
31310
+ });
31311
+
31198
31312
  // ../core/dist/runs/autopilotPreflight.js
31199
31313
  var require_autopilotPreflight = __commonJS({
31200
31314
  "../core/dist/runs/autopilotPreflight.js"(exports2) {
@@ -31247,6 +31361,7 @@ var require_autopilotPreflight = __commonJS({
31247
31361
  var os3 = __importStar(require("os"));
31248
31362
  var path17 = __importStar(require("path"));
31249
31363
  var claudeHome_1 = require_claudeHome();
31364
+ var codeFingerprint_1 = require_codeFingerprint();
31250
31365
  var EpicScaffold_1 = require_EpicScaffold();
31251
31366
  var WorkspaceSchema_1 = require_WorkspaceSchema();
31252
31367
  exports2.APPROVAL_GATE_SCRIPT = "aidlc-approval-gate";
@@ -31325,14 +31440,25 @@ var require_autopilotPreflight = __commonJS({
31325
31440
  } else if (protectedBranches.has(branch)) {
31326
31441
  problems.push(`You are on "${branch}". Autopilot does not commit to it \u2014 switch to a branch for this epic (git switch -c <branch>).`);
31327
31442
  }
31328
- const skip = [
31443
+ const exclude = [
31329
31444
  toPosix(path17.relative(root, path17.join((0, EpicScaffold_1.epicsRoot)(root, config), state.runId))),
31330
31445
  ".aidlc"
31331
31446
  ];
31332
- const dirty = dirtyPaths(git(["status", "--porcelain=v1", "-z", "--untracked-files=all"]) ?? "").filter((p) => !skip.some((s) => p === s || p.startsWith(`${s}/`)));
31447
+ const dirty = (0, codeFingerprint_1.uncommittedPaths)(root, exclude);
31333
31448
  if (dirty.length > 0) {
31334
- const shown = dirty.slice(0, 5).join(", ") + (dirty.length > 5 ? `, and ${dirty.length - 5} more` : "");
31335
- problems.push(`The working tree has uncommitted changes (${shown}). Commit or stash them first: the agent would build on them, and its own changes would be mixed in with them.`);
31449
+ const shown = listPaths(dirty);
31450
+ const left = state.steps.filter((s) => s.leftover);
31451
+ const tree = left.length > 0 ? (0, codeFingerprint_1.codeFingerprint)(root, exclude) : null;
31452
+ const own = tree ? left.find((s) => s.leftover.tree === tree) : void 0;
31453
+ if (own) {
31454
+ args.onNote?.(`Carrying on from what "${own.name ?? own.agent}" left uncommitted when it ${leftoverWhy(own)} (${shown}). Nothing else has changed since.`);
31455
+ } else if (args.allowDirty) {
31456
+ args.onNote?.(`--allow-dirty: starting on top of uncommitted changes (${shown}).`);
31457
+ } else {
31458
+ args.onDirty?.(dirty);
31459
+ const changed = left.length > 0 ? ` They are not what "${left.map((s) => s.name ?? s.agent).join('", "')}" left when it stopped \u2014 something has changed since.` : "";
31460
+ problems.push(`The working tree has uncommitted changes (${shown}). Commit or stash them first: the agent would build on them, and its own changes would be mixed in with them.${changed} If they are this run's own unfinished work, run again with --allow-dirty.`);
31461
+ }
31336
31462
  }
31337
31463
  }
31338
31464
  const claudeSteps = new Set(state.steps.filter((s) => s.status !== "approved").map((s) => config.agents.find((a) => a.id === s.agent)).filter((a) => a?.runner === "default").map((a) => a.id));
@@ -31368,20 +31494,18 @@ var require_autopilotPreflight = __commonJS({
31368
31494
  function emptyCiChecksMessage2(runner, step) {
31369
31495
  return `${runner} has no commands in CHECKS, so it passes whatever "${step}" builds. Add your lint, typecheck and test commands to it before leaving a run alone.`;
31370
31496
  }
31371
- function dirtyPaths(out2) {
31372
- const parts = out2.split("\0");
31373
- const paths = [];
31374
- for (let i = 0; i < parts.length; i++) {
31375
- const entry = parts[i];
31376
- if (entry.length < 4) {
31377
- continue;
31378
- }
31379
- paths.push(entry.slice(3));
31380
- if (entry[0] === "R" || entry[0] === "C") {
31381
- i++;
31382
- }
31497
+ function listPaths(paths) {
31498
+ return paths.slice(0, 5).join(", ") + (paths.length > 5 ? `, and ${paths.length - 5} more` : "");
31499
+ }
31500
+ function leftoverWhy(step) {
31501
+ switch (step.leftover.why) {
31502
+ case "timeout":
31503
+ return "ran past its timeout_minutes";
31504
+ case "stopped":
31505
+ return "was stopped";
31506
+ default:
31507
+ return "failed";
31383
31508
  }
31384
- return paths;
31385
31509
  }
31386
31510
  function matcherCoversBash(matcher) {
31387
31511
  if (!matcher || matcher === "*") {
@@ -32207,89 +32331,6 @@ var require_runLock = __commonJS({
32207
32331
  }
32208
32332
  });
32209
32333
 
32210
- // ../core/dist/runs/codeFingerprint.js
32211
- var require_codeFingerprint = __commonJS({
32212
- "../core/dist/runs/codeFingerprint.js"(exports2) {
32213
- "use strict";
32214
- var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) {
32215
- if (k2 === void 0) k2 = k;
32216
- var desc = Object.getOwnPropertyDescriptor(m, k);
32217
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
32218
- desc = { enumerable: true, get: function() {
32219
- return m[k];
32220
- } };
32221
- }
32222
- Object.defineProperty(o, k2, desc);
32223
- } : function(o, m, k, k2) {
32224
- if (k2 === void 0) k2 = k;
32225
- o[k2] = m[k];
32226
- });
32227
- var __setModuleDefault = exports2 && exports2.__setModuleDefault || (Object.create ? function(o, v) {
32228
- Object.defineProperty(o, "default", { enumerable: true, value: v });
32229
- } : function(o, v) {
32230
- o["default"] = v;
32231
- });
32232
- var __importStar = exports2 && exports2.__importStar || /* @__PURE__ */ function() {
32233
- var ownKeys = function(o) {
32234
- ownKeys = Object.getOwnPropertyNames || function(o2) {
32235
- var ar = [];
32236
- for (var k in o2) if (Object.prototype.hasOwnProperty.call(o2, k)) ar[ar.length] = k;
32237
- return ar;
32238
- };
32239
- return ownKeys(o);
32240
- };
32241
- return function(mod) {
32242
- if (mod && mod.__esModule) return mod;
32243
- var result = {};
32244
- if (mod != null) {
32245
- for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32246
- }
32247
- __setModuleDefault(result, mod);
32248
- return result;
32249
- };
32250
- }();
32251
- Object.defineProperty(exports2, "__esModule", { value: true });
32252
- exports2.codeFingerprint = codeFingerprint;
32253
- var child_process_1 = require("child_process");
32254
- var fs14 = __importStar(require("fs"));
32255
- var os3 = __importStar(require("os"));
32256
- var path17 = __importStar(require("path"));
32257
- function codeFingerprint(root, exclude) {
32258
- const git = (args, env) => (0, child_process_1.execFileSync)("git", args, {
32259
- cwd: root,
32260
- encoding: "utf8",
32261
- env: env ? { ...process.env, ...env } : process.env,
32262
- stdio: ["ignore", "pipe", "ignore"],
32263
- maxBuffer: 64 * 1024 * 1024
32264
- }).trim();
32265
- let realIndex;
32266
- try {
32267
- realIndex = path17.resolve(root, git(["rev-parse", "--git-path", "index"]));
32268
- } catch {
32269
- return null;
32270
- }
32271
- const dir = fs14.mkdtempSync(path17.join(os3.tmpdir(), "aidlc-fp-"));
32272
- const index = path17.join(dir, "index");
32273
- try {
32274
- if (fs14.existsSync(realIndex)) {
32275
- fs14.copyFileSync(realIndex, index);
32276
- }
32277
- const env = { GIT_INDEX_FILE: index };
32278
- git(["add", "-A", "--", "."], env);
32279
- const skip = exclude.filter((p) => p && !p.startsWith(".."));
32280
- if (skip.length > 0) {
32281
- git(["rm", "-r", "-q", "--cached", "--ignore-unmatch", "--", ...skip], env);
32282
- }
32283
- return git(["write-tree"], env);
32284
- } catch {
32285
- return null;
32286
- } finally {
32287
- fs14.rmSync(dir, { recursive: true, force: true });
32288
- }
32289
- }
32290
- }
32291
- });
32292
-
32293
32334
  // ../core/dist/runs/batchStatus.js
32294
32335
  var require_batchStatus = __commonJS({
32295
32336
  "../core/dist/runs/batchStatus.js"(exports2) {
@@ -32481,16 +32522,27 @@ var require_execEngine = __commonJS({
32481
32522
  const batchesRun = /* @__PURE__ */ new Map();
32482
32523
  if (initialPipeline.autopilot && !opts.dryRun) {
32483
32524
  let problems;
32525
+ let dirty;
32484
32526
  try {
32485
32527
  const ws = WorkspaceLoader_1.WorkspaceLoader.load(root);
32486
- problems = (0, autopilotPreflight_1.autopilotPreflight)({ root, state: initialState, pipeline: initialPipeline, config: ws.config });
32528
+ problems = (0, autopilotPreflight_1.autopilotPreflight)({
32529
+ root,
32530
+ state: initialState,
32531
+ pipeline: initialPipeline,
32532
+ config: ws.config,
32533
+ allowDirty: opts.allowDirty,
32534
+ onNote: (m) => hooks.onPreflightNote?.(m),
32535
+ onDirty: (paths) => {
32536
+ dirty = paths;
32537
+ }
32538
+ });
32487
32539
  } catch (err) {
32488
32540
  problems = [`Could not check the workspace: ${errMsg(err)}`];
32489
32541
  }
32490
32542
  if (problems.length > 0) {
32491
32543
  hooks.onRunFailed?.(`Pipeline "${initialPipeline.id}" is an autopilot pipeline, and it is not safe to leave this run alone yet:
32492
32544
  ` + problems.map((p) => ` - ${p}`).join("\n"));
32493
- return { kind: "error" };
32545
+ return dirty && problems.length === 1 ? { kind: "error", dirty } : { kind: "error" };
32494
32546
  }
32495
32547
  }
32496
32548
  while (true) {
@@ -32769,7 +32821,8 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32769
32821
  }
32770
32822
  const batchNo = report ? batchesOf(stepRec).length + 1 : 0;
32771
32823
  const batchNote = report ? batchInstructions(report, batchNo, stepRec.revision) : null;
32772
- const userMessage = [baseMessage, feedback, batchNote].filter(Boolean).join("\n\n");
32824
+ const leftoverNote = leftoverInstructions(stepRec);
32825
+ const userMessage = [baseMessage, feedback, leftoverNote, batchNote].filter(Boolean).join("\n\n");
32773
32826
  if (opts.dryRun) {
32774
32827
  hooks.onDryRunPreview?.({
32775
32828
  skills: skillIds.join(", "),
@@ -32831,6 +32884,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32831
32884
  }
32832
32885
  if (stop.signal.aborted) {
32833
32886
  recordInterrupted(root, runId, stepIdx, timedOut ? { why: "timeout", minutes } : { why: "stopped" });
32887
+ recordLeftover(root, runId, stepIdx, timedOut ? "timeout" : "stopped", codeExclude);
32834
32888
  if (timedOut) {
32835
32889
  hooks.onStepFailed?.({
32836
32890
  stepIdx,
@@ -32844,6 +32898,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32844
32898
  return "stopped";
32845
32899
  }
32846
32900
  if (!result || !result.success) {
32901
+ recordLeftover(root, runId, stepIdx, "failed", codeExclude);
32847
32902
  hooks.onStepFailed?.({ stepIdx, agent: agentId, label: stepLabel3(stepRec), message: `Step "${agentId}" failed (non-zero exit).` });
32848
32903
  return "failed";
32849
32904
  }
@@ -32899,6 +32954,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32899
32954
  return "failed";
32900
32955
  }
32901
32956
  recordProvenance(rec, { agent, resolvedModel, agentModel, skillIds, alternatives, modelOpts });
32957
+ delete rec.leftover;
32902
32958
  const cost = addBatchCost(rec, batchNo, result, batchCost(result, ws, agent.runner, resolvedModel ?? agentModel));
32903
32959
  rec.history = [...rec.history ?? [], {
32904
32960
  kind: "batch",
@@ -32927,6 +32983,7 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
32927
32983
  freshState = RunStateStore_1.RunStateStore.load(root, runId);
32928
32984
  const rec = freshState.steps[stepIdx];
32929
32985
  recordProvenance(rec, { agent, resolvedModel, agentModel, skillIds, alternatives, modelOpts });
32986
+ delete rec.leftover;
32930
32987
  addBatchCost(rec, batchNo, result, batchCost(result, ws, agent.runner, resolvedModel ?? agentModel));
32931
32988
  next = (0, PipelineRunner_1.markStepDone)({ state: freshState, pipeline, workspaceRoot: root });
32932
32989
  } catch (err) {
@@ -33055,6 +33112,29 @@ About these inputs: ${(0, inheritedContext_1.inheritedContextNote)(epicRoot)}` :
33055
33112
  }];
33056
33113
  RunStateStore_1.RunStateStore.save(root, fresh);
33057
33114
  }
33115
+ function recordLeftover(root, runId, stepIdx, why, exclude) {
33116
+ const fresh = RunStateStore_1.RunStateStore.load(root, runId);
33117
+ const rec = fresh?.steps[stepIdx];
33118
+ if (!fresh || !rec) {
33119
+ return;
33120
+ }
33121
+ const paths = (0, codeFingerprint_1.uncommittedPaths)(root, exclude);
33122
+ const tree = paths.length > 0 ? (0, codeFingerprint_1.codeFingerprint)(root, exclude) : null;
33123
+ if (tree) {
33124
+ rec.leftover = { at: (/* @__PURE__ */ new Date()).toISOString(), revision: rec.revision, why, tree, paths };
33125
+ } else {
33126
+ delete rec.leftover;
33127
+ }
33128
+ RunStateStore_1.RunStateStore.save(root, fresh);
33129
+ }
33130
+ function leftoverInstructions(rec) {
33131
+ const l = rec.leftover;
33132
+ if (!l || l.revision !== rec.revision) {
33133
+ return null;
33134
+ }
33135
+ const shown = l.paths.slice(0, 20).join(", ") + (l.paths.length > 20 ? `, and ${l.paths.length - 20} more` : "");
33136
+ return `A previous attempt at this revision stopped before it finished. Its unfinished changes are still in the working tree, uncommitted: ${shown}. Read them first and carry on from there \u2014 keep what is right, finish what is missing \u2014 rather than starting over.`;
33137
+ }
33058
33138
  async function runAutoReviewStep(root, runId, hooks) {
33059
33139
  const state = RunStateStore_1.RunStateStore.load(root, runId);
33060
33140
  if (!state) {
@@ -45359,7 +45439,7 @@ var require_package = __commonJS({
45359
45439
  "package.json"(exports2, module2) {
45360
45440
  module2.exports = {
45361
45441
  name: "@delete101020/aidlc",
45362
- version: "4.0.46",
45442
+ version: "4.0.47",
45363
45443
  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.",
45364
45444
  license: "MIT",
45365
45445
  repository: {
@@ -50394,7 +50474,7 @@ function registerRun(program3) {
50394
50474
  });
50395
50475
  cmd.command("exec <runId>").description(
50396
50476
  "Execute the current step by spawning the claude CLI, then auto-advance.\n Streams output live. Stops at human_review steps unless --auto-approve.\n Exit codes: 0 completed (or stopped at --until), 2 paused on a gate\n (awaiting review / rejected / sent back max_send_backs times / no code\n change after a send-back or a batch / max_batches / pause_between_batches /\n budget / stopped), 1 error (a step that ran\n past its timeout_minutes included). --require-complete maps any\n non-completed outcome to 1 for CI gating.\n Ctrl+C once: stop after the running step. Twice: stop it now."
50397
- ).option("--until <step>", "Stop after this step completes (index or agent id)").option("--auto-approve", "Also auto-approve human_review steps without pausing").option("--require-complete", "Exit 1 unless the run reaches completed (for CI gating)").option("--json", "Suppress decorative output; print a final JSON summary to stdout (claude stream goes to stderr)").option("--message <text>", "Override the user message sent to claude (default: context pairs)").option("--dry-run", "Print the assembled prompt without spawning claude").option("--skill <id>", "On steps that offer alternative skills (default_skill), run this one").action(async (runId, opts, actionCmd) => {
50477
+ ).option("--until <step>", "Stop after this step completes (index or agent id)").option("--auto-approve", "Also auto-approve human_review steps without pausing").option("--require-complete", "Exit 1 unless the run reaches completed (for CI gating)").option("--json", "Suppress decorative output; print a final JSON summary to stdout (claude stream goes to stderr)").option("--message <text>", "Override the user message sent to claude (default: context pairs)").option("--dry-run", "Print the assembled prompt without spawning claude").option("--skill <id>", "On steps that offer alternative skills (default_skill), run this one").option("--allow-dirty", "Autopilot: start on top of uncommitted changes (e.g. a step killed mid-run)").action(async (runId, opts, actionCmd) => {
50398
50478
  const root = resolveWorkspaceRoot(actionCmd);
50399
50479
  if (opts.json) {
50400
50480
  setQuiet(true);
@@ -50524,6 +50604,7 @@ async function execLoop(root, runId, opts) {
50524
50604
  message: opts.message,
50525
50605
  dryRun: opts.dryRun,
50526
50606
  skill: opts.skill,
50607
+ allowDirty: opts.allowDirty,
50527
50608
  shouldCancel: () => cancelRequested,
50528
50609
  signal: stopNow.signal
50529
50610
  },
@@ -50577,6 +50658,7 @@ function cliExecHooks(runId, claudeOut) {
50577
50658
  onRunCompleted: () => info(import_chalk10.default.green("\n\u{1F389} Run completed \u2014 all steps approved.")),
50578
50659
  onRunFailed: (reason) => console.error(import_chalk10.default.red(`
50579
50660
  ${reason}`)),
50661
+ onPreflightNote: (message) => info(import_chalk10.default.yellow(`\u26A0 ${message}`)),
50580
50662
  onStepStart: (e) => {
50581
50663
  info(import_chalk10.default.bold(`
50582
50664
  \u25B6 Step ${e.stepIdx}: ${e.label}`) + import_chalk10.default.dim(` (rev ${e.revision})`));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delete101020/aidlc",
3
- "version": "4.0.46",
3
+ "version": "4.0.47",
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": {