@delete101020/aidlc 4.0.13 → 4.0.14

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 +340 -26
  2. package/package.json +1 -1
package/dist/bundle.js CHANGED
@@ -19761,7 +19761,7 @@ var require_WorkspaceSchema = __commonJS({
19761
19761
  "use strict";
19762
19762
  Object.defineProperty(exports2, "__esModule", { value: true });
19763
19763
  exports2.WorkspaceValidationError = exports2.WorkspaceSchema = void 0;
19764
- exports2.normalizeStep = normalizeStep2;
19764
+ exports2.normalizeStep = normalizeStep3;
19765
19765
  exports2.stepAgentId = stepAgentId3;
19766
19766
  exports2.stepDagId = stepDagId;
19767
19767
  exports2.collectWorkspaceRefIssues = collectWorkspaceRefIssues3;
@@ -19975,7 +19975,7 @@ var require_WorkspaceSchema = __commonJS({
19975
19975
  */
19976
19976
  gates: zod_1.z.record(zod_1.z.string(), RecipeGateSchema).optional()
19977
19977
  });
19978
- function normalizeStep2(step) {
19978
+ function normalizeStep3(step) {
19979
19979
  if (typeof step === "string") {
19980
19980
  return {
19981
19981
  agent: step,
@@ -20028,7 +20028,7 @@ var require_WorkspaceSchema = __commonJS({
20028
20028
  return "";
20029
20029
  }
20030
20030
  function stepDagId(step) {
20031
- const norm = normalizeStep2(step);
20031
+ const norm = normalizeStep3(step);
20032
20032
  return norm.name ?? norm.agent;
20033
20033
  }
20034
20034
  function collectWorkspaceRefIssues3(config) {
@@ -20048,7 +20048,7 @@ var require_WorkspaceSchema = __commonJS({
20048
20048
  }
20049
20049
  for (const pipeline of config.pipelines) {
20050
20050
  for (const step of pipeline.steps) {
20051
- const norm = normalizeStep2(step);
20051
+ const norm = normalizeStep3(step);
20052
20052
  const id = norm.name ?? norm.agent;
20053
20053
  if (!agentIds.has(norm.agent)) {
20054
20054
  issues.push({
@@ -20753,7 +20753,7 @@ var require_RunState = __commonJS({
20753
20753
  exports2.stepIdentity = stepIdentity2;
20754
20754
  exports2.migrateRunState = migrateRunState;
20755
20755
  exports2.resolvePath = resolvePath;
20756
- exports2.RUN_STATE_SCHEMA_VERSION = 2;
20756
+ exports2.RUN_STATE_SCHEMA_VERSION = 3;
20757
20757
  function stepIdentity2(step) {
20758
20758
  return step.name ?? step.agent;
20759
20759
  }
@@ -20766,12 +20766,12 @@ var require_RunState = __commonJS({
20766
20766
  return null;
20767
20767
  }
20768
20768
  const version2 = obj.schemaVersion;
20769
- if (version2 !== 1 && version2 !== exports2.RUN_STATE_SCHEMA_VERSION) {
20770
- return null;
20771
- }
20772
20769
  if (version2 === exports2.RUN_STATE_SCHEMA_VERSION) {
20773
20770
  return obj;
20774
20771
  }
20772
+ if (version2 !== 1 && version2 !== 2) {
20773
+ return null;
20774
+ }
20775
20775
  return { ...obj, schemaVersion: exports2.RUN_STATE_SCHEMA_VERSION };
20776
20776
  }
20777
20777
  function resolvePath(template, context) {
@@ -20792,6 +20792,7 @@ var require_runProgress = __commonJS({
20792
20792
  exports2.isStepOptional = isStepOptional;
20793
20793
  exports2.deriveRunProgress = deriveRunProgress;
20794
20794
  exports2.isRunComplete = isRunComplete;
20795
+ exports2.weighStepProgress = weighStepProgress2;
20795
20796
  var WorkspaceSchema_1 = require_WorkspaceSchema();
20796
20797
  var ACTIVE = /* @__PURE__ */ new Set([
20797
20798
  "awaiting_work",
@@ -20857,6 +20858,63 @@ var require_runProgress = __commonJS({
20857
20858
  return s.status === "rejected" || s.status === "pending";
20858
20859
  });
20859
20860
  }
20861
+ function weighStepProgress2(steps) {
20862
+ const n = steps.length;
20863
+ if (n === 0) {
20864
+ return { ranks: [], weights: [], stages: 0, stagesDone: 0, percent: 0 };
20865
+ }
20866
+ const idxById = /* @__PURE__ */ new Map();
20867
+ steps.forEach((s, i) => {
20868
+ if (!idxById.has(s.id)) {
20869
+ idxById.set(s.id, i);
20870
+ }
20871
+ });
20872
+ if (!steps.some((s) => (s.dependsOn?.length ?? 0) > 0)) {
20873
+ const ranks2 = steps.map((_, i) => i);
20874
+ const weights2 = steps.map(() => 1);
20875
+ const stagesDone2 = steps.reduce((sum, s) => s.done ? sum + 1 : sum, 0);
20876
+ return { ranks: ranks2, weights: weights2, stages: n, stagesDone: stagesDone2, percent: Math.round(stagesDone2 / n * 100) };
20877
+ }
20878
+ const ranks = new Array(n).fill(-1);
20879
+ const visiting = new Array(n).fill(false);
20880
+ const rankOf = (i) => {
20881
+ if (ranks[i] >= 0) {
20882
+ return ranks[i];
20883
+ }
20884
+ if (visiting[i]) {
20885
+ return 0;
20886
+ }
20887
+ visiting[i] = true;
20888
+ let rank = 0;
20889
+ for (const dep of steps[i].dependsOn ?? []) {
20890
+ const j = idxById.get(dep);
20891
+ if (j === void 0 || j === i) {
20892
+ continue;
20893
+ }
20894
+ rank = Math.max(rank, rankOf(j) + 1);
20895
+ }
20896
+ visiting[i] = false;
20897
+ ranks[i] = rank;
20898
+ return rank;
20899
+ };
20900
+ for (let i = 0; i < n; i++) {
20901
+ rankOf(i);
20902
+ }
20903
+ const sizeByRank = /* @__PURE__ */ new Map();
20904
+ for (const r of ranks) {
20905
+ sizeByRank.set(r, (sizeByRank.get(r) ?? 0) + 1);
20906
+ }
20907
+ const weights = ranks.map((r) => 1 / (sizeByRank.get(r) ?? 1));
20908
+ const stages = sizeByRank.size;
20909
+ const stagesDone = steps.reduce((sum, s, i) => s.done ? sum + weights[i] : sum, 0);
20910
+ return {
20911
+ ranks,
20912
+ weights,
20913
+ stages,
20914
+ stagesDone,
20915
+ percent: stages > 0 ? Math.round(stagesDone / stages * 100) : 0
20916
+ };
20917
+ }
20860
20918
  }
20861
20919
  });
20862
20920
 
@@ -21026,6 +21084,9 @@ var require_PipelineRunner = __commonJS({
21026
21084
  exports2.rejectStep = rejectStep3;
21027
21085
  exports2.rerunStep = rerunStep3;
21028
21086
  exports2.requestStepUpdate = requestStepUpdate2;
21087
+ exports2.dirtyUpstreamOf = dirtyUpstreamOf2;
21088
+ exports2.canRerunApprovedStep = canRerunApprovedStep;
21089
+ exports2.rerunApprovedStep = rerunApprovedStep2;
21029
21090
  var fs14 = __importStar(require("fs"));
21030
21091
  var path17 = __importStar(require("path"));
21031
21092
  var WorkspaceSchema_1 = require_WorkspaceSchema();
@@ -21535,6 +21596,156 @@ var require_PipelineRunner = __commonJS({
21535
21596
  next.status = "running";
21536
21597
  return next;
21537
21598
  }
21599
+ function descendantsOf(pipeline, idx) {
21600
+ const normalized = pipeline.steps.map(WorkspaceSchema_1.normalizeStep);
21601
+ const usesDag = normalized.some((s) => s.depends_on.length > 0);
21602
+ if (!usesDag) {
21603
+ return sequentialRange(idx + 1, normalized.length - 1);
21604
+ }
21605
+ const idxByDagId = /* @__PURE__ */ new Map();
21606
+ normalized.forEach((s, i) => {
21607
+ idxByDagId.set(s.name ?? s.agent, i);
21608
+ });
21609
+ const found = /* @__PURE__ */ new Set([idx]);
21610
+ let changed = true;
21611
+ while (changed) {
21612
+ changed = false;
21613
+ normalized.forEach((s, i) => {
21614
+ if (found.has(i)) {
21615
+ return;
21616
+ }
21617
+ if (s.depends_on.some((dep) => {
21618
+ const di = idxByDagId.get(dep);
21619
+ return di !== void 0 && found.has(di);
21620
+ })) {
21621
+ found.add(i);
21622
+ changed = true;
21623
+ }
21624
+ });
21625
+ }
21626
+ found.delete(idx);
21627
+ return Array.from(found).sort((a, b) => a - b);
21628
+ }
21629
+ function ancestorsOf(pipeline, idx) {
21630
+ const normalized = pipeline.steps.map(WorkspaceSchema_1.normalizeStep);
21631
+ const usesDag = normalized.some((s) => s.depends_on.length > 0);
21632
+ if (!usesDag) {
21633
+ return sequentialRange(0, idx - 1);
21634
+ }
21635
+ const idxByDagId = /* @__PURE__ */ new Map();
21636
+ normalized.forEach((s, i) => {
21637
+ idxByDagId.set(s.name ?? s.agent, i);
21638
+ });
21639
+ const found = /* @__PURE__ */ new Set();
21640
+ const queue = [idx];
21641
+ while (queue.length > 0) {
21642
+ const cur = queue.pop();
21643
+ for (const dep of normalized[cur]?.depends_on ?? []) {
21644
+ const di = idxByDagId.get(dep);
21645
+ if (di === void 0 || found.has(di) || di === idx) {
21646
+ continue;
21647
+ }
21648
+ found.add(di);
21649
+ queue.push(di);
21650
+ }
21651
+ }
21652
+ return Array.from(found).sort((a, b) => a - b);
21653
+ }
21654
+ function dirtyUpstreamOf2(args) {
21655
+ const { state, pipeline, stepIdx } = args;
21656
+ if (!state.steps[stepIdx]) {
21657
+ return [];
21658
+ }
21659
+ const out2 = [];
21660
+ for (const i of ancestorsOf(pipeline, stepIdx)) {
21661
+ const s = state.steps[i];
21662
+ if (!s?.dirty) {
21663
+ continue;
21664
+ }
21665
+ out2.push({ stepIdx: i, step: (0, RunState_1.stepIdentity)(s), dirty: s.dirty });
21666
+ }
21667
+ return out2;
21668
+ }
21669
+ function canRerunApprovedStep(args) {
21670
+ const { state, pipeline } = args;
21671
+ const idx = args.stepIdx ?? state.currentStepIdx;
21672
+ const step = state.steps[idx];
21673
+ if (!step) {
21674
+ return { ok: false, reason: `No step at index ${idx}` };
21675
+ }
21676
+ if (!(0, reconcileRun_1.reconcileRunSteps)(state, pipeline).aligned) {
21677
+ return {
21678
+ ok: false,
21679
+ reason: `Run "${state.runId}" no longer matches pipeline "${pipeline.id}" \u2014 reconcile it before rerunning anything.`
21680
+ };
21681
+ }
21682
+ if (step.status !== "approved") {
21683
+ return {
21684
+ ok: false,
21685
+ reason: step.status === "awaiting_review" || step.status === "awaiting_auto_review" ? `Step "${(0, RunState_1.stepIdentity)(step)}" has not been approved yet \u2014 take the mark-done back with "Undo" instead.` : `Step "${(0, RunState_1.stepIdentity)(step)}" is "${step.status}", not "approved" \u2014 there is nothing to rerun.`
21686
+ };
21687
+ }
21688
+ return { ok: true };
21689
+ }
21690
+ function rerunApprovedStep2(args) {
21691
+ const { pipeline, feedback } = args;
21692
+ const state = alignedOrThrow(args.state, pipeline);
21693
+ const idx = args.stepIdx ?? state.currentStepIdx;
21694
+ const gate = canRerunApprovedStep({ state, pipeline, stepIdx: idx });
21695
+ if (!gate.ok) {
21696
+ throw new PipelineRunError3(gate.reason);
21697
+ }
21698
+ const step = state.steps[idx];
21699
+ const now = (/* @__PURE__ */ new Date()).toISOString();
21700
+ const next = clone(state);
21701
+ const newRev = step.revision + 1;
21702
+ const carriedFeedback = feedback ?? step.feedback;
21703
+ next.steps[idx] = {
21704
+ ...step,
21705
+ status: "awaiting_work",
21706
+ revision: newRev,
21707
+ feedback: carriedFeedback,
21708
+ rejectReason: void 0,
21709
+ autoReviewVerdict: void 0,
21710
+ // The target is being redone, so whatever made *it* suspect is moot.
21711
+ dirty: void 0,
21712
+ artifactsProduced: [],
21713
+ finishedAt: void 0,
21714
+ startedAt: now,
21715
+ history: pushHistory(step.history, {
21716
+ kind: "rerun",
21717
+ at: now,
21718
+ revision: newRev,
21719
+ feedback: carriedFeedback
21720
+ })
21721
+ };
21722
+ const mark = {
21723
+ since: now,
21724
+ byStepIdx: idx,
21725
+ byStep: (0, RunState_1.stepIdentity)(step),
21726
+ byRevision: newRev
21727
+ };
21728
+ for (const i of descendantsOf(pipeline, idx)) {
21729
+ const d = next.steps[i];
21730
+ if (!d || d.status !== "approved") {
21731
+ continue;
21732
+ }
21733
+ next.steps[i] = {
21734
+ ...d,
21735
+ dirty: mark,
21736
+ history: pushHistory(d.history, {
21737
+ kind: "dirty",
21738
+ at: now,
21739
+ revision: d.revision,
21740
+ byStep: mark.byStep,
21741
+ byStepIdx: idx
21742
+ })
21743
+ };
21744
+ }
21745
+ next.currentStepIdx = idx;
21746
+ next.status = "running";
21747
+ return next;
21748
+ }
21538
21749
  function advance(next, idx, pipeline) {
21539
21750
  const finishedAt = (/* @__PURE__ */ new Date()).toISOString();
21540
21751
  const approved = next.steps[idx];
@@ -21542,6 +21753,10 @@ var require_PipelineRunner = __commonJS({
21542
21753
  ...approved,
21543
21754
  status: "approved",
21544
21755
  finishedAt,
21756
+ // The step has now run against whatever its input currently is, so the
21757
+ // mark an upstream rerun left on it no longer describes anything. This is
21758
+ // the only thing that clears it.
21759
+ dirty: void 0,
21545
21760
  history: pushHistory(approved.history, {
21546
21761
  kind: "approve",
21547
21762
  at: finishedAt,
@@ -25039,7 +25254,7 @@ var require_PlanGenerator = __commonJS({
25039
25254
  Object.defineProperty(exports2, "__esModule", { value: true });
25040
25255
  exports2.generatePlan = generatePlan;
25041
25256
  exports2.renderPlanMarkdown = renderPlanMarkdown;
25042
- function normalizeStep2(step) {
25257
+ function normalizeStep3(step) {
25043
25258
  if (typeof step === "string") {
25044
25259
  return { name: step };
25045
25260
  }
@@ -25155,7 +25370,7 @@ var require_PlanGenerator = __commonJS({
25155
25370
  }
25156
25371
  function generatePlan(epicId, context, pipeline, workspace) {
25157
25372
  const complexity = inferScopeComplexity(context.scope);
25158
- const steps = (pipeline.steps || []).map(normalizeStep2);
25373
+ const steps = (pipeline.steps || []).map(normalizeStep3);
25159
25374
  const agentCountPerPhase = allocateAgentCount(complexity, steps.length);
25160
25375
  const phaseAllocations = steps.map((step) => {
25161
25376
  const agentId = step.agent || "unknown";
@@ -25381,6 +25596,10 @@ var require_EpicScaffold = __commonJS({
25381
25596
  startedAt: s.startedAt ?? null,
25382
25597
  finishedAt: s.finishedAt ?? null,
25383
25598
  rejectReason: s.rejectReason,
25599
+ // Mirrored because `status` alone reads as a plain `done` here: the whole
25600
+ // point of the mark is that it does not change the status, so a reader of
25601
+ // state.json that only saw `status` would have no way to know.
25602
+ dirty: s.dirty,
25384
25603
  feedback: s.feedback,
25385
25604
  autoReviewVerdict: s.autoReviewVerdict,
25386
25605
  history: s.history ?? [],
@@ -30603,7 +30822,8 @@ var require_execEngine = __commonJS({
30603
30822
  revision: stepRec.revision,
30604
30823
  skills: agent.skills,
30605
30824
  model: agent.model,
30606
- context: userMessage
30825
+ context: userMessage,
30826
+ dirtyUpstream: (0, PipelineRunner_1.dirtyUpstreamOf)({ state, pipeline, stepIdx }).map((d) => ({ stepIdx: d.stepIdx, step: d.step, byStep: d.dirty.byStep }))
30607
30827
  });
30608
30828
  const aliases = (0, pricing_1.providerAliases)(ws.config.providers, agent.runner);
30609
30829
  const resolvedModel = (0, models_1.resolveProviderModel)(agent.runner, agent.model, aliases);
@@ -33050,9 +33270,10 @@ var require_dist = __commonJS({
33050
33270
  exports2.followUpEpicId = exports2.renderIntentMarkdown = exports2.openFollowUpEpic = exports2.openIncidentEpic = exports2.SignalParseError = exports2.isSignal = exports2.parseSignal = exports2.SignalSchema = exports2.EpicStepEditError = exports2.resolveStepRef = exports2.describeGateEffect = exports2.commitEpicStepEdit = exports2.planSetEpicStepGates = exports2.planRemoveEpicStep = exports2.planAddEpicStep = exports2.EpicWorkflowSwitchError = exports2.canSwitchEpicWorkflow = exports2.epicWorkflowLock = exports2.applyEpicWorkflowSwitch = exports2.stageEpicWorkflowSwitch = exports2.planEpicWorkflowSwitch = exports2.EpicDescriptionError = exports2.setEpicDescription = exports2.lockedEpicDirError = exports2.EpicScaffoldError = exports2.epicsRoot = exports2.mapStepStatusToEpic = exports2.mirrorRunStateToEpic = exports2.scaffoldEpic = exports2.resolveArtifactCommitConfig = exports2.commitApprovedArtifacts = exports2.PipelineAdaptError = exports2.applyAdaptation = exports2.parseAdaptationVerdict = exports2.buildAdaptationPrompt = exports2.buildPhaseCatalog = exports2.slugEpicId = exports2.parseClassificationVerdict = exports2.buildClassificationPrompt = exports2.heuristicClassify = exports2.PipelineAssembleError = exports2.recipePipelineId = exports2.assemblePipeline = exports2.collectWorkspaceRefIssues = exports2.stepDagId = exports2.stepAgentId = exports2.normalizeStep = exports2.WorkspaceValidationError = exports2.validateWorkspace = exports2.WorkspaceSchema = void 0;
33051
33271
  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 = 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.openManifestFollowUp = 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 = void 0;
33052
33272
  exports2.commandBodyIsStale = exports2.readEpicTags = exports2.normalizeTags = exports2.normalizeTag = exports2.epicMatchesTags = exports2.applyTagEdit = exports2.MAX_TAG_LENGTH = exports2.EPIC_TAGS_KEY = exports2.strictModeSection = exports2.resolveEpicStrictMode = exports2.epicStrictMode = exports2.commandBodyPredatesStrictMode = exports2.STRICT_MODE_KEY = exports2.STRICT_MODE_HEADING = exports2.writeUserEpicIdPrefix = exports2.userConfigPath = 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 = void 0;
33053
- exports2.providerAliases = exports2.ratesFromConfig = exports2.mergeRates = exports2.BUILTIN_RATES = exports2.checkBudget = exports2.isActiveStatus = exports2.isStepOptional = exports2.isRunComplete = exports2.deriveRunProgress = exports2.PipelineRunError = exports2.retryAutoReview = exports2.submitAutoReviewVerdict = 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.CodexRunner = exports2.DefaultRunner = exports2.RunnerRegistry = exports2.targetPath = exports2.scopePaths = exports2.discoverAssets = void 0;
33054
- exports2.CANONICAL_PHASES = exports2.renderTemplate = exports2.DEFAULT_GLOBAL_WORKFLOW_IDS = exports2.detectGlobalBuiltinSource = exports2.uninstallWorkflowGlobalsByIds = exports2.isWorkflowGloballyInstalled = exports2.installWorkflowGlobalsByIds = exports2.installGlobalDefaults = exports2.resolveProviderModel = 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 = void 0;
33055
- 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 = 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 = void 0;
33273
+ exports2.checkBudget = exports2.weighStepProgress = exports2.isActiveStatus = exports2.isStepOptional = exports2.isRunComplete = exports2.deriveRunProgress = exports2.PipelineRunError = exports2.retryAutoReview = exports2.submitAutoReviewVerdict = exports2.dirtyUpstreamOf = exports2.rerunApprovedStep = exports2.canRerunApprovedStep = 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.CodexRunner = exports2.DefaultRunner = exports2.RunnerRegistry = exports2.targetPath = exports2.scopePaths = exports2.discoverAssets = void 0;
33274
+ exports2.uninstallWorkflowGlobalsByIds = exports2.isWorkflowGloballyInstalled = exports2.installWorkflowGlobalsByIds = exports2.installGlobalDefaults = exports2.resolveProviderModel = 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 = void 0;
33275
+ exports2.resolveCommand = exports2.remapClaudePath = exports2.claudeConfigEnv = exports2.claudeJsonPath = exports2.isDefaultClaudeConfigDir = exports2.claudeConfigDir = exports2.resolveClaudeConfigDir = 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 = void 0;
33276
+ exports2.AIDLC_CORE_VERSION = exports2.AIDLC_CLI_GUIDE_TEXT = exports2.AIDLC_KNOWLEDGE = exports2.clearResolveCommandCache = void 0;
33056
33277
  var WorkspaceSchema_1 = require_WorkspaceSchema();
33057
33278
  Object.defineProperty(exports2, "WorkspaceSchema", { enumerable: true, get: function() {
33058
33279
  return WorkspaceSchema_1.WorkspaceSchema;
@@ -33661,6 +33882,15 @@ var require_dist = __commonJS({
33661
33882
  Object.defineProperty(exports2, "requestStepUpdate", { enumerable: true, get: function() {
33662
33883
  return PipelineRunner_1.requestStepUpdate;
33663
33884
  } });
33885
+ Object.defineProperty(exports2, "canRerunApprovedStep", { enumerable: true, get: function() {
33886
+ return PipelineRunner_1.canRerunApprovedStep;
33887
+ } });
33888
+ Object.defineProperty(exports2, "rerunApprovedStep", { enumerable: true, get: function() {
33889
+ return PipelineRunner_1.rerunApprovedStep;
33890
+ } });
33891
+ Object.defineProperty(exports2, "dirtyUpstreamOf", { enumerable: true, get: function() {
33892
+ return PipelineRunner_1.dirtyUpstreamOf;
33893
+ } });
33664
33894
  Object.defineProperty(exports2, "submitAutoReviewVerdict", { enumerable: true, get: function() {
33665
33895
  return PipelineRunner_1.submitAutoReviewVerdict;
33666
33896
  } });
@@ -33683,6 +33913,9 @@ var require_dist = __commonJS({
33683
33913
  Object.defineProperty(exports2, "isActiveStatus", { enumerable: true, get: function() {
33684
33914
  return runProgress_1.isActiveStatus;
33685
33915
  } });
33916
+ Object.defineProperty(exports2, "weighStepProgress", { enumerable: true, get: function() {
33917
+ return runProgress_1.weighStepProgress;
33918
+ } });
33686
33919
  var budget_1 = require_budget();
33687
33920
  Object.defineProperty(exports2, "checkBudget", { enumerable: true, get: function() {
33688
33921
  return budget_1.checkBudget;
@@ -42685,7 +42918,7 @@ var require_package = __commonJS({
42685
42918
  "package.json"(exports2, module2) {
42686
42919
  module2.exports = {
42687
42920
  name: "@delete101020/aidlc",
42688
- version: "4.0.13",
42921
+ version: "4.0.14",
42689
42922
  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.",
42690
42923
  license: "MIT",
42691
42924
  repository: {
@@ -46421,7 +46654,8 @@ ${import_chalk5.default.bold(state.runId)} ${runColor(state.status)}`);
46421
46654
  const rev = step.revision > 1 ? import_chalk5.default.dim(` rev${step.revision}`) : "";
46422
46655
  const feedback = step.feedback ? import_chalk5.default.dim(` [feedback: ${step.feedback.slice(0, 40)}]`) : "";
46423
46656
  const reason = step.rejectReason ? import_chalk5.default.red(` \u2718 ${step.rejectReason.slice(0, 60)}`) : "";
46424
- console.log(` ${marker} ${idxLabel} ${agent.padEnd(20)} ${status}${rev}${feedback}${reason}`);
46657
+ const dirty = step.dirty ? import_chalk5.default.yellow(` \u26A0 dirty (${step.dirty.byStep} was rerun after this)`) : "";
46658
+ console.log(` ${marker} ${idxLabel} ${agent.padEnd(20)} ${status}${rev}${dirty}${feedback}${reason}`);
46425
46659
  });
46426
46660
  console.log();
46427
46661
  }
@@ -47459,6 +47693,12 @@ function registerRun(program3) {
47459
47693
  }
47460
47694
  process.exit(1);
47461
47695
  }
47696
+ const stale = (0, import_core13.dirtyUpstreamOf)({ state, pipeline, stepIdx: state.currentStepIdx });
47697
+ for (const d of stale) {
47698
+ console.log(import_chalk10.default.yellow(
47699
+ `\u26A0 upstream step ${d.stepIdx} ("${d.step}") is dirty \u2014 "${d.dirty.byStep}" was rerun after it finished. This step's input may be out of date.`
47700
+ ));
47701
+ }
47462
47702
  saveRunState(root, next, state);
47463
47703
  const prevStatus = state.steps[state.currentStepIdx].status;
47464
47704
  const step = next.steps[state.currentStepIdx];
@@ -47563,6 +47803,37 @@ function registerRun(program3) {
47563
47803
  console.log(import_chalk10.default.dim(` When done: aidlc run mark-done ${runId}`));
47564
47804
  printRunSummary(next);
47565
47805
  });
47806
+ cmd.command("redo <runId> <step>").description(
47807
+ "Rerun an already-approved step, KEEPING what was built on top of it.\n Approved steps downstream stay approved and are marked dirty \u2014 still done,\n but done against an input that has since changed. Use request-update instead\n when the change invalidates them and they must be redone from scratch.\n <step> can be a 0-based index or an agent id."
47808
+ ).option("--feedback <text>", "Notes for the next attempt (stored on the step)").action((runId, step, opts, actionCmd) => {
47809
+ const root = resolveWorkspaceRoot(actionCmd);
47810
+ const state = requireRun(root, runId);
47811
+ const pipeline = requirePipelineForRun(root, state);
47812
+ const stepIdx = requireStepIdx(state, step);
47813
+ let next;
47814
+ try {
47815
+ next = (0, import_core13.rerunApprovedStep)({ state, pipeline, stepIdx, feedback: opts.feedback });
47816
+ } catch (err) {
47817
+ console.error(import_chalk10.default.red(err instanceof Error ? err.message : String(err)));
47818
+ process.exit(1);
47819
+ }
47820
+ saveRunState(root, next, state);
47821
+ const target = next.steps[stepIdx];
47822
+ console.log(import_chalk10.default.yellow("\u21BA") + ` Rerunning "${target.agent}" (rev ${target.revision})`);
47823
+ if (opts.feedback) {
47824
+ console.log(import_chalk10.default.dim(` Feedback: ${opts.feedback}`));
47825
+ }
47826
+ const marked = next.steps.filter((st) => st.dirty?.byStepIdx === stepIdx);
47827
+ if (marked.length > 0) {
47828
+ console.log(import_chalk10.default.yellow(` \u26A0 ${marked.length} approved step(s) downstream kept and marked dirty:`));
47829
+ for (const m of marked) {
47830
+ console.log(import_chalk10.default.dim(` ${m.stepIdx}. ${m.name ?? m.agent}`));
47831
+ }
47832
+ console.log(import_chalk10.default.dim(" They still count as done. Redo each one to clear its mark."));
47833
+ }
47834
+ console.log(import_chalk10.default.dim(` When done: aidlc run mark-done ${runId}`));
47835
+ printRunSummary(next);
47836
+ });
47566
47837
  cmd.command("delete <runId>").description("Delete a run state file").option("--force", "Skip confirmation for running/active runs").action((runId, opts, actionCmd) => {
47567
47838
  const root = resolveWorkspaceRoot(actionCmd);
47568
47839
  const state = requireRun(root, runId);
@@ -47748,6 +48019,11 @@ ${reason}`)),
47748
48019
  if (e.context) {
47749
48020
  info(import_chalk10.default.dim(` context: ${e.context}`));
47750
48021
  }
48022
+ for (const d of e.dirtyUpstream ?? []) {
48023
+ info(import_chalk10.default.yellow(
48024
+ ` \u26A0 upstream step ${d.stepIdx} ("${d.step}") is dirty: "${d.byStep}" was rerun after it finished, so this step may be building on output that is out of date.`
48025
+ ));
48026
+ }
47751
48027
  sep4();
47752
48028
  },
47753
48029
  onStepResult: (e) => {
@@ -48330,6 +48606,21 @@ function epicsRoot(workspaceRoot, doc) {
48330
48606
  const stateRoot = doc?.state && typeof doc.state.root === "string" ? String(doc.state.root) : "docs/epics";
48331
48607
  return path10.resolve(workspaceRoot, stateRoot);
48332
48608
  }
48609
+ function pipelineStepsOf(doc, pipelineId) {
48610
+ const pipelines = Array.isArray(doc?.pipelines) ? doc.pipelines : [];
48611
+ const match = pipelines.find(
48612
+ (p) => !!p && typeof p === "object" && String(p.id) === pipelineId
48613
+ );
48614
+ const steps = Array.isArray(match?.steps) ? match.steps : [];
48615
+ return steps.map((raw) => {
48616
+ try {
48617
+ const n = (0, import_core17.normalizeStep)(raw);
48618
+ return { name: n.name, depends_on: n.depends_on };
48619
+ } catch {
48620
+ return { depends_on: [] };
48621
+ }
48622
+ });
48623
+ }
48333
48624
  function listEpics(workspaceRoot, doc) {
48334
48625
  const dir = epicsRoot(workspaceRoot, doc);
48335
48626
  if (!fs9.existsSync(dir)) {
@@ -48353,12 +48644,19 @@ function listEpics(workspaceRoot, doc) {
48353
48644
  continue;
48354
48645
  }
48355
48646
  const stepStatesRaw = Array.isArray(parsed.stepStates) ? parsed.stepStates : [];
48356
- const stepDetails = stepStatesRaw.map((s) => ({
48357
- agent: typeof s.agent === "string" ? s.agent : "",
48358
- status: asStatus(s.status),
48359
- startedAt: typeof s.startedAt === "string" ? s.startedAt : null,
48360
- finishedAt: typeof s.finishedAt === "string" ? s.finishedAt : null
48361
- }));
48647
+ const pipelineId = typeof parsed.pipeline === "string" ? parsed.pipeline : null;
48648
+ const pipelineSteps = pipelineId ? pipelineStepsOf(doc, pipelineId) : [];
48649
+ const stepDetails = stepStatesRaw.map((s, i) => {
48650
+ const cfg = pipelineSteps[i];
48651
+ return {
48652
+ agent: typeof s.agent === "string" ? s.agent : "",
48653
+ name: typeof s.name === "string" ? s.name : cfg?.name,
48654
+ status: asStatus(s.status),
48655
+ startedAt: typeof s.startedAt === "string" ? s.startedAt : null,
48656
+ finishedAt: typeof s.finishedAt === "string" ? s.finishedAt : null,
48657
+ dependsOn: cfg?.depends_on ?? []
48658
+ };
48659
+ });
48362
48660
  epics.push({
48363
48661
  id: typeof parsed.id === "string" ? parsed.id : folder,
48364
48662
  title: typeof parsed.title === "string" ? parsed.title : "",
@@ -48366,7 +48664,7 @@ function listEpics(workspaceRoot, doc) {
48366
48664
  status: asStatus(parsed.status),
48367
48665
  createdAt: typeof parsed.createdAt === "string" ? parsed.createdAt : "",
48368
48666
  tags: (0, import_core17.readEpicTags)(parsed),
48369
- pipeline: typeof parsed.pipeline === "string" ? parsed.pipeline : null,
48667
+ pipeline: pipelineId,
48370
48668
  agents: Array.isArray(parsed.agents) ? parsed.agents.map(String) : [],
48371
48669
  currentStep: typeof parsed.currentStep === "number" ? parsed.currentStep : 0,
48372
48670
  stepDetails,
@@ -48403,6 +48701,15 @@ function readInputs(epicDir) {
48403
48701
  return {};
48404
48702
  }
48405
48703
  }
48704
+ function epicProgress(epic) {
48705
+ return (0, import_core17.weighStepProgress)(
48706
+ epic.stepDetails.map((s) => ({
48707
+ id: s.name ?? s.agent,
48708
+ dependsOn: s.dependsOn,
48709
+ done: s.status === "done"
48710
+ }))
48711
+ );
48712
+ }
48406
48713
 
48407
48714
  // src/commands/dashboard.ts
48408
48715
  var RUNS_GLOB3 = ".aidlc/runs/*.json";
@@ -48462,7 +48769,10 @@ function registerDashboard(program3) {
48462
48769
  }
48463
48770
  if (url.pathname === "/api/epics") {
48464
48771
  const doc = readYaml(root);
48465
- const epics = listEpics(root, doc);
48772
+ const epics = listEpics(root, doc).map((e) => {
48773
+ const { percent, stages } = epicProgress(e);
48774
+ return { ...e, progress: percent, stages };
48775
+ });
48466
48776
  res.writeHead(200, { "Content-Type": "application/json" });
48467
48777
  res.end(JSON.stringify(epics));
48468
48778
  return;
@@ -49100,7 +49410,11 @@ function renderEpicsList() {
49100
49410
  el.innerHTML = filtered.map(e => {
49101
49411
  const total = (e.stepDetails || []).length;
49102
49412
  const done = (e.stepDetails || []).filter(s => s.status === 'done').length;
49103
- const pct = total ? Math.round((done / total) * 100) : 0;
49413
+ // Server-computed: stages, not steps. Falls back to the plain count only
49414
+ // when talking to an older server that sends no progress field.
49415
+ const pct = typeof e.progress === 'number'
49416
+ ? e.progress
49417
+ : (total ? Math.round((done / total) * 100) : 0);
49104
49418
 
49105
49419
  const stepsHtml = (e.stepDetails || []).map((s, i) => {
49106
49420
  const cls = i === e.currentStep && e.status === 'in_progress' ? 'step current' : 'step';
@@ -49189,7 +49503,7 @@ function registerEpic(program3) {
49189
49503
  for (const epic of epics) {
49190
49504
  const total = epic.stepDetails.length;
49191
49505
  const done = epic.stepDetails.filter((s) => s.status === "done").length;
49192
- const pct = total ? Math.round(done / total * 100) : 0;
49506
+ const pct = epicProgress(epic).percent;
49193
49507
  const stepLabel2 = total ? `${done}/${total} (${pct}%)` : "\u2014";
49194
49508
  table.push([
49195
49509
  import_chalk15.default.bold(epic.id),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@delete101020/aidlc",
3
- "version": "4.0.13",
3
+ "version": "4.0.14",
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": {