@pourkit/cli 0.0.0-next-20260625073725 → 0.0.0-next-20260627024509
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 +2537 -581
- package/dist/cli.js.map +1 -1
- package/dist/e2e/run-live-e2e.js +288 -37
- package/dist/e2e/run-live-e2e.js.map +1 -1
- package/dist/managed/docs/agents/domain.md +2 -0
- package/dist/managed/skills/publish-prd/SKILL.md +162 -19
- package/package.json +1 -1
package/dist/e2e/run-live-e2e.js
CHANGED
|
@@ -1756,7 +1756,7 @@ async function runBaseRefreshAttempt(options) {
|
|
|
1756
1756
|
|
|
1757
1757
|
// commands/conflict-resolution.ts
|
|
1758
1758
|
import { existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
|
|
1759
|
-
import { join as
|
|
1759
|
+
import { join as join8 } from "path";
|
|
1760
1760
|
init_common();
|
|
1761
1761
|
|
|
1762
1762
|
// conflicts/conflict-resolution-artifact.ts
|
|
@@ -1919,8 +1919,8 @@ function parseConflictResolutionArtifact(output) {
|
|
|
1919
1919
|
|
|
1920
1920
|
// commands/artifact-validation.ts
|
|
1921
1921
|
import { execSync } from "child_process";
|
|
1922
|
-
import { existsSync as existsSync8, readFileSync as readFileSync8 } from "fs";
|
|
1923
|
-
import { isAbsolute as isAbsolute2, resolve as resolve2 } from "path";
|
|
1922
|
+
import { existsSync as existsSync8, readdirSync as readdirSync3, readFileSync as readFileSync8 } from "fs";
|
|
1923
|
+
import { isAbsolute as isAbsolute2, join as join7, resolve as resolve2 } from "path";
|
|
1924
1924
|
|
|
1925
1925
|
// pr/review-verdict.ts
|
|
1926
1926
|
var ReviewVerdictProtocolError = class extends Error {
|
|
@@ -3319,6 +3319,13 @@ var ISSUE_FINAL_REVIEW_SCOPE_VERDICTS = [
|
|
|
3319
3319
|
"incidental",
|
|
3320
3320
|
"out-of-scope"
|
|
3321
3321
|
];
|
|
3322
|
+
function escapeRegExp(value) {
|
|
3323
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
3324
|
+
}
|
|
3325
|
+
function normalizeChildRef(value) {
|
|
3326
|
+
const match = value.match(/^I-0*(\d+)$/i);
|
|
3327
|
+
return match ? `I-${match[1].padStart(2, "0")}` : value.toUpperCase();
|
|
3328
|
+
}
|
|
3322
3329
|
function invalid(options, reason, diagnostics = []) {
|
|
3323
3330
|
return {
|
|
3324
3331
|
ok: false,
|
|
@@ -3668,11 +3675,177 @@ function validateIssueFinalReviewArtifact(parsed, options) {
|
|
|
3668
3675
|
}
|
|
3669
3676
|
return { ok: true, verdict: parsed.verdict };
|
|
3670
3677
|
}
|
|
3678
|
+
function validatePrdPlanWorkspace(options) {
|
|
3679
|
+
const workspacePath = options.workspace || options.artifactPath;
|
|
3680
|
+
const prdRef = options.prdRef;
|
|
3681
|
+
if (!prdRef) {
|
|
3682
|
+
return invalid(options, "PRD plan workspace validation requires --prd-ref");
|
|
3683
|
+
}
|
|
3684
|
+
const diagnostics = [];
|
|
3685
|
+
const prdPath = join7(workspacePath, "PRD.md");
|
|
3686
|
+
if (!existsSync8(prdPath)) {
|
|
3687
|
+
return invalid(options, `PRD plan workspace missing PRD.md at ${prdPath}`);
|
|
3688
|
+
}
|
|
3689
|
+
let prdContent;
|
|
3690
|
+
try {
|
|
3691
|
+
prdContent = readFileSync8(prdPath, "utf-8");
|
|
3692
|
+
} catch {
|
|
3693
|
+
return invalid(options, `Cannot read PRD.md at ${prdPath}`);
|
|
3694
|
+
}
|
|
3695
|
+
const prdFirstLine = prdContent.split("\n")[0];
|
|
3696
|
+
const prdHeadingMatch = prdFirstLine.match(/^# (PRD-\d{4}):.*$/i);
|
|
3697
|
+
if (!prdFirstLine.startsWith("# ") || !prdHeadingMatch) {
|
|
3698
|
+
return invalid(
|
|
3699
|
+
options,
|
|
3700
|
+
"PRD.md must start with a heading: # PRD-NNNN: Title"
|
|
3701
|
+
);
|
|
3702
|
+
}
|
|
3703
|
+
if (prdHeadingMatch[1].toUpperCase() !== prdRef.toUpperCase()) {
|
|
3704
|
+
return invalid(
|
|
3705
|
+
options,
|
|
3706
|
+
`PRD.md heading ${prdHeadingMatch[1].toUpperCase()} does not match --prd-ref ${prdRef}`
|
|
3707
|
+
);
|
|
3708
|
+
}
|
|
3709
|
+
diagnostics.push(`PRD title: ${prdFirstLine.slice(2).trim()}`);
|
|
3710
|
+
const issuesDir = join7(workspacePath, "issues");
|
|
3711
|
+
if (!existsSync8(issuesDir)) {
|
|
3712
|
+
return invalid(
|
|
3713
|
+
options,
|
|
3714
|
+
`PRD plan workspace missing issues/ directory at ${issuesDir}`
|
|
3715
|
+
);
|
|
3716
|
+
}
|
|
3717
|
+
let childFiles;
|
|
3718
|
+
const CHILD_FILE_PATTERN = /^I-0*(\d+)-.+\.md$/i;
|
|
3719
|
+
try {
|
|
3720
|
+
childFiles = readdirSync3(issuesDir).filter(
|
|
3721
|
+
(f) => CHILD_FILE_PATTERN.test(f) && !f.startsWith(".")
|
|
3722
|
+
);
|
|
3723
|
+
} catch {
|
|
3724
|
+
return invalid(options, `Cannot read issues/ directory at ${issuesDir}`);
|
|
3725
|
+
}
|
|
3726
|
+
childFiles.sort((a, b) => {
|
|
3727
|
+
const aMatch = a.match(CHILD_FILE_PATTERN);
|
|
3728
|
+
const bMatch = b.match(CHILD_FILE_PATTERN);
|
|
3729
|
+
if (!aMatch || !bMatch) return 0;
|
|
3730
|
+
return Number(aMatch[1]) - Number(bMatch[1]);
|
|
3731
|
+
});
|
|
3732
|
+
if (childFiles.length === 0) {
|
|
3733
|
+
return invalid(
|
|
3734
|
+
options,
|
|
3735
|
+
`PRD plan workspace must contain at least one issues/I-0N-*.md child Issue`
|
|
3736
|
+
);
|
|
3737
|
+
}
|
|
3738
|
+
const children = [];
|
|
3739
|
+
const CHILD_REF_PATTERN = /^\s*(I-0*\d+)\s*$/i;
|
|
3740
|
+
const BLOCKED_BY_SECTION_REGEX = /## Blocked by\s*\n([\s\S]*?)(?=\n## |$)/i;
|
|
3741
|
+
const PARENT_SECTION_REGEX = /## Parent\s*\n([\s\S]*?)(?=\n## |$)/i;
|
|
3742
|
+
for (const childFile of childFiles) {
|
|
3743
|
+
const childPath = join7(issuesDir, childFile);
|
|
3744
|
+
let childContent;
|
|
3745
|
+
try {
|
|
3746
|
+
childContent = readFileSync8(childPath, "utf-8");
|
|
3747
|
+
} catch {
|
|
3748
|
+
diagnostics.push(`${childFile}: cannot read`);
|
|
3749
|
+
continue;
|
|
3750
|
+
}
|
|
3751
|
+
const childFileMatch = childFile.match(CHILD_FILE_PATTERN);
|
|
3752
|
+
if (!childFileMatch) continue;
|
|
3753
|
+
const childRef = `I-${childFileMatch[1].padStart(2, "0")}`;
|
|
3754
|
+
const firstChildLine = childContent.split("\n")[0];
|
|
3755
|
+
if (!firstChildLine.startsWith("# ") || !new RegExp(`^# ${prdRef} / ${childRef}:`).test(firstChildLine)) {
|
|
3756
|
+
return invalid(
|
|
3757
|
+
options,
|
|
3758
|
+
`${childFile}: expected heading: # ${prdRef} / ${childRef}: Title`
|
|
3759
|
+
);
|
|
3760
|
+
}
|
|
3761
|
+
const parentSection = childContent.match(PARENT_SECTION_REGEX)?.[1];
|
|
3762
|
+
const parentPrdRegex = new RegExp(`\\b${escapeRegExp(prdRef)}\\b`, "i");
|
|
3763
|
+
if (!parentSection || !parentPrdRegex.test(parentSection)) {
|
|
3764
|
+
return invalid(
|
|
3765
|
+
options,
|
|
3766
|
+
`${childFile}: missing ## Parent section pointing to ${prdRef}`
|
|
3767
|
+
);
|
|
3768
|
+
}
|
|
3769
|
+
const section = childContent.match(BLOCKED_BY_SECTION_REGEX)?.[1];
|
|
3770
|
+
const blockedByRefs = [];
|
|
3771
|
+
if (section) {
|
|
3772
|
+
for (const rawLine of section.split("\n")) {
|
|
3773
|
+
const line = rawLine.trim();
|
|
3774
|
+
if (!line) continue;
|
|
3775
|
+
for (const part of line.split(",")) {
|
|
3776
|
+
const trimmed = part.trim();
|
|
3777
|
+
const match = trimmed.match(CHILD_REF_PATTERN);
|
|
3778
|
+
if (match) {
|
|
3779
|
+
blockedByRefs.push(match[1].toUpperCase());
|
|
3780
|
+
}
|
|
3781
|
+
}
|
|
3782
|
+
}
|
|
3783
|
+
}
|
|
3784
|
+
children.push({ childRef, blockedByRefs, sourcePath: childFile });
|
|
3785
|
+
diagnostics.push(`${childFile}: ${childRef}`);
|
|
3786
|
+
}
|
|
3787
|
+
const validChildRefs = new Set(children.map((c) => c.childRef));
|
|
3788
|
+
for (const child of children) {
|
|
3789
|
+
for (const blockedRef of child.blockedByRefs) {
|
|
3790
|
+
if (!validChildRefs.has(blockedRef.toUpperCase())) {
|
|
3791
|
+
return invalid(
|
|
3792
|
+
options,
|
|
3793
|
+
`Child ${child.childRef} references nonexistent child ${blockedRef} in Blocked by section`,
|
|
3794
|
+
[child.sourcePath]
|
|
3795
|
+
);
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
}
|
|
3799
|
+
diagnostics.push(`children: ${children.length} total`);
|
|
3800
|
+
return valid(options, diagnostics);
|
|
3801
|
+
}
|
|
3802
|
+
function validatePrdPlan(content, options) {
|
|
3803
|
+
const firstLine = content.split("\n")[0];
|
|
3804
|
+
if (!firstLine.startsWith("# ") || !/^# PRD-\d{4}:/.test(firstLine)) {
|
|
3805
|
+
return invalid(
|
|
3806
|
+
options,
|
|
3807
|
+
"PRD plan must start with a heading: # PRD-NNNN: Title"
|
|
3808
|
+
);
|
|
3809
|
+
}
|
|
3810
|
+
const title = firstLine.slice(2).trim();
|
|
3811
|
+
return valid(options, [`title: ${title}`]);
|
|
3812
|
+
}
|
|
3813
|
+
function validatePrdChildIssue(content, options) {
|
|
3814
|
+
const firstLine = content.split("\n")[0];
|
|
3815
|
+
const match = firstLine.match(/^# (PRD-\d{4}) \/ (I-\d+):/);
|
|
3816
|
+
if (!firstLine.startsWith("# ") || !match) {
|
|
3817
|
+
return invalid(
|
|
3818
|
+
options,
|
|
3819
|
+
"Child issue must start with a heading: # PRD-NNNN / I-0N: Title"
|
|
3820
|
+
);
|
|
3821
|
+
}
|
|
3822
|
+
if (options.childId) {
|
|
3823
|
+
const normalizedHeadingChildId = normalizeChildRef(match[2]);
|
|
3824
|
+
const normalizedChildId = normalizeChildRef(options.childId);
|
|
3825
|
+
if (normalizedHeadingChildId !== normalizedChildId) {
|
|
3826
|
+
return invalid(
|
|
3827
|
+
options,
|
|
3828
|
+
`Child issue heading ${normalizedHeadingChildId} does not match --child-id ${normalizedChildId}`
|
|
3829
|
+
);
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
const title = firstLine.slice(2).trim();
|
|
3833
|
+
return valid(options, [`title: ${title}`]);
|
|
3834
|
+
}
|
|
3671
3835
|
function validateAgentArtifact(options) {
|
|
3836
|
+
if (options.kind === "prd-plan-workspace") {
|
|
3837
|
+
return validatePrdPlanWorkspace(options);
|
|
3838
|
+
}
|
|
3672
3839
|
const artifact = readArtifact(options);
|
|
3673
3840
|
if (!artifact.ok) return artifact.result;
|
|
3674
3841
|
try {
|
|
3675
3842
|
switch (options.kind) {
|
|
3843
|
+
case "prd-plan": {
|
|
3844
|
+
return validatePrdPlan(artifact.content, options);
|
|
3845
|
+
}
|
|
3846
|
+
case "prd-child-issue": {
|
|
3847
|
+
return validatePrdChildIssue(artifact.content, options);
|
|
3848
|
+
}
|
|
3676
3849
|
case "reviewer": {
|
|
3677
3850
|
const iteration = options.iteration ?? 1;
|
|
3678
3851
|
const verdict = parseReviewVerdict(artifact.content);
|
|
@@ -3815,7 +3988,7 @@ function shellQuote(value) {
|
|
|
3815
3988
|
var CONFLICT_MARKER_PATTERN2 = /<<<<<<<|=======|>>>>>>>/m;
|
|
3816
3989
|
async function hasUnresolvedConflictMarkers(worktreePath, files) {
|
|
3817
3990
|
for (const file of files) {
|
|
3818
|
-
const filePath =
|
|
3991
|
+
const filePath = join8(worktreePath, file);
|
|
3819
3992
|
try {
|
|
3820
3993
|
const content = readFileSync9(filePath, "utf-8");
|
|
3821
3994
|
if (CONFLICT_MARKER_PATTERN2.test(content)) {
|
|
@@ -3829,7 +4002,7 @@ async function hasUnresolvedConflictMarkers(worktreePath, files) {
|
|
|
3829
4002
|
|
|
3830
4003
|
// failure-resolution/failure-resolution-agent.ts
|
|
3831
4004
|
import { readFileSync as readFileSync10 } from "fs";
|
|
3832
|
-
import { join as
|
|
4005
|
+
import { join as join9 } from "path";
|
|
3833
4006
|
|
|
3834
4007
|
// failure-resolution/recovery-policy.ts
|
|
3835
4008
|
function isSecuritySensitiveFailure(failure) {
|
|
@@ -3905,7 +4078,7 @@ async function runFailureResolutionAgent(options) {
|
|
|
3905
4078
|
} = options;
|
|
3906
4079
|
const frConfig = target.strategy.failureResolution;
|
|
3907
4080
|
const artifactPath = packet.artifactTarget;
|
|
3908
|
-
const fullArtifactPath =
|
|
4081
|
+
const fullArtifactPath = join9(worktreePath, artifactPath);
|
|
3909
4082
|
const fingerprint = computeFailureFingerprint(packet.stageName, failure._tag);
|
|
3910
4083
|
const prompt = [
|
|
3911
4084
|
`# Failure Resolution: ${packet.failureType}`,
|
|
@@ -4736,11 +4909,11 @@ async function assertCanonicalBaseAncestor(options) {
|
|
|
4736
4909
|
|
|
4737
4910
|
// issues/pr-description-agent.ts
|
|
4738
4911
|
import { existsSync as existsSync12, readFileSync as readFileSync13 } from "fs";
|
|
4739
|
-
import { isAbsolute as isAbsolute4, join as
|
|
4912
|
+
import { isAbsolute as isAbsolute4, join as join12 } from "path";
|
|
4740
4913
|
|
|
4741
4914
|
// pr/pr-description-context.ts
|
|
4742
4915
|
init_common();
|
|
4743
|
-
import { join as
|
|
4916
|
+
import { join as join10 } from "path";
|
|
4744
4917
|
import { readFile } from "fs/promises";
|
|
4745
4918
|
import { Effect as Effect6 } from "effect";
|
|
4746
4919
|
function collectFinalizerContextEffect(options) {
|
|
@@ -4805,7 +4978,7 @@ function remoteTargetBase(targetBase) {
|
|
|
4805
4978
|
return targetBase.includes("/") ? targetBase : `origin/${targetBase}`;
|
|
4806
4979
|
}
|
|
4807
4980
|
function buildFinalizerPrompt(context, promptTemplate) {
|
|
4808
|
-
const artifactPathInWorktree =
|
|
4981
|
+
const artifactPathInWorktree = join10(
|
|
4809
4982
|
".pourkit",
|
|
4810
4983
|
".tmp",
|
|
4811
4984
|
"finalizer",
|
|
@@ -4860,9 +5033,9 @@ Before handoff, run: pourkit validate-artifact finalizer ${artifactPathInWorktre
|
|
|
4860
5033
|
|
|
4861
5034
|
// issues/issue-final-review.ts
|
|
4862
5035
|
import { existsSync as existsSync11, readFileSync as readFileSync12 } from "fs";
|
|
4863
|
-
import { isAbsolute as isAbsolute3, join as
|
|
5036
|
+
import { isAbsolute as isAbsolute3, join as join11, relative as relative2, sep as sep2 } from "path";
|
|
4864
5037
|
init_common();
|
|
4865
|
-
var ISSUE_FINAL_REVIEW_ARTIFACT_PATH =
|
|
5038
|
+
var ISSUE_FINAL_REVIEW_ARTIFACT_PATH = join11(
|
|
4866
5039
|
".pourkit",
|
|
4867
5040
|
".tmp",
|
|
4868
5041
|
"issue-final-review",
|
|
@@ -4880,7 +5053,7 @@ async function runIssueFinalReview(options) {
|
|
|
4880
5053
|
logger
|
|
4881
5054
|
} = options;
|
|
4882
5055
|
const artifactPathInWorktree = ISSUE_FINAL_REVIEW_ARTIFACT_PATH;
|
|
4883
|
-
const artifactPath =
|
|
5056
|
+
const artifactPath = join11(worktreePath, artifactPathInWorktree);
|
|
4884
5057
|
const ifrFromState = options.worktreeState?.issueFinalReview;
|
|
4885
5058
|
if (ifrFromState?.completed && ifrFromState.verdict === "pass") {
|
|
4886
5059
|
if (!ifrFromState.artifactPath) {
|
|
@@ -4888,7 +5061,7 @@ async function runIssueFinalReview(options) {
|
|
|
4888
5061
|
"Issue Final Review state is incomplete: missing artifactPath"
|
|
4889
5062
|
);
|
|
4890
5063
|
}
|
|
4891
|
-
const cachedArtifactPath = isAbsolute3(ifrFromState.artifactPath) ? ifrFromState.artifactPath :
|
|
5064
|
+
const cachedArtifactPath = isAbsolute3(ifrFromState.artifactPath) ? ifrFromState.artifactPath : join11(worktreePath, ifrFromState.artifactPath);
|
|
4892
5065
|
const validation2 = validateAgentArtifact({
|
|
4893
5066
|
kind: "issue-final-review",
|
|
4894
5067
|
artifactPath: cachedArtifactPath,
|
|
@@ -5237,20 +5410,20 @@ function loadFinalizerPromptEffect(repoRoot2, promptTemplate, fs) {
|
|
|
5237
5410
|
}
|
|
5238
5411
|
function persistGeneratedArtifactEffect(worktreePath, output, fs) {
|
|
5239
5412
|
return Effect7.gen(function* () {
|
|
5240
|
-
const dir =
|
|
5413
|
+
const dir = join12(worktreePath, ".pourkit", ".tmp", "finalizer");
|
|
5241
5414
|
yield* fs.mkdir(dir).pipe(Effect7.catchAll(() => Effect7.void));
|
|
5242
|
-
yield* fs.writeFile(
|
|
5415
|
+
yield* fs.writeFile(join12(dir, "generated.md"), output).pipe(Effect7.catchAll(() => Effect7.void));
|
|
5243
5416
|
});
|
|
5244
5417
|
}
|
|
5245
5418
|
function runPrDescriptionAgent(options) {
|
|
5246
5419
|
const { executionProvider } = options;
|
|
5247
|
-
const artifactPathInWorktree =
|
|
5420
|
+
const artifactPathInWorktree = join12(
|
|
5248
5421
|
".pourkit",
|
|
5249
5422
|
".tmp",
|
|
5250
5423
|
"finalizer",
|
|
5251
5424
|
"agent-output.md"
|
|
5252
5425
|
);
|
|
5253
|
-
const artifactPath =
|
|
5426
|
+
const artifactPath = join12(options.worktreePath, artifactPathInWorktree);
|
|
5254
5427
|
const finalizerFromState = options.worktreeState?.finalizer?.completed ? options.worktreeState.finalizer : null;
|
|
5255
5428
|
if (finalizerFromState) {
|
|
5256
5429
|
return Effect7.gen(function* () {
|
|
@@ -5261,7 +5434,7 @@ function runPrDescriptionAgent(options) {
|
|
|
5261
5434
|
})
|
|
5262
5435
|
);
|
|
5263
5436
|
}
|
|
5264
|
-
const resolvedArtifactPath = isAbsolute4(finalizerFromState.artifactPath) ? finalizerFromState.artifactPath :
|
|
5437
|
+
const resolvedArtifactPath = isAbsolute4(finalizerFromState.artifactPath) ? finalizerFromState.artifactPath : join12(options.worktreePath, finalizerFromState.artifactPath);
|
|
5265
5438
|
if (!existsSync12(resolvedArtifactPath)) {
|
|
5266
5439
|
return yield* Effect7.fail(
|
|
5267
5440
|
new FinalizerFailure({
|
|
@@ -5383,7 +5556,7 @@ function runPrDescriptionAgent(options) {
|
|
|
5383
5556
|
);
|
|
5384
5557
|
}
|
|
5385
5558
|
function runPrDescriptionFinalizerCore(options) {
|
|
5386
|
-
const artifactPath =
|
|
5559
|
+
const artifactPath = join12(
|
|
5387
5560
|
options.worktreePath,
|
|
5388
5561
|
options.artifactPathInWorktree
|
|
5389
5562
|
);
|
|
@@ -5484,7 +5657,7 @@ function runPrDescriptionFinalizerCore(options) {
|
|
|
5484
5657
|
// issues/github-issue-publication.ts
|
|
5485
5658
|
init_common();
|
|
5486
5659
|
import { existsSync as existsSync13, readFileSync as readFileSync14 } from "fs";
|
|
5487
|
-
import { isAbsolute as isAbsolute5, join as
|
|
5660
|
+
import { isAbsolute as isAbsolute5, join as join13 } from "path";
|
|
5488
5661
|
|
|
5489
5662
|
// issues/issue-transitions.ts
|
|
5490
5663
|
function createIssueTransitions(deps, labels) {
|
|
@@ -5542,6 +5715,35 @@ function createIssueTransitions(deps, labels) {
|
|
|
5542
5715
|
};
|
|
5543
5716
|
}
|
|
5544
5717
|
|
|
5718
|
+
// beads/client.ts
|
|
5719
|
+
init_common();
|
|
5720
|
+
async function runBdJson(options) {
|
|
5721
|
+
return execJson("bd", options.args, {
|
|
5722
|
+
cwd: options.repoRoot,
|
|
5723
|
+
logger: options.logger,
|
|
5724
|
+
label: options.label
|
|
5725
|
+
});
|
|
5726
|
+
}
|
|
5727
|
+
|
|
5728
|
+
// beads/prd-completion.ts
|
|
5729
|
+
async function closeBeadsPrdChild(options) {
|
|
5730
|
+
const { repoRoot: repoRoot2, childId, reason, logger } = options;
|
|
5731
|
+
if (!childId || childId.trim().length === 0) {
|
|
5732
|
+
throw new Error(
|
|
5733
|
+
"childId is required and must be a non-empty Beads ID string"
|
|
5734
|
+
);
|
|
5735
|
+
}
|
|
5736
|
+
if (!reason || reason.trim().length === 0) {
|
|
5737
|
+
throw new Error("reason is required and must be a non-empty string");
|
|
5738
|
+
}
|
|
5739
|
+
const response = await runBdJson({
|
|
5740
|
+
repoRoot: repoRoot2,
|
|
5741
|
+
args: ["close", childId, "--reason", reason, "--json"],
|
|
5742
|
+
logger
|
|
5743
|
+
});
|
|
5744
|
+
return { ok: true, childId, response };
|
|
5745
|
+
}
|
|
5746
|
+
|
|
5545
5747
|
// issues/stacked-issue.ts
|
|
5546
5748
|
var BODY_PARENT_SECTION_REGEX = /## Parent\s*\n([\s\S]*?)(?=\n## |$)/i;
|
|
5547
5749
|
var AFFECTED_CODE_PATHS_SECTION_REGEX = /## Affected code paths\s*\n([\s\S]*?)(?=\n## |$)/i;
|
|
@@ -5959,7 +6161,7 @@ function readIssueFinalReviewArtifact(worktreeState, worktreePath) {
|
|
|
5959
6161
|
if (!configuredPath) {
|
|
5960
6162
|
return null;
|
|
5961
6163
|
}
|
|
5962
|
-
const artifactPath = isAbsolute5(configuredPath) ? configuredPath :
|
|
6164
|
+
const artifactPath = isAbsolute5(configuredPath) ? configuredPath : join13(worktreePath, configuredPath);
|
|
5963
6165
|
if (!existsSync13(artifactPath)) return null;
|
|
5964
6166
|
let parsed;
|
|
5965
6167
|
try {
|
|
@@ -6066,19 +6268,56 @@ function formatTableCell(value) {
|
|
|
6066
6268
|
return typeof value === "string" && value.trim() !== "" ? value.trim().replace(/\s+/g, " ").replace(/\|/g, "\\|") : "Unknown";
|
|
6067
6269
|
}
|
|
6068
6270
|
async function performCleanupAndClosure(options, pr) {
|
|
6069
|
-
|
|
6070
|
-
|
|
6071
|
-
|
|
6072
|
-
|
|
6073
|
-
|
|
6074
|
-
|
|
6075
|
-
|
|
6076
|
-
|
|
6271
|
+
if (options.beadsCompletion) {
|
|
6272
|
+
await closeBeadsPrdChild({
|
|
6273
|
+
repoRoot: options.repoRoot,
|
|
6274
|
+
childId: options.beadsCompletion.childId,
|
|
6275
|
+
reason: `Issue #${options.issue.number} merged`,
|
|
6276
|
+
logger: options.logger
|
|
6277
|
+
});
|
|
6278
|
+
}
|
|
6279
|
+
try {
|
|
6280
|
+
await options.issueProvider.removeLabel(
|
|
6281
|
+
options.issue.number,
|
|
6282
|
+
options.labels.agentInProgress
|
|
6283
|
+
);
|
|
6284
|
+
} catch (error) {
|
|
6285
|
+
if (options.beadsCompletion) {
|
|
6286
|
+
throw new Error(
|
|
6287
|
+
`Projection failure after Beads close: GitHub Issue #${options.issue.number} label ${options.labels.agentInProgress} removal failed (Beads child ${options.beadsCompletion.childId} remains completed). ${error instanceof Error ? error.message : String(error)}`
|
|
6288
|
+
);
|
|
6289
|
+
}
|
|
6290
|
+
options.logger.step(
|
|
6291
|
+
"warn",
|
|
6292
|
+
`Failed to remove ${options.labels.agentInProgress} label (cleanup): ${error instanceof Error ? error.message : String(error)}`
|
|
6293
|
+
);
|
|
6294
|
+
}
|
|
6295
|
+
try {
|
|
6296
|
+
await options.issueProvider.removeLabel(
|
|
6297
|
+
options.issue.number,
|
|
6298
|
+
options.labels.prOpenAwaitingMerge
|
|
6299
|
+
);
|
|
6300
|
+
} catch (error) {
|
|
6301
|
+
if (options.beadsCompletion) {
|
|
6302
|
+
throw new Error(
|
|
6303
|
+
`Projection failure after Beads close: GitHub Issue #${options.issue.number} label ${options.labels.prOpenAwaitingMerge} removal failed (Beads child ${options.beadsCompletion.childId} remains completed). ${error instanceof Error ? error.message : String(error)}`
|
|
6304
|
+
);
|
|
6305
|
+
}
|
|
6306
|
+
options.logger.step(
|
|
6307
|
+
"warn",
|
|
6308
|
+
`Failed to remove ${options.labels.prOpenAwaitingMerge} label (cleanup): ${error instanceof Error ? error.message : String(error)}`
|
|
6309
|
+
);
|
|
6310
|
+
}
|
|
6077
6311
|
let childCloseSucceeded = false;
|
|
6078
6312
|
try {
|
|
6079
6313
|
await options.issueProvider.closeIssue(options.issue.number);
|
|
6080
6314
|
childCloseSucceeded = true;
|
|
6081
6315
|
} catch (error) {
|
|
6316
|
+
if (options.beadsCompletion) {
|
|
6317
|
+
throw new Error(
|
|
6318
|
+
`Projection failure after Beads close: GitHub Issue #${options.issue.number} close failed (Beads child ${options.beadsCompletion.childId} remains completed). ${error instanceof Error ? error.message : String(error)}`
|
|
6319
|
+
);
|
|
6320
|
+
}
|
|
6082
6321
|
options.logger.step(
|
|
6083
6322
|
"warn",
|
|
6084
6323
|
`Issue #${options.issue.number} could not be closed: ${error instanceof Error ? error.message : String(error)}`
|
|
@@ -6277,7 +6516,7 @@ async function runFinalCommit(options) {
|
|
|
6277
6516
|
|
|
6278
6517
|
// issues/issue-worktree-resolution.ts
|
|
6279
6518
|
init_common();
|
|
6280
|
-
import { join as
|
|
6519
|
+
import { join as join14 } from "path";
|
|
6281
6520
|
async function resolveIssueWorktree(root, branchName, baseBranch, logger) {
|
|
6282
6521
|
const worktreeList = await execCapture(
|
|
6283
6522
|
"git",
|
|
@@ -6335,7 +6574,7 @@ async function resolveIssueWorktree(root, branchName, baseBranch, logger) {
|
|
|
6335
6574
|
return { mode: "new", branchName, baseRef };
|
|
6336
6575
|
}
|
|
6337
6576
|
function issueWorktreePath(root, branchName) {
|
|
6338
|
-
return
|
|
6577
|
+
return join14(root, ".sandcastle", "worktrees", branchName.replace(/\//g, "-"));
|
|
6339
6578
|
}
|
|
6340
6579
|
function resolveRegisteredIssueWorktreePath(worktreeListPorcelain, root, branchName) {
|
|
6341
6580
|
const branchWorktreePath = parseWorktreeListPorcelain(
|
|
@@ -6728,7 +6967,9 @@ async function completeIssueRun(options) {
|
|
|
6728
6967
|
blocked: config.labels.blocked
|
|
6729
6968
|
},
|
|
6730
6969
|
checkWaitOptions,
|
|
6731
|
-
secretLikeContentDetectionEnabled: true
|
|
6970
|
+
secretLikeContentDetectionEnabled: true,
|
|
6971
|
+
repoRoot: ROOT,
|
|
6972
|
+
beadsCompletion: options.beadsIssueRunContext
|
|
6732
6973
|
});
|
|
6733
6974
|
return {
|
|
6734
6975
|
branchName,
|
|
@@ -7068,6 +7309,16 @@ var GitHubIssueProvider = class {
|
|
|
7068
7309
|
});
|
|
7069
7310
|
return { number: data.number, url: data.html_url, title: data.title };
|
|
7070
7311
|
}
|
|
7312
|
+
async updateIssue(issueNumber, options) {
|
|
7313
|
+
const { data } = await this.client.octokit.rest.issues.update({
|
|
7314
|
+
owner: this.client.owner,
|
|
7315
|
+
repo: this.client.repo,
|
|
7316
|
+
issue_number: issueNumber,
|
|
7317
|
+
...options.title !== void 0 ? { title: options.title } : {},
|
|
7318
|
+
...options.body !== void 0 ? { body: options.body } : {}
|
|
7319
|
+
});
|
|
7320
|
+
return { number: data.number, url: data.html_url, title: data.title };
|
|
7321
|
+
}
|
|
7071
7322
|
async fetchIssue(number) {
|
|
7072
7323
|
const { data } = await this.client.octokit.rest.issues.get({
|
|
7073
7324
|
owner: this.client.owner,
|
|
@@ -7692,7 +7943,7 @@ async function ensureSandboxImageBuilt(repoRoot2, options) {
|
|
|
7692
7943
|
}
|
|
7693
7944
|
|
|
7694
7945
|
// execution/sandbox-options.ts
|
|
7695
|
-
import { join as
|
|
7946
|
+
import { join as join15 } from "path";
|
|
7696
7947
|
var POURKIT_ICM_CONTAINER_DIR = "/home/agent/.pourkit/icm";
|
|
7697
7948
|
function buildSandboxOptions(repoRoot2, sandbox, memory) {
|
|
7698
7949
|
const mounts = [];
|
|
@@ -7701,12 +7952,12 @@ function buildSandboxOptions(repoRoot2, sandbox, memory) {
|
|
|
7701
7952
|
}
|
|
7702
7953
|
if (memory?.available) {
|
|
7703
7954
|
mounts.push({
|
|
7704
|
-
hostPath:
|
|
7955
|
+
hostPath: join15(repoRoot2, ".pourkit", "icm"),
|
|
7705
7956
|
sandboxPath: POURKIT_ICM_CONTAINER_DIR,
|
|
7706
7957
|
readonly: false
|
|
7707
7958
|
});
|
|
7708
7959
|
mounts.push({
|
|
7709
|
-
hostPath:
|
|
7960
|
+
hostPath: join15(repoRoot2, ".pourkit", "icm", "cache"),
|
|
7710
7961
|
sandboxPath: "/home/agent/.cache/icm",
|
|
7711
7962
|
readonly: false
|
|
7712
7963
|
});
|
|
@@ -7724,10 +7975,10 @@ init_common();
|
|
|
7724
7975
|
import { mkdtempSync } from "fs";
|
|
7725
7976
|
import { writeFile } from "fs/promises";
|
|
7726
7977
|
import { tmpdir } from "os";
|
|
7727
|
-
import { dirname as dirname5, join as
|
|
7978
|
+
import { dirname as dirname5, join as join16 } from "path";
|
|
7728
7979
|
async function writeExecutionArtifacts(worktreePath, artifacts) {
|
|
7729
7980
|
for (const artifact of artifacts) {
|
|
7730
|
-
const filePath =
|
|
7981
|
+
const filePath = join16(worktreePath, artifact.path);
|
|
7731
7982
|
await ensureDir(dirname5(filePath));
|
|
7732
7983
|
await writeFile(filePath, artifact.content, "utf-8");
|
|
7733
7984
|
}
|