@pourkit/cli 0.0.0-next-20260714055657 → 0.0.0-next-20260715085442

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/cli.js CHANGED
@@ -370,10 +370,26 @@ function applyOutputRetriesDefaults(retries) {
370
370
  }
371
371
  function applyStageAgentDefaults(agent) {
372
372
  return {
373
- ...agent,
373
+ agent: agent.agent,
374
+ model: agent.model,
375
+ variant: agent.variant,
376
+ env: agent.env,
377
+ promptTemplate: agent.promptTemplate,
374
378
  outputRetries: applyOutputRetriesDefaults(agent.outputRetries)
375
379
  };
376
380
  }
381
+ var DEFAULT_POST_COMPLETION_FINAL_REVIEW_PROMPT = "post-completion-final-review.prompt.md";
382
+ function applyPostCompletionFinalReviewDefaults(agent, issueFinalReview) {
383
+ if (agent) return applyStageAgentDefaults(agent);
384
+ return applyStageAgentDefaults({
385
+ agent: issueFinalReview.agent,
386
+ model: issueFinalReview.model,
387
+ variant: issueFinalReview.variant,
388
+ env: issueFinalReview.env,
389
+ promptTemplate: DEFAULT_POST_COMPLETION_FINAL_REVIEW_PROMPT,
390
+ outputRetries: issueFinalReview.outputRetries
391
+ });
392
+ }
377
393
  function assertRepoRelativePath(value, location) {
378
394
  const normalized = normalize(value);
379
395
  if (isAbsolute(value) || isAbsolute(normalized) || normalized === ".." || normalized.startsWith(`..${sep}`)) {
@@ -432,6 +448,10 @@ function validateConfigSemantics(input) {
432
448
  target.strategy.issueFinalReview,
433
449
  `targets[${targetIndex}].strategy.issueFinalReview`
434
450
  );
451
+ assertStageAgentPath(
452
+ target.strategy.postCompletionFinalReview,
453
+ `targets[${targetIndex}].strategy.postCompletionFinalReview`
454
+ );
435
455
  assertStageAgentPath(
436
456
  target.strategy.finalize.prDescriptionAgent,
437
457
  `targets[${targetIndex}].strategy.finalize.prDescriptionAgent`
@@ -506,6 +526,10 @@ function normalizePourkitConfig(input) {
506
526
  ),
507
527
  maxAttempts: t.strategy.issueFinalReview.maxAttempts
508
528
  },
529
+ postCompletionFinalReview: applyPostCompletionFinalReviewDefaults(
530
+ t.strategy.postCompletionFinalReview,
531
+ t.strategy.issueFinalReview
532
+ ),
509
533
  finalize: {
510
534
  prDescriptionAgent: applyStageAgentDefaults(
511
535
  t.strategy.finalize.prDescriptionAgent
@@ -3772,7 +3796,7 @@ function validatePrdPlanWorkspace(options) {
3772
3796
  );
3773
3797
  }
3774
3798
  const children = [];
3775
- const CHILD_REF_PATTERN2 = /^\s*(I-0*\d+)\s*$/i;
3799
+ const CHILD_REF_PATTERN = /^\s*(I-0*\d+)\s*$/i;
3776
3800
  const BLOCKED_BY_SECTION_REGEX2 = /## Blocked by\s*\n([\s\S]*?)(?=\n## |$)/i;
3777
3801
  const PARENT_SECTION_REGEX2 = /## Parent\s*\n([\s\S]*?)(?=\n## |$)/i;
3778
3802
  for (const childFile of childFiles) {
@@ -3810,7 +3834,7 @@ function validatePrdPlanWorkspace(options) {
3810
3834
  if (!line) continue;
3811
3835
  for (const part of line.split(",")) {
3812
3836
  const trimmed = part.trim();
3813
- const match = trimmed.match(CHILD_REF_PATTERN2);
3837
+ const match = trimmed.match(CHILD_REF_PATTERN);
3814
3838
  if (match) {
3815
3839
  blockedByRefs.push(match[1].toUpperCase());
3816
3840
  }
@@ -4257,6 +4281,20 @@ var POST_COMPLETION_FINAL_REVIEW_ARTIFACT_PATH = join9(
4257
4281
  "post-completion-final-review",
4258
4282
  "agent-output.json"
4259
4283
  );
4284
+ var DEFAULT_POST_COMPLETION_FINAL_REVIEW_PROMPT2 = "post-completion-final-review.prompt.md";
4285
+ function resolvePostCompletionFinalReviewAgent(target) {
4286
+ const configured = target.strategy.postCompletionFinalReview;
4287
+ if (configured) return configured;
4288
+ const fallback = target.strategy.issueFinalReview;
4289
+ return {
4290
+ agent: fallback.agent,
4291
+ model: fallback.model,
4292
+ variant: fallback.variant,
4293
+ env: fallback.env,
4294
+ outputRetries: fallback.outputRetries,
4295
+ promptTemplate: DEFAULT_POST_COMPLETION_FINAL_REVIEW_PROMPT2
4296
+ };
4297
+ }
4260
4298
  async function runPostCompletionFinalReview(options) {
4261
4299
  const {
4262
4300
  executionProvider,
@@ -4308,9 +4346,10 @@ async function runPostCompletionFinalReview(options) {
4308
4346
  };
4309
4347
  }
4310
4348
  const strategy = target.strategy;
4311
- const agent = strategy.issueFinalReview;
4349
+ const agent = resolvePostCompletionFinalReviewAgent(target);
4312
4350
  const prompt = loadPostCompletionFinalReviewPrompt({
4313
4351
  repoRoot: repoRoot2,
4352
+ promptTemplate: agent.promptTemplate,
4314
4353
  sourceDocumentPath,
4315
4354
  completedBranch,
4316
4355
  validationCommand: `pourkit validate-artifact post-completion-final-review ${artifactPathInWorktree}`,
@@ -4452,11 +4491,14 @@ Completed branch: ${completedBranch}`,
4452
4491
  );
4453
4492
  }
4454
4493
  function loadPostCompletionFinalReviewPrompt(options) {
4455
- const { repoRoot: repoRoot2, sourceDocumentPath, completedBranch, validationCommand } = options;
4456
- const promptPath = resolvePromptTemplatePath(
4457
- repoRoot2,
4458
- "post-completion-final-review.prompt.md"
4459
- );
4494
+ const {
4495
+ repoRoot: repoRoot2,
4496
+ promptTemplate,
4497
+ sourceDocumentPath,
4498
+ completedBranch,
4499
+ validationCommand
4500
+ } = options;
4501
+ const promptPath = resolvePromptTemplatePath(repoRoot2, promptTemplate);
4460
4502
  const promptBody = existsSync9(promptPath) ? readFileSync8(promptPath, "utf-8") : `Review the completed branch against the source document.
4461
4503
 
4462
4504
  ## Source Document
@@ -8815,7 +8857,7 @@ import { isAbsolute as isAbsolute8, join as join22, relative as relative3, resol
8815
8857
  import { readFile as readFile5, readdir as readdir2 } from "fs/promises";
8816
8858
  import { join as join19 } from "path";
8817
8859
  var CHILD_FILE_PATTERN = /^I-0*(\d+)-.+\.md$/i;
8818
- var CHILD_REF_PATTERN = /^\s*(?:[-*]|\d+[.)])?\s*(I-0*\d+)\s*$/i;
8860
+ var CHILD_REF_REGEX = /\bI-0*(\d+)\b/gi;
8819
8861
  var BLOCKED_BY_SECTION_REGEX = /## Blocked by\s*\n([\s\S]*?)(?=\n## |$)/i;
8820
8862
  var PARENT_SECTION_REGEX = /## Parent\s*\n([\s\S]*?)(?=\n## |$)/i;
8821
8863
  function escapeRegExp2(value) {
@@ -8840,19 +8882,10 @@ function parseChildRefsFromBody(body) {
8840
8882
  const section = body.match(BLOCKED_BY_SECTION_REGEX)?.[1];
8841
8883
  if (!section) return [];
8842
8884
  const refs = [];
8843
- for (const rawLine of section.split("\n")) {
8844
- const line = rawLine.trim();
8845
- if (!line) continue;
8846
- const parts = line.split(",");
8847
- for (const part of parts) {
8848
- const trimmed = part.trim();
8849
- const match = trimmed.match(CHILD_REF_PATTERN);
8850
- if (match) {
8851
- refs.push(match[1].toUpperCase());
8852
- }
8853
- }
8885
+ for (const match of section.matchAll(CHILD_REF_REGEX)) {
8886
+ refs.push(`I-${match[1].padStart(2, "0")}`);
8854
8887
  }
8855
- return refs;
8888
+ return Array.from(new Set(refs));
8856
8889
  }
8857
8890
  function extractTitleBody(content) {
8858
8891
  const firstLine = content.split("\n")[0];
@@ -11099,10 +11132,11 @@ async function runPrdPlanWorkspacePublishCommand(options) {
11099
11132
 
11100
11133
  // commands/prd-run.ts
11101
11134
  import { lstatSync, realpathSync } from "fs";
11102
- import { join as join23 } from "path";
11135
+ import { join as join24 } from "path";
11103
11136
 
11104
11137
  // prd-run/coordinator.ts
11105
11138
  import { spawnSync as spawnSync2 } from "child_process";
11139
+ import { join as join23 } from "path";
11106
11140
  import { Match, pipe } from "effect";
11107
11141
  init_common();
11108
11142
 
@@ -11819,7 +11853,8 @@ function validatePrdRunTerminalEvidence(record, context) {
11819
11853
  humanReadableReason: `PRD Run ${context.prdRef} is missing proof that all child Issues finalized into ${context.prdBranch}.`,
11820
11854
  repairability: "operator-action",
11821
11855
  nextAction: "inspect-and-retry",
11822
- nextRecommendedCommand: "pourkit prd-run launch"
11856
+ nextRecommendedCommand: "pourkit prd-run launch",
11857
+ diagnostics: [...context.childFinalizationDiagnostics ?? []]
11823
11858
  })
11824
11859
  };
11825
11860
  }
@@ -11859,6 +11894,29 @@ async function claimReadyPrdChild(options) {
11859
11894
  }
11860
11895
  };
11861
11896
  }
11897
+ async function releaseClaimedPrdChild(options) {
11898
+ const result = await runBdJson({
11899
+ repoRoot: options.repoRoot,
11900
+ args: ["update", options.childId, "--status", "open", "--json"],
11901
+ logger: options.logger
11902
+ });
11903
+ const child = findReadyClaim(result);
11904
+ if (!child?.id) {
11905
+ return {
11906
+ ok: false,
11907
+ childId: options.childId,
11908
+ reason: `bd update ${options.childId} --status open returned no child.`
11909
+ };
11910
+ }
11911
+ return {
11912
+ ok: true,
11913
+ child: {
11914
+ id: child.id,
11915
+ title: child.title,
11916
+ metadata: child.metadata
11917
+ }
11918
+ };
11919
+ }
11862
11920
  function findReadyClaim(value) {
11863
11921
  if (!value) return void 0;
11864
11922
  if (Array.isArray(value)) return value.find((entry) => Boolean(entry.id));
@@ -13051,6 +13109,32 @@ async function reconcileBlockedBeadsIssueProjection(options) {
13051
13109
  }
13052
13110
  return refreshed;
13053
13111
  }
13112
+ async function releaseSkippedBlockedBeadsChildren(options) {
13113
+ for (const child of options.children) {
13114
+ let result;
13115
+ try {
13116
+ result = await releaseClaimedPrdChild({
13117
+ repoRoot: options.repoRoot,
13118
+ childId: child.id,
13119
+ logger: options.logger
13120
+ });
13121
+ } catch (error) {
13122
+ logCoordinatorStep(
13123
+ options.logger,
13124
+ "warn",
13125
+ `Failed to release skipped Beads child ${child.id}: ${error instanceof Error ? error.message : String(error)}`
13126
+ );
13127
+ continue;
13128
+ }
13129
+ if (!result.ok) {
13130
+ logCoordinatorStep(
13131
+ options.logger,
13132
+ "warn",
13133
+ `Failed to release skipped Beads child ${child.id}: ${result.reason}`
13134
+ );
13135
+ }
13136
+ }
13137
+ }
13054
13138
  function extractIssueFromQueueError(error) {
13055
13139
  if (!error || typeof error !== "object" || !("issue" in error)) {
13056
13140
  return void 0;
@@ -13199,6 +13283,105 @@ async function selectPrdRunCoordinatorMode(options) {
13199
13283
  })
13200
13284
  };
13201
13285
  }
13286
+ function escapeRegExp3(value) {
13287
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
13288
+ }
13289
+ function normalizeChildRef2(value) {
13290
+ const match = value.match(/^I-0*(\d+)$/i);
13291
+ if (!match) return null;
13292
+ return `I-${match[1].padStart(2, "0")}`;
13293
+ }
13294
+ function issueChildRef(prdRef, issue) {
13295
+ const match = issue.title.match(
13296
+ new RegExp(`^${escapeRegExp3(prdRef)}\\s*/\\s*(I-0*\\d+)\\s*:`, "i")
13297
+ );
13298
+ return match ? normalizeChildRef2(match[1]) : null;
13299
+ }
13300
+ function issueSummary(issue) {
13301
+ return `#${issue.number} ${issue.title}`;
13302
+ }
13303
+ async function readPlannedChildRefs(options) {
13304
+ const sourceDocument = await resolvePrdPostCompletionSourceDocument(options);
13305
+ if (!sourceDocument || sourceDocument.status !== "resolved") {
13306
+ return {
13307
+ ok: false,
13308
+ diagnostics: sourceDocument && sourceDocument.status === "blocked" ? [...sourceDocument.diagnostics] : [
13309
+ sourceDocument?.reason ?? `Unable to resolve source document for ${options.prdRef}.`
13310
+ ]
13311
+ };
13312
+ }
13313
+ const parsed = await parsePrdPlanWorkspace({
13314
+ workspacePath: join23(options.repoRoot, sourceDocument.workspacePath),
13315
+ prdRef: options.prdRef
13316
+ });
13317
+ if (!parsed.ok) {
13318
+ return {
13319
+ ok: false,
13320
+ diagnostics: parsed.diagnostics.map((diagnostic) => diagnostic.message)
13321
+ };
13322
+ }
13323
+ return {
13324
+ ok: true,
13325
+ childRefs: parsed.workspace.children.map((child) => child.childRef)
13326
+ };
13327
+ }
13328
+ async function verifyPrdChildFinalizationEvidence(options) {
13329
+ const diagnostics = [];
13330
+ const unfinalizedProcessed = options.processedResults.filter(
13331
+ (result) => !result.noOp && result.publicationStatus !== "merged"
13332
+ );
13333
+ if (unfinalizedProcessed.length > 0) {
13334
+ diagnostics.push(
13335
+ `Processed child Issues missing PRD Branch merge/no-op evidence: ${unfinalizedProcessed.map((result) => `#${result.issueNumber}`).join(", ")}.`
13336
+ );
13337
+ }
13338
+ let relatedIssues;
13339
+ try {
13340
+ relatedIssues = await options.issueProvider.listRelatedIssues(
13341
+ options.prdRef
13342
+ );
13343
+ } catch (error) {
13344
+ return {
13345
+ ok: false,
13346
+ diagnostics: [
13347
+ `Failed to list child Issues for ${options.prdRef}: ${error instanceof Error ? error.message : String(error)}`
13348
+ ]
13349
+ };
13350
+ }
13351
+ if (relatedIssues.length === 0) {
13352
+ diagnostics.push(`No child Issue projections found for ${options.prdRef}.`);
13353
+ }
13354
+ const planned = await readPlannedChildRefs({
13355
+ repoRoot: options.repoRoot,
13356
+ prdRef: options.prdRef
13357
+ });
13358
+ if (!planned.ok) {
13359
+ diagnostics.push(...planned.diagnostics);
13360
+ } else if (planned.childRefs.length === 0) {
13361
+ diagnostics.push(`No planned child Issues found for ${options.prdRef}.`);
13362
+ } else {
13363
+ const relatedRefs = new Set(
13364
+ relatedIssues.map((issue) => issueChildRef(options.prdRef, issue)).filter((ref) => ref !== null)
13365
+ );
13366
+ const missingRefs = planned.childRefs.filter(
13367
+ (ref) => !relatedRefs.has(ref)
13368
+ );
13369
+ if (missingRefs.length > 0) {
13370
+ diagnostics.push(
13371
+ `Planned child Issues without published Issue projections: ${missingRefs.join(", ")}.`
13372
+ );
13373
+ }
13374
+ }
13375
+ const openRelatedIssues = relatedIssues.filter(
13376
+ (issue) => issue.state !== "closed"
13377
+ );
13378
+ if (openRelatedIssues.length > 0) {
13379
+ diagnostics.push(
13380
+ `Child Issues still open: ${openRelatedIssues.map(issueSummary).join(", ")}.`
13381
+ );
13382
+ }
13383
+ return { ok: diagnostics.length === 0, diagnostics };
13384
+ }
13202
13385
  async function runPostCompletionAfterTerminal(options, prdRef, record, resumeFacts, startOutcome) {
13203
13386
  const receipt = record.postCompletionFinalReview;
13204
13387
  if (receipt?.status === "passed" || receipt?.status === "overridden") {
@@ -13758,17 +13941,25 @@ async function launchPrdRun(options) {
13758
13941
  logger: options.logger
13759
13942
  });
13760
13943
  }
13761
- if (currentRecord && startReceipt && activeRepairGuidance?.failureCode === "missing-child-finalization-evidence" && await prdParentIssueIsClosed({
13762
- issueProvider: options.issueProvider,
13944
+ const parentClosureIssueProvider = options.issueProvider;
13945
+ if (currentRecord && startReceipt && parentClosureIssueProvider && activeRepairGuidance?.failureCode === "missing-child-finalization-evidence" && await prdParentIssueIsClosed({
13946
+ issueProvider: parentClosureIssueProvider,
13763
13947
  prdRef,
13764
13948
  logger: options.logger
13765
13949
  })) {
13766
13950
  const prdBranch = startReceipt.prdBranch ?? prdRef;
13951
+ const childFinalizationEvidence = await verifyPrdChildFinalizationEvidence({
13952
+ repoRoot: options.repoRoot,
13953
+ prdRef,
13954
+ issueProvider: parentClosureIssueProvider,
13955
+ processedResults: []
13956
+ });
13767
13957
  const terminalEvidence = validatePrdRunTerminalEvidence(currentRecord, {
13768
13958
  prdRef,
13769
13959
  baseBranch: startReceipt.startBaseBranch,
13770
13960
  prdBranch,
13771
- allChildIssuesFinalizedIntoPrdBranch: true
13961
+ allChildIssuesFinalizedIntoPrdBranch: childFinalizationEvidence.ok,
13962
+ childFinalizationDiagnostics: childFinalizationEvidence.diagnostics
13772
13963
  });
13773
13964
  if (!terminalEvidence.ok) {
13774
13965
  return buildLaunchBlockedOutcome(
@@ -14002,11 +14193,22 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
14002
14193
  writeDrainedRecord(options.repoRoot, prdRef, startReceipt, targetName);
14003
14194
  const drainRecord = readPrdRun(options.repoRoot, prdRef).record;
14004
14195
  if (drainRecord) {
14196
+ const childFinalizationEvidence = await verifyPrdChildFinalizationEvidence({
14197
+ repoRoot: options.repoRoot,
14198
+ prdRef,
14199
+ issueProvider,
14200
+ processedResults: outcome.results.map((result2) => ({
14201
+ issueNumber: result2.selected.number,
14202
+ noOp: result2.runResult.noOp,
14203
+ publicationStatus: result2.runResult.publicationStatus
14204
+ }))
14205
+ });
14005
14206
  const drainContext = {
14006
14207
  prdRef,
14007
14208
  baseBranch: startReceipt.startBaseBranch,
14008
14209
  prdBranch,
14009
- allChildIssuesFinalizedIntoPrdBranch: outcome.allProcessedIssuesFinalizedIntoPrdBranch === true
14210
+ allChildIssuesFinalizedIntoPrdBranch: childFinalizationEvidence.ok,
14211
+ childFinalizationDiagnostics: childFinalizationEvidence.diagnostics
14010
14212
  };
14011
14213
  const terminalEvidence = validatePrdRunTerminalEvidence(
14012
14214
  drainRecord,
@@ -14267,6 +14469,7 @@ async function launchBeadsQueueDrain(options, prdRef, startReceipt, targetName,
14267
14469
  const executionProvider = options.executionProvider;
14268
14470
  const logger = options.logger;
14269
14471
  const processedResults = [];
14472
+ const skippedBlockedBeadsChildren = [];
14270
14473
  const originalGuidance = readPrdRun(options.repoRoot, prdRef).record?.repairGuidance;
14271
14474
  logCoordinatorStep(
14272
14475
  logger,
@@ -14365,33 +14568,42 @@ async function launchBeadsQueueDrain(options, prdRef, startReceipt, targetName,
14365
14568
  prdRef,
14366
14569
  logger
14367
14570
  });
14368
- logCoordinatorStep(
14369
- logger,
14370
- "info",
14371
- `Running GitHub Issue #${issue.number} from Beads child ${contextResult.beads.childId}.`
14372
- );
14373
- const runResult = await runClaimedPrdIssueCommand({
14374
- targetName,
14375
- config: options.config,
14376
- issueProvider,
14377
- prProvider,
14378
- executionProvider,
14379
- force: false,
14380
- logger,
14381
- repoRoot: options.repoRoot,
14382
- issue,
14383
- queueRunContext: {
14384
- prdRef,
14385
- prdBranch: startReceipt.prdBranch,
14386
- beadsChild: contextResult.beads
14387
- }
14388
- });
14389
- processedResults.push({
14390
- beadsChildId: contextResult.beads.childId,
14391
- issueNumber: runResult.selected.number,
14392
- noOp: runResult.runResult.noOp,
14393
- publicationStatus: runResult.runResult.publicationStatus
14394
- });
14571
+ if (issue.labels.includes(options.config.labels.blocked)) {
14572
+ logCoordinatorStep(
14573
+ logger,
14574
+ "info",
14575
+ `Skipping Beads child ${contextResult.beads.childId} because GitHub Issue #${issue.number} remains labeled ${options.config.labels.blocked}.`
14576
+ );
14577
+ skippedBlockedBeadsChildren.push(readResult.child);
14578
+ } else {
14579
+ logCoordinatorStep(
14580
+ logger,
14581
+ "info",
14582
+ `Running GitHub Issue #${issue.number} from Beads child ${contextResult.beads.childId}.`
14583
+ );
14584
+ const runResult = await runClaimedPrdIssueCommand({
14585
+ targetName,
14586
+ config: options.config,
14587
+ issueProvider,
14588
+ prProvider,
14589
+ executionProvider,
14590
+ force: false,
14591
+ logger,
14592
+ repoRoot: options.repoRoot,
14593
+ issue,
14594
+ queueRunContext: {
14595
+ prdRef,
14596
+ prdBranch: startReceipt.prdBranch,
14597
+ beadsChild: contextResult.beads
14598
+ }
14599
+ });
14600
+ processedResults.push({
14601
+ beadsChildId: contextResult.beads.childId,
14602
+ issueNumber: runResult.selected.number,
14603
+ noOp: runResult.runResult.noOp,
14604
+ publicationStatus: runResult.runResult.publicationStatus
14605
+ });
14606
+ }
14395
14607
  } catch (error) {
14396
14608
  const msg = error instanceof Error ? error.message : String(error);
14397
14609
  const repair = buildQueueIssueRunRepairMetadata(
@@ -14469,30 +14681,52 @@ async function launchBeadsQueueDrain(options, prdRef, startReceipt, targetName,
14469
14681
  prdRef,
14470
14682
  logger
14471
14683
  });
14472
- const runResult = await runClaimedPrdIssueCommand({
14473
- targetName,
14474
- config: options.config,
14475
- issueProvider,
14476
- prProvider,
14477
- executionProvider,
14478
- force: false,
14479
- logger,
14480
- repoRoot: options.repoRoot,
14481
- issue: fetchedIssue,
14482
- queueRunContext: {
14483
- prdRef,
14484
- prdBranch: startReceipt.prdBranch,
14485
- ...resumeBeadsContext ? { beadsChild: resumeBeadsContext } : {}
14684
+ if (fetchedIssue.labels.includes(options.config.labels.blocked)) {
14685
+ logCoordinatorStep(
14686
+ logger,
14687
+ "info",
14688
+ `Skipping resume issue #${fetchedIssue.number} because it remains labeled ${options.config.labels.blocked}; selecting another Beads-ready child.`
14689
+ );
14690
+ if (resumeBeadsContext) {
14691
+ skippedBlockedBeadsChildren.push({
14692
+ id: resumeBeadsContext.childId,
14693
+ title: fetchedIssue.title,
14694
+ metadata: {
14695
+ pourkit: {
14696
+ prdRef,
14697
+ childRef: resumeBeadsContext.childRef,
14698
+ githubIssueNumber: resumeIssueNumber
14699
+ }
14700
+ }
14701
+ });
14486
14702
  }
14487
- });
14488
- processedResults.push({
14489
- beadsChildId: resumeIssue?.beadsChildId ?? "resumed",
14490
- issueNumber: runResult.selected.number,
14491
- noOp: runResult.runResult.noOp,
14492
- publicationStatus: runResult.runResult.publicationStatus
14493
- });
14494
- startReceipt.queueDrainedAt = (/* @__PURE__ */ new Date()).toISOString();
14495
- startReceipt.queueProcessedCount = processedResults.length;
14703
+ resumeIssueNumber = void 0;
14704
+ } else {
14705
+ const runResult = await runClaimedPrdIssueCommand({
14706
+ targetName,
14707
+ config: options.config,
14708
+ issueProvider,
14709
+ prProvider,
14710
+ executionProvider,
14711
+ force: false,
14712
+ logger,
14713
+ repoRoot: options.repoRoot,
14714
+ issue: fetchedIssue,
14715
+ queueRunContext: {
14716
+ prdRef,
14717
+ prdBranch: startReceipt.prdBranch,
14718
+ ...resumeBeadsContext ? { beadsChild: resumeBeadsContext } : {}
14719
+ }
14720
+ });
14721
+ processedResults.push({
14722
+ beadsChildId: resumeIssue?.beadsChildId ?? "resumed",
14723
+ issueNumber: runResult.selected.number,
14724
+ noOp: runResult.runResult.noOp,
14725
+ publicationStatus: runResult.runResult.publicationStatus
14726
+ });
14727
+ startReceipt.queueDrainedAt = (/* @__PURE__ */ new Date()).toISOString();
14728
+ startReceipt.queueProcessedCount = processedResults.length;
14729
+ }
14496
14730
  } catch (error) {
14497
14731
  const msg = error instanceof Error ? error.message : String(error);
14498
14732
  const repair = buildQueueIssueRunRepairMetadata(
@@ -14528,143 +14762,160 @@ async function launchBeadsQueueDrain(options, prdRef, startReceipt, targetName,
14528
14762
  }
14529
14763
  }
14530
14764
  let beadsClaimAttempted = false;
14531
- while (true) {
14532
- const claimResult = await claimReadyPrdChild({
14533
- repoRoot: options.repoRoot,
14534
- prdRef,
14535
- logger
14536
- });
14537
- if (!claimResult.ok) {
14538
- if (claimResult.reason === "no-ready-child") {
14539
- logCoordinatorStep(
14540
- logger,
14541
- "info",
14542
- `Beads-backed PRD queue drain for ${prdRef} found no additional ready child work.`
14543
- );
14544
- break;
14545
- }
14546
- return buildLaunchBlockedOutcome(
14547
- options.repoRoot,
14548
- prdRef,
14549
- buildPrdRunRepairGuidance({
14550
- blockedGate: "queue",
14551
- blockedStage: "queue-drain",
14552
- failureCode: "beads-claim-failed",
14553
- humanReadableReason: `Beads claim failed for PRD ${prdRef} epic ${claimResult.epicId}.`,
14554
- repairability: "operator-action",
14555
- nextAction: "inspect-and-retry",
14556
- nextRecommendedCommand: `pourkit prd-run status ${prdRef}`,
14557
- diagnostics: [`Beads claim error for epic ${claimResult.epicId}.`]
14558
- }),
14559
- plan,
14560
- startOutcome,
14561
- targetName,
14562
- startReceipt
14563
- );
14564
- }
14565
- beadsClaimAttempted = true;
14566
- logCoordinatorStep(
14567
- logger,
14568
- "info",
14569
- `Claimed Beads child ${claimResult.child.id} for ${prdRef}; mapping to GitHub Issue context.`
14570
- );
14571
- const contextResult = await buildIssueContextFromBeadsChild({
14572
- child: claimResult.child,
14573
- issueProvider,
14574
- expectedPrdRef: prdRef
14575
- });
14576
- if (!contextResult.ok) {
14577
- return buildLaunchBlockedOutcome(
14578
- options.repoRoot,
14579
- prdRef,
14580
- buildPrdRunRepairGuidance({
14581
- blockedGate: "queue",
14582
- blockedStage: "queue-drain",
14583
- failureCode: "beads-context-mapping-failed",
14584
- humanReadableReason: `Failed to map Beads child ${claimResult.child.id} to Issue context: ${contextResult.reason}`,
14585
- repairability: "operator-action",
14586
- nextAction: "inspect-and-retry",
14587
- nextRecommendedCommand: `pourkit prd-run status ${prdRef}`,
14588
- diagnostics: [contextResult.reason],
14589
- issue: claimedBeadsChildRepairIssue(claimResult.child)
14590
- }),
14591
- plan,
14592
- startOutcome,
14593
- targetName,
14594
- startReceipt
14595
- );
14596
- }
14597
- try {
14598
- const issue = await reconcileBlockedBeadsIssueProjection({
14599
- issue: contextResult.issue,
14600
- issueProvider,
14601
- config: options.config,
14765
+ try {
14766
+ while (true) {
14767
+ const claimResult = await claimReadyPrdChild({
14768
+ repoRoot: options.repoRoot,
14602
14769
  prdRef,
14603
14770
  logger
14604
14771
  });
14772
+ if (!claimResult.ok) {
14773
+ if (claimResult.reason === "no-ready-child") {
14774
+ logCoordinatorStep(
14775
+ logger,
14776
+ "info",
14777
+ `Beads-backed PRD queue drain for ${prdRef} found no additional ready child work.`
14778
+ );
14779
+ break;
14780
+ }
14781
+ return buildLaunchBlockedOutcome(
14782
+ options.repoRoot,
14783
+ prdRef,
14784
+ buildPrdRunRepairGuidance({
14785
+ blockedGate: "queue",
14786
+ blockedStage: "queue-drain",
14787
+ failureCode: "beads-claim-failed",
14788
+ humanReadableReason: `Beads claim failed for PRD ${prdRef} epic ${claimResult.epicId}.`,
14789
+ repairability: "operator-action",
14790
+ nextAction: "inspect-and-retry",
14791
+ nextRecommendedCommand: `pourkit prd-run status ${prdRef}`,
14792
+ diagnostics: [`Beads claim error for epic ${claimResult.epicId}.`]
14793
+ }),
14794
+ plan,
14795
+ startOutcome,
14796
+ targetName,
14797
+ startReceipt
14798
+ );
14799
+ }
14605
14800
  logCoordinatorStep(
14606
14801
  logger,
14607
14802
  "info",
14608
- `Running GitHub Issue #${issue.number} from Beads child ${contextResult.beads.childId}.`
14803
+ `Claimed Beads child ${claimResult.child.id} for ${prdRef}; mapping to GitHub Issue context.`
14609
14804
  );
14610
- const runResult = await runClaimedPrdIssueCommand({
14611
- targetName,
14612
- config: options.config,
14805
+ const contextResult = await buildIssueContextFromBeadsChild({
14806
+ child: claimResult.child,
14613
14807
  issueProvider,
14614
- prProvider,
14615
- executionProvider,
14616
- force: false,
14617
- logger,
14618
- repoRoot: options.repoRoot,
14619
- issue,
14620
- queueRunContext: {
14808
+ expectedPrdRef: prdRef
14809
+ });
14810
+ if (!contextResult.ok) {
14811
+ return buildLaunchBlockedOutcome(
14812
+ options.repoRoot,
14621
14813
  prdRef,
14622
- prdBranch: startReceipt.prdBranch,
14623
- beadsChild: contextResult.beads
14814
+ buildPrdRunRepairGuidance({
14815
+ blockedGate: "queue",
14816
+ blockedStage: "queue-drain",
14817
+ failureCode: "beads-context-mapping-failed",
14818
+ humanReadableReason: `Failed to map Beads child ${claimResult.child.id} to Issue context: ${contextResult.reason}`,
14819
+ repairability: "operator-action",
14820
+ nextAction: "inspect-and-retry",
14821
+ nextRecommendedCommand: `pourkit prd-run status ${prdRef}`,
14822
+ diagnostics: [contextResult.reason],
14823
+ issue: claimedBeadsChildRepairIssue(claimResult.child)
14824
+ }),
14825
+ plan,
14826
+ startOutcome,
14827
+ targetName,
14828
+ startReceipt
14829
+ );
14830
+ }
14831
+ try {
14832
+ const issue = await reconcileBlockedBeadsIssueProjection({
14833
+ issue: contextResult.issue,
14834
+ issueProvider,
14835
+ config: options.config,
14836
+ prdRef,
14837
+ logger
14838
+ });
14839
+ if (issue.labels.includes(options.config.labels.blocked)) {
14840
+ logCoordinatorStep(
14841
+ logger,
14842
+ "info",
14843
+ `Skipping Beads child ${contextResult.beads.childId} because GitHub Issue #${issue.number} remains labeled ${options.config.labels.blocked}.`
14844
+ );
14845
+ skippedBlockedBeadsChildren.push(claimResult.child);
14846
+ continue;
14624
14847
  }
14625
- });
14626
- processedResults.push({
14627
- beadsChildId: claimResult.child.id,
14628
- issueNumber: runResult.selected.number,
14629
- noOp: runResult.runResult.noOp,
14630
- publicationStatus: runResult.runResult.publicationStatus
14631
- });
14632
- } catch (error) {
14633
- const msg = error instanceof Error ? error.message : String(error);
14634
- const repair = buildQueueIssueRunRepairMetadata(
14635
- msg,
14636
- "beads-issue-run-failed",
14637
- prdRef
14638
- );
14639
- const beadsChildClosed = msg.startsWith(
14640
- "Projection failure after Beads close"
14641
- );
14642
- return buildLaunchBlockedOutcome(
14643
- options.repoRoot,
14644
- prdRef,
14645
- buildPrdRunRepairGuidance({
14646
- blockedGate: "queue",
14647
- blockedStage: "queue-drain",
14648
- failureCode: repair.failureCode,
14649
- humanReadableReason: msg,
14650
- repairability: repair.repairability,
14651
- nextAction: repair.nextAction,
14652
- nextRecommendedCommand: repair.nextRecommendedCommand,
14653
- diagnostics: [msg],
14654
- issue: {
14655
- number: contextResult.issue.number,
14656
- title: contextResult.issue.title,
14657
- beadsChildId: contextResult.beads.childId,
14658
- beadsChildRef: contextResult.beads.childRef,
14659
- beadsChildClosed
14848
+ beadsClaimAttempted = true;
14849
+ logCoordinatorStep(
14850
+ logger,
14851
+ "info",
14852
+ `Running GitHub Issue #${issue.number} from Beads child ${contextResult.beads.childId}.`
14853
+ );
14854
+ const runResult = await runClaimedPrdIssueCommand({
14855
+ targetName,
14856
+ config: options.config,
14857
+ issueProvider,
14858
+ prProvider,
14859
+ executionProvider,
14860
+ force: false,
14861
+ logger,
14862
+ repoRoot: options.repoRoot,
14863
+ issue,
14864
+ queueRunContext: {
14865
+ prdRef,
14866
+ prdBranch: startReceipt.prdBranch,
14867
+ beadsChild: contextResult.beads
14660
14868
  }
14661
- }),
14662
- plan,
14663
- startOutcome,
14664
- targetName,
14665
- startReceipt
14666
- );
14869
+ });
14870
+ processedResults.push({
14871
+ beadsChildId: claimResult.child.id,
14872
+ issueNumber: runResult.selected.number,
14873
+ noOp: runResult.runResult.noOp,
14874
+ publicationStatus: runResult.runResult.publicationStatus
14875
+ });
14876
+ } catch (error) {
14877
+ const msg = error instanceof Error ? error.message : String(error);
14878
+ const repair = buildQueueIssueRunRepairMetadata(
14879
+ msg,
14880
+ "beads-issue-run-failed",
14881
+ prdRef
14882
+ );
14883
+ const beadsChildClosed = msg.startsWith(
14884
+ "Projection failure after Beads close"
14885
+ );
14886
+ return buildLaunchBlockedOutcome(
14887
+ options.repoRoot,
14888
+ prdRef,
14889
+ buildPrdRunRepairGuidance({
14890
+ blockedGate: "queue",
14891
+ blockedStage: "queue-drain",
14892
+ failureCode: repair.failureCode,
14893
+ humanReadableReason: msg,
14894
+ repairability: repair.repairability,
14895
+ nextAction: repair.nextAction,
14896
+ nextRecommendedCommand: repair.nextRecommendedCommand,
14897
+ diagnostics: [msg],
14898
+ issue: {
14899
+ number: contextResult.issue.number,
14900
+ title: contextResult.issue.title,
14901
+ beadsChildId: contextResult.beads.childId,
14902
+ beadsChildRef: contextResult.beads.childRef,
14903
+ beadsChildClosed
14904
+ }
14905
+ }),
14906
+ plan,
14907
+ startOutcome,
14908
+ targetName,
14909
+ startReceipt
14910
+ );
14911
+ }
14667
14912
  }
14913
+ } finally {
14914
+ await releaseSkippedBlockedBeadsChildren({
14915
+ repoRoot: options.repoRoot,
14916
+ children: skippedBlockedBeadsChildren,
14917
+ logger
14918
+ });
14668
14919
  }
14669
14920
  if (processedResults.length === 0 && !beadsClaimAttempted) {
14670
14921
  const diagnostics = [
@@ -14712,13 +14963,18 @@ async function launchBeadsQueueDrain(options, prdRef, startReceipt, targetName,
14712
14963
  writeDrainedRecord(options.repoRoot, prdRef, startReceipt, targetName);
14713
14964
  const drainRecord = readPrdRun(options.repoRoot, prdRef).record;
14714
14965
  if (drainRecord) {
14966
+ const childFinalizationEvidence = await verifyPrdChildFinalizationEvidence({
14967
+ repoRoot: options.repoRoot,
14968
+ prdRef,
14969
+ issueProvider,
14970
+ processedResults
14971
+ });
14715
14972
  const drainContext = {
14716
14973
  prdRef,
14717
14974
  baseBranch: startReceipt.startBaseBranch,
14718
14975
  prdBranch,
14719
- allChildIssuesFinalizedIntoPrdBranch: processedResults.length > 0 && processedResults.every(
14720
- (r) => r.noOp || r.publicationStatus === "merged"
14721
- )
14976
+ allChildIssuesFinalizedIntoPrdBranch: childFinalizationEvidence.ok,
14977
+ childFinalizationDiagnostics: childFinalizationEvidence.diagnostics
14722
14978
  };
14723
14979
  const terminalEvidence = validatePrdRunTerminalEvidence(
14724
14980
  drainRecord,
@@ -15675,12 +15931,12 @@ icm --db .pourkit/icm/memories.db topics # list a
15675
15931
  var MANAGED_BLOCK_BEGIN = "<!-- BEGIN POURKIT MANAGED BLOCK -->";
15676
15932
  var MANAGED_BLOCK_END = "<!-- END POURKIT MANAGED BLOCK -->";
15677
15933
  var MANAGED_BLOCK_PATTERN = new RegExp(
15678
- `${escapeRegExp3(MANAGED_BLOCK_BEGIN)}\\r?\\n[\\s\\S]*?${escapeRegExp3(
15934
+ `${escapeRegExp4(MANAGED_BLOCK_BEGIN)}\\r?\\n[\\s\\S]*?${escapeRegExp4(
15679
15935
  MANAGED_BLOCK_END
15680
15936
  )}[ \\t]*(?:\\r?\\n)?`,
15681
15937
  "g"
15682
15938
  );
15683
- function escapeRegExp3(value) {
15939
+ function escapeRegExp4(value) {
15684
15940
  return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
15685
15941
  }
15686
15942
  function buildManagedBlock(content) {
@@ -15895,6 +16151,12 @@ function generateConfigTemplate(options) {
15895
16151
  promptTemplate: ".pourkit/managed/prompts/issue-final-review.prompt.md",
15896
16152
  maxAttempts: 3
15897
16153
  },
16154
+ postCompletionFinalReview: {
16155
+ agent: "pourkit-reviewer",
16156
+ model: "openai/gpt-5.5",
16157
+ variant: "max",
16158
+ promptTemplate: ".pourkit/managed/prompts/post-completion-final-review.prompt.md"
16159
+ },
15898
16160
  finalize: {
15899
16161
  prDescriptionAgent: {
15900
16162
  agent: "pourkit-pr-description",
@@ -15915,7 +16177,7 @@ function generateConfigTemplate(options) {
15915
16177
  };
15916
16178
  const config = {
15917
16179
  $schema: "./schema/pourkit.schema.json",
15918
- schemaVersion: 3,
16180
+ schemaVersion: 4,
15919
16181
  targets: [target],
15920
16182
  workflowPack: {
15921
16183
  version: "1.0.0",
@@ -17858,13 +18120,13 @@ Init applied: ${result.applied} operations applied, ${result.skipped} skipped.`
17858
18120
  // commands/memory-init.ts
17859
18121
  import { existsSync as existsSync20, mkdirSync as mkdirSync8, readFileSync as readFileSync19, writeFileSync as writeFileSync5 } from "fs";
17860
18122
  import { execFile as execFile3 } from "child_process";
17861
- import { join as join24 } from "path";
18123
+ import { join as join25 } from "path";
17862
18124
  import { promisify as promisify3 } from "util";
17863
18125
  var execFileAsync3 = promisify3(execFile3);
17864
18126
  async function runMemoryInitCommand(options) {
17865
18127
  const cwd = options.cwd ?? process.cwd();
17866
18128
  const execCommand = options.execCommand ?? execFileAsync3;
17867
- const configPath = join24(cwd, ".pourkit", "config.json");
18129
+ const configPath = join25(cwd, ".pourkit", "config.json");
17868
18130
  if (!existsSync20(configPath)) {
17869
18131
  return {
17870
18132
  ok: false,
@@ -17896,8 +18158,8 @@ async function runMemoryInitCommand(options) {
17896
18158
  const next = { ...raw, memory };
17897
18159
  writeFileSync5(configPath, JSON.stringify(next, null, 2) + "\n");
17898
18160
  }
17899
- const memoryDir = join24(cwd, ".pourkit", "icm");
17900
- const memoryDbPath = join24(memoryDir, "memories.db");
18161
+ const memoryDir = join25(cwd, ".pourkit", "icm");
18162
+ const memoryDbPath = join25(memoryDir, "memories.db");
17901
18163
  mkdirSync8(memoryDir, { recursive: true });
17902
18164
  let dbInitialized = false;
17903
18165
  let warning;
@@ -17911,7 +18173,7 @@ async function runMemoryInitCommand(options) {
17911
18173
  } catch {
17912
18174
  warning = "ICM is not available or could not initialize .pourkit/icm/memories.db. Install ICM and run `pourkit doctor` to verify repo-scoped memory setup.";
17913
18175
  }
17914
- const gitignorePath = join24(cwd, ".gitignore");
18176
+ const gitignorePath = join25(cwd, ".gitignore");
17915
18177
  updateManagedBlockSync(gitignorePath, generateGitignoreBlock());
17916
18178
  const managed = await generateManagedAgentInstructions({
17917
18179
  sourceRoot: cwd,
@@ -17919,14 +18181,14 @@ async function runMemoryInitCommand(options) {
17919
18181
  });
17920
18182
  let updatedAgentFile = false;
17921
18183
  for (const fileName of ["AGENTS.md", "CLAUDE.md"]) {
17922
- const agentPath = join24(cwd, fileName);
18184
+ const agentPath = join25(cwd, fileName);
17923
18185
  if (existsSync20(agentPath)) {
17924
18186
  updateManagedBlockSync(agentPath, managed);
17925
18187
  updatedAgentFile = true;
17926
18188
  }
17927
18189
  }
17928
18190
  if (!updatedAgentFile) {
17929
- updateManagedBlockSync(join24(cwd, "AGENTS.md"), managed);
18191
+ updateManagedBlockSync(join25(cwd, "AGENTS.md"), managed);
17930
18192
  }
17931
18193
  return {
17932
18194
  ok: true,
@@ -20198,7 +20460,7 @@ init_common();
20198
20460
 
20199
20461
  // execution/sandcastle-execution.ts
20200
20462
  import { existsSync as existsSync24, mkdirSync as mkdirSync9, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
20201
- import { join as join27 } from "path";
20463
+ import { join as join28 } from "path";
20202
20464
  import { createWorktree, opencode } from "@ai-hero/sandcastle";
20203
20465
  import { docker } from "@ai-hero/sandcastle/sandboxes/docker";
20204
20466
 
@@ -20207,10 +20469,10 @@ init_common();
20207
20469
  import { mkdtempSync } from "fs";
20208
20470
  import { writeFile as writeFile5 } from "fs/promises";
20209
20471
  import { tmpdir } from "os";
20210
- import { dirname as dirname8, join as join25 } from "path";
20472
+ import { dirname as dirname8, join as join26 } from "path";
20211
20473
  async function writeExecutionArtifacts(worktreePath, artifacts) {
20212
20474
  for (const artifact of artifacts) {
20213
- const filePath = join25(worktreePath, artifact.path);
20475
+ const filePath = join26(worktreePath, artifact.path);
20214
20476
  await ensureDir(dirname8(filePath));
20215
20477
  await writeFile5(filePath, artifact.content, "utf-8");
20216
20478
  }
@@ -20272,7 +20534,7 @@ async function createSandboxFromExistingWorktree(options) {
20272
20534
  }
20273
20535
 
20274
20536
  // execution/sandbox-options.ts
20275
- import { join as join26 } from "path";
20537
+ import { join as join27 } from "path";
20276
20538
  var POURKIT_ICM_CONTAINER_DIR = "/home/agent/.pourkit/icm";
20277
20539
  function buildSandboxOptions(repoRoot2, sandbox, memory) {
20278
20540
  const mounts = [];
@@ -20281,12 +20543,12 @@ function buildSandboxOptions(repoRoot2, sandbox, memory) {
20281
20543
  }
20282
20544
  if (memory?.available) {
20283
20545
  mounts.push({
20284
- hostPath: join26(repoRoot2, ".pourkit", "icm"),
20546
+ hostPath: join27(repoRoot2, ".pourkit", "icm"),
20285
20547
  sandboxPath: POURKIT_ICM_CONTAINER_DIR,
20286
20548
  readonly: false
20287
20549
  });
20288
20550
  mounts.push({
20289
- hostPath: join26(repoRoot2, ".pourkit", "icm", "cache"),
20551
+ hostPath: join27(repoRoot2, ".pourkit", "icm", "cache"),
20290
20552
  sandboxPath: "/home/agent/.cache/icm",
20291
20553
  readonly: false
20292
20554
  });
@@ -20420,13 +20682,13 @@ var SandcastleExecutionSession = class {
20420
20682
  "Memory enabled but memory context is invalid. Run `pourkit memory init` or install ICM for host planning use."
20421
20683
  );
20422
20684
  }
20423
- const hostMemoryDir = join27(repoRoot2, ".pourkit", "icm");
20685
+ const hostMemoryDir = join28(repoRoot2, ".pourkit", "icm");
20424
20686
  if (!existsSync24(hostMemoryDir) || !statSync2(hostMemoryDir).isDirectory()) {
20425
20687
  throw new MissingHostMemoryDirError(
20426
20688
  "Memory enabled but host .pourkit/icm/ directory is missing. Run `pourkit memory init` to create the repo-scoped memory store."
20427
20689
  );
20428
20690
  }
20429
- mkdirSync9(join27(hostMemoryDir, "cache"), { recursive: true });
20691
+ mkdirSync9(join28(hostMemoryDir, "cache"), { recursive: true });
20430
20692
  }
20431
20693
  const sandboxOptions = buildSandboxOptions(
20432
20694
  repoRoot2,
@@ -20585,7 +20847,7 @@ function sanitizeBranch(branchName) {
20585
20847
  }
20586
20848
  function safeCopyToWorktreePaths(paths, repoRoot2, worktreePath) {
20587
20849
  return paths.filter((relativePath) => {
20588
- const source = join27(repoRoot2, relativePath);
20850
+ const source = join28(repoRoot2, relativePath);
20589
20851
  if (!existsSync24(source)) {
20590
20852
  return true;
20591
20853
  }
@@ -20596,7 +20858,7 @@ function safeCopyToWorktreePaths(paths, repoRoot2, worktreePath) {
20596
20858
  } catch {
20597
20859
  return true;
20598
20860
  }
20599
- const destination = join27(worktreePath, relativePath);
20861
+ const destination = join28(worktreePath, relativePath);
20600
20862
  return !existsSync24(destination);
20601
20863
  });
20602
20864
  }
@@ -20661,12 +20923,12 @@ function isPlainObject(value) {
20661
20923
  return typeof value === "object" && value !== null && !Array.isArray(value);
20662
20924
  }
20663
20925
  function savePromptToFile(repoRoot2, stage, iteration, prompt) {
20664
- const promptsDir = join27(repoRoot2, ".pourkit", ".tmp", "prompts");
20926
+ const promptsDir = join28(repoRoot2, ".pourkit", ".tmp", "prompts");
20665
20927
  mkdirSync9(promptsDir, { recursive: true });
20666
20928
  const timestamp2 = Date.now();
20667
20929
  const iterationSuffix = iteration !== void 0 ? `-iteration-${iteration}` : "";
20668
20930
  const filename = `${stage}${iterationSuffix}-${timestamp2}.md`;
20669
- const filePath = join27(promptsDir, filename);
20931
+ const filePath = join28(promptsDir, filename);
20670
20932
  writeFileSync6(filePath, prompt, "utf-8");
20671
20933
  }
20672
20934
 
@@ -21450,11 +21712,11 @@ function createCliProgram(version) {
21450
21712
  return program;
21451
21713
  }
21452
21714
  async function resolveCliVersion() {
21453
- if (isPackageVersion("0.0.0-next-20260714055657")) {
21454
- return "0.0.0-next-20260714055657";
21715
+ if (isPackageVersion("0.0.0-next-20260715085442")) {
21716
+ return "0.0.0-next-20260715085442";
21455
21717
  }
21456
- if (isReleaseVersion("0.0.0-next-20260714055657")) {
21457
- return "0.0.0-next-20260714055657";
21718
+ if (isReleaseVersion("0.0.0-next-20260715085442")) {
21719
+ return "0.0.0-next-20260715085442";
21458
21720
  }
21459
21721
  try {
21460
21722
  const root = repoRoot();