@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 +494 -232
- package/dist/cli.js.map +1 -1
- package/dist/e2e/run-live-e2e.js +49 -7
- package/dist/e2e/run-live-e2e.js.map +1 -1
- package/dist/schema/pourkit.schema.hash +1 -1
- package/dist/schema/pourkit.schema.json +280 -90
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -370,10 +370,26 @@ function applyOutputRetriesDefaults(retries) {
|
|
|
370
370
|
}
|
|
371
371
|
function applyStageAgentDefaults(agent) {
|
|
372
372
|
return {
|
|
373
|
-
|
|
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
|
|
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(
|
|
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 =
|
|
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 {
|
|
4456
|
-
|
|
4457
|
-
|
|
4458
|
-
|
|
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
|
|
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
|
|
8844
|
-
|
|
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
|
|
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
|
-
|
|
13762
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
14369
|
-
|
|
14370
|
-
|
|
14371
|
-
|
|
14372
|
-
|
|
14373
|
-
|
|
14374
|
-
|
|
14375
|
-
|
|
14376
|
-
|
|
14377
|
-
|
|
14378
|
-
|
|
14379
|
-
|
|
14380
|
-
|
|
14381
|
-
|
|
14382
|
-
|
|
14383
|
-
|
|
14384
|
-
|
|
14385
|
-
|
|
14386
|
-
|
|
14387
|
-
|
|
14388
|
-
|
|
14389
|
-
|
|
14390
|
-
|
|
14391
|
-
|
|
14392
|
-
|
|
14393
|
-
|
|
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
|
-
|
|
14473
|
-
|
|
14474
|
-
|
|
14475
|
-
|
|
14476
|
-
|
|
14477
|
-
|
|
14478
|
-
|
|
14479
|
-
|
|
14480
|
-
|
|
14481
|
-
|
|
14482
|
-
|
|
14483
|
-
|
|
14484
|
-
|
|
14485
|
-
|
|
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
|
-
|
|
14489
|
-
|
|
14490
|
-
|
|
14491
|
-
|
|
14492
|
-
|
|
14493
|
-
|
|
14494
|
-
|
|
14495
|
-
|
|
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
|
-
|
|
14532
|
-
|
|
14533
|
-
|
|
14534
|
-
|
|
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
|
-
`
|
|
14803
|
+
`Claimed Beads child ${claimResult.child.id} for ${prdRef}; mapping to GitHub Issue context.`
|
|
14609
14804
|
);
|
|
14610
|
-
const
|
|
14611
|
-
|
|
14612
|
-
config: options.config,
|
|
14805
|
+
const contextResult = await buildIssueContextFromBeadsChild({
|
|
14806
|
+
child: claimResult.child,
|
|
14613
14807
|
issueProvider,
|
|
14614
|
-
|
|
14615
|
-
|
|
14616
|
-
|
|
14617
|
-
|
|
14618
|
-
|
|
14619
|
-
issue,
|
|
14620
|
-
queueRunContext: {
|
|
14808
|
+
expectedPrdRef: prdRef
|
|
14809
|
+
});
|
|
14810
|
+
if (!contextResult.ok) {
|
|
14811
|
+
return buildLaunchBlockedOutcome(
|
|
14812
|
+
options.repoRoot,
|
|
14621
14813
|
prdRef,
|
|
14622
|
-
|
|
14623
|
-
|
|
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
|
-
|
|
14627
|
-
|
|
14628
|
-
|
|
14629
|
-
|
|
14630
|
-
|
|
14631
|
-
|
|
14632
|
-
|
|
14633
|
-
|
|
14634
|
-
|
|
14635
|
-
|
|
14636
|
-
|
|
14637
|
-
|
|
14638
|
-
|
|
14639
|
-
|
|
14640
|
-
|
|
14641
|
-
|
|
14642
|
-
|
|
14643
|
-
|
|
14644
|
-
|
|
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
|
-
|
|
14663
|
-
|
|
14664
|
-
|
|
14665
|
-
|
|
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:
|
|
14720
|
-
|
|
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
|
-
`${
|
|
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
|
|
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:
|
|
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
|
|
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 =
|
|
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 =
|
|
17900
|
-
const memoryDbPath =
|
|
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 =
|
|
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 =
|
|
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(
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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:
|
|
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:
|
|
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 =
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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-
|
|
21454
|
-
return "0.0.0-next-
|
|
21715
|
+
if (isPackageVersion("0.0.0-next-20260715085442")) {
|
|
21716
|
+
return "0.0.0-next-20260715085442";
|
|
21455
21717
|
}
|
|
21456
|
-
if (isReleaseVersion("0.0.0-next-
|
|
21457
|
-
return "0.0.0-next-
|
|
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();
|