@pourkit/cli 0.0.0-next-20260619045442 → 0.0.0-next-20260619094345

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
@@ -869,20 +869,6 @@ function parseConfig(raw) {
869
869
  function getVerificationCommands(target) {
870
870
  return target.strategy.verify?.commands ?? [];
871
871
  }
872
- function resolvePrdRunMode(target, opts) {
873
- if (opts?.localOverride === true) {
874
- return { mode: "local", source: "cli-override", targetName: target.name };
875
- }
876
- const configMode = target.prdRun?.mode;
877
- if (configMode) {
878
- return {
879
- mode: configMode,
880
- source: "target-config",
881
- targetName: target.name
882
- };
883
- }
884
- return { mode: "github", source: "default", targetName: target.name };
885
- }
886
872
  function shouldCleanupRepositoryAfterPrdDrain(target) {
887
873
  return target.prdRun?.cleanupRepository ?? true;
888
874
  }
@@ -894,11 +880,11 @@ var OBSOLETE_CONFIG_PATHS = [
894
880
  ];
895
881
  var CANONICAL_CONFIG_PATH = ".pourkit/config.json";
896
882
  async function loadRepoConfig(repoRoot2, _configFileName) {
897
- const { existsSync: existsSync24 } = await import("fs");
883
+ const { existsSync: existsSync21 } = await import("fs");
898
884
  const { join: pjoin } = await import("path");
899
885
  for (const obPath of OBSOLETE_CONFIG_PATHS) {
900
886
  const fullPath = pjoin(repoRoot2, obPath);
901
- if (existsSync24(fullPath)) {
887
+ if (existsSync21(fullPath)) {
902
888
  const isRootJson = obPath === "pourkit.json";
903
889
  throw new Error(
904
890
  isRootJson ? `Found root ${obPath}, but Pourkit config now lives at ${CANONICAL_CONFIG_PATH}. Move the file and update "$schema" to "./schema/pourkit.schema.json".` : `Found ${obPath}, but executable config is no longer supported. Move configuration to ${CANONICAL_CONFIG_PATH} with "$schema": "./schema/pourkit.schema.json".`
@@ -906,13 +892,13 @@ async function loadRepoConfig(repoRoot2, _configFileName) {
906
892
  }
907
893
  }
908
894
  const configPath = pjoin(repoRoot2, CANONICAL_CONFIG_PATH);
909
- if (!existsSync24(configPath)) {
895
+ if (!existsSync21(configPath)) {
910
896
  throw new Error(
911
897
  `No Pourkit config found at ${CANONICAL_CONFIG_PATH}. Run pourkit init or create ${CANONICAL_CONFIG_PATH} with "$schema": "./schema/pourkit.schema.json".`
912
898
  );
913
899
  }
914
- const { readFile: readFile8 } = await import("fs/promises");
915
- const raw = await readFile8(configPath, "utf-8");
900
+ const { readFile: readFile7 } = await import("fs/promises");
901
+ const raw = await readFile7(configPath, "utf-8");
916
902
  let parsed;
917
903
  try {
918
904
  parsed = JSON.parse(raw);
@@ -923,10 +909,10 @@ async function loadRepoConfig(repoRoot2, _configFileName) {
923
909
  return parseConfig(parsed);
924
910
  }
925
911
  async function loadConfig(configPath) {
926
- const { readFile: readFile8 } = await import("fs/promises");
912
+ const { readFile: readFile7 } = await import("fs/promises");
927
913
  const ext = configPath.split(".").pop()?.toLowerCase();
928
914
  if (ext === "json") {
929
- const raw = await readFile8(configPath, "utf-8");
915
+ const raw = await readFile7(configPath, "utf-8");
930
916
  return parseConfig(JSON.parse(raw));
931
917
  }
932
918
  if (ext === "mjs" || ext === "js" || ext === "ts") {
@@ -1148,10 +1134,9 @@ async function cleanupRepository(options) {
1148
1134
  }
1149
1135
 
1150
1136
  // commands/artifact-validation.ts
1151
- import { createHash } from "crypto";
1152
1137
  import { execSync } from "child_process";
1153
- import { existsSync as existsSync7, readdirSync as readdirSync3, readFileSync as readFileSync7 } from "fs";
1154
- import { isAbsolute as isAbsolute3, join as join7, resolve as resolve3 } from "path";
1138
+ import { existsSync as existsSync7, readFileSync as readFileSync7 } from "fs";
1139
+ import { isAbsolute as isAbsolute3, resolve as resolve3 } from "path";
1155
1140
 
1156
1141
  // pr/review-verdict.ts
1157
1142
  var ReviewVerdictProtocolError = class extends Error {
@@ -3670,18 +3655,6 @@ function validateAgentArtifact(options) {
3670
3655
  }
3671
3656
  return valid(options, [`decision: ${parsed.json.recoveryDecision}`]);
3672
3657
  }
3673
- case "local-prd":
3674
- case "local-issue":
3675
- case "local-triage":
3676
- return invalid(
3677
- options,
3678
- `Local artifact kind must be validated through runLocalValidateArtifactCommand`
3679
- );
3680
- case "local-prepare":
3681
- return invalid(
3682
- options,
3683
- `Artifact kind "${options.kind}" has been removed from PRD Run validation`
3684
- );
3685
3658
  }
3686
3659
  } catch (error) {
3687
3660
  if (error instanceof ReviewArtifactValidationError || error instanceof ReviewVerdictProtocolError || error instanceof PrDescriptionProtocolError || error instanceof ConflictResolutionArtifactProtocolError || error instanceof RecoveryArtifactInvalid || error instanceof Error) {
@@ -3735,874 +3708,127 @@ function isIssueFinalReviewAuditedPath(path9) {
3735
3708
  function shellQuote(value) {
3736
3709
  return `'${value.replace(/'/g, `'"'"'`)}'`;
3737
3710
  }
3738
- function runLocalValidateArtifactCommand(options) {
3739
- const resolvedPath = resolve3(options.repoRoot, options.artifactPath);
3740
- const resolvedExtra = (options.extraArgs ?? []).map(
3741
- (p) => isAbsolute3(p) ? p : resolve3(options.repoRoot, p)
3742
- );
3743
- let localResult;
3744
- switch (options.kind) {
3745
- case "local-prd":
3746
- localResult = validateLocalPrd(resolvedPath);
3747
- break;
3748
- case "local-issue":
3749
- localResult = validateLocalIssue(resolvedPath);
3750
- break;
3751
- case "local-triage":
3752
- localResult = validateLocalTriage(resolvedPath, resolvedExtra);
3753
- break;
3754
- default:
3755
- return {
3756
- ok: false,
3757
- kind: options.kind,
3758
- artifactPath: resolvedPath,
3759
- reason: `Unsupported local artifact kind "${options.kind}"`,
3760
- diagnostics: []
3761
- };
3762
- }
3763
- if (localResult.ok) {
3764
- return {
3765
- ok: true,
3766
- kind: options.kind,
3767
- artifactPath: resolvedPath,
3768
- diagnostics: []
3769
- };
3770
- }
3771
- const diagnostics = [];
3772
- if (localResult.gate) diagnostics.push(`gate: ${localResult.gate}`);
3773
- if (localResult.failureCode)
3774
- diagnostics.push(`failureCode: ${localResult.failureCode}`);
3775
- if (localResult.offendingPath)
3776
- diagnostics.push(`offendingPath: ${localResult.offendingPath}`);
3777
- if (localResult.message) diagnostics.push(localResult.message);
3778
- return {
3779
- ok: false,
3780
- kind: options.kind,
3781
- artifactPath: resolvedPath,
3782
- reason: localResult.message ?? "Validation failed",
3783
- diagnostics
3784
- };
3711
+
3712
+ // commands/issue-run.ts
3713
+ import { existsSync as existsSync12, readFileSync as readFileSync14 } from "fs";
3714
+ import { isAbsolute as isAbsolute5, join as join14 } from "path";
3715
+
3716
+ // pr/templates.ts
3717
+ init_common();
3718
+ function renderBranchName(template, issue) {
3719
+ return renderTemplate(template, issue);
3785
3720
  }
3786
- function readLocalArtifact(path9, failureCode) {
3787
- try {
3788
- const raw = readFileSync7(path9, "utf-8");
3789
- const parsed = JSON.parse(raw);
3790
- if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
3791
- return {
3792
- ok: false,
3793
- failureCode: failureCode ?? "invalid_prd_artifact",
3794
- offendingPath: path9,
3795
- message: `Expected a JSON object, got ${Array.isArray(parsed) ? "array" : parsed === null ? "null" : typeof parsed}`
3796
- };
3797
- }
3798
- return { ok: true, data: parsed };
3799
- } catch (e) {
3800
- return {
3801
- ok: false,
3802
- failureCode: failureCode ?? "invalid_prd_artifact",
3803
- offendingPath: path9,
3804
- message: `Failed to read or parse: ${e}`
3805
- };
3806
- }
3721
+ function renderTemplate(template, issue) {
3722
+ const issueSlug = slugify(issue.title);
3723
+ return template.replace(/\{\{issue\.number\}\}/g, String(issue.number)).replace(/\{\{issue\.title\}\}/g, issue.title).replace(/\{\{issue\.body\}\}/g, issue.body).replace(/\{\{issue\.slug\}\}/g, issueSlug).replace(/\{\{issue\.state\}\}/g, issue.state);
3807
3724
  }
3808
- var VALID_LOCAL_PRD_STATUSES = [
3809
- "draft",
3810
- "ready",
3811
- "prepared",
3812
- "running",
3813
- "final-review",
3814
- "reconciliation",
3815
- "complete",
3816
- "blocked"
3817
- ];
3818
- var TO_PRD_REQUIRED_HEADINGS = [
3819
- "Problem Statement",
3820
- "Solution",
3821
- "Plan Documents",
3822
- "User Stories",
3823
- "Implementation Decisions",
3824
- "Testing Decisions",
3825
- "Out of Scope",
3826
- "Further Notes"
3827
- ];
3828
- var TO_ISSUES_REQUIRED_HEADINGS = [
3829
- "Parent",
3830
- "Plan Documents",
3831
- "Source of truth for behavior",
3832
- "What to build",
3833
- "High-level explanation",
3834
- "Affected code paths",
3835
- "Exploration evidence",
3836
- "Contract decisions",
3837
- "Execution path matrix",
3838
- "Regression contract (CRITICAL)",
3839
- "Step-by-step implementation",
3840
- "Contracts / interfaces",
3841
- "Edge cases",
3842
- "Validation",
3843
- "Out of scope",
3844
- "Priority",
3845
- "Acceptance criteria",
3846
- "Blocked by"
3847
- ];
3848
- var VALID_LOCAL_ISSUE_STATUSES = [
3849
- "needs-triage",
3850
- "ready-for-agent",
3851
- "blocked",
3852
- "ready-for-human",
3853
- "wontfix",
3854
- "running",
3855
- "complete"
3856
- ];
3857
- var VALID_ISSUE_TRIAGE_LABELS = [
3858
- "needs-triage",
3859
- "ready-for-agent",
3860
- "blocked",
3861
- "ready-for-human",
3862
- "wontfix",
3863
- "running",
3864
- "complete"
3865
- ];
3866
- var VALID_ISSUE_CATEGORY_LABELS = ["bug", "enhancement"];
3867
- var VALID_ISSUE_TYPE_LABELS = [
3868
- "type:bugfix",
3869
- "type:infra",
3870
- "type:feature",
3871
- "type:polish",
3872
- "type:refactor"
3873
- ];
3874
- var ISSUE_RECEIPT_FIELDS = [
3875
- "createdAt",
3876
- "updatedAt",
3877
- "preparedAt",
3878
- "startedAt",
3879
- "completedAt",
3880
- "reviewedAt",
3881
- "mergedAt"
3882
- ];
3883
- var ISSUE_PROJECTION_FIELDS = [
3884
- "issueNumber",
3885
- "issueUrl",
3886
- "publishedAt",
3887
- "syncedAt"
3888
- ];
3889
- function getMarkdownHeadings(markdown) {
3890
- const headingRegex = /^## (.+)$/gm;
3891
- const headings = [];
3892
- let match;
3893
- while ((match = headingRegex.exec(markdown)) !== null) {
3894
- headings.push(match[1].trim());
3725
+
3726
+ // commands/issue-run.ts
3727
+ init_common();
3728
+
3729
+ // commands/base-refresh.ts
3730
+ init_common();
3731
+ async function isIssueBranchStale(worktreePath, baseBranch, logger) {
3732
+ try {
3733
+ await execCapture(
3734
+ "git",
3735
+ ["merge-base", "--is-ancestor", baseBranch, "HEAD"],
3736
+ {
3737
+ cwd: worktreePath,
3738
+ logger,
3739
+ label: "git merge-base --is-ancestor"
3740
+ }
3741
+ );
3742
+ return false;
3743
+ } catch {
3744
+ return true;
3895
3745
  }
3896
- return headings;
3897
3746
  }
3898
- function validateLocalPrd(path9) {
3899
- const parsed = readLocalArtifact(path9);
3900
- if (!parsed.ok) return parsed;
3901
- const data = parsed.data;
3902
- if (data.schemaVersion !== 1) {
3903
- return {
3904
- ok: false,
3905
- failureCode: "invalid_prd_artifact",
3906
- offendingPath: path9,
3907
- message: "schemaVersion must be 1"
3908
- };
3909
- }
3910
- if (data.kind !== "prd") {
3911
- return {
3912
- ok: false,
3913
- failureCode: "invalid_prd_artifact",
3914
- offendingPath: path9,
3915
- message: "kind must be prd"
3916
- };
3917
- }
3918
- if (typeof data.id !== "string" || data.id.trim() === "") {
3919
- return {
3920
- ok: false,
3921
- failureCode: "invalid_prd_artifact",
3922
- offendingPath: path9,
3923
- message: "id must be a non-empty string"
3924
- };
3925
- }
3926
- if (typeof data.title !== "string" || data.title.trim() === "") {
3927
- return {
3928
- ok: false,
3929
- failureCode: "invalid_prd_artifact",
3930
- offendingPath: path9,
3931
- message: "title must be a non-empty string"
3932
- };
3933
- }
3934
- if (typeof data.status !== "string" || !VALID_LOCAL_PRD_STATUSES.includes(data.status)) {
3935
- return {
3936
- ok: false,
3937
- failureCode: "invalid_prd_artifact",
3938
- offendingPath: path9,
3939
- message: `status must be one of: ${VALID_LOCAL_PRD_STATUSES.join(", ")}`
3940
- };
3941
- }
3942
- if (!Array.isArray(data.childIssueIds)) {
3943
- return {
3944
- ok: false,
3945
- failureCode: "invalid_prd_artifact",
3946
- offendingPath: path9,
3947
- message: "childIssueIds must be an array"
3948
- };
3949
- }
3950
- if (!Array.isArray(data.linkedDecisionIds)) {
3951
- return {
3952
- ok: false,
3953
- failureCode: "invalid_prd_artifact",
3954
- offendingPath: path9,
3955
- message: "linkedDecisionIds must be an array"
3956
- };
3957
- }
3958
- if (!data.reconciliationTarget || typeof data.reconciliationTarget !== "object") {
3959
- return {
3960
- ok: false,
3961
- failureCode: "invalid_prd_artifact",
3962
- offendingPath: path9,
3963
- message: "reconciliationTarget must be an object"
3964
- };
3965
- }
3966
- const reconciliationTarget = data.reconciliationTarget;
3967
- if (typeof reconciliationTarget.localPrdBranch !== "string" || reconciliationTarget.localPrdBranch.trim() === "") {
3968
- return {
3969
- ok: false,
3970
- failureCode: "invalid_prd_artifact",
3971
- offendingPath: path9,
3972
- message: "reconciliationTarget.localPrdBranch must be a non-empty string"
3973
- };
3974
- }
3975
- if (typeof reconciliationTarget.integrationBranch !== "string" || reconciliationTarget.integrationBranch.trim() === "") {
3976
- return {
3977
- ok: false,
3978
- failureCode: "invalid_prd_artifact",
3979
- offendingPath: path9,
3980
- message: "reconciliationTarget.integrationBranch must be a non-empty string"
3981
- };
3982
- }
3983
- if (typeof data.bodyMarkdown !== "string" || data.bodyMarkdown.trim() === "") {
3984
- return {
3985
- ok: false,
3986
- failureCode: "invalid_prd_artifact",
3987
- offendingPath: path9,
3988
- message: "bodyMarkdown must be a non-empty string"
3989
- };
3990
- }
3991
- if (!data.bodyContract || typeof data.bodyContract !== "object") {
3992
- return {
3993
- ok: false,
3994
- failureCode: "invalid_prd_artifact",
3995
- offendingPath: path9,
3996
- message: "bodyContract must be an object"
3997
- };
3998
- }
3999
- const bodyContract = data.bodyContract;
4000
- if (bodyContract.contract !== "to-prd") {
4001
- return {
4002
- ok: false,
4003
- failureCode: "invalid_prd_artifact",
4004
- offendingPath: path9,
4005
- message: 'bodyContract.contract must be "to-prd"'
4006
- };
4007
- }
4008
- if (!Array.isArray(bodyContract.requiredHeadings)) {
4009
- return {
4010
- ok: false,
4011
- failureCode: "invalid_prd_artifact",
4012
- offendingPath: path9,
4013
- message: "bodyContract.requiredHeadings must be an array"
4014
- };
4015
- }
4016
- const requiredHeadings = bodyContract.requiredHeadings;
4017
- const missingHeadings = TO_PRD_REQUIRED_HEADINGS.filter(
4018
- (h) => !requiredHeadings.includes(h)
4019
- );
4020
- if (missingHeadings.length > 0) {
4021
- return {
4022
- ok: false,
4023
- failureCode: "invalid_prd_artifact",
4024
- offendingPath: path9,
4025
- message: `bodyContract.requiredHeadings missing: ${missingHeadings.join(", ")}`
4026
- };
4027
- }
4028
- const markdownHeadings = getMarkdownHeadings(data.bodyMarkdown);
4029
- const missingInMarkdown = TO_PRD_REQUIRED_HEADINGS.filter(
4030
- (h) => !markdownHeadings.includes(h)
4031
- );
4032
- if (missingInMarkdown.length > 0) {
4033
- return {
4034
- ok: false,
4035
- failureCode: "invalid_prd_artifact",
4036
- offendingPath: path9,
4037
- message: `bodyMarkdown missing headings: ${missingInMarkdown.join(", ")}`
4038
- };
3747
+ async function refreshStaleIssueBranch(options) {
3748
+ const {
3749
+ worktreePath,
3750
+ baseBranch,
3751
+ localGitBaseRef,
3752
+ logger,
3753
+ prNumber,
3754
+ prState
3755
+ } = options;
3756
+ const stale = await isIssueBranchStale(worktreePath, localGitBaseRef, logger);
3757
+ if (!stale) {
3758
+ return { status: "skipped-current" };
4039
3759
  }
4040
- if (!data.receipts || typeof data.receipts !== "object") {
3760
+ if (prNumber !== void 0 && prState !== void 0) {
4041
3761
  return {
4042
- ok: false,
4043
- failureCode: "invalid_prd_artifact",
4044
- offendingPath: path9,
4045
- message: "receipts must be an object"
3762
+ status: "refused-published-history",
3763
+ prNumber,
3764
+ prState
4046
3765
  };
4047
3766
  }
4048
- const receipts = data.receipts;
4049
- const expectedReceiptFields = [
4050
- "createdAt",
4051
- "updatedAt",
4052
- "preparedAt",
4053
- "startedAt",
4054
- "finalReviewedAt",
4055
- "reconciledAt",
4056
- "completedAt"
4057
- ];
4058
- for (const field of expectedReceiptFields) {
4059
- if (!(field in receipts)) {
4060
- return {
4061
- ok: false,
4062
- failureCode: "invalid_prd_artifact",
4063
- offendingPath: path9,
4064
- message: `receipts.${field} is missing`
4065
- };
3767
+ try {
3768
+ await execCapture("git", ["rebase", "--autostash", localGitBaseRef], {
3769
+ cwd: worktreePath,
3770
+ logger,
3771
+ label: "git rebase --autostash"
3772
+ });
3773
+ return { status: "refreshed" };
3774
+ } catch (error) {
3775
+ let conflictedPaths = [];
3776
+ try {
3777
+ const statusResult = await execCapture("git", ["status", "--porcelain"], {
3778
+ cwd: worktreePath,
3779
+ logger,
3780
+ label: "git status"
3781
+ });
3782
+ conflictedPaths = statusResult.stdout.split("\n").filter((line) => /^(AA|DD|UU|AU|UA|DU|UD)\s/.test(line)).map((line) => line.slice(3).trim()).filter(Boolean);
3783
+ } catch {
4066
3784
  }
4067
- }
4068
- if (!data.githubProjection || typeof data.githubProjection !== "object") {
4069
3785
  return {
4070
- ok: false,
4071
- failureCode: "invalid_prd_artifact",
4072
- offendingPath: path9,
4073
- message: "githubProjection must be an object"
3786
+ status: "conflicted",
3787
+ message: error instanceof Error ? error.message : String(error),
3788
+ conflictedPaths
4074
3789
  };
4075
3790
  }
4076
- const githubProjection = data.githubProjection;
4077
- const expectedProjectionFields = [
4078
- "issueNumber",
4079
- "issueUrl",
4080
- "publishedAt",
4081
- "syncedAt"
4082
- ];
4083
- for (const field of expectedProjectionFields) {
4084
- if (!(field in githubProjection)) {
4085
- return {
4086
- ok: false,
4087
- failureCode: "invalid_prd_artifact",
4088
- offendingPath: path9,
4089
- message: `githubProjection.${field} is missing`
4090
- };
3791
+ }
3792
+ function invalidateAfterBaseRefresh(state) {
3793
+ return {
3794
+ issueNumber: state.issueNumber,
3795
+ targetName: state.targetName,
3796
+ branchName: state.branchName,
3797
+ baseBranch: state.baseBranch,
3798
+ createdAt: state.createdAt,
3799
+ updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
3800
+ completedStages: {
3801
+ builder: state.completedStages.builder
3802
+ },
3803
+ review: {
3804
+ lifetimeIterations: 0
4091
3805
  }
4092
- }
4093
- return { ok: true };
3806
+ };
4094
3807
  }
4095
- function validateLocalIssue(path9) {
4096
- const parsed = readLocalArtifact(path9);
4097
- if (!parsed.ok) {
4098
- return {
4099
- ok: false,
4100
- failureCode: "invalid_issue_artifact",
4101
- offendingPath: path9,
4102
- message: parsed.message
4103
- };
4104
- }
4105
- const data = parsed.data;
4106
- if (data.schemaVersion !== 1) {
4107
- return {
4108
- ok: false,
4109
- failureCode: "invalid_issue_artifact",
4110
- offendingPath: path9,
4111
- message: "schemaVersion must be 1"
4112
- };
4113
- }
4114
- if (data.kind !== "issue") {
4115
- return {
4116
- ok: false,
4117
- failureCode: "invalid_issue_artifact",
4118
- offendingPath: path9,
4119
- message: 'kind must be "issue"'
4120
- };
4121
- }
4122
- if (typeof data.id !== "string" || data.id.trim() === "") {
4123
- return {
4124
- ok: false,
4125
- failureCode: "invalid_issue_artifact",
4126
- offendingPath: path9,
4127
- message: "id must be a non-empty string"
4128
- };
4129
- }
4130
- if (typeof data.parentPrdId !== "string" || !/^PRD-\d{4}$/.test(data.parentPrdId.trim())) {
4131
- return {
4132
- ok: false,
4133
- failureCode: "invalid_issue_artifact",
4134
- offendingPath: path9,
4135
- message: "parentPrdId must match PRD-0000N format"
4136
- };
3808
+
3809
+ // failure-resolution/effect-runtime.ts
3810
+ import { Effect as Effect4 } from "effect";
3811
+
3812
+ // shared/effect-runtime.ts
3813
+ import { Effect as Effect3, Exit } from "effect";
3814
+ import { UnknownException } from "effect/Cause";
3815
+ var initialized = false;
3816
+ function initializeEffectRuntime() {
3817
+ if (initialized) return;
3818
+ initialized = true;
3819
+ }
3820
+ function runEffect(program) {
3821
+ ensureEffectRuntime();
3822
+ return Effect3.runPromiseExit(program);
3823
+ }
3824
+ function ensureEffectRuntime() {
3825
+ if (!initialized) {
3826
+ initializeEffectRuntime();
4137
3827
  }
4138
- if (typeof data.title !== "string" || data.title.trim() === "") {
4139
- return {
4140
- ok: false,
4141
- failureCode: "invalid_issue_artifact",
4142
- offendingPath: path9,
4143
- message: "title must be a non-empty string"
4144
- };
4145
- }
4146
- if (typeof data.status !== "string" || !VALID_LOCAL_ISSUE_STATUSES.includes(data.status)) {
4147
- return {
4148
- ok: false,
4149
- failureCode: "invalid_issue_artifact",
4150
- offendingPath: path9,
4151
- message: `status must be one of: ${VALID_LOCAL_ISSUE_STATUSES.join(", ")}`
4152
- };
4153
- }
4154
- if (!Array.isArray(data.labels)) {
4155
- return {
4156
- ok: false,
4157
- failureCode: "invalid_issue_artifact",
4158
- offendingPath: path9,
4159
- message: "labels must be an array"
4160
- };
4161
- }
4162
- const labels = data.labels;
4163
- const triageLabel = labels.find((l) => VALID_ISSUE_TRIAGE_LABELS.includes(l));
4164
- const categoryLabel = labels.find(
4165
- (l) => VALID_ISSUE_CATEGORY_LABELS.includes(l)
4166
- );
4167
- const typeLabel = labels.find((l) => VALID_ISSUE_TYPE_LABELS.includes(l));
4168
- const unknownLabels = labels.filter(
4169
- (l) => !VALID_ISSUE_TRIAGE_LABELS.includes(l) && !VALID_ISSUE_CATEGORY_LABELS.includes(l) && !VALID_ISSUE_TYPE_LABELS.includes(l)
4170
- );
4171
- if (!triageLabel) {
4172
- return {
4173
- ok: false,
4174
- failureCode: "invalid_issue_artifact",
4175
- offendingPath: path9,
4176
- message: `labels must include one triage-state label from: ${VALID_ISSUE_TRIAGE_LABELS.join(", ")}`
4177
- };
4178
- }
4179
- if (!categoryLabel) {
4180
- return {
4181
- ok: false,
4182
- failureCode: "invalid_issue_artifact",
4183
- offendingPath: path9,
4184
- message: `labels must include one category label from: ${VALID_ISSUE_CATEGORY_LABELS.join(", ")}`
4185
- };
4186
- }
4187
- if (!typeLabel) {
4188
- return {
4189
- ok: false,
4190
- failureCode: "invalid_issue_artifact",
4191
- offendingPath: path9,
4192
- message: `labels must include one type label from: ${VALID_ISSUE_TYPE_LABELS.join(", ")}`
4193
- };
4194
- }
4195
- if (data.status !== "running" && data.status !== "complete" && triageLabel !== data.status) {
4196
- return {
4197
- ok: false,
4198
- failureCode: "invalid_issue_artifact",
4199
- offendingPath: path9,
4200
- message: `triage-state label must match status: expected "${data.status}", got "${triageLabel}"`
4201
- };
4202
- }
4203
- const typeLabels = labels.filter((l) => l.startsWith("type:"));
4204
- if (typeLabels.length > 1) {
4205
- return {
4206
- ok: false,
4207
- failureCode: "invalid_issue_artifact",
4208
- offendingPath: path9,
4209
- message: "more than one type:* label found"
4210
- };
4211
- }
4212
- if (labels.length !== 3 || unknownLabels.length > 0) {
4213
- return {
4214
- ok: false,
4215
- failureCode: "invalid_issue_artifact",
4216
- offendingPath: path9,
4217
- message: "labels must contain exactly 3 entries: one triage-state, one category, one type:*"
4218
- };
4219
- }
4220
- if (!Array.isArray(data.dependencyIssueIds)) {
4221
- return {
4222
- ok: false,
4223
- failureCode: "invalid_issue_artifact",
4224
- offendingPath: path9,
4225
- message: "dependencyIssueIds must be an array"
4226
- };
4227
- }
4228
- if (typeof data.branchName !== "string" || !/^local\/PRD-\d{4}\/I-\d{2}-[a-z0-9-]+$/.test(data.branchName)) {
4229
- return {
4230
- ok: false,
4231
- failureCode: "invalid_issue_artifact",
4232
- offendingPath: path9,
4233
- message: "branchName must match local/PRD-0000N/I-0N-slug pattern"
4234
- };
4235
- }
4236
- if (!(data.blockedReason === null || typeof data.blockedReason === "string")) {
4237
- return {
4238
- ok: false,
4239
- failureCode: "invalid_issue_artifact",
4240
- offendingPath: path9,
4241
- message: "blockedReason must be a string or null"
4242
- };
4243
- }
4244
- if (!(data.readyForHumanReason === null || typeof data.readyForHumanReason === "string")) {
4245
- return {
4246
- ok: false,
4247
- failureCode: "invalid_issue_artifact",
4248
- offendingPath: path9,
4249
- message: "readyForHumanReason must be a string or null"
4250
- };
4251
- }
4252
- if (typeof data.bodyMarkdown !== "string" || data.bodyMarkdown.trim() === "") {
4253
- return {
4254
- ok: false,
4255
- failureCode: "invalid_issue_artifact",
4256
- offendingPath: path9,
4257
- message: "bodyMarkdown must be a non-empty string"
4258
- };
4259
- }
4260
- if (!data.bodyContract || typeof data.bodyContract !== "object") {
4261
- return {
4262
- ok: false,
4263
- failureCode: "invalid_issue_artifact",
4264
- offendingPath: path9,
4265
- message: "bodyContract must be an object"
4266
- };
4267
- }
4268
- const bodyContract = data.bodyContract;
4269
- if (bodyContract.contract !== "to-issues") {
4270
- return {
4271
- ok: false,
4272
- failureCode: "invalid_issue_artifact",
4273
- offendingPath: path9,
4274
- message: 'bodyContract.contract must be "to-issues"'
4275
- };
4276
- }
4277
- if (!Array.isArray(bodyContract.requiredHeadings)) {
4278
- return {
4279
- ok: false,
4280
- failureCode: "invalid_issue_artifact",
4281
- offendingPath: path9,
4282
- message: "bodyContract.requiredHeadings must be an array"
4283
- };
4284
- }
4285
- const requiredHeadings = bodyContract.requiredHeadings;
4286
- const missingHeadings = TO_ISSUES_REQUIRED_HEADINGS.filter(
4287
- (h) => !requiredHeadings.includes(h)
4288
- );
4289
- if (missingHeadings.length > 0) {
4290
- return {
4291
- ok: false,
4292
- failureCode: "invalid_issue_artifact",
4293
- offendingPath: path9,
4294
- message: `bodyContract.requiredHeadings missing: ${missingHeadings.join(", ")}`
4295
- };
4296
- }
4297
- const markdownHeadings = getMarkdownHeadings(data.bodyMarkdown);
4298
- const missingInMarkdown = TO_ISSUES_REQUIRED_HEADINGS.filter(
4299
- (h) => !markdownHeadings.includes(h)
4300
- );
4301
- if (missingInMarkdown.length > 0) {
4302
- return {
4303
- ok: false,
4304
- failureCode: "invalid_issue_artifact",
4305
- offendingPath: path9,
4306
- message: `bodyMarkdown missing headings: ${missingInMarkdown.join(", ")}`
4307
- };
4308
- }
4309
- if (!data.receipts || typeof data.receipts !== "object") {
4310
- return {
4311
- ok: false,
4312
- failureCode: "invalid_issue_artifact",
4313
- offendingPath: path9,
4314
- message: "receipts must be an object"
4315
- };
4316
- }
4317
- const receipts = data.receipts;
4318
- for (const field of ISSUE_RECEIPT_FIELDS) {
4319
- if (!(field in receipts)) {
4320
- return {
4321
- ok: false,
4322
- failureCode: "invalid_issue_artifact",
4323
- offendingPath: path9,
4324
- message: `receipts.${field} is missing`
4325
- };
4326
- }
4327
- }
4328
- if (!data.githubProjection || typeof data.githubProjection !== "object") {
4329
- return {
4330
- ok: false,
4331
- failureCode: "invalid_issue_artifact",
4332
- offendingPath: path9,
4333
- message: "githubProjection must be an object"
4334
- };
4335
- }
4336
- const githubProjection = data.githubProjection;
4337
- for (const field of ISSUE_PROJECTION_FIELDS) {
4338
- if (!(field in githubProjection)) {
4339
- return {
4340
- ok: false,
4341
- failureCode: "invalid_issue_artifact",
4342
- offendingPath: path9,
4343
- message: `githubProjection.${field} is missing`
4344
- };
4345
- }
4346
- }
4347
- return { ok: true };
4348
- }
4349
- function validateLocalTriage(prdPath, issuePaths) {
4350
- const prd = readLocalArtifact(
4351
- prdPath,
4352
- "triage_inconsistent"
4353
- );
4354
- if (!prd.ok || !prd.data) {
4355
- return {
4356
- ok: false,
4357
- failureCode: "triage_inconsistent",
4358
- offendingPath: prdPath,
4359
- message: prd.message ?? "Invalid PRD artifact"
4360
- };
4361
- }
4362
- if (issuePaths.length === 0) {
4363
- return { ok: true };
4364
- }
4365
- const issues = [];
4366
- for (const issuePath of issuePaths) {
4367
- const issue = readLocalArtifact(
4368
- issuePath,
4369
- "triage_inconsistent"
4370
- );
4371
- if (!issue.ok || !issue.data) {
4372
- return {
4373
- ok: false,
4374
- failureCode: "triage_inconsistent",
4375
- offendingPath: issuePath,
4376
- message: issue.message ?? "Invalid Issue artifact"
4377
- };
4378
- }
4379
- issues.push({ path: issuePath, data: issue.data });
4380
- }
4381
- const issuesById = new Map(issues.map((i) => [i.data.id, i]));
4382
- const needsTriage = issues.filter((i) => i.data.status === "needs-triage");
4383
- if (needsTriage.length > 0) {
4384
- return {
4385
- ok: false,
4386
- failureCode: "triage_inconsistent",
4387
- message: `Parent PRD cannot prepare: child Issue(s) still in needs-triage: ${needsTriage.map((i) => i.data.id).join(", ")}`
4388
- };
4389
- }
4390
- for (const issue of issues.filter((i) => i.data.status === "blocked")) {
4391
- const deps = issue.data.dependencyIssueIds ?? [];
4392
- const blockedReason = issue.data.blockedReason;
4393
- const readyForHumanReason = issue.data.readyForHumanReason;
4394
- if (deps.length === 0 && blockedReason == null && readyForHumanReason == null) {
4395
- return {
4396
- ok: false,
4397
- failureCode: "triage_inconsistent",
4398
- offendingPath: issue.path,
4399
- message: `Blocked Issue ${issue.data.id} requires at least one blocker source: dependencyIssueIds, blockedReason, or readyForHumanReason`
4400
- };
4401
- }
4402
- }
4403
- for (const issue of issues.filter(
4404
- (i) => i.data.status === "ready-for-human"
4405
- )) {
4406
- if (issue.data.readyForHumanReason == null) {
4407
- return {
4408
- ok: false,
4409
- failureCode: "triage_inconsistent",
4410
- offendingPath: issue.path,
4411
- message: `ready-for-human Issue ${issue.data.id} must have a readyForHumanReason`
4412
- };
4413
- }
4414
- }
4415
- for (const issue of issues.filter((i) => i.data.status === "wontfix")) {
4416
- if (issue.data.blockedReason == null) {
4417
- return {
4418
- ok: false,
4419
- failureCode: "triage_inconsistent",
4420
- offendingPath: issue.path,
4421
- message: `wontfix Issue ${issue.data.id} must have a blockedReason`
4422
- };
4423
- }
4424
- }
4425
- const blockedCount = issues.filter((i) => i.data.status === "blocked").length;
4426
- if (blockedCount > 0) {
4427
- const readyForAgentCount = issues.filter(
4428
- (i) => i.data.status === "ready-for-agent"
4429
- ).length;
4430
- if (readyForAgentCount === 0) {
4431
- return {
4432
- ok: false,
4433
- failureCode: "triage_inconsistent",
4434
- message: "At least one child Issue must be ready-for-agent when blocked children exist"
4435
- };
4436
- }
4437
- }
4438
- for (const issue of issues) {
4439
- const labels = issue.data.labels ?? [];
4440
- const status = issue.data.status;
4441
- const triageLabel = labels.find(
4442
- (l) => VALID_ISSUE_TRIAGE_LABELS.includes(l)
4443
- );
4444
- if (triageLabel && status !== "running" && status !== "complete" && triageLabel !== status) {
4445
- return {
4446
- ok: false,
4447
- failureCode: "triage_inconsistent",
4448
- offendingPath: issue.path,
4449
- message: `Issue ${issue.data.id} has status "${status}" but triage-state label "${triageLabel}"`
4450
- };
4451
- }
4452
- }
4453
- for (const issue of issues) {
4454
- const labels = issue.data.labels ?? [];
4455
- const triageLabels = labels.filter(
4456
- (l) => VALID_ISSUE_TRIAGE_LABELS.includes(l)
4457
- );
4458
- if (triageLabels.length !== 1) {
4459
- return {
4460
- ok: false,
4461
- failureCode: "triage_inconsistent",
4462
- offendingPath: issue.path,
4463
- message: `Issue ${issue.data.id} must have exactly one triage-state label, got ${triageLabels.length}`
4464
- };
4465
- }
4466
- }
4467
- for (const issue of issues.filter(
4468
- (i) => i.data.status === "ready-for-agent"
4469
- )) {
4470
- const deps = issue.data.dependencyIssueIds ?? [];
4471
- for (const depId of deps) {
4472
- const dep = issuesById.get(depId);
4473
- if (dep && dep.data.status !== "complete") {
4474
- return {
4475
- ok: false,
4476
- failureCode: "triage_inconsistent",
4477
- offendingPath: issue.path,
4478
- message: `ready-for-agent Issue ${issue.data.id} has unresolved dependency ${depId} (status: ${dep.data.status})`
4479
- };
4480
- }
4481
- }
4482
- }
4483
- return { ok: true };
4484
- }
4485
-
4486
- // commands/issue-run.ts
4487
- import { existsSync as existsSync13, readFileSync as readFileSync15 } from "fs";
4488
- import { isAbsolute as isAbsolute5, join as join16 } from "path";
4489
-
4490
- // pr/templates.ts
4491
- init_common();
4492
- function renderBranchName(template, issue) {
4493
- return renderTemplate(template, issue);
4494
- }
4495
- function renderTemplate(template, issue) {
4496
- const issueSlug = slugify(issue.title);
4497
- return template.replace(/\{\{issue\.number\}\}/g, String(issue.number)).replace(/\{\{issue\.title\}\}/g, issue.title).replace(/\{\{issue\.body\}\}/g, issue.body).replace(/\{\{issue\.slug\}\}/g, issueSlug).replace(/\{\{issue\.state\}\}/g, issue.state);
4498
- }
4499
-
4500
- // commands/issue-run.ts
4501
- init_common();
4502
-
4503
- // commands/base-refresh.ts
4504
- init_common();
4505
- async function isIssueBranchStale(worktreePath, baseBranch, logger) {
4506
- try {
4507
- await execCapture(
4508
- "git",
4509
- ["merge-base", "--is-ancestor", baseBranch, "HEAD"],
4510
- {
4511
- cwd: worktreePath,
4512
- logger,
4513
- label: "git merge-base --is-ancestor"
4514
- }
4515
- );
4516
- return false;
4517
- } catch {
4518
- return true;
4519
- }
4520
- }
4521
- async function refreshStaleIssueBranch(options) {
4522
- const {
4523
- worktreePath,
4524
- baseBranch,
4525
- localGitBaseRef,
4526
- logger,
4527
- prNumber,
4528
- prState
4529
- } = options;
4530
- const stale = await isIssueBranchStale(worktreePath, localGitBaseRef, logger);
4531
- if (!stale) {
4532
- return { status: "skipped-current" };
4533
- }
4534
- if (prNumber !== void 0 && prState !== void 0) {
4535
- return {
4536
- status: "refused-published-history",
4537
- prNumber,
4538
- prState
4539
- };
4540
- }
4541
- try {
4542
- await execCapture("git", ["rebase", "--autostash", localGitBaseRef], {
4543
- cwd: worktreePath,
4544
- logger,
4545
- label: "git rebase --autostash"
4546
- });
4547
- return { status: "refreshed" };
4548
- } catch (error) {
4549
- let conflictedPaths = [];
4550
- try {
4551
- const statusResult = await execCapture("git", ["status", "--porcelain"], {
4552
- cwd: worktreePath,
4553
- logger,
4554
- label: "git status"
4555
- });
4556
- conflictedPaths = statusResult.stdout.split("\n").filter((line) => /^(AA|DD|UU|AU|UA|DU|UD)\s/.test(line)).map((line) => line.slice(3).trim()).filter(Boolean);
4557
- } catch {
4558
- }
4559
- return {
4560
- status: "conflicted",
4561
- message: error instanceof Error ? error.message : String(error),
4562
- conflictedPaths
4563
- };
4564
- }
4565
- }
4566
- function invalidateAfterBaseRefresh(state) {
4567
- return {
4568
- issueNumber: state.issueNumber,
4569
- targetName: state.targetName,
4570
- branchName: state.branchName,
4571
- baseBranch: state.baseBranch,
4572
- createdAt: state.createdAt,
4573
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
4574
- completedStages: {
4575
- builder: state.completedStages.builder
4576
- },
4577
- review: {
4578
- lifetimeIterations: 0
4579
- }
4580
- };
4581
- }
4582
-
4583
- // failure-resolution/effect-runtime.ts
4584
- import { Effect as Effect4 } from "effect";
4585
-
4586
- // shared/effect-runtime.ts
4587
- import { Effect as Effect3, Exit } from "effect";
4588
- import { UnknownException } from "effect/Cause";
4589
- var initialized = false;
4590
- function initializeEffectRuntime() {
4591
- if (initialized) return;
4592
- initialized = true;
4593
- }
4594
- function runEffect(program) {
4595
- ensureEffectRuntime();
4596
- return Effect3.runPromiseExit(program);
4597
- }
4598
- function ensureEffectRuntime() {
4599
- if (!initialized) {
4600
- initializeEffectRuntime();
4601
- }
4602
- }
4603
- function unwrapError(error) {
4604
- if (error instanceof UnknownException && error.error !== void 0) {
4605
- return error.error;
3828
+ }
3829
+ function unwrapError(error) {
3830
+ if (error instanceof UnknownException && error.error !== void 0) {
3831
+ return error.error;
4606
3832
  }
4607
3833
  return error;
4608
3834
  }
@@ -4621,15 +3847,15 @@ function runEffectAndMapExit(program) {
4621
3847
 
4622
3848
  // shared/attempt-log.ts
4623
3849
  import { appendFileSync, existsSync as existsSync8, mkdirSync as mkdirSync6, readFileSync as readFileSync8 } from "fs";
4624
- import { dirname as dirname4, join as join8 } from "path";
3850
+ import { dirname as dirname4, join as join7 } from "path";
4625
3851
  var ATTEMPT_LOG_PATH = ".pourkit/attempt-log.jsonl";
4626
3852
  function writeAttemptLog(worktreePath, entry) {
4627
- const logPath = join8(worktreePath, ATTEMPT_LOG_PATH);
3853
+ const logPath = join7(worktreePath, ATTEMPT_LOG_PATH);
4628
3854
  mkdirSync6(dirname4(logPath), { recursive: true });
4629
3855
  appendFileSync(logPath, JSON.stringify(entry) + "\n", "utf-8");
4630
3856
  }
4631
3857
  function readAttemptLog(worktreePath) {
4632
- const logPath = join8(worktreePath, ATTEMPT_LOG_PATH);
3858
+ const logPath = join7(worktreePath, ATTEMPT_LOG_PATH);
4633
3859
  if (!existsSync8(logPath)) {
4634
3860
  return [];
4635
3861
  }
@@ -4753,12 +3979,12 @@ async function runBaseRefreshAttempt(options) {
4753
3979
 
4754
3980
  // commands/conflict-resolution.ts
4755
3981
  import { existsSync as existsSync9, readFileSync as readFileSync9 } from "fs";
4756
- import { join as join9 } from "path";
3982
+ import { join as join8 } from "path";
4757
3983
  init_common();
4758
3984
  var CONFLICT_MARKER_PATTERN2 = /<<<<<<<|=======|>>>>>>>/m;
4759
3985
  async function hasUnresolvedConflictMarkers(worktreePath, files) {
4760
3986
  for (const file of files) {
4761
- const filePath = join9(worktreePath, file);
3987
+ const filePath = join8(worktreePath, file);
4762
3988
  try {
4763
3989
  const content = readFileSync9(filePath, "utf-8");
4764
3990
  if (CONFLICT_MARKER_PATTERN2.test(content)) {
@@ -5092,7 +4318,7 @@ async function prepareSerenaForTarget(options) {
5092
4318
 
5093
4319
  // failure-resolution/failure-resolution-agent.ts
5094
4320
  import { readFileSync as readFileSync10 } from "fs";
5095
- import { join as join10 } from "path";
4321
+ import { join as join9 } from "path";
5096
4322
 
5097
4323
  // failure-resolution/recovery-policy.ts
5098
4324
  function isSecuritySensitiveFailure(failure) {
@@ -5168,7 +4394,7 @@ async function runFailureResolutionAgent(options) {
5168
4394
  } = options;
5169
4395
  const frConfig = target.strategy.failureResolution;
5170
4396
  const artifactPath = packet.artifactTarget;
5171
- const fullArtifactPath = join10(worktreePath, artifactPath);
4397
+ const fullArtifactPath = join9(worktreePath, artifactPath);
5172
4398
  const fingerprint = computeFailureFingerprint(packet.stageName, failure._tag);
5173
4399
  const prompt = [
5174
4400
  `# Failure Resolution: ${packet.failureType}`,
@@ -5339,12 +4565,12 @@ async function writeRecoveryAttempt(worktreePath, outcome, fingerprint, summary,
5339
4565
  }
5340
4566
 
5341
4567
  // commands/pr-description-agent.ts
5342
- import { join as join12 } from "path";
4568
+ import { join as join11 } from "path";
5343
4569
  import { readFileSync as readFileSync11 } from "fs";
5344
4570
 
5345
4571
  // pr/pr-description-context.ts
5346
4572
  init_common();
5347
- import { join as join11 } from "path";
4573
+ import { join as join10 } from "path";
5348
4574
  import { readFile } from "fs/promises";
5349
4575
  import { Effect as Effect5 } from "effect";
5350
4576
  function collectFinalizerContextEffect(options) {
@@ -5409,7 +4635,7 @@ function remoteTargetBase(targetBase) {
5409
4635
  return targetBase.includes("/") ? targetBase : `origin/${targetBase}`;
5410
4636
  }
5411
4637
  function buildFinalizerPrompt(context, promptTemplate) {
5412
- const artifactPathInWorktree = join11(
4638
+ const artifactPathInWorktree = join10(
5413
4639
  ".pourkit",
5414
4640
  ".tmp",
5415
4641
  "finalizer",
@@ -5479,13 +4705,13 @@ function bridgeExecutionProvider2(ep) {
5479
4705
  }
5480
4706
  function runFinalizerAgent(options) {
5481
4707
  const { executionProvider } = options;
5482
- const artifactPathInWorktree = join12(
4708
+ const artifactPathInWorktree = join11(
5483
4709
  ".pourkit",
5484
4710
  ".tmp",
5485
4711
  "finalizer",
5486
4712
  "agent-output.md"
5487
4713
  );
5488
- const artifactPath = join12(options.worktreePath, artifactPathInWorktree);
4714
+ const artifactPath = join11(options.worktreePath, artifactPathInWorktree);
5489
4715
  const program = Effect6.gen(function* () {
5490
4716
  const fs = yield* FileSystem;
5491
4717
  const context = yield* collectFinalizerContextEffect({
@@ -5547,7 +4773,7 @@ function runFinalizerAgent(options) {
5547
4773
  );
5548
4774
  }
5549
4775
  function runPrDescriptionFinalizerCore(options) {
5550
- const artifactPath = join12(
4776
+ const artifactPath = join11(
5551
4777
  options.worktreePath,
5552
4778
  options.artifactPathInWorktree
5553
4779
  );
@@ -5656,298 +4882,10 @@ function loadFinalizerPromptEffect(repoRoot2, promptTemplate, fs) {
5656
4882
  }
5657
4883
  function persistGeneratedArtifactEffect(worktreePath, output, fs) {
5658
4884
  return Effect6.gen(function* () {
5659
- const dir = join12(worktreePath, ".pourkit", ".tmp", "finalizer");
4885
+ const dir = join11(worktreePath, ".pourkit", ".tmp", "finalizer");
5660
4886
  yield* fs.mkdir(dir).pipe(Effect6.catchAll(() => Effect6.void));
5661
- yield* fs.writeFile(join12(dir, "generated.md"), output).pipe(Effect6.catchAll(() => Effect6.void));
5662
- });
5663
- }
5664
-
5665
- // prd-run/local-merge-coordinator.ts
5666
- import { execFileSync as execFileSync2 } from "child_process";
5667
- import { existsSync as existsSync10, mkdirSync as mkdirSync7, readFileSync as readFileSync12, writeFileSync as writeFileSync4 } from "fs";
5668
- import { join as join13 } from "path";
5669
-
5670
- // prd-run/local-branches.ts
5671
- import { execFileSync, spawnSync as spawnSync2 } from "child_process";
5672
- function getLocalPrdBranchName(prdId) {
5673
- return `local/${prdId}`;
5674
- }
5675
- function materializeLocalPrdBranch(prdId, startBaseCommit, repoRoot2) {
5676
- const branch = getLocalPrdBranchName(prdId);
5677
- const root = repoRoot2 ?? process.cwd();
5678
- const branchExists = (() => {
5679
- try {
5680
- return spawnSync2("git", ["rev-parse", "--verify", "--quiet", branch], {
5681
- cwd: root,
5682
- encoding: "utf8",
5683
- stdio: "pipe"
5684
- }).status === 0;
5685
- } catch {
5686
- return false;
5687
- }
5688
- })();
5689
- if (branchExists) {
5690
- const currentCommit = spawnSync2("git", ["rev-parse", branch], {
5691
- cwd: root,
5692
- encoding: "utf8",
5693
- stdio: "pipe"
5694
- }).stdout?.toString?.().trim() ?? "";
5695
- if (currentCommit !== startBaseCommit) {
5696
- return {
5697
- ok: false,
5698
- failureCode: "branch_commit_mismatch",
5699
- message: `Local PRD branch ${branch} exists at commit ${currentCommit} but expected commit ${startBaseCommit}. The branch has diverged from the start base. To resolve, delete the local branch and rerun start, or manually reset it to the expected commit.`
5700
- };
5701
- }
5702
- return {
5703
- ok: true,
5704
- created: false
5705
- };
5706
- }
5707
- const branchResult = spawnSync2("git", ["branch", branch, startBaseCommit], {
5708
- cwd: root,
5709
- encoding: "utf8",
5710
- stdio: "pipe"
4887
+ yield* fs.writeFile(join11(dir, "generated.md"), output).pipe(Effect6.catchAll(() => Effect6.void));
5711
4888
  });
5712
- if (branchResult.status !== 0) {
5713
- const stderr = branchResult.stderr?.toString?.() ?? "unknown error";
5714
- return {
5715
- ok: false,
5716
- failureCode: "branch_creation_failed",
5717
- message: `Failed to create local PRD branch ${branch} at ${startBaseCommit}: ${stderr}`
5718
- };
5719
- }
5720
- return { ok: true, created: true };
5721
- }
5722
- var PROTECTED_BRANCHES = /* @__PURE__ */ new Set(["dev", "next", "main"]);
5723
- var LOCAL_BRANCH_PATTERN = /^local\/PRD-\d{4}(\/(I-\d{2}(-[a-z0-9-]+)?)?)?$/;
5724
- function validateLocalBranchName(name) {
5725
- if (!name || name.length === 0) {
5726
- return {
5727
- ok: false,
5728
- failureCode: "invalid_format",
5729
- message: "Branch name is empty."
5730
- };
5731
- }
5732
- if (isProtectedBranch(name)) {
5733
- return {
5734
- ok: false,
5735
- failureCode: "protected_branch",
5736
- message: `Branch "${name}" is protected.`
5737
- };
5738
- }
5739
- if (!LOCAL_BRANCH_PATTERN.test(name)) {
5740
- return {
5741
- ok: false,
5742
- failureCode: "invalid_format",
5743
- message: `Branch "${name}" does not match the local branch pattern.`
5744
- };
5745
- }
5746
- return { ok: true };
5747
- }
5748
- function isProtectedBranch(name) {
5749
- return PROTECTED_BRANCHES.has(name);
5750
- }
5751
-
5752
- // prd-run/local-merge-coordinator.ts
5753
- function getLocalStorePath(repoRoot2, prdId) {
5754
- return join13(repoRoot2, ".pourkit", "local-prd-runs", prdId);
5755
- }
5756
- function getMergeReceiptPath(repoRoot2, prdId, issueId) {
5757
- return join13(
5758
- getLocalStorePath(repoRoot2, prdId),
5759
- "merge-receipts",
5760
- `${issueId}.json`
5761
- );
5762
- }
5763
- function getIssueArtifactPath(repoRoot2, prdId, issueId) {
5764
- return join13(getLocalStorePath(repoRoot2, prdId), "issues", `${issueId}.json`);
5765
- }
5766
- function readIssueBranchName(repoRoot2, prdId, issueId) {
5767
- const issuePath = getIssueArtifactPath(repoRoot2, prdId, issueId);
5768
- if (!existsSync10(issuePath)) return null;
5769
- try {
5770
- const content = readFileSync12(issuePath, "utf-8");
5771
- const parsed = JSON.parse(content);
5772
- return typeof parsed.branchName === "string" && parsed.branchName ? parsed.branchName : null;
5773
- } catch {
5774
- return null;
5775
- }
5776
- }
5777
- async function hasLocalIssueMergeReceipt(prdId, issueId, repoRoot2) {
5778
- const root = repoRoot2 ?? process.cwd();
5779
- const receiptPath = getMergeReceiptPath(root, prdId, issueId);
5780
- if (!existsSync10(receiptPath)) return null;
5781
- try {
5782
- const content = readFileSync12(receiptPath, "utf-8");
5783
- const parsed = JSON.parse(content);
5784
- if (typeof parsed.prdId === "string" && typeof parsed.issueId === "string" && typeof parsed.stage === "string" && typeof parsed.sourceBranch === "string" && typeof parsed.localPrdBranch === "string" && typeof parsed.mergeCommit === "string" && typeof parsed.completedAt === "string") {
5785
- return parsed;
5786
- }
5787
- return null;
5788
- } catch {
5789
- return null;
5790
- }
5791
- }
5792
- async function squashMergeLocalIssue(prdId, issueId, input, repoRoot2) {
5793
- const root = repoRoot2 ?? process.cwd();
5794
- const receiptPath = getMergeReceiptPath(root, prdId, issueId);
5795
- if (existsSync10(receiptPath)) {
5796
- try {
5797
- const existing = JSON.parse(
5798
- readFileSync12(receiptPath, "utf-8")
5799
- );
5800
- if (existing.prdId === prdId && existing.issueId === issueId && existing.mergeCommit) {
5801
- return {
5802
- ok: false,
5803
- failureCode: "already_merged",
5804
- repairGuidance: `Issue ${issueId} was already merged into ${existing.localPrdBranch}. Merge commit: ${existing.mergeCommit}`
5805
- };
5806
- }
5807
- return {
5808
- ok: false,
5809
- failureCode: "invalid_receipt",
5810
- repairGuidance: `Merge receipt for ${issueId} belongs to different prd/issue. Remove it manually: ${receiptPath}`
5811
- };
5812
- } catch {
5813
- return {
5814
- ok: false,
5815
- failureCode: "invalid_receipt",
5816
- repairGuidance: `Merge receipt for ${issueId} is corrupted. Remove it manually: ${receiptPath}`
5817
- };
5818
- }
5819
- }
5820
- const sourceBranch = input?.sourceBranch ?? readIssueBranchName(root, prdId, issueId);
5821
- if (!sourceBranch) {
5822
- return {
5823
- ok: false,
5824
- failureCode: "not_found",
5825
- repairGuidance: `No source branch found for issue ${issueId} under PRD ${prdId}. Ensure the issue artifact exists with a valid branchName field.`
5826
- };
5827
- }
5828
- try {
5829
- execFileSync2(
5830
- "git",
5831
- ["show-ref", "--verify", "--quiet", `refs/heads/${sourceBranch}`],
5832
- { cwd: root, encoding: "utf8", stdio: "pipe" }
5833
- );
5834
- } catch {
5835
- return {
5836
- ok: false,
5837
- failureCode: "not_found",
5838
- repairGuidance: `Source branch "${sourceBranch}" does not exist locally. Check that the branch was created and not deleted.`
5839
- };
5840
- }
5841
- const targetBranch = getLocalPrdBranchName(prdId);
5842
- try {
5843
- execFileSync2(
5844
- "git",
5845
- ["show-ref", "--verify", "--quiet", `refs/heads/${targetBranch}`],
5846
- { cwd: root, encoding: "utf8", stdio: "pipe" }
5847
- );
5848
- } catch {
5849
- return {
5850
- ok: false,
5851
- failureCode: "not_found",
5852
- repairGuidance: `Local PRD branch "${targetBranch}" does not exist. Run \`prd-run start\` first to create it.`
5853
- };
5854
- }
5855
- try {
5856
- execFileSync2("git", ["checkout", targetBranch], {
5857
- cwd: root,
5858
- encoding: "utf8",
5859
- stdio: "pipe"
5860
- });
5861
- let preMergeHead;
5862
- try {
5863
- preMergeHead = execFileSync2("git", ["rev-parse", "HEAD"], {
5864
- cwd: root,
5865
- encoding: "utf8",
5866
- stdio: "pipe"
5867
- }).trim();
5868
- } catch {
5869
- return {
5870
- ok: false,
5871
- failureCode: "merge_error",
5872
- repairGuidance: "Failed to read current HEAD before merge."
5873
- };
5874
- }
5875
- execFileSync2("git", ["merge", "--squash", sourceBranch], {
5876
- cwd: root,
5877
- encoding: "utf8",
5878
- stdio: "pipe"
5879
- });
5880
- if (input) {
5881
- execFileSync2(
5882
- "git",
5883
- ["commit", "-m", input.finalizerTitle, "-m", input.finalizerBody],
5884
- { cwd: root, encoding: "utf8", stdio: "pipe" }
5885
- );
5886
- } else {
5887
- execFileSync2(
5888
- "git",
5889
- ["commit", "-m", `Squash merge ${sourceBranch} into ${targetBranch}`],
5890
- { cwd: root, encoding: "utf8", stdio: "pipe" }
5891
- );
5892
- }
5893
- const revParseResult = execFileSync2("git", ["rev-parse", "HEAD"], {
5894
- cwd: root,
5895
- encoding: "utf8",
5896
- stdio: "pipe"
5897
- });
5898
- const mergeCommit = revParseResult.trim();
5899
- const receipt = {
5900
- prdId,
5901
- issueId,
5902
- stage: "child-issue",
5903
- sourceBranch,
5904
- localPrdBranch: targetBranch,
5905
- mergeCommit,
5906
- finalizerArtifactPath: input?.finalizerArtifactPath ?? "",
5907
- completedAt: (/* @__PURE__ */ new Date()).toISOString()
5908
- };
5909
- try {
5910
- const receiptsDir = join13(
5911
- root,
5912
- ".pourkit",
5913
- "local-prd-runs",
5914
- prdId,
5915
- "merge-receipts"
5916
- );
5917
- mkdirSync7(receiptsDir, { recursive: true });
5918
- writeFileSync4(receiptPath, JSON.stringify(receipt, null, 2), "utf-8");
5919
- } catch {
5920
- try {
5921
- execFileSync2("git", ["reset", "--hard", preMergeHead], {
5922
- cwd: root,
5923
- encoding: "utf8",
5924
- stdio: "pipe"
5925
- });
5926
- } catch {
5927
- }
5928
- return {
5929
- ok: false,
5930
- failureCode: "receipt_error",
5931
- repairGuidance: "Failed to write merge receipt. Check disk space and permissions on .pourkit/local-prd-runs/. The merge commit has been rolled back."
5932
- };
5933
- }
5934
- return { ok: true, receipt };
5935
- } catch (error) {
5936
- const message = error instanceof Error ? error.message : String(error);
5937
- if (message.toLowerCase().includes("conflict")) {
5938
- return {
5939
- ok: false,
5940
- failureCode: "conflict",
5941
- repairGuidance: "Merge conflict during squash. Resolve conflicts in the working tree, then retry."
5942
- };
5943
- }
5944
- const stderr = error instanceof Error && "stderr" in error ? error.stderr : void 0;
5945
- return {
5946
- ok: false,
5947
- failureCode: "merge_error",
5948
- repairGuidance: stderr ? `Merge failed: ${stderr}` : `Merge failed: ${message}`
5949
- };
5950
- }
5951
4889
  }
5952
4890
 
5953
4891
  // pr/pr-body.ts
@@ -6020,8 +4958,8 @@ function extractClosingRefs(body) {
6020
4958
 
6021
4959
  // issues/github-issue-publication.ts
6022
4960
  init_common();
6023
- import { existsSync as existsSync11, readFileSync as readFileSync13 } from "fs";
6024
- import { isAbsolute as isAbsolute4, join as join14 } from "path";
4961
+ import { existsSync as existsSync10, readFileSync as readFileSync12 } from "fs";
4962
+ import { isAbsolute as isAbsolute4, join as join12 } from "path";
6025
4963
 
6026
4964
  // issues/issue-transitions.ts
6027
4965
  function createIssueTransitions(deps, labels) {
@@ -6496,11 +5434,11 @@ function readIssueFinalReviewArtifact(worktreeState, worktreePath) {
6496
5434
  if (!configuredPath) {
6497
5435
  return null;
6498
5436
  }
6499
- const artifactPath = isAbsolute4(configuredPath) ? configuredPath : join14(worktreePath, configuredPath);
6500
- if (!existsSync11(artifactPath)) return null;
5437
+ const artifactPath = isAbsolute4(configuredPath) ? configuredPath : join12(worktreePath, configuredPath);
5438
+ if (!existsSync10(artifactPath)) return null;
6501
5439
  let parsed;
6502
5440
  try {
6503
- parsed = JSON.parse(readFileSync13(artifactPath, "utf-8"));
5441
+ parsed = JSON.parse(readFileSync12(artifactPath, "utf-8"));
6504
5442
  } catch {
6505
5443
  return null;
6506
5444
  }
@@ -6755,9 +5693,9 @@ function isAllowedSecretPlaceholder(value) {
6755
5693
  }
6756
5694
 
6757
5695
  // commands/issue-final-review-agent.ts
6758
- import { existsSync as existsSync12, readFileSync as readFileSync14 } from "fs";
6759
- import { join as join15 } from "path";
6760
- var ISSUE_FINAL_REVIEW_ARTIFACT_PATH = join15(
5696
+ import { existsSync as existsSync11, readFileSync as readFileSync13 } from "fs";
5697
+ import { join as join13 } from "path";
5698
+ var ISSUE_FINAL_REVIEW_ARTIFACT_PATH = join13(
6761
5699
  ".pourkit",
6762
5700
  ".tmp",
6763
5701
  "issue-final-review",
@@ -6775,7 +5713,7 @@ async function runIssueFinalReviewAgent(options) {
6775
5713
  logger
6776
5714
  } = options;
6777
5715
  const artifactPathInWorktree = ISSUE_FINAL_REVIEW_ARTIFACT_PATH;
6778
- const artifactPath = join15(worktreePath, artifactPathInWorktree);
5716
+ const artifactPath = join13(worktreePath, artifactPathInWorktree);
6779
5717
  const strategy = target.strategy;
6780
5718
  const issueFinalReview = strategy.issueFinalReview;
6781
5719
  const agent = issueFinalReview;
@@ -6880,7 +5818,7 @@ function extractChangedPaths(parsed) {
6880
5818
  function loadIssueFinalReviewPrompt(options) {
6881
5819
  const { repoRoot: repoRoot2, promptTemplate, validationCommand } = options;
6882
5820
  const promptPath = resolvePromptTemplatePath(repoRoot2, promptTemplate);
6883
- const promptBody = existsSync12(promptPath) ? readFileSync14(promptPath, "utf-8") : promptTemplate;
5821
+ const promptBody = existsSync11(promptPath) ? readFileSync13(promptPath, "utf-8") : promptTemplate;
6884
5822
  return appendProtectedWorkGuidance(`${promptBody}
6885
5823
 
6886
5824
  ## Shared Run Context
@@ -6991,7 +5929,7 @@ async function advanceIssueFinalReview(options) {
6991
5929
  "Issue Final Review state is incomplete: missing artifactPath"
6992
5930
  );
6993
5931
  }
6994
- const artifactPath = isAbsolute5(ifrFromState.artifactPath) ? ifrFromState.artifactPath : join16(worktreePath, ifrFromState.artifactPath);
5932
+ const artifactPath = isAbsolute5(ifrFromState.artifactPath) ? ifrFromState.artifactPath : join14(worktreePath, ifrFromState.artifactPath);
6995
5933
  const validation = validateAgentArtifact({
6996
5934
  kind: "issue-final-review",
6997
5935
  artifactPath,
@@ -7396,7 +6334,6 @@ async function completeIssueRun(options) {
7396
6334
  let prTitle = issue.title;
7397
6335
  let prBody;
7398
6336
  let finalizerResult;
7399
- const isLocalModeForFinalizer = options.prdRunMode?.mode === "local";
7400
6337
  const finalizerFromState = worktreeState?.finalizer?.completed ? worktreeState.finalizer : null;
7401
6338
  if (finalizerFromState) {
7402
6339
  try {
@@ -7404,12 +6341,12 @@ async function completeIssueRun(options) {
7404
6341
  prTitle = finalizerFromState.title;
7405
6342
  prBody = finalizerFromState.body;
7406
6343
  } else if (finalizerFromState.artifactPath) {
7407
- if (!existsSync13(finalizerFromState.artifactPath)) {
6344
+ if (!existsSync12(finalizerFromState.artifactPath)) {
7408
6345
  throw new FinalizerFailure({
7409
6346
  message: `Finalizer artifact missing at ${finalizerFromState.artifactPath}`
7410
6347
  });
7411
6348
  }
7412
- const artifactContent = readFileSync15(
6349
+ const artifactContent = readFileSync14(
7413
6350
  finalizerFromState.artifactPath,
7414
6351
  "utf-8"
7415
6352
  );
@@ -7422,17 +6359,6 @@ async function completeIssueRun(options) {
7422
6359
  });
7423
6360
  }
7424
6361
  } catch (error) {
7425
- if (isLocalModeForFinalizer) {
7426
- return {
7427
- branchName,
7428
- target,
7429
- issue,
7430
- noOp: false,
7431
- mode: "local",
7432
- failureCode: "finalizer_failed",
7433
- repairGuidance: error instanceof Error ? error.message : "Finalizer state is invalid"
7434
- };
7435
- }
7436
6362
  throw error;
7437
6363
  }
7438
6364
  } else {
@@ -7453,17 +6379,6 @@ async function completeIssueRun(options) {
7453
6379
  })
7454
6380
  );
7455
6381
  } catch (error) {
7456
- if (isLocalModeForFinalizer) {
7457
- return {
7458
- branchName,
7459
- target,
7460
- issue,
7461
- noOp: false,
7462
- mode: "local",
7463
- failureCode: "finalizer_failed",
7464
- repairGuidance: error instanceof Error ? error.message : "Finalizer execution failed"
7465
- };
7466
- }
7467
6382
  throw error;
7468
6383
  }
7469
6384
  prTitle = finalizerResult.title;
@@ -7495,153 +6410,28 @@ async function completeIssueRun(options) {
7495
6410
  }
7496
6411
  });
7497
6412
  }
7498
- const finalCommitFromState = worktreeState?.finalCommit?.completed;
7499
- if (!finalCommitFromState) {
7500
- await finalizeWorktreeCommit({
7501
- worktreePath: executionResult.worktreePath,
7502
- baseRef: `origin/${effectiveBaseBranch}`,
7503
- title: prTitle,
7504
- body: finalBody,
7505
- logger
7506
- });
7507
- if (executionResult.worktreePath) {
7508
- const revParse = await execCapture("git", ["rev-parse", "HEAD"], {
7509
- cwd: executionResult.worktreePath,
7510
- logger,
7511
- label: "git rev-parse HEAD"
7512
- });
7513
- updateWorktreeRunState(executionResult.worktreePath, {
7514
- finalCommit: {
7515
- completed: true,
7516
- sha: revParse.stdout.trim()
7517
- }
7518
- });
7519
- }
7520
- }
7521
- const isLocalMode = options.prdRunMode?.mode === "local";
7522
- if (isLocalMode) {
7523
- const parsed = parseStackedIssue(issue.title, issue.body);
7524
- const prdId = parsed.parentRef;
7525
- if (!prdId) {
7526
- return {
7527
- branchName,
7528
- target,
7529
- issue,
7530
- noOp: false,
7531
- mode: "local",
7532
- failureCode: "finalizer_failed",
7533
- repairGuidance: "Local mode requires a PRD reference (## Parent) in the issue body or title. Add the parent PRD reference and retry."
7534
- };
7535
- }
7536
- const finalizerFromWorktreeState = worktreeState?.finalizer;
7537
- if (finalizerFromWorktreeState && !finalizerFromWorktreeState.completed) {
7538
- return {
7539
- branchName,
7540
- target,
7541
- issue,
7542
- noOp: false,
7543
- mode: "local",
7544
- failureCode: "finalizer_failed",
7545
- repairGuidance: "Finalizer did not complete on previous run. Re-run the issue finalizer and try again."
7546
- };
7547
- }
7548
- if (!prTitle || !finalBody) {
7549
- return {
7550
- branchName,
7551
- target,
7552
- issue,
7553
- noOp: false,
7554
- mode: "local",
7555
- failureCode: "finalizer_failed",
7556
- repairGuidance: "Finalizer produced empty title or body. Re-run the issue finalizer and try again."
7557
- };
7558
- }
7559
- const existingReceipt = await hasLocalIssueMergeReceipt(
7560
- prdId,
7561
- `issue-${issueNumber}`,
7562
- ROOT
7563
- );
7564
- if (existingReceipt) {
7565
- return {
7566
- branchName,
7567
- target,
7568
- issue,
7569
- noOp: false,
7570
- mode: "local",
7571
- failureCode: "already_merged",
7572
- localPrdBranch: existingReceipt.localPrdBranch,
7573
- mergeCommit: existingReceipt.mergeCommit,
7574
- receiptPath: join16(
7575
- ROOT,
7576
- ".pourkit",
7577
- "local-prd-runs",
7578
- prdId,
7579
- "merge-receipts",
7580
- `issue-${issueNumber}.json`
7581
- )
7582
- };
7583
- }
7584
- const mergeResult = await squashMergeLocalIssue(
7585
- prdId,
7586
- `issue-${issueNumber}`,
7587
- {
7588
- finalizerTitle: prTitle,
7589
- finalizerBody: finalBody,
7590
- finalizerArtifactPath: worktreeState?.finalizer?.artifactPath ?? "",
7591
- sourceBranch: branchName
7592
- },
7593
- ROOT
7594
- );
7595
- if (!mergeResult.ok) {
7596
- return {
7597
- branchName,
7598
- target,
7599
- issue,
7600
- noOp: false,
7601
- mode: "local",
7602
- failureCode: mergeResult.failureCode,
7603
- repairGuidance: mergeResult.repairGuidance ?? `Local squash-merge failed: ${mergeResult.failureCode}`
7604
- };
7605
- }
7606
- await issueProvider.removeLabel(issueNumber, config.labels.agentInProgress);
7607
- await issueProvider.removeLabel(
7608
- issueNumber,
7609
- config.labels.prOpenAwaitingMerge
7610
- );
7611
- let childCloseSucceeded = false;
7612
- try {
7613
- await issueProvider.closeIssue(issueNumber);
7614
- childCloseSucceeded = true;
7615
- } catch (error) {
7616
- logger.step(
7617
- "warn",
7618
- `Issue #${issueNumber} could not be closed: ${error instanceof Error ? error.message : String(error)}`
7619
- );
7620
- }
7621
- if (childCloseSucceeded) {
7622
- await maybeCloseParentAfterChildCompletion(
7623
- issueProvider,
7624
- issueNumber,
7625
- logger
7626
- );
6413
+ const finalCommitFromState = worktreeState?.finalCommit?.completed;
6414
+ if (!finalCommitFromState) {
6415
+ await finalizeWorktreeCommit({
6416
+ worktreePath: executionResult.worktreePath,
6417
+ baseRef: `origin/${effectiveBaseBranch}`,
6418
+ title: prTitle,
6419
+ body: finalBody,
6420
+ logger
6421
+ });
6422
+ if (executionResult.worktreePath) {
6423
+ const revParse = await execCapture("git", ["rev-parse", "HEAD"], {
6424
+ cwd: executionResult.worktreePath,
6425
+ logger,
6426
+ label: "git rev-parse HEAD"
6427
+ });
6428
+ updateWorktreeRunState(executionResult.worktreePath, {
6429
+ finalCommit: {
6430
+ completed: true,
6431
+ sha: revParse.stdout.trim()
6432
+ }
6433
+ });
7627
6434
  }
7628
- return {
7629
- branchName,
7630
- target,
7631
- issue,
7632
- noOp: false,
7633
- mode: "local",
7634
- localPrdBranch: getLocalPrdBranchName(prdId),
7635
- mergeCommit: mergeResult.receipt.mergeCommit,
7636
- receiptPath: join16(
7637
- ROOT,
7638
- ".pourkit",
7639
- "local-prd-runs",
7640
- prdId,
7641
- "merge-receipts",
7642
- `issue-${issueNumber}.json`
7643
- )
7644
- };
7645
6435
  }
7646
6436
  if (!executionResult.worktreePath) {
7647
6437
  throw new Error(
@@ -8008,7 +6798,7 @@ async function resolveIssueWorktree(root, branchName, baseBranch, logger) {
8008
6798
  return { mode: "new", branchName, baseRef };
8009
6799
  }
8010
6800
  function issueWorktreePath(root, branchName) {
8011
- return join16(root, ".sandcastle", "worktrees", branchName.replace(/\//g, "-"));
6801
+ return join14(root, ".sandcastle", "worktrees", branchName.replace(/\//g, "-"));
8012
6802
  }
8013
6803
  function resolveRegisteredIssueWorktreePath(worktreeListPorcelain, root, branchName) {
8014
6804
  const branchWorktreePath = parseWorktreeListPorcelain(
@@ -8036,7 +6826,7 @@ async function syncTargetBranch(root, baseBranch, logger) {
8036
6826
  }
8037
6827
  function loadBuilderPrompt(repoRoot2, promptTemplate) {
8038
6828
  const promptPath = resolvePromptTemplatePath(repoRoot2, promptTemplate);
8039
- const promptBody = existsSync13(promptPath) ? readFileSync15(promptPath, "utf-8") : promptTemplate;
6829
+ const promptBody = existsSync12(promptPath) ? readFileSync14(promptPath, "utf-8") : promptTemplate;
8040
6830
  return appendProtectedWorkGuidance(`${promptBody}
8041
6831
 
8042
6832
  ## Shared Run Context
@@ -8531,18 +7321,17 @@ async function runIssueCreateCommand(args, issueProvider, logger) {
8531
7321
 
8532
7322
  // commands/prd-run.ts
8533
7323
  import { lstatSync, realpathSync } from "fs";
8534
- import { join as join21 } from "path";
7324
+ import { join as join16 } from "path";
8535
7325
 
8536
7326
  // prd-run/state.ts
8537
7327
  import {
8538
- existsSync as existsSync14,
8539
- mkdirSync as mkdirSync8,
8540
- readFileSync as readFileSync16,
8541
- readdirSync as readdirSync4,
8542
- writeFileSync as writeFileSync5
7328
+ existsSync as existsSync13,
7329
+ mkdirSync as mkdirSync7,
7330
+ readFileSync as readFileSync15,
7331
+ readdirSync as readdirSync3,
7332
+ writeFileSync as writeFileSync4
8543
7333
  } from "fs";
8544
- import { mkdir as mkdir4, readFile as readFile4, writeFile } from "fs/promises";
8545
- import { join as join17 } from "path";
7334
+ import { join as join15 } from "path";
8546
7335
  import { z } from "zod";
8547
7336
  var PRD_RUN_STATE_DIR = ".pourkit/prd-runs";
8548
7337
  var PrdRunRecordSchema = z.object({
@@ -8559,11 +7348,9 @@ var PrdRunRecordSchema = z.object({
8559
7348
  "waiting_for_integration",
8560
7349
  "finalizing",
8561
7350
  "final_reviewed",
8562
- "complete",
8563
- "completed_local_branch"
7351
+ "complete"
8564
7352
  ]),
8565
7353
  updatedAt: z.string().min(1),
8566
- mode: z.enum(["github", "local"]).optional(),
8567
7354
  blockedGate: z.enum(["receipt-check", "branch-state", "git", "queue", "final-review"]).optional(),
8568
7355
  targetName: z.string().min(1).optional(),
8569
7356
  prdBranch: z.string().min(1).optional(),
@@ -8633,16 +7420,16 @@ function normalizePrdRunRef(ref) {
8633
7420
  function readPrdRun(repoRoot2, prdRef) {
8634
7421
  const normalized = normalizePrdRunRef(prdRef);
8635
7422
  const recordPath = getRecordPath(repoRoot2, normalized);
8636
- if (!existsSync14(recordPath)) {
7423
+ if (!existsSync13(recordPath)) {
8637
7424
  return { record: null, diagnostics: [] };
8638
7425
  }
8639
7426
  try {
8640
- const raw = JSON.parse(readFileSync16(recordPath, "utf-8"));
7427
+ const raw = JSON.parse(readFileSync15(recordPath, "utf-8"));
8641
7428
  const parsed = normalizeLegacyPrdRunRecord(PrdRunRecordSchema.parse(raw));
8642
7429
  return { record: parsed, diagnostics: [] };
8643
7430
  } catch (error) {
8644
7431
  try {
8645
- const raw = JSON.parse(readFileSync16(recordPath, "utf-8"));
7432
+ const raw = JSON.parse(readFileSync15(recordPath, "utf-8"));
8646
7433
  if (raw && typeof raw === "object" && raw.start && typeof raw.start === "object" && raw.start.startBaseBranch === void 0) {
8647
7434
  return {
8648
7435
  record: raw,
@@ -8663,20 +7450,20 @@ function readPrdRun(repoRoot2, prdRef) {
8663
7450
  }
8664
7451
  }
8665
7452
  function listPrdRuns(repoRoot2) {
8666
- const stateDir = join17(repoRoot2, PRD_RUN_STATE_DIR);
8667
- if (!existsSync14(stateDir)) {
7453
+ const stateDir = join15(repoRoot2, PRD_RUN_STATE_DIR);
7454
+ if (!existsSync13(stateDir)) {
8668
7455
  return { records: [], diagnostics: [] };
8669
7456
  }
8670
7457
  const records = [];
8671
7458
  const diagnostics = [];
8672
- for (const entry of readdirSync4(stateDir, { withFileTypes: true }).sort(
7459
+ for (const entry of readdirSync3(stateDir, { withFileTypes: true }).sort(
8673
7460
  (left, right) => left.name.localeCompare(right.name)
8674
7461
  )) {
8675
7462
  if (!entry.isFile() || !entry.name.endsWith(".json")) continue;
8676
- const recordPath = join17(stateDir, entry.name);
7463
+ const recordPath = join15(stateDir, entry.name);
8677
7464
  try {
8678
7465
  const record = normalizeLegacyPrdRunRecord(
8679
- PrdRunRecordSchema.parse(JSON.parse(readFileSync16(recordPath, "utf-8")))
7466
+ PrdRunRecordSchema.parse(JSON.parse(readFileSync15(recordPath, "utf-8")))
8680
7467
  );
8681
7468
  records.push(record);
8682
7469
  } catch (error) {
@@ -8689,10 +7476,10 @@ function listPrdRuns(repoRoot2) {
8689
7476
  }
8690
7477
  function writePrdRunRecord(repoRoot2, record) {
8691
7478
  const normalized = normalizePrdRunRef(record.prdRef);
8692
- const stateDir = join17(repoRoot2, PRD_RUN_STATE_DIR);
7479
+ const stateDir = join15(repoRoot2, PRD_RUN_STATE_DIR);
8693
7480
  const recordPath = getRecordPath(repoRoot2, normalized);
8694
- mkdirSync8(stateDir, { recursive: true });
8695
- writeFileSync5(
7481
+ mkdirSync7(stateDir, { recursive: true });
7482
+ writeFileSync4(
8696
7483
  recordPath,
8697
7484
  JSON.stringify({ ...record, prdRef: normalized }, null, 2),
8698
7485
  "utf-8"
@@ -8708,43 +7495,8 @@ function normalizeLegacyPrdRunRecord(record) {
8708
7495
  offendingPaths: void 0
8709
7496
  };
8710
7497
  }
8711
- var LocalPrdRunRecordSchema = z.object({
8712
- prdId: z.string().regex(
8713
- /^PRD-\d{4}$/,
8714
- "PRD id must use four-digit format (e.g., PRD-0052)"
8715
- ),
8716
- createdAt: z.string().min(1),
8717
- receipts: z.object({
8718
- start: z.object({
8719
- startedAt: z.string().min(1),
8720
- branch: z.string().min(1),
8721
- baseCommit: z.string().min(1)
8722
- }).strict().optional(),
8723
- queue: z.object({ completedAt: z.string().min(1) }).strict().optional(),
8724
- finalReview: z.object({
8725
- completedAt: z.string().min(1),
8726
- targetName: z.string().optional(),
8727
- prdBranch: z.string().optional(),
8728
- mergeBase: z.string().optional(),
8729
- verdict: z.enum([
8730
- "pass_no_changes",
8731
- "pass_with_retouch",
8732
- "needs_human_review",
8733
- "blocked"
8734
- ]).optional(),
8735
- diagnostics: z.array(z.string()).optional(),
8736
- artifactPath: z.string().optional()
8737
- }).strict().optional(),
8738
- complete: z.object({
8739
- completedAt: z.string().min(1),
8740
- branch: z.string().min(1),
8741
- stages: z.array(z.string())
8742
- }).strict().optional()
8743
- }).strict(),
8744
- metadata: z.record(z.unknown())
8745
- }).strict();
8746
7498
  function getRecordPath(repoRoot2, prdRef) {
8747
- return join17(
7499
+ return join15(
8748
7500
  repoRoot2,
8749
7501
  PRD_RUN_STATE_DIR,
8750
7502
  `${normalizePrdRunRef(prdRef)}.json`
@@ -8752,567 +7504,9 @@ function getRecordPath(repoRoot2, prdRef) {
8752
7504
  }
8753
7505
 
8754
7506
  // prd-run/coordinator.ts
8755
- import { spawnSync as spawnSync3 } from "child_process";
8756
- import { existsSync as existsSync16, readFileSync as readFileSync18 } from "fs";
8757
- import { join as join20 } from "path";
7507
+ import { spawnSync as spawnSync2 } from "child_process";
8758
7508
  import { Match, pipe } from "effect";
8759
7509
 
8760
- // prd-run/local-queue-loop.ts
8761
- import { readFileSync as readFileSync17, writeFileSync as writeFileSync6 } from "fs";
8762
- import { join as join19 } from "path";
8763
-
8764
- // prd-run/local-artifacts.ts
8765
- import { existsSync as existsSync15 } from "fs";
8766
- import { join as join18 } from "path";
8767
- var REQUIRED_PRD_FIELDS = [
8768
- "schemaVersion",
8769
- "kind",
8770
- "id",
8771
- "title",
8772
- "status",
8773
- "childIssueIds",
8774
- "linkedDecisionIds",
8775
- "reconciliationTarget",
8776
- "bodyMarkdown",
8777
- "bodyContract",
8778
- "receipts",
8779
- "githubProjection"
8780
- ];
8781
- var REQUIRED_ISSUE_FIELDS = [
8782
- "schemaVersion",
8783
- "kind",
8784
- "id",
8785
- "parentPrdId",
8786
- "title",
8787
- "status",
8788
- "labels",
8789
- "dependencyIssueIds",
8790
- "branchName",
8791
- "blockedReason",
8792
- "readyForHumanReason",
8793
- "bodyMarkdown",
8794
- "bodyContract",
8795
- "receipts",
8796
- "githubProjection"
8797
- ];
8798
- function prdStorePath(repoRoot2, prdId) {
8799
- return join18(repoRoot2, ".pourkit", "local-prd-runs", prdId);
8800
- }
8801
- function prdArtifactPath(repoRoot2, prdId) {
8802
- return join18(prdStorePath(repoRoot2, prdId), "prd.json");
8803
- }
8804
- function issueArtifactPath(repoRoot2, prdId, issueId) {
8805
- return join18(prdStorePath(repoRoot2, prdId), "issues", `${issueId}.json`);
8806
- }
8807
- function hasRequiredFields(data, requiredFields) {
8808
- for (const field of requiredFields) {
8809
- if (!(field in data)) {
8810
- return String(field);
8811
- }
8812
- }
8813
- return null;
8814
- }
8815
- async function resolveLocalPrdArtifact(prdId, repoRoot2) {
8816
- const root = repoRoot2 ?? process.cwd();
8817
- const prdPath = prdArtifactPath(root, prdId);
8818
- if (!existsSync15(prdPath)) {
8819
- return {
8820
- ok: false,
8821
- failureCode: "missing_prd_artifact",
8822
- message: `Local PRD artifact not found at ${prdPath}. Create the PRD artifact at .pourkit/local-prd-runs/${prdId}/prd.json using to-prd-local.`
8823
- };
8824
- }
8825
- const result = readLocalArtifact(prdPath);
8826
- if (!result.ok || !result.data) {
8827
- return {
8828
- ok: false,
8829
- failureCode: "invalid_artifact",
8830
- message: `Failed to read or parse PRD artifact at ${prdPath}: ${result.message}`
8831
- };
8832
- }
8833
- const missing = hasRequiredFields(
8834
- result.data,
8835
- REQUIRED_PRD_FIELDS
8836
- );
8837
- if (missing) {
8838
- return {
8839
- ok: false,
8840
- failureCode: "invalid_artifact",
8841
- message: `PRD artifact at ${prdPath} is missing required field: ${missing}`
8842
- };
8843
- }
8844
- if (result.data.kind !== "prd") {
8845
- return {
8846
- ok: false,
8847
- failureCode: "invalid_artifact",
8848
- message: `PRD artifact at ${prdPath} has kind "${result.data.kind}", expected "prd"`
8849
- };
8850
- }
8851
- return { ok: true, data: result.data };
8852
- }
8853
- async function resolveLocalIssueArtifacts(prdId, repoRoot2) {
8854
- const root = repoRoot2 ?? process.cwd();
8855
- const prdResult = await resolveLocalPrdArtifact(prdId, root);
8856
- if (!prdResult.ok) {
8857
- return prdResult;
8858
- }
8859
- const childIssueIds = prdResult.data.childIssueIds;
8860
- const issues = [];
8861
- for (const childId of childIssueIds) {
8862
- const issuePath = issueArtifactPath(root, prdId, childId);
8863
- if (!existsSync15(issuePath)) {
8864
- return {
8865
- ok: false,
8866
- failureCode: "missing_child_issue",
8867
- missingId: childId,
8868
- message: `Child Issue artifact "${childId}" not found at ${issuePath}. Ensure all child issues listed in childIssueIds have corresponding JSON artifacts under .pourkit/local-prd-runs/${prdId}/issues/.`
8869
- };
8870
- }
8871
- const result = readLocalArtifact(issuePath);
8872
- if (!result.ok || !result.data) {
8873
- return {
8874
- ok: false,
8875
- failureCode: "invalid_artifact",
8876
- missingId: childId,
8877
- message: `Failed to read or parse Issue artifact at ${issuePath}: ${result.message}`
8878
- };
8879
- }
8880
- const missing = hasRequiredFields(
8881
- result.data,
8882
- REQUIRED_ISSUE_FIELDS
8883
- );
8884
- if (missing) {
8885
- return {
8886
- ok: false,
8887
- failureCode: "invalid_artifact",
8888
- missingId: childId,
8889
- message: `Issue artifact at ${issuePath} is missing required field: ${missing}`
8890
- };
8891
- }
8892
- if (result.data.kind !== "issue") {
8893
- return {
8894
- ok: false,
8895
- failureCode: "invalid_artifact",
8896
- missingId: childId,
8897
- message: `Issue artifact at ${issuePath} has kind "${result.data.kind}", expected "issue"`
8898
- };
8899
- }
8900
- issues.push(result.data);
8901
- }
8902
- return { ok: true, data: issues };
8903
- }
8904
-
8905
- // prd-run/local-issue-run.ts
8906
- import { execFileSync as execFileSync3 } from "child_process";
8907
- init_common();
8908
- async function createLocalIssueBranch(prdId, issueId, repoRoot2) {
8909
- const root = repoRoot2 ?? process.cwd();
8910
- const issuesResult = await resolveLocalIssueArtifacts(prdId, root);
8911
- if (!issuesResult.ok) {
8912
- throw new Error(
8913
- `Cannot create local issue branch: ${issuesResult.message}`
8914
- );
8915
- }
8916
- const issue = issuesResult.data.find((i) => i.id === issueId);
8917
- if (!issue) {
8918
- throw new Error(`Issue "${issueId}" not found under PRD "${prdId}"`);
8919
- }
8920
- const slug = slugify(issue.title);
8921
- const branchName = `local/${prdId}/${issueId}-${slug}`;
8922
- const validation = validateLocalBranchName(branchName);
8923
- if (!validation.ok) {
8924
- throw new Error(
8925
- `Invalid local issue branch name "${branchName}": ${validation.message}`
8926
- );
8927
- }
8928
- const localPrdBranch = `local/${prdId}`;
8929
- try {
8930
- execFileSync3(
8931
- "git",
8932
- ["show-ref", "--verify", "--quiet", `refs/heads/${localPrdBranch}`],
8933
- {
8934
- cwd: root,
8935
- encoding: "utf8",
8936
- stdio: "pipe"
8937
- }
8938
- );
8939
- } catch {
8940
- throw new Error(
8941
- `Local PRD branch "${localPrdBranch}" does not exist. Create it first.`
8942
- );
8943
- }
8944
- let branchExists = false;
8945
- try {
8946
- execFileSync3(
8947
- "git",
8948
- ["show-ref", "--verify", "--quiet", `refs/heads/${branchName}`],
8949
- {
8950
- cwd: root,
8951
- encoding: "utf8",
8952
- stdio: "pipe"
8953
- }
8954
- );
8955
- branchExists = true;
8956
- } catch {
8957
- }
8958
- if (!branchExists) {
8959
- execFileSync3("git", ["checkout", "-b", branchName, localPrdBranch], {
8960
- cwd: root,
8961
- encoding: "utf8",
8962
- stdio: "pipe"
8963
- });
8964
- }
8965
- return { branchName, issue };
8966
- }
8967
- async function runLocalIssue(prdId, issueId, builder, repoRoot2, memory) {
8968
- try {
8969
- const root = repoRoot2 ?? process.cwd();
8970
- const { branchName: branch, issue } = await createLocalIssueBranch(
8971
- prdId,
8972
- issueId,
8973
- root
8974
- );
8975
- if (builder) {
8976
- const result = await builder.execute({
8977
- prdId,
8978
- issueId,
8979
- branch,
8980
- bodyMarkdown: issue.bodyMarkdown,
8981
- ...memory ? { memory } : {}
8982
- });
8983
- if (!result.ok) {
8984
- return {
8985
- ok: false,
8986
- issueId,
8987
- branch,
8988
- failureCode: result.error ?? "Builder execution failed"
8989
- };
8990
- }
8991
- if (!result.issueFinalReviewPassedAt || !result.finalizerTitle || !result.finalizerBody) {
8992
- return {
8993
- ok: false,
8994
- issueId,
8995
- branch,
8996
- failureCode: "Local issue run did not produce Issue Final Review and finalizer receipts"
8997
- };
8998
- }
8999
- return {
9000
- ok: true,
9001
- issueId,
9002
- branch,
9003
- issueFinalReviewPassedAt: result.issueFinalReviewPassedAt,
9004
- finalizerTitle: result.finalizerTitle,
9005
- finalizerBody: result.finalizerBody,
9006
- finalizerArtifactPath: result.finalizerArtifactPath
9007
- };
9008
- }
9009
- return {
9010
- ok: false,
9011
- issueId,
9012
- branch,
9013
- failureCode: "Local issue runner requires Issue Final Review and finalizer lifecycle execution before merge"
9014
- };
9015
- } catch (error) {
9016
- return {
9017
- ok: false,
9018
- issueId,
9019
- branch: "",
9020
- failureCode: error instanceof Error ? error.message : String(error)
9021
- };
9022
- }
9023
- }
9024
-
9025
- // prd-run/local-issue-adapter.ts
9026
- var VALID_TRIAGE_LABELS = /* @__PURE__ */ new Set([
9027
- "needs-triage",
9028
- "ready-for-agent",
9029
- "blocked",
9030
- "ready-for-human",
9031
- "wontfix"
9032
- ]);
9033
- function countTypeLabels(labels) {
9034
- return labels.filter((l) => l.startsWith("type:")).length;
9035
- }
9036
- function countTriageLabels(labels) {
9037
- return labels.filter((l) => VALID_TRIAGE_LABELS.has(l)).length;
9038
- }
9039
- function countCategoryLabels(labels) {
9040
- const triageCount = countTriageLabels(labels);
9041
- const typeCount = countTypeLabels(labels);
9042
- return labels.length - triageCount - typeCount;
9043
- }
9044
- function hasValidLabels(labels) {
9045
- if (countTriageLabels(labels) !== 1) return false;
9046
- if (!labels.includes("ready-for-agent")) return false;
9047
- if (countTypeLabels(labels) !== 1) return false;
9048
- if (countCategoryLabels(labels) !== 1) return false;
9049
- return true;
9050
- }
9051
- function isIssueBlockedByDependencies(issue, issues) {
9052
- const blockers = [];
9053
- for (const depId of issue.dependencyIssueIds) {
9054
- const dep = issues.find((i) => i.id === depId);
9055
- if (!dep || dep.receipts.completedAt === null) {
9056
- blockers.push(depId);
9057
- }
9058
- }
9059
- return blockers;
9060
- }
9061
- async function getRunnableLocalIssues(prdId, repoRoot2) {
9062
- const issuesResult = await resolveLocalIssueArtifacts(prdId, repoRoot2);
9063
- if (!issuesResult.ok) return [];
9064
- const issues = issuesResult.data;
9065
- const runnable = [];
9066
- for (const issue of issues) {
9067
- if (!hasValidLabels(issue.labels)) continue;
9068
- if (issue.status !== "ready-for-agent") continue;
9069
- const blockers = isIssueBlockedByDependencies(issue, issues);
9070
- runnable.push({
9071
- id: issue.id,
9072
- title: issue.title,
9073
- labels: issue.labels,
9074
- blockedBy: blockers.length > 0 ? blockers : void 0
9075
- });
9076
- }
9077
- const filtered = runnable.filter(
9078
- (i) => !i.blockedBy || i.blockedBy.length === 0
9079
- );
9080
- return filtered;
9081
- }
9082
-
9083
- // prd-run/local-queue-loop.ts
9084
- var CHILD_CLEANUP_LABELS = ["agent-in-progress", "pr-open-awaiting-merge"];
9085
- var LOCAL_ISSUE_ID_REGEX = /^I-(\d+)$/i;
9086
- function getIssueArtifactPath2(repoRoot2, prdId, issueId) {
9087
- return join19(
9088
- repoRoot2,
9089
- ".pourkit",
9090
- "local-prd-runs",
9091
- prdId,
9092
- "issues",
9093
- `${issueId}.json`
9094
- );
9095
- }
9096
- function readIssueArtifact(repoRoot2, prdId, issueId) {
9097
- try {
9098
- const content = readFileSync17(
9099
- getIssueArtifactPath2(repoRoot2, prdId, issueId),
9100
- "utf-8"
9101
- );
9102
- return JSON.parse(content);
9103
- } catch {
9104
- return null;
9105
- }
9106
- }
9107
- function writeIssueArtifact(repoRoot2, prdId, issue) {
9108
- writeFileSync6(
9109
- getIssueArtifactPath2(repoRoot2, prdId, issue.id),
9110
- JSON.stringify(issue, null, 2),
9111
- "utf-8"
9112
- );
9113
- }
9114
- function compareLocalIssueIds(a, b) {
9115
- const aMatch = a.match(LOCAL_ISSUE_ID_REGEX);
9116
- const bMatch = b.match(LOCAL_ISSUE_ID_REGEX);
9117
- if (aMatch && bMatch) {
9118
- const aNumber = Number.parseInt(aMatch[1], 10);
9119
- const bNumber = Number.parseInt(bMatch[1], 10);
9120
- if (aNumber !== bNumber) return aNumber - bNumber;
9121
- }
9122
- return a.localeCompare(b);
9123
- }
9124
- async function reconcileLocalBlockedIssues(prdId, repoRoot2) {
9125
- const root = repoRoot2 ?? process.cwd();
9126
- const issuesResult = await resolveLocalIssueArtifacts(prdId, root);
9127
- if (!issuesResult.ok) return;
9128
- const issues = issuesResult.data;
9129
- for (const issue of issues) {
9130
- const isBlocked = issue.status === "blocked";
9131
- if (!isBlocked) continue;
9132
- if (issue.dependencyIssueIds.length === 0) continue;
9133
- const depResults = await Promise.all(
9134
- issue.dependencyIssueIds.map(
9135
- (depId) => hasLocalIssueMergeReceipt(prdId, depId, root)
9136
- )
9137
- );
9138
- if (!depResults.every(Boolean)) continue;
9139
- const updated = readIssueArtifact(root, prdId, issue.id);
9140
- if (!updated) continue;
9141
- updated.blockedReason = null;
9142
- updated.labels = updated.labels.filter((l) => l !== "blocked");
9143
- if (!updated.labels.includes("ready-for-agent")) {
9144
- updated.labels.push("ready-for-agent");
9145
- }
9146
- if (hasValidLabels(updated.labels)) {
9147
- updated.status = "ready-for-agent";
9148
- } else {
9149
- updated.status = "needs-triage";
9150
- updated.labels = updated.labels.filter((l) => l !== "ready-for-agent");
9151
- if (!updated.labels.includes("needs-triage")) {
9152
- updated.labels.push("needs-triage");
9153
- }
9154
- }
9155
- updated.receipts.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
9156
- writeIssueArtifact(root, prdId, updated);
9157
- }
9158
- }
9159
- async function cleanupChildGitHubIssue(issue, issueProvider) {
9160
- const issueNumber = issue.githubProjection.issueNumber;
9161
- if (!issueNumber) return { ok: true };
9162
- if (!issueProvider) {
9163
- return {
9164
- ok: false,
9165
- failureCode: "missing_issue_provider",
9166
- repairGuidance: "Issue provider is not available. Cannot close child GitHub Issue or remove labels. Configure a GitHub Issue provider to enable cleanup parity."
9167
- };
9168
- }
9169
- for (const label of CHILD_CLEANUP_LABELS) {
9170
- try {
9171
- await issueProvider.removeLabel(issueNumber, label);
9172
- } catch {
9173
- }
9174
- }
9175
- try {
9176
- await issueProvider.closeIssue(issueNumber);
9177
- } catch {
9178
- }
9179
- return { ok: true };
9180
- }
9181
- async function runLocalQueueLoop(prdId, repoRoot2, issueProvider, memory) {
9182
- const root = repoRoot2 ?? process.cwd();
9183
- const completedIssues = [];
9184
- const blockedIssues = [];
9185
- await reconcileLocalBlockedIssues(prdId, root);
9186
- for (; ; ) {
9187
- const runnable = await getRunnableLocalIssues(prdId, root);
9188
- if (runnable.length === 0) {
9189
- const issuesResult = await resolveLocalIssueArtifacts(prdId, root);
9190
- if (issuesResult.ok) {
9191
- for (const issue2 of issuesResult.data) {
9192
- if (issue2.status === "blocked") {
9193
- blockedIssues.push(issue2.id);
9194
- }
9195
- }
9196
- }
9197
- break;
9198
- }
9199
- const issue = [...runnable].sort(
9200
- (a, b) => compareLocalIssueIds(a.id, b.id)
9201
- )[0];
9202
- const runResult = memory ? await runLocalIssue(prdId, issue.id, void 0, root, memory) : await runLocalIssue(prdId, issue.id, void 0, root);
9203
- if (!runResult.ok) {
9204
- return {
9205
- ok: false,
9206
- completedIssues,
9207
- blockedIssues,
9208
- failureCode: runResult.failureCode ?? `Issue ${issue.id} failed`,
9209
- repairGuidance: `Local issue run failed for ${issue.id}. Check the issue artifact and branch state.`,
9210
- blockedGate: "queue"
9211
- };
9212
- }
9213
- if (!runResult.issueFinalReviewPassedAt || !runResult.finalizerTitle || !runResult.finalizerBody) {
9214
- return {
9215
- ok: false,
9216
- completedIssues,
9217
- blockedIssues,
9218
- failureCode: runResult.failureCode ?? "issue_final_review_not_passed",
9219
- repairGuidance: "Local issue run must complete Issue Final Review and finalizer before local squash merge.",
9220
- blockedGate: "queue"
9221
- };
9222
- }
9223
- const runArtifact = readIssueArtifact(root, prdId, issue.id);
9224
- if (!runArtifact) {
9225
- return {
9226
- ok: false,
9227
- completedIssues,
9228
- blockedIssues,
9229
- failureCode: "missing_issue_artifact",
9230
- repairGuidance: `Issue artifact not found for ${issue.id} under PRD ${prdId}. Ensure the issue exists before running the queue loop.`,
9231
- blockedGate: "queue"
9232
- };
9233
- }
9234
- runArtifact.issueFinalReviewPassedAt = runResult.issueFinalReviewPassedAt;
9235
- runArtifact.receipts.reviewedAt = runResult.issueFinalReviewPassedAt;
9236
- runArtifact.receipts.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
9237
- writeIssueArtifact(root, prdId, runArtifact);
9238
- const mergeResult = await squashMergeLocalIssue(
9239
- prdId,
9240
- issue.id,
9241
- {
9242
- finalizerTitle: runResult.finalizerTitle,
9243
- finalizerBody: runResult.finalizerBody,
9244
- finalizerArtifactPath: runResult.finalizerArtifactPath ?? "",
9245
- sourceBranch: runResult.branch
9246
- },
9247
- root
9248
- );
9249
- if (!mergeResult.ok) {
9250
- if (mergeResult.failureCode === "already_merged") {
9251
- const alreadyMergedArtifact = readIssueArtifact(root, prdId, issue.id);
9252
- if (alreadyMergedArtifact) {
9253
- alreadyMergedArtifact.status = "complete";
9254
- alreadyMergedArtifact.receipts.completedAt = mergeResult.receipt?.completedAt ?? (/* @__PURE__ */ new Date()).toISOString();
9255
- alreadyMergedArtifact.receipts.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
9256
- writeIssueArtifact(root, prdId, alreadyMergedArtifact);
9257
- const cleanupResult = await cleanupChildGitHubIssue(
9258
- alreadyMergedArtifact,
9259
- issueProvider
9260
- );
9261
- if (!cleanupResult.ok) {
9262
- return {
9263
- ok: false,
9264
- completedIssues,
9265
- blockedIssues,
9266
- failureCode: cleanupResult.failureCode ?? "child_cleanup_failed",
9267
- repairGuidance: cleanupResult.repairGuidance ?? `Child GitHub Issue cleanup failed for ${issue.id}.`,
9268
- blockedGate: "queue"
9269
- };
9270
- }
9271
- }
9272
- completedIssues.push(issue.id);
9273
- await reconcileLocalBlockedIssues(prdId, root);
9274
- continue;
9275
- }
9276
- return {
9277
- ok: false,
9278
- completedIssues,
9279
- blockedIssues,
9280
- failureCode: mergeResult.failureCode ?? `Merge of ${issue.id} failed`,
9281
- repairGuidance: mergeResult.repairGuidance,
9282
- blockedGate: "queue"
9283
- };
9284
- }
9285
- const completedArtifact = readIssueArtifact(root, prdId, issue.id);
9286
- if (completedArtifact) {
9287
- completedArtifact.status = "complete";
9288
- completedArtifact.receipts.completedAt = mergeResult.receipt?.completedAt ?? (/* @__PURE__ */ new Date()).toISOString();
9289
- completedArtifact.receipts.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
9290
- writeIssueArtifact(root, prdId, completedArtifact);
9291
- const cleanupResult = await cleanupChildGitHubIssue(
9292
- completedArtifact,
9293
- issueProvider
9294
- );
9295
- if (!cleanupResult.ok) {
9296
- return {
9297
- ok: false,
9298
- completedIssues,
9299
- blockedIssues,
9300
- failureCode: cleanupResult.failureCode ?? "child_cleanup_failed",
9301
- repairGuidance: cleanupResult.repairGuidance ?? `Child GitHub Issue cleanup failed for ${issue.id}.`,
9302
- blockedGate: "queue"
9303
- };
9304
- }
9305
- }
9306
- completedIssues.push(issue.id);
9307
- await reconcileLocalBlockedIssues(prdId, root);
9308
- }
9309
- return {
9310
- ok: true,
9311
- completedIssues,
9312
- blockedIssues
9313
- };
9314
- }
9315
-
9316
7510
  // commands/queue.ts
9317
7511
  init_common();
9318
7512
  import { Effect as Effect8 } from "effect";
@@ -9670,7 +7864,6 @@ function runOneQueueIssueEffect(options) {
9670
7864
  }
9671
7865
  const { issue: selected } = outcome;
9672
7866
  const baseBranchOverride = options.queueRunContext?.prdBranch;
9673
- const prdRunMode = options.prdRunMode ?? options.queueRunContext?.prdRunMode;
9674
7867
  const runResult = yield* Effect8.tryPromise({
9675
7868
  try: () => runIssueCommand({
9676
7869
  issueNumber: selected.number,
@@ -9682,8 +7875,7 @@ function runOneQueueIssueEffect(options) {
9682
7875
  force,
9683
7876
  logger,
9684
7877
  repoRoot: repoRoot2,
9685
- ...baseBranchOverride ? { baseBranchOverride } : {},
9686
- ...prdRunMode ? { prdRunMode } : {}
7878
+ ...baseBranchOverride ? { baseBranchOverride } : {}
9687
7879
  }),
9688
7880
  catch: (e) => {
9689
7881
  if (e instanceof Error && e.name === "HumanHandoffStop") {
@@ -9699,10 +7891,6 @@ function runOneQueueIssueEffect(options) {
9699
7891
  logger.raw(` Branch: ${runResult.branchName}`);
9700
7892
  if (runResult.noOp) {
9701
7893
  logger.raw(" Status: no-op (closed without PR)");
9702
- } else if (runResult.mode === "local") {
9703
- logger.raw(` Local PRD Branch: ${runResult.localPrdBranch}`);
9704
- logger.raw(` Merge Commit: ${runResult.mergeCommit}`);
9705
- logger.raw(` Receipt: ${runResult.receiptPath}`);
9706
7894
  } else {
9707
7895
  logger.raw(` PR Title: ${runResult.prTitle}`);
9708
7896
  logger.raw(` PR Number: ${runResult.prNumber}`);
@@ -9762,8 +7950,7 @@ async function runQueueCommand(options) {
9762
7950
  logger: options.logger,
9763
7951
  repoRoot: options.repoRoot,
9764
7952
  prdRef: options.prdRef,
9765
- queueRunContext: options.queueRunContext,
9766
- prdRunMode: options.queueRunContext?.prdRunMode
7953
+ queueRunContext: options.queueRunContext
9767
7954
  };
9768
7955
  if (!options.loop) {
9769
7956
  return runEffectAndMapExit(runQueue(queueOptions));
@@ -9793,11 +7980,6 @@ function planPrdRunLaunchResume(record) {
9793
7980
  skipped: ["start", "queue"],
9794
7981
  resumed: []
9795
7982
  })),
9796
- Match.when({ status: "completed_local_branch" }, () => ({
9797
- attempted: [],
9798
- skipped: ["start", "queue"],
9799
- resumed: []
9800
- })),
9801
7983
  Match.when({ status: "complete" }, () => ({
9802
7984
  attempted: [],
9803
7985
  skipped: ["start", "queue"],
@@ -9945,42 +8127,16 @@ function resolvePrdRunBaseBranch(options) {
9945
8127
  return {
9946
8128
  ok: false,
9947
8129
  gate: "branch-state",
9948
- reason: `Invalid PRD Run base branch: "${trimmed}" must not end with ".lock" suffix.`,
9949
- diagnostics: [`Provided branch value: "${trimmed}"`],
9950
- offendingPaths: []
9951
- };
9952
- }
9953
- const source = options.baseBranchOverride !== void 0 ? "override" : "target";
9954
- return { ok: true, baseBranch: trimmed, source };
9955
- }
9956
- function validateLocalStartStore(repoRoot2, prdRef) {
9957
- const localStoreDir = join20(repoRoot2, ".pourkit", "local-prd-runs", prdRef);
9958
- const localStorePath = join20(localStoreDir, "prd.json");
9959
- let localStoreReady = false;
9960
- if (existsSync16(localStorePath)) {
9961
- try {
9962
- const content = JSON.parse(readFileSync18(localStorePath, "utf8"));
9963
- localStoreReady = content?.id === prdRef && content?.kind === "prd";
9964
- } catch {
9965
- localStoreReady = false;
9966
- }
9967
- }
9968
- if (!localStoreReady) {
9969
- return {
9970
- ok: false,
9971
- gate: "branch-state",
9972
- reason: `Local PRD Run Store not ready for ${prdRef}. Expected valid prd.json at .pourkit/local-prd-runs/${prdRef}/prd.json with matching PRD ID. Ensure Local PRD Run Store is initialized before starting.`,
9973
- diagnostics: [
9974
- `Expected store path: .pourkit/local-prd-runs/${prdRef}/prd.json`,
9975
- `Expected PRD ID: ${prdRef}`
9976
- ],
8130
+ reason: `Invalid PRD Run base branch: "${trimmed}" must not end with ".lock" suffix.`,
8131
+ diagnostics: [`Provided branch value: "${trimmed}"`],
9977
8132
  offendingPaths: []
9978
8133
  };
9979
8134
  }
9980
- return { ok: true };
8135
+ const source = options.baseBranchOverride !== void 0 ? "override" : "target";
8136
+ return { ok: true, baseBranch: trimmed, source };
9981
8137
  }
9982
8138
  function fetchOriginBranch(repoRoot2, baseBranch) {
9983
- const fetchResult = spawnSync3("git", ["fetch", "origin", baseBranch], {
8139
+ const fetchResult = spawnSync2("git", ["fetch", "origin", baseBranch], {
9984
8140
  cwd: repoRoot2,
9985
8141
  encoding: "utf8"
9986
8142
  });
@@ -9997,7 +8153,7 @@ function fetchOriginBranch(repoRoot2, baseBranch) {
9997
8153
  offendingPaths: []
9998
8154
  };
9999
8155
  }
10000
- const revParseResult = spawnSync3(
8156
+ const revParseResult = spawnSync2(
10001
8157
  "git",
10002
8158
  ["rev-parse", `origin/${baseBranch}`],
10003
8159
  {
@@ -10021,7 +8177,7 @@ function fetchOriginBranch(repoRoot2, baseBranch) {
10021
8177
  return { ok: true, startBaseCommit: revParseResult.stdout.trim() };
10022
8178
  }
10023
8179
  function inspectRemotePrdBranch(repoRoot2, prdRef) {
10024
- const result = spawnSync3("git", ["ls-remote", "--heads", "origin", prdRef], {
8180
+ const result = spawnSync2("git", ["ls-remote", "--heads", "origin", prdRef], {
10025
8181
  cwd: repoRoot2,
10026
8182
  encoding: "utf8"
10027
8183
  });
@@ -10045,7 +8201,7 @@ function inspectRemotePrdBranch(repoRoot2, prdRef) {
10045
8201
  return { ok: true, exists: true, headSha };
10046
8202
  }
10047
8203
  function fetchPrdBranch(repoRoot2, prdRef) {
10048
- const result = spawnSync3("git", ["fetch", "origin", prdRef], {
8204
+ const result = spawnSync2("git", ["fetch", "origin", prdRef], {
10049
8205
  cwd: repoRoot2,
10050
8206
  encoding: "utf8"
10051
8207
  });
@@ -10065,7 +8221,7 @@ function fetchPrdBranch(repoRoot2, prdRef) {
10065
8221
  return { ok: true };
10066
8222
  }
10067
8223
  async function ensurePrdBranchPublished(repoRoot2, prdRef, startBaseCommit) {
10068
- const pushResult = spawnSync3(
8224
+ const pushResult = spawnSync2(
10069
8225
  "git",
10070
8226
  ["push", "origin", `${startBaseCommit}:refs/heads/${prdRef}`],
10071
8227
  {
@@ -10124,8 +8280,7 @@ function persistStartingPrdRunRecord(repoRoot2, prdRef, existingRecord, start, c
10124
8280
  status: "starting",
10125
8281
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
10126
8282
  targetName: context.targetName,
10127
- start,
10128
- mode: context.mode
8283
+ start
10129
8284
  });
10130
8285
  }
10131
8286
  function blocked(repoRoot2, prdRef, gate, failureCode, reason, diagnostics, targetName) {
@@ -10155,28 +8310,6 @@ async function startPrdRun(options) {
10155
8310
  );
10156
8311
  }
10157
8312
  const existingRecord = readPrdRun(options.repoRoot, prdRef);
10158
- const resolvedMode = options.config ? (() => {
10159
- try {
10160
- const target = resolveTarget(options.config, targetName);
10161
- return resolvePrdRunMode(target).mode;
10162
- } catch {
10163
- return void 0;
10164
- }
10165
- })() : void 0;
10166
- if (resolvedMode && existingRecord.record?.mode && existingRecord.record.mode !== resolvedMode) {
10167
- return blocked(
10168
- options.repoRoot,
10169
- prdRef,
10170
- "branch-state",
10171
- "mode_mismatch",
10172
- `PRD Run ${prdRef} mode mismatch: recorded "${existingRecord.record.mode}" but resolved "${resolvedMode}". Resolve by using the correct target.`,
10173
- [
10174
- `Recorded mode: ${existingRecord.record.mode}`,
10175
- `Resolved mode: ${resolvedMode}`
10176
- ],
10177
- targetName
10178
- );
10179
- }
10180
8313
  const resolvedTarget = options.config ? resolveTarget(options.config, targetName) : null;
10181
8314
  const targetBaseBranch = resolvedTarget?.baseBranch ?? "main";
10182
8315
  const baseResolution = resolvePrdRunBaseBranch({
@@ -10222,11 +8355,10 @@ async function startPrdRun(options) {
10222
8355
  );
10223
8356
  }
10224
8357
  const currentStatus = existingRecord.record.status;
10225
- if (currentStatus === "running" || currentStatus === "drained" || currentStatus === "completed_prd_branch" || currentStatus === "completed_local_branch" || currentStatus === "complete") {
8358
+ if (currentStatus === "running" || currentStatus === "drained" || currentStatus === "completed_prd_branch" || currentStatus === "complete") {
10226
8359
  return {
10227
8360
  kind: "started",
10228
8361
  prdRef,
10229
- mode: resolvedMode,
10230
8362
  start: existingRecord.record.start,
10231
8363
  diagnostics: [],
10232
8364
  preservedStatus: currentStatus
@@ -10267,12 +8399,11 @@ async function startPrdRun(options) {
10267
8399
  prdRef,
10268
8400
  existingRecord,
10269
8401
  reusedStart,
10270
- { targetName, mode: resolvedMode }
8402
+ { targetName }
10271
8403
  );
10272
8404
  return {
10273
8405
  kind: "started",
10274
8406
  prdRef,
10275
- mode: resolvedMode,
10276
8407
  start: reusedStart,
10277
8408
  diagnostics: []
10278
8409
  };
@@ -10303,7 +8434,7 @@ async function startPrdRun(options) {
10303
8434
  fetchPrdResult.diagnostics
10304
8435
  );
10305
8436
  }
10306
- const ancestryResult = spawnSync3(
8437
+ const ancestryResult = spawnSync2(
10307
8438
  "git",
10308
8439
  [
10309
8440
  "merge-base",
@@ -10340,12 +8471,11 @@ async function startPrdRun(options) {
10340
8471
  prdRef,
10341
8472
  existingRecord,
10342
8473
  adoptedStart,
10343
- { targetName, mode: resolvedMode }
8474
+ { targetName }
10344
8475
  );
10345
8476
  return {
10346
8477
  kind: "started",
10347
8478
  prdRef,
10348
- mode: resolvedMode,
10349
8479
  start: adoptedStart,
10350
8480
  diagnostics: []
10351
8481
  };
@@ -10365,59 +8495,6 @@ async function startPrdRun(options) {
10365
8495
  fetchResult.diagnostics
10366
8496
  );
10367
8497
  }
10368
- if (resolvedMode === "local") {
10369
- const localStoreResult = validateLocalStartStore(options.repoRoot, prdRef);
10370
- if (!localStoreResult.ok) {
10371
- return blocked(
10372
- options.repoRoot,
10373
- prdRef,
10374
- localStoreResult.gate,
10375
- "local_store_invalid",
10376
- localStoreResult.reason,
10377
- localStoreResult.diagnostics
10378
- );
10379
- }
10380
- const localBranchName = getLocalPrdBranchName(prdRef);
10381
- const localBranchResult = materializeLocalPrdBranch(
10382
- prdRef,
10383
- fetchResult.startBaseCommit,
10384
- options.repoRoot
10385
- );
10386
- if (!localBranchResult.ok) {
10387
- return blocked(
10388
- options.repoRoot,
10389
- prdRef,
10390
- "branch-state",
10391
- "local_branch_failed",
10392
- localBranchResult.message,
10393
- [localBranchResult.message]
10394
- );
10395
- }
10396
- const updatedAt2 = (/* @__PURE__ */ new Date()).toISOString();
10397
- const start2 = buildStartReceipt({
10398
- status: "started",
10399
- targetName,
10400
- prdBranch: localBranchName,
10401
- startBaseBranch: baseResolution.baseBranch,
10402
- startBaseCommit: fetchResult.startBaseCommit,
10403
- branchAction: localBranchResult.created ? "created" : "reused",
10404
- startedAt: updatedAt2
10405
- });
10406
- persistStartingPrdRunRecord(
10407
- options.repoRoot,
10408
- prdRef,
10409
- existingRecord,
10410
- start2,
10411
- { targetName, mode: resolvedMode }
10412
- );
10413
- return {
10414
- kind: "started",
10415
- prdRef,
10416
- mode: resolvedMode,
10417
- start: start2,
10418
- diagnostics: []
10419
- };
10420
- }
10421
8498
  const branchResult = inspectRemotePrdBranch(options.repoRoot, prdRef);
10422
8499
  if (!branchResult.ok) {
10423
8500
  return blocked(
@@ -10456,7 +8533,7 @@ async function startPrdRun(options) {
10456
8533
  fetchPrdResult.diagnostics
10457
8534
  );
10458
8535
  }
10459
- const ancestryResult = spawnSync3(
8536
+ const ancestryResult = spawnSync2(
10460
8537
  "git",
10461
8538
  [
10462
8539
  "merge-base",
@@ -10493,12 +8570,11 @@ async function startPrdRun(options) {
10493
8570
  prdRef,
10494
8571
  existingRecord,
10495
8572
  adoptedStart,
10496
- { targetName, mode: resolvedMode }
8573
+ { targetName }
10497
8574
  );
10498
8575
  return {
10499
8576
  kind: "started",
10500
8577
  prdRef,
10501
- mode: resolvedMode,
10502
8578
  start: adoptedStart,
10503
8579
  diagnostics: []
10504
8580
  };
@@ -10532,13 +8608,11 @@ async function startPrdRun(options) {
10532
8608
  startedAt: updatedAt
10533
8609
  });
10534
8610
  persistStartingPrdRunRecord(options.repoRoot, prdRef, existingRecord, start, {
10535
- targetName,
10536
- mode: resolvedMode
8611
+ targetName
10537
8612
  });
10538
8613
  return {
10539
8614
  kind: "started",
10540
8615
  prdRef,
10541
- mode: resolvedMode,
10542
8616
  start,
10543
8617
  diagnostics: []
10544
8618
  };
@@ -10552,25 +8626,23 @@ function buildLaunchBlockedOutcome(prdRef, guidance, resume, start) {
10552
8626
  resume
10553
8627
  };
10554
8628
  }
10555
- function writeDrainedRecord(repoRoot2, prdRef, startReceipt, targetName, mode) {
8629
+ function writeDrainedRecord(repoRoot2, prdRef, startReceipt, targetName) {
10556
8630
  writePrdRunRecord(repoRoot2, {
10557
8631
  prdRef,
10558
8632
  status: "drained",
10559
8633
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
10560
8634
  targetName,
10561
- start: startReceipt,
10562
- mode
8635
+ start: startReceipt
10563
8636
  });
10564
8637
  }
10565
- function writeTerminalRecord(repoRoot2, prdRef, status, targetName, startReceipt, prdBranch, mode) {
8638
+ function writeTerminalRecord(repoRoot2, prdRef, status, targetName, startReceipt, prdBranch) {
10566
8639
  writePrdRunRecord(repoRoot2, {
10567
8640
  prdRef,
10568
8641
  status,
10569
8642
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
10570
8643
  targetName,
10571
8644
  prdBranch,
10572
- start: startReceipt,
10573
- mode
8645
+ start: startReceipt
10574
8646
  });
10575
8647
  }
10576
8648
  function validatePrdRunStartEvidence(record, context) {
@@ -10629,22 +8701,6 @@ function validatePrdRunStartEvidence(record, context) {
10629
8701
  }
10630
8702
  };
10631
8703
  }
10632
- if (record.mode && record.mode !== context.mode) {
10633
- return {
10634
- ok: false,
10635
- guidance: {
10636
- blockedGate: "branch-state",
10637
- failureCode: "mode_mismatch",
10638
- reason: `PRD Run ${context.prdRef} mode mismatch: recorded "${record.mode}" but expected "${context.mode}".`,
10639
- repairability: "operator-action",
10640
- diagnostics: [
10641
- `Recorded mode: ${record.mode}`,
10642
- `Expected mode: ${context.mode}`
10643
- ],
10644
- offendingPaths: []
10645
- }
10646
- };
10647
- }
10648
8704
  if (record.prdRef !== context.prdRef) {
10649
8705
  return {
10650
8706
  ok: false,
@@ -10764,31 +8820,6 @@ function validatePrdRunDrainEvidence(record, context) {
10764
8820
  async function launchPrdRun(options) {
10765
8821
  const prdRef = normalizePrdRunRef(options.prdRef);
10766
8822
  const existingRecord = readPrdRun(options.repoRoot, prdRef);
10767
- const resolvedLaunchMode = options.config ? (() => {
10768
- try {
10769
- const target = resolveTarget(options.config, options.targetName);
10770
- return resolvePrdRunMode(target).mode;
10771
- } catch {
10772
- return void 0;
10773
- }
10774
- })() : void 0;
10775
- if (resolvedLaunchMode && existingRecord.record?.mode && existingRecord.record.mode !== resolvedLaunchMode) {
10776
- return buildLaunchBlockedOutcome(
10777
- prdRef,
10778
- {
10779
- blockedGate: "branch-state",
10780
- failureCode: "mode_mismatch",
10781
- reason: `PRD Run ${prdRef} mode mismatch: recorded "${existingRecord.record.mode}" but resolved "${resolvedLaunchMode}". Resolve by using the correct target.`,
10782
- repairability: "operator-action",
10783
- diagnostics: [
10784
- `Recorded mode: ${existingRecord.record.mode}`,
10785
- `Resolved mode: ${resolvedLaunchMode}`
10786
- ],
10787
- offendingPaths: []
10788
- },
10789
- { attempted: [], skipped: ["start", "queue"], resumed: [] }
10790
- );
10791
- }
10792
8823
  const plan = planPrdRunLaunchResume(existingRecord.record);
10793
8824
  if (plan.blocked === "final_reviewed-incompatible") {
10794
8825
  return buildLaunchBlockedOutcome(
@@ -10806,7 +8837,7 @@ async function launchPrdRun(options) {
10806
8837
  plan
10807
8838
  );
10808
8839
  }
10809
- if (existingRecord.record?.status === "completed_prd_branch" || existingRecord.record?.status === "complete" || existingRecord.record?.status === "completed_local_branch") {
8840
+ if (existingRecord.record?.status === "completed_prd_branch" || existingRecord.record?.status === "complete") {
10810
8841
  return {
10811
8842
  kind: "already-terminal",
10812
8843
  prdRef,
@@ -10834,7 +8865,6 @@ async function launchPrdRun(options) {
10834
8865
  plan
10835
8866
  );
10836
8867
  }
10837
- const drainMode = resolvedLaunchMode ?? record.mode ?? "github";
10838
8868
  const resolvedTarget = options.config ? resolveTarget(options.config, options.targetName) : null;
10839
8869
  const targetBaseBranch = resolvedTarget?.baseBranch ?? "main";
10840
8870
  const baseResolution = resolvePrdRunBaseBranch({
@@ -10857,7 +8887,6 @@ async function launchPrdRun(options) {
10857
8887
  }
10858
8888
  const drainContext = {
10859
8889
  prdRef,
10860
- mode: drainMode,
10861
8890
  baseBranch: baseResolution.baseBranch,
10862
8891
  prdBranch: record.start.prdBranch
10863
8892
  };
@@ -10869,20 +8898,18 @@ async function launchPrdRun(options) {
10869
8898
  if (!drainEvidence.ok) {
10870
8899
  return buildLaunchBlockedOutcome(prdRef, drainEvidence.guidance, plan);
10871
8900
  }
10872
- const terminalStatus = drainMode === "local" ? "completed_local_branch" : "completed_prd_branch";
10873
8901
  writeTerminalRecord(
10874
8902
  options.repoRoot,
10875
8903
  prdRef,
10876
- terminalStatus,
8904
+ "completed_prd_branch",
10877
8905
  record.targetName ?? options.targetName,
10878
8906
  record.start,
10879
- record.start.prdBranch,
10880
- drainMode
8907
+ record.start.prdBranch
10881
8908
  );
10882
8909
  return {
10883
8910
  kind: "completed",
10884
8911
  prdRef,
10885
- status: terminalStatus,
8912
+ status: "completed_prd_branch",
10886
8913
  prdBranch: record.start.prdBranch,
10887
8914
  diagnostics: [
10888
8915
  `PRD Run ${prdRef} completed from drained state. Branch: ${record.start.prdBranch}.`
@@ -10933,7 +8960,6 @@ async function launchPrdRun(options) {
10933
8960
  const currentRecord = readPrdRun(options.repoRoot, prdRef).record;
10934
8961
  const startReceipt = currentRecord?.start;
10935
8962
  const targetName = currentRecord?.targetName ?? options.targetName;
10936
- const explicitMode = resolvedLaunchMode ?? currentRecord?.mode;
10937
8963
  if (startReceipt) {
10938
8964
  startReceipt.queueStartedAt = (/* @__PURE__ */ new Date()).toISOString();
10939
8965
  startReceipt.queueCommand = "queue-run";
@@ -10943,236 +8969,18 @@ async function launchPrdRun(options) {
10943
8969
  status: "running",
10944
8970
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
10945
8971
  targetName,
10946
- start: startReceipt,
10947
- mode: explicitMode
8972
+ start: startReceipt
10948
8973
  });
10949
- if (explicitMode === "local") {
10950
- return await launchLocalQueueDrain(
10951
- options,
10952
- prdRef,
10953
- startReceipt,
10954
- targetName,
10955
- explicitMode,
10956
- plan,
10957
- startOutcome
10958
- );
10959
- }
10960
8974
  return await launchGithubQueueDrain(
10961
8975
  options,
10962
8976
  prdRef,
10963
8977
  startReceipt,
10964
8978
  targetName,
10965
- explicitMode,
10966
8979
  plan,
10967
8980
  startOutcome
10968
8981
  );
10969
8982
  }
10970
- async function launchLocalQueueDrain(options, prdRef, startReceipt, targetName, mode, plan, startOutcome) {
10971
- if (!startReceipt) {
10972
- writePrdRunRecord(options.repoRoot, {
10973
- prdRef,
10974
- status: "blocked",
10975
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
10976
- targetName,
10977
- blockedGate: "branch-state",
10978
- blockedReason: `PRD Run ${prdRef} is missing start receipt before local queue drain.`,
10979
- diagnostics: [],
10980
- offendingPaths: []
10981
- });
10982
- return buildLaunchBlockedOutcome(
10983
- prdRef,
10984
- {
10985
- blockedGate: "branch-state",
10986
- failureCode: "missing_start_receipt",
10987
- reason: `PRD Run ${prdRef} is missing start receipt before local queue drain.`,
10988
- repairability: "automatic-retry-safe",
10989
- diagnostics: [],
10990
- offendingPaths: []
10991
- },
10992
- plan,
10993
- startOutcome
10994
- );
10995
- }
10996
- const localStoreDir = join20(
10997
- options.repoRoot,
10998
- ".pourkit",
10999
- "local-prd-runs",
11000
- prdRef
11001
- );
11002
- let localStoreReady = false;
11003
- if (existsSync16(localStoreDir)) {
11004
- const localStorePath = join20(localStoreDir, "prd.json");
11005
- try {
11006
- const content = JSON.parse(readFileSync18(localStorePath, "utf8"));
11007
- localStoreReady = content?.id === prdRef && content?.kind === "prd";
11008
- } catch {
11009
- localStoreReady = false;
11010
- }
11011
- }
11012
- if (!localStoreReady) {
11013
- const reason = `Local PRD Run Store not ready for ${prdRef}. Expected valid prd.json at .pourkit/local-prd-runs/${prdRef}/prd.json with matching PRD ID.`;
11014
- writePrdRunRecord(options.repoRoot, {
11015
- prdRef,
11016
- status: "blocked",
11017
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11018
- targetName,
11019
- start: startReceipt,
11020
- mode,
11021
- blockedGate: "branch-state",
11022
- blockedReason: reason,
11023
- diagnostics: [
11024
- `Expected store path: .pourkit/local-prd-runs/${prdRef}/prd.json`,
11025
- `Expected PRD ID: ${prdRef}`
11026
- ],
11027
- offendingPaths: []
11028
- });
11029
- return buildLaunchBlockedOutcome(
11030
- prdRef,
11031
- {
11032
- blockedGate: "branch-state",
11033
- failureCode: "local_store_invalid",
11034
- reason,
11035
- repairability: "operator-action",
11036
- diagnostics: [
11037
- `Expected store path: .pourkit/local-prd-runs/${prdRef}/prd.json`,
11038
- `Expected PRD ID: ${prdRef}`
11039
- ],
11040
- offendingPaths: []
11041
- },
11042
- plan,
11043
- startOutcome
11044
- );
11045
- }
11046
- const memoryExecutionContext = options.config?.memory?.enabled ? { available: true, sandboxDbPath: "/home/agent/.pourkit/icm/memories.db" } : void 0;
11047
- const queueResult = await runLocalQueueLoop(
11048
- prdRef,
11049
- options.repoRoot,
11050
- options.issueProvider,
11051
- memoryExecutionContext
11052
- );
11053
- if (!queueResult.ok) {
11054
- const failureCode = queueResult.failureCode ?? "queue_error";
11055
- const reason = queueResult.repairGuidance ?? `Local queue loop blocked: ${failureCode}`;
11056
- const diagnostics = [
11057
- `Local queue loop failed with failureCode "${failureCode}".`,
11058
- ...queueResult.repairGuidance ? [`Repair guidance: ${queueResult.repairGuidance}`] : []
11059
- ];
11060
- writePrdRunRecord(options.repoRoot, {
11061
- prdRef,
11062
- status: "blocked",
11063
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11064
- targetName,
11065
- start: startReceipt,
11066
- mode,
11067
- blockedGate: "queue",
11068
- blockedReason: reason,
11069
- diagnostics,
11070
- offendingPaths: []
11071
- });
11072
- return buildLaunchBlockedOutcome(
11073
- prdRef,
11074
- {
11075
- blockedGate: "queue",
11076
- failureCode,
11077
- reason,
11078
- repairability: "automatic-retry-safe",
11079
- diagnostics,
11080
- offendingPaths: []
11081
- },
11082
- plan,
11083
- startOutcome
11084
- );
11085
- }
11086
- if (queueResult.blockedIssues.length > 0) {
11087
- const reason = `Queue processed complete but ${queueResult.blockedIssues.length} blocked child issue(s) remain.`;
11088
- const diagnostics = [
11089
- reason,
11090
- `Blocked issues: ${queueResult.blockedIssues.join(", ")}`,
11091
- "Resolve blocked children before parent close."
11092
- ];
11093
- writePrdRunRecord(options.repoRoot, {
11094
- prdRef,
11095
- status: "blocked",
11096
- updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11097
- targetName,
11098
- start: startReceipt,
11099
- mode,
11100
- blockedGate: "queue",
11101
- blockedReason: reason,
11102
- diagnostics,
11103
- offendingPaths: []
11104
- });
11105
- return buildLaunchBlockedOutcome(
11106
- prdRef,
11107
- {
11108
- blockedGate: "queue",
11109
- failureCode: "blocked_child_issues",
11110
- reason,
11111
- repairability: "operator-action",
11112
- diagnostics,
11113
- offendingPaths: []
11114
- },
11115
- plan,
11116
- startOutcome
11117
- );
11118
- }
11119
- startReceipt.queueDrainedAt = (/* @__PURE__ */ new Date()).toISOString();
11120
- startReceipt.queueProcessedCount = queueResult.completedIssues.length + queueResult.blockedIssues.length;
11121
- const prdBranch = startReceipt.prdBranch ?? `local/${prdRef}`;
11122
- writeDrainedRecord(options.repoRoot, prdRef, startReceipt, targetName, mode);
11123
- const drainRecord = readPrdRun(options.repoRoot, prdRef).record;
11124
- if (drainRecord) {
11125
- const drainContext = {
11126
- prdRef,
11127
- mode,
11128
- baseBranch: startReceipt.startBaseBranch,
11129
- prdBranch
11130
- };
11131
- const startEvidence = validatePrdRunStartEvidence(
11132
- drainRecord,
11133
- drainContext
11134
- );
11135
- if (!startEvidence.ok) {
11136
- return buildLaunchBlockedOutcome(
11137
- prdRef,
11138
- startEvidence.guidance,
11139
- plan,
11140
- startOutcome
11141
- );
11142
- }
11143
- const drainEvidence = validatePrdRunDrainEvidence(
11144
- drainRecord,
11145
- drainContext
11146
- );
11147
- if (!drainEvidence.ok) {
11148
- return buildLaunchBlockedOutcome(
11149
- prdRef,
11150
- drainEvidence.guidance,
11151
- plan,
11152
- startOutcome
11153
- );
11154
- }
11155
- }
11156
- writeTerminalRecord(
11157
- options.repoRoot,
11158
- prdRef,
11159
- "completed_local_branch",
11160
- targetName,
11161
- startReceipt,
11162
- prdBranch,
11163
- mode
11164
- );
11165
- return {
11166
- kind: "completed",
11167
- prdRef,
11168
- status: "completed_local_branch",
11169
- prdBranch,
11170
- diagnostics: [`Local PRD Run ${prdRef} completed. Branch: ${prdBranch}.`],
11171
- start: startOutcome,
11172
- resume: plan
11173
- };
11174
- }
11175
- async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName, mode, plan, startOutcome) {
8983
+ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName, plan, startOutcome) {
11176
8984
  if (!options.issueProvider || !options.prProvider || !options.executionProvider || !options.logger) {
11177
8985
  const reason = `PRD Run ${prdRef} requires issueProvider, prProvider, executionProvider, and logger for GitHub-backed queue drain.`;
11178
8986
  writePrdRunRecord(options.repoRoot, {
@@ -11181,7 +8989,6 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11181
8989
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11182
8990
  targetName,
11183
8991
  start: startReceipt,
11184
- mode,
11185
8992
  blockedGate: "queue",
11186
8993
  blockedReason: reason,
11187
8994
  diagnostics: [
@@ -11212,7 +9019,6 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11212
9019
  status: "blocked",
11213
9020
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11214
9021
  targetName,
11215
- mode,
11216
9022
  blockedGate: "branch-state",
11217
9023
  blockedReason: `PRD Run ${prdRef} is missing start receipt before GitHub queue drain.`,
11218
9024
  diagnostics: [],
@@ -11240,7 +9046,6 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11240
9046
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11241
9047
  targetName,
11242
9048
  start: startReceipt,
11243
- mode,
11244
9049
  blockedGate: "queue",
11245
9050
  blockedReason: reason,
11246
9051
  diagnostics: ["Missing config for GitHub-backed mode."],
@@ -11264,13 +9069,6 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11264
9069
  const prProvider = options.prProvider;
11265
9070
  const executionProvider = options.executionProvider;
11266
9071
  const logger = options.logger;
11267
- let resolvedModeForQueue;
11268
- try {
11269
- const target = resolveTarget(options.config, options.targetName);
11270
- resolvedModeForQueue = resolvePrdRunMode(target);
11271
- } catch {
11272
- resolvedModeForQueue = void 0;
11273
- }
11274
9072
  try {
11275
9073
  const outcome = await runQueueCommand({
11276
9074
  targetName,
@@ -11285,8 +9083,7 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11285
9083
  prdRef,
11286
9084
  queueRunContext: {
11287
9085
  prdRef,
11288
- prdBranch: startReceipt.prdBranch,
11289
- prdRunMode: resolvedModeForQueue
9086
+ prdBranch: startReceipt.prdBranch
11290
9087
  }
11291
9088
  });
11292
9089
  if (outcome.selected === null && outcome.code === "drained") {
@@ -11300,7 +9097,6 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11300
9097
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11301
9098
  targetName,
11302
9099
  start: startReceipt,
11303
- mode,
11304
9100
  blockedGate: "queue",
11305
9101
  blockedReason: diagnostics[0],
11306
9102
  diagnostics,
@@ -11323,19 +9119,11 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11323
9119
  startReceipt.queueDrainedAt = (/* @__PURE__ */ new Date()).toISOString();
11324
9120
  startReceipt.queueProcessedCount = outcome.processedCount;
11325
9121
  const prdBranch = startReceipt.prdBranch ?? prdRef;
11326
- writeDrainedRecord(
11327
- options.repoRoot,
11328
- prdRef,
11329
- startReceipt,
11330
- targetName,
11331
- mode
11332
- );
9122
+ writeDrainedRecord(options.repoRoot, prdRef, startReceipt, targetName);
11333
9123
  const drainRecord = readPrdRun(options.repoRoot, prdRef).record;
11334
9124
  if (drainRecord) {
11335
- const drainMode = mode ?? "github";
11336
9125
  const drainContext = {
11337
9126
  prdRef,
11338
- mode: drainMode,
11339
9127
  baseBranch: startReceipt.startBaseBranch,
11340
9128
  prdBranch
11341
9129
  };
@@ -11370,8 +9158,7 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11370
9158
  "completed_prd_branch",
11371
9159
  targetName,
11372
9160
  startReceipt,
11373
- prdBranch,
11374
- mode
9161
+ prdBranch
11375
9162
  );
11376
9163
  return {
11377
9164
  kind: "completed",
@@ -11393,7 +9180,6 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11393
9180
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11394
9181
  targetName,
11395
9182
  start: startReceipt,
11396
- mode,
11397
9183
  blockedGate: "queue",
11398
9184
  blockedReason: outcome.reason,
11399
9185
  diagnostics,
@@ -11421,7 +9207,6 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11421
9207
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11422
9208
  targetName,
11423
9209
  start: startReceipt,
11424
- mode,
11425
9210
  blockedGate: "queue",
11426
9211
  blockedReason: outcomeReason,
11427
9212
  diagnostics: outcomeDiagnostics,
@@ -11449,7 +9234,6 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11449
9234
  updatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11450
9235
  targetName,
11451
9236
  start: startReceipt,
11452
- mode,
11453
9237
  blockedGate: "queue",
11454
9238
  blockedReason: msg,
11455
9239
  diagnostics,
@@ -11472,13 +9256,13 @@ async function launchGithubQueueDrain(options, prdRef, startReceipt, targetName,
11472
9256
  }
11473
9257
 
11474
9258
  // prd-run/final-review-validation.ts
11475
- import { existsSync as existsSync17, readFileSync as readFileSync19 } from "fs";
9259
+ import { existsSync as existsSync14, readFileSync as readFileSync16 } from "fs";
11476
9260
 
11477
9261
  // commands/prd-run.ts
11478
9262
  async function runPrdRunLaunchCommand(options) {
11479
9263
  const outcome = await launchPrdRun(options);
11480
9264
  const result = mapLaunchPrdRunOutcomeToCommandResult(outcome, options);
11481
- if (options.config && options.logger && (result.status === "completed_prd_branch" || result.status === "completed_local_branch")) {
9265
+ if (options.config && options.logger && result.status === "completed_prd_branch") {
11482
9266
  try {
11483
9267
  const target = resolveTarget(options.config, options.targetName);
11484
9268
  if (shouldCleanupRepositoryAfterPrdDrain(target)) {
@@ -11505,10 +9289,7 @@ function mapLaunchPrdRunOutcomeToCommandResult(outcome, options) {
11505
9289
  if (outcome.kind === "already-terminal") {
11506
9290
  const diagnostics = [
11507
9291
  `PRD Run ${prdRef} is already in status "${outcome.status}".`,
11508
- ...outcome.status === "completed_prd_branch" ? [buildCompletedPrdBranchHint(outcome.prdBranch ?? prdRef)] : [],
11509
- ...outcome.status === "completed_local_branch" ? [
11510
- `Local PRD Run ${prdRef} completed. Branch: ${outcome.prdBranch ?? `local/${prdRef}`}.`
11511
- ] : []
9292
+ ...outcome.status === "completed_prd_branch" ? [buildCompletedPrdBranchHint(outcome.prdBranch ?? prdRef)] : []
11512
9293
  ];
11513
9294
  return {
11514
9295
  prdRef,
@@ -11985,16 +9766,16 @@ async function runPrMergeCommand(args, logger, prProvider, config) {
11985
9766
  }
11986
9767
 
11987
9768
  // commands/init.ts
11988
- import { existsSync as existsSync18, statSync } from "fs";
9769
+ import { existsSync as existsSync15, statSync } from "fs";
11989
9770
  import {
11990
9771
  copyFile,
11991
- mkdir as mkdir5,
11992
- readFile as readFile5,
9772
+ mkdir as mkdir4,
9773
+ readFile as readFile4,
11993
9774
  readdir,
11994
9775
  rename,
11995
- writeFile as writeFile2
9776
+ writeFile
11996
9777
  } from "fs/promises";
11997
- import { createHash as createHash2, randomUUID } from "crypto";
9778
+ import { createHash, randomUUID } from "crypto";
11998
9779
  import path5 from "path";
11999
9780
  import { execFile as execFile2 } from "child_process";
12000
9781
  import { promisify as promisify2 } from "util";
@@ -12251,7 +10032,40 @@ Database path: use \`$POURKIT_ICM_DB\` when set, otherwise use \`.pourkit/icm/me
12251
10032
 
12252
10033
  CLI fallback: when MCP memory tools are unavailable, recall with \`icm --db "$POURKIT_ICM_DB" recall "<query>"\` or \`icm --db .pourkit/icm/memories.db recall "<query>"\`, and store durable observations with \`icm --db "$POURKIT_ICM_DB" store -c "<concise reusable observation>"\` or \`icm --db .pourkit/icm/memories.db store -c "<concise reusable observation>"\`.
12253
10034
 
12254
- Memory is advisory only. Never treat memory as a replacement for reading current repository files, Run Context, artifacts, or verification output. When memory conflicts with current source or canonical state, current source and canonical state win.`;
10035
+ Memory is advisory only. Never treat memory as a replacement for reading current repository files, Run Context, artifacts, or verification output. When memory conflicts with current source or canonical state, current source and canonical state win.
10036
+
10037
+ <!-- icm:start -->
10038
+ ## Persistent memory (ICM) \u2014 MANDATORY
10039
+
10040
+ This project uses [ICM](https://github.com/rtk-ai/icm) for persistent memory across sessions.
10041
+ You MUST use it actively. Not optional.
10042
+
10043
+ ### Recall (before starting work)
10044
+ \`\`\`bash
10045
+ icm recall "query" # search memories
10046
+ icm recall "query" -t "topic-name" # filter by topic
10047
+ icm recall-context "query" --limit 5 # formatted for prompt injection
10048
+ \`\`\`
10049
+
10050
+ ### Store \u2014 MANDATORY triggers
10051
+ You MUST call \`icm store\` when ANY of the following happens:
10052
+ 1. **Error resolved** \u2192 \`icm store -t errors-resolved -c "description" -i high -k "keyword1,keyword2"\`
10053
+ 2. **Architecture/design decision** \u2192 \`icm store -t decisions-{project} -c "description" -i high\`
10054
+ 3. **User preference discovered** \u2192 \`icm store -t preferences -c "description" -i critical\`
10055
+ 4. **Significant task completed** \u2192 \`icm store -t context-{project} -c "summary of work done" -i high\`
10056
+ 5. **Conversation exceeds ~20 tool calls without a store** \u2192 store a progress summary
10057
+
10058
+ Do this BEFORE responding to the user. Not after. Not later. Immediately.
10059
+
10060
+ Do NOT store: trivial details, info already in CLAUDE.md, ephemeral state (build logs, git status).
10061
+
10062
+ ### Other commands
10063
+ \`\`\`bash
10064
+ icm update <id> -c "updated content" # edit memory in-place
10065
+ icm health # topic hygiene audit
10066
+ icm topics # list all topics
10067
+ \`\`\`
10068
+ <!-- icm:end -->`;
12255
10069
  }
12256
10070
 
12257
10071
  // commands/init.ts
@@ -12268,7 +10082,7 @@ function resolveSourceAssetPath(sourceRoot, ...segments) {
12268
10082
  path5.join(sourceRoot, "dist", ...segments)
12269
10083
  ];
12270
10084
  for (const candidatePath of candidatePaths) {
12271
- if (existsSync18(candidatePath)) return candidatePath;
10085
+ if (existsSync15(candidatePath)) return candidatePath;
12272
10086
  }
12273
10087
  return path5.join(sourceRoot, "pourkit", ...segments);
12274
10088
  }
@@ -12485,7 +10299,7 @@ function generateConfigTemplate(options) {
12485
10299
  }
12486
10300
  const config = {
12487
10301
  $schema: "./schema/pourkit.schema.json",
12488
- schemaVersion: 1,
10302
+ schemaVersion: 2,
12489
10303
  targets: [target],
12490
10304
  workflowPack: {
12491
10305
  version: "1.0.0",
@@ -12674,11 +10488,11 @@ async function walkDir(dir) {
12674
10488
  return files;
12675
10489
  }
12676
10490
  async function computeFileChecksum(filePath) {
12677
- const content = await readFile5(filePath);
12678
- return createHash2("sha256").update(content).digest("hex");
10491
+ const content = await readFile4(filePath);
10492
+ return createHash("sha256").update(content).digest("hex");
12679
10493
  }
12680
10494
  function lockfileExists(root, name) {
12681
- return existsSync18(path5.join(root, name));
10495
+ return existsSync15(path5.join(root, name));
12682
10496
  }
12683
10497
  function detectPackageManager(root) {
12684
10498
  if (lockfileExists(root, "pnpm-lock.yaml")) return "pnpm";
@@ -12722,7 +10536,7 @@ async function discoverLocalSource(sourcePath) {
12722
10536
  async function discoverReadme(root) {
12723
10537
  for (const name of ["README.md", "readme.md"]) {
12724
10538
  const p = path5.join(root, name);
12725
- if (existsSync18(p)) {
10539
+ if (existsSync15(p)) {
12726
10540
  return p;
12727
10541
  }
12728
10542
  }
@@ -12732,7 +10546,7 @@ async function discoverAgentFiles(root) {
12732
10546
  const files = [];
12733
10547
  for (const name of ["AGENTS.md", "CLAUDE.md"]) {
12734
10548
  const p = path5.join(root, name);
12735
- if (existsSync18(p)) {
10549
+ if (existsSync15(p)) {
12736
10550
  files.push(p);
12737
10551
  }
12738
10552
  }
@@ -12740,7 +10554,7 @@ async function discoverAgentFiles(root) {
12740
10554
  }
12741
10555
  async function discoverMerlleState(root) {
12742
10556
  const p = path5.join(root, ".pourkit", "state.json");
12743
- return existsSync18(p) ? p : null;
10557
+ return existsSync15(p) ? p : null;
12744
10558
  }
12745
10559
  async function discoverAgentSkills(root) {
12746
10560
  const dirs = [
@@ -12749,7 +10563,7 @@ async function discoverAgentSkills(root) {
12749
10563
  ];
12750
10564
  const found = [];
12751
10565
  for (const d of dirs) {
12752
- if (existsSync18(d)) {
10566
+ if (existsSync15(d)) {
12753
10567
  found.push(d);
12754
10568
  }
12755
10569
  }
@@ -12759,12 +10573,12 @@ async function discoverRootDomainDocs(root) {
12759
10573
  const docs = [];
12760
10574
  for (const name of ["CONTEXT.md", "CONTEXT-MAP.md"]) {
12761
10575
  const p = path5.join(root, name);
12762
- if (existsSync18(p)) {
10576
+ if (existsSync15(p)) {
12763
10577
  docs.push(p);
12764
10578
  }
12765
10579
  }
12766
10580
  const adrDir = path5.join(root, "docs", "adr");
12767
- if (existsSync18(adrDir)) {
10581
+ if (existsSync15(adrDir)) {
12768
10582
  const entries = await readdir(adrDir, { withFileTypes: true });
12769
10583
  for (const entry of entries) {
12770
10584
  if (entry.isFile() && entry.name.endsWith(".md")) {
@@ -12906,7 +10720,7 @@ async function planInit(options) {
12906
10720
  for (const file of skillFiles) {
12907
10721
  const relPath = path5.relative(s, file);
12908
10722
  const destPath = path5.join(targetRoot, ".agents", "skills", relPath);
12909
- if (!existsSync18(destPath)) {
10723
+ if (!existsSync15(destPath)) {
12910
10724
  operations.push({
12911
10725
  kind: "copy",
12912
10726
  sourcePath: file,
@@ -12969,7 +10783,7 @@ async function planInit(options) {
12969
10783
  });
12970
10784
  }
12971
10785
  if (sourceRoot) {
12972
- if (!existsSync18(sourceRoot) || !statSync(sourceRoot).isDirectory()) {
10786
+ if (!existsSync15(sourceRoot) || !statSync(sourceRoot).isDirectory()) {
12973
10787
  warnings.push(
12974
10788
  `--from-local path does not exist or is not a directory: ${sourceRoot}`
12975
10789
  );
@@ -13034,9 +10848,9 @@ async function planInit(options) {
13034
10848
  "release",
13035
10849
  "skills"
13036
10850
  );
13037
- const srcSkills = existsSync18(packagedManagedSkills) ? [
10851
+ const srcSkills = existsSync15(packagedManagedSkills) ? [
13038
10852
  packagedManagedSkills,
13039
- ...existsSync18(packagedReleaseAddonSkills) ? [packagedReleaseAddonSkills] : []
10853
+ ...existsSync15(packagedReleaseAddonSkills) ? [packagedReleaseAddonSkills] : []
13040
10854
  ] : await discoverAgentSkills(sourceRoot);
13041
10855
  for (const s of srcSkills) {
13042
10856
  const isOpenCode = s.includes(".opencode");
@@ -13059,7 +10873,7 @@ async function planInit(options) {
13059
10873
  "skills",
13060
10874
  relPath
13061
10875
  );
13062
- if (!existsSync18(destPath)) {
10876
+ if (!existsSync15(destPath)) {
13063
10877
  operations.push({
13064
10878
  kind: "copy",
13065
10879
  sourcePath: file,
@@ -13146,7 +10960,7 @@ async function planInit(options) {
13146
10960
  });
13147
10961
  continue;
13148
10962
  }
13149
- const sourceContent = await readFile5(file, "utf-8");
10963
+ const sourceContent = await readFile4(file, "utf-8");
13150
10964
  const managedSourcePath = isReleaseAddon ? `.pourkit/managed/addons/release/skills/${skillName}/${relPath}` : `.pourkit/managed/skills/${skillName}/${relPath}`;
13151
10965
  operations.push({
13152
10966
  kind: "create",
@@ -13191,7 +11005,7 @@ async function planInit(options) {
13191
11005
  requiresConfirmation: false,
13192
11006
  destructive: false
13193
11007
  });
13194
- } else if (existsSync18(destPath)) {
11008
+ } else if (existsSync15(destPath)) {
13195
11009
  operations.push({
13196
11010
  kind: "skip",
13197
11011
  path: destPath,
@@ -13226,7 +11040,7 @@ async function planInit(options) {
13226
11040
  let packageScripts = {};
13227
11041
  let hasPackageJson = true;
13228
11042
  try {
13229
- const pkgContent = await readFile5(
11043
+ const pkgContent = await readFile4(
13230
11044
  path5.join(targetRoot, "package.json"),
13231
11045
  "utf-8"
13232
11046
  );
@@ -13249,7 +11063,7 @@ async function planInit(options) {
13249
11063
  }
13250
11064
  }
13251
11065
  const contextPath = path5.join(targetRoot, ".pourkit", "CONTEXT.md");
13252
- if (!existsSync18(contextPath) && !merleDestPaths.has(contextPath)) {
11066
+ if (!existsSync15(contextPath) && !merleDestPaths.has(contextPath)) {
13253
11067
  operations.push({
13254
11068
  kind: "create",
13255
11069
  path: contextPath,
@@ -13267,7 +11081,7 @@ async function planInit(options) {
13267
11081
  "adr",
13268
11082
  ".gitkeep"
13269
11083
  );
13270
- if (!existsSync18(adrGitkeep)) {
11084
+ if (!existsSync15(adrGitkeep)) {
13271
11085
  operations.push({
13272
11086
  kind: "create",
13273
11087
  path: adrGitkeep,
@@ -13289,7 +11103,7 @@ async function planInit(options) {
13289
11103
  "docs",
13290
11104
  "agents"
13291
11105
  );
13292
- const srcDocAgents = existsSync18(packagedManagedDocAgents) ? packagedManagedDocAgents : legacyDocAgents;
11106
+ const srcDocAgents = existsSync15(packagedManagedDocAgents) ? packagedManagedDocAgents : legacyDocAgents;
13293
11107
  const tgtManagedDocAgents = path5.join(
13294
11108
  targetRoot,
13295
11109
  ".pourkit",
@@ -13303,12 +11117,12 @@ async function planInit(options) {
13303
11117
  "docs",
13304
11118
  "agents"
13305
11119
  );
13306
- if (existsSync18(srcDocAgents)) {
11120
+ if (existsSync15(srcDocAgents)) {
13307
11121
  const docFiles = await walkDir(srcDocAgents);
13308
11122
  for (const file of docFiles) {
13309
11123
  const relPath = path5.relative(srcDocAgents, file);
13310
11124
  const managedDocDest = path5.join(tgtManagedDocAgents, relPath);
13311
- if (!existsSync18(managedDocDest) && relPath === "triage-labels.md") {
11125
+ if (!existsSync15(managedDocDest) && relPath === "triage-labels.md") {
13312
11126
  operations.push({
13313
11127
  kind: "create",
13314
11128
  path: managedDocDest,
@@ -13320,7 +11134,7 @@ async function planInit(options) {
13320
11134
  options.labels ?? DEFAULT_RUNNER_LABELS
13321
11135
  )
13322
11136
  });
13323
- } else if (!existsSync18(managedDocDest)) {
11137
+ } else if (!existsSync15(managedDocDest)) {
13324
11138
  const checksum = await computeFileChecksum(file);
13325
11139
  operations.push({
13326
11140
  kind: "copy",
@@ -13342,7 +11156,7 @@ async function planInit(options) {
13342
11156
  relPath
13343
11157
  );
13344
11158
  const stubDocDest = path5.join(tgtStubDocAgents, relPath);
13345
- if (existsSync18(stubDocDest)) continue;
11159
+ if (existsSync15(stubDocDest)) continue;
13346
11160
  operations.push({
13347
11161
  kind: "create",
13348
11162
  path: stubDocDest,
@@ -13376,7 +11190,7 @@ Do not edit this file.
13376
11190
  "docs",
13377
11191
  "agents"
13378
11192
  );
13379
- if (existsSync18(packagedReleaseAddonDocs)) {
11193
+ if (existsSync15(packagedReleaseAddonDocs)) {
13380
11194
  const docFiles = await walkDir(packagedReleaseAddonDocs);
13381
11195
  for (const file of docFiles) {
13382
11196
  const relPath = path5.relative(packagedReleaseAddonDocs, file);
@@ -13400,19 +11214,19 @@ Do not edit this file.
13400
11214
  "prompts"
13401
11215
  );
13402
11216
  const legacyPrompts = path5.join(sourceRoot, ".pourkit", "prompts");
13403
- const srcPrompts = existsSync18(packagedManagedPrompts) ? packagedManagedPrompts : legacyPrompts;
11217
+ const srcPrompts = existsSync15(packagedManagedPrompts) ? packagedManagedPrompts : legacyPrompts;
13404
11218
  const tgtManagedPrompts = path5.join(
13405
11219
  targetRoot,
13406
11220
  ".pourkit",
13407
11221
  "managed",
13408
11222
  "prompts"
13409
11223
  );
13410
- if (existsSync18(srcPrompts)) {
11224
+ if (existsSync15(srcPrompts)) {
13411
11225
  const promptFiles = await walkDir(srcPrompts);
13412
11226
  for (const file of promptFiles) {
13413
11227
  const relPath = path5.relative(srcPrompts, file);
13414
11228
  const promptDest = path5.join(tgtManagedPrompts, relPath);
13415
- if (existsSync18(promptDest)) continue;
11229
+ if (existsSync15(promptDest)) continue;
13416
11230
  const checksum = await computeFileChecksum(file);
13417
11231
  operations.push({
13418
11232
  kind: "copy",
@@ -13436,7 +11250,7 @@ Do not edit this file.
13436
11250
  ".sandcastle",
13437
11251
  "Dockerfile"
13438
11252
  );
13439
- if (existsSync18(tgtSandboxDockerfile)) {
11253
+ if (existsSync15(tgtSandboxDockerfile)) {
13440
11254
  operations.push({
13441
11255
  kind: "skip",
13442
11256
  path: tgtSandboxDockerfile,
@@ -13445,7 +11259,7 @@ Do not edit this file.
13445
11259
  requiresConfirmation: false,
13446
11260
  destructive: false
13447
11261
  });
13448
- } else if (existsSync18(srcSandboxDockerfile)) {
11262
+ } else if (existsSync15(srcSandboxDockerfile)) {
13449
11263
  const checksum = await computeFileChecksum(srcSandboxDockerfile);
13450
11264
  operations.push({
13451
11265
  kind: "copy",
@@ -13459,7 +11273,7 @@ Do not edit this file.
13459
11273
  });
13460
11274
  }
13461
11275
  const configJsonPath = path5.join(targetRoot, ".pourkit", "config.json");
13462
- if (!existsSync18(configJsonPath)) {
11276
+ if (!existsSync15(configJsonPath)) {
13463
11277
  const verifyCommands = inferVerificationCommands(
13464
11278
  packageScripts,
13465
11279
  pm || "npm"
@@ -13503,9 +11317,9 @@ Do not edit this file.
13503
11317
  "schema",
13504
11318
  "pourkit.schema.json"
13505
11319
  );
13506
- if (existsSync18(srcSchemaJson)) {
11320
+ if (existsSync15(srcSchemaJson)) {
13507
11321
  const checksum = await computeFileChecksum(srcSchemaJson);
13508
- if (!existsSync18(schemaJsonPath)) {
11322
+ if (!existsSync15(schemaJsonPath)) {
13509
11323
  operations.push({
13510
11324
  kind: "copy",
13511
11325
  sourcePath: srcSchemaJson,
@@ -13538,9 +11352,9 @@ Do not edit this file.
13538
11352
  "schema",
13539
11353
  "pourkit.schema.hash"
13540
11354
  );
13541
- if (existsSync18(srcSchemaHash)) {
11355
+ if (existsSync15(srcSchemaHash)) {
13542
11356
  const checksum = await computeFileChecksum(srcSchemaHash);
13543
- if (!existsSync18(schemaHashPath)) {
11357
+ if (!existsSync15(schemaHashPath)) {
13544
11358
  operations.push({
13545
11359
  kind: "copy",
13546
11360
  sourcePath: srcSchemaHash,
@@ -13566,7 +11380,7 @@ Do not edit this file.
13566
11380
  const hasExistingAgents = operations.some(
13567
11381
  (op) => (op.kind === "skip" || op.kind === "update") && op.path?.endsWith("AGENTS.md")
13568
11382
  );
13569
- if ((agentFileMode === "agents" || agentFileMode === "both") && !hasExistingAgents && !existsSync18(path5.join(targetRoot, "AGENTS.md"))) {
11383
+ if ((agentFileMode === "agents" || agentFileMode === "both") && !hasExistingAgents && !existsSync15(path5.join(targetRoot, "AGENTS.md"))) {
13570
11384
  operations.push({
13571
11385
  kind: "create",
13572
11386
  path: path5.join(targetRoot, "AGENTS.md"),
@@ -13582,7 +11396,7 @@ ${managedAgentContent}${MANAGED_BLOCK_END}
13582
11396
  const hasExistingClaude = operations.some(
13583
11397
  (op) => (op.kind === "skip" || op.kind === "update") && op.path?.endsWith("CLAUDE.md")
13584
11398
  );
13585
- if ((agentFileMode === "claude" || agentFileMode === "both") && !hasExistingClaude && !existsSync18(path5.join(targetRoot, "CLAUDE.md"))) {
11399
+ if ((agentFileMode === "claude" || agentFileMode === "both") && !hasExistingClaude && !existsSync15(path5.join(targetRoot, "CLAUDE.md"))) {
13586
11400
  operations.push({
13587
11401
  kind: "create",
13588
11402
  path: path5.join(targetRoot, "CLAUDE.md"),
@@ -13597,7 +11411,7 @@ ${managedAgentContent}${MANAGED_BLOCK_END}
13597
11411
  }
13598
11412
  const gitignoreTarget = path5.join(targetRoot, ".gitignore");
13599
11413
  const gitignoreContent = generateGitignoreBlock();
13600
- if (!existsSync18(gitignoreTarget)) {
11414
+ if (!existsSync15(gitignoreTarget)) {
13601
11415
  operations.push({
13602
11416
  kind: "create",
13603
11417
  path: gitignoreTarget,
@@ -13621,7 +11435,7 @@ ${gitignoreContent}${MANAGED_BLOCK_END}
13621
11435
  });
13622
11436
  }
13623
11437
  const openCodePath = path5.join(targetRoot, "opencode.json");
13624
- if (!existsSync18(openCodePath)) {
11438
+ if (!existsSync15(openCodePath)) {
13625
11439
  operations.push({
13626
11440
  kind: "create",
13627
11441
  path: openCodePath,
@@ -13633,7 +11447,7 @@ ${gitignoreContent}${MANAGED_BLOCK_END}
13633
11447
  });
13634
11448
  } else {
13635
11449
  try {
13636
- const existingContent = await readFile5(openCodePath, "utf-8");
11450
+ const existingContent = await readFile4(openCodePath, "utf-8");
13637
11451
  const existingConfig = JSON.parse(existingContent);
13638
11452
  if (typeof existingConfig !== "object" || existingConfig === null || Array.isArray(existingConfig)) {
13639
11453
  warnings.push(
@@ -13678,7 +11492,7 @@ ${gitignoreContent}${MANAGED_BLOCK_END}
13678
11492
  }
13679
11493
  }
13680
11494
  const manifestPath = path5.join(targetRoot, ".pourkit", "manifest.json");
13681
- if (existsSync18(manifestPath)) {
11495
+ if (existsSync15(manifestPath)) {
13682
11496
  operations.push({
13683
11497
  kind: "skip",
13684
11498
  path: manifestPath,
@@ -14059,7 +11873,7 @@ async function promptForInitChoices(plan, current) {
14059
11873
  }
14060
11874
  async function writeFileAtomic(filePath, content) {
14061
11875
  const tmpPath = `${filePath}.tmp.${randomUUID()}`;
14062
- await writeFile2(tmpPath, content, "utf-8");
11876
+ await writeFile(tmpPath, content, "utf-8");
14063
11877
  await rename(tmpPath, filePath);
14064
11878
  }
14065
11879
  var MANAGED_BLOCK_BEGIN = "<!-- BEGIN POURKIT MANAGED BLOCK -->";
@@ -14068,13 +11882,13 @@ async function updateManagedBlock(filePath, content) {
14068
11882
  const blockContent = `${MANAGED_BLOCK_BEGIN}
14069
11883
  ${content}${MANAGED_BLOCK_END}
14070
11884
  `;
14071
- if (!existsSync18(filePath)) {
11885
+ if (!existsSync15(filePath)) {
14072
11886
  const dir = path5.dirname(filePath);
14073
- await mkdir5(dir, { recursive: true });
11887
+ await mkdir4(dir, { recursive: true });
14074
11888
  await writeFileAtomic(filePath, blockContent);
14075
11889
  return;
14076
11890
  }
14077
- const existing = await readFile5(filePath, "utf-8");
11891
+ const existing = await readFile4(filePath, "utf-8");
14078
11892
  const beginIdx = existing.indexOf(MANAGED_BLOCK_BEGIN);
14079
11893
  const endIdx = existing.indexOf(MANAGED_BLOCK_END);
14080
11894
  if (beginIdx !== -1 && endIdx !== -1 && endIdx > beginIdx) {
@@ -14097,7 +11911,7 @@ async function writeManifest(plan, sourceMeta, agentFiles, packageManager) {
14097
11911
  if (op.requiresConfirmation) continue;
14098
11912
  const relPath = path5.relative(plan.targetRoot, op.path);
14099
11913
  if (relPath === ".pourkit/manifest.json") continue;
14100
- if (existsSync18(op.path)) {
11914
+ if (existsSync15(op.path)) {
14101
11915
  const sha256 = await computeFileChecksum(op.path);
14102
11916
  assets[relPath] = {
14103
11917
  ownership: op.ownership || "managed",
@@ -14106,7 +11920,7 @@ async function writeManifest(plan, sourceMeta, agentFiles, packageManager) {
14106
11920
  }
14107
11921
  }
14108
11922
  const manifest = {
14109
- schemaVersion: 1,
11923
+ schemaVersion: 2,
14110
11924
  initializedAt: (/* @__PURE__ */ new Date()).toISOString(),
14111
11925
  pourkit: {
14112
11926
  versionSource: sourceMeta.versionSource,
@@ -14122,7 +11936,7 @@ async function writeManifest(plan, sourceMeta, agentFiles, packageManager) {
14122
11936
  workflowPack: buildWorkflowPackMetadata(plan.enabledAddons ?? []),
14123
11937
  assets
14124
11938
  };
14125
- await mkdir5(manifestDir, { recursive: true });
11939
+ await mkdir4(manifestDir, { recursive: true });
14126
11940
  await writeFileAtomic(manifestPath, JSON.stringify(manifest, null, 2) + "\n");
14127
11941
  return manifest;
14128
11942
  }
@@ -14143,12 +11957,12 @@ async function applyInitPlan(plan, options) {
14143
11957
  skipped++;
14144
11958
  continue;
14145
11959
  }
14146
- if (existsSync18(op.path) && !op.destructive) {
11960
+ if (existsSync15(op.path) && !op.destructive) {
14147
11961
  skipped++;
14148
11962
  continue;
14149
11963
  }
14150
11964
  const dir = path5.dirname(op.path);
14151
- await mkdir5(dir, { recursive: true });
11965
+ await mkdir4(dir, { recursive: true });
14152
11966
  await writeFileAtomic(op.path, op.content ?? "");
14153
11967
  applied++;
14154
11968
  break;
@@ -14158,7 +11972,7 @@ async function applyInitPlan(plan, options) {
14158
11972
  skipped++;
14159
11973
  continue;
14160
11974
  }
14161
- if (existsSync18(op.path)) {
11975
+ if (existsSync15(op.path)) {
14162
11976
  skipped++;
14163
11977
  continue;
14164
11978
  }
@@ -14167,7 +11981,7 @@ async function applyInitPlan(plan, options) {
14167
11981
  skipped++;
14168
11982
  } else {
14169
11983
  const dir = path5.dirname(op.path);
14170
- await mkdir5(dir, { recursive: true });
11984
+ await mkdir4(dir, { recursive: true });
14171
11985
  await copyFile(op.sourcePath, op.path);
14172
11986
  applied++;
14173
11987
  }
@@ -14187,12 +12001,12 @@ async function applyInitPlan(plan, options) {
14187
12001
  skipped++;
14188
12002
  continue;
14189
12003
  }
14190
- if (existsSync18(op.path)) {
12004
+ if (existsSync15(op.path)) {
14191
12005
  skipped++;
14192
12006
  continue;
14193
12007
  }
14194
12008
  const dir = path5.dirname(op.path);
14195
- await mkdir5(dir, { recursive: true });
12009
+ await mkdir4(dir, { recursive: true });
14196
12010
  await rename(op.sourcePath, op.path);
14197
12011
  applied++;
14198
12012
  break;
@@ -14331,7 +12145,7 @@ async function applyInitFromSource(options) {
14331
12145
  if (!manifestSkipped) {
14332
12146
  const agentFiles = [];
14333
12147
  for (const name of ["AGENTS.md", "CLAUDE.md"]) {
14334
- if (existsSync18(path5.join(targetRoot, name))) {
12148
+ if (existsSync15(path5.join(targetRoot, name))) {
14335
12149
  agentFiles.push(path5.join(targetRoot, name));
14336
12150
  }
14337
12151
  }
@@ -14507,18 +12321,18 @@ Init applied: ${result.applied} operations applied, ${result.skipped} skipped.`
14507
12321
  }
14508
12322
 
14509
12323
  // commands/memory-init.ts
14510
- import { existsSync as existsSync19, mkdirSync as mkdirSync9, readFileSync as readFileSync20, writeFileSync as writeFileSync7 } from "fs";
14511
- import { join as join22 } from "path";
12324
+ import { existsSync as existsSync16, mkdirSync as mkdirSync8, readFileSync as readFileSync17, writeFileSync as writeFileSync5 } from "fs";
12325
+ import { join as join17 } from "path";
14512
12326
  async function runMemoryInitCommand(options) {
14513
12327
  const cwd = options.cwd ?? process.cwd();
14514
- const configPath = join22(cwd, ".pourkit", "config.json");
14515
- if (!existsSync19(configPath)) {
12328
+ const configPath = join17(cwd, ".pourkit", "config.json");
12329
+ if (!existsSync16(configPath)) {
14516
12330
  return {
14517
12331
  ok: false,
14518
12332
  message: "No .pourkit/config.json found. Run `pourkit init` first to initialize Pourkit, then run `pourkit memory init`."
14519
12333
  };
14520
12334
  }
14521
- const raw = JSON.parse(readFileSync20(configPath, "utf8"));
12335
+ const raw = JSON.parse(readFileSync17(configPath, "utf8"));
14522
12336
  let alreadyEnabled = false;
14523
12337
  if (Object.prototype.hasOwnProperty.call(raw, "memory")) {
14524
12338
  const m = raw.memory;
@@ -14541,10 +12355,10 @@ async function runMemoryInitCommand(options) {
14541
12355
  const memory = { enabled: true, provider: "icm" };
14542
12356
  if (!alreadyEnabled) {
14543
12357
  const next = { ...raw, memory };
14544
- writeFileSync7(configPath, JSON.stringify(next, null, 2) + "\n");
12358
+ writeFileSync5(configPath, JSON.stringify(next, null, 2) + "\n");
14545
12359
  }
14546
- mkdirSync9(join22(cwd, ".pourkit", "icm"), { recursive: true });
14547
- const gitignorePath = join22(cwd, ".gitignore");
12360
+ mkdirSync8(join17(cwd, ".pourkit", "icm"), { recursive: true });
12361
+ const gitignorePath = join17(cwd, ".gitignore");
14548
12362
  updateManagedBlockSync(gitignorePath, generateGitignoreBlock());
14549
12363
  const managed = await generateManagedAgentInstructions({
14550
12364
  sourceRoot: cwd,
@@ -14552,14 +12366,14 @@ async function runMemoryInitCommand(options) {
14552
12366
  });
14553
12367
  let updatedAgentFile = false;
14554
12368
  for (const fileName of ["AGENTS.md", "CLAUDE.md"]) {
14555
- const agentPath = join22(cwd, fileName);
14556
- if (existsSync19(agentPath)) {
12369
+ const agentPath = join17(cwd, fileName);
12370
+ if (existsSync16(agentPath)) {
14557
12371
  updateManagedBlockSync(agentPath, managed);
14558
12372
  updatedAgentFile = true;
14559
12373
  }
14560
12374
  }
14561
12375
  if (!updatedAgentFile) {
14562
- updateManagedBlockSync(join22(cwd, "AGENTS.md"), managed);
12376
+ updateManagedBlockSync(join17(cwd, "AGENTS.md"), managed);
14563
12377
  }
14564
12378
  return {
14565
12379
  ok: true,
@@ -14571,21 +12385,21 @@ function updateManagedBlockSync(filePath, content) {
14571
12385
  const blockContent = `${MANAGED_BLOCK_BEGIN}
14572
12386
  ${content}${MANAGED_BLOCK_END}
14573
12387
  `;
14574
- if (!existsSync19(filePath)) {
14575
- writeFileSync7(filePath, blockContent);
12388
+ if (!existsSync16(filePath)) {
12389
+ writeFileSync5(filePath, blockContent);
14576
12390
  return;
14577
12391
  }
14578
- const existing = readFileSync20(filePath, "utf8");
12392
+ const existing = readFileSync17(filePath, "utf8");
14579
12393
  const beginIdx = existing.indexOf(MANAGED_BLOCK_BEGIN);
14580
12394
  const endIdx = existing.indexOf(MANAGED_BLOCK_END);
14581
12395
  if (beginIdx !== -1 && endIdx !== -1 && endIdx > beginIdx) {
14582
12396
  const before = existing.slice(0, beginIdx);
14583
12397
  const after = existing.slice(endIdx + MANAGED_BLOCK_END.length);
14584
- writeFileSync7(filePath, before + blockContent + after);
12398
+ writeFileSync5(filePath, before + blockContent + after);
14585
12399
  return;
14586
12400
  }
14587
12401
  const suffix = existing.endsWith("\n") ? "" : "\n";
14588
- writeFileSync7(filePath, `${existing}${suffix}${blockContent}`);
12402
+ writeFileSync5(filePath, `${existing}${suffix}${blockContent}`);
14589
12403
  }
14590
12404
 
14591
12405
  // commands/serena.ts
@@ -14704,8 +12518,8 @@ async function runSerenaStatusCommand(options) {
14704
12518
  }
14705
12519
 
14706
12520
  // commands/config-schema.ts
14707
- import { readFileSync as readFileSync21, existsSync as existsSync20 } from "fs";
14708
- import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile3, readdir as readdir2 } from "fs/promises";
12521
+ import { readFileSync as readFileSync18, existsSync as existsSync17 } from "fs";
12522
+ import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile2, readdir as readdir2 } from "fs/promises";
14709
12523
  import { resolve as resolve4, dirname as dirname5, relative as relative2 } from "path";
14710
12524
  import { fileURLToPath as fileURLToPath3 } from "url";
14711
12525
  import Ajv2 from "ajv";
@@ -14717,7 +12531,7 @@ function resolvePackagedAssetPath2(fileName) {
14717
12531
  resolve4(__dirname3, "schema", fileName),
14718
12532
  resolve4(__dirname3, "../schema", fileName)
14719
12533
  ];
14720
- return candidates.find((candidate) => existsSync20(candidate)) ?? candidates[0];
12534
+ return candidates.find((candidate) => existsSync17(candidate)) ?? candidates[0];
14721
12535
  }
14722
12536
  var PACKAGED_SCHEMA_PATH = resolvePackagedAssetPath2("pourkit.schema.json");
14723
12537
  var PACKAGED_HASH_PATH = resolvePackagedAssetPath2("pourkit.schema.hash");
@@ -14725,7 +12539,7 @@ var _schemaValidator = null;
14725
12539
  var _schemaErrors = null;
14726
12540
  function getSchemaValidator() {
14727
12541
  if (!_schemaValidator) {
14728
- const schema = JSON.parse(readFileSync21(PACKAGED_SCHEMA_PATH, "utf-8"));
12542
+ const schema = JSON.parse(readFileSync18(PACKAGED_SCHEMA_PATH, "utf-8"));
14729
12543
  const ajv = new Ajv2({ strict: true });
14730
12544
  ajv.addKeyword("x-pourkit-schema-version");
14731
12545
  const validate = ajv.compile(schema);
@@ -14739,7 +12553,7 @@ function getSchemaValidator() {
14739
12553
  return _schemaValidator;
14740
12554
  }
14741
12555
  function readPackagedHash() {
14742
- return readFileSync21(PACKAGED_HASH_PATH, "utf-8");
12556
+ return readFileSync18(PACKAGED_HASH_PATH, "utf-8");
14743
12557
  }
14744
12558
  function localSchemaDir(repoRoot2) {
14745
12559
  return resolve4(repoRoot2, ".pourkit/schema");
@@ -14763,7 +12577,7 @@ function resolvePackagedReleaseAddonDocPath(docName) {
14763
12577
  }
14764
12578
  async function readPackagedTextFile(filePath) {
14765
12579
  try {
14766
- return await readFile6(filePath, "utf-8");
12580
+ return await readFile5(filePath, "utf-8");
14767
12581
  } catch {
14768
12582
  return null;
14769
12583
  }
@@ -14860,7 +12674,7 @@ async function validateWorkflowPack(cwd) {
14860
12674
  const baselineSkills = getBaselineManagedSkillNames();
14861
12675
  for (const docName of catalog.docs) {
14862
12676
  const localPath = resolve4(cwd, `.pourkit/managed/docs/agents/${docName}`);
14863
- if (!existsSync20(localPath)) {
12677
+ if (!existsSync17(localPath)) {
14864
12678
  failures.push({
14865
12679
  severity: "failure",
14866
12680
  kind: "missing_managed_asset",
@@ -14872,13 +12686,13 @@ async function validateWorkflowPack(cwd) {
14872
12686
  const packagedContent = await readPackagedTextFile(packagedPath);
14873
12687
  if (packagedContent !== null) {
14874
12688
  try {
14875
- const localContent = await readFile6(localPath, "utf-8");
12689
+ const localContent = await readFile5(localPath, "utf-8");
14876
12690
  if (localContent !== packagedContent) {
14877
12691
  const overridePath = resolve4(
14878
12692
  cwd,
14879
12693
  `.pourkit/overrides/docs/agents/${docName}`
14880
12694
  );
14881
- if (existsSync20(overridePath)) {
12695
+ if (existsSync17(overridePath)) {
14882
12696
  warnings.push({
14883
12697
  severity: "warning",
14884
12698
  kind: "overridden",
@@ -14901,7 +12715,7 @@ async function validateWorkflowPack(cwd) {
14901
12715
  }
14902
12716
  for (const skillName of baselineSkills) {
14903
12717
  const skillDir = resolve4(cwd, `.pourkit/managed/skills/${skillName}`);
14904
- if (!existsSync20(skillDir)) {
12718
+ if (!existsSync17(skillDir)) {
14905
12719
  failures.push({
14906
12720
  severity: "failure",
14907
12721
  kind: "missing_managed_asset",
@@ -14910,7 +12724,7 @@ async function validateWorkflowPack(cwd) {
14910
12724
  });
14911
12725
  } else {
14912
12726
  const skillSourcePath = resolve4(skillDir, "SKILL.md");
14913
- if (existsSync20(skillSourcePath)) {
12727
+ if (existsSync17(skillSourcePath)) {
14914
12728
  const packagedSkillPath = resolvePackagedManagedPath(
14915
12729
  "skills",
14916
12730
  skillName,
@@ -14919,13 +12733,13 @@ async function validateWorkflowPack(cwd) {
14919
12733
  const packagedContent = await readPackagedTextFile(packagedSkillPath);
14920
12734
  if (packagedContent !== null) {
14921
12735
  try {
14922
- const localContent = await readFile6(skillSourcePath, "utf-8");
12736
+ const localContent = await readFile5(skillSourcePath, "utf-8");
14923
12737
  if (localContent !== packagedContent) {
14924
12738
  const overridePath = resolve4(
14925
12739
  cwd,
14926
12740
  `.pourkit/overrides/skills/${skillName}/SKILL.md`
14927
12741
  );
14928
- if (existsSync20(overridePath)) {
12742
+ if (existsSync17(overridePath)) {
14929
12743
  warnings.push({
14930
12744
  severity: "warning",
14931
12745
  kind: "overridden",
@@ -14949,7 +12763,7 @@ async function validateWorkflowPack(cwd) {
14949
12763
  }
14950
12764
  for (const promptName of catalog.prompts) {
14951
12765
  const promptPath = resolve4(cwd, `.pourkit/managed/prompts/${promptName}`);
14952
- if (!existsSync20(promptPath)) {
12766
+ if (!existsSync17(promptPath)) {
14953
12767
  failures.push({
14954
12768
  severity: "failure",
14955
12769
  kind: "missing_managed_asset",
@@ -14960,7 +12774,7 @@ async function validateWorkflowPack(cwd) {
14960
12774
  }
14961
12775
  for (const skillName of baselineSkills) {
14962
12776
  const projectionDir = resolve4(cwd, `.agents/skills/${skillName}`);
14963
- if (!existsSync20(projectionDir)) {
12777
+ if (!existsSync17(projectionDir)) {
14964
12778
  warnings.push({
14965
12779
  severity: "warning",
14966
12780
  kind: "projection_stale",
@@ -14969,7 +12783,7 @@ async function validateWorkflowPack(cwd) {
14969
12783
  });
14970
12784
  } else {
14971
12785
  const projectionPath = resolve4(projectionDir, "SKILL.md");
14972
- if (existsSync20(projectionPath)) {
12786
+ if (existsSync17(projectionPath)) {
14973
12787
  const managedSourcePath = resolvePackagedManagedPath(
14974
12788
  "skills",
14975
12789
  skillName,
@@ -14978,7 +12792,7 @@ async function validateWorkflowPack(cwd) {
14978
12792
  const packagedContent = await readPackagedTextFile(managedSourcePath);
14979
12793
  if (packagedContent !== null) {
14980
12794
  try {
14981
- const projectionContent = await readFile6(projectionPath, "utf-8");
12795
+ const projectionContent = await readFile5(projectionPath, "utf-8");
14982
12796
  const managedSourceRelativePath = `.pourkit/managed/skills/${skillName}/SKILL.md`;
14983
12797
  if (projectionContent !== buildOpenCodeSkillProjectionContent(
14984
12798
  managedSourceRelativePath,
@@ -14998,9 +12812,9 @@ async function validateWorkflowPack(cwd) {
14998
12812
  }
14999
12813
  }
15000
12814
  const agentsPath = resolve4(cwd, "AGENTS.md");
15001
- if (existsSync20(agentsPath)) {
12815
+ if (existsSync17(agentsPath)) {
15002
12816
  try {
15003
- const agentsContent = await readFile6(agentsPath, "utf-8");
12817
+ const agentsContent = await readFile5(agentsPath, "utf-8");
15004
12818
  if (agentsContent.includes(OLD_DOCS_PATH_PATTERN)) {
15005
12819
  failures.push({
15006
12820
  severity: "failure",
@@ -15021,7 +12835,7 @@ async function validateWorkflowPack(cwd) {
15021
12835
  }
15022
12836
  }
15023
12837
  const overridesDir = resolve4(cwd, ".pourkit/overrides");
15024
- if (existsSync20(overridesDir)) {
12838
+ if (existsSync17(overridesDir)) {
15025
12839
  const overrideFiles = await walkDir2(overridesDir);
15026
12840
  for (const file of overrideFiles) {
15027
12841
  const relPath = relative2(cwd, file);
@@ -15036,9 +12850,9 @@ async function validateWorkflowPack(cwd) {
15036
12850
  }
15037
12851
  }
15038
12852
  const configPath = resolve4(cwd, ".pourkit/config.json");
15039
- if (existsSync20(configPath)) {
12853
+ if (existsSync17(configPath)) {
15040
12854
  try {
15041
- const configContent = await readFile6(configPath, "utf-8");
12855
+ const configContent = await readFile5(configPath, "utf-8");
15042
12856
  const parsed = JSON.parse(configContent);
15043
12857
  const releaseEnabled = parsed.releaseWorkflow?.enabled === true;
15044
12858
  if (releaseEnabled) {
@@ -15047,7 +12861,7 @@ async function validateWorkflowPack(cwd) {
15047
12861
  cwd,
15048
12862
  `.pourkit/managed/addons/release/skills/${skillName}`
15049
12863
  );
15050
- if (!existsSync20(addonDir)) {
12864
+ if (!existsSync17(addonDir)) {
15051
12865
  failures.push({
15052
12866
  severity: "failure",
15053
12867
  kind: "release_config_conflict",
@@ -15061,7 +12875,7 @@ async function validateWorkflowPack(cwd) {
15061
12875
  cwd,
15062
12876
  `.pourkit/managed/addons/release/docs/agents/${docName}`
15063
12877
  );
15064
- if (!existsSync20(addonDocPath)) {
12878
+ if (!existsSync17(addonDocPath)) {
15065
12879
  failures.push({
15066
12880
  severity: "failure",
15067
12881
  kind: "release_config_conflict",
@@ -15073,7 +12887,7 @@ async function validateWorkflowPack(cwd) {
15073
12887
  resolvePackagedReleaseAddonDocPath(docName)
15074
12888
  );
15075
12889
  if (packagedContent !== null) {
15076
- const localContent = await readFile6(addonDocPath, "utf-8");
12890
+ const localContent = await readFile5(addonDocPath, "utf-8");
15077
12891
  if (localContent !== packagedContent) {
15078
12892
  failures.push({
15079
12893
  severity: "failure",
@@ -15106,7 +12920,7 @@ async function validateWorkflowPack(cwd) {
15106
12920
  cwd,
15107
12921
  `.pourkit/managed/addons/release/skills/${skillName}`
15108
12922
  );
15109
- if (existsSync20(addonDir)) {
12923
+ if (existsSync17(addonDir)) {
15110
12924
  failures.push({
15111
12925
  severity: "failure",
15112
12926
  kind: "release_config_conflict",
@@ -15120,7 +12934,7 @@ async function validateWorkflowPack(cwd) {
15120
12934
  cwd,
15121
12935
  `.pourkit/managed/addons/release/docs/agents/${docName}`
15122
12936
  );
15123
- if (existsSync20(addonDocPath)) {
12937
+ if (existsSync17(addonDocPath)) {
15124
12938
  failures.push({
15125
12939
  severity: "failure",
15126
12940
  kind: "release_config_conflict",
@@ -15134,9 +12948,9 @@ async function validateWorkflowPack(cwd) {
15134
12948
  }
15135
12949
  }
15136
12950
  const manifestPath = resolve4(cwd, ".pourkit/manifest.json");
15137
- if (existsSync20(manifestPath)) {
12951
+ if (existsSync17(manifestPath)) {
15138
12952
  try {
15139
- const manifestContent = await readFile6(manifestPath, "utf-8");
12953
+ const manifestContent = await readFile5(manifestPath, "utf-8");
15140
12954
  const manifest = JSON.parse(manifestContent);
15141
12955
  const wp = manifest.workflowPack;
15142
12956
  if (wp?.projections) {
@@ -15157,7 +12971,7 @@ async function validateWorkflowPack(cwd) {
15157
12971
  }
15158
12972
  }
15159
12973
  const pathEscapeOverrideDir = resolve4(cwd, ".pourkit/overrides");
15160
- if (existsSync20(pathEscapeOverrideDir)) {
12974
+ if (existsSync17(pathEscapeOverrideDir)) {
15161
12975
  const overrideFiles = await walkDir2(pathEscapeOverrideDir);
15162
12976
  for (const file of overrideFiles) {
15163
12977
  if (!isPathContained(cwd, file)) {
@@ -15171,12 +12985,12 @@ async function validateWorkflowPack(cwd) {
15171
12985
  }
15172
12986
  }
15173
12987
  const managedDocsDir = resolve4(cwd, ".pourkit/managed/docs/agents");
15174
- if (existsSync20(managedDocsDir)) {
12988
+ if (existsSync17(managedDocsDir)) {
15175
12989
  const docFiles = await walkDir2(managedDocsDir);
15176
12990
  for (const file of docFiles) {
15177
12991
  if (!file.endsWith(".md")) continue;
15178
12992
  try {
15179
- const content = await readFile6(file, "utf-8");
12993
+ const content = await readFile5(file, "utf-8");
15180
12994
  const relPath = relative2(cwd, file);
15181
12995
  const violations = scanManagedPolicyText(content, relPath);
15182
12996
  for (const v of violations) {
@@ -15192,14 +13006,14 @@ async function validateWorkflowPack(cwd) {
15192
13006
  }
15193
13007
  }
15194
13008
  const managedSkillsDir = resolve4(cwd, ".pourkit/managed/skills");
15195
- if (existsSync20(managedSkillsDir)) {
13009
+ if (existsSync17(managedSkillsDir)) {
15196
13010
  const skillDirs = await readdir2(managedSkillsDir, { withFileTypes: true });
15197
13011
  for (const entry of skillDirs) {
15198
13012
  if (!entry.isDirectory()) continue;
15199
13013
  const skillFile = resolve4(managedSkillsDir, entry.name, "SKILL.md");
15200
- if (!existsSync20(skillFile)) continue;
13014
+ if (!existsSync17(skillFile)) continue;
15201
13015
  try {
15202
- const content = await readFile6(skillFile, "utf-8");
13016
+ const content = await readFile5(skillFile, "utf-8");
15203
13017
  const relPath = relative2(cwd, skillFile);
15204
13018
  const violations = scanManagedPolicyText(content, relPath);
15205
13019
  for (const v of violations) {
@@ -15215,12 +13029,12 @@ async function validateWorkflowPack(cwd) {
15215
13029
  }
15216
13030
  }
15217
13031
  const managedPromptsDir = resolve4(cwd, ".pourkit/managed/prompts");
15218
- if (existsSync20(managedPromptsDir)) {
13032
+ if (existsSync17(managedPromptsDir)) {
15219
13033
  for (const promptName of catalog.prompts) {
15220
13034
  const promptFile = resolve4(managedPromptsDir, promptName);
15221
- if (!existsSync20(promptFile)) continue;
13035
+ if (!existsSync17(promptFile)) continue;
15222
13036
  try {
15223
- const content = await readFile6(promptFile, "utf-8");
13037
+ const content = await readFile5(promptFile, "utf-8");
15224
13038
  const relPath = relative2(cwd, promptFile);
15225
13039
  const violations = scanManagedPolicyText(content, relPath);
15226
13040
  for (const v of violations) {
@@ -15240,9 +13054,9 @@ async function validateWorkflowPack(cwd) {
15240
13054
  cwd,
15241
13055
  `.pourkit/managed/addons/release/skills/${skillName}/SKILL.md`
15242
13056
  );
15243
- if (!existsSync20(addonSkillFile)) continue;
13057
+ if (!existsSync17(addonSkillFile)) continue;
15244
13058
  try {
15245
- const content = await readFile6(addonSkillFile, "utf-8");
13059
+ const content = await readFile5(addonSkillFile, "utf-8");
15246
13060
  const relPath = relative2(cwd, addonSkillFile);
15247
13061
  const violations = scanManagedPolicyText(content, relPath);
15248
13062
  for (const v of violations) {
@@ -15261,9 +13075,9 @@ async function validateWorkflowPack(cwd) {
15261
13075
  cwd,
15262
13076
  `.pourkit/managed/addons/release/docs/agents/${docName}`
15263
13077
  );
15264
- if (!existsSync20(addonDocFile)) continue;
13078
+ if (!existsSync17(addonDocFile)) continue;
15265
13079
  try {
15266
- const content = await readFile6(addonDocFile, "utf-8");
13080
+ const content = await readFile5(addonDocFile, "utf-8");
15267
13081
  const relPath = relative2(cwd, addonDocFile);
15268
13082
  const violations = scanManagedPolicyText(content, relPath);
15269
13083
  for (const v of violations) {
@@ -15295,7 +13109,7 @@ async function validateMemoryHealth(cwd, memoryConfig) {
15295
13109
  detail: icmPath !== null ? icmPath : "icm not found on PATH"
15296
13110
  });
15297
13111
  const gitignorePath = resolve4(cwd, ".gitignore");
15298
- const gitignoreContent = existsSync20(gitignorePath) ? readFileSync21(gitignorePath, "utf-8") : "";
13112
+ const gitignoreContent = existsSync17(gitignorePath) ? readFileSync18(gitignorePath, "utf-8") : "";
15299
13113
  const hasGitignoreEntry = gitignoreContent.includes(".pourkit/icm/");
15300
13114
  checks.push({
15301
13115
  name: "icm-gitignore",
@@ -15322,8 +13136,8 @@ async function runDoctorCommand(options) {
15322
13136
  const schemaDir = localSchemaDir(repoRootPath);
15323
13137
  const localSchemaPath = resolve4(schemaDir, "pourkit.schema.json");
15324
13138
  const localHashPath = resolve4(schemaDir, "pourkit.schema.hash");
15325
- const localSchemaExists = existsSync20(localSchemaPath);
15326
- const localHashExists = existsSync20(localHashPath);
13139
+ const localSchemaExists = existsSync17(localSchemaPath);
13140
+ const localHashExists = existsSync17(localHashPath);
15327
13141
  let packagedHash = null;
15328
13142
  try {
15329
13143
  packagedHash = readPackagedHash();
@@ -15332,7 +13146,7 @@ async function runDoctorCommand(options) {
15332
13146
  let localHashContent = null;
15333
13147
  if (localHashExists) {
15334
13148
  try {
15335
- localHashContent = await readFile6(localHashPath, "utf-8");
13149
+ localHashContent = await readFile5(localHashPath, "utf-8");
15336
13150
  } catch {
15337
13151
  }
15338
13152
  }
@@ -15342,9 +13156,9 @@ async function runDoctorCommand(options) {
15342
13156
  const configPath = resolve4(repoRootPath, ".pourkit/config.json");
15343
13157
  let configValidation;
15344
13158
  let rawMemoryConfig;
15345
- if (existsSync20(configPath)) {
13159
+ if (existsSync17(configPath)) {
15346
13160
  try {
15347
- const raw = JSON.parse(readFileSync21(configPath, "utf-8"));
13161
+ const raw = JSON.parse(readFileSync18(configPath, "utf-8"));
15348
13162
  rawMemoryConfig = raw.memory;
15349
13163
  const validate = getSchemaValidator();
15350
13164
  const valid2 = validate(raw);
@@ -15377,7 +13191,7 @@ async function runDoctorCommand(options) {
15377
13191
  "pourkit.config.mjs",
15378
13192
  "pourkit.config.js",
15379
13193
  "pourkit.json"
15380
- ].filter((p) => existsSync20(resolve4(repoRootPath, p)));
13194
+ ].filter((p) => existsSync17(resolve4(repoRootPath, p)));
15381
13195
  const workflowPack = await validateWorkflowPack(repoRootPath);
15382
13196
  const memory = await validateMemoryHealth(repoRootPath, rawMemoryConfig);
15383
13197
  let recommendation = null;
@@ -15420,31 +13234,31 @@ async function runDoctorCommand(options) {
15420
13234
  async function runConfigSyncSchemaCommand(options) {
15421
13235
  const repoRootPath = options.cwd ?? process.cwd();
15422
13236
  const schemaDir = localSchemaDir(repoRootPath);
15423
- await mkdir6(schemaDir, { recursive: true });
15424
- const packagedSchema = await readFile6(PACKAGED_SCHEMA_PATH, "utf-8");
15425
- const packagedHash = await readFile6(PACKAGED_HASH_PATH, "utf-8");
13237
+ await mkdir5(schemaDir, { recursive: true });
13238
+ const packagedSchema = await readFile5(PACKAGED_SCHEMA_PATH, "utf-8");
13239
+ const packagedHash = await readFile5(PACKAGED_HASH_PATH, "utf-8");
15426
13240
  const localSchemaPath = resolve4(schemaDir, "pourkit.schema.json");
15427
13241
  const localHashPath = resolve4(schemaDir, "pourkit.schema.hash");
15428
13242
  let schemaWritten = false;
15429
13243
  let hashWritten = false;
15430
- if (existsSync20(localSchemaPath)) {
15431
- const existing = await readFile6(localSchemaPath, "utf-8");
13244
+ if (existsSync17(localSchemaPath)) {
13245
+ const existing = await readFile5(localSchemaPath, "utf-8");
15432
13246
  if (existing !== packagedSchema) {
15433
- await writeFile3(localSchemaPath, packagedSchema, "utf-8");
13247
+ await writeFile2(localSchemaPath, packagedSchema, "utf-8");
15434
13248
  schemaWritten = true;
15435
13249
  }
15436
13250
  } else {
15437
- await writeFile3(localSchemaPath, packagedSchema, "utf-8");
13251
+ await writeFile2(localSchemaPath, packagedSchema, "utf-8");
15438
13252
  schemaWritten = true;
15439
13253
  }
15440
- if (existsSync20(localHashPath)) {
15441
- const existing = await readFile6(localHashPath, "utf-8");
13254
+ if (existsSync17(localHashPath)) {
13255
+ const existing = await readFile5(localHashPath, "utf-8");
15442
13256
  if (existing !== packagedHash) {
15443
- await writeFile3(localHashPath, packagedHash, "utf-8");
13257
+ await writeFile2(localHashPath, packagedHash, "utf-8");
15444
13258
  hashWritten = true;
15445
13259
  }
15446
13260
  } else {
15447
- await writeFile3(localHashPath, packagedHash, "utf-8");
13261
+ await writeFile2(localHashPath, packagedHash, "utf-8");
15448
13262
  hashWritten = true;
15449
13263
  }
15450
13264
  return {
@@ -15455,8 +13269,8 @@ async function runConfigSyncSchemaCommand(options) {
15455
13269
  }
15456
13270
 
15457
13271
  // commands/workflow-pack-sync.ts
15458
- import { existsSync as existsSync21, readdirSync as readdirSync5 } from "fs";
15459
- import { mkdir as mkdir7, readFile as readFile7, writeFile as writeFile4, readdir as readdir3 } from "fs/promises";
13272
+ import { existsSync as existsSync18, readdirSync as readdirSync4 } from "fs";
13273
+ import { mkdir as mkdir6, readFile as readFile6, writeFile as writeFile3, readdir as readdir3 } from "fs/promises";
15460
13274
  import { resolve as resolve5, dirname as dirname6, relative as relative3, normalize as normalize2 } from "path";
15461
13275
  import { fileURLToPath as fileURLToPath4 } from "url";
15462
13276
  var __filename4 = fileURLToPath4(import.meta.url);
@@ -15494,7 +13308,7 @@ function resolvePackagedManagedPromptPath(promptName) {
15494
13308
  }
15495
13309
  async function readPackagedTextFile2(filePath) {
15496
13310
  try {
15497
- return await readFile7(filePath, "utf-8");
13311
+ return await readFile6(filePath, "utf-8");
15498
13312
  } catch {
15499
13313
  return null;
15500
13314
  }
@@ -15577,20 +13391,20 @@ async function syncFile(cwd, targetRelativePath, sourceContent, errors) {
15577
13391
  errors.push(escapeError);
15578
13392
  return false;
15579
13393
  }
15580
- await mkdir7(resolve5(targetPath, ".."), { recursive: true });
15581
- if (existsSync21(targetPath)) {
15582
- const existing = await readFile7(targetPath, "utf-8");
13394
+ await mkdir6(resolve5(targetPath, ".."), { recursive: true });
13395
+ if (existsSync18(targetPath)) {
13396
+ const existing = await readFile6(targetPath, "utf-8");
15583
13397
  if (existing === sourceContent) {
15584
13398
  return false;
15585
13399
  }
15586
13400
  }
15587
- await writeFile4(targetPath, sourceContent, "utf-8");
13401
+ await writeFile3(targetPath, sourceContent, "utf-8");
15588
13402
  return true;
15589
13403
  }
15590
13404
  function walkDirSync(dir) {
15591
13405
  const result = [];
15592
13406
  try {
15593
- const entries = readdirSync5(dir, { withFileTypes: true });
13407
+ const entries = readdirSync4(dir, { withFileTypes: true });
15594
13408
  for (const entry of entries) {
15595
13409
  const full = resolve5(dir, entry.name);
15596
13410
  if (entry.isDirectory()) {
@@ -15605,7 +13419,7 @@ function walkDirSync(dir) {
15605
13419
  }
15606
13420
  async function detectOverrides(cwd) {
15607
13421
  const overridesDir = resolve5(cwd, OVERRIDES_DIR);
15608
- if (!existsSync21(overridesDir)) {
13422
+ if (!existsSync18(overridesDir)) {
15609
13423
  return [];
15610
13424
  }
15611
13425
  const files = await walkDir3(overridesDir);
@@ -15615,13 +13429,13 @@ async function detectProjectOwnedFiles(cwd) {
15615
13429
  const found = [];
15616
13430
  for (const ownedPath of PROJECT_OWNED_PATHS) {
15617
13431
  const fullPath = resolve5(cwd, ownedPath);
15618
- if (existsSync21(fullPath)) {
13432
+ if (existsSync18(fullPath)) {
15619
13433
  found.push(ownedPath);
15620
13434
  }
15621
13435
  }
15622
13436
  for (const ownedDir of PROJECT_OWNED_DIRECTORIES) {
15623
13437
  const fullDir = resolve5(cwd, ownedDir);
15624
- if (existsSync21(fullDir)) {
13438
+ if (existsSync18(fullDir)) {
15625
13439
  const files = await walkDir3(fullDir);
15626
13440
  for (const file of files) {
15627
13441
  found.push(relative3(cwd, file));
@@ -15633,7 +13447,7 @@ async function detectProjectOwnedFiles(cwd) {
15633
13447
  async function isReleaseWorkflowEnabled(cwd) {
15634
13448
  try {
15635
13449
  const configPath = resolve5(cwd, ".pourkit", "config.json");
15636
- const content = await readFile7(configPath, "utf-8");
13450
+ const content = await readFile6(configPath, "utf-8");
15637
13451
  const parsed = JSON.parse(content);
15638
13452
  return parsed.releaseWorkflow?.enabled === true;
15639
13453
  } catch {
@@ -15773,12 +13587,12 @@ async function runWorkflowPackSyncCommand(options) {
15773
13587
  const fullManagedBlock = `${MANAGED_BLOCK_BEGIN3}${managedBlockContent}${MANAGED_BLOCK_END2}`;
15774
13588
  async function syncManagedAgentFile(fileName, options2) {
15775
13589
  const filePath = resolve5(cwd, fileName);
15776
- if (!existsSync21(filePath)) {
13590
+ if (!existsSync18(filePath)) {
15777
13591
  if (!options2.createIfMissing) return false;
15778
- await writeFile4(filePath, fullManagedBlock + "\n", "utf-8");
13592
+ await writeFile3(filePath, fullManagedBlock + "\n", "utf-8");
15779
13593
  return true;
15780
13594
  }
15781
- const existing = await readFile7(filePath, "utf-8");
13595
+ const existing = await readFile6(filePath, "utf-8");
15782
13596
  const beginIdx = existing.indexOf(MANAGED_BLOCK_BEGIN3);
15783
13597
  const endIdx = existing.indexOf(MANAGED_BLOCK_END2);
15784
13598
  if (beginIdx !== -1 && endIdx !== -1) {
@@ -15786,7 +13600,7 @@ async function runWorkflowPackSyncCommand(options) {
15786
13600
  const afterBlock = existing.slice(endIdx + MANAGED_BLOCK_END2.length);
15787
13601
  const newContent = `${beforeBlock}${fullManagedBlock}${afterBlock}`;
15788
13602
  if (newContent !== existing) {
15789
- await writeFile4(filePath, newContent, "utf-8");
13603
+ await writeFile3(filePath, newContent, "utf-8");
15790
13604
  return true;
15791
13605
  }
15792
13606
  } else {
@@ -15795,7 +13609,7 @@ async function runWorkflowPackSyncCommand(options) {
15795
13609
  ${fullManagedBlock}
15796
13610
  `;
15797
13611
  if (newContent !== existing) {
15798
- await writeFile4(filePath, newContent, "utf-8");
13612
+ await writeFile3(filePath, newContent, "utf-8");
15799
13613
  return true;
15800
13614
  }
15801
13615
  }
@@ -15813,7 +13627,7 @@ ${fullManagedBlock}
15813
13627
  let manifestWritten = false;
15814
13628
  let previousManifestWorkflowPack = void 0;
15815
13629
  try {
15816
- const existingRaw = await readFile7(manifestPath, "utf-8").catch(() => null);
13630
+ const existingRaw = await readFile6(manifestPath, "utf-8").catch(() => null);
15817
13631
  if (existingRaw) {
15818
13632
  const existing = JSON.parse(existingRaw);
15819
13633
  previousManifestWorkflowPack = existing.workflowPack;
@@ -15822,13 +13636,13 @@ ${fullManagedBlock}
15822
13636
  }
15823
13637
  if (previousManifestWorkflowPack === void 0 || JSON.stringify(previousManifestWorkflowPack) !== JSON.stringify(manifestMeta)) {
15824
13638
  try {
15825
- const existingRaw = await readFile7(manifestPath, "utf-8").catch(
13639
+ const existingRaw = await readFile6(manifestPath, "utf-8").catch(
15826
13640
  () => null
15827
13641
  );
15828
13642
  let manifest = existingRaw ? JSON.parse(existingRaw) : {};
15829
13643
  manifest.workflowPack = manifestMeta;
15830
- await mkdir7(resolve5(manifestPath, ".."), { recursive: true });
15831
- await writeFile4(
13644
+ await mkdir6(resolve5(manifestPath, ".."), { recursive: true });
13645
+ await writeFile3(
15832
13646
  manifestPath,
15833
13647
  JSON.stringify(manifest, null, 2) + "\n",
15834
13648
  "utf-8"
@@ -16548,22 +14362,22 @@ function formatChecks2(checks) {
16548
14362
  init_common();
16549
14363
 
16550
14364
  // execution/sandcastle-execution.ts
16551
- import { existsSync as existsSync23, mkdirSync as mkdirSync10, statSync as statSync2, writeFileSync as writeFileSync8 } from "fs";
16552
- import { join as join25 } from "path";
14365
+ import { existsSync as existsSync20, mkdirSync as mkdirSync9, statSync as statSync2, writeFileSync as writeFileSync6 } from "fs";
14366
+ import { join as join20 } from "path";
16553
14367
  import { createWorktree, opencode } from "@ai-hero/sandcastle";
16554
14368
  import { docker } from "@ai-hero/sandcastle/sandboxes/docker";
16555
14369
 
16556
14370
  // execution/execution-provider.ts
16557
14371
  init_common();
16558
14372
  import { mkdtempSync } from "fs";
16559
- import { writeFile as writeFile5 } from "fs/promises";
14373
+ import { writeFile as writeFile4 } from "fs/promises";
16560
14374
  import { tmpdir } from "os";
16561
- import { dirname as dirname7, join as join23 } from "path";
14375
+ import { dirname as dirname7, join as join18 } from "path";
16562
14376
  async function writeExecutionArtifacts(worktreePath, artifacts) {
16563
14377
  for (const artifact of artifacts) {
16564
- const filePath = join23(worktreePath, artifact.path);
14378
+ const filePath = join18(worktreePath, artifact.path);
16565
14379
  await ensureDir(dirname7(filePath));
16566
- await writeFile5(filePath, artifact.content, "utf-8");
14380
+ await writeFile4(filePath, artifact.content, "utf-8");
16567
14381
  }
16568
14382
  }
16569
14383
 
@@ -16575,19 +14389,19 @@ init_common();
16575
14389
  import path7 from "path";
16576
14390
 
16577
14391
  // execution/sandbox-image.ts
16578
- import { createHash as createHash3 } from "crypto";
16579
- import { existsSync as existsSync22, readFileSync as readFileSync22 } from "fs";
14392
+ import { createHash as createHash2 } from "crypto";
14393
+ import { existsSync as existsSync19, readFileSync as readFileSync19 } from "fs";
16580
14394
  import path6 from "path";
16581
14395
  function sandboxImageName(repoRoot2, installIcm) {
16582
14396
  const dirName = path6.basename(repoRoot2.replace(/[\\/]+$/, "")) || "local";
16583
14397
  const sanitized = dirName.toLowerCase().replace(/[^a-z0-9_.-]/g, "-");
16584
14398
  const baseName = sanitized || "local";
16585
14399
  const dockerfilePath = path6.join(repoRoot2, ".sandcastle", "Dockerfile");
16586
- if (!existsSync22(dockerfilePath)) {
14400
+ if (!existsSync19(dockerfilePath)) {
16587
14401
  const base2 = `sandcastle:${baseName}`;
16588
14402
  return installIcm ? `${base2}-icm` : base2;
16589
14403
  }
16590
- const fingerprint = createHash3("sha256").update(readFileSync22(dockerfilePath)).digest("hex").slice(0, 8);
14404
+ const fingerprint = createHash2("sha256").update(readFileSync19(dockerfilePath)).digest("hex").slice(0, 8);
16591
14405
  const base = `sandcastle:${baseName}-${fingerprint}`;
16592
14406
  return installIcm ? `${base}-icm` : base;
16593
14407
  }
@@ -16623,7 +14437,7 @@ async function createSandboxFromExistingWorktree(options) {
16623
14437
  }
16624
14438
 
16625
14439
  // execution/sandbox-options.ts
16626
- import { join as join24 } from "path";
14440
+ import { join as join19 } from "path";
16627
14441
  var POURKIT_ICM_CONTAINER_DIR = "/home/agent/.pourkit/icm";
16628
14442
  function buildSandboxOptions(repoRoot2, sandbox, memory) {
16629
14443
  const mounts = [];
@@ -16632,12 +14446,12 @@ function buildSandboxOptions(repoRoot2, sandbox, memory) {
16632
14446
  }
16633
14447
  if (memory?.available) {
16634
14448
  mounts.push({
16635
- hostPath: join24(repoRoot2, ".pourkit", "icm"),
14449
+ hostPath: join19(repoRoot2, ".pourkit", "icm"),
16636
14450
  sandboxPath: POURKIT_ICM_CONTAINER_DIR,
16637
14451
  readonly: false
16638
14452
  });
16639
14453
  mounts.push({
16640
- hostPath: join24(repoRoot2, ".pourkit", "icm", "cache"),
14454
+ hostPath: join19(repoRoot2, ".pourkit", "icm", "cache"),
16641
14455
  sandboxPath: "/home/agent/.cache/icm",
16642
14456
  readonly: false
16643
14457
  });
@@ -16771,13 +14585,13 @@ var SandcastleExecutionSession = class {
16771
14585
  "Memory enabled but memory context is invalid. Run `pourkit memory init` or install ICM for host planning use."
16772
14586
  );
16773
14587
  }
16774
- const hostMemoryDir = join25(repoRoot2, ".pourkit", "icm");
16775
- if (!existsSync23(hostMemoryDir) || !statSync2(hostMemoryDir).isDirectory()) {
14588
+ const hostMemoryDir = join20(repoRoot2, ".pourkit", "icm");
14589
+ if (!existsSync20(hostMemoryDir) || !statSync2(hostMemoryDir).isDirectory()) {
16776
14590
  throw new MissingHostMemoryDirError(
16777
14591
  "Memory enabled but host .pourkit/icm/ directory is missing. Run `pourkit memory init` to create the repo-scoped memory store."
16778
14592
  );
16779
14593
  }
16780
- mkdirSync10(join25(hostMemoryDir, "cache"), { recursive: true });
14594
+ mkdirSync9(join20(hostMemoryDir, "cache"), { recursive: true });
16781
14595
  }
16782
14596
  const sandboxOptions = buildSandboxOptions(
16783
14597
  repoRoot2,
@@ -16936,8 +14750,8 @@ function sanitizeBranch(branchName) {
16936
14750
  }
16937
14751
  function safeCopyToWorktreePaths(paths, repoRoot2, worktreePath) {
16938
14752
  return paths.filter((relativePath) => {
16939
- const source = join25(repoRoot2, relativePath);
16940
- if (!existsSync23(source)) {
14753
+ const source = join20(repoRoot2, relativePath);
14754
+ if (!existsSync20(source)) {
16941
14755
  return true;
16942
14756
  }
16943
14757
  try {
@@ -16947,8 +14761,8 @@ function safeCopyToWorktreePaths(paths, repoRoot2, worktreePath) {
16947
14761
  } catch {
16948
14762
  return true;
16949
14763
  }
16950
- const destination = join25(worktreePath, relativePath);
16951
- return !existsSync23(destination);
14764
+ const destination = join20(worktreePath, relativePath);
14765
+ return !existsSync20(destination);
16952
14766
  });
16953
14767
  }
16954
14768
  function formatAgentStreamEvent(event) {
@@ -17012,13 +14826,13 @@ function isPlainObject(value) {
17012
14826
  return typeof value === "object" && value !== null && !Array.isArray(value);
17013
14827
  }
17014
14828
  function savePromptToFile(repoRoot2, stage, iteration, prompt) {
17015
- const promptsDir = join25(repoRoot2, ".pourkit", ".tmp", "prompts");
17016
- mkdirSync10(promptsDir, { recursive: true });
14829
+ const promptsDir = join20(repoRoot2, ".pourkit", ".tmp", "prompts");
14830
+ mkdirSync9(promptsDir, { recursive: true });
17017
14831
  const timestamp2 = Date.now();
17018
14832
  const iterationSuffix = iteration !== void 0 ? `-iteration-${iteration}` : "";
17019
14833
  const filename = `${stage}${iterationSuffix}-${timestamp2}.md`;
17020
- const filePath = join25(promptsDir, filename);
17021
- writeFileSync8(filePath, prompt, "utf-8");
14834
+ const filePath = join20(promptsDir, filename);
14835
+ writeFileSync6(filePath, prompt, "utf-8");
17022
14836
  }
17023
14837
 
17024
14838
  // cli.ts
@@ -17118,8 +14932,8 @@ function createCliProgram(version) {
17118
14932
  });
17119
14933
  program.command("validate-artifact").description("Validate an agent handoff artifact").argument(
17120
14934
  "<kind>",
17121
- "artifact kind: reviewer, refactor, finalizer, conflict-resolution, failure-resolution, local-prd, local-issue, local-triage, or issue-final-review"
17122
- ).argument("<artifactPath>", "artifact path to validate").argument("[extraPaths...]", "additional artifact paths (for local-triage)").option("--iteration <number>", "review/refactor iteration", (value) => {
14935
+ "artifact kind: reviewer, refactor, finalizer, conflict-resolution, failure-resolution, or issue-final-review"
14936
+ ).argument("<artifactPath>", "artifact path to validate").argument("[extraPaths...]", "unused compatibility argument").option("--iteration <number>", "review/refactor iteration", (value) => {
17123
14937
  const parsed = Number.parseInt(value, 10);
17124
14938
  if (!Number.isInteger(parsed) || parsed < 1) {
17125
14939
  throw new CommanderError(
@@ -17172,16 +14986,13 @@ function createCliProgram(version) {
17172
14986
  "--base-ref <ref>",
17173
14987
  "canonical base ref for issue-final-review changedFiles coverage validation"
17174
14988
  ).option("--no-check-conflict-markers", "skip conflict marker scan").option("--cwd <path>", "target repository directory").action(
17175
- (kind, artifactPath, extraPaths, options) => {
14989
+ (kind, artifactPath, _extraPaths, options) => {
17176
14990
  const allowedKinds = /* @__PURE__ */ new Set([
17177
14991
  "reviewer",
17178
14992
  "refactor",
17179
14993
  "finalizer",
17180
14994
  "conflict-resolution",
17181
14995
  "failure-resolution",
17182
- "local-prd",
17183
- "local-issue",
17184
- "local-triage",
17185
14996
  "issue-final-review"
17186
14997
  ]);
17187
14998
  if (!allowedKinds.has(kind)) {
@@ -17191,18 +15002,8 @@ function createCliProgram(version) {
17191
15002
  `Unsupported artifact kind "${kind}"`
17192
15003
  );
17193
15004
  }
17194
- const LOCAL_KINDS = /* @__PURE__ */ new Set([
17195
- "local-prd",
17196
- "local-issue",
17197
- "local-triage"
17198
- ]);
17199
15005
  const targetRepoRoot = options.cwd ? repoRoot(options.cwd) : repoRoot();
17200
- const result = LOCAL_KINDS.has(kind) ? runLocalValidateArtifactCommand({
17201
- repoRoot: targetRepoRoot,
17202
- kind,
17203
- artifactPath,
17204
- extraArgs: extraPaths
17205
- }) : runValidateArtifactCommand({
15006
+ const result = runValidateArtifactCommand({
17206
15007
  repoRoot: targetRepoRoot,
17207
15008
  kind,
17208
15009
  artifactPath,
@@ -17485,15 +15286,14 @@ function createCliProgram(version) {
17485
15286
  const logger = createLogger("pourkit", logPath);
17486
15287
  try {
17487
15288
  const config = await loadRepoConfig(targetRepoRoot);
17488
- const target = resolveTarget(config, options.target);
17489
- const mode = resolvePrdRunMode(target).mode;
17490
- const client = mode === "local" ? void 0 : await requireGitHubClient({ cwd: targetRepoRoot });
17491
- const issueProvider = client ? new GitHubIssueProvider(client, {
15289
+ resolveTarget(config, options.target);
15290
+ const client = await requireGitHubClient({ cwd: targetRepoRoot });
15291
+ const issueProvider = new GitHubIssueProvider(client, {
17492
15292
  readyForAgentLabel: config.labels.readyForAgent,
17493
15293
  blockedLabel: config.labels.blocked,
17494
15294
  issueListLimit: config.checks.issueListLimit
17495
- }) : void 0;
17496
- const prProvider = client ? new GitHubPRProvider(client, logger) : void 0;
15295
+ });
15296
+ const prProvider = new GitHubPRProvider(client, logger);
17497
15297
  const executionProvider = new SandcastleExecutionProvider();
17498
15298
  const result = await runPrdRunLaunchCommand({
17499
15299
  repoRoot: targetRepoRoot,
@@ -17752,11 +15552,11 @@ function createCliProgram(version) {
17752
15552
  return program;
17753
15553
  }
17754
15554
  async function resolveCliVersion() {
17755
- if (isPackageVersion("0.0.0-next-20260619045442")) {
17756
- return "0.0.0-next-20260619045442";
15555
+ if (isPackageVersion("0.0.0-next-20260619094345")) {
15556
+ return "0.0.0-next-20260619094345";
17757
15557
  }
17758
- if (isReleaseVersion("0.0.0-next-20260619045442")) {
17759
- return "0.0.0-next-20260619045442";
15558
+ if (isReleaseVersion("0.0.0-next-20260619094345")) {
15559
+ return "0.0.0-next-20260619094345";
17760
15560
  }
17761
15561
  try {
17762
15562
  const root = repoRoot();