@pourkit/cli 0.0.0-next-20260614074434 → 0.0.0-next-20260614201555

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
@@ -153,6 +153,7 @@ __export(common_exports, {
153
153
  execJson: () => execJson,
154
154
  parseWorktreeListPorcelain: () => parseWorktreeListPorcelain,
155
155
  readMaybeEnvInt: () => readMaybeEnvInt,
156
+ redactSensitiveValues: () => redactSensitiveValues,
156
157
  repoRelative: () => repoRelative,
157
158
  repoRoot: () => repoRoot,
158
159
  sleep: () => sleep,
@@ -311,7 +312,14 @@ function parseWorktreeListPorcelain(text2, branch) {
311
312
  }
312
313
  return null;
313
314
  }
314
- var execFileAsync, TRANSIENT_GH_ERROR, TYPE_LABELS;
315
+ function redactSensitiveValues(input) {
316
+ let redacted = input;
317
+ for (const pattern of TOKEN_LIKE_PATTERNS) {
318
+ redacted = redacted.replace(pattern, "[REDACTED]");
319
+ }
320
+ return redacted;
321
+ }
322
+ var execFileAsync, TRANSIENT_GH_ERROR, TYPE_LABELS, TOKEN_LIKE_PATTERNS;
315
323
  var init_common = __esm({
316
324
  "shared/common.ts"() {
317
325
  "use strict";
@@ -325,6 +333,16 @@ var init_common = __esm({
325
333
  "type:polish",
326
334
  "type:refactor"
327
335
  ];
336
+ TOKEN_LIKE_PATTERNS = [
337
+ /gh[ps]_[A-Za-z0-9]{20,}/g,
338
+ /token[=:_\s][A-Za-z0-9_-]{20,}/gi,
339
+ /secret[=:_\s][A-Za-z0-9_-]{20,}/gi,
340
+ /credential[=:_\s][A-Za-z0-9_-]{20,}/gi,
341
+ /key[=:_\s][A-Za-z0-9_-]{20,}/gi,
342
+ /bearer\s+[A-Za-z0-9_-]{20,}/gi,
343
+ /authorization:\s*Bearer\s+[A-Za-z0-9_-]{20,}/gi,
344
+ /xox[baprs]-[A-Za-z0-9_-]{10,}/g
345
+ ];
328
346
  }
329
347
  });
330
348
 
@@ -335,13 +353,20 @@ import { pathToFileURL } from "url";
335
353
  import { Command, Option, CommanderError } from "commander";
336
354
 
337
355
  // shared/config.ts
338
- import { readFileSync } from "fs";
356
+ import { existsSync, readFileSync } from "fs";
339
357
  import { fileURLToPath } from "url";
340
358
  import { dirname, isAbsolute, join, normalize, sep, resolve } from "path";
341
359
  import Ajv from "ajv";
342
360
  var __filename = fileURLToPath(import.meta.url);
343
361
  var __dirname = dirname(__filename);
344
- var SCHEMA_PATH = resolve(__dirname, "../schema/pourkit.schema.json");
362
+ function resolvePackagedAssetPath(fileName) {
363
+ const candidates = [
364
+ resolve(__dirname, "schema", fileName),
365
+ resolve(__dirname, "../schema", fileName)
366
+ ];
367
+ return candidates.find((candidate) => existsSync(candidate)) ?? candidates[0];
368
+ }
369
+ var SCHEMA_PATH = resolvePackagedAssetPath("pourkit.schema.json");
345
370
  var _schema = null;
346
371
  var _validate = null;
347
372
  var _ajvErrors = null;
@@ -929,12 +954,12 @@ function resolveTarget(config, explicitTarget) {
929
954
  init_common();
930
955
 
931
956
  // shared/worktree-run-state.ts
932
- import { existsSync, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
957
+ import { existsSync as existsSync2, mkdirSync as mkdirSync2, readFileSync as readFileSync2, writeFileSync } from "fs";
933
958
  import { dirname as dirname2, join as join2 } from "path";
934
959
  var WORKTREE_RUN_STATE_PATH = ".pourkit/state.json";
935
960
  function readWorktreeRunState(worktreePath) {
936
961
  const statePath = join2(worktreePath, WORKTREE_RUN_STATE_PATH);
937
- if (!existsSync(statePath)) {
962
+ if (!existsSync2(statePath)) {
938
963
  return null;
939
964
  }
940
965
  try {
@@ -1106,7 +1131,7 @@ async function cleanupRepository(options) {
1106
1131
  // commands/artifact-validation.ts
1107
1132
  import { createHash } from "crypto";
1108
1133
  import { execSync } from "child_process";
1109
- import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync8 } from "fs";
1134
+ import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync7 } from "fs";
1110
1135
  import { isAbsolute as isAbsolute3, join as join7, resolve as resolve3 } from "path";
1111
1136
 
1112
1137
  // pr/review-verdict.ts
@@ -1140,7 +1165,7 @@ function parseReviewVerdict(output) {
1140
1165
 
1141
1166
  // commands/review.ts
1142
1167
  import {
1143
- existsSync as existsSync5,
1168
+ existsSync as existsSync6,
1144
1169
  mkdirSync as mkdirSync5,
1145
1170
  readFileSync as readFileSync6,
1146
1171
  readdirSync as readdirSync2,
@@ -1149,7 +1174,7 @@ import {
1149
1174
  import { join as join6 } from "path";
1150
1175
 
1151
1176
  // execution/agent-output-retry.ts
1152
- import { existsSync as existsSync2, mkdirSync as mkdirSync3, readFileSync as readFileSync3, rmSync } from "fs";
1177
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, rmSync } from "fs";
1153
1178
  import { dirname as dirname3, join as join4 } from "path";
1154
1179
  async function executeWithMissingOrEmptyArtifactRetry({
1155
1180
  executionProvider,
@@ -1207,7 +1232,7 @@ async function executeWithMissingOrEmptyArtifactRetry({
1207
1232
  };
1208
1233
  }
1209
1234
  function readArtifactOutput(artifactPath) {
1210
- if (!existsSync2(artifactPath)) {
1235
+ if (!existsSync3(artifactPath)) {
1211
1236
  return { _tag: "missing", path: artifactPath };
1212
1237
  }
1213
1238
  const output = readFileSync3(artifactPath, "utf-8");
@@ -1222,7 +1247,7 @@ function prepareArtifactPath(artifactPath) {
1222
1247
  }
1223
1248
 
1224
1249
  // shared/run-context.ts
1225
- import { existsSync as existsSync3, readFileSync as readFileSync4, readdirSync } from "fs";
1250
+ import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync } from "fs";
1226
1251
  import { isAbsolute as isAbsolute2, join as join5, relative, resolve as resolve2 } from "path";
1227
1252
 
1228
1253
  // commands/run-verification.ts
@@ -1371,13 +1396,6 @@ var STAGE_SECTIONS = {
1371
1396
  "branch",
1372
1397
  "verification-commands",
1373
1398
  "artifacts"
1374
- ],
1375
- prdReconciliation: [
1376
- "issue",
1377
- "comments",
1378
- "branch",
1379
- "verification-commands",
1380
- "artifacts"
1381
1399
  ]
1382
1400
  };
1383
1401
  function buildRunContextArtifact(options) {
@@ -1524,7 +1542,7 @@ function renderPrdContext(issue, parentPrdIssue, repoRoot2) {
1524
1542
  }
1525
1543
  for (const documentPath of documentPaths) {
1526
1544
  const absolutePath = resolveRepoPath(repoRoot2, documentPath);
1527
- if (!absolutePath || !existsSync3(absolutePath)) continue;
1545
+ if (!absolutePath || !existsSync4(absolutePath)) continue;
1528
1546
  parts.push(
1529
1547
  `### Document Content: \`${documentPath}\``,
1530
1548
  "",
@@ -1561,27 +1579,20 @@ function resolveRepoPath(repoRoot2, path9) {
1561
1579
  return resolved;
1562
1580
  }
1563
1581
  function findParentPrdPath(repoRoot2, parentRef) {
1564
- const directPath = join5(
1565
- repoRoot2,
1566
- ".pourkit",
1567
- "architecture",
1568
- parentRef,
1569
- "PRD.md"
1570
- );
1571
- if (existsSync3(directPath)) return directPath;
1572
- const architectureRoot = join5(repoRoot2, ".pourkit", "architecture");
1573
- if (!existsSync3(architectureRoot)) return null;
1574
- return findPrdMirror(architectureRoot, parentRef);
1582
+ const plansRoot = join5(repoRoot2, ".pourkit", "plans");
1583
+ if (!existsSync4(plansRoot)) return null;
1584
+ return findPrdInPlans(plansRoot, parentRef);
1575
1585
  }
1576
- function findPrdMirror(directory, parentRef) {
1586
+ function findPrdInPlans(directory, parentRef) {
1577
1587
  for (const entry of readdirSync(directory, { withFileTypes: true })) {
1578
1588
  const entryPath = join5(directory, entry.name);
1579
1589
  if (entry.isDirectory()) {
1580
- if (entry.name.startsWith(parentRef)) {
1590
+ const prdNumber = parentRef.match(/^PRD-(\d+)$/)?.[1];
1591
+ if (entry.name.startsWith(parentRef) || prdNumber && entry.name.startsWith(`${prdNumber}-`)) {
1581
1592
  const prdPath = join5(entryPath, "PRD.md");
1582
- if (existsSync3(prdPath)) return prdPath;
1593
+ if (existsSync4(prdPath)) return prdPath;
1583
1594
  }
1584
- const nested = findPrdMirror(entryPath, parentRef);
1595
+ const nested = findPrdInPlans(entryPath, parentRef);
1585
1596
  if (nested) return nested;
1586
1597
  }
1587
1598
  }
@@ -1613,7 +1624,7 @@ function appendProtectedWorkGuidance(promptBody) {
1613
1624
 
1614
1625
  // shared/effect-services.ts
1615
1626
  import { Context, Effect, Layer } from "effect";
1616
- import { existsSync as existsSync4, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync2, rmSync as rmSync2 } from "fs";
1627
+ import { existsSync as existsSync5, mkdirSync as mkdirSync4, readFileSync as readFileSync5, writeFileSync as writeFileSync2, rmSync as rmSync2 } from "fs";
1617
1628
  var GitExecutionError = class extends Error {
1618
1629
  _tag = "GitExecutionError";
1619
1630
  message;
@@ -1641,7 +1652,7 @@ var FileSystemDefault = Layer.succeed(
1641
1652
  )
1642
1653
  }),
1643
1654
  exists: (path9) => Effect.try({
1644
- try: () => existsSync4(path9),
1655
+ try: () => existsSync5(path9),
1645
1656
  catch: (error) => new Error(
1646
1657
  `Failed to check existence of ${path9}: ${error instanceof Error ? error.message : String(error)}`
1647
1658
  )
@@ -2025,7 +2036,7 @@ function extractLatestFindingIds(reviewOutput, iteration) {
2025
2036
  return ids;
2026
2037
  }
2027
2038
  function validateRefactorArtifact(artifactPath, findingIds) {
2028
- if (!existsSync5(artifactPath)) {
2039
+ if (!existsSync6(artifactPath)) {
2029
2040
  throw new RefactorArtifactValidationError(
2030
2041
  `Refactor artifact missing at ${artifactPath}`
2031
2042
  );
@@ -2516,14 +2527,14 @@ function recoverReviewOutputFromString(logContent) {
2516
2527
  return recoveredOutput.length > 0 ? recoveredOutput : null;
2517
2528
  }
2518
2529
  function recoverReviewOutputFromLog(logPath) {
2519
- if (!existsSync5(logPath)) {
2530
+ if (!existsSync6(logPath)) {
2520
2531
  return null;
2521
2532
  }
2522
2533
  const logContent = readFileSync6(logPath, "utf-8");
2523
2534
  return recoverReviewOutputFromString(logContent);
2524
2535
  }
2525
2536
  function readReviewArtifact(artifactPath, logPath) {
2526
- if (existsSync5(artifactPath)) {
2537
+ if (existsSync6(artifactPath)) {
2527
2538
  const output = readFileSync6(artifactPath, "utf-8");
2528
2539
  if (output.trim()) {
2529
2540
  return output;
@@ -2534,7 +2545,7 @@ function readReviewArtifact(artifactPath, logPath) {
2534
2545
  writeFileSync3(artifactPath, recoveredOutput, "utf-8");
2535
2546
  return recoveredOutput;
2536
2547
  }
2537
- if (!existsSync5(artifactPath)) {
2548
+ if (!existsSync6(artifactPath)) {
2538
2549
  throw new Error(`Reviewer did not produce output at ${artifactPath}`);
2539
2550
  }
2540
2551
  throw new Error(`Reviewer produced empty output at ${artifactPath}`);
@@ -3173,194 +3184,6 @@ function parseConflictResolutionArtifact(output) {
3173
3184
  };
3174
3185
  }
3175
3186
 
3176
- // prd-run/final-review-validation.ts
3177
- import { existsSync as existsSync6, readFileSync as readFileSync7 } from "fs";
3178
- function parseFinalReviewArtifact(artifactPath) {
3179
- if (!existsSync6(artifactPath)) {
3180
- return {
3181
- ok: false,
3182
- reason: "Final Review artifact not found.",
3183
- diagnostics: [`Artifact path: ${artifactPath}`]
3184
- };
3185
- }
3186
- let content;
3187
- try {
3188
- content = readFileSync7(artifactPath, "utf-8");
3189
- } catch (error) {
3190
- return {
3191
- ok: false,
3192
- reason: "Final Review artifact could not be read.",
3193
- diagnostics: [
3194
- error instanceof Error ? error.message : String(error),
3195
- `Artifact path: ${artifactPath}`
3196
- ]
3197
- };
3198
- }
3199
- let parsed;
3200
- try {
3201
- parsed = JSON.parse(content);
3202
- } catch {
3203
- return {
3204
- ok: false,
3205
- reason: "Final Review artifact is not valid JSON.",
3206
- diagnostics: [`Artifact path: ${artifactPath}`]
3207
- };
3208
- }
3209
- const verdict = parsed.verdict;
3210
- if (!verdict || typeof verdict !== "string") {
3211
- return {
3212
- ok: false,
3213
- reason: "Final Review artifact is missing a verdict field.",
3214
- diagnostics: [`Artifact content preview: ${content.slice(0, 300)}`]
3215
- };
3216
- }
3217
- const allowedVerdicts = [
3218
- "pass_no_changes",
3219
- "pass_with_retouch",
3220
- "needs_human_review",
3221
- "blocked"
3222
- ];
3223
- if (!allowedVerdicts.includes(verdict)) {
3224
- return {
3225
- ok: false,
3226
- reason: `Final Review artifact has unsupported verdict "${verdict}".`,
3227
- diagnostics: [`Allowed verdicts: ${allowedVerdicts.join(", ")}`]
3228
- };
3229
- }
3230
- const summary = typeof parsed.summary === "string" ? parsed.summary : typeof parsed.reason === "string" ? parsed.reason : String(verdict);
3231
- const diagnostics = Array.isArray(parsed.diagnostics) ? parsed.diagnostics : [];
3232
- const changedPaths = Array.isArray(parsed.changedPaths) ? parsed.changedPaths : void 0;
3233
- const isAutoSummary = !parsed.summary && !parsed.reason;
3234
- if (verdict === "pass_with_retouch" && (!changedPaths || changedPaths.length === 0) && isAutoSummary) {
3235
- return {
3236
- ok: false,
3237
- reason: 'Final Review artifact with "pass_with_retouch" verdict requires changed paths.',
3238
- diagnostics: [
3239
- "pass_with_retouch verdict must include a changedPaths array in the artifact or provide a summary/reason with enough context for git diff fallback.",
3240
- "Provide changedPaths or a descriptive summary in the artifact."
3241
- ]
3242
- };
3243
- }
3244
- const prdRef = typeof parsed.prdRef === "string" && parsed.prdRef.trim() ? parsed.prdRef.trim() : void 0;
3245
- const stage = typeof parsed.stage === "string" && parsed.stage.trim() ? parsed.stage.trim() : void 0;
3246
- const checkoutBase = typeof parsed.checkoutBase === "string" && parsed.checkoutBase.trim() ? parsed.checkoutBase.trim() : void 0;
3247
- const reviewBase = typeof parsed.reviewBase === "string" && parsed.reviewBase.trim() ? parsed.reviewBase.trim() : void 0;
3248
- return {
3249
- ok: true,
3250
- verdict,
3251
- summary,
3252
- diagnostics,
3253
- changedPaths,
3254
- prdRef,
3255
- stage,
3256
- checkoutBase,
3257
- reviewBase
3258
- };
3259
- }
3260
- function validateFinalReviewArtifactSemanticIds(artifact, context) {
3261
- const errors = [];
3262
- if (!artifact.prdRef) {
3263
- errors.push("Final Review artifact is missing prdRef.");
3264
- } else if (artifact.prdRef !== context.prdRef) {
3265
- errors.push(
3266
- `Final Review artifact prdRef "${artifact.prdRef}" does not match active PRD Run "${context.prdRef}".`
3267
- );
3268
- }
3269
- if (!artifact.stage) {
3270
- errors.push("Final Review artifact is missing stage field.");
3271
- } else if (artifact.stage !== "prdFinalReview") {
3272
- errors.push(
3273
- `Final Review artifact stage "${artifact.stage}" is not "prdFinalReview".`
3274
- );
3275
- }
3276
- if (!artifact.checkoutBase) {
3277
- errors.push("Final Review artifact is missing checkoutBase.");
3278
- } else if (artifact.checkoutBase !== context.prdBranch) {
3279
- errors.push(
3280
- `Final Review artifact checkoutBase "${artifact.checkoutBase}" does not match active PRD Branch "${context.prdBranch}".`
3281
- );
3282
- }
3283
- if (!artifact.reviewBase) {
3284
- errors.push("Final Review artifact is missing reviewBase.");
3285
- } else if (artifact.reviewBase !== context.mergeBase) {
3286
- errors.push(
3287
- `Final Review artifact reviewBase "${artifact.reviewBase}" does not match active merge base "${context.mergeBase}".`
3288
- );
3289
- }
3290
- if (errors.length > 0) {
3291
- return { ok: false, errors, blockedGate: "final-review" };
3292
- }
3293
- return { ok: true };
3294
- }
3295
- function validateFinalReviewRetouchScope(changedPaths) {
3296
- if (!changedPaths || changedPaths.length === 0) {
3297
- return {
3298
- ok: false,
3299
- reason: "Final Review retouch scope validation failed. No changed paths available. Provide changed paths or run Final Review with a summary that includes changed paths.",
3300
- diagnostics: ["Changed paths list is empty or undefined."],
3301
- offendingPaths: []
3302
- };
3303
- }
3304
- const offendingPaths = changedPaths.filter((p) => !isRetouchScopePath(p));
3305
- const allowedPaths = changedPaths.filter((p) => isRetouchScopePath(p));
3306
- if (allowedPaths.length === 0) {
3307
- return {
3308
- ok: false,
3309
- reason: "Final Review retouch scope validation failed. No implementation, test, or Changeset paths found for retouch.",
3310
- diagnostics: [
3311
- "All changed paths are prohibited for retouch.",
3312
- ...changedPaths.map((p) => ` - ${p}`)
3313
- ],
3314
- offendingPaths
3315
- };
3316
- }
3317
- if (offendingPaths.length > 0) {
3318
- return {
3319
- ok: false,
3320
- reason: "Final Review retouch scope validation failed. Prohibited paths cannot be included in retouch PR.",
3321
- diagnostics: [
3322
- "Prohibited paths found:",
3323
- ...offendingPaths.map((p) => ` - ${p}`)
3324
- ],
3325
- offendingPaths
3326
- };
3327
- }
3328
- return { ok: true, changedPaths };
3329
- }
3330
- function validateFinalReviewAgentOutputs(options) {
3331
- const artifact = parseFinalReviewArtifact(options.artifactPath);
3332
- if (!artifact.ok) {
3333
- return { ...artifact, offendingPaths: [] };
3334
- }
3335
- const semanticResult = validateFinalReviewArtifactSemanticIds(
3336
- artifact,
3337
- options.context
3338
- );
3339
- if (!semanticResult.ok) {
3340
- return {
3341
- ok: false,
3342
- reason: "Final Review artifact has mismatched semantic IDs.",
3343
- diagnostics: semanticResult.errors,
3344
- offendingPaths: []
3345
- };
3346
- }
3347
- if (artifact.verdict !== "pass_with_retouch") {
3348
- return { ok: true, artifact };
3349
- }
3350
- const changedPaths = options.changedPaths && options.changedPaths.length > 0 ? options.changedPaths : artifact.changedPaths;
3351
- const retouch = validateFinalReviewRetouchScope(changedPaths ?? []);
3352
- if (!retouch.ok) {
3353
- return retouch;
3354
- }
3355
- return { ok: true, artifact, retouch };
3356
- }
3357
- function isRetouchScopePath(path9) {
3358
- if (path9.startsWith(".pourkit/plans/") || path9 === ".pourkit/CONTEXT.md" || path9.startsWith(".pourkit/docs/") || /^\.pourkit\/prd-runs\/[^/]+\.json$/.test(path9)) {
3359
- return false;
3360
- }
3361
- return true;
3362
- }
3363
-
3364
3187
  // commands/artifact-validation.ts
3365
3188
  var CONFLICT_MARKER_PATTERN = /<<<<<<<|=======|>>>>>>>/m;
3366
3189
  function invalid(options, reason, diagnostics = []) {
@@ -3388,7 +3211,7 @@ function readArtifact(options) {
3388
3211
  };
3389
3212
  }
3390
3213
  try {
3391
- const content = readFileSync8(options.artifactPath, "utf-8");
3214
+ const content = readFileSync7(options.artifactPath, "utf-8");
3392
3215
  if (!content.trim()) {
3393
3216
  return { ok: false, result: invalid(options, "Artifact is empty") };
3394
3217
  }
@@ -3559,7 +3382,7 @@ function validateAgentArtifact(options) {
3559
3382
  case "refactor": {
3560
3383
  let findingIds = options.findingIds ?? [];
3561
3384
  if (findingIds.length === 0 && options.latestReviewArtifactPath) {
3562
- const latestReview = readFileSync8(
3385
+ const latestReview = readFileSync7(
3563
3386
  options.latestReviewArtifactPath,
3564
3387
  "utf-8"
3565
3388
  );
@@ -3585,7 +3408,7 @@ function validateAgentArtifact(options) {
3585
3408
  const filePath = resolve3(base, file);
3586
3409
  try {
3587
3410
  return CONFLICT_MARKER_PATTERN.test(
3588
- readFileSync8(filePath, "utf-8")
3411
+ readFileSync7(filePath, "utf-8")
3589
3412
  );
3590
3413
  } catch {
3591
3414
  return false;
@@ -3601,29 +3424,6 @@ function validateAgentArtifact(options) {
3601
3424
  }
3602
3425
  return valid(options, [`status: ${parsed.status}`]);
3603
3426
  }
3604
- // QUARANTINED: Retained for Issue Final Review artifact validation via
3605
- // `runPrdRunValidateFinalReviewCommand`. Remove when Issue Final Review
3606
- // is migrated to its own dedicated validator kind.
3607
- case "final-review": {
3608
- if (!options.prdRef || !options.checkoutBase || !options.reviewBase) {
3609
- return invalid(
3610
- options,
3611
- "Final Review artifact validation requires --prd-ref, --checkout-base, and --review-base."
3612
- );
3613
- }
3614
- const result = validateFinalReviewAgentOutputs({
3615
- artifactPath: options.artifactPath,
3616
- context: {
3617
- prdRef: options.prdRef,
3618
- prdBranch: options.checkoutBase,
3619
- mergeBase: options.reviewBase
3620
- }
3621
- });
3622
- if (!result.ok) {
3623
- return invalid(options, result.reason, result.diagnostics);
3624
- }
3625
- return valid(options, [`verdict: ${result.artifact.verdict}`]);
3626
- }
3627
3427
  case "issue-final-review": {
3628
3428
  if (options.issueNumber === void 0 || !options.branchName) {
3629
3429
  return invalid(
@@ -3663,12 +3463,6 @@ function validateAgentArtifact(options) {
3663
3463
  }
3664
3464
  return valid(options, [`decision: ${parsed.json.recoveryDecision}`]);
3665
3465
  }
3666
- case "reconciliation":
3667
- case "planning-manifest":
3668
- return invalid(
3669
- options,
3670
- `Artifact kind "${options.kind}" has been removed from PRD Run validation`
3671
- );
3672
3466
  case "local-prd":
3673
3467
  case "local-issue":
3674
3468
  case "local-triage":
@@ -3749,7 +3543,7 @@ function runLocalValidateArtifactCommand(options) {
3749
3543
  }
3750
3544
  function readLocalArtifact(path9, failureCode) {
3751
3545
  try {
3752
- const raw = readFileSync8(path9, "utf-8");
3546
+ const raw = readFileSync7(path9, "utf-8");
3753
3547
  const parsed = JSON.parse(raw);
3754
3548
  if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
3755
3549
  return {
@@ -4448,7 +4242,7 @@ function validateLocalTriage(prdPath, issuePaths) {
4448
4242
  }
4449
4243
 
4450
4244
  // commands/issue-run.ts
4451
- import { existsSync as existsSync12, readFileSync as readFileSync15 } from "fs";
4245
+ import { existsSync as existsSync12, readFileSync as readFileSync14 } from "fs";
4452
4246
  import { isAbsolute as isAbsolute4, join as join15 } from "path";
4453
4247
 
4454
4248
  // pr/templates.ts
@@ -4584,7 +4378,7 @@ function runEffectAndMapExit(program) {
4584
4378
  }
4585
4379
 
4586
4380
  // shared/attempt-log.ts
4587
- import { appendFileSync, existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync9 } from "fs";
4381
+ import { appendFileSync, existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync8 } from "fs";
4588
4382
  import { dirname as dirname4, join as join8 } from "path";
4589
4383
  var ATTEMPT_LOG_PATH = ".pourkit/attempt-log.jsonl";
4590
4384
  function writeAttemptLog(worktreePath, entry) {
@@ -4597,7 +4391,7 @@ function readAttemptLog(worktreePath) {
4597
4391
  if (!existsSync8(logPath)) {
4598
4392
  return [];
4599
4393
  }
4600
- const raw = readFileSync9(logPath, "utf-8");
4394
+ const raw = readFileSync8(logPath, "utf-8");
4601
4395
  const lines = raw.split("\n").filter((l) => l.length > 0);
4602
4396
  const entries = [];
4603
4397
  for (const line of lines) {
@@ -4716,7 +4510,7 @@ async function runBaseRefreshAttempt(options) {
4716
4510
  }
4717
4511
 
4718
4512
  // commands/conflict-resolution.ts
4719
- import { existsSync as existsSync9, readFileSync as readFileSync10 } from "fs";
4513
+ import { existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
4720
4514
  import { join as join9 } from "path";
4721
4515
  init_common();
4722
4516
  var CONFLICT_MARKER_PATTERN2 = /<<<<<<<|=======|>>>>>>>/m;
@@ -4724,7 +4518,7 @@ async function hasUnresolvedConflictMarkers(worktreePath, files) {
4724
4518
  for (const file of files) {
4725
4519
  const filePath = join9(worktreePath, file);
4726
4520
  try {
4727
- const content = readFileSync10(filePath, "utf-8");
4521
+ const content = readFileSync9(filePath, "utf-8");
4728
4522
  if (CONFLICT_MARKER_PATTERN2.test(content)) {
4729
4523
  return true;
4730
4524
  }
@@ -5055,7 +4849,7 @@ async function prepareSerenaForTarget(options) {
5055
4849
  }
5056
4850
 
5057
4851
  // failure-resolution/failure-resolution-agent.ts
5058
- import { readFileSync as readFileSync11 } from "fs";
4852
+ import { readFileSync as readFileSync10 } from "fs";
5059
4853
  import { join as join10 } from "path";
5060
4854
 
5061
4855
  // failure-resolution/recovery-policy.ts
@@ -5209,7 +5003,7 @@ async function runFailureResolutionAgent(options) {
5209
5003
  }
5210
5004
  let artifact;
5211
5005
  try {
5212
- const md = readFileSync11(fullArtifactPath, "utf-8");
5006
+ const md = readFileSync10(fullArtifactPath, "utf-8");
5213
5007
  const validation2 = validateAgentArtifact({
5214
5008
  kind: "failure-resolution",
5215
5009
  artifactPath: fullArtifactPath,
@@ -5303,7 +5097,7 @@ async function writeRecoveryAttempt(worktreePath, outcome, fingerprint, summary,
5303
5097
 
5304
5098
  // commands/pr-description-agent.ts
5305
5099
  import { join as join12 } from "path";
5306
- import { readFileSync as readFileSync12 } from "fs";
5100
+ import { readFileSync as readFileSync11 } from "fs";
5307
5101
 
5308
5102
  // pr/pr-description-context.ts
5309
5103
  init_common();
@@ -5497,7 +5291,7 @@ function runFinalizerAgent(options) {
5497
5291
  ],
5498
5292
  logger: options.logger
5499
5293
  });
5500
- const output = readFileSync12(artifactPath, "utf-8");
5294
+ const output = readFileSync11(artifactPath, "utf-8");
5501
5295
  yield* persistGeneratedArtifactEffect(options.worktreePath, output, fs);
5502
5296
  return result;
5503
5297
  });
@@ -5625,7 +5419,7 @@ function persistGeneratedArtifactEffect(worktreePath, output, fs) {
5625
5419
 
5626
5420
  // prd-run/local-merge-coordinator.ts
5627
5421
  import { execFileSync as execFileSync2 } from "child_process";
5628
- import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync13, writeFileSync as writeFileSync4 } from "fs";
5422
+ import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync12, writeFileSync as writeFileSync4 } from "fs";
5629
5423
  import { join as join13 } from "path";
5630
5424
 
5631
5425
  // prd-run/local-branches.ts
@@ -5728,7 +5522,7 @@ function readIssueBranchName(repoRoot2, prdId, issueId) {
5728
5522
  const issuePath = getIssueArtifactPath(repoRoot2, prdId, issueId);
5729
5523
  if (!existsSync10(issuePath)) return null;
5730
5524
  try {
5731
- const content = readFileSync13(issuePath, "utf-8");
5525
+ const content = readFileSync12(issuePath, "utf-8");
5732
5526
  const parsed = JSON.parse(content);
5733
5527
  return typeof parsed.branchName === "string" && parsed.branchName ? parsed.branchName : null;
5734
5528
  } catch {
@@ -5740,7 +5534,7 @@ async function hasLocalIssueMergeReceipt(prdId, issueId, repoRoot2) {
5740
5534
  const receiptPath = getMergeReceiptPath(root, prdId, issueId);
5741
5535
  if (!existsSync10(receiptPath)) return null;
5742
5536
  try {
5743
- const content = readFileSync13(receiptPath, "utf-8");
5537
+ const content = readFileSync12(receiptPath, "utf-8");
5744
5538
  const parsed = JSON.parse(content);
5745
5539
  if (typeof parsed.prdId === "string" && typeof parsed.issueId === "string" && typeof parsed.stage === "string" && typeof parsed.sourceBranch === "string" && typeof parsed.localPrdBranch === "string" && typeof parsed.mergeCommit === "string" && typeof parsed.completedAt === "string") {
5746
5540
  return parsed;
@@ -5756,7 +5550,7 @@ async function squashMergeLocalIssue(prdId, issueId, input, repoRoot2) {
5756
5550
  if (existsSync10(receiptPath)) {
5757
5551
  try {
5758
5552
  const existing = JSON.parse(
5759
- readFileSync13(receiptPath, "utf-8")
5553
+ readFileSync12(receiptPath, "utf-8")
5760
5554
  );
5761
5555
  if (existing.prdId === prdId && existing.issueId === issueId && existing.mergeCommit) {
5762
5556
  return {
@@ -6165,7 +5959,7 @@ function runMergeCoordinator(options) {
6165
5959
  }
6166
5960
 
6167
5961
  // commands/issue-final-review-agent.ts
6168
- import { existsSync as existsSync11, readFileSync as readFileSync14 } from "fs";
5962
+ import { existsSync as existsSync11, readFileSync as readFileSync13 } from "fs";
6169
5963
  import { join as join14 } from "path";
6170
5964
  var ISSUE_FINAL_REVIEW_ARTIFACT_PATH = join14(
6171
5965
  ".pourkit",
@@ -6279,7 +6073,7 @@ async function runIssueFinalReviewAgent(options) {
6279
6073
  }
6280
6074
  function loadIssueFinalReviewPrompt(repoRoot2, promptTemplate) {
6281
6075
  const promptPath = resolvePromptTemplatePath(repoRoot2, promptTemplate);
6282
- const promptBody = existsSync11(promptPath) ? readFileSync14(promptPath, "utf-8") : promptTemplate;
6076
+ const promptBody = existsSync11(promptPath) ? readFileSync13(promptPath, "utf-8") : promptTemplate;
6283
6077
  return appendProtectedWorkGuidance(`${promptBody}
6284
6078
 
6285
6079
  ## Shared Run Context
@@ -6901,7 +6695,7 @@ async function completeIssueRun(options) {
6901
6695
  message: `Finalizer artifact missing at ${finalizerFromState.artifactPath}`
6902
6696
  });
6903
6697
  }
6904
- const artifactContent = readFileSync15(
6698
+ const artifactContent = readFileSync14(
6905
6699
  finalizerFromState.artifactPath,
6906
6700
  "utf-8"
6907
6701
  );
@@ -7615,7 +7409,7 @@ async function syncTargetBranch(root, baseBranch, logger) {
7615
7409
  }
7616
7410
  function loadBuilderPrompt(repoRoot2, promptTemplate) {
7617
7411
  const promptPath = resolvePromptTemplatePath(repoRoot2, promptTemplate);
7618
- const promptBody = existsSync12(promptPath) ? readFileSync15(promptPath, "utf-8") : promptTemplate;
7412
+ const promptBody = existsSync12(promptPath) ? readFileSync14(promptPath, "utf-8") : promptTemplate;
7619
7413
  return appendProtectedWorkGuidance(`${promptBody}
7620
7414
 
7621
7415
  ## Shared Run Context
@@ -8106,26 +7900,16 @@ async function runIssueCreateCommand(args, issueProvider, logger) {
8106
7900
  }
8107
7901
 
8108
7902
  // commands/prd-run.ts
8109
- import {
8110
- cpSync,
8111
- existsSync as existsSync16,
8112
- lstatSync,
8113
- mkdirSync as mkdirSync10,
8114
- mkdtempSync,
8115
- readFileSync as readFileSync18,
8116
- realpathSync,
8117
- rmSync as rmSync3
8118
- } from "fs";
7903
+ import { existsSync as existsSync16, lstatSync, readFileSync as readFileSync18, realpathSync } from "fs";
8119
7904
  import { spawnSync as spawnSync3 } from "child_process";
8120
- import { dirname as dirname5, join as join20, relative as relative2 } from "path";
8121
- import { tmpdir } from "os";
7905
+ import { join as join19, relative as relative2 } from "path";
8122
7906
  import { Match, pipe } from "effect";
8123
7907
 
8124
7908
  // prd-run/state.ts
8125
7909
  import {
8126
7910
  existsSync as existsSync13,
8127
7911
  mkdirSync as mkdirSync8,
8128
- readFileSync as readFileSync16,
7912
+ readFileSync as readFileSync15,
8129
7913
  readdirSync as readdirSync4,
8130
7914
  writeFileSync as writeFileSync5
8131
7915
  } from "fs";
@@ -8225,12 +8009,12 @@ function readPrdRun(repoRoot2, prdRef) {
8225
8009
  return { record: null, diagnostics: [] };
8226
8010
  }
8227
8011
  try {
8228
- const raw = JSON.parse(readFileSync16(recordPath, "utf-8"));
8012
+ const raw = JSON.parse(readFileSync15(recordPath, "utf-8"));
8229
8013
  const parsed = normalizeLegacyPrdRunRecord(PrdRunRecordSchema.parse(raw));
8230
8014
  return { record: parsed, diagnostics: [] };
8231
8015
  } catch (error) {
8232
8016
  try {
8233
- const raw = JSON.parse(readFileSync16(recordPath, "utf-8"));
8017
+ const raw = JSON.parse(readFileSync15(recordPath, "utf-8"));
8234
8018
  if (raw && typeof raw === "object" && raw.start && typeof raw.start === "object" && raw.start.startBaseBranch === void 0) {
8235
8019
  return {
8236
8020
  record: raw,
@@ -8264,7 +8048,7 @@ function listPrdRuns(repoRoot2) {
8264
8048
  const recordPath = join16(stateDir, entry.name);
8265
8049
  try {
8266
8050
  const record = normalizeLegacyPrdRunRecord(
8267
- PrdRunRecordSchema.parse(JSON.parse(readFileSync16(recordPath, "utf-8")))
8051
+ PrdRunRecordSchema.parse(JSON.parse(readFileSync15(recordPath, "utf-8")))
8268
8052
  );
8269
8053
  records.push(record);
8270
8054
  } catch (error) {
@@ -8339,26 +8123,9 @@ function getRecordPath(repoRoot2, prdRef) {
8339
8123
  );
8340
8124
  }
8341
8125
 
8342
- // prd-run/evidence-packet.ts
8343
- import { createHash as createHash2 } from "crypto";
8344
- import { z as z2 } from "zod";
8345
- var PRD_REF_REGEX2 = /^PRD-\d{3,4}$/;
8346
- var StageSchema = z2.enum(["prdFinalReview", "prdReconciliation"]);
8347
- var EvidencePacketSchema = z2.object({
8348
- prdRef: z2.string().regex(PRD_REF_REGEX2),
8349
- prdBranch: z2.string().min(1),
8350
- mergeBase: z2.string().min(6),
8351
- planningManifestPath: z2.string().min(1),
8352
- planningManifestFacts: z2.object({
8353
- parentPrdIssueUrl: z2.string().min(1),
8354
- childIssueCount: z2.number().int().nonnegative()
8355
- }),
8356
- stage: StageSchema,
8357
- stageReceipts: z2.record(z2.string(), z2.unknown())
8358
- }).strict();
8359
-
8360
- // commands/prd-run.ts
8361
- init_common();
8126
+ // prd-run/local-queue-loop.ts
8127
+ import { readFileSync as readFileSync16, writeFileSync as writeFileSync6 } from "fs";
8128
+ import { join as join18 } from "path";
8362
8129
 
8363
8130
  // prd-run/local-artifacts.ts
8364
8131
  import { existsSync as existsSync14 } from "fs";
@@ -8501,75 +8268,8 @@ async function resolveLocalIssueArtifacts(prdId, repoRoot2) {
8501
8268
  return { ok: true, data: issues };
8502
8269
  }
8503
8270
 
8504
- // prd-run/local-issue-adapter.ts
8505
- var VALID_TRIAGE_LABELS = /* @__PURE__ */ new Set([
8506
- "needs-triage",
8507
- "ready-for-agent",
8508
- "blocked",
8509
- "ready-for-human",
8510
- "wontfix"
8511
- ]);
8512
- function countTypeLabels(labels) {
8513
- return labels.filter((l) => l.startsWith("type:")).length;
8514
- }
8515
- function countTriageLabels(labels) {
8516
- return labels.filter((l) => VALID_TRIAGE_LABELS.has(l)).length;
8517
- }
8518
- function countCategoryLabels(labels) {
8519
- const triageCount = countTriageLabels(labels);
8520
- const typeCount = countTypeLabels(labels);
8521
- return labels.length - triageCount - typeCount;
8522
- }
8523
- function hasValidLabels(labels) {
8524
- if (countTriageLabels(labels) !== 1) return false;
8525
- if (!labels.includes("ready-for-agent")) return false;
8526
- if (countTypeLabels(labels) !== 1) return false;
8527
- if (countCategoryLabels(labels) !== 1) return false;
8528
- return true;
8529
- }
8530
- function isIssueBlockedByDependencies(issue, issues) {
8531
- const blockers = [];
8532
- for (const depId of issue.dependencyIssueIds) {
8533
- const dep = issues.find((i) => i.id === depId);
8534
- if (!dep || dep.receipts.completedAt === null) {
8535
- blockers.push(depId);
8536
- }
8537
- }
8538
- return blockers;
8539
- }
8540
- async function getRunnableLocalIssues(prdId, repoRoot2) {
8541
- const issuesResult = await resolveLocalIssueArtifacts(prdId, repoRoot2);
8542
- if (!issuesResult.ok) return [];
8543
- const issues = issuesResult.data;
8544
- const runnable = [];
8545
- for (const issue of issues) {
8546
- if (!hasValidLabels(issue.labels)) continue;
8547
- if (issue.status !== "ready-for-agent") continue;
8548
- const blockers = isIssueBlockedByDependencies(issue, issues);
8549
- runnable.push({
8550
- id: issue.id,
8551
- title: issue.title,
8552
- labels: issue.labels,
8553
- blockedBy: blockers.length > 0 ? blockers : void 0
8554
- });
8555
- }
8556
- const filtered = runnable.filter(
8557
- (i) => !i.blockedBy || i.blockedBy.length === 0
8558
- );
8559
- return filtered;
8560
- }
8561
-
8562
- // prd-run/local-final-review.ts
8563
- import { execFileSync as execFileSync3, execSync as execSync2 } from "child_process";
8564
- import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync6 } from "fs";
8565
- import { join as join18 } from "path";
8566
-
8567
- // prd-run/local-queue-loop.ts
8568
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync7 } from "fs";
8569
- import { join as join19 } from "path";
8570
-
8571
8271
  // prd-run/local-issue-run.ts
8572
- import { execFileSync as execFileSync4 } from "child_process";
8272
+ import { execFileSync as execFileSync3 } from "child_process";
8573
8273
  init_common();
8574
8274
  async function createLocalIssueBranch(prdId, issueId, repoRoot2) {
8575
8275
  const root = repoRoot2 ?? process.cwd();
@@ -8593,7 +8293,7 @@ async function createLocalIssueBranch(prdId, issueId, repoRoot2) {
8593
8293
  }
8594
8294
  const localPrdBranch = `local/${prdId}`;
8595
8295
  try {
8596
- execFileSync4(
8296
+ execFileSync3(
8597
8297
  "git",
8598
8298
  ["show-ref", "--verify", "--quiet", `refs/heads/${localPrdBranch}`],
8599
8299
  {
@@ -8609,7 +8309,7 @@ async function createLocalIssueBranch(prdId, issueId, repoRoot2) {
8609
8309
  }
8610
8310
  let branchExists = false;
8611
8311
  try {
8612
- execFileSync4(
8312
+ execFileSync3(
8613
8313
  "git",
8614
8314
  ["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`],
8615
8315
  {
@@ -8622,7 +8322,7 @@ async function createLocalIssueBranch(prdId, issueId, repoRoot2) {
8622
8322
  } catch {
8623
8323
  }
8624
8324
  if (!branchExists) {
8625
- execFileSync4("git", ["checkout", "-b", branchName, localPrdBranch], {
8325
+ execFileSync3("git", ["checkout", "-b", branchName, localPrdBranch], {
8626
8326
  cwd: root,
8627
8327
  encoding: "utf8",
8628
8328
  stdio: "pipe"
@@ -8687,11 +8387,69 @@ async function runLocalIssue(prdId, issueId, builder, repoRoot2) {
8687
8387
  }
8688
8388
  }
8689
8389
 
8390
+ // prd-run/local-issue-adapter.ts
8391
+ var VALID_TRIAGE_LABELS = /* @__PURE__ */ new Set([
8392
+ "needs-triage",
8393
+ "ready-for-agent",
8394
+ "blocked",
8395
+ "ready-for-human",
8396
+ "wontfix"
8397
+ ]);
8398
+ function countTypeLabels(labels) {
8399
+ return labels.filter((l) => l.startsWith("type:")).length;
8400
+ }
8401
+ function countTriageLabels(labels) {
8402
+ return labels.filter((l) => VALID_TRIAGE_LABELS.has(l)).length;
8403
+ }
8404
+ function countCategoryLabels(labels) {
8405
+ const triageCount = countTriageLabels(labels);
8406
+ const typeCount = countTypeLabels(labels);
8407
+ return labels.length - triageCount - typeCount;
8408
+ }
8409
+ function hasValidLabels(labels) {
8410
+ if (countTriageLabels(labels) !== 1) return false;
8411
+ if (!labels.includes("ready-for-agent")) return false;
8412
+ if (countTypeLabels(labels) !== 1) return false;
8413
+ if (countCategoryLabels(labels) !== 1) return false;
8414
+ return true;
8415
+ }
8416
+ function isIssueBlockedByDependencies(issue, issues) {
8417
+ const blockers = [];
8418
+ for (const depId of issue.dependencyIssueIds) {
8419
+ const dep = issues.find((i) => i.id === depId);
8420
+ if (!dep || dep.receipts.completedAt === null) {
8421
+ blockers.push(depId);
8422
+ }
8423
+ }
8424
+ return blockers;
8425
+ }
8426
+ async function getRunnableLocalIssues(prdId, repoRoot2) {
8427
+ const issuesResult = await resolveLocalIssueArtifacts(prdId, repoRoot2);
8428
+ if (!issuesResult.ok) return [];
8429
+ const issues = issuesResult.data;
8430
+ const runnable = [];
8431
+ for (const issue of issues) {
8432
+ if (!hasValidLabels(issue.labels)) continue;
8433
+ if (issue.status !== "ready-for-agent") continue;
8434
+ const blockers = isIssueBlockedByDependencies(issue, issues);
8435
+ runnable.push({
8436
+ id: issue.id,
8437
+ title: issue.title,
8438
+ labels: issue.labels,
8439
+ blockedBy: blockers.length > 0 ? blockers : void 0
8440
+ });
8441
+ }
8442
+ const filtered = runnable.filter(
8443
+ (i) => !i.blockedBy || i.blockedBy.length === 0
8444
+ );
8445
+ return filtered;
8446
+ }
8447
+
8690
8448
  // prd-run/local-queue-loop.ts
8691
8449
  var CHILD_CLEANUP_LABELS = ["agent-in-progress", "pr-open-awaiting-merge"];
8692
8450
  var LOCAL_ISSUE_ID_REGEX = /^I-(\d+)$/i;
8693
8451
  function getIssueArtifactPath2(repoRoot2, prdId, issueId) {
8694
- return join19(
8452
+ return join18(
8695
8453
  repoRoot2,
8696
8454
  ".pourkit",
8697
8455
  "local-prd-runs",
@@ -8702,7 +8460,7 @@ function getIssueArtifactPath2(repoRoot2, prdId, issueId) {
8702
8460
  }
8703
8461
  function readIssueArtifact(repoRoot2, prdId, issueId) {
8704
8462
  try {
8705
- const content = readFileSync17(
8463
+ const content = readFileSync16(
8706
8464
  getIssueArtifactPath2(repoRoot2, prdId, issueId),
8707
8465
  "utf-8"
8708
8466
  );
@@ -8712,7 +8470,7 @@ function readIssueArtifact(repoRoot2, prdId, issueId) {
8712
8470
  }
8713
8471
  }
8714
8472
  function writeIssueArtifact(repoRoot2, prdId, issue) {
8715
- writeFileSync7(
8473
+ writeFileSync6(
8716
8474
  getIssueArtifactPath2(repoRoot2, prdId, issue.id),
8717
8475
  JSON.stringify(issue, null, 2),
8718
8476
  "utf-8"
@@ -9378,6 +9136,9 @@ async function runQueueCommand(options) {
9378
9136
  return runEffectAndMapExit(runQueueLoop(queueOptions));
9379
9137
  }
9380
9138
 
9139
+ // prd-run/final-review-validation.ts
9140
+ import { existsSync as existsSync15, readFileSync as readFileSync17 } from "fs";
9141
+
9381
9142
  // commands/prd-run.ts
9382
9143
  function planLaunchResume(record) {
9383
9144
  if (!record) return { attempted: [], skipped: [], resumed: [] };
@@ -9439,10 +9200,10 @@ function planLaunchResume(record) {
9439
9200
  );
9440
9201
  }
9441
9202
  function validateLocalStartStore(repoRoot2, prdRef) {
9442
- const localStoreDir = join20(repoRoot2, ".pourkit", "local-prd-runs", prdRef);
9203
+ const localStoreDir = join19(repoRoot2, ".pourkit", "local-prd-runs", prdRef);
9443
9204
  let localStoreReady = false;
9444
9205
  if (existsSync16(localStoreDir)) {
9445
- const localStorePath = join20(localStoreDir, "prd.json");
9206
+ const localStorePath = join19(localStoreDir, "prd.json");
9446
9207
  try {
9447
9208
  const content = JSON.parse(readFileSync18(localStorePath, "utf8"));
9448
9209
  localStoreReady = content?.id === prdRef && content?.kind === "prd";
@@ -9614,7 +9375,7 @@ async function runPrdRunLaunchCommand(options) {
9614
9375
  attempted.push("queue");
9615
9376
  }
9616
9377
  const currentRecord = readPrdRun(options.repoRoot, prdRef).record;
9617
- const localStorePath = join20(
9378
+ const localStorePath = join19(
9618
9379
  options.repoRoot,
9619
9380
  ".pourkit",
9620
9381
  "local-prd-runs",
@@ -10131,7 +9892,7 @@ async function processStartResult(startResult, options) {
10131
9892
  start,
10132
9893
  mode: modeForRecord
10133
9894
  });
10134
- const localStorePath = join20(repoRoot2, ".pourkit", "local-prd-runs", prdRef);
9895
+ const localStorePath = join19(repoRoot2, ".pourkit", "local-prd-runs", prdRef);
10135
9896
  if (existsSync16(localStorePath)) {
10136
9897
  const queueResult = await runLocalQueueLoop(
10137
9898
  prdRef,
@@ -11029,7 +10790,7 @@ import {
11029
10790
  rename,
11030
10791
  writeFile as writeFile2
11031
10792
  } from "fs/promises";
11032
- import { createHash as createHash3, randomUUID } from "crypto";
10793
+ import { createHash as createHash2, randomUUID } from "crypto";
11033
10794
  import path5 from "path";
11034
10795
  import { execFile as execFile2 } from "child_process";
11035
10796
  import { promisify as promisify2 } from "util";
@@ -11505,7 +11266,7 @@ async function walkDir(dir) {
11505
11266
  }
11506
11267
  async function computeFileChecksum(filePath) {
11507
11268
  const content = await readFile5(filePath);
11508
- return createHash3("sha256").update(content).digest("hex");
11269
+ return createHash2("sha256").update(content).digest("hex");
11509
11270
  }
11510
11271
  function lockfileExists(root, name) {
11511
11272
  return existsSync17(path5.join(root, name));
@@ -13180,16 +12941,20 @@ async function runSerenaStatusCommand(options) {
13180
12941
  // commands/config-schema.ts
13181
12942
  import { readFileSync as readFileSync19, existsSync as existsSync18 } from "fs";
13182
12943
  import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile3 } from "fs/promises";
13183
- import { resolve as resolve4, dirname as dirname6 } from "path";
12944
+ import { resolve as resolve4, dirname as dirname5 } from "path";
13184
12945
  import { fileURLToPath as fileURLToPath2 } from "url";
13185
12946
  import Ajv2 from "ajv";
13186
12947
  var __filename2 = fileURLToPath2(import.meta.url);
13187
- var __dirname2 = dirname6(__filename2);
13188
- var PACKAGED_SCHEMA_PATH = resolve4(
13189
- __dirname2,
13190
- "../schema/pourkit.schema.json"
13191
- );
13192
- var PACKAGED_HASH_PATH = resolve4(__dirname2, "../schema/pourkit.schema.hash");
12948
+ var __dirname2 = dirname5(__filename2);
12949
+ function resolvePackagedAssetPath2(fileName) {
12950
+ const candidates = [
12951
+ resolve4(__dirname2, "schema", fileName),
12952
+ resolve4(__dirname2, "../schema", fileName)
12953
+ ];
12954
+ return candidates.find((candidate) => existsSync18(candidate)) ?? candidates[0];
12955
+ }
12956
+ var PACKAGED_SCHEMA_PATH = resolvePackagedAssetPath2("pourkit.schema.json");
12957
+ var PACKAGED_HASH_PATH = resolvePackagedAssetPath2("pourkit.schema.hash");
13193
12958
  var _schemaValidator = null;
13194
12959
  var _schemaErrors = null;
13195
12960
  function getSchemaValidator() {
@@ -13865,21 +13630,21 @@ function formatChecks2(checks) {
13865
13630
  init_common();
13866
13631
 
13867
13632
  // execution/sandcastle-execution.ts
13868
- import { mkdirSync as mkdirSync11, writeFileSync as writeFileSync8 } from "fs";
13869
- import { join as join22 } from "path";
13633
+ import { mkdirSync as mkdirSync9, writeFileSync as writeFileSync7 } from "fs";
13634
+ import { join as join21 } from "path";
13870
13635
  import { createWorktree, opencode } from "@ai-hero/sandcastle";
13871
13636
  import { docker } from "@ai-hero/sandcastle/sandboxes/docker";
13872
13637
 
13873
13638
  // execution/execution-provider.ts
13874
13639
  init_common();
13875
- import { mkdtempSync as mkdtempSync2 } from "fs";
13640
+ import { mkdtempSync } from "fs";
13876
13641
  import { writeFile as writeFile4 } from "fs/promises";
13877
- import { tmpdir as tmpdir2 } from "os";
13878
- import { dirname as dirname7, join as join21 } from "path";
13642
+ import { tmpdir } from "os";
13643
+ import { dirname as dirname6, join as join20 } from "path";
13879
13644
  async function writeExecutionArtifacts(worktreePath, artifacts) {
13880
13645
  for (const artifact of artifacts) {
13881
- const filePath = join21(worktreePath, artifact.path);
13882
- await ensureDir(dirname7(filePath));
13646
+ const filePath = join20(worktreePath, artifact.path);
13647
+ await ensureDir(dirname6(filePath));
13883
13648
  await writeFile4(filePath, artifact.content, "utf-8");
13884
13649
  }
13885
13650
  }
@@ -13889,7 +13654,7 @@ init_common();
13889
13654
  import path7 from "path";
13890
13655
 
13891
13656
  // execution/sandbox-image.ts
13892
- import { createHash as createHash4 } from "crypto";
13657
+ import { createHash as createHash3 } from "crypto";
13893
13658
  import { existsSync as existsSync19, readFileSync as readFileSync20 } from "fs";
13894
13659
  import path6 from "path";
13895
13660
  function sandboxImageName(repoRoot2) {
@@ -13900,7 +13665,7 @@ function sandboxImageName(repoRoot2) {
13900
13665
  if (!existsSync19(dockerfilePath)) {
13901
13666
  return `sandcastle:${baseName}`;
13902
13667
  }
13903
- const fingerprint = createHash4("sha256").update(readFileSync20(dockerfilePath)).digest("hex").slice(0, 8);
13668
+ const fingerprint = createHash3("sha256").update(readFileSync20(dockerfilePath)).digest("hex").slice(0, 8);
13904
13669
  return `sandcastle:${baseName}-${fingerprint}`;
13905
13670
  }
13906
13671
 
@@ -14196,13 +13961,13 @@ function isPlainObject(value) {
14196
13961
  return typeof value === "object" && value !== null && !Array.isArray(value);
14197
13962
  }
14198
13963
  function savePromptToFile(repoRoot2, stage, iteration, prompt) {
14199
- const promptsDir = join22(repoRoot2, ".pourkit", ".tmp", "prompts");
14200
- mkdirSync11(promptsDir, { recursive: true });
13964
+ const promptsDir = join21(repoRoot2, ".pourkit", ".tmp", "prompts");
13965
+ mkdirSync9(promptsDir, { recursive: true });
14201
13966
  const timestamp2 = Date.now();
14202
13967
  const iterationSuffix = iteration !== void 0 ? `-iteration-${iteration}` : "";
14203
13968
  const filename = `${stage}${iterationSuffix}-${timestamp2}.md`;
14204
- const filePath = join22(promptsDir, filename);
14205
- writeFileSync8(filePath, prompt, "utf-8");
13969
+ const filePath = join21(promptsDir, filename);
13970
+ writeFileSync7(filePath, prompt, "utf-8");
14206
13971
  }
14207
13972
 
14208
13973
  // cli.ts
@@ -14302,7 +14067,7 @@ function createCliProgram(version) {
14302
14067
  });
14303
14068
  program.command("validate-artifact").description("Validate an agent handoff artifact").argument(
14304
14069
  "<kind>",
14305
- "artifact kind: reviewer, refactor, finalizer, conflict-resolution, final-review (retained for Issue Final Review validation), failure-resolution, local-prd, local-issue, local-triage, or issue-final-review"
14070
+ "artifact kind: reviewer, refactor, finalizer, conflict-resolution, failure-resolution, local-prd, local-issue, local-triage, or issue-final-review"
14306
14071
  ).argument("<artifactPath>", "artifact path to validate").argument("[extraPaths...]", "additional artifact paths (for local-triage)").option("--iteration <number>", "review/refactor iteration", (value) => {
14307
14072
  const parsed = Number.parseInt(value, 10);
14308
14073
  if (!Number.isInteger(parsed) || parsed < 1) {
@@ -14335,12 +14100,6 @@ function createCliProgram(version) {
14335
14100
  return previous;
14336
14101
  },
14337
14102
  []
14338
- ).option("--prd-ref <ref>", "PRD ref for final-review artifacts").option(
14339
- "--checkout-base <ref>",
14340
- "checkout base / PRD branch for final-review artifacts"
14341
- ).option(
14342
- "--review-base <ref>",
14343
- "review merge base for final-review artifacts"
14344
14103
  ).option(
14345
14104
  "--issue-number <number>",
14346
14105
  "issue number for issue-final-review artifacts",
@@ -14365,7 +14124,6 @@ function createCliProgram(version) {
14365
14124
  "refactor",
14366
14125
  "finalizer",
14367
14126
  "conflict-resolution",
14368
- "final-review",
14369
14127
  "failure-resolution",
14370
14128
  "local-prd",
14371
14129
  "local-issue",
@@ -14399,9 +14157,6 @@ function createCliProgram(version) {
14399
14157
  findingIds: options.findingId,
14400
14158
  latestReviewArtifactPath: options.latestReviewArtifact,
14401
14159
  allowedDecisions: options.allowedDecision,
14402
- prdRef: options.prdRef,
14403
- checkoutBase: options.checkoutBase,
14404
- reviewBase: options.reviewBase,
14405
14160
  issueNumber: options.issueNumber,
14406
14161
  branchName: options.branchName,
14407
14162
  checkConflictMarkers: options.checkConflictMarkers
@@ -14905,11 +14660,11 @@ function createCliProgram(version) {
14905
14660
  return program;
14906
14661
  }
14907
14662
  async function resolveCliVersion() {
14908
- if (isPackageVersion("0.0.0-next-20260614074434")) {
14909
- return "0.0.0-next-20260614074434";
14663
+ if (isPackageVersion("0.0.0-next-20260614201555")) {
14664
+ return "0.0.0-next-20260614201555";
14910
14665
  }
14911
- if (isReleaseVersion("0.0.0-next-20260614074434")) {
14912
- return "0.0.0-next-20260614074434";
14666
+ if (isReleaseVersion("0.0.0-next-20260614201555")) {
14667
+ return "0.0.0-next-20260614201555";
14913
14668
  }
14914
14669
  try {
14915
14670
  const root = repoRoot();