@parabolic-technologies/banzai 2.7.1 → 2.7.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/banzai.mjs CHANGED
@@ -8790,6 +8790,11 @@ async function withRunnerWorkOwnership(root, bound, action) {
8790
8790
  return withExecutionOwnership(root, bound.binding.artifacts.reviewDirectory, action, bound.sha256);
8791
8791
  }
8792
8792
 
8793
+ // src/work-documents.ts
8794
+ function isHistoricalWork(bound) {
8795
+ return bound !== void 0 && parseBinding(bound.binding).schemaVersion !== 3;
8796
+ }
8797
+
8793
8798
  // src/config.ts
8794
8799
  import { access, mkdir as mkdir3, readFile as readFile3, writeFile } from "node:fs/promises";
8795
8800
  import path10 from "node:path";
@@ -16036,7 +16041,7 @@ import process7 from "node:process";
16036
16041
  // package.json
16037
16042
  var package_default = {
16038
16043
  name: "@parabolic-technologies/banzai",
16039
- version: "2.7.1",
16044
+ version: "2.7.2",
16040
16045
  private: false,
16041
16046
  description: "Spec-driven AI development CLI for Codex and Claude Code, with human approvals and independent review for complex changes.",
16042
16047
  keywords: [
@@ -31173,6 +31178,10 @@ function planningReviewStatusLines(status) {
31173
31178
  }
31174
31179
  return lines;
31175
31180
  }
31181
+ function historicalRunNotice(state) {
31182
+ if (!isHistoricalWork(state.artifactBinding)) return null;
31183
+ return TERMINAL_STATUSES.has(state.status) ? "This run was created by an earlier Banzai version and is read-only. Its documents stay where they are." : "This run was created by an earlier Banzai version and cannot resume. Cancel it to start new work; its documents stay where they are.";
31184
+ }
31176
31185
  function reviewStatusLines(status) {
31177
31186
  if (status.latestReview === null || status.state.latestReview === null) {
31178
31187
  return [];
@@ -34332,6 +34341,7 @@ var WorkflowRunner = class {
34332
34341
  }
34333
34342
  async status() {
34334
34343
  const state = await this.store.requireActiveState();
34344
+ const historical = isHistoricalWork(state.artifactBinding);
34335
34345
  let planApprovalValid = null;
34336
34346
  if (state.planApproval !== null) {
34337
34347
  try {
@@ -34345,7 +34355,7 @@ var WorkflowRunner = class {
34345
34355
  }
34346
34356
  }
34347
34357
  let reviewValid = null;
34348
- if (state.latestReview !== null) {
34358
+ if (state.latestReview !== null && !historical) {
34349
34359
  reviewValid = await workspaceDigest(this.repoRoot, {
34350
34360
  artifactBinding: state.artifactBinding,
34351
34361
  excludedPaths: state.latestReview.artifactPath === void 0 ? [] : [state.latestReview.artifactPath],
@@ -34357,6 +34367,9 @@ var WorkflowRunner = class {
34357
34367
  const recovery = await this.recoveryEligibility(state);
34358
34368
  const taskCompletion = await this.taskCompletionStatus(state);
34359
34369
  const completionPublication2 = await this.completionPublicationStatus(state);
34370
+ let recommended = nextAction(state, retry, recovery, completionPublication2);
34371
+ if (historical)
34372
+ recommended = TERMINAL_STATUSES.has(state.status) ? null : "banzai cancel";
34360
34373
  let configurationPrerequisite;
34361
34374
  if (state.pendingHumanDecision?.kind === "configuration_prerequisite") {
34362
34375
  const request = state.pendingHumanDecision;
@@ -34405,7 +34418,7 @@ var WorkflowRunner = class {
34405
34418
  latestReview,
34406
34419
  retry,
34407
34420
  recovery,
34408
- nextAction: nextAction(state, retry, recovery, completionPublication2),
34421
+ nextAction: recommended,
34409
34422
  taskCompletion,
34410
34423
  completionPublication: completionPublication2,
34411
34424
  ...configurationPrerequisite ? { configurationPrerequisite } : {}
@@ -34518,6 +34531,21 @@ var WorkflowRunner = class {
34518
34531
  ]
34519
34532
  };
34520
34533
  }
34534
+ if (isHistoricalWork(state.artifactBinding)) {
34535
+ return {
34536
+ state: "legacy",
34537
+ source: "legacy",
34538
+ completed: null,
34539
+ total,
34540
+ diagnostics: [
34541
+ {
34542
+ code: "PLAN_TASK_COMPLETION_LEGACY",
34543
+ taskId: null,
34544
+ message: "Run was created by an earlier Banzai version; its recorded completion evidence is read-only and is not revalidated."
34545
+ }
34546
+ ]
34547
+ };
34548
+ }
34521
34549
  try {
34522
34550
  const allowBlockedFixReportRefresh = state.status === "blocked" && state.blockedFrom === "fixing" && state.activeAttempt === null;
34523
34551
  const validated = await revalidateTaskCompletion(
@@ -41293,13 +41321,13 @@ async function activeRunCheck(repoRoot) {
41293
41321
  "The referenced run state uses an unsupported structure."
41294
41322
  );
41295
41323
  }
41324
+ let historical = false;
41296
41325
  if (state.schemaVersion === 4 || state.schemaVersion === 5 || state.schemaVersion === 6 || state.schemaVersion === 7 || state.schemaVersion === 8 || state.schemaVersion === 9 || state.schemaVersion === 10) {
41297
41326
  try {
41298
41327
  validateConfigurationStateEnvelope(state);
41299
- await inspectBoundWork(
41300
- repoRoot,
41301
- state.artifactBinding
41302
- );
41328
+ const bound = state.artifactBinding;
41329
+ historical = state.schemaVersion <= 8 && isHistoricalWork(bound);
41330
+ if (!historical) await inspectBoundWork(repoRoot, bound);
41303
41331
  } catch {
41304
41332
  return check(
41305
41333
  "run.active",
@@ -41326,7 +41354,21 @@ async function activeRunCheck(repoRoot) {
41326
41354
  "run.active",
41327
41355
  "run-state",
41328
41356
  "pass",
41329
- `The latest-run pointer references terminal status ${state.status}.`
41357
+ historical ? `The latest-run pointer references terminal status ${state.status} from an earlier Banzai version; that run is read-only history.` : `The latest-run pointer references terminal status ${state.status}.`
41358
+ );
41359
+ }
41360
+ if (historical) {
41361
+ return check(
41362
+ "run.active",
41363
+ "run-state",
41364
+ "warning",
41365
+ `A run created by an earlier Banzai version is ${state.status} and cannot resume.`,
41366
+ [
41367
+ {
41368
+ action: "Run banzai cancel, then start new work. The earlier run's documents stay where they are.",
41369
+ documentation: "documentation/getting-started.md"
41370
+ }
41371
+ ]
41330
41372
  );
41331
41373
  }
41332
41374
  return check(
@@ -44566,6 +44608,11 @@ function renderStatus(io, status, styler, humanTime) {
44566
44608
  io.writeLine(styler.dim(` ${facts.join(" \xB7 ")}`));
44567
44609
  }
44568
44610
  io.writeLine(styler.dim(` ${state.runId}`));
44611
+ const historical = historicalRunNotice(state);
44612
+ if (historical !== null) {
44613
+ io.writeLine();
44614
+ writeLabeled(io, "History", historical);
44615
+ }
44569
44616
  if (state.workflowSelection != null) {
44570
44617
  io.writeLine();
44571
44618
  writeLabeled(io, "Why this workflow", state.workflowSelection.reason);
@@ -45271,6 +45318,20 @@ async function handleStatus(runner, io, status, options) {
45271
45318
  }
45272
45319
  return false;
45273
45320
  }
45321
+ if (historicalRunNotice(state) !== null) {
45322
+ const action2 = await io.select("What next?", [
45323
+ { name: "Cancel run", value: "cancel" },
45324
+ { name: "Exit", value: "exit" }
45325
+ ]);
45326
+ if (action2 === "cancel") {
45327
+ return await confirmCancellation(
45328
+ runner,
45329
+ options.cancellationIO ?? io,
45330
+ state.runId
45331
+ );
45332
+ }
45333
+ return false;
45334
+ }
45274
45335
  if (state.status === "needs_plan_approval") {
45275
45336
  const prerequisites = await runner.getPlanHumanPrerequisites?.();
45276
45337
  if (prerequisites)
@@ -47246,6 +47307,8 @@ function printState(status, metrics = false) {
47246
47307
  console.log(`Feature: ${state.slug}`);
47247
47308
  const gloss = runStatusGloss(state.status);
47248
47309
  console.log(`Status: ${state.status}${gloss === null ? "" : ` (${gloss})`}`);
47310
+ const historical = historicalRunNotice(state);
47311
+ if (historical !== null) printLabeled("History", historical);
47249
47312
  const completion = status.taskCompletion;
47250
47313
  const count = completion.completed === null ? completion.total === null ? completion.state : `${completion.state}/${completion.total}` : `${completion.completed}/${completion.total ?? "?"}`;
47251
47314
  console.log(`Plan tasks: ${count} (${completion.source})`);
@@ -48065,7 +48128,7 @@ ${escapeTerminalText(prerequisites)}`
48065
48128
  throw new BanzaiError("INVALID_COMMAND", `Unknown command: ${command}`);
48066
48129
  }
48067
48130
  main().catch((error) => {
48068
- const code2 = error instanceof BanzaiError ? error.code : "UNEXPECTED_ERROR";
48131
+ const code2 = error instanceof BanzaiError || error instanceof ProjectFileError ? error.code : "UNEXPECTED_ERROR";
48069
48132
  closeProgress();
48070
48133
  console.error(`[${code2}] ${errorMessage(error)}`);
48071
48134
  process7.exitCode = error instanceof BanzaiError ? error.exitCode : 1;