@neriros/ralphy 3.10.0 → 3.10.2
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 +16 -2
- package/dist/shell/index.js +176 -86
- package/package.json +1 -1
package/dist/mcp/index.js
CHANGED
|
@@ -6615,20 +6615,33 @@ import {
|
|
|
6615
6615
|
writeFileSync,
|
|
6616
6616
|
existsSync,
|
|
6617
6617
|
unlinkSync,
|
|
6618
|
+
renameSync,
|
|
6618
6619
|
mkdirSync,
|
|
6619
6620
|
readdirSync
|
|
6620
6621
|
} from "fs";
|
|
6621
6622
|
import { dirname } from "path";
|
|
6622
6623
|
|
|
6623
6624
|
class FileSystemProvider {
|
|
6625
|
+
writeSeq = 0;
|
|
6624
6626
|
read(path) {
|
|
6625
6627
|
if (!existsSync(path))
|
|
6626
6628
|
return null;
|
|
6627
6629
|
return readFileSync(path, "utf-8");
|
|
6628
6630
|
}
|
|
6629
6631
|
write(path, content) {
|
|
6630
|
-
|
|
6631
|
-
|
|
6632
|
+
const dir = dirname(path);
|
|
6633
|
+
mkdirSync(dir, { recursive: true });
|
|
6634
|
+
const tmp = `${path}.tmp-${process.pid}-${this.writeSeq++}`;
|
|
6635
|
+
try {
|
|
6636
|
+
writeFileSync(tmp, content, "utf-8");
|
|
6637
|
+
renameSync(tmp, path);
|
|
6638
|
+
} catch (err) {
|
|
6639
|
+
try {
|
|
6640
|
+
if (existsSync(tmp))
|
|
6641
|
+
unlinkSync(tmp);
|
|
6642
|
+
} catch {}
|
|
6643
|
+
throw err;
|
|
6644
|
+
}
|
|
6632
6645
|
}
|
|
6633
6646
|
remove(path) {
|
|
6634
6647
|
if (!existsSync(path))
|
|
@@ -24050,6 +24063,7 @@ var HistoryEntrySchema = exports_external.object({
|
|
|
24050
24063
|
engine: exports_external.string(),
|
|
24051
24064
|
model: exports_external.string(),
|
|
24052
24065
|
result: exports_external.string(),
|
|
24066
|
+
appVersion: exports_external.string().optional(),
|
|
24053
24067
|
usage: IterationUsageSchema.partial().optional()
|
|
24054
24068
|
});
|
|
24055
24069
|
var StateSchema = 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.2")
|
|
18932
|
+
return "3.10.2";
|
|
18933
18933
|
} catch {}
|
|
18934
18934
|
const dirsToTry = [];
|
|
18935
18935
|
try {
|
|
@@ -81370,8 +81370,7 @@ var init_fields = __esm(() => {
|
|
|
81370
81370
|
id: "linear.syncSpecsAsAttachments",
|
|
81371
81371
|
label: "Upload proposal.md / design.md as attachments?",
|
|
81372
81372
|
description: "Upload the OpenSpec planning docs (proposal.md, design.md) to the issue as attachments. OpenSpec is Ralphy's spec-driven planning format.",
|
|
81373
|
-
spec: yes()
|
|
81374
|
-
when: isOn("linear.syncTasksToComment")
|
|
81373
|
+
spec: yes()
|
|
81375
81374
|
},
|
|
81376
81375
|
{
|
|
81377
81376
|
id: "linear.specAttachmentFormats",
|
|
@@ -82780,6 +82779,14 @@ function buildFromAnswers(mode, answers, build = buildWorkflowMarkdown) {
|
|
|
82780
82779
|
else
|
|
82781
82780
|
delete values2["linear.indicators"];
|
|
82782
82781
|
}
|
|
82782
|
+
if (values2["linear.confirmationMode.enabled"] === true && values2["linear.indicators"] && typeof values2["linear.indicators"] === "object") {
|
|
82783
|
+
const map3 = { ...values2["linear.indicators"] };
|
|
82784
|
+
if (!("getApproved" in map3)) {
|
|
82785
|
+
map3.getApproved = { filter: [{ type: "label", value: "approved" }] };
|
|
82786
|
+
map3.clearApproved = { type: "label", value: "approved" };
|
|
82787
|
+
values2["linear.indicators"] = map3;
|
|
82788
|
+
}
|
|
82789
|
+
}
|
|
82783
82790
|
let bodyOverride;
|
|
82784
82791
|
if (PROMPT_BODY_FIELD_ID in values2) {
|
|
82785
82792
|
const body = values2[PROMPT_BODY_FIELD_ID];
|
|
@@ -83785,12 +83792,6 @@ var init_SetupWizard = __esm(async () => {
|
|
|
83785
83792
|
}
|
|
83786
83793
|
];
|
|
83787
83794
|
CONFIRMATION_STATES = [
|
|
83788
|
-
{
|
|
83789
|
-
key: "confirmGate",
|
|
83790
|
-
label: "Confirmation gate",
|
|
83791
|
-
description: "Opt-in: only require human approval for issues that match this.",
|
|
83792
|
-
slots: ["getConfirmGate"]
|
|
83793
|
-
},
|
|
83794
83795
|
{
|
|
83795
83796
|
key: "autoApprove",
|
|
83796
83797
|
label: "Auto-approve",
|
|
@@ -84079,20 +84080,33 @@ import {
|
|
|
84079
84080
|
writeFileSync,
|
|
84080
84081
|
existsSync as existsSync2,
|
|
84081
84082
|
unlinkSync,
|
|
84083
|
+
renameSync,
|
|
84082
84084
|
mkdirSync,
|
|
84083
84085
|
readdirSync
|
|
84084
84086
|
} from "fs";
|
|
84085
84087
|
import { dirname as dirname2 } from "path";
|
|
84086
84088
|
|
|
84087
84089
|
class FileSystemProvider {
|
|
84090
|
+
writeSeq = 0;
|
|
84088
84091
|
read(path) {
|
|
84089
84092
|
if (!existsSync2(path))
|
|
84090
84093
|
return null;
|
|
84091
84094
|
return readFileSync3(path, "utf-8");
|
|
84092
84095
|
}
|
|
84093
84096
|
write(path, content) {
|
|
84094
|
-
|
|
84095
|
-
|
|
84097
|
+
const dir = dirname2(path);
|
|
84098
|
+
mkdirSync(dir, { recursive: true });
|
|
84099
|
+
const tmp = `${path}.tmp-${process.pid}-${this.writeSeq++}`;
|
|
84100
|
+
try {
|
|
84101
|
+
writeFileSync(tmp, content, "utf-8");
|
|
84102
|
+
renameSync(tmp, path);
|
|
84103
|
+
} catch (err) {
|
|
84104
|
+
try {
|
|
84105
|
+
if (existsSync2(tmp))
|
|
84106
|
+
unlinkSync(tmp);
|
|
84107
|
+
} catch {}
|
|
84108
|
+
throw err;
|
|
84109
|
+
}
|
|
84096
84110
|
}
|
|
84097
84111
|
remove(path) {
|
|
84098
84112
|
if (!existsSync2(path))
|
|
@@ -84149,7 +84163,7 @@ function projectLayout(root) {
|
|
|
84149
84163
|
stateFile: (name) => join6(statesDir, name, STATE_FILE)
|
|
84150
84164
|
};
|
|
84151
84165
|
}
|
|
84152
|
-
var STATE_FILE = ".ralph-state.json";
|
|
84166
|
+
var STATE_FILE = ".ralph-state.json", GAVEUP_COUNT_FILE = ".ralph-gaveup-count";
|
|
84153
84167
|
var init_layout = __esm(() => {
|
|
84154
84168
|
init_context();
|
|
84155
84169
|
});
|
|
@@ -88848,6 +88862,7 @@ var init_types2 = __esm(() => {
|
|
|
88848
88862
|
engine: exports_external2.string(),
|
|
88849
88863
|
model: exports_external2.string(),
|
|
88850
88864
|
result: exports_external2.string(),
|
|
88865
|
+
appVersion: exports_external2.string().optional(),
|
|
88851
88866
|
usage: IterationUsageSchema.partial().optional()
|
|
88852
88867
|
});
|
|
88853
88868
|
StateSchema = exports_external2.object({
|
|
@@ -99615,6 +99630,7 @@ function updateStateIteration(stateDir, result2, startedAt, engine, model, usage
|
|
|
99615
99630
|
engine,
|
|
99616
99631
|
model,
|
|
99617
99632
|
result: result2,
|
|
99633
|
+
appVersion: VERSION,
|
|
99618
99634
|
usage: usage ? {
|
|
99619
99635
|
cost_usd: usage.cost_usd,
|
|
99620
99636
|
duration_ms: usage.duration_ms,
|
|
@@ -99676,6 +99692,7 @@ function mergeUsage(base2, resumed) {
|
|
|
99676
99692
|
}
|
|
99677
99693
|
var STEERING_MAX_LINES = 20;
|
|
99678
99694
|
var init_loop = __esm(() => {
|
|
99695
|
+
init_version();
|
|
99679
99696
|
init_state();
|
|
99680
99697
|
init_context();
|
|
99681
99698
|
init_tasks_md();
|
|
@@ -99807,7 +99824,9 @@ function useLoop(opts) {
|
|
|
99807
99824
|
startingStatus: currentState.status
|
|
99808
99825
|
});
|
|
99809
99826
|
while (!cancelled) {
|
|
99810
|
-
|
|
99827
|
+
const { state: polled } = tryReadStateRaw(stateDir);
|
|
99828
|
+
if (polled !== null)
|
|
99829
|
+
currentState = polled;
|
|
99811
99830
|
setState(currentState);
|
|
99812
99831
|
if (!actor.getSnapshot().matches("running"))
|
|
99813
99832
|
break;
|
|
@@ -100411,7 +100430,7 @@ import { join as join16, dirname as dirname7 } from "path";
|
|
|
100411
100430
|
import { homedir as homedir4 } from "os";
|
|
100412
100431
|
import { mkdir as mkdir5 } from "fs/promises";
|
|
100413
100432
|
function fmt(type, text) {
|
|
100414
|
-
return `[${new Date().toISOString()}] [${type}] ${text}
|
|
100433
|
+
return `[${new Date().toISOString()}] [v${VERSION}] [${type}] ${text}
|
|
100415
100434
|
`;
|
|
100416
100435
|
}
|
|
100417
100436
|
function write(path, line) {
|
|
@@ -100453,6 +100472,7 @@ async function initWorkerLog(logFile) {
|
|
|
100453
100472
|
}
|
|
100454
100473
|
var jsonLogChains, ANSI_RE, AGENT_LOG_PATH;
|
|
100455
100474
|
var init_log = __esm(() => {
|
|
100475
|
+
init_version();
|
|
100456
100476
|
jsonLogChains = new Map;
|
|
100457
100477
|
ANSI_RE = /\x1b(?:\[[0-9;]*[A-Za-z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|.)/g;
|
|
100458
100478
|
AGENT_LOG_PATH = join16(homedir4(), ".ralph", "agent-mode.log");
|
|
@@ -101475,7 +101495,16 @@ function branchForChange(changeName) {
|
|
|
101475
101495
|
function worktreeDirNameForIssue(issue2) {
|
|
101476
101496
|
return issue2.identifier.toLowerCase();
|
|
101477
101497
|
}
|
|
101478
|
-
|
|
101498
|
+
function withRepoLock(projectRoot, fn) {
|
|
101499
|
+
const prev = repoWorktreeLocks.get(projectRoot) ?? Promise.resolve();
|
|
101500
|
+
const result2 = prev.then(fn, fn);
|
|
101501
|
+
repoWorktreeLocks.set(projectRoot, result2.then(() => {}, () => {}));
|
|
101502
|
+
return result2;
|
|
101503
|
+
}
|
|
101504
|
+
function createWorktree(projectRoot, changeName, baseBranch, runner) {
|
|
101505
|
+
return withRepoLock(projectRoot, () => provisionWorktree(projectRoot, changeName, baseBranch, runner));
|
|
101506
|
+
}
|
|
101507
|
+
async function provisionWorktree(projectRoot, changeName, baseBranch, runner) {
|
|
101479
101508
|
const dir = worktreesDir2(projectRoot);
|
|
101480
101509
|
const cwd2 = join20(dir, changeName);
|
|
101481
101510
|
const branch = branchForChange(changeName);
|
|
@@ -101570,7 +101599,7 @@ async function seedWorktreeMcpConfig(projectRoot, worktreeCwd) {
|
|
|
101570
101599
|
await Bun.write(dst, JSON.stringify(parsed, null, 2) + `
|
|
101571
101600
|
`);
|
|
101572
101601
|
}
|
|
101573
|
-
var PRE_PUSH_HOOK_SCRIPT = `#!/usr/bin/env bash
|
|
101602
|
+
var repoWorktreeLocks, PRE_PUSH_HOOK_SCRIPT = `#!/usr/bin/env bash
|
|
101574
101603
|
# Installed by ralphy createWorktree (RLF-107).
|
|
101575
101604
|
# Rejects any push whose remote ref is not refs/heads/ralph/*,
|
|
101576
101605
|
# and rejects force pushes unless RALPH_ALLOW_FORCE_PUSH=1.
|
|
@@ -101590,7 +101619,9 @@ while read local_ref local_sha remote_ref remote_sha; do
|
|
|
101590
101619
|
done
|
|
101591
101620
|
exit 0
|
|
101592
101621
|
`;
|
|
101593
|
-
var init_worktree = () => {
|
|
101622
|
+
var init_worktree = __esm(() => {
|
|
101623
|
+
repoWorktreeLocks = new Map;
|
|
101624
|
+
});
|
|
101594
101625
|
|
|
101595
101626
|
// apps/agent/src/shared/capabilities/git.ts
|
|
101596
101627
|
var createWorktree2, removeWorktree2, seedWorktreeMcpConfig2, git;
|
|
@@ -103276,7 +103307,7 @@ function emitFeatureSkipped(bus, id, reason) {
|
|
|
103276
103307
|
var init_run_feature = () => {};
|
|
103277
103308
|
|
|
103278
103309
|
// apps/agent/src/agent/post-task.ts
|
|
103279
|
-
import { join as join21 } from "path";
|
|
103310
|
+
import { join as join21, dirname as dirname9 } from "path";
|
|
103280
103311
|
function summarizeUncommittedStatus(stdout) {
|
|
103281
103312
|
const lines = stdout.split(`
|
|
103282
103313
|
`).filter((line) => line.length > 0);
|
|
@@ -103918,6 +103949,17 @@ async function runValidateOnlyPhase(input, deps) {
|
|
|
103918
103949
|
await reactivateState(stateFilePath, log3, changeName);
|
|
103919
103950
|
return respawnWorker();
|
|
103920
103951
|
}
|
|
103952
|
+
async function recordGaveUp(stateFilePath, log3, changeName) {
|
|
103953
|
+
const path = join21(dirname9(stateFilePath), GAVEUP_COUNT_FILE);
|
|
103954
|
+
try {
|
|
103955
|
+
const file2 = Bun.file(path);
|
|
103956
|
+
const current = await file2.exists() ? Number.parseInt(await file2.text(), 10) || 0 : 0;
|
|
103957
|
+
await Bun.write(path, String(current + 1) + `
|
|
103958
|
+
`);
|
|
103959
|
+
} catch (err) {
|
|
103960
|
+
log3(`! could not record gave-up for ${changeName}: ${err.message}`, "yellow");
|
|
103961
|
+
}
|
|
103962
|
+
}
|
|
103921
103963
|
async function runPostTask(input, deps) {
|
|
103922
103964
|
const { log: log3, cmd, git: git2, runScript } = deps;
|
|
103923
103965
|
const emit3 = (phase, detail) => deps.onPhase?.(phase, detail);
|
|
@@ -103961,6 +104003,8 @@ async function runPostTask(input, deps) {
|
|
|
103961
104003
|
respawnWorker
|
|
103962
104004
|
});
|
|
103963
104005
|
emit3(effectiveCode === 0 ? "done" : "gave-up", effectiveCode !== 0 ? `exit ${effectiveCode}` : undefined);
|
|
104006
|
+
if (effectiveCode !== 0)
|
|
104007
|
+
await recordGaveUp(stateFilePath, log3, changeName);
|
|
103964
104008
|
await runWorktreeCleanupPhase({ changeName, cwd: cwd2, projectRoot, useWorktree, effectiveCode, cfg }, { git: git2, log: log3, emit: emit3 });
|
|
103965
104009
|
await runTeardownPhase({ cwd: cwd2, teardownScript: cfg.teardownScript }, { runScript, log: log3, emit: emit3 });
|
|
103966
104010
|
return effectiveCode;
|
|
@@ -104035,6 +104079,8 @@ async function runPostTask(input, deps) {
|
|
|
104035
104079
|
}
|
|
104036
104080
|
const succeeded = effectiveCode === 0 || effectiveCode === NO_CHANGES_EXIT;
|
|
104037
104081
|
emit3(succeeded ? "done" : "gave-up", succeeded ? undefined : `exit ${effectiveCode}`);
|
|
104082
|
+
if (!succeeded)
|
|
104083
|
+
await recordGaveUp(stateFilePath, log3, changeName);
|
|
104038
104084
|
await runWorktreeCleanupPhase({ changeName, cwd: cwd2, projectRoot, useWorktree, effectiveCode, cfg }, { git: git2, log: log3, emit: emit3 });
|
|
104039
104085
|
await runTeardownPhase({ cwd: cwd2, teardownScript: cfg.teardownScript }, { runScript, log: log3, emit: emit3 });
|
|
104040
104086
|
return effectiveCode;
|
|
@@ -104052,6 +104098,7 @@ var CI_FAILED_EXIT = 70, PR_FAILED_EXIT = 71, NO_CHANGES_EXIT = 72, repoAutoMerg
|
|
|
104052
104098
|
return { exitCode: proc.exitCode ?? 1, output };
|
|
104053
104099
|
};
|
|
104054
104100
|
var init_post_task = __esm(() => {
|
|
104101
|
+
init_layout();
|
|
104055
104102
|
init_tasks_md();
|
|
104056
104103
|
init_fs_change();
|
|
104057
104104
|
init_git2();
|
|
@@ -105160,7 +105207,7 @@ var init_detections = __esm(() => {
|
|
|
105160
105207
|
});
|
|
105161
105208
|
|
|
105162
105209
|
// apps/agent/src/features/confirmation/state.ts
|
|
105163
|
-
import { dirname as
|
|
105210
|
+
import { dirname as dirname10, join as join23 } from "path";
|
|
105164
105211
|
import { mkdir as mkdir8 } from "fs/promises";
|
|
105165
105212
|
async function readConfirmationState(statePath) {
|
|
105166
105213
|
const f2 = Bun.file(statePath);
|
|
@@ -105185,7 +105232,7 @@ async function readConfirmationState(statePath) {
|
|
|
105185
105232
|
return { stateObj, confirmation };
|
|
105186
105233
|
}
|
|
105187
105234
|
async function writeConfirmationState(statePath, stateObj, confirmation) {
|
|
105188
|
-
await mkdir8(
|
|
105235
|
+
await mkdir8(dirname10(statePath), { recursive: true });
|
|
105189
105236
|
await Bun.write(statePath, JSON.stringify({ ...stateObj, confirmation }, null, 2) + `
|
|
105190
105237
|
`);
|
|
105191
105238
|
}
|
|
@@ -105427,7 +105474,7 @@ var init_inspect = __esm(() => {
|
|
|
105427
105474
|
});
|
|
105428
105475
|
|
|
105429
105476
|
// apps/agent/src/features/confirmation/awaiting.ts
|
|
105430
|
-
import { join as join24, dirname as
|
|
105477
|
+
import { join as join24, dirname as dirname11 } from "path";
|
|
105431
105478
|
import { mkdir as mkdir9 } from "fs/promises";
|
|
105432
105479
|
async function resolveChangeCwdForIssue(issue2, changeName, deps) {
|
|
105433
105480
|
const tracked = deps.cwdOf(changeName);
|
|
@@ -105489,7 +105536,7 @@ async function postPlanReadyCommentOnce(issue2, statePath, changeName, deps) {
|
|
|
105489
105536
|
rounds: confirmation?.rounds ?? 0
|
|
105490
105537
|
};
|
|
105491
105538
|
try {
|
|
105492
|
-
await mkdir9(
|
|
105539
|
+
await mkdir9(dirname11(statePath), { recursive: true });
|
|
105493
105540
|
await Bun.write(statePath, JSON.stringify({ ...stateObj, confirmation: nextConfirmation }, null, 2) + `
|
|
105494
105541
|
`);
|
|
105495
105542
|
} catch (err) {
|
|
@@ -105811,7 +105858,10 @@ var init_runners = __esm(() => {
|
|
|
105811
105858
|
const stderr = await new Response(proc.stderr).text();
|
|
105812
105859
|
const code = await proc.exited;
|
|
105813
105860
|
if (code !== 0) {
|
|
105814
|
-
const
|
|
105861
|
+
const firstStderrLine = stderr.trim().split(`
|
|
105862
|
+
`)[0] ?? "";
|
|
105863
|
+
const summary = firstStderrLine ? `: ${firstStderrLine}` : "";
|
|
105864
|
+
const err = new Error(`git \`${args.join(" ")}\` failed${summary}`);
|
|
105815
105865
|
err.stderr = stderr;
|
|
105816
105866
|
err.code = code;
|
|
105817
105867
|
throw err;
|
|
@@ -106493,17 +106543,17 @@ var init_pr_discovery = __esm(() => {
|
|
|
106493
106543
|
});
|
|
106494
106544
|
|
|
106495
106545
|
// apps/agent/src/features/review-followup/scan.ts
|
|
106496
|
-
import { dirname as
|
|
106546
|
+
import { dirname as dirname12, join as join26 } from "path";
|
|
106497
106547
|
async function resolveReviewStateDir(changeName, deps) {
|
|
106498
106548
|
const root = deps.cwdOf(changeName);
|
|
106499
106549
|
if (root)
|
|
106500
|
-
return
|
|
106550
|
+
return dirname12(projectLayout(root).stateFile(changeName));
|
|
106501
106551
|
if (!deps.useWorktree)
|
|
106502
|
-
return
|
|
106552
|
+
return dirname12(projectLayout(deps.projectRoot).stateFile(changeName));
|
|
106503
106553
|
const wtPath = join26(worktreesDir2(deps.projectRoot), changeName);
|
|
106504
106554
|
const statePath = projectLayout(wtPath).stateFile(changeName);
|
|
106505
106555
|
if (await Bun.file(statePath).exists())
|
|
106506
|
-
return
|
|
106556
|
+
return dirname12(statePath);
|
|
106507
106557
|
return null;
|
|
106508
106558
|
}
|
|
106509
106559
|
async function readReviewWatermark(stateDir) {
|
|
@@ -107541,8 +107591,8 @@ var init_linear_sync = __esm(() => {
|
|
|
107541
107591
|
});
|
|
107542
107592
|
|
|
107543
107593
|
// apps/agent/src/agent/linear-sync/comment-sync.ts
|
|
107544
|
-
import { dirname as
|
|
107545
|
-
import { mkdir as mkdir11 } from "fs/promises";
|
|
107594
|
+
import { dirname as dirname13, join as join30 } from "path";
|
|
107595
|
+
import { mkdir as mkdir11, rename, unlink as unlink2 } from "fs/promises";
|
|
107546
107596
|
async function readStateJson(statePath) {
|
|
107547
107597
|
const file2 = Bun.file(statePath);
|
|
107548
107598
|
if (!await file2.exists())
|
|
@@ -107554,9 +107604,16 @@ async function readStateJson(statePath) {
|
|
|
107554
107604
|
}
|
|
107555
107605
|
}
|
|
107556
107606
|
async function writeStateJson(statePath, state) {
|
|
107557
|
-
await mkdir11(
|
|
107558
|
-
|
|
107607
|
+
await mkdir11(dirname13(statePath), { recursive: true });
|
|
107608
|
+
const tmp = `${statePath}.tmp-${process.pid}-${writeStateSeq++}`;
|
|
107609
|
+
try {
|
|
107610
|
+
await Bun.write(tmp, JSON.stringify(state, null, 2) + `
|
|
107559
107611
|
`);
|
|
107612
|
+
await rename(tmp, statePath);
|
|
107613
|
+
} catch (err) {
|
|
107614
|
+
await unlink2(tmp).catch(() => {});
|
|
107615
|
+
throw err;
|
|
107616
|
+
}
|
|
107560
107617
|
}
|
|
107561
107618
|
function readComments(state) {
|
|
107562
107619
|
const raw = state?.linearComments ?? {};
|
|
@@ -107763,7 +107820,7 @@ ${deps.message.trim()}`;
|
|
|
107763
107820
|
iteration: deps.iteration
|
|
107764
107821
|
});
|
|
107765
107822
|
}
|
|
107766
|
-
var PLAN_COMMENT_TITLE = "\uD83D\uDCCB Ralph plan", STEERING_COMMENT_TITLE = "\uD83E\uDDED Ralph steering";
|
|
107823
|
+
var PLAN_COMMENT_TITLE = "\uD83D\uDCCB Ralph plan", STEERING_COMMENT_TITLE = "\uD83E\uDDED Ralph steering", writeStateSeq = 0;
|
|
107767
107824
|
var init_comment_sync = __esm(() => {
|
|
107768
107825
|
init_linear_sync();
|
|
107769
107826
|
});
|
|
@@ -259977,7 +260034,7 @@ var init_render_pdf = __esm(() => {
|
|
|
259977
260034
|
});
|
|
259978
260035
|
|
|
259979
260036
|
// apps/agent/src/agent/linear-sync/spec-attachments.ts
|
|
259980
|
-
import { dirname as
|
|
260037
|
+
import { dirname as dirname14, join as join31 } from "path";
|
|
259981
260038
|
function describeLinearError(err) {
|
|
259982
260039
|
const e = err;
|
|
259983
260040
|
const parts = [e.message ?? String(err)];
|
|
@@ -259992,7 +260049,7 @@ function describeLinearError(err) {
|
|
|
259992
260049
|
return parts.join(" ");
|
|
259993
260050
|
}
|
|
259994
260051
|
function stateDirOf(statePath) {
|
|
259995
|
-
return
|
|
260052
|
+
return dirname14(statePath);
|
|
259996
260053
|
}
|
|
259997
260054
|
async function readRawState(statePath) {
|
|
259998
260055
|
const file2 = Bun.file(statePath);
|
|
@@ -260251,7 +260308,9 @@ var init_spec_attachments = __esm(() => {
|
|
|
260251
260308
|
// apps/agent/src/agent/wire/comment-sync.ts
|
|
260252
260309
|
function createCommentSyncHooks(input) {
|
|
260253
260310
|
const { apiKey, cfg, projectRoot, onLog, diag, cwdByChange, issueByChange } = input;
|
|
260254
|
-
const
|
|
260311
|
+
const commentsEnabled = Boolean(cfg.linear.syncTasksToComment && apiKey);
|
|
260312
|
+
const specAttachmentsEnabled = Boolean(cfg.linear.syncSpecsAsAttachments && apiKey);
|
|
260313
|
+
const enabled2 = commentsEnabled || specAttachmentsEnabled;
|
|
260255
260314
|
if (!enabled2)
|
|
260256
260315
|
return { enabled: false };
|
|
260257
260316
|
const commentMutations = {
|
|
@@ -260265,7 +260324,6 @@ function createCommentSyncHooks(input) {
|
|
|
260265
260324
|
deleteAttachment,
|
|
260266
260325
|
findIssueAttachmentByTitle
|
|
260267
260326
|
};
|
|
260268
|
-
const specAttachmentsEnabled = Boolean(cfg.linear.syncSpecsAsAttachments);
|
|
260269
260327
|
return {
|
|
260270
260328
|
enabled: enabled2,
|
|
260271
260329
|
syncTasks: async (worker, iteration) => {
|
|
@@ -260273,27 +260331,29 @@ function createCommentSyncHooks(input) {
|
|
|
260273
260331
|
const layout = projectLayout(root);
|
|
260274
260332
|
const changeDir = layout.changeDir(worker.changeName);
|
|
260275
260333
|
const statePath = layout.stateFile(worker.changeName);
|
|
260276
|
-
if (
|
|
260277
|
-
|
|
260334
|
+
if (commentsEnabled) {
|
|
260335
|
+
if (!specAttachmentsEnabled) {
|
|
260336
|
+
await postPlanCommentOnce({
|
|
260337
|
+
apiKey,
|
|
260338
|
+
issueId: worker.issueId,
|
|
260339
|
+
statePath,
|
|
260340
|
+
changeDir,
|
|
260341
|
+
changeName: worker.changeName,
|
|
260342
|
+
log: onLog,
|
|
260343
|
+
mutations: commentMutations
|
|
260344
|
+
});
|
|
260345
|
+
}
|
|
260346
|
+
await postOrUpdateTasksComment({
|
|
260278
260347
|
apiKey,
|
|
260279
260348
|
issueId: worker.issueId,
|
|
260280
260349
|
statePath,
|
|
260281
260350
|
changeDir,
|
|
260282
260351
|
changeName: worker.changeName,
|
|
260352
|
+
iteration,
|
|
260283
260353
|
log: onLog,
|
|
260284
260354
|
mutations: commentMutations
|
|
260285
260355
|
});
|
|
260286
260356
|
}
|
|
260287
|
-
await postOrUpdateTasksComment({
|
|
260288
|
-
apiKey,
|
|
260289
|
-
issueId: worker.issueId,
|
|
260290
|
-
statePath,
|
|
260291
|
-
changeDir,
|
|
260292
|
-
changeName: worker.changeName,
|
|
260293
|
-
iteration,
|
|
260294
|
-
log: onLog,
|
|
260295
|
-
mutations: commentMutations
|
|
260296
|
-
});
|
|
260297
260357
|
if (specAttachmentsEnabled) {
|
|
260298
260358
|
await syncSpecAttachments({
|
|
260299
260359
|
apiKey,
|
|
@@ -260307,37 +260367,39 @@ function createCommentSyncHooks(input) {
|
|
|
260307
260367
|
});
|
|
260308
260368
|
}
|
|
260309
260369
|
},
|
|
260310
|
-
|
|
260311
|
-
|
|
260312
|
-
|
|
260313
|
-
|
|
260314
|
-
|
|
260315
|
-
|
|
260316
|
-
|
|
260317
|
-
|
|
260318
|
-
|
|
260319
|
-
|
|
260320
|
-
|
|
260321
|
-
let iteration = 0;
|
|
260322
|
-
try {
|
|
260323
|
-
const f2 = Bun.file(statePath);
|
|
260324
|
-
if (await f2.exists()) {
|
|
260325
|
-
const json2 = await f2.json();
|
|
260326
|
-
iteration = json2.iteration ?? 0;
|
|
260370
|
+
...commentsEnabled ? {
|
|
260371
|
+
onSteeringAppended: async (changeName, message) => {
|
|
260372
|
+
const root = cwdByChange.get(changeName) ?? projectRoot;
|
|
260373
|
+
const layout = projectLayout(root);
|
|
260374
|
+
const changeDir = layout.changeDir(changeName);
|
|
260375
|
+
const statePath = layout.stateFile(changeName);
|
|
260376
|
+
const issue2 = issueByChange.get(changeName) ?? null;
|
|
260377
|
+
const issueId = issue2?.id ?? null;
|
|
260378
|
+
if (!issueId) {
|
|
260379
|
+
diag("comment-sync", ` comment-sync: no Linear issue cached for ${changeName}; skipping steering refresh`, "gray");
|
|
260380
|
+
return;
|
|
260327
260381
|
}
|
|
260328
|
-
|
|
260329
|
-
|
|
260330
|
-
|
|
260331
|
-
|
|
260332
|
-
|
|
260333
|
-
|
|
260334
|
-
|
|
260335
|
-
|
|
260336
|
-
|
|
260337
|
-
|
|
260338
|
-
|
|
260339
|
-
|
|
260340
|
-
|
|
260382
|
+
let iteration = 0;
|
|
260383
|
+
try {
|
|
260384
|
+
const f2 = Bun.file(statePath);
|
|
260385
|
+
if (await f2.exists()) {
|
|
260386
|
+
const json2 = await f2.json();
|
|
260387
|
+
iteration = json2.iteration ?? 0;
|
|
260388
|
+
}
|
|
260389
|
+
} catch {}
|
|
260390
|
+
await postSteeringAndRefreshTasks({
|
|
260391
|
+
apiKey,
|
|
260392
|
+
issueId,
|
|
260393
|
+
statePath,
|
|
260394
|
+
changeDir,
|
|
260395
|
+
changeName,
|
|
260396
|
+
iteration,
|
|
260397
|
+
message,
|
|
260398
|
+
log: onLog,
|
|
260399
|
+
mutations: commentMutations
|
|
260400
|
+
});
|
|
260401
|
+
}
|
|
260402
|
+
} : {}
|
|
260341
260403
|
};
|
|
260342
260404
|
}
|
|
260343
260405
|
var init_comment_sync2 = __esm(() => {
|
|
@@ -260697,7 +260759,19 @@ function buildAgentCoordinator(input) {
|
|
|
260697
260759
|
pollInterval,
|
|
260698
260760
|
getWorkerCwd: (changeName) => cwdByChange.get(changeName),
|
|
260699
260761
|
syncTasksEnabled: commentSync.enabled,
|
|
260700
|
-
runBaselineGate: runBaselineGateOnce
|
|
260762
|
+
runBaselineGate: runBaselineGateOnce,
|
|
260763
|
+
getGaveUpTotal: async () => {
|
|
260764
|
+
let total = 0;
|
|
260765
|
+
for (const [changeName, root] of cwdByChange) {
|
|
260766
|
+
const file2 = Bun.file(join33(projectLayout(root).taskStateDir(changeName), GAVEUP_COUNT_FILE));
|
|
260767
|
+
if (!await file2.exists())
|
|
260768
|
+
continue;
|
|
260769
|
+
try {
|
|
260770
|
+
total += Number.parseInt(await file2.text(), 10) || 0;
|
|
260771
|
+
} catch {}
|
|
260772
|
+
}
|
|
260773
|
+
return total;
|
|
260774
|
+
}
|
|
260701
260775
|
};
|
|
260702
260776
|
}
|
|
260703
260777
|
var init_wire = __esm(() => {
|
|
@@ -260723,19 +260797,19 @@ var init_wire = __esm(() => {
|
|
|
260723
260797
|
|
|
260724
260798
|
// apps/agent/src/agent/json-log/json-log-file.ts
|
|
260725
260799
|
import { mkdir as mkdir12, appendFile as appendFile2 } from "fs/promises";
|
|
260726
|
-
import { dirname as
|
|
260800
|
+
import { dirname as dirname15 } from "path";
|
|
260727
260801
|
function createJsonLogFileSink(path) {
|
|
260728
260802
|
if (!path)
|
|
260729
260803
|
return { emit: () => {} };
|
|
260730
260804
|
let chain2 = (async () => {
|
|
260731
260805
|
try {
|
|
260732
|
-
await mkdir12(
|
|
260806
|
+
await mkdir12(dirname15(path), { recursive: true });
|
|
260733
260807
|
await Bun.write(path, "");
|
|
260734
260808
|
} catch {}
|
|
260735
260809
|
})();
|
|
260736
260810
|
return {
|
|
260737
260811
|
emit(event) {
|
|
260738
|
-
const line = JSON.stringify({ ts: Date.now(), ...event }) + `
|
|
260812
|
+
const line = JSON.stringify({ ts: Date.now(), v: VERSION, ...event }) + `
|
|
260739
260813
|
`;
|
|
260740
260814
|
chain2 = chain2.then(async () => {
|
|
260741
260815
|
try {
|
|
@@ -260745,7 +260819,9 @@ function createJsonLogFileSink(path) {
|
|
|
260745
260819
|
}
|
|
260746
260820
|
};
|
|
260747
260821
|
}
|
|
260748
|
-
var init_json_log_file = () => {
|
|
260822
|
+
var init_json_log_file = __esm(() => {
|
|
260823
|
+
init_version();
|
|
260824
|
+
});
|
|
260749
260825
|
|
|
260750
260826
|
// apps/agent/src/runtime/shutdown.ts
|
|
260751
260827
|
async function waitForActiveWorkers(deps) {
|
|
@@ -261323,6 +261399,7 @@ function AgentMode({
|
|
|
261323
261399
|
const [focusedIdx, setFocusedIdx] = import_react62.useState(0);
|
|
261324
261400
|
const [showPendingTasks, setShowPendingTasks] = import_react62.useState(false);
|
|
261325
261401
|
const [showAllSubtasks, setShowAllSubtasks] = import_react62.useState(false);
|
|
261402
|
+
const [gaveUpCount, setGaveUpCount] = import_react62.useState(0);
|
|
261326
261403
|
const coordRef = import_react62.useRef(null);
|
|
261327
261404
|
const workerMetaRef = import_react62.useRef(new Map);
|
|
261328
261405
|
const gatedTicketsRef = import_react62.useRef(new Map);
|
|
@@ -261373,7 +261450,7 @@ function AgentMode({
|
|
|
261373
261450
|
}, 100);
|
|
261374
261451
|
return;
|
|
261375
261452
|
}
|
|
261376
|
-
const { coord: coord2, filterDesc, concurrency, pollInterval, runBaselineGate: runBaselineGate2 } = buildCoordinator({
|
|
261453
|
+
const { coord: coord2, filterDesc, concurrency, pollInterval, runBaselineGate: runBaselineGate2, getGaveUpTotal } = buildCoordinator({
|
|
261377
261454
|
args,
|
|
261378
261455
|
cfg: cfg2,
|
|
261379
261456
|
projectRoot,
|
|
@@ -261519,6 +261596,12 @@ function AgentMode({
|
|
|
261519
261596
|
if (cancelled)
|
|
261520
261597
|
return;
|
|
261521
261598
|
fileEmit({ type: "poll_done", found, added, buckets, prStatus });
|
|
261599
|
+
getGaveUpTotal().then((total) => {
|
|
261600
|
+
if (!cancelled)
|
|
261601
|
+
setGaveUpCount(total);
|
|
261602
|
+
}).catch(() => {
|
|
261603
|
+
return;
|
|
261604
|
+
});
|
|
261522
261605
|
if (added > 0) {
|
|
261523
261606
|
appendLog(` ${added} new issue${added === 1 ? "" : "s"} queued (found ${found} open)`);
|
|
261524
261607
|
}
|
|
@@ -261830,7 +261913,14 @@ function AgentMode({
|
|
|
261830
261913
|
cfg.useWorktree && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
261831
261914
|
color: "green",
|
|
261832
261915
|
children: " \u25CF worktree"
|
|
261833
|
-
}, undefined, false, undefined, this)
|
|
261916
|
+
}, undefined, false, undefined, this),
|
|
261917
|
+
gaveUpCount > 0 && /* @__PURE__ */ jsx_dev_runtime11.jsxDEV(Text, {
|
|
261918
|
+
color: "red",
|
|
261919
|
+
children: [
|
|
261920
|
+
" \u2502 gave-up \xD7",
|
|
261921
|
+
gaveUpCount
|
|
261922
|
+
]
|
|
261923
|
+
}, undefined, true, undefined, this)
|
|
261834
261924
|
]
|
|
261835
261925
|
}, undefined, true, undefined, this)
|
|
261836
261926
|
]
|