@pourkit/cli 0.0.0-next-20260621233457 → 0.0.0-next-20260622201317

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
@@ -1513,16 +1513,6 @@ function renderCommandList(target, heading, repoRoot2) {
1513
1513
  "Use the wrapper as the configured verification method for Builder, Reviewer, Refactor, and Issue Final Review handoffs. Run the underlying commands directly only when no wrapper path can run, and record that degraded path in the role's artifact or handoff notes.",
1514
1514
  ""
1515
1515
  ];
1516
- if (isPourkitSourceRepo(repoRoot2)) {
1517
- parts.push(
1518
- "Pourkit self-development fallback:",
1519
- "",
1520
- `- If \`${wrapperCommand}\` fails before running configured commands because the installed CLI rejects this worktree's config schemaVersion, build and rerun the same target with the worktree-local CLI: \`npm run build --workspace pourkit\`, then \`node pourkit/dist/cli.js run-verification --target ${target.name}\`.`,
1521
- '- Treat local CLI wrapper success as valid configured verification and record it as `verification.method: "local-wrapper"` in Issue Final Review artifacts, or as local-wrapper verification in Builder/Reviewer/Refactor handoff notes.',
1522
- '- Fall back to the underlying configured commands only if the worktree-local CLI cannot be built or invoked; record that degraded path as `verification.method: "commands"` in Issue Final Review artifacts, or as direct-command verification in Builder/Reviewer/Refactor handoff notes, and explain why the wrapper path could not run.',
1523
- ""
1524
- );
1525
- }
1526
1516
  if (commands.length > 0) {
1527
1517
  parts.push(
1528
1518
  "Configured commands executed by the wrapper:",
@@ -1535,17 +1525,6 @@ function renderCommandList(target, heading, repoRoot2) {
1535
1525
  }
1536
1526
  return parts;
1537
1527
  }
1538
- function isPourkitSourceRepo(repoRoot2) {
1539
- if (!repoRoot2) return false;
1540
- const packagePath = join5(repoRoot2, "pourkit", "package.json");
1541
- if (!existsSync4(packagePath)) return false;
1542
- try {
1543
- const parsed = JSON.parse(readFileSync4(packagePath, "utf-8"));
1544
- return parsed.name === "@pourkit/cli";
1545
- } catch {
1546
- return false;
1547
- }
1548
- }
1549
1528
  function renderParentPrdContext(issue, parentPrdIssue, repoRoot2) {
1550
1529
  const parent = extractIssueSection(issue.body, "Parent");
1551
1530
  const parentRef = parent?.match(/\bPRD-\d+\b/i)?.[0]?.toUpperCase() ?? issue.title.match(/^\s*(PRD-\d+)\s*\/\s*I-\d+\b/i)?.[1]?.toUpperCase();
@@ -2291,7 +2270,6 @@ Read the selected issue requirements, planning context (including plan and PRD c
2291
2270
 
2292
2271
  - First read ${RUN_CONTEXT_PATH_IN_WORKTREE} only far enough to identify the configured verification commands.
2293
2272
  - Before reviewing code, diffs, artifacts, or prior findings, run the configured verification wrapper yourself from the Worktree.
2294
- - If ${RUN_CONTEXT_PATH_IN_WORKTREE} provides a worktree-local CLI fallback, use that fallback before considering direct command execution.
2295
2273
  - Run underlying verification commands directly only when no wrapper path can run, and record why verification used direct commands.
2296
2274
  - If a configured command fails, keep reviewing after recording the failure details; use the failure output as review evidence.
2297
2275
  - If a command cannot run because the environment is missing required setup, dependencies, or scripts outside agent control, treat it as a human handoff blocker.
@@ -2542,7 +2520,6 @@ Read the selected issue requirements, planning context (including plan and PRD c
2542
2520
  ## Verification Handoff
2543
2521
 
2544
2522
  - Run the verification wrapper listed in ${RUN_CONTEXT_PATH_IN_WORKTREE} after making changes.
2545
- - If ${RUN_CONTEXT_PATH_IN_WORKTREE} provides a worktree-local CLI fallback, use that fallback before considering direct command execution.
2546
2523
  - Run underlying verification commands directly only when no wrapper path can run, and record why verification used direct commands in the Refactor Artifact.
2547
2524
  - If configured verification fails because of fixable Issue work, fix the work and rerun verification before handoff.
2548
2525
  - Failed or blocked verification prohibits <promise>COMPLETE</promise>.
@@ -3260,12 +3237,6 @@ var ISSUE_FINAL_REVIEW_SCOPE_VERDICTS = [
3260
3237
  "incidental",
3261
3238
  "out-of-scope"
3262
3239
  ];
3263
- var ISSUE_FINAL_REVIEW_VERIFICATION_METHODS = [
3264
- "wrapper",
3265
- "local-wrapper",
3266
- "commands",
3267
- "none"
3268
- ];
3269
3240
  function invalid(options, reason, diagnostics = []) {
3270
3241
  return {
3271
3242
  ok: false,
@@ -3573,15 +3544,6 @@ function validateIssueFinalReviewArtifact(parsed, options) {
3573
3544
  diagnostics
3574
3545
  };
3575
3546
  }
3576
- if ("method" in verification && !ISSUE_FINAL_REVIEW_VERIFICATION_METHODS.includes(
3577
- verification.method
3578
- )) {
3579
- return {
3580
- ok: false,
3581
- reason: 'verification.method must be "wrapper", "local-wrapper", "commands", or "none"',
3582
- diagnostics
3583
- };
3584
- }
3585
3547
  diagnostics.push("verification: present");
3586
3548
  const verificationWasRecorded = verification.required === true || Array.isArray(verification.commands) && verification.commands.length > 0;
3587
3549
  if (parsed.verdict === "pass" && verificationWasRecorded) {
@@ -3596,20 +3558,6 @@ function validateIssueFinalReviewArtifact(parsed, options) {
3596
3558
  ]
3597
3559
  };
3598
3560
  }
3599
- if (typeof verification.method !== "string") {
3600
- return {
3601
- ok: false,
3602
- reason: "Issue Final Review pass with verification evidence requires verification.method",
3603
- diagnostics
3604
- };
3605
- }
3606
- if (verification.method === "none") {
3607
- return {
3608
- ok: false,
3609
- reason: 'Issue Final Review pass with verification evidence requires verification.method other than "none"',
3610
- diagnostics
3611
- };
3612
- }
3613
3561
  diagnostics.push("pass verification: valid");
3614
3562
  }
3615
3563
  if (parsed.selfRetouched === true && parsed.verdict === "pass") {
@@ -3794,7 +3742,6 @@ function shellQuote(value) {
3794
3742
 
3795
3743
  // commands/issue-run.ts
3796
3744
  import { existsSync as existsSync13, readFileSync as readFileSync15 } from "fs";
3797
- import { isAbsolute as isAbsolute4, join as join15 } from "path";
3798
3745
 
3799
3746
  // pr/templates.ts
3800
3747
  init_common();
@@ -4973,7 +4920,6 @@ Read the selected issue requirements, planning context (including plan and PRD c
4973
4920
  ## Verification Handoff
4974
4921
 
4975
4922
  - Run the verification wrapper listed in ${RUN_CONTEXT_PATH_IN_WORKTREE}.
4976
- - If ${RUN_CONTEXT_PATH_IN_WORKTREE} provides a worktree-local CLI fallback, use that fallback before considering direct command execution.
4977
4923
  - Run underlying verification commands directly only when no wrapper path can run, and report why verification used direct commands.
4978
4924
  - If configured verification fails because of fixable Issue work, fix the work and rerun verification before handoff.
4979
4925
  - Failed or blocked verification prohibits <promise>COMPLETE</promise>.`);
@@ -5922,9 +5868,6 @@ function buildIssueFinalReviewPrComment(artifact) {
5922
5868
  `- **Required:** ${formatBoolean(artifact.verification.required)}`,
5923
5869
  `- **Passed:** ${formatBoolean(artifact.verification.passed)}`
5924
5870
  );
5925
- if (typeof artifact.verification.method === "string") {
5926
- lines.push(`- **Method:** ${formatLabel(artifact.verification.method)}`);
5927
- }
5928
5871
  const commands = Array.isArray(artifact.verification.commands) ? artifact.verification.commands.filter(
5929
5872
  (command) => typeof command === "string"
5930
5873
  ) : [];
@@ -6147,16 +6090,17 @@ function isAllowedDocumentationTokenReference(value) {
6147
6090
  return /^token\s*:\s*["']?<verdict>/i.test(value);
6148
6091
  }
6149
6092
 
6150
- // commands/issue-final-review-agent.ts
6093
+ // issues/issue-final-review.ts
6151
6094
  import { existsSync as existsSync12, readFileSync as readFileSync14 } from "fs";
6152
- import { join as join13 } from "path";
6095
+ import { isAbsolute as isAbsolute4, join as join13 } from "path";
6096
+ init_common();
6153
6097
  var ISSUE_FINAL_REVIEW_ARTIFACT_PATH = join13(
6154
6098
  ".pourkit",
6155
6099
  ".tmp",
6156
6100
  "issue-final-review",
6157
6101
  "agent-output.json"
6158
6102
  );
6159
- async function runIssueFinalReviewAgent(options) {
6103
+ async function runIssueFinalReview(options) {
6160
6104
  const {
6161
6105
  executionProvider,
6162
6106
  target,
@@ -6169,6 +6113,34 @@ async function runIssueFinalReviewAgent(options) {
6169
6113
  } = options;
6170
6114
  const artifactPathInWorktree = ISSUE_FINAL_REVIEW_ARTIFACT_PATH;
6171
6115
  const artifactPath = join13(worktreePath, artifactPathInWorktree);
6116
+ const ifrFromState = options.worktreeState?.issueFinalReview;
6117
+ if (ifrFromState?.completed && ifrFromState.verdict === "pass") {
6118
+ if (!ifrFromState.artifactPath) {
6119
+ throw new Error(
6120
+ "Issue Final Review state is incomplete: missing artifactPath"
6121
+ );
6122
+ }
6123
+ const cachedArtifactPath = isAbsolute4(ifrFromState.artifactPath) ? ifrFromState.artifactPath : join13(worktreePath, ifrFromState.artifactPath);
6124
+ const validation2 = validateAgentArtifact({
6125
+ kind: "issue-final-review",
6126
+ artifactPath: cachedArtifactPath,
6127
+ issueNumber: issue.number,
6128
+ branchName: builderBranch
6129
+ });
6130
+ if (!validation2.ok) {
6131
+ throw new Error(
6132
+ `Issue Final Review state artifact is invalid: ${validation2.reason}`
6133
+ );
6134
+ }
6135
+ return {
6136
+ status: "skipped",
6137
+ verdict: "pass",
6138
+ artifactPath: cachedArtifactPath,
6139
+ selfRetouched: ifrFromState.selfRetouched ?? false,
6140
+ changedPaths: ifrFromState.changedPaths ?? [],
6141
+ verificationPassed: ifrFromState.verificationPassed ?? false
6142
+ };
6143
+ }
6172
6144
  const strategy = target.strategy;
6173
6145
  const issueFinalReview = strategy.issueFinalReview;
6174
6146
  const agent = issueFinalReview;
@@ -6245,17 +6217,42 @@ async function runIssueFinalReviewAgent(options) {
6245
6217
  }
6246
6218
  const parsed = JSON.parse(content);
6247
6219
  const verdict = parsed.verdict;
6220
+ const baseRef = `origin/${target.baseBranch}`;
6221
+ await assertCanonicalBaseAncestor2({
6222
+ worktreePath,
6223
+ baseRef,
6224
+ stageName: "Issue Final Review",
6225
+ logger
6226
+ });
6248
6227
  if (verdict === "pass") {
6228
+ const changedPaths = await completeIssueFinalReviewChangedPaths({
6229
+ worktreePath,
6230
+ baseRef,
6231
+ declaredChangedPaths: extractChangedPaths(parsed),
6232
+ logger
6233
+ });
6234
+ updateWorktreeRunState(worktreePath, {
6235
+ issueFinalReview: {
6236
+ completed: true,
6237
+ verdict: "pass",
6238
+ artifactPath,
6239
+ selfRetouched: parsed.selfRetouched === true,
6240
+ changedPaths,
6241
+ verificationPassed: parsed.verification?.passed === true
6242
+ }
6243
+ });
6249
6244
  return {
6245
+ status: "passed",
6250
6246
  verdict: "pass",
6251
6247
  artifactPath,
6252
6248
  selfRetouched: parsed.selfRetouched === true,
6253
- changedPaths: extractChangedPaths(parsed),
6249
+ changedPaths,
6254
6250
  verificationPassed: parsed.verification?.passed === true
6255
6251
  };
6256
6252
  }
6257
6253
  if (verdict === "needs_human_review") {
6258
6254
  return {
6255
+ status: "needs_human_review",
6259
6256
  verdict: "needs_human_review",
6260
6257
  artifactPath,
6261
6258
  needsHumanReason: parsed.needsHumanReason,
@@ -6267,6 +6264,89 @@ async function runIssueFinalReviewAgent(options) {
6267
6264
  `Unknown Issue Final Review verdict: ${JSON.stringify(verdict)}`
6268
6265
  );
6269
6266
  }
6267
+ async function assertCanonicalBaseAncestor2(options) {
6268
+ const { worktreePath, baseRef, stageName, logger } = options;
6269
+ await syncRemoteBaseRef2(worktreePath, baseRef, logger);
6270
+ try {
6271
+ await execCapture("git", ["merge-base", "--is-ancestor", baseRef, "HEAD"], {
6272
+ cwd: worktreePath,
6273
+ logger,
6274
+ label: "git merge-base --is-ancestor"
6275
+ });
6276
+ } catch {
6277
+ throw new Error(
6278
+ `Cannot continue after ${stageName}: ${baseRef} is not an ancestor of HEAD. An agent may have moved the issue branch behind the canonical base; refresh the branch onto the latest target base before continuing.`
6279
+ );
6280
+ }
6281
+ }
6282
+ async function syncRemoteBaseRef2(worktreePath, baseRef, logger) {
6283
+ const remoteBase = parseRemoteBaseRef2(baseRef);
6284
+ if (!remoteBase) {
6285
+ return;
6286
+ }
6287
+ await execCapture("git", ["fetch", remoteBase.remote, remoteBase.branch], {
6288
+ cwd: worktreePath,
6289
+ logger,
6290
+ label: "git fetch target"
6291
+ });
6292
+ }
6293
+ function parseRemoteBaseRef2(baseRef) {
6294
+ const [remote, ...branchParts] = baseRef.split("/");
6295
+ const branch = branchParts.join("/");
6296
+ if (!remote || !branch) {
6297
+ return null;
6298
+ }
6299
+ return { remote, branch };
6300
+ }
6301
+ async function completeIssueFinalReviewChangedPaths(options) {
6302
+ const actualChangedPaths = await listIssueFinalReviewChangedPaths2(options);
6303
+ const declared = new Set(options.declaredChangedPaths.map(normalizeGitPath2));
6304
+ const missing = actualChangedPaths.filter((path9) => !declared.has(path9));
6305
+ if (missing.length === 0) {
6306
+ return actualChangedPaths;
6307
+ }
6308
+ options.logger.step(
6309
+ "warn",
6310
+ `Issue Final Review pass omitted ${missing.length} changed file(s) from changedFiles; using git inventory for finalization state.`
6311
+ );
6312
+ options.logger.kv("MISSING_CHANGED_FILES", missing.join(", "));
6313
+ return actualChangedPaths;
6314
+ }
6315
+ async function listIssueFinalReviewChangedPaths2(options) {
6316
+ const trackedDiff = await execCapture(
6317
+ "git",
6318
+ ["diff-index", "--name-only", options.baseRef, "--"],
6319
+ {
6320
+ cwd: options.worktreePath,
6321
+ logger: options.logger,
6322
+ label: "git diff-index Issue Final Review paths"
6323
+ }
6324
+ );
6325
+ const untrackedFiles = await execCapture(
6326
+ "git",
6327
+ ["ls-files", "--others", "--exclude-standard"],
6328
+ {
6329
+ cwd: options.worktreePath,
6330
+ logger: options.logger,
6331
+ label: "git ls-files Issue Final Review paths"
6332
+ }
6333
+ );
6334
+ return Array.from(
6335
+ /* @__PURE__ */ new Set([
6336
+ ...parseGitPathList2(trackedDiff.stdout),
6337
+ ...parseGitPathList2(untrackedFiles.stdout)
6338
+ ])
6339
+ ).filter(isIssueFinalReviewAuditedPath2);
6340
+ }
6341
+ function parseGitPathList2(output) {
6342
+ return output.split(/\r?\n/).map(normalizeGitPath2).filter((path9) => path9.length > 0);
6343
+ }
6344
+ function normalizeGitPath2(path9) {
6345
+ return path9.replace(/^"|"$/g, "").replace(/\\/g, "/").replace(/^\.\/+/, "").replace(/\/+$/, "");
6346
+ }
6347
+ function isIssueFinalReviewAuditedPath2(path9) {
6348
+ return path9 !== "" && path9 !== WORKTREE_RUN_STATE_PATH && !path9.startsWith(".pourkit/.tmp/") && !path9.startsWith(".pourkit/logs/");
6349
+ }
6270
6350
  function extractChangedPaths(parsed) {
6271
6351
  return Array.isArray(parsed.changedFiles) ? parsed.changedFiles.map(
6272
6352
  (file) => file && typeof file === "object" ? file.path : void 0
@@ -6292,9 +6372,7 @@ Read the selected issue requirements, planning context (including plan and PRD c
6292
6372
 
6293
6373
  - First read ${RUN_CONTEXT_PATH_IN_WORKTREE} only far enough to identify the configured verification commands.
6294
6374
  - Before reviewing code, diffs, artifacts, or prior findings, run the verification wrapper from the Worktree.
6295
- - If the installed Pourkit CLI rejects the worktree config schemaVersion and the Run Context provides a Pourkit self-development fallback, build and run the worktree-local CLI wrapper exactly as instructed.
6296
- - Do not substitute direct underlying commands unless neither wrapper path can run; if you must use direct commands, record degraded verification with \`verification.method: "commands"\` and explain why in \`verification.summary\`.
6297
- - Record successful wrapper verification with \`verification.method: "wrapper"\`, or worktree-local CLI wrapper verification with \`verification.method: "local-wrapper"\`.
6375
+ - Do not substitute direct underlying commands unless no wrapper path can run; if you must use direct commands, explain why in \`verification.summary\`.
6298
6376
  - If a configured verification command fails because of fixable Issue work, self-retouch the Worktree, then rerun all configured verification commands.
6299
6377
  - Do not return \`pass\` while any configured verification command is failing.
6300
6378
  - If a command cannot run because the environment is missing required setup, dependencies, or scripts outside agent control, treat it as a human handoff blocker.
@@ -6507,90 +6585,7 @@ function assertIssueFinalReviewPassed(worktreeState) {
6507
6585
  }
6508
6586
  }
6509
6587
  async function advanceIssueFinalReview(options) {
6510
- const {
6511
- executionProvider,
6512
- config,
6513
- target,
6514
- issue,
6515
- parentPrdIssue,
6516
- builderBranch,
6517
- worktreePath,
6518
- repoRoot: repoRoot2,
6519
- logger,
6520
- reviewArtifactPath,
6521
- reviewVerdict,
6522
- worktreeState
6523
- } = options;
6524
- const ifrFromState = worktreeState?.issueFinalReview;
6525
- if (ifrFromState?.completed && ifrFromState.verdict === "pass") {
6526
- if (!ifrFromState.artifactPath) {
6527
- throw new Error(
6528
- "Issue Final Review state is incomplete: missing artifactPath"
6529
- );
6530
- }
6531
- const artifactPath = isAbsolute4(ifrFromState.artifactPath) ? ifrFromState.artifactPath : join15(worktreePath, ifrFromState.artifactPath);
6532
- const validation = validateAgentArtifact({
6533
- kind: "issue-final-review",
6534
- artifactPath,
6535
- issueNumber: issue.number,
6536
- branchName: builderBranch
6537
- });
6538
- if (!validation.ok) {
6539
- throw new Error(
6540
- `Issue Final Review state artifact is invalid: ${validation.reason}`
6541
- );
6542
- }
6543
- return {
6544
- verdict: "pass",
6545
- artifactPath,
6546
- selfRetouched: ifrFromState.selfRetouched ?? false,
6547
- changedPaths: ifrFromState.changedPaths ?? [],
6548
- verificationPassed: ifrFromState.verificationPassed ?? false
6549
- };
6550
- }
6551
- const result = await runIssueFinalReviewAgent({
6552
- executionProvider,
6553
- config,
6554
- target,
6555
- issue,
6556
- parentPrdIssue,
6557
- builderBranch,
6558
- worktreePath,
6559
- repoRoot: repoRoot2,
6560
- logger,
6561
- reviewArtifactPath,
6562
- reviewVerdict,
6563
- ...options.memory ? { memory: options.memory } : {}
6564
- });
6565
- await assertCanonicalBaseAncestor2({
6566
- worktreePath,
6567
- baseRef: `origin/${target.baseBranch}`,
6568
- stageName: "Issue Final Review",
6569
- logger
6570
- });
6571
- if (result.verdict === "pass") {
6572
- const changedPaths = await completeIssueFinalReviewChangedPaths({
6573
- worktreePath,
6574
- baseRef: `origin/${target.baseBranch}`,
6575
- declaredChangedPaths: result.changedPaths,
6576
- logger
6577
- });
6578
- updateWorktreeRunState(worktreePath, {
6579
- issueFinalReview: {
6580
- completed: true,
6581
- verdict: "pass",
6582
- artifactPath: result.artifactPath,
6583
- selfRetouched: result.selfRetouched,
6584
- changedPaths,
6585
- verificationPassed: result.verificationPassed
6586
- }
6587
- });
6588
- return {
6589
- ...result,
6590
- changedPaths
6591
- };
6592
- }
6593
- return result;
6588
+ return runIssueFinalReview(options);
6594
6589
  }
6595
6590
  async function startIssueRun(options) {
6596
6591
  const {
@@ -7026,89 +7021,6 @@ async function finalizeWorktreeCommit(options) {
7026
7021
  label: "git commit"
7027
7022
  });
7028
7023
  }
7029
- async function assertCanonicalBaseAncestor2(options) {
7030
- const { worktreePath, baseRef, stageName, logger } = options;
7031
- await syncRemoteBaseRef2(worktreePath, baseRef, logger);
7032
- try {
7033
- await execCapture("git", ["merge-base", "--is-ancestor", baseRef, "HEAD"], {
7034
- cwd: worktreePath,
7035
- logger,
7036
- label: "git merge-base --is-ancestor"
7037
- });
7038
- } catch {
7039
- throw new Error(
7040
- `Cannot continue after ${stageName}: ${baseRef} is not an ancestor of HEAD. An agent may have moved the issue branch behind the canonical base; refresh the branch onto the latest target base before continuing.`
7041
- );
7042
- }
7043
- }
7044
- async function completeIssueFinalReviewChangedPaths(options) {
7045
- const actualChangedPaths = await listIssueFinalReviewChangedPaths2(options);
7046
- const declared = new Set(options.declaredChangedPaths.map(normalizeGitPath2));
7047
- const missing = actualChangedPaths.filter((path9) => !declared.has(path9));
7048
- if (missing.length === 0) {
7049
- return actualChangedPaths;
7050
- }
7051
- options.logger.step(
7052
- "warn",
7053
- `Issue Final Review pass omitted ${missing.length} changed file(s) from changedFiles; using git inventory for finalization state.`
7054
- );
7055
- options.logger.kv("MISSING_CHANGED_FILES", missing.join(", "));
7056
- return actualChangedPaths;
7057
- }
7058
- async function listIssueFinalReviewChangedPaths2(options) {
7059
- const trackedDiff = await execCapture(
7060
- "git",
7061
- ["diff-index", "--name-only", options.baseRef, "--"],
7062
- {
7063
- cwd: options.worktreePath,
7064
- logger: options.logger,
7065
- label: "git diff-index Issue Final Review paths"
7066
- }
7067
- );
7068
- const untrackedFiles = await execCapture(
7069
- "git",
7070
- ["ls-files", "--others", "--exclude-standard"],
7071
- {
7072
- cwd: options.worktreePath,
7073
- logger: options.logger,
7074
- label: "git ls-files Issue Final Review paths"
7075
- }
7076
- );
7077
- return Array.from(
7078
- /* @__PURE__ */ new Set([
7079
- ...parseGitPathList2(trackedDiff.stdout),
7080
- ...parseGitPathList2(untrackedFiles.stdout)
7081
- ])
7082
- ).filter(isIssueFinalReviewAuditedPath2);
7083
- }
7084
- function parseGitPathList2(output) {
7085
- return output.split(/\r?\n/).map(normalizeGitPath2).filter((path9) => path9.length > 0);
7086
- }
7087
- function normalizeGitPath2(path9) {
7088
- return path9.replace(/^"|"$/g, "").replace(/\\/g, "/").replace(/^\.\/+/, "").replace(/\/+$/, "");
7089
- }
7090
- function isIssueFinalReviewAuditedPath2(path9) {
7091
- return path9 !== "" && path9 !== WORKTREE_RUN_STATE_PATH && !path9.startsWith(".pourkit/.tmp/") && !path9.startsWith(".pourkit/logs/");
7092
- }
7093
- async function syncRemoteBaseRef2(worktreePath, baseRef, logger) {
7094
- const remoteBase = parseRemoteBaseRef2(baseRef);
7095
- if (!remoteBase) {
7096
- return;
7097
- }
7098
- await execCapture("git", ["fetch", remoteBase.remote, remoteBase.branch], {
7099
- cwd: worktreePath,
7100
- logger,
7101
- label: "git fetch target"
7102
- });
7103
- }
7104
- function parseRemoteBaseRef2(baseRef) {
7105
- const [remote, ...branchParts] = baseRef.split("/");
7106
- const branch = branchParts.join("/");
7107
- if (!remote || !branch) {
7108
- return null;
7109
- }
7110
- return { remote, branch };
7111
- }
7112
7024
  function makeIssueTransitions2(provider, config) {
7113
7025
  return createIssueTransitions(
7114
7026
  {
@@ -7257,7 +7169,7 @@ async function runIssueLifecycle(options) {
7257
7169
  worktreeState: startResult.worktreeState,
7258
7170
  memory: startResult.memory
7259
7171
  });
7260
- if (finalReviewResult.verdict === "needs_human_review") {
7172
+ if (finalReviewResult.status === "needs_human_review") {
7261
7173
  await options.deps.transitionIssueFinalReviewNeedsHumanToHandoff({
7262
7174
  issueNumber: options.issueNumber,
7263
7175
  finalReviewResult
@@ -7451,7 +7363,7 @@ async function runIssueCreateCommand(args, issueProvider, logger) {
7451
7363
 
7452
7364
  // commands/prd-run.ts
7453
7365
  import { lstatSync, realpathSync } from "fs";
7454
- import { join as join17 } from "path";
7366
+ import { join as join16 } from "path";
7455
7367
 
7456
7368
  // prd-run/state.ts
7457
7369
  import {
@@ -7461,7 +7373,7 @@ import {
7461
7373
  readdirSync as readdirSync3,
7462
7374
  writeFileSync as writeFileSync4
7463
7375
  } from "fs";
7464
- import { join as join16 } from "path";
7376
+ import { join as join15 } from "path";
7465
7377
  import { z } from "zod";
7466
7378
  var PRD_RUN_STATE_DIR = ".pourkit/prd-runs";
7467
7379
  var PrdRunRecordSchema = z.object({
@@ -7576,7 +7488,7 @@ function readPrdRun(repoRoot2, prdRef) {
7576
7488
  }
7577
7489
  }
7578
7490
  function listPrdRuns(repoRoot2) {
7579
- const stateDir = join16(repoRoot2, PRD_RUN_STATE_DIR);
7491
+ const stateDir = join15(repoRoot2, PRD_RUN_STATE_DIR);
7580
7492
  if (!existsSync14(stateDir)) {
7581
7493
  return { records: [], diagnostics: [] };
7582
7494
  }
@@ -7586,7 +7498,7 @@ function listPrdRuns(repoRoot2) {
7586
7498
  (left, right) => left.name.localeCompare(right.name)
7587
7499
  )) {
7588
7500
  if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
7589
- const recordPath = join16(stateDir, entry.name);
7501
+ const recordPath = join15(stateDir, entry.name);
7590
7502
  try {
7591
7503
  const record = PrdRunRecordSchema.parse(
7592
7504
  JSON.parse(readFileSync16(recordPath, "utf-8"))
@@ -7602,7 +7514,7 @@ function listPrdRuns(repoRoot2) {
7602
7514
  }
7603
7515
  function writePrdRunRecord(repoRoot2, record) {
7604
7516
  const normalized = normalizePrdRunRef(record.prdRef);
7605
- const stateDir = join16(repoRoot2, PRD_RUN_STATE_DIR);
7517
+ const stateDir = join15(repoRoot2, PRD_RUN_STATE_DIR);
7606
7518
  const recordPath = getRecordPath(repoRoot2, normalized);
7607
7519
  mkdirSync7(stateDir, { recursive: true });
7608
7520
  writeFileSync4(
@@ -7612,7 +7524,7 @@ function writePrdRunRecord(repoRoot2, record) {
7612
7524
  );
7613
7525
  }
7614
7526
  function getRecordPath(repoRoot2, prdRef) {
7615
- return join16(
7527
+ return join15(
7616
7528
  repoRoot2,
7617
7529
  PRD_RUN_STATE_DIR,
7618
7530
  `${normalizePrdRunRef(prdRef)}.json`
@@ -12383,10 +12295,10 @@ Init applied: ${result.applied} operations applied, ${result.skipped} skipped.`
12383
12295
 
12384
12296
  // commands/memory-init.ts
12385
12297
  import { existsSync as existsSync17, mkdirSync as mkdirSync8, readFileSync as readFileSync18, writeFileSync as writeFileSync5 } from "fs";
12386
- import { join as join18 } from "path";
12298
+ import { join as join17 } from "path";
12387
12299
  async function runMemoryInitCommand(options) {
12388
12300
  const cwd = options.cwd ?? process.cwd();
12389
- const configPath = join18(cwd, ".pourkit", "config.json");
12301
+ const configPath = join17(cwd, ".pourkit", "config.json");
12390
12302
  if (!existsSync17(configPath)) {
12391
12303
  return {
12392
12304
  ok: false,
@@ -12418,8 +12330,8 @@ async function runMemoryInitCommand(options) {
12418
12330
  const next = { ...raw, memory };
12419
12331
  writeFileSync5(configPath, JSON.stringify(next, null, 2) + "\n");
12420
12332
  }
12421
- mkdirSync8(join18(cwd, ".pourkit", "icm"), { recursive: true });
12422
- const gitignorePath = join18(cwd, ".gitignore");
12333
+ mkdirSync8(join17(cwd, ".pourkit", "icm"), { recursive: true });
12334
+ const gitignorePath = join17(cwd, ".gitignore");
12423
12335
  updateManagedBlockSync(gitignorePath, generateGitignoreBlock());
12424
12336
  const managed = await generateManagedAgentInstructions({
12425
12337
  sourceRoot: cwd,
@@ -12427,14 +12339,14 @@ async function runMemoryInitCommand(options) {
12427
12339
  });
12428
12340
  let updatedAgentFile = false;
12429
12341
  for (const fileName of ["AGENTS.md", "CLAUDE.md"]) {
12430
- const agentPath = join18(cwd, fileName);
12342
+ const agentPath = join17(cwd, fileName);
12431
12343
  if (existsSync17(agentPath)) {
12432
12344
  updateManagedBlockSync(agentPath, managed);
12433
12345
  updatedAgentFile = true;
12434
12346
  }
12435
12347
  }
12436
12348
  if (!updatedAgentFile) {
12437
- updateManagedBlockSync(join18(cwd, "AGENTS.md"), managed);
12349
+ updateManagedBlockSync(join17(cwd, "AGENTS.md"), managed);
12438
12350
  }
12439
12351
  return {
12440
12352
  ok: true,
@@ -14431,7 +14343,7 @@ init_common();
14431
14343
 
14432
14344
  // execution/sandcastle-execution.ts
14433
14345
  import { existsSync as existsSync21, mkdirSync as mkdirSync9, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
14434
- import { join as join21 } from "path";
14346
+ import { join as join20 } from "path";
14435
14347
  import { createWorktree, opencode } from "@ai-hero/sandcastle";
14436
14348
  import { docker } from "@ai-hero/sandcastle/sandboxes/docker";
14437
14349
 
@@ -14440,10 +14352,10 @@ init_common();
14440
14352
  import { mkdtempSync } from "fs";
14441
14353
  import { writeFile as writeFile4 } from "fs/promises";
14442
14354
  import { tmpdir } from "os";
14443
- import { dirname as dirname7, join as join19 } from "path";
14355
+ import { dirname as dirname7, join as join18 } from "path";
14444
14356
  async function writeExecutionArtifacts(worktreePath, artifacts) {
14445
14357
  for (const artifact of artifacts) {
14446
- const filePath = join19(worktreePath, artifact.path);
14358
+ const filePath = join18(worktreePath, artifact.path);
14447
14359
  await ensureDir(dirname7(filePath));
14448
14360
  await writeFile4(filePath, artifact.content, "utf-8");
14449
14361
  }
@@ -14505,7 +14417,7 @@ async function createSandboxFromExistingWorktree(options) {
14505
14417
  }
14506
14418
 
14507
14419
  // execution/sandbox-options.ts
14508
- import { join as join20 } from "path";
14420
+ import { join as join19 } from "path";
14509
14421
  var POURKIT_ICM_CONTAINER_DIR = "/home/agent/.pourkit/icm";
14510
14422
  function buildSandboxOptions(repoRoot2, sandbox, memory) {
14511
14423
  const mounts = [];
@@ -14514,12 +14426,12 @@ function buildSandboxOptions(repoRoot2, sandbox, memory) {
14514
14426
  }
14515
14427
  if (memory?.available) {
14516
14428
  mounts.push({
14517
- hostPath: join20(repoRoot2, ".pourkit", "icm"),
14429
+ hostPath: join19(repoRoot2, ".pourkit", "icm"),
14518
14430
  sandboxPath: POURKIT_ICM_CONTAINER_DIR,
14519
14431
  readonly: false
14520
14432
  });
14521
14433
  mounts.push({
14522
- hostPath: join20(repoRoot2, ".pourkit", "icm", "cache"),
14434
+ hostPath: join19(repoRoot2, ".pourkit", "icm", "cache"),
14523
14435
  sandboxPath: "/home/agent/.cache/icm",
14524
14436
  readonly: false
14525
14437
  });
@@ -14653,13 +14565,13 @@ var SandcastleExecutionSession = class {
14653
14565
  "Memory enabled but memory context is invalid. Run `pourkit memory init` or install ICM for host planning use."
14654
14566
  );
14655
14567
  }
14656
- const hostMemoryDir = join21(repoRoot2, ".pourkit", "icm");
14568
+ const hostMemoryDir = join20(repoRoot2, ".pourkit", "icm");
14657
14569
  if (!existsSync21(hostMemoryDir) || !statSync2(hostMemoryDir).isDirectory()) {
14658
14570
  throw new MissingHostMemoryDirError(
14659
14571
  "Memory enabled but host .pourkit/icm/ directory is missing. Run `pourkit memory init` to create the repo-scoped memory store."
14660
14572
  );
14661
14573
  }
14662
- mkdirSync9(join21(hostMemoryDir, "cache"), { recursive: true });
14574
+ mkdirSync9(join20(hostMemoryDir, "cache"), { recursive: true });
14663
14575
  }
14664
14576
  const sandboxOptions = buildSandboxOptions(
14665
14577
  repoRoot2,
@@ -14818,7 +14730,7 @@ function sanitizeBranch(branchName) {
14818
14730
  }
14819
14731
  function safeCopyToWorktreePaths(paths, repoRoot2, worktreePath) {
14820
14732
  return paths.filter((relativePath) => {
14821
- const source = join21(repoRoot2, relativePath);
14733
+ const source = join20(repoRoot2, relativePath);
14822
14734
  if (!existsSync21(source)) {
14823
14735
  return true;
14824
14736
  }
@@ -14829,7 +14741,7 @@ function safeCopyToWorktreePaths(paths, repoRoot2, worktreePath) {
14829
14741
  } catch {
14830
14742
  return true;
14831
14743
  }
14832
- const destination = join21(worktreePath, relativePath);
14744
+ const destination = join20(worktreePath, relativePath);
14833
14745
  return !existsSync21(destination);
14834
14746
  });
14835
14747
  }
@@ -14894,12 +14806,12 @@ function isPlainObject(value) {
14894
14806
  return typeof value === "object" && value !== null && !Array.isArray(value);
14895
14807
  }
14896
14808
  function savePromptToFile(repoRoot2, stage, iteration, prompt) {
14897
- const promptsDir = join21(repoRoot2, ".pourkit", ".tmp", "prompts");
14809
+ const promptsDir = join20(repoRoot2, ".pourkit", ".tmp", "prompts");
14898
14810
  mkdirSync9(promptsDir, { recursive: true });
14899
14811
  const timestamp2 = Date.now();
14900
14812
  const iterationSuffix = iteration !== void 0 ? `-iteration-${iteration}` : "";
14901
14813
  const filename = `${stage}${iterationSuffix}-${timestamp2}.md`;
14902
- const filePath = join21(promptsDir, filename);
14814
+ const filePath = join20(promptsDir, filename);
14903
14815
  writeFileSync6(filePath, prompt, "utf-8");
14904
14816
  }
14905
14817
 
@@ -15620,11 +15532,11 @@ function createCliProgram(version) {
15620
15532
  return program;
15621
15533
  }
15622
15534
  async function resolveCliVersion() {
15623
- if (isPackageVersion("0.0.0-next-20260621233457")) {
15624
- return "0.0.0-next-20260621233457";
15535
+ if (isPackageVersion("0.0.0-next-20260622201317")) {
15536
+ return "0.0.0-next-20260622201317";
15625
15537
  }
15626
- if (isReleaseVersion("0.0.0-next-20260621233457")) {
15627
- return "0.0.0-next-20260621233457";
15538
+ if (isReleaseVersion("0.0.0-next-20260622201317")) {
15539
+ return "0.0.0-next-20260622201317";
15628
15540
  }
15629
15541
  try {
15630
15542
  const root = repoRoot();