@neriros/ralphy 3.10.10 → 3.10.11
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/mcp/index.js +10 -0
- package/dist/shell/index.js +287 -87
- package/package.json +1 -1
package/dist/mcp/index.js
CHANGED
|
@@ -24093,6 +24093,12 @@ var HistoryEntrySchema = exports_external.object({
|
|
|
24093
24093
|
appVersion: exports_external.string().optional(),
|
|
24094
24094
|
usage: IterationUsageSchema.partial().optional()
|
|
24095
24095
|
});
|
|
24096
|
+
var RevisionSchema = exports_external.object({
|
|
24097
|
+
version: exports_external.number(),
|
|
24098
|
+
attachmentId: exports_external.string(),
|
|
24099
|
+
sha256: exports_external.string(),
|
|
24100
|
+
trigger: exports_external.string()
|
|
24101
|
+
});
|
|
24096
24102
|
var StateSchema = exports_external.object({
|
|
24097
24103
|
version: exports_external.literal("2"),
|
|
24098
24104
|
name: exports_external.string(),
|
|
@@ -24141,12 +24147,16 @@ var StateSchema = exports_external.object({
|
|
|
24141
24147
|
attachmentId: exports_external.string().nullable().default(null),
|
|
24142
24148
|
sha256: exports_external.string().nullable().default(null)
|
|
24143
24149
|
}).default({ attachmentId: null, sha256: null }),
|
|
24150
|
+
designRevisions: exports_external.array(RevisionSchema).default([]),
|
|
24151
|
+
designPdfRevisions: exports_external.array(RevisionSchema).default([]),
|
|
24144
24152
|
legacyProposalPurged: exports_external.boolean().default(false)
|
|
24145
24153
|
}).default({
|
|
24146
24154
|
proposal: { attachmentId: null, sha256: null },
|
|
24147
24155
|
design: { attachmentId: null, sha256: null },
|
|
24148
24156
|
proposalPdf: { attachmentId: null, sha256: null },
|
|
24149
24157
|
designPdf: { attachmentId: null, sha256: null },
|
|
24158
|
+
designRevisions: [],
|
|
24159
|
+
designPdfRevisions: [],
|
|
24150
24160
|
legacyProposalPurged: false
|
|
24151
24161
|
}),
|
|
24152
24162
|
confirmation: exports_external.object({
|
package/dist/shell/index.js
CHANGED
|
@@ -18928,8 +18928,8 @@ import { readFileSync } from "fs";
|
|
|
18928
18928
|
import { resolve } from "path";
|
|
18929
18929
|
function getVersion() {
|
|
18930
18930
|
try {
|
|
18931
|
-
if ("3.10.
|
|
18932
|
-
return "3.10.
|
|
18931
|
+
if ("3.10.11")
|
|
18932
|
+
return "3.10.11";
|
|
18933
18933
|
} catch {}
|
|
18934
18934
|
const dirsToTry = [];
|
|
18935
18935
|
try {
|
|
@@ -89590,7 +89590,7 @@ var init_zod2 = __esm(() => {
|
|
|
89590
89590
|
function markersOf(set3) {
|
|
89591
89591
|
return Array.isArray(set3) ? set3 : [set3];
|
|
89592
89592
|
}
|
|
89593
|
-
var IterationUsageSchema, UsageSchema, HistoryEntrySchema, StateSchema, PhaseFrontmatterSchema;
|
|
89593
|
+
var IterationUsageSchema, UsageSchema, HistoryEntrySchema, RevisionSchema, StateSchema, PhaseFrontmatterSchema;
|
|
89594
89594
|
var init_types2 = __esm(() => {
|
|
89595
89595
|
init_zod2();
|
|
89596
89596
|
IterationUsageSchema = exports_external2.object({
|
|
@@ -89623,6 +89623,12 @@ var init_types2 = __esm(() => {
|
|
|
89623
89623
|
appVersion: exports_external2.string().optional(),
|
|
89624
89624
|
usage: IterationUsageSchema.partial().optional()
|
|
89625
89625
|
});
|
|
89626
|
+
RevisionSchema = exports_external2.object({
|
|
89627
|
+
version: exports_external2.number(),
|
|
89628
|
+
attachmentId: exports_external2.string(),
|
|
89629
|
+
sha256: exports_external2.string(),
|
|
89630
|
+
trigger: exports_external2.string()
|
|
89631
|
+
});
|
|
89626
89632
|
StateSchema = exports_external2.object({
|
|
89627
89633
|
version: exports_external2.literal("2"),
|
|
89628
89634
|
name: exports_external2.string(),
|
|
@@ -89671,12 +89677,16 @@ var init_types2 = __esm(() => {
|
|
|
89671
89677
|
attachmentId: exports_external2.string().nullable().default(null),
|
|
89672
89678
|
sha256: exports_external2.string().nullable().default(null)
|
|
89673
89679
|
}).default({ attachmentId: null, sha256: null }),
|
|
89680
|
+
designRevisions: exports_external2.array(RevisionSchema).default([]),
|
|
89681
|
+
designPdfRevisions: exports_external2.array(RevisionSchema).default([]),
|
|
89674
89682
|
legacyProposalPurged: exports_external2.boolean().default(false)
|
|
89675
89683
|
}).default({
|
|
89676
89684
|
proposal: { attachmentId: null, sha256: null },
|
|
89677
89685
|
design: { attachmentId: null, sha256: null },
|
|
89678
89686
|
proposalPdf: { attachmentId: null, sha256: null },
|
|
89679
89687
|
designPdf: { attachmentId: null, sha256: null },
|
|
89688
|
+
designRevisions: [],
|
|
89689
|
+
designPdfRevisions: [],
|
|
89680
89690
|
legacyProposalPurged: false
|
|
89681
89691
|
}),
|
|
89682
89692
|
confirmation: exports_external2.object({
|
|
@@ -105470,6 +105480,7 @@ class AgentCoordinator {
|
|
|
105470
105480
|
opts;
|
|
105471
105481
|
workers = [];
|
|
105472
105482
|
pendingIds = new Set;
|
|
105483
|
+
inFlight = new Set;
|
|
105473
105484
|
queue = [];
|
|
105474
105485
|
stopped = false;
|
|
105475
105486
|
paused = null;
|
|
@@ -106036,7 +106047,31 @@ class AgentCoordinator {
|
|
|
106036
106047
|
while (this.workers.length + this.pendingIds.size < this.opts.concurrency && this.queue.length > 0) {
|
|
106037
106048
|
const next = this.queue.shift();
|
|
106038
106049
|
this.pendingIds.add(next.issue.id);
|
|
106039
|
-
this.launchWorker(next.issue, next.trigger, next.mention);
|
|
106050
|
+
this.track(this.launchWorker(next.issue, next.trigger, next.mention));
|
|
106051
|
+
}
|
|
106052
|
+
}
|
|
106053
|
+
track(p) {
|
|
106054
|
+
this.inFlight.add(p);
|
|
106055
|
+
p.finally(() => {
|
|
106056
|
+
this.inFlight.delete(p);
|
|
106057
|
+
});
|
|
106058
|
+
return p;
|
|
106059
|
+
}
|
|
106060
|
+
async whenSettled() {
|
|
106061
|
+
let consecutiveEmpty = 0;
|
|
106062
|
+
for (let guard = 0;guard < 1000; guard++) {
|
|
106063
|
+
if (this.inFlight.size > 0) {
|
|
106064
|
+
await Promise.allSettled(this.inFlight);
|
|
106065
|
+
consecutiveEmpty = 0;
|
|
106066
|
+
}
|
|
106067
|
+
await new Promise((r) => setTimeout(r, 0));
|
|
106068
|
+
if (this.inFlight.size === 0) {
|
|
106069
|
+
consecutiveEmpty += 1;
|
|
106070
|
+
if (consecutiveEmpty >= WHEN_SETTLED_STABLE_HOPS)
|
|
106071
|
+
return;
|
|
106072
|
+
} else {
|
|
106073
|
+
consecutiveEmpty = 0;
|
|
106074
|
+
}
|
|
106040
106075
|
}
|
|
106041
106076
|
}
|
|
106042
106077
|
async launchWorker(issue2, trigger, mention) {
|
|
@@ -106154,7 +106189,10 @@ class AgentCoordinator {
|
|
|
106154
106189
|
this.deps.onLog(`! sync-tasks (launch) failed for ${issue2.identifier}: ${err.message}`, "yellow");
|
|
106155
106190
|
}
|
|
106156
106191
|
}
|
|
106157
|
-
handle.exited.then(
|
|
106192
|
+
handle.exited.then((code) => this.track(this.finalizeWorkerExit(worker, issue2, prep, trigger, code)));
|
|
106193
|
+
}
|
|
106194
|
+
async finalizeWorkerExit(worker, issue2, prep, trigger, code) {
|
|
106195
|
+
{
|
|
106158
106196
|
const idx = this.workers.indexOf(worker);
|
|
106159
106197
|
if (idx >= 0)
|
|
106160
106198
|
this.workers.splice(idx, 1);
|
|
@@ -106202,7 +106240,7 @@ class AgentCoordinator {
|
|
|
106202
106240
|
await this.notifyExited(issue2, prep.changeName, code, trigger);
|
|
106203
106241
|
this.deps.onWorkersChanged();
|
|
106204
106242
|
this.spawnNext();
|
|
106205
|
-
}
|
|
106243
|
+
}
|
|
106206
106244
|
}
|
|
106207
106245
|
async restartWorker(changeName) {
|
|
106208
106246
|
if (this.stopped)
|
|
@@ -106378,7 +106416,7 @@ var emptyPrStatus = () => ({
|
|
|
106378
106416
|
conflicted: 0,
|
|
106379
106417
|
ciFailed: 0,
|
|
106380
106418
|
quarantined: 0
|
|
106381
|
-
}), emptyPollResult = () => ({
|
|
106419
|
+
}), WHEN_SETTLED_STABLE_HOPS = 3, emptyPollResult = () => ({
|
|
106382
106420
|
found: 0,
|
|
106383
106421
|
added: 0,
|
|
106384
106422
|
buckets: {
|
|
@@ -107521,6 +107559,11 @@ var init_linear_resolvers = __esm(() => {
|
|
|
107521
107559
|
// apps/agent/src/agent/wire/prepare.ts
|
|
107522
107560
|
import { mkdir as mkdir8 } from "fs/promises";
|
|
107523
107561
|
import { join as join27 } from "path";
|
|
107562
|
+
function composeAppendPrompt(promptArg, cfgAppendPrompt, workflowPrompt) {
|
|
107563
|
+
return [promptArg || cfgAppendPrompt || "", workflowPrompt].filter(Boolean).join(`
|
|
107564
|
+
|
|
107565
|
+
`);
|
|
107566
|
+
}
|
|
107524
107567
|
function createPrepareHelpers(input) {
|
|
107525
107568
|
const {
|
|
107526
107569
|
args,
|
|
@@ -107617,9 +107660,7 @@ function createPrepareHelpers(input) {
|
|
|
107617
107660
|
} catch (err) {
|
|
107618
107661
|
diag("workflow", `! workflow render failed: ${err.message}`, "yellow");
|
|
107619
107662
|
}
|
|
107620
|
-
const appendPrompt =
|
|
107621
|
-
|
|
107622
|
-
`);
|
|
107663
|
+
const appendPrompt = composeAppendPrompt(args.prompt ?? "", cfg.appendPrompt ?? "", workflowPrompt);
|
|
107623
107664
|
changeName = await scaffoldChangeForIssue(scaffoldTasksDir, scaffoldStatesDir, issue2, comments, appendPrompt, attachments);
|
|
107624
107665
|
} else {
|
|
107625
107666
|
changeName = derivedName;
|
|
@@ -108620,6 +108661,103 @@ function buildTicketDigest(issue2, comments) {
|
|
|
108620
108661
|
function retroDepEntry(agentDebug, hook) {
|
|
108621
108662
|
return agentDebug ? { runRetrospective: hook } : {};
|
|
108622
108663
|
}
|
|
108664
|
+
function computeWantPr(wantPrBase, isAwaiting, isAwaitingConfirmation) {
|
|
108665
|
+
return wantPrBase && !isAwaiting && !isAwaitingConfirmation;
|
|
108666
|
+
}
|
|
108667
|
+
function computeWantValidateOnly(hasValidateSpec, wantPrBase) {
|
|
108668
|
+
return hasValidateSpec && !wantPrBase;
|
|
108669
|
+
}
|
|
108670
|
+
function releaseWorkerMaps(maps, changeName) {
|
|
108671
|
+
maps.cwdByChange.delete(changeName);
|
|
108672
|
+
maps.statesDirByChange.delete(changeName);
|
|
108673
|
+
maps.branchByChange.delete(changeName);
|
|
108674
|
+
maps.issueByChange.delete(changeName);
|
|
108675
|
+
}
|
|
108676
|
+
function buildTaskCmd(args, cfg, changeName) {
|
|
108677
|
+
const engine = args.engineSet ? args.engine : cfg.engine;
|
|
108678
|
+
const model = args.engineSet ? args.model : cfg.model;
|
|
108679
|
+
const c = [
|
|
108680
|
+
process.execPath,
|
|
108681
|
+
process.argv[1] ?? "",
|
|
108682
|
+
"loop",
|
|
108683
|
+
"task",
|
|
108684
|
+
"--name",
|
|
108685
|
+
changeName,
|
|
108686
|
+
"--" + engine,
|
|
108687
|
+
"--model",
|
|
108688
|
+
model
|
|
108689
|
+
];
|
|
108690
|
+
const maxIter = args.maxIterations || cfg.maxIterationsPerTask;
|
|
108691
|
+
if (maxIter > 0)
|
|
108692
|
+
c.push("--max-iterations", String(maxIter));
|
|
108693
|
+
const maxCost = args.maxCostUsd || cfg.maxCostUsdPerTask;
|
|
108694
|
+
if (maxCost > 0)
|
|
108695
|
+
c.push("--max-cost", String(maxCost));
|
|
108696
|
+
const maxRuntime = args.maxRuntimeMinutes || cfg.maxRuntimeMinutesPerTask;
|
|
108697
|
+
if (maxRuntime > 0)
|
|
108698
|
+
c.push("--max-runtime", String(maxRuntime));
|
|
108699
|
+
const maxFailures = args.maxConsecutiveFailures !== 5 ? args.maxConsecutiveFailures : cfg.maxConsecutiveFailuresPerTask;
|
|
108700
|
+
if (maxFailures !== 5)
|
|
108701
|
+
c.push("--max-failures", String(maxFailures));
|
|
108702
|
+
const delay2 = args.delay || cfg.iterationDelaySeconds;
|
|
108703
|
+
if (delay2 > 0)
|
|
108704
|
+
c.push("--delay", String(delay2));
|
|
108705
|
+
if (args.log || cfg.logRawStream)
|
|
108706
|
+
c.push("--log");
|
|
108707
|
+
if (args.verbose || cfg.taskVerbose)
|
|
108708
|
+
c.push("--verbose");
|
|
108709
|
+
if (args.manualTest || cfg.enableManualTest)
|
|
108710
|
+
c.push("--manual-test");
|
|
108711
|
+
const rp = cfg.openspec.reviewPhase;
|
|
108712
|
+
if (rp.enabled) {
|
|
108713
|
+
c.push("--review-enabled");
|
|
108714
|
+
if (rp.maxRounds !== 1)
|
|
108715
|
+
c.push("--review-max-rounds", String(rp.maxRounds));
|
|
108716
|
+
if (rp.reviewerModel !== undefined)
|
|
108717
|
+
c.push("--review-model", rp.reviewerModel);
|
|
108718
|
+
if (rp.reviewerContextStrategy !== "fresh")
|
|
108719
|
+
c.push("--review-context-strategy", rp.reviewerContextStrategy);
|
|
108720
|
+
}
|
|
108721
|
+
c.push("--from-agent");
|
|
108722
|
+
return c;
|
|
108723
|
+
}
|
|
108724
|
+
function buildPostTaskInput(input) {
|
|
108725
|
+
const { args, cfg } = input;
|
|
108726
|
+
return {
|
|
108727
|
+
...input.trigger ? { mode: input.trigger } : {},
|
|
108728
|
+
...input.prUrl ? { prUrl: input.prUrl } : {},
|
|
108729
|
+
changeName: input.changeName,
|
|
108730
|
+
cwd: input.cwd,
|
|
108731
|
+
projectRoot: input.projectRoot,
|
|
108732
|
+
changeDir: input.changeDir,
|
|
108733
|
+
stateFilePath: input.stateFilePath,
|
|
108734
|
+
branch: input.branch,
|
|
108735
|
+
issue: input.issue,
|
|
108736
|
+
exitCode: input.exitCode,
|
|
108737
|
+
useWorktree: input.useWorktree,
|
|
108738
|
+
wantPr: input.wantPr,
|
|
108739
|
+
wantFixCi: input.wantFixCi,
|
|
108740
|
+
wantAutoMerge: input.wantAutoMerge,
|
|
108741
|
+
wantValidateOnly: input.wantValidateOnly,
|
|
108742
|
+
cfg: {
|
|
108743
|
+
teardownScript: cfg.teardownScript ?? null,
|
|
108744
|
+
prBaseBranch: cfg.prBaseBranch,
|
|
108745
|
+
autoMergeStrategy: cfg.autoMergeStrategy,
|
|
108746
|
+
maxCiFixAttempts: cfg.maxCiFixAttempts,
|
|
108747
|
+
ciPollIntervalSeconds: cfg.ciPollIntervalSeconds,
|
|
108748
|
+
cleanupWorktreeOnSuccess: cfg.cleanupWorktreeOnSuccess,
|
|
108749
|
+
ignoreCiChecks: cfg.ignoreCiChecks,
|
|
108750
|
+
stackPrsOnDependencies: args.stackPrs || cfg.stackPrsOnDependencies,
|
|
108751
|
+
neverTouch: cfg.boundaries.never_touch,
|
|
108752
|
+
metaOnlyFiles: cfg.boundaries.meta_only_files,
|
|
108753
|
+
finalizeNoOpAsDone: cfg.finalizeNoOpAsDone,
|
|
108754
|
+
manualMergeWhenAutoMergeDisabled: cfg.manualMergeWhenAutoMergeDisabled,
|
|
108755
|
+
prDraft: cfg.prDraft,
|
|
108756
|
+
validateCommands: [cfg.commands.test, cfg.commands.lint, cfg.commands.typecheck].filter((c) => Boolean(c))
|
|
108757
|
+
},
|
|
108758
|
+
respawnWorker: input.respawnWorker
|
|
108759
|
+
};
|
|
108760
|
+
}
|
|
108623
108761
|
function createSpawnWorker(input) {
|
|
108624
108762
|
const {
|
|
108625
108763
|
args,
|
|
@@ -108652,54 +108790,8 @@ function createSpawnWorker(input) {
|
|
|
108652
108790
|
onWorkerOutput,
|
|
108653
108791
|
onWorkerCmd
|
|
108654
108792
|
} = input;
|
|
108655
|
-
|
|
108656
|
-
|
|
108657
|
-
const model = args.engineSet ? args.model : cfg.model;
|
|
108658
|
-
const c = [
|
|
108659
|
-
process.execPath,
|
|
108660
|
-
process.argv[1] ?? "",
|
|
108661
|
-
"loop",
|
|
108662
|
-
"task",
|
|
108663
|
-
"--name",
|
|
108664
|
-
changeName,
|
|
108665
|
-
"--" + engine,
|
|
108666
|
-
"--model",
|
|
108667
|
-
model
|
|
108668
|
-
];
|
|
108669
|
-
const maxIter = args.maxIterations || cfg.maxIterationsPerTask;
|
|
108670
|
-
if (maxIter > 0)
|
|
108671
|
-
c.push("--max-iterations", String(maxIter));
|
|
108672
|
-
const maxCost = args.maxCostUsd || cfg.maxCostUsdPerTask;
|
|
108673
|
-
if (maxCost > 0)
|
|
108674
|
-
c.push("--max-cost", String(maxCost));
|
|
108675
|
-
const maxRuntime = args.maxRuntimeMinutes || cfg.maxRuntimeMinutesPerTask;
|
|
108676
|
-
if (maxRuntime > 0)
|
|
108677
|
-
c.push("--max-runtime", String(maxRuntime));
|
|
108678
|
-
const maxFailures = args.maxConsecutiveFailures !== 5 ? args.maxConsecutiveFailures : cfg.maxConsecutiveFailuresPerTask;
|
|
108679
|
-
if (maxFailures !== 5)
|
|
108680
|
-
c.push("--max-failures", String(maxFailures));
|
|
108681
|
-
const delay2 = args.delay || cfg.iterationDelaySeconds;
|
|
108682
|
-
if (delay2 > 0)
|
|
108683
|
-
c.push("--delay", String(delay2));
|
|
108684
|
-
if (args.log || cfg.logRawStream)
|
|
108685
|
-
c.push("--log");
|
|
108686
|
-
if (args.verbose || cfg.taskVerbose)
|
|
108687
|
-
c.push("--verbose");
|
|
108688
|
-
if (args.manualTest || cfg.enableManualTest)
|
|
108689
|
-
c.push("--manual-test");
|
|
108690
|
-
const rp = cfg.openspec.reviewPhase;
|
|
108691
|
-
if (rp.enabled) {
|
|
108692
|
-
c.push("--review-enabled");
|
|
108693
|
-
if (rp.maxRounds !== 1)
|
|
108694
|
-
c.push("--review-max-rounds", String(rp.maxRounds));
|
|
108695
|
-
if (rp.reviewerModel !== undefined)
|
|
108696
|
-
c.push("--review-model", rp.reviewerModel);
|
|
108697
|
-
if (rp.reviewerContextStrategy !== "fresh")
|
|
108698
|
-
c.push("--review-context-strategy", rp.reviewerContextStrategy);
|
|
108699
|
-
}
|
|
108700
|
-
c.push("--from-agent");
|
|
108701
|
-
return c;
|
|
108702
|
-
}
|
|
108793
|
+
const doPostTask = input.runners?.runPostTask ?? runPostTask;
|
|
108794
|
+
const buildTaskCmdFor = (changeName) => buildTaskCmd(args, cfg, changeName);
|
|
108703
108795
|
const retroSeen = new Set;
|
|
108704
108796
|
const runRetrospectiveHook = async (info) => {
|
|
108705
108797
|
try {
|
|
@@ -108777,7 +108869,7 @@ function createSpawnWorker(input) {
|
|
|
108777
108869
|
const workerLayout = projectLayout(cwd2);
|
|
108778
108870
|
const validateSpecPath = join33(workerLayout.changeDir(changeName), "specs", "validate.md");
|
|
108779
108871
|
const hasValidateSpec = await Bun.file(validateSpecPath).exists();
|
|
108780
|
-
const wantValidateOnly = hasValidateSpec
|
|
108872
|
+
const wantValidateOnly = computeWantValidateOnly(hasValidateSpec, wantPrBase);
|
|
108781
108873
|
if (hasValidateSpec) {
|
|
108782
108874
|
try {
|
|
108783
108875
|
const stateFile = workerLayout.stateFile(changeName);
|
|
@@ -108821,10 +108913,10 @@ function createSpawnWorker(input) {
|
|
|
108821
108913
|
} catch (err) {
|
|
108822
108914
|
diag("tasks", `! tasks.md normalization failed: ${err.message}`, "yellow");
|
|
108823
108915
|
}
|
|
108824
|
-
const wantPr = wantPrBase
|
|
108825
|
-
const effectiveCode = await
|
|
108826
|
-
|
|
108827
|
-
|
|
108916
|
+
const wantPr = computeWantPr(wantPrBase, awaitingChangeSet.has(changeName), coordRef.current?.isAwaitingConfirmation(changeName) ?? false);
|
|
108917
|
+
const effectiveCode = await doPostTask(buildPostTaskInput({
|
|
108918
|
+
args,
|
|
108919
|
+
cfg,
|
|
108828
108920
|
changeName,
|
|
108829
108921
|
cwd: cwd2,
|
|
108830
108922
|
projectRoot,
|
|
@@ -108838,24 +108930,10 @@ function createSpawnWorker(input) {
|
|
|
108838
108930
|
wantFixCi,
|
|
108839
108931
|
wantAutoMerge,
|
|
108840
108932
|
wantValidateOnly,
|
|
108841
|
-
|
|
108842
|
-
|
|
108843
|
-
prBaseBranch: cfg.prBaseBranch,
|
|
108844
|
-
autoMergeStrategy: cfg.autoMergeStrategy,
|
|
108845
|
-
maxCiFixAttempts: cfg.maxCiFixAttempts,
|
|
108846
|
-
ciPollIntervalSeconds: cfg.ciPollIntervalSeconds,
|
|
108847
|
-
cleanupWorktreeOnSuccess: cfg.cleanupWorktreeOnSuccess,
|
|
108848
|
-
ignoreCiChecks: cfg.ignoreCiChecks,
|
|
108849
|
-
stackPrsOnDependencies: args.stackPrs || cfg.stackPrsOnDependencies,
|
|
108850
|
-
neverTouch: cfg.boundaries.never_touch,
|
|
108851
|
-
metaOnlyFiles: cfg.boundaries.meta_only_files,
|
|
108852
|
-
finalizeNoOpAsDone: cfg.finalizeNoOpAsDone,
|
|
108853
|
-
manualMergeWhenAutoMergeDisabled: cfg.manualMergeWhenAutoMergeDisabled,
|
|
108854
|
-
prDraft: cfg.prDraft,
|
|
108855
|
-
validateCommands: [cfg.commands.test, cfg.commands.lint, cfg.commands.typecheck].filter((c) => Boolean(c))
|
|
108856
|
-
},
|
|
108933
|
+
...trigger ? { trigger } : {},
|
|
108934
|
+
...prByChange?.get(changeName) ? { prUrl: prByChange.get(changeName) } : {},
|
|
108857
108935
|
respawnWorker: respawn
|
|
108858
|
-
}, {
|
|
108936
|
+
}), {
|
|
108859
108937
|
cmd: tracedCmd,
|
|
108860
108938
|
git: gitRunner,
|
|
108861
108939
|
log: onLog,
|
|
@@ -108894,10 +108972,7 @@ function createSpawnWorker(input) {
|
|
|
108894
108972
|
},
|
|
108895
108973
|
resolveDependencyBaseBranch: (issue2) => resolveDependencyBaseBranchImpl(issue2, tracedCmd, cwd2, { apiKey, onLog })
|
|
108896
108974
|
});
|
|
108897
|
-
cwdByChange
|
|
108898
|
-
statesDirByChange.delete(changeName);
|
|
108899
|
-
branchByChange.delete(changeName);
|
|
108900
|
-
issueByChange.delete(changeName);
|
|
108975
|
+
releaseWorkerMaps({ cwdByChange, statesDirByChange, branchByChange, issueByChange }, changeName);
|
|
108901
108976
|
onWorkerExited(changeName);
|
|
108902
108977
|
return effectiveCode;
|
|
108903
108978
|
});
|
|
@@ -261725,6 +261800,25 @@ async function readSpecAttachmentsSubtree(statePath) {
|
|
|
261725
261800
|
const sidecar = await readSlotSidecar(dirname13(statePath), "specAttachments");
|
|
261726
261801
|
return sidecar ?? await readInlineSpecAttachments(statePath);
|
|
261727
261802
|
}
|
|
261803
|
+
function asRevisions(value) {
|
|
261804
|
+
if (!Array.isArray(value))
|
|
261805
|
+
return [];
|
|
261806
|
+
const out = [];
|
|
261807
|
+
for (const entry of value) {
|
|
261808
|
+
if (entry && typeof entry === "object" && !Array.isArray(entry)) {
|
|
261809
|
+
const e = entry;
|
|
261810
|
+
if (typeof e.version === "number" && typeof e.attachmentId === "string" && typeof e.sha256 === "string" && typeof e.trigger === "string") {
|
|
261811
|
+
out.push({
|
|
261812
|
+
version: e.version,
|
|
261813
|
+
attachmentId: e.attachmentId,
|
|
261814
|
+
sha256: e.sha256,
|
|
261815
|
+
trigger: e.trigger
|
|
261816
|
+
});
|
|
261817
|
+
}
|
|
261818
|
+
}
|
|
261819
|
+
}
|
|
261820
|
+
return out;
|
|
261821
|
+
}
|
|
261728
261822
|
async function readSpecAttachments(statePath) {
|
|
261729
261823
|
const sa = await readSpecAttachmentsSubtree(statePath);
|
|
261730
261824
|
return {
|
|
@@ -261743,12 +261837,45 @@ async function readSpecAttachments(statePath) {
|
|
|
261743
261837
|
designPdf: {
|
|
261744
261838
|
attachmentId: sa.designPdf?.attachmentId ?? null,
|
|
261745
261839
|
sha256: sa.designPdf?.sha256 ?? null
|
|
261746
|
-
}
|
|
261840
|
+
},
|
|
261841
|
+
designRevisions: asRevisions(sa.designRevisions),
|
|
261842
|
+
designPdfRevisions: asRevisions(sa.designPdfRevisions)
|
|
261747
261843
|
};
|
|
261748
261844
|
}
|
|
261749
261845
|
async function persistSlot(statePath, slot, value) {
|
|
261750
261846
|
await writeField(stateDirOf(statePath), "linear-attachments", `specAttachments.${slot}`, value);
|
|
261751
261847
|
}
|
|
261848
|
+
async function persistRevision(statePath, slot, revisions) {
|
|
261849
|
+
await writeField(stateDirOf(statePath), "linear-attachments", `specAttachments.${REVISIONS_KEY[slot]}`, revisions);
|
|
261850
|
+
}
|
|
261851
|
+
async function isDesignSealed(stateDir) {
|
|
261852
|
+
try {
|
|
261853
|
+
const pr2 = await readSlotSidecar(stateDir, "pr");
|
|
261854
|
+
const url2 = pr2?.url;
|
|
261855
|
+
if (typeof url2 === "string" && url2.length > 0)
|
|
261856
|
+
return true;
|
|
261857
|
+
} catch {}
|
|
261858
|
+
try {
|
|
261859
|
+
const confirmation = await readSlotSidecar(stateDir, "confirmation");
|
|
261860
|
+
if (confirmation?.earlyDraftPrAt != null)
|
|
261861
|
+
return true;
|
|
261862
|
+
} catch {}
|
|
261863
|
+
return false;
|
|
261864
|
+
}
|
|
261865
|
+
async function resolveTriggerLabel(stateDir) {
|
|
261866
|
+
try {
|
|
261867
|
+
const flow2 = await readSlotSidecar(stateDir, "flow");
|
|
261868
|
+
const snapshot = flow2?.actorSnapshot;
|
|
261869
|
+
const value = snapshot?.value;
|
|
261870
|
+
if (typeof value === "string" && TRIGGER_LABELS[value])
|
|
261871
|
+
return TRIGGER_LABELS[value];
|
|
261872
|
+
} catch {}
|
|
261873
|
+
return "revision";
|
|
261874
|
+
}
|
|
261875
|
+
function versionedTitle(slot, n, label) {
|
|
261876
|
+
const base2 = `Ralph design #${n} (${label})`;
|
|
261877
|
+
return slot === "designPdf" ? `${base2} (PDF)` : base2;
|
|
261878
|
+
}
|
|
261752
261879
|
async function adopt(deps, slot) {
|
|
261753
261880
|
const spec = SLOT_SPECS[slot];
|
|
261754
261881
|
try {
|
|
@@ -261793,6 +261920,65 @@ function extractImplementationSection(tasksMarkdown) {
|
|
|
261793
261920
|
return captured.join(`
|
|
261794
261921
|
`).trim();
|
|
261795
261922
|
}
|
|
261923
|
+
async function syncSlotSealed(deps, slot, sourceBytes, hash2, state) {
|
|
261924
|
+
const spec = SLOT_SPECS[slot];
|
|
261925
|
+
const revisions = state[REVISIONS_KEY[slot]];
|
|
261926
|
+
const v1Sha = state[slot]?.sha256 ?? null;
|
|
261927
|
+
if (hash2 === v1Sha || revisions.some((r) => r.sha256 === hash2)) {
|
|
261928
|
+
deps.log(` spec-attachments: ${spec.uploadFilename} unchanged (sealed), skipping`, "gray");
|
|
261929
|
+
return;
|
|
261930
|
+
}
|
|
261931
|
+
const n = 2 + revisions.length;
|
|
261932
|
+
const label = await resolveTriggerLabel(stateDirOf(deps.statePath));
|
|
261933
|
+
const title = versionedTitle(slot, n, label);
|
|
261934
|
+
let uploadBytes;
|
|
261935
|
+
try {
|
|
261936
|
+
uploadBytes = await spec.renderBytes(sourceBytes);
|
|
261937
|
+
} catch (err) {
|
|
261938
|
+
deps.log(`! spec-attachments: render ${spec.uploadFilename} (sealed) failed: ${err.message}`, "yellow");
|
|
261939
|
+
return;
|
|
261940
|
+
}
|
|
261941
|
+
let assetUrl;
|
|
261942
|
+
try {
|
|
261943
|
+
const uploaded = await deps.mutations.uploadFileToLinear(deps.apiKey, {
|
|
261944
|
+
filename: spec.uploadFilename,
|
|
261945
|
+
contentType: spec.contentType,
|
|
261946
|
+
bytes: uploadBytes
|
|
261947
|
+
});
|
|
261948
|
+
assetUrl = uploaded.assetUrl;
|
|
261949
|
+
} catch (err) {
|
|
261950
|
+
deps.log(`! spec-attachments: upload ${spec.uploadFilename} (sealed) failed: ${describeLinearError(err)}`, "yellow");
|
|
261951
|
+
return;
|
|
261952
|
+
}
|
|
261953
|
+
let attachmentId = null;
|
|
261954
|
+
try {
|
|
261955
|
+
attachmentId = await deps.mutations.findIssueAttachmentByTitle(deps.apiKey, deps.issueId, title);
|
|
261956
|
+
if (attachmentId) {
|
|
261957
|
+
deps.log(` spec-attachments: adopted existing ${title} attachment ${attachmentId}`, "gray");
|
|
261958
|
+
}
|
|
261959
|
+
} catch (err) {
|
|
261960
|
+
deps.log(`! spec-attachments: findIssueAttachmentByTitle ${title} failed (treating as no match): ${describeLinearError(err)}`, "yellow");
|
|
261961
|
+
attachmentId = null;
|
|
261962
|
+
}
|
|
261963
|
+
if (!attachmentId) {
|
|
261964
|
+
try {
|
|
261965
|
+
attachmentId = await deps.mutations.createAttachmentForUrl(deps.apiKey, {
|
|
261966
|
+
issueId: deps.issueId,
|
|
261967
|
+
url: assetUrl,
|
|
261968
|
+
title,
|
|
261969
|
+
subtitle: `iteration ${deps.iteration}`
|
|
261970
|
+
});
|
|
261971
|
+
} catch (err) {
|
|
261972
|
+
deps.log(`! spec-attachments: createAttachmentForUrl ${title} failed: ${describeLinearError(err)}`, "yellow");
|
|
261973
|
+
return;
|
|
261974
|
+
}
|
|
261975
|
+
deps.log(` spec-attachments: created ${title} attachment`, "gray");
|
|
261976
|
+
}
|
|
261977
|
+
await persistRevision(deps.statePath, slot, [
|
|
261978
|
+
...revisions,
|
|
261979
|
+
{ version: n, attachmentId, sha256: hash2, trigger: label }
|
|
261980
|
+
]);
|
|
261981
|
+
}
|
|
261796
261982
|
async function syncSlot(deps, slot) {
|
|
261797
261983
|
const spec = SLOT_SPECS[slot];
|
|
261798
261984
|
const [primaryName, ...trailingNames] = spec.sourceFiles;
|
|
@@ -261848,7 +262034,12 @@ ${body}
|
|
|
261848
262034
|
offset += p.length;
|
|
261849
262035
|
}
|
|
261850
262036
|
const hash2 = sha256Hex(sourceBytes);
|
|
261851
|
-
|
|
262037
|
+
const state = await readSpecAttachments(deps.statePath);
|
|
262038
|
+
if (await isDesignSealed(stateDirOf(deps.statePath))) {
|
|
262039
|
+
await syncSlotSealed(deps, slot, sourceBytes, hash2, state);
|
|
262040
|
+
return;
|
|
262041
|
+
}
|
|
262042
|
+
let current = state[slot] ?? EMPTY_SLOT;
|
|
261852
262043
|
if (!current.attachmentId) {
|
|
261853
262044
|
const { adoptedId } = await adopt(deps, slot);
|
|
261854
262045
|
if (adoptedId) {
|
|
@@ -261950,7 +262141,7 @@ async function syncSpecAttachments(deps) {
|
|
|
261950
262141
|
await syncSlot(deps, slot);
|
|
261951
262142
|
}
|
|
261952
262143
|
}
|
|
261953
|
-
var identityRender = async (b2) => b2, pdfRender = (title) => async (b2) => renderMarkdownToPdf(new TextDecoder().decode(b2), title), SLOT_SPECS, LEGACY_SLOT_TITLES, EMPTY_SLOT;
|
|
262144
|
+
var identityRender = async (b2) => b2, pdfRender = (title) => async (b2) => renderMarkdownToPdf(new TextDecoder().decode(b2), title), SLOT_SPECS, LEGACY_SLOT_TITLES, REVISIONS_KEY, EMPTY_SLOT, TRIGGER_LABELS;
|
|
261954
262145
|
var init_spec_attachments = __esm(() => {
|
|
261955
262146
|
init_store();
|
|
261956
262147
|
init_comment_sync();
|
|
@@ -261977,7 +262168,16 @@ var init_spec_attachments = __esm(() => {
|
|
|
261977
262168
|
proposal: "Ralph proposal",
|
|
261978
262169
|
proposalPdf: "Ralph proposal (PDF)"
|
|
261979
262170
|
};
|
|
262171
|
+
REVISIONS_KEY = {
|
|
262172
|
+
design: "designRevisions",
|
|
262173
|
+
designPdf: "designPdfRevisions"
|
|
262174
|
+
};
|
|
261980
262175
|
EMPTY_SLOT = { attachmentId: null, sha256: null };
|
|
262176
|
+
TRIGGER_LABELS = {
|
|
262177
|
+
review: "review follow-up",
|
|
262178
|
+
"ci-fix": "CI fix",
|
|
262179
|
+
"conflict-fix": "conflict fix"
|
|
262180
|
+
};
|
|
261981
262181
|
});
|
|
261982
262182
|
|
|
261983
262183
|
// apps/agent/src/agent/wire/comment-sync.ts
|
package/package.json
CHANGED