@neriros/ralphy 3.0.1 → 3.1.0
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/README.md +29 -0
- package/dist/shell/index.js +1764 -474
- package/package.json +1 -1
package/dist/shell/index.js
CHANGED
|
@@ -18923,8 +18923,44 @@ var init_node = __esm(() => {
|
|
|
18923
18923
|
};
|
|
18924
18924
|
});
|
|
18925
18925
|
|
|
18926
|
+
// packages/version/src/version.ts
|
|
18927
|
+
import { readFileSync } from "fs";
|
|
18928
|
+
import { resolve } from "path";
|
|
18929
|
+
function getVersion() {
|
|
18930
|
+
try {
|
|
18931
|
+
if ("3.1.0")
|
|
18932
|
+
return "3.1.0";
|
|
18933
|
+
} catch {}
|
|
18934
|
+
const dirsToTry = [];
|
|
18935
|
+
try {
|
|
18936
|
+
dirsToTry.push(import.meta.dir);
|
|
18937
|
+
} catch {}
|
|
18938
|
+
dirsToTry.push(process.cwd());
|
|
18939
|
+
for (const startDir of dirsToTry) {
|
|
18940
|
+
let current = startDir;
|
|
18941
|
+
for (let i = 0;i < 10; i++) {
|
|
18942
|
+
const pkgPath = resolve(current, "package.json");
|
|
18943
|
+
try {
|
|
18944
|
+
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
18945
|
+
if (pkg.workspaces && pkg.version && pkg.version !== "0.0.0") {
|
|
18946
|
+
return pkg.version;
|
|
18947
|
+
}
|
|
18948
|
+
} catch {}
|
|
18949
|
+
const parent = resolve(current, "..");
|
|
18950
|
+
if (parent === current)
|
|
18951
|
+
break;
|
|
18952
|
+
current = parent;
|
|
18953
|
+
}
|
|
18954
|
+
}
|
|
18955
|
+
return "unknown";
|
|
18956
|
+
}
|
|
18957
|
+
var VERSION;
|
|
18958
|
+
var init_version = __esm(() => {
|
|
18959
|
+
VERSION = getVersion();
|
|
18960
|
+
});
|
|
18961
|
+
|
|
18926
18962
|
// packages/telemetry/src/index.ts
|
|
18927
|
-
import { homedir } from "os";
|
|
18963
|
+
import { homedir, hostname, platform, arch, release } from "os";
|
|
18928
18964
|
import { join } from "path";
|
|
18929
18965
|
import { randomUUID } from "crypto";
|
|
18930
18966
|
function setDefaultProperties(props) {
|
|
@@ -18946,6 +18982,23 @@ async function init() {
|
|
|
18946
18982
|
flushAt: 20,
|
|
18947
18983
|
flushInterval: 0
|
|
18948
18984
|
});
|
|
18985
|
+
defaultProps = {
|
|
18986
|
+
version: VERSION,
|
|
18987
|
+
machine_name: hostname(),
|
|
18988
|
+
platform: platform(),
|
|
18989
|
+
arch: arch(),
|
|
18990
|
+
os_release: release(),
|
|
18991
|
+
...defaultProps
|
|
18992
|
+
};
|
|
18993
|
+
}
|
|
18994
|
+
function captureError(event, error, properties) {
|
|
18995
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
18996
|
+
capture(event, {
|
|
18997
|
+
...properties,
|
|
18998
|
+
error_message: err.message,
|
|
18999
|
+
error_name: err.name,
|
|
19000
|
+
error_stack: err.stack
|
|
19001
|
+
});
|
|
18949
19002
|
}
|
|
18950
19003
|
function capture(event, properties) {
|
|
18951
19004
|
const merged = { ...defaultProps, ...properties };
|
|
@@ -18958,47 +19011,12 @@ async function shutdown() {
|
|
|
18958
19011
|
var POSTHOG_KEY, HOST = "https://eu.i.posthog.com", enabled, client = null, distinctId = "anonymous", defaultProps;
|
|
18959
19012
|
var init_src = __esm(() => {
|
|
18960
19013
|
init_node();
|
|
19014
|
+
init_version();
|
|
18961
19015
|
POSTHOG_KEY = process.env["RALPH_POSTHOG_KEY"] ?? "phc_Bua8TpmaxSSM8h43htLrm6VUoaB2L9GZgA4kiEcMrpaY";
|
|
18962
19016
|
enabled = process.env["RALPH_TELEMETRY"] !== "0";
|
|
18963
19017
|
defaultProps = {};
|
|
18964
19018
|
});
|
|
18965
19019
|
|
|
18966
|
-
// packages/version/src/version.ts
|
|
18967
|
-
import { readFileSync } from "fs";
|
|
18968
|
-
import { resolve } from "path";
|
|
18969
|
-
function getVersion() {
|
|
18970
|
-
try {
|
|
18971
|
-
if ("3.0.1")
|
|
18972
|
-
return "3.0.1";
|
|
18973
|
-
} catch {}
|
|
18974
|
-
const dirsToTry = [];
|
|
18975
|
-
try {
|
|
18976
|
-
dirsToTry.push(import.meta.dir);
|
|
18977
|
-
} catch {}
|
|
18978
|
-
dirsToTry.push(process.cwd());
|
|
18979
|
-
for (const startDir of dirsToTry) {
|
|
18980
|
-
let current = startDir;
|
|
18981
|
-
for (let i = 0;i < 10; i++) {
|
|
18982
|
-
const pkgPath = resolve(current, "package.json");
|
|
18983
|
-
try {
|
|
18984
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
18985
|
-
if (pkg.workspaces && pkg.version && pkg.version !== "0.0.0") {
|
|
18986
|
-
return pkg.version;
|
|
18987
|
-
}
|
|
18988
|
-
} catch {}
|
|
18989
|
-
const parent = resolve(current, "..");
|
|
18990
|
-
if (parent === current)
|
|
18991
|
-
break;
|
|
18992
|
-
current = parent;
|
|
18993
|
-
}
|
|
18994
|
-
}
|
|
18995
|
-
return "unknown";
|
|
18996
|
-
}
|
|
18997
|
-
var VERSION;
|
|
18998
|
-
var init_version = __esm(() => {
|
|
18999
|
-
VERSION = getVersion();
|
|
19000
|
-
});
|
|
19001
|
-
|
|
19002
19020
|
// node_modules/.bun/react@18.3.1/node_modules/react/cjs/react.development.js
|
|
19003
19021
|
var require_react_development = __commonJS((exports, module) => {
|
|
19004
19022
|
if (true) {
|
|
@@ -20939,7 +20957,7 @@ var init_compat = __esm(() => {
|
|
|
20939
20957
|
});
|
|
20940
20958
|
|
|
20941
20959
|
// node_modules/.bun/environment@1.1.0/node_modules/environment/index.js
|
|
20942
|
-
var isBrowser, isNode, isBun, isDeno, isElectron, isJsDom, isWebWorker, isDedicatedWorker, isSharedWorker, isServiceWorker,
|
|
20960
|
+
var isBrowser, isNode, isBun, isDeno, isElectron, isJsDom, isWebWorker, isDedicatedWorker, isSharedWorker, isServiceWorker, platform2, isMacOs, isWindows, isLinux, isIos, isAndroid;
|
|
20943
20961
|
var init_environment = __esm(() => {
|
|
20944
20962
|
isBrowser = globalThis.window?.document !== undefined;
|
|
20945
20963
|
isNode = globalThis.process?.versions?.node !== undefined;
|
|
@@ -20951,12 +20969,12 @@ var init_environment = __esm(() => {
|
|
|
20951
20969
|
isDedicatedWorker = typeof DedicatedWorkerGlobalScope !== "undefined" && globalThis instanceof DedicatedWorkerGlobalScope;
|
|
20952
20970
|
isSharedWorker = typeof SharedWorkerGlobalScope !== "undefined" && globalThis instanceof SharedWorkerGlobalScope;
|
|
20953
20971
|
isServiceWorker = typeof ServiceWorkerGlobalScope !== "undefined" && globalThis instanceof ServiceWorkerGlobalScope;
|
|
20954
|
-
|
|
20955
|
-
isMacOs =
|
|
20956
|
-
isWindows =
|
|
20957
|
-
isLinux =
|
|
20958
|
-
isIos =
|
|
20959
|
-
isAndroid =
|
|
20972
|
+
platform2 = globalThis.navigator?.userAgentData?.platform;
|
|
20973
|
+
isMacOs = platform2 === "macOS" || globalThis.navigator?.platform === "MacIntel" || globalThis.navigator?.userAgent?.includes(" Mac ") === true || globalThis.process?.platform === "darwin";
|
|
20974
|
+
isWindows = platform2 === "Windows" || globalThis.navigator?.platform === "Win32" || globalThis.process?.platform === "win32";
|
|
20975
|
+
isLinux = platform2 === "Linux" || globalThis.navigator?.platform?.startsWith("Linux") === true || globalThis.navigator?.userAgent?.includes(" Linux ") === true || globalThis.process?.platform === "linux";
|
|
20976
|
+
isIos = platform2 === "iOS" || globalThis.navigator?.platform === "MacIntel" && globalThis.navigator?.maxTouchPoints > 1 || /iPad|iPhone|iPod/.test(globalThis.navigator?.platform);
|
|
20977
|
+
isAndroid = platform2 === "Android" || globalThis.navigator?.platform === "Android" || globalThis.navigator?.userAgent?.includes(" Android ") === true || globalThis.process?.platform === "android";
|
|
20960
20978
|
});
|
|
20961
20979
|
|
|
20962
20980
|
// node_modules/.bun/ansi-escapes@7.3.0/node_modules/ansi-escapes/base.js
|
|
@@ -68777,6 +68795,41 @@ var init_FeedLine = __esm(async () => {
|
|
|
68777
68795
|
};
|
|
68778
68796
|
});
|
|
68779
68797
|
|
|
68798
|
+
// apps/loop/src/hooks/useTerminalSize.ts
|
|
68799
|
+
function readSize() {
|
|
68800
|
+
return {
|
|
68801
|
+
columns: process.stdout.columns ?? 80,
|
|
68802
|
+
rows: process.stdout.rows ?? 24
|
|
68803
|
+
};
|
|
68804
|
+
}
|
|
68805
|
+
function useTerminalSize() {
|
|
68806
|
+
const [size2, setSize] = import_react53.useState(() => ({
|
|
68807
|
+
...readSize(),
|
|
68808
|
+
resizeKey: 0
|
|
68809
|
+
}));
|
|
68810
|
+
import_react53.useEffect(() => {
|
|
68811
|
+
if (!process.stdout.isTTY)
|
|
68812
|
+
return;
|
|
68813
|
+
const onResize = () => {
|
|
68814
|
+
const { columns, rows } = readSize();
|
|
68815
|
+
setSize((prev) => {
|
|
68816
|
+
if (prev.columns === columns && prev.rows === rows)
|
|
68817
|
+
return prev;
|
|
68818
|
+
return { columns, rows, resizeKey: prev.resizeKey + 1 };
|
|
68819
|
+
});
|
|
68820
|
+
};
|
|
68821
|
+
process.stdout.on("resize", onResize);
|
|
68822
|
+
return () => {
|
|
68823
|
+
process.stdout.off("resize", onResize);
|
|
68824
|
+
};
|
|
68825
|
+
}, []);
|
|
68826
|
+
return size2;
|
|
68827
|
+
}
|
|
68828
|
+
var import_react53;
|
|
68829
|
+
var init_useTerminalSize = __esm(() => {
|
|
68830
|
+
import_react53 = __toESM(require_react(), 1);
|
|
68831
|
+
});
|
|
68832
|
+
|
|
68780
68833
|
// apps/loop/src/components/StatusBar.tsx
|
|
68781
68834
|
function formatElapsed(ms) {
|
|
68782
68835
|
const totalSec = Math.floor(ms / 1000);
|
|
@@ -68803,14 +68856,16 @@ function StatusBar({
|
|
|
68803
68856
|
model,
|
|
68804
68857
|
isRunning
|
|
68805
68858
|
}) {
|
|
68806
|
-
const [elapsed, setElapsed] =
|
|
68807
|
-
|
|
68859
|
+
const [elapsed, setElapsed] = import_react54.useState(0);
|
|
68860
|
+
import_react54.useEffect(() => {
|
|
68808
68861
|
if (!isRunning)
|
|
68809
68862
|
return;
|
|
68810
68863
|
const id = setInterval(() => setElapsed(Date.now() - startedAt), 1000);
|
|
68811
68864
|
return () => clearInterval(id);
|
|
68812
68865
|
}, [isRunning, startedAt]);
|
|
68813
|
-
const
|
|
68866
|
+
const { columns } = useTerminalSize();
|
|
68867
|
+
const barWidth = Math.max(8, Math.min(52, columns));
|
|
68868
|
+
const bar = "\u2500".repeat(barWidth);
|
|
68814
68869
|
return /* @__PURE__ */ jsx_dev_runtime5.jsxDEV(Box_default, {
|
|
68815
68870
|
flexDirection: "column",
|
|
68816
68871
|
children: [
|
|
@@ -68874,13 +68929,14 @@ function StatusBar({
|
|
|
68874
68929
|
]
|
|
68875
68930
|
}, undefined, true, undefined, this);
|
|
68876
68931
|
}
|
|
68877
|
-
var
|
|
68932
|
+
var import_react54, jsx_dev_runtime5;
|
|
68878
68933
|
var init_StatusBar = __esm(async () => {
|
|
68934
|
+
init_useTerminalSize();
|
|
68879
68935
|
await __promiseAll([
|
|
68880
68936
|
init_build2(),
|
|
68881
68937
|
init_build3()
|
|
68882
68938
|
]);
|
|
68883
|
-
|
|
68939
|
+
import_react54 = __toESM(require_react(), 1);
|
|
68884
68940
|
jsx_dev_runtime5 = __toESM(require_jsx_dev_runtime(), 1);
|
|
68885
68941
|
});
|
|
68886
68942
|
|
|
@@ -69137,7 +69193,7 @@ var init_spawn = __esm(() => {
|
|
|
69137
69193
|
});
|
|
69138
69194
|
|
|
69139
69195
|
// packages/engine/src/formatters/claude-stream.ts
|
|
69140
|
-
function extractToolInputSummary(input) {
|
|
69196
|
+
function extractToolInputSummary(input, maxWidth) {
|
|
69141
69197
|
if (typeof input.file_path === "string") {
|
|
69142
69198
|
return { kind: "file", name: input.file_path.split("/").pop() ?? input.file_path };
|
|
69143
69199
|
}
|
|
@@ -69169,14 +69225,16 @@ function extractToolInputSummary(input) {
|
|
|
69169
69225
|
const keys2 = Object.keys(input);
|
|
69170
69226
|
if (keys2.length === 0)
|
|
69171
69227
|
return;
|
|
69228
|
+
const budget = maxWidth && maxWidth > 0 ? Math.max(80, maxWidth - PREFIX_PADDING) : LEGACY_BUDGET;
|
|
69229
|
+
const valueCap = maxWidth && maxWidth > 0 ? Math.max(LEGACY_VALUE_CAP, Math.floor(budget / 3)) : LEGACY_VALUE_CAP;
|
|
69172
69230
|
const parts = [];
|
|
69173
69231
|
let len = 0;
|
|
69174
69232
|
for (const k of keys2) {
|
|
69175
69233
|
const v = input[k];
|
|
69176
69234
|
const val = typeof v === "string" ? v : JSON.stringify(v);
|
|
69177
|
-
const short = val.length >
|
|
69235
|
+
const short = val.length > valueCap ? val.slice(0, valueCap) + "\u2026" : val;
|
|
69178
69236
|
const part = `${k}=${short}`;
|
|
69179
|
-
if (len + part.length >
|
|
69237
|
+
if (len + part.length > budget)
|
|
69180
69238
|
break;
|
|
69181
69239
|
parts.push(part);
|
|
69182
69240
|
len += part.length + 2;
|
|
@@ -69195,7 +69253,7 @@ function extractUsage(event) {
|
|
|
69195
69253
|
cache_creation_input_tokens: usage.cache_creation_input_tokens ?? 0
|
|
69196
69254
|
};
|
|
69197
69255
|
}
|
|
69198
|
-
function parseClaudeLine(line, state) {
|
|
69256
|
+
function parseClaudeLine(line, state, options) {
|
|
69199
69257
|
if (!line.trim())
|
|
69200
69258
|
return [];
|
|
69201
69259
|
let event;
|
|
@@ -69248,7 +69306,7 @@ function parseClaudeLine(line, state) {
|
|
|
69248
69306
|
} else if (btype === "tool_use") {
|
|
69249
69307
|
state.toolCount++;
|
|
69250
69308
|
const name = block.name ?? "?";
|
|
69251
|
-
const summary = extractToolInputSummary(block.input ?? {});
|
|
69309
|
+
const summary = extractToolInputSummary(block.input ?? {}, options?.maxWidth);
|
|
69252
69310
|
const ev = { type: "tool-start", name };
|
|
69253
69311
|
if (summary)
|
|
69254
69312
|
ev.summary = summary;
|
|
@@ -69325,6 +69383,7 @@ function parseClaudeLine(line, state) {
|
|
|
69325
69383
|
}
|
|
69326
69384
|
return events;
|
|
69327
69385
|
}
|
|
69386
|
+
var LEGACY_BUDGET = 120, LEGACY_VALUE_CAP = 40, PREFIX_PADDING = 20;
|
|
69328
69387
|
|
|
69329
69388
|
// packages/engine/src/agents/stream.ts
|
|
69330
69389
|
async function* streamLines(stream) {
|
|
@@ -69452,6 +69511,7 @@ var init_claude = __esm(() => {
|
|
|
69452
69511
|
let sessionId = null;
|
|
69453
69512
|
let detectedRateLimit = false;
|
|
69454
69513
|
const stdout = proc.stdout;
|
|
69514
|
+
const parseOptions = process.stdout.isTTY && process.stdout.columns ? { maxWidth: process.stdout.columns } : undefined;
|
|
69455
69515
|
for await (const line of streamLines(stdout)) {
|
|
69456
69516
|
req.onRawLine?.(line);
|
|
69457
69517
|
if (sessionId === null) {
|
|
@@ -69462,7 +69522,7 @@ var init_claude = __esm(() => {
|
|
|
69462
69522
|
}
|
|
69463
69523
|
} catch {}
|
|
69464
69524
|
}
|
|
69465
|
-
for (const event of parseClaudeLine(line, claudeState)) {
|
|
69525
|
+
for (const event of parseClaudeLine(line, claudeState, parseOptions)) {
|
|
69466
69526
|
if (event.type === "text" && isRateLimitText(event.text)) {
|
|
69467
69527
|
detectedRateLimit = true;
|
|
69468
69528
|
}
|
|
@@ -70117,6 +70177,10 @@ function commitTaskDir(taskDir, message) {
|
|
|
70117
70177
|
var init_git = () => {};
|
|
70118
70178
|
|
|
70119
70179
|
// packages/core/src/tasks-md.ts
|
|
70180
|
+
function isFlowTaskHeading(heading) {
|
|
70181
|
+
const stripped = heading.replace(/\s*\([^()]*\)\s*$/, "").trim();
|
|
70182
|
+
return FLOW_TASK_HEADING_PREFIXES.some((p) => stripped.startsWith(p));
|
|
70183
|
+
}
|
|
70120
70184
|
function firstUnchecked(tasksContent) {
|
|
70121
70185
|
const sections = tasksContent.split(/(?=^## )/m);
|
|
70122
70186
|
for (const section of sections) {
|
|
@@ -70159,6 +70223,18 @@ ${failureOutput.trim()}
|
|
|
70159
70223
|
${fence}`;
|
|
70160
70224
|
await Bun.write(tasksPath, prependSection(existing, stamped, body));
|
|
70161
70225
|
}
|
|
70226
|
+
var MISSION_TASKS_FILENAME = "tasks.md", AGENT_TASKS_FILENAME = "agent-tasks.md", FLOW_TASK_HEADING_PREFIXES;
|
|
70227
|
+
var init_tasks_md = __esm(() => {
|
|
70228
|
+
FLOW_TASK_HEADING_PREFIXES = [
|
|
70229
|
+
"Fix failing CI checks",
|
|
70230
|
+
"Fix push rejection",
|
|
70231
|
+
"Resolve PR merge conflicts",
|
|
70232
|
+
"Resolve merge conflict with origin/",
|
|
70233
|
+
"Address reviewer comments",
|
|
70234
|
+
"Address GitHub @ralphy mention",
|
|
70235
|
+
"Address Linear @ralphy mention"
|
|
70236
|
+
];
|
|
70237
|
+
});
|
|
70162
70238
|
|
|
70163
70239
|
// packages/core/src/loop.ts
|
|
70164
70240
|
import { join as join10 } from "path";
|
|
@@ -70184,9 +70260,21 @@ function buildTaskPrompt(state, taskDir) {
|
|
|
70184
70260
|
`;
|
|
70185
70261
|
}
|
|
70186
70262
|
}
|
|
70187
|
-
const
|
|
70188
|
-
|
|
70189
|
-
|
|
70263
|
+
const agentTasksPath = join10(taskDir, AGENT_TASKS_FILENAME);
|
|
70264
|
+
const missionTasksPath = join10(taskDir, MISSION_TASKS_FILENAME);
|
|
70265
|
+
const agentTasksContent = storage.read(agentTasksPath);
|
|
70266
|
+
const missionTasksContent = storage.read(missionTasksPath);
|
|
70267
|
+
let activePath = null;
|
|
70268
|
+
let activeContent = null;
|
|
70269
|
+
if (agentTasksContent !== null && /^- \[ \]/m.test(agentTasksContent)) {
|
|
70270
|
+
activePath = agentTasksPath;
|
|
70271
|
+
activeContent = agentTasksContent;
|
|
70272
|
+
} else if (missionTasksContent !== null) {
|
|
70273
|
+
activePath = missionTasksPath;
|
|
70274
|
+
activeContent = missionTasksContent;
|
|
70275
|
+
}
|
|
70276
|
+
if (activeContent !== null && activePath !== null) {
|
|
70277
|
+
const section = firstUnchecked(activeContent);
|
|
70190
70278
|
if (section) {
|
|
70191
70279
|
prompt += `---
|
|
70192
70280
|
|
|
@@ -70199,7 +70287,7 @@ function buildTaskPrompt(state, taskDir) {
|
|
|
70199
70287
|
prompt += `---
|
|
70200
70288
|
|
|
70201
70289
|
`;
|
|
70202
|
-
prompt += `**Tracking progress**: as you finish each item above, edit ` + `\`${
|
|
70290
|
+
prompt += `**Tracking progress**: as you finish each item above, edit ` + `\`${activePath}\` and change its \`- [ ]\` to ` + `\`- [x]\` in the same commit. The loop reads this file between ` + `iterations and stops when no \`- [ ]\` items remain \u2014 if you do ` + `not tick the box, the next iteration will repeat this task.
|
|
70203
70291
|
|
|
70204
70292
|
`;
|
|
70205
70293
|
}
|
|
@@ -70220,10 +70308,11 @@ function buildTaskPrompt(state, taskDir) {
|
|
|
70220
70308
|
`;
|
|
70221
70309
|
}
|
|
70222
70310
|
if (state.manualTest) {
|
|
70223
|
-
const
|
|
70224
|
-
const
|
|
70225
|
-
|
|
70226
|
-
|
|
70311
|
+
const tasksContent = missionTasksContent;
|
|
70312
|
+
const hasUncheckedMission = tasksContent !== null && /^- \[ \]/m.test(tasksContent);
|
|
70313
|
+
const hasUncheckedAgent = agentTasksContent !== null && /^- \[ \]/m.test(agentTasksContent);
|
|
70314
|
+
if (!hasUncheckedMission && !hasUncheckedAgent) {
|
|
70315
|
+
const hasManualTestSection = tasksContent !== null && /^## Manual Testing/m.test(tasksContent);
|
|
70227
70316
|
if (!hasManualTestSection) {
|
|
70228
70317
|
prompt += `---
|
|
70229
70318
|
|
|
@@ -70379,11 +70468,14 @@ var STEERING_MAX_LINES = 20;
|
|
|
70379
70468
|
var init_loop = __esm(() => {
|
|
70380
70469
|
init_state();
|
|
70381
70470
|
init_context();
|
|
70471
|
+
init_tasks_md();
|
|
70472
|
+
init_tasks_md();
|
|
70382
70473
|
});
|
|
70383
70474
|
|
|
70384
70475
|
// apps/loop/src/loop.ts
|
|
70385
70476
|
var init_loop2 = __esm(() => {
|
|
70386
70477
|
init_loop();
|
|
70478
|
+
init_tasks_md();
|
|
70387
70479
|
});
|
|
70388
70480
|
|
|
70389
70481
|
// apps/loop/src/hooks/useLoop.ts
|
|
@@ -70392,22 +70484,22 @@ function sleep(seconds) {
|
|
|
70392
70484
|
return new Promise((resolve3) => setTimeout(resolve3, seconds * 1000));
|
|
70393
70485
|
}
|
|
70394
70486
|
function useLoop(opts) {
|
|
70395
|
-
const [state, setState] =
|
|
70396
|
-
const [iteration, setIteration] =
|
|
70397
|
-
const [consecutiveFailures, setConsecutiveFailures] =
|
|
70398
|
-
const [logLines, setLogLines] =
|
|
70399
|
-
const [stopReason, setStopReason] =
|
|
70400
|
-
const [isRunning, setIsRunning] =
|
|
70401
|
-
const [isResume, setIsResume] =
|
|
70402
|
-
const [startedAt] =
|
|
70403
|
-
const lineIdRef =
|
|
70404
|
-
const steerControllerRef =
|
|
70405
|
-
const pendingSteerRef =
|
|
70487
|
+
const [state, setState] = import_react55.useState(null);
|
|
70488
|
+
const [iteration, setIteration] = import_react55.useState(0);
|
|
70489
|
+
const [consecutiveFailures, setConsecutiveFailures] = import_react55.useState(0);
|
|
70490
|
+
const [logLines, setLogLines] = import_react55.useState([]);
|
|
70491
|
+
const [stopReason, setStopReason] = import_react55.useState(null);
|
|
70492
|
+
const [isRunning, setIsRunning] = import_react55.useState(true);
|
|
70493
|
+
const [isResume, setIsResume] = import_react55.useState(false);
|
|
70494
|
+
const [startedAt] = import_react55.useState(() => Date.now());
|
|
70495
|
+
const lineIdRef = import_react55.useRef(0);
|
|
70496
|
+
const steerControllerRef = import_react55.useRef(null);
|
|
70497
|
+
const pendingSteerRef = import_react55.useRef(null);
|
|
70406
70498
|
const steer = (message) => {
|
|
70407
70499
|
pendingSteerRef.current = message;
|
|
70408
70500
|
steerControllerRef.current?.abort();
|
|
70409
70501
|
};
|
|
70410
|
-
|
|
70502
|
+
import_react55.useEffect(() => {
|
|
70411
70503
|
let cancelled = false;
|
|
70412
70504
|
const nextId = () => String(lineIdRef.current++);
|
|
70413
70505
|
const addInfo = (text) => {
|
|
@@ -70471,15 +70563,24 @@ function useLoop(opts) {
|
|
|
70471
70563
|
const stop = checkStopCondition(currentState, iter, opts, loopStartTime, consFailures);
|
|
70472
70564
|
if (stop !== null) {
|
|
70473
70565
|
finalStopReason = stop;
|
|
70474
|
-
setStopReason(stop);
|
|
70475
70566
|
break;
|
|
70476
70567
|
}
|
|
70477
|
-
const tasksContent = storage.read(join11(tasksDir,
|
|
70568
|
+
const tasksContent = storage.read(join11(tasksDir, MISSION_TASKS_FILENAME));
|
|
70569
|
+
const agentTasksContent = storage.read(join11(tasksDir, AGENT_TASKS_FILENAME));
|
|
70478
70570
|
if (tasksContent !== null) {
|
|
70479
70571
|
const remaining = countUnchecked(tasksContent);
|
|
70480
|
-
|
|
70481
|
-
|
|
70482
|
-
|
|
70572
|
+
const agentRemaining = agentTasksContent !== null ? countUnchecked(agentTasksContent) : 0;
|
|
70573
|
+
const parts = [
|
|
70574
|
+
`tasks.md: ${remaining} unchecked item${remaining === 1 ? "" : "s"} remaining`
|
|
70575
|
+
];
|
|
70576
|
+
if (agentTasksContent !== null) {
|
|
70577
|
+
parts.push(`agent-tasks.md: ${agentRemaining} unchecked item${agentRemaining === 1 ? "" : "s"} remaining`);
|
|
70578
|
+
}
|
|
70579
|
+
addInfo(parts.join(" \xB7 "));
|
|
70580
|
+
}
|
|
70581
|
+
const missionDone = tasksContent !== null && allCompleted(tasksContent);
|
|
70582
|
+
const agentDone = agentTasksContent === null || allCompleted(agentTasksContent);
|
|
70583
|
+
if (missionDone && agentDone && tasksContent !== null) {
|
|
70483
70584
|
addInfo("All tasks completed \u2014 archiving change.");
|
|
70484
70585
|
currentState = {
|
|
70485
70586
|
...currentState,
|
|
@@ -70495,7 +70596,6 @@ function useLoop(opts) {
|
|
|
70495
70596
|
addInfo(`Archive warning: ${err}`);
|
|
70496
70597
|
}
|
|
70497
70598
|
finalStopReason = "completed";
|
|
70498
|
-
setStopReason("completed");
|
|
70499
70599
|
break;
|
|
70500
70600
|
}
|
|
70501
70601
|
iter++;
|
|
@@ -70555,7 +70655,6 @@ function useLoop(opts) {
|
|
|
70555
70655
|
if (failure.shouldStop || engineResult.rateLimited) {
|
|
70556
70656
|
capture("engine_rate_limited", { exit_code: engineResult.exitCode, iteration: iter });
|
|
70557
70657
|
finalStopReason = "rateLimited";
|
|
70558
|
-
setStopReason("rateLimited");
|
|
70559
70658
|
break;
|
|
70560
70659
|
}
|
|
70561
70660
|
capture("iteration_failed", {
|
|
@@ -70614,6 +70713,9 @@ function useLoop(opts) {
|
|
|
70614
70713
|
gitPush();
|
|
70615
70714
|
} catch {}
|
|
70616
70715
|
}
|
|
70716
|
+
if (finalStopReason !== null) {
|
|
70717
|
+
setStopReason(finalStopReason);
|
|
70718
|
+
}
|
|
70617
70719
|
setIsRunning(false);
|
|
70618
70720
|
});
|
|
70619
70721
|
return () => {
|
|
@@ -70632,7 +70734,7 @@ function useLoop(opts) {
|
|
|
70632
70734
|
steer
|
|
70633
70735
|
};
|
|
70634
70736
|
}
|
|
70635
|
-
var
|
|
70737
|
+
var import_react55;
|
|
70636
70738
|
var init_useLoop = __esm(() => {
|
|
70637
70739
|
init_state();
|
|
70638
70740
|
init_engine();
|
|
@@ -70640,7 +70742,7 @@ var init_useLoop = __esm(() => {
|
|
|
70640
70742
|
init_context();
|
|
70641
70743
|
init_src();
|
|
70642
70744
|
init_loop2();
|
|
70643
|
-
|
|
70745
|
+
import_react55 = __toESM(require_react(), 1);
|
|
70644
70746
|
});
|
|
70645
70747
|
|
|
70646
70748
|
// apps/loop/src/components/TaskLoop.tsx
|
|
@@ -70695,10 +70797,10 @@ function handleSteerKeyInput(key, history, currentIndex) {
|
|
|
70695
70797
|
return navigateHistory(history, currentIndex, dir);
|
|
70696
70798
|
}
|
|
70697
70799
|
function SteerInput({ onSubmit }) {
|
|
70698
|
-
const [inputKey, setInputKey] =
|
|
70699
|
-
const [defaultValue, setDefaultValue] =
|
|
70700
|
-
const historyRef =
|
|
70701
|
-
const historyIndexRef =
|
|
70800
|
+
const [inputKey, setInputKey] = import_react56.useState(0);
|
|
70801
|
+
const [defaultValue, setDefaultValue] = import_react56.useState("");
|
|
70802
|
+
const historyRef = import_react56.useRef([]);
|
|
70803
|
+
const historyIndexRef = import_react56.useRef(-1);
|
|
70702
70804
|
use_input_default((_input, key) => {
|
|
70703
70805
|
const result2 = handleSteerKeyInput(key, historyRef.current, historyIndexRef.current);
|
|
70704
70806
|
if (result2) {
|
|
@@ -70730,12 +70832,19 @@ function TaskLoop({ opts }) {
|
|
|
70730
70832
|
const { exit } = use_app_default();
|
|
70731
70833
|
const loop = useLoop(opts);
|
|
70732
70834
|
const { isRawModeSupported } = use_stdin_default();
|
|
70733
|
-
const
|
|
70734
|
-
const
|
|
70835
|
+
const { stdout } = use_stdout_default();
|
|
70836
|
+
const { resizeKey } = useTerminalSize();
|
|
70837
|
+
const bannerItem = import_react56.useRef({ id: "__banner__", kind: "banner" });
|
|
70838
|
+
import_react56.useEffect(() => {
|
|
70839
|
+
if (resizeKey === 0)
|
|
70840
|
+
return;
|
|
70841
|
+
stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
70842
|
+
}, [resizeKey, stdout]);
|
|
70843
|
+
const feedItems = import_react56.useMemo(() => [
|
|
70735
70844
|
bannerItem.current,
|
|
70736
70845
|
...loop.logLines.map((e) => ({ id: e.id, kind: "entry", entry: e }))
|
|
70737
70846
|
], [loop.logLines]);
|
|
70738
|
-
|
|
70847
|
+
import_react56.useEffect(() => {
|
|
70739
70848
|
if (!loop.isRunning) {
|
|
70740
70849
|
exit();
|
|
70741
70850
|
}
|
|
@@ -70783,7 +70892,7 @@ function TaskLoop({ opts }) {
|
|
|
70783
70892
|
}, undefined, false, undefined, this)
|
|
70784
70893
|
]
|
|
70785
70894
|
}, undefined, true, undefined, this),
|
|
70786
|
-
loop.stopReason && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(jsx_dev_runtime7.Fragment, {
|
|
70895
|
+
!loop.isRunning && loop.stopReason && /* @__PURE__ */ jsx_dev_runtime7.jsxDEV(jsx_dev_runtime7.Fragment, {
|
|
70787
70896
|
children: [
|
|
70788
70897
|
/* @__PURE__ */ jsx_dev_runtime7.jsxDEV(StatusBar, {
|
|
70789
70898
|
iteration: loop.iteration,
|
|
@@ -70805,11 +70914,12 @@ function TaskLoop({ opts }) {
|
|
|
70805
70914
|
]
|
|
70806
70915
|
}, undefined, true, undefined, this)
|
|
70807
70916
|
]
|
|
70808
|
-
},
|
|
70917
|
+
}, resizeKey, true, undefined, this);
|
|
70809
70918
|
}
|
|
70810
|
-
var
|
|
70919
|
+
var import_react56, jsx_dev_runtime7;
|
|
70811
70920
|
var init_TaskLoop = __esm(async () => {
|
|
70812
70921
|
init_useLoop();
|
|
70922
|
+
init_useTerminalSize();
|
|
70813
70923
|
await __promiseAll([
|
|
70814
70924
|
init_build2(),
|
|
70815
70925
|
init_build3(),
|
|
@@ -70819,7 +70929,7 @@ var init_TaskLoop = __esm(async () => {
|
|
|
70819
70929
|
init_StatusBar(),
|
|
70820
70930
|
init_StopMessage()
|
|
70821
70931
|
]);
|
|
70822
|
-
|
|
70932
|
+
import_react56 = __toESM(require_react(), 1);
|
|
70823
70933
|
jsx_dev_runtime7 = __toESM(require_jsx_dev_runtime(), 1);
|
|
70824
70934
|
});
|
|
70825
70935
|
|
|
@@ -70827,7 +70937,7 @@ var init_TaskLoop = __esm(async () => {
|
|
|
70827
70937
|
import { join as join13 } from "path";
|
|
70828
70938
|
function ExitAfterRender({ children }) {
|
|
70829
70939
|
const { exit } = use_app_default();
|
|
70830
|
-
|
|
70940
|
+
import_react57.useEffect(() => {
|
|
70831
70941
|
exit();
|
|
70832
70942
|
}, [exit]);
|
|
70833
70943
|
return /* @__PURE__ */ jsx_dev_runtime8.jsxDEV(jsx_dev_runtime8.Fragment, {
|
|
@@ -70836,7 +70946,7 @@ function ExitAfterRender({ children }) {
|
|
|
70836
70946
|
}
|
|
70837
70947
|
function ErrorMessage({ message }) {
|
|
70838
70948
|
const { exit } = use_app_default();
|
|
70839
|
-
|
|
70949
|
+
import_react57.useEffect(() => {
|
|
70840
70950
|
process.exitCode = 1;
|
|
70841
70951
|
exit();
|
|
70842
70952
|
}, [exit]);
|
|
@@ -70915,7 +71025,7 @@ function App2({ args, statesDir, tasksDir }) {
|
|
|
70915
71025
|
}
|
|
70916
71026
|
}
|
|
70917
71027
|
}
|
|
70918
|
-
var
|
|
71028
|
+
var import_react57, jsx_dev_runtime8;
|
|
70919
71029
|
var init_App2 = __esm(async () => {
|
|
70920
71030
|
init_state();
|
|
70921
71031
|
init_context();
|
|
@@ -70925,7 +71035,7 @@ var init_App2 = __esm(async () => {
|
|
|
70925
71035
|
init_TaskStatus(),
|
|
70926
71036
|
init_TaskLoop()
|
|
70927
71037
|
]);
|
|
70928
|
-
|
|
71038
|
+
import_react57 = __toESM(require_react(), 1);
|
|
70929
71039
|
jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
|
|
70930
71040
|
});
|
|
70931
71041
|
|
|
@@ -79420,7 +79530,7 @@ __export(exports_regexes, {
|
|
|
79420
79530
|
integer: () => integer,
|
|
79421
79531
|
idnEmail: () => idnEmail,
|
|
79422
79532
|
html5Email: () => html5Email,
|
|
79423
|
-
hostname: () =>
|
|
79533
|
+
hostname: () => hostname2,
|
|
79424
79534
|
hex: () => hex,
|
|
79425
79535
|
guid: () => guid,
|
|
79426
79536
|
extendedDuration: () => extendedDuration,
|
|
@@ -79475,7 +79585,7 @@ var cuid, cuid2, ulid, xid, ksuid, nanoid, duration, extendedDuration, guid, uui
|
|
|
79475
79585
|
}, uuid4, uuid6, uuid7, email, html5Email, rfc5322Email, unicodeEmail, idnEmail, browserEmail, _emoji = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`, ipv4, ipv6, mac = (delimiter) => {
|
|
79476
79586
|
const escapedDelim = escapeRegex(delimiter ?? ":");
|
|
79477
79587
|
return new RegExp(`^(?:[0-9A-F]{2}${escapedDelim}){5}[0-9A-F]{2}$|^(?:[0-9a-f]{2}${escapedDelim}){5}[0-9a-f]{2}$`);
|
|
79478
|
-
}, cidrv4, cidrv6, base64, base64url,
|
|
79588
|
+
}, cidrv4, cidrv6, base64, base64url, hostname2, domain, e164, dateSource = `(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))`, date, string = (params) => {
|
|
79479
79589
|
const regex2 = params ? `[\\s\\S]{${params?.minimum ?? 0},${params?.maximum ?? ""}}` : `[\\s\\S]*`;
|
|
79480
79590
|
return new RegExp(`^${regex2}$`);
|
|
79481
79591
|
}, bigint, integer, number, boolean, _null, _undefined, lowercase, uppercase, hex, md5_hex, md5_base64, md5_base64url, sha1_hex, sha1_base64, sha1_base64url, sha256_hex, sha256_base64, sha256_base64url, sha384_hex, sha384_base64, sha384_base64url, sha512_hex, sha512_base64, sha512_base64url;
|
|
@@ -79505,7 +79615,7 @@ var init_regexes = __esm(() => {
|
|
|
79505
79615
|
cidrv6 = /^(([0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}|::|([0-9a-fA-F]{1,4})?::([0-9a-fA-F]{1,4}:?){0,6})\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
|
|
79506
79616
|
base64 = /^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$/;
|
|
79507
79617
|
base64url = /^[A-Za-z0-9_-]*$/;
|
|
79508
|
-
|
|
79618
|
+
hostname2 = /^(?=.{1,253}\.?$)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[-0-9a-zA-Z]{0,61}[0-9a-zA-Z])?)*\.?$/;
|
|
79509
79619
|
domain = /^([a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[a-zA-Z]{2,}$/;
|
|
79510
79620
|
e164 = /^\+[1-9]\d{6,14}$/;
|
|
79511
79621
|
date = /* @__PURE__ */ new RegExp(`^${dateSource}$`);
|
|
@@ -90290,7 +90400,7 @@ __export(exports_schemas2, {
|
|
|
90290
90400
|
int: () => int,
|
|
90291
90401
|
instanceof: () => _instanceof,
|
|
90292
90402
|
httpUrl: () => httpUrl,
|
|
90293
|
-
hostname: () =>
|
|
90403
|
+
hostname: () => hostname3,
|
|
90294
90404
|
hex: () => hex2,
|
|
90295
90405
|
hash: () => hash,
|
|
90296
90406
|
guid: () => guid2,
|
|
@@ -90474,7 +90584,7 @@ function jwt(params) {
|
|
|
90474
90584
|
function stringFormat(format2, fnOrRegex, _params = {}) {
|
|
90475
90585
|
return _stringFormat(ZodCustomStringFormat, format2, fnOrRegex, _params);
|
|
90476
90586
|
}
|
|
90477
|
-
function
|
|
90587
|
+
function hostname3(_params) {
|
|
90478
90588
|
return _stringFormat(ZodCustomStringFormat, "hostname", exports_regexes.hostname, _params);
|
|
90479
90589
|
}
|
|
90480
90590
|
function hex2(_params) {
|
|
@@ -92112,7 +92222,7 @@ __export(exports_external2, {
|
|
|
92112
92222
|
instanceof: () => _instanceof,
|
|
92113
92223
|
includes: () => _includes,
|
|
92114
92224
|
httpUrl: () => httpUrl,
|
|
92115
|
-
hostname: () =>
|
|
92225
|
+
hostname: () => hostname3,
|
|
92116
92226
|
hex: () => hex2,
|
|
92117
92227
|
hash: () => hash,
|
|
92118
92228
|
guid: () => guid2,
|
|
@@ -92394,7 +92504,20 @@ var init_schema = __esm(() => {
|
|
|
92394
92504
|
fix_on_failure: exports_external2.boolean().optional(),
|
|
92395
92505
|
max_attempts: exports_external2.number().int().positive().optional(),
|
|
92396
92506
|
poll_interval_seconds: exports_external2.number().int().positive().optional()
|
|
92397
|
-
}).strict().optional()
|
|
92507
|
+
}).strict().optional(),
|
|
92508
|
+
preExistingErrorCheck: exports_external2.object({
|
|
92509
|
+
enabled: exports_external2.boolean().default(false),
|
|
92510
|
+
commands: exports_external2.array(exports_external2.string()).default([]),
|
|
92511
|
+
baseBranch: exports_external2.string().default("main"),
|
|
92512
|
+
label: exports_external2.string().default("ralph:pre-existing-error"),
|
|
92513
|
+
outputCharLimit: exports_external2.number().int().positive().default(4000)
|
|
92514
|
+
}).strict().default({
|
|
92515
|
+
enabled: false,
|
|
92516
|
+
commands: [],
|
|
92517
|
+
baseBranch: "main",
|
|
92518
|
+
label: "ralph:pre-existing-error",
|
|
92519
|
+
outputCharLimit: 4000
|
|
92520
|
+
})
|
|
92398
92521
|
});
|
|
92399
92522
|
});
|
|
92400
92523
|
|
|
@@ -92478,6 +92601,17 @@ engine: claude
|
|
|
92478
92601
|
# Model tier: "haiku", "sonnet", or "opus".
|
|
92479
92602
|
model: opus
|
|
92480
92603
|
|
|
92604
|
+
# Pre-existing error check: gate the agent when the base branch is already broken.
|
|
92605
|
+
# When enabled, the agent runs these commands against the base branch HEAD before
|
|
92606
|
+
# scheduling new work; failures open a Linear ticket and pause new pickups.
|
|
92607
|
+
preExistingErrorCheck:
|
|
92608
|
+
enabled: false
|
|
92609
|
+
# Commands to run against the base branch. When empty, falls back to commands.lint / commands.test.
|
|
92610
|
+
commands: []
|
|
92611
|
+
baseBranch: main
|
|
92612
|
+
label: "ralph:pre-existing-error"
|
|
92613
|
+
outputCharLimit: 4000
|
|
92614
|
+
|
|
92481
92615
|
linear:
|
|
92482
92616
|
# Linear team key (e.g. "ENG"). Omit to match all teams.
|
|
92483
92617
|
# team: ENG
|
|
@@ -92556,6 +92690,10 @@ Previous attempt failed with: {{ last_error }}
|
|
|
92556
92690
|
|
|
92557
92691
|
{{ issue.description }}
|
|
92558
92692
|
|
|
92693
|
+
{% if issue.labels %}
|
|
92694
|
+
Labels: {{ issue.labels | join(", ") }}
|
|
92695
|
+
{% endif %}
|
|
92696
|
+
|
|
92559
92697
|
{% if rules %}
|
|
92560
92698
|
Project rules:
|
|
92561
92699
|
{% for rule in rules %}- {{ rule }}
|
|
@@ -92743,6 +92881,7 @@ function renderTemplate(src, ctx) {
|
|
|
92743
92881
|
var exports_workflow = {};
|
|
92744
92882
|
__export(exports_workflow, {
|
|
92745
92883
|
workflowPath: () => workflowPath,
|
|
92884
|
+
resolveBaselineCommands: () => resolveBaselineCommands,
|
|
92746
92885
|
renderWorkflowPrompt: () => renderWorkflowPrompt,
|
|
92747
92886
|
renderTemplate: () => renderTemplate,
|
|
92748
92887
|
parseWorkflow: () => parseWorkflow,
|
|
@@ -92875,6 +93014,17 @@ function extractDefaultBody() {
|
|
|
92875
93014
|
const m = FRONTMATTER_RE.exec(DEFAULT_WORKFLOW_MD);
|
|
92876
93015
|
return m ? m[2] ?? "" : "";
|
|
92877
93016
|
}
|
|
93017
|
+
function resolveBaselineCommands(config2) {
|
|
93018
|
+
const configured = config2.preExistingErrorCheck?.commands ?? [];
|
|
93019
|
+
if (configured.length > 0)
|
|
93020
|
+
return [...configured];
|
|
93021
|
+
const fallback = [];
|
|
93022
|
+
if (config2.commands.lint)
|
|
93023
|
+
fallback.push(config2.commands.lint);
|
|
93024
|
+
if (config2.commands.test)
|
|
93025
|
+
fallback.push(config2.commands.test);
|
|
93026
|
+
return fallback;
|
|
93027
|
+
}
|
|
92878
93028
|
function renderWorkflowPrompt(workflow, ctx) {
|
|
92879
93029
|
const fullCtx = {
|
|
92880
93030
|
project: workflow.config.project,
|
|
@@ -93027,12 +93177,12 @@ async function main(argv) {
|
|
|
93027
93177
|
await ensureRalphGitignore(projectRoot);
|
|
93028
93178
|
}
|
|
93029
93179
|
await runWithContext(createDefaultContext(), async () => {
|
|
93030
|
-
const { waitUntilExit } = render_default(
|
|
93180
|
+
const { waitUntilExit } = render_default(import_react58.createElement(App2, { args, statesDir, tasksDir, projectRoot }));
|
|
93031
93181
|
await waitUntilExit();
|
|
93032
93182
|
});
|
|
93033
93183
|
return typeof process.exitCode === "number" ? process.exitCode : 0;
|
|
93034
93184
|
}
|
|
93035
|
-
var
|
|
93185
|
+
var import_react58;
|
|
93036
93186
|
var init_src5 = __esm(async () => {
|
|
93037
93187
|
init_context();
|
|
93038
93188
|
init_layout();
|
|
@@ -93044,7 +93194,7 @@ var init_src5 = __esm(async () => {
|
|
|
93044
93194
|
init_build2(),
|
|
93045
93195
|
init_App2()
|
|
93046
93196
|
]);
|
|
93047
|
-
|
|
93197
|
+
import_react58 = __toESM(require_react(), 1);
|
|
93048
93198
|
});
|
|
93049
93199
|
|
|
93050
93200
|
// apps/agent/src/cli.ts
|
|
@@ -93225,6 +93375,9 @@ async function parseArgs2(argv) {
|
|
|
93225
93375
|
case "--debug":
|
|
93226
93376
|
result2.debug = true;
|
|
93227
93377
|
break;
|
|
93378
|
+
case "--pre-existing-error-check":
|
|
93379
|
+
result2.preExistingErrorCheck = true;
|
|
93380
|
+
break;
|
|
93228
93381
|
default:
|
|
93229
93382
|
if (VALID_MODES2.has(arg)) {
|
|
93230
93383
|
result2.mode = arg;
|
|
@@ -93305,6 +93458,7 @@ var init_cli2 = __esm(() => {
|
|
|
93305
93458
|
" --code-review Watch open tracked PRs for unresolved review comments",
|
|
93306
93459
|
" --max-tickets <n> Stop picking up new issues after N have been started (0 = unlimited)",
|
|
93307
93460
|
" --json-output Emit JSONL to stdout instead of the Ink dashboard (for scripting/CI)",
|
|
93461
|
+
" --pre-existing-error-check Run baseline commands against the base branch; pause new pickups + open a Linear ticket when red",
|
|
93308
93462
|
" --debug List mode: explain why a Linear ticket was not picked up (use with --name)",
|
|
93309
93463
|
" --help, -h Show this help message",
|
|
93310
93464
|
"",
|
|
@@ -93425,7 +93579,7 @@ async function fetchOpenIssues(apiKey, spec) {
|
|
|
93425
93579
|
const query = `query Issues($filter: IssueFilter) {
|
|
93426
93580
|
issues(filter: $filter, first: 50) {
|
|
93427
93581
|
nodes {
|
|
93428
|
-
id identifier title description url priority
|
|
93582
|
+
id identifier title description url priority createdAt
|
|
93429
93583
|
state { name type }
|
|
93430
93584
|
assignee { id email name }
|
|
93431
93585
|
labels { nodes { name } }
|
|
@@ -93452,6 +93606,7 @@ async function fetchOpenIssues(apiKey, spec) {
|
|
|
93452
93606
|
assignee: n.assignee,
|
|
93453
93607
|
labels: n.labels.nodes.map((l) => l.name),
|
|
93454
93608
|
priority: n.priority,
|
|
93609
|
+
createdAt: n.createdAt ?? "",
|
|
93455
93610
|
blockedByIds: (n.relations?.nodes ?? []).filter((r) => r.type === "blocked_by" && !DONE_STATE_TYPES.has(r.relatedIssue.state.type)).map((r) => r.relatedIssue.id)
|
|
93456
93611
|
}));
|
|
93457
93612
|
}
|
|
@@ -93478,6 +93633,15 @@ async function linearRequest(apiKey, query, variables) {
|
|
|
93478
93633
|
}
|
|
93479
93634
|
return json2.data;
|
|
93480
93635
|
}
|
|
93636
|
+
async function addReactionToComment(apiKey, commentId, emoji3) {
|
|
93637
|
+
const mutation = `mutation Reaction($commentId: String!, $emoji: String!) {
|
|
93638
|
+
reactionCreate(input: { commentId: $commentId, emoji: $emoji }) { success }
|
|
93639
|
+
}`;
|
|
93640
|
+
await linearRequest(apiKey, mutation, {
|
|
93641
|
+
commentId,
|
|
93642
|
+
emoji: emoji3
|
|
93643
|
+
});
|
|
93644
|
+
}
|
|
93481
93645
|
async function addIssueComment(apiKey, issueId, body) {
|
|
93482
93646
|
const mutation = `mutation Comment($issueId: String!, $body: String!) {
|
|
93483
93647
|
commentCreate(input: { issueId: $issueId, body: $body }) { success }
|
|
@@ -93653,6 +93817,53 @@ function issueMatchesGetIndicator(issue2, indicator) {
|
|
|
93653
93817
|
return false;
|
|
93654
93818
|
});
|
|
93655
93819
|
}
|
|
93820
|
+
async function createIssue(apiKey, input) {
|
|
93821
|
+
const mutation = `mutation CreateIssue($input: IssueCreateInput!) {
|
|
93822
|
+
issueCreate(input: $input) {
|
|
93823
|
+
success
|
|
93824
|
+
issue { id identifier }
|
|
93825
|
+
}
|
|
93826
|
+
}`;
|
|
93827
|
+
const variables = {
|
|
93828
|
+
input: {
|
|
93829
|
+
teamId: input.teamId,
|
|
93830
|
+
title: input.title,
|
|
93831
|
+
description: input.description,
|
|
93832
|
+
...input.labelIds && input.labelIds.length > 0 ? { labelIds: input.labelIds } : {}
|
|
93833
|
+
}
|
|
93834
|
+
};
|
|
93835
|
+
const data = await linearRequest(apiKey, mutation, variables);
|
|
93836
|
+
const issue2 = data.issueCreate.issue;
|
|
93837
|
+
if (!issue2)
|
|
93838
|
+
throw new Error("issueCreate returned no issue");
|
|
93839
|
+
return issue2;
|
|
93840
|
+
}
|
|
93841
|
+
async function updateIssueDescription(apiKey, issueId, description) {
|
|
93842
|
+
const mutation = `mutation UpdateDesc($id: String!, $description: String!) {
|
|
93843
|
+
issueUpdate(id: $id, input: { description: $description }) { success }
|
|
93844
|
+
}`;
|
|
93845
|
+
await linearRequest(apiKey, mutation, {
|
|
93846
|
+
id: issueId,
|
|
93847
|
+
description
|
|
93848
|
+
});
|
|
93849
|
+
}
|
|
93850
|
+
async function findOpenIssueByLabel(apiKey, teamKey, labelName) {
|
|
93851
|
+
const query = `query OpenByLabel($team: String!, $label: String!) {
|
|
93852
|
+
issues(
|
|
93853
|
+
filter: {
|
|
93854
|
+
team: { key: { eq: $team } },
|
|
93855
|
+
labels: { some: { name: { eq: $label } } },
|
|
93856
|
+
state: { type: { in: ["unstarted", "started", "backlog", "triage"] } }
|
|
93857
|
+
},
|
|
93858
|
+
first: 1,
|
|
93859
|
+
orderBy: createdAt
|
|
93860
|
+
) {
|
|
93861
|
+
nodes { id identifier description }
|
|
93862
|
+
}
|
|
93863
|
+
}`;
|
|
93864
|
+
const data = await linearRequest(apiKey, query, { team: teamKey, label: labelName });
|
|
93865
|
+
return data.issues.nodes[0] ?? null;
|
|
93866
|
+
}
|
|
93656
93867
|
async function removeLabelFromIssue(apiKey, issueId, labelId) {
|
|
93657
93868
|
const mutation = `mutation RemoveLabel($id: String!, $labelId: String!) {
|
|
93658
93869
|
issueRemoveLabel(id: $id, labelId: $labelId) { success }
|
|
@@ -93664,6 +93875,43 @@ async function removeLabelFromIssue(apiKey, issueId, labelId) {
|
|
|
93664
93875
|
}
|
|
93665
93876
|
var LINEAR_API = "https://api.linear.app/graphql", RALPHY_ATTACHMENT_TITLE_FILTER = "Ralphy", RALPHY_ATTACHMENT_TITLE = "Ralphy", BRANCH_LABEL_PREFIX = "ralph:branch:";
|
|
93666
93877
|
|
|
93878
|
+
// apps/agent/src/sort/compare.ts
|
|
93879
|
+
function chain(...comparators) {
|
|
93880
|
+
return (a, b) => {
|
|
93881
|
+
for (const c of comparators) {
|
|
93882
|
+
const r = c(a, b);
|
|
93883
|
+
if (r !== 0)
|
|
93884
|
+
return r;
|
|
93885
|
+
}
|
|
93886
|
+
return 0;
|
|
93887
|
+
};
|
|
93888
|
+
}
|
|
93889
|
+
|
|
93890
|
+
// apps/agent/src/queue/queue-order.ts
|
|
93891
|
+
function compareQueueEntries(getAutoMerge) {
|
|
93892
|
+
const isAutoMergeBoost = (e) => e.mode === "conflict-fix" && issueMatchesGetIndicator(e.issue, getAutoMerge);
|
|
93893
|
+
return chain((a, b) => Number(!isAutoMergeBoost(a)) - Number(!isAutoMergeBoost(b)), (a, b) => {
|
|
93894
|
+
const pa = a.issue.priority === 0 ? Infinity : a.issue.priority;
|
|
93895
|
+
const pb = b.issue.priority === 0 ? Infinity : b.issue.priority;
|
|
93896
|
+
return pa - pb;
|
|
93897
|
+
}, (a, b) => MODE_RANK[a.mode] - MODE_RANK[b.mode], (a, b) => {
|
|
93898
|
+
const ca = a.issue.createdAt;
|
|
93899
|
+
const cb = b.issue.createdAt;
|
|
93900
|
+
if (ca === cb)
|
|
93901
|
+
return 0;
|
|
93902
|
+
return ca < cb ? -1 : 1;
|
|
93903
|
+
});
|
|
93904
|
+
}
|
|
93905
|
+
var MODE_RANK;
|
|
93906
|
+
var init_queue_order = __esm(() => {
|
|
93907
|
+
MODE_RANK = {
|
|
93908
|
+
resume: 0,
|
|
93909
|
+
"conflict-fix": 1,
|
|
93910
|
+
review: 2,
|
|
93911
|
+
fresh: 3
|
|
93912
|
+
};
|
|
93913
|
+
});
|
|
93914
|
+
|
|
93667
93915
|
// apps/agent/src/agent/coordinator.ts
|
|
93668
93916
|
class AgentCoordinator {
|
|
93669
93917
|
deps;
|
|
@@ -93672,6 +93920,7 @@ class AgentCoordinator {
|
|
|
93672
93920
|
pendingIds = new Set;
|
|
93673
93921
|
queue = [];
|
|
93674
93922
|
stopped = false;
|
|
93923
|
+
paused = null;
|
|
93675
93924
|
conflictNotified = new Set;
|
|
93676
93925
|
ticketsStarted = 0;
|
|
93677
93926
|
constructor(deps, opts) {
|
|
@@ -93690,6 +93939,18 @@ class AgentCoordinator {
|
|
|
93690
93939
|
get ticketsStartedCount() {
|
|
93691
93940
|
return this.ticketsStarted;
|
|
93692
93941
|
}
|
|
93942
|
+
isPaused() {
|
|
93943
|
+
return this.paused !== null;
|
|
93944
|
+
}
|
|
93945
|
+
getPause() {
|
|
93946
|
+
return this.paused;
|
|
93947
|
+
}
|
|
93948
|
+
setPaused(state) {
|
|
93949
|
+
this.paused = state;
|
|
93950
|
+
}
|
|
93951
|
+
clearPaused() {
|
|
93952
|
+
this.paused = null;
|
|
93953
|
+
}
|
|
93693
93954
|
async init() {}
|
|
93694
93955
|
async pollOnce() {
|
|
93695
93956
|
if (this.stopped)
|
|
@@ -93713,11 +93974,23 @@ class AgentCoordinator {
|
|
|
93713
93974
|
return emptyPollResult();
|
|
93714
93975
|
}
|
|
93715
93976
|
if (todo.length + inProgress.length + conflicted.length + review.length + mentions.length > 0) {
|
|
93716
|
-
this.deps.
|
|
93977
|
+
this.deps.onFileLog?.(` poll: ${todo.length} todo, ${inProgress.length} in-progress, ${conflicted.length} conflicted, ${review.length} review, ${mentions.length} mention`);
|
|
93717
93978
|
}
|
|
93718
93979
|
const queuedIds = new Set(this.queue.map((q) => q.issue.id));
|
|
93719
93980
|
const activeIds = new Set(this.workers.map((w) => w.issueId));
|
|
93720
93981
|
const eligible = (id) => !queuedIds.has(id) && !activeIds.has(id) && !this.pendingIds.has(id);
|
|
93982
|
+
if (this.paused) {
|
|
93983
|
+
this.deps.onLog(` paused \u2014 baseline broken (${this.paused.issueIdentifier}); skipping new pickups`, "yellow");
|
|
93984
|
+
const buckets2 = {
|
|
93985
|
+
todo: todo.length,
|
|
93986
|
+
inProgress: inProgress.length,
|
|
93987
|
+
conflicted: conflicted.length,
|
|
93988
|
+
review: review.length,
|
|
93989
|
+
mentions: mentions.length
|
|
93990
|
+
};
|
|
93991
|
+
const found2 = buckets2.todo + buckets2.inProgress + buckets2.conflicted + buckets2.review + buckets2.mentions;
|
|
93992
|
+
return { found: found2, added: 0, buckets: buckets2, prStatus: emptyPrStatus() };
|
|
93993
|
+
}
|
|
93721
93994
|
const maxT = this.opts.maxTickets ?? 0;
|
|
93722
93995
|
const atTicketLimit = () => {
|
|
93723
93996
|
if (maxT === 0)
|
|
@@ -93746,7 +94019,11 @@ class AgentCoordinator {
|
|
|
93746
94019
|
this.queue.push({ issue: issue2, mode: "conflict-fix" });
|
|
93747
94020
|
queuedIds.add(issue2.id);
|
|
93748
94021
|
added += 1;
|
|
93749
|
-
this.
|
|
94022
|
+
if (this.isAutoMergeUnblock(issue2)) {
|
|
94023
|
+
this.deps.onLog(` \u21B3 ${issue2.identifier} queued (auto-merge unblock, prioritized)`, "cyan");
|
|
94024
|
+
} else {
|
|
94025
|
+
this.deps.onLog(` \u21B3 ${issue2.identifier} queued (conflict-fix)`, "gray");
|
|
94026
|
+
}
|
|
93750
94027
|
}
|
|
93751
94028
|
for (const issue2 of review) {
|
|
93752
94029
|
if (atTicketLimit())
|
|
@@ -93781,19 +94058,7 @@ class AgentCoordinator {
|
|
|
93781
94058
|
this.deps.onLog(` \u21B3 ${issue2.identifier} queued (fresh)`, "gray");
|
|
93782
94059
|
}
|
|
93783
94060
|
if (added > 0) {
|
|
93784
|
-
|
|
93785
|
-
resume: 0,
|
|
93786
|
-
"conflict-fix": 1,
|
|
93787
|
-
review: 2,
|
|
93788
|
-
fresh: 3
|
|
93789
|
-
};
|
|
93790
|
-
this.queue.sort((a, b) => {
|
|
93791
|
-
const pa = a.issue.priority === 0 ? Infinity : a.issue.priority;
|
|
93792
|
-
const pb = b.issue.priority === 0 ? Infinity : b.issue.priority;
|
|
93793
|
-
if (pa !== pb)
|
|
93794
|
-
return pa - pb;
|
|
93795
|
-
return modeRank[a.mode] - modeRank[b.mode];
|
|
93796
|
-
});
|
|
94061
|
+
this.queue.sort(compareQueueEntries(this.opts.getAutoMerge));
|
|
93797
94062
|
}
|
|
93798
94063
|
this.spawnNext();
|
|
93799
94064
|
const prStatus = await this.scanDoneForConflicts();
|
|
@@ -93808,6 +94073,9 @@ class AgentCoordinator {
|
|
|
93808
94073
|
const found = buckets.todo + buckets.inProgress + buckets.conflicted + buckets.review + buckets.mentions;
|
|
93809
94074
|
return { found, added, buckets, prStatus };
|
|
93810
94075
|
}
|
|
94076
|
+
isAutoMergeUnblock(issue2) {
|
|
94077
|
+
return issueMatchesGetIndicator(issue2, this.opts.getAutoMerge);
|
|
94078
|
+
}
|
|
93811
94079
|
dependenciesResolved(issue2) {
|
|
93812
94080
|
if (issue2.blockedByIds.length === 0)
|
|
93813
94081
|
return true;
|
|
@@ -94006,7 +94274,8 @@ class AgentCoordinator {
|
|
|
94006
94274
|
issue: issue2,
|
|
94007
94275
|
mode,
|
|
94008
94276
|
kill: handle.kill,
|
|
94009
|
-
lastReportedIteration: 0
|
|
94277
|
+
lastReportedIteration: 0,
|
|
94278
|
+
restarting: false
|
|
94010
94279
|
};
|
|
94011
94280
|
this.workers.push(worker);
|
|
94012
94281
|
this.pendingIds.delete(issue2.id);
|
|
@@ -94024,6 +94293,13 @@ class AgentCoordinator {
|
|
|
94024
94293
|
const idx = this.workers.indexOf(worker);
|
|
94025
94294
|
if (idx >= 0)
|
|
94026
94295
|
this.workers.splice(idx, 1);
|
|
94296
|
+
if (worker.restarting) {
|
|
94297
|
+
this.ticketsStarted = Math.max(0, this.ticketsStarted - 1);
|
|
94298
|
+
this.queue.unshift({ issue: issue2, mode: "resume" });
|
|
94299
|
+
this.deps.onWorkersChanged();
|
|
94300
|
+
this.spawnNext();
|
|
94301
|
+
return;
|
|
94302
|
+
}
|
|
94027
94303
|
const ok = code === 0;
|
|
94028
94304
|
this.deps.onLog(`${ok ? "\u2713" : "\u2717"} ${issue2.identifier} \u2192 ${prep.changeName} exited (code ${code})`, ok ? "green" : "red");
|
|
94029
94305
|
capture("agent_worker_exited", {
|
|
@@ -94037,6 +94313,24 @@ class AgentCoordinator {
|
|
|
94037
94313
|
this.spawnNext();
|
|
94038
94314
|
});
|
|
94039
94315
|
}
|
|
94316
|
+
async restartWorker(changeName) {
|
|
94317
|
+
if (this.stopped)
|
|
94318
|
+
return false;
|
|
94319
|
+
const worker = this.workers.find((w) => w.changeName === changeName);
|
|
94320
|
+
if (!worker)
|
|
94321
|
+
return false;
|
|
94322
|
+
if (worker.restarting)
|
|
94323
|
+
return true;
|
|
94324
|
+
worker.restarting = true;
|
|
94325
|
+
capture("agent_worker_restarted", {
|
|
94326
|
+
change_name: changeName,
|
|
94327
|
+
reason: "steering"
|
|
94328
|
+
});
|
|
94329
|
+
try {
|
|
94330
|
+
worker.kill();
|
|
94331
|
+
} catch {}
|
|
94332
|
+
return true;
|
|
94333
|
+
}
|
|
94040
94334
|
async notifyExited(issue2, changeName, code, mode) {
|
|
94041
94335
|
const ok = code === 0;
|
|
94042
94336
|
if (this.opts.postComments !== false) {
|
|
@@ -94121,6 +94415,7 @@ var emptyPrStatus = () => ({ mergeable: 0, conflicted: 0, ciFailed: 0 }), emptyP
|
|
|
94121
94415
|
prStatus: emptyPrStatus()
|
|
94122
94416
|
});
|
|
94123
94417
|
var init_coordinator = __esm(() => {
|
|
94418
|
+
init_queue_order();
|
|
94124
94419
|
init_src();
|
|
94125
94420
|
});
|
|
94126
94421
|
|
|
@@ -94149,6 +94444,7 @@ async function scaffoldChangeForIssue(tasksDir, statesDir, issue2, comments = []
|
|
|
94149
94444
|
""
|
|
94150
94445
|
])
|
|
94151
94446
|
] : [];
|
|
94447
|
+
const descriptionBody = issue2.description?.trim() || "_No description provided in Linear._";
|
|
94152
94448
|
const proposal = [
|
|
94153
94449
|
`# ${issue2.identifier}: ${issue2.title}`,
|
|
94154
94450
|
"",
|
|
@@ -94157,9 +94453,17 @@ async function scaffoldChangeForIssue(tasksDir, statesDir, issue2, comments = []
|
|
|
94157
94453
|
issue2.assignee ? `Assignee: ${issue2.assignee.name}` : "",
|
|
94158
94454
|
issue2.labels.length ? `Labels: ${issue2.labels.join(", ")}` : "",
|
|
94159
94455
|
"",
|
|
94456
|
+
"## Why",
|
|
94457
|
+
"",
|
|
94458
|
+
descriptionBody,
|
|
94459
|
+
"",
|
|
94460
|
+
"## What Changes",
|
|
94461
|
+
"",
|
|
94462
|
+
"_Describe the concrete changes this proposal introduces (one bullet per change)._",
|
|
94463
|
+
"",
|
|
94160
94464
|
"## Description",
|
|
94161
94465
|
"",
|
|
94162
|
-
|
|
94466
|
+
descriptionBody,
|
|
94163
94467
|
...commentsBlock,
|
|
94164
94468
|
...appendPrompt.trim() ? ["", "## Additional instructions", "", appendPrompt.trim()] : [],
|
|
94165
94469
|
"",
|
|
@@ -94176,6 +94480,8 @@ async function scaffoldChangeForIssue(tasksDir, statesDir, issue2, comments = []
|
|
|
94176
94480
|
"",
|
|
94177
94481
|
`- [ ] Read the Linear issue at ${issue2.url} and research the codebase to understand the mission and its scope`,
|
|
94178
94482
|
`- [ ] Refine proposal.md with the problem statement, approach, and acceptance criteria derived from the research`,
|
|
94483
|
+
`- [ ] Fill in \`## Why\` and \`## What Changes\` in proposal.md so \`openspec validate\` passes (these sections are required by the validator)`,
|
|
94484
|
+
`- [ ] Add at least one spec delta under \`specs/<capability>/spec.md\` describing the behavior added/modified/removed by this change`,
|
|
94179
94485
|
`- [ ] Fill in design.md with the technical design (files to touch, data flow, edge cases)`,
|
|
94180
94486
|
`- [ ] Append an \`## Implementation\` section below with concrete mission-specific tasks derived from the plan (one \`- [ ] task\` per discrete unit of work, including tests and \`bun run lint\` / \`bun run test\`)`,
|
|
94181
94487
|
""
|
|
@@ -94509,6 +94815,33 @@ async function createPullRequest(input, runner) {
|
|
|
94509
94815
|
|
|
94510
94816
|
// apps/agent/src/agent/post-task.ts
|
|
94511
94817
|
import { join as join20 } from "path";
|
|
94818
|
+
function summarizeUncommittedStatus(stdout) {
|
|
94819
|
+
const lines = stdout.split(`
|
|
94820
|
+
`).filter((line) => line.length > 0);
|
|
94821
|
+
const preview = lines.slice(0, 10);
|
|
94822
|
+
return { count: lines.length, preview, truncated: Math.max(0, lines.length - preview.length) };
|
|
94823
|
+
}
|
|
94824
|
+
async function findExistingOpenPrUrl(cmd, cwd2, branch) {
|
|
94825
|
+
try {
|
|
94826
|
+
const result2 = await cmd.run([
|
|
94827
|
+
"gh",
|
|
94828
|
+
"pr",
|
|
94829
|
+
"list",
|
|
94830
|
+
"--head",
|
|
94831
|
+
branch,
|
|
94832
|
+
"--state",
|
|
94833
|
+
"open",
|
|
94834
|
+
"--json",
|
|
94835
|
+
"url",
|
|
94836
|
+
"--jq",
|
|
94837
|
+
".[0].url // empty"
|
|
94838
|
+
], cwd2);
|
|
94839
|
+
const url2 = result2.stdout.trim();
|
|
94840
|
+
return url2 || null;
|
|
94841
|
+
} catch {
|
|
94842
|
+
return null;
|
|
94843
|
+
}
|
|
94844
|
+
}
|
|
94512
94845
|
async function detectRepoAutoMergeAllowed(prUrl, cmd, cwd2, log2) {
|
|
94513
94846
|
const m = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/\d+/.exec(prUrl);
|
|
94514
94847
|
if (!m)
|
|
@@ -94552,7 +94885,7 @@ async function reactivateState(stateFilePath, log2, changeName) {
|
|
|
94552
94885
|
}
|
|
94553
94886
|
async function runWorkerWithFixTask(ctx, heading, body) {
|
|
94554
94887
|
try {
|
|
94555
|
-
await prependFixTask(join20(ctx.changeDir,
|
|
94888
|
+
await prependFixTask(join20(ctx.changeDir, AGENT_TASKS_FILENAME), heading, body);
|
|
94556
94889
|
} catch (err) {
|
|
94557
94890
|
ctx.log(`! could not prepend fix task: ${err.message}`, "red");
|
|
94558
94891
|
return 1;
|
|
@@ -94831,8 +95164,20 @@ async function runPrPhase(input, deps) {
|
|
|
94831
95164
|
};
|
|
94832
95165
|
try {
|
|
94833
95166
|
const status = await cmd.run(["git", "status", "--porcelain"], cwd2);
|
|
94834
|
-
|
|
94835
|
-
|
|
95167
|
+
const summary = summarizeUncommittedStatus(status.stdout);
|
|
95168
|
+
if (summary.count > 0) {
|
|
95169
|
+
const existingPrUrl = branch ? await findExistingOpenPrUrl(cmd, cwd2, branch) : null;
|
|
95170
|
+
const indented = summary.preview.map((line) => ` ${line}`).join(`
|
|
95171
|
+
`);
|
|
95172
|
+
const suffix = summary.truncated ? `
|
|
95173
|
+
... and ${summary.truncated} more` : "";
|
|
95174
|
+
if (existingPrUrl) {
|
|
95175
|
+
log2(` ${changeName}: ${summary.count} uncommitted file(s) after worker \u2014 will retry next iteration:
|
|
95176
|
+
${indented}${suffix}`, "gray");
|
|
95177
|
+
} else {
|
|
95178
|
+
log2(`! ${changeName} has uncommitted changes after worker exit \u2014 the agent should commit everything before finishing. These changes will not be included in the PR:
|
|
95179
|
+
${indented}${suffix}`, "yellow");
|
|
95180
|
+
}
|
|
94836
95181
|
}
|
|
94837
95182
|
} catch (err) {
|
|
94838
95183
|
log2(`! git status check failed for ${changeName}: ${err.message}`, "yellow");
|
|
@@ -94987,14 +95332,233 @@ async function runPostTask(input, deps) {
|
|
|
94987
95332
|
}
|
|
94988
95333
|
var CI_FAILED_EXIT = 70, PR_FAILED_EXIT = 71, repoAutoMergeCache;
|
|
94989
95334
|
var init_post_task = __esm(() => {
|
|
95335
|
+
init_tasks_md();
|
|
94990
95336
|
init_ci();
|
|
94991
95337
|
init_worktree();
|
|
94992
95338
|
repoAutoMergeCache = new Map;
|
|
94993
95339
|
});
|
|
94994
95340
|
|
|
95341
|
+
// apps/agent/src/agent/baseline/runner.ts
|
|
95342
|
+
import { createHash } from "crypto";
|
|
95343
|
+
async function runBaseline(input) {
|
|
95344
|
+
const { cmdRunner, gitRunner, cwd: cwd2, commands, baseBranch, outputCharLimit } = input;
|
|
95345
|
+
if (commands.length === 0) {
|
|
95346
|
+
return { ok: true, failures: [], fingerprint: "" };
|
|
95347
|
+
}
|
|
95348
|
+
try {
|
|
95349
|
+
await gitRunner.run(["fetch", "origin", baseBranch], cwd2);
|
|
95350
|
+
await gitRunner.run(["reset", "--hard", `origin/${baseBranch}`], cwd2);
|
|
95351
|
+
} catch (err) {
|
|
95352
|
+
const e = err;
|
|
95353
|
+
const failure = {
|
|
95354
|
+
command: `git checkout ${baseBranch}`,
|
|
95355
|
+
exitCode: -1,
|
|
95356
|
+
stdout: "",
|
|
95357
|
+
stderr: truncate3(e.stderr ?? e.message, outputCharLimit),
|
|
95358
|
+
fingerprint: fingerprintFor(`git checkout ${baseBranch}`, e.stderr ?? e.message)
|
|
95359
|
+
};
|
|
95360
|
+
return {
|
|
95361
|
+
ok: false,
|
|
95362
|
+
failures: [failure],
|
|
95363
|
+
fingerprint: failure.fingerprint
|
|
95364
|
+
};
|
|
95365
|
+
}
|
|
95366
|
+
const failures = [];
|
|
95367
|
+
for (const command of commands) {
|
|
95368
|
+
const parts = parseCommand(command);
|
|
95369
|
+
let stdout = "";
|
|
95370
|
+
let stderr = "";
|
|
95371
|
+
let exitCode = 0;
|
|
95372
|
+
try {
|
|
95373
|
+
const r = await cmdRunner.run(parts, cwd2);
|
|
95374
|
+
stdout = r.stdout;
|
|
95375
|
+
stderr = r.stderr;
|
|
95376
|
+
} catch (err) {
|
|
95377
|
+
const e = err;
|
|
95378
|
+
stdout = e.stdout ?? "";
|
|
95379
|
+
stderr = e.stderr ?? e.message;
|
|
95380
|
+
exitCode = typeof e.code === "number" ? e.code : 1;
|
|
95381
|
+
}
|
|
95382
|
+
if (exitCode !== 0) {
|
|
95383
|
+
failures.push({
|
|
95384
|
+
command,
|
|
95385
|
+
exitCode,
|
|
95386
|
+
stdout: truncate3(stdout, outputCharLimit),
|
|
95387
|
+
stderr: truncate3(stderr, outputCharLimit),
|
|
95388
|
+
fingerprint: fingerprintFor(command, stderr || stdout)
|
|
95389
|
+
});
|
|
95390
|
+
}
|
|
95391
|
+
}
|
|
95392
|
+
return {
|
|
95393
|
+
ok: failures.length === 0,
|
|
95394
|
+
failures,
|
|
95395
|
+
fingerprint: failures[0]?.fingerprint ?? ""
|
|
95396
|
+
};
|
|
95397
|
+
}
|
|
95398
|
+
function parseCommand(cmd) {
|
|
95399
|
+
return cmd.trim().split(/\s+/);
|
|
95400
|
+
}
|
|
95401
|
+
function truncate3(text, limit) {
|
|
95402
|
+
if (text.length <= limit)
|
|
95403
|
+
return text;
|
|
95404
|
+
return text.slice(0, limit) + `
|
|
95405
|
+
\u2026(truncated ${text.length - limit} chars)`;
|
|
95406
|
+
}
|
|
95407
|
+
function fingerprintFor(command, output) {
|
|
95408
|
+
const firstLine = (output || "").split(`
|
|
95409
|
+
`).find((l) => l.trim().length > 0) ?? "";
|
|
95410
|
+
return createHash("sha1").update(`${command}
|
|
95411
|
+
${firstLine.trim()}`).digest("hex").slice(0, 12);
|
|
95412
|
+
}
|
|
95413
|
+
var init_runner = () => {};
|
|
95414
|
+
|
|
95415
|
+
// apps/agent/src/agent/baseline/gate.ts
|
|
95416
|
+
async function runBaselineGate(deps) {
|
|
95417
|
+
if (!deps.enabled)
|
|
95418
|
+
return;
|
|
95419
|
+
if (deps.commands.length === 0) {
|
|
95420
|
+
deps.onLog(" baseline check skipped \u2014 no commands configured", "gray");
|
|
95421
|
+
return;
|
|
95422
|
+
}
|
|
95423
|
+
const result2 = await runBaseline({
|
|
95424
|
+
cmdRunner: deps.cmdRunner,
|
|
95425
|
+
gitRunner: deps.gitRunner,
|
|
95426
|
+
cwd: deps.cwd,
|
|
95427
|
+
commands: deps.commands,
|
|
95428
|
+
baseBranch: deps.baseBranch,
|
|
95429
|
+
outputCharLimit: deps.outputCharLimit
|
|
95430
|
+
});
|
|
95431
|
+
if (result2.ok) {
|
|
95432
|
+
if (deps.coordinator.isPaused()) {
|
|
95433
|
+
deps.coordinator.clearPaused();
|
|
95434
|
+
deps.onLog("\u2713 baseline recovered \u2014 resuming new pickups", "green");
|
|
95435
|
+
}
|
|
95436
|
+
return;
|
|
95437
|
+
}
|
|
95438
|
+
const firstFailure = result2.failures[0];
|
|
95439
|
+
const description = renderIssueBody(result2, deps.outputCharLimit);
|
|
95440
|
+
const title = `Pre-existing baseline error on ${deps.baseBranch}: \`${firstFailure.command}\``;
|
|
95441
|
+
let issueIdentifier = "BASELINE";
|
|
95442
|
+
let issueId;
|
|
95443
|
+
if (deps.linear) {
|
|
95444
|
+
try {
|
|
95445
|
+
const existing = await deps.linear.findOpen();
|
|
95446
|
+
if (existing) {
|
|
95447
|
+
const existingFp = extractFingerprint(existing.description ?? "");
|
|
95448
|
+
if (existingFp !== result2.fingerprint) {
|
|
95449
|
+
await deps.linear.updateDescription(existing.id, description);
|
|
95450
|
+
deps.onLog(` baseline ticket ${existing.identifier} updated (fingerprint changed)`, "yellow");
|
|
95451
|
+
}
|
|
95452
|
+
issueIdentifier = existing.identifier;
|
|
95453
|
+
issueId = existing.id;
|
|
95454
|
+
} else {
|
|
95455
|
+
const created = await deps.linear.create(title, description);
|
|
95456
|
+
issueIdentifier = created.identifier;
|
|
95457
|
+
issueId = created.id;
|
|
95458
|
+
deps.onLog(` baseline ticket ${created.identifier} created`, "yellow");
|
|
95459
|
+
}
|
|
95460
|
+
} catch (err) {
|
|
95461
|
+
deps.onLog(`! Linear baseline ticket sync failed: ${err.message}`, "red");
|
|
95462
|
+
}
|
|
95463
|
+
} else {
|
|
95464
|
+
deps.onLog("! baseline failed but no Linear client configured \u2014 pausing without ticket", "yellow");
|
|
95465
|
+
}
|
|
95466
|
+
const since = deps.coordinator.isPaused() ? deps.coordinator.getPause()?.since ?? deps.now?.() ?? Date.now() : deps.now?.() ?? Date.now();
|
|
95467
|
+
deps.coordinator.setPaused({
|
|
95468
|
+
issueIdentifier,
|
|
95469
|
+
...issueId !== undefined ? { issueId } : {},
|
|
95470
|
+
command: firstFailure.command,
|
|
95471
|
+
fingerprint: result2.fingerprint,
|
|
95472
|
+
since
|
|
95473
|
+
});
|
|
95474
|
+
}
|
|
95475
|
+
function extractFingerprint(body) {
|
|
95476
|
+
const m = FINGERPRINT_MARKER_RE.exec(body);
|
|
95477
|
+
return m?.[1] ?? null;
|
|
95478
|
+
}
|
|
95479
|
+
function renderIssueBody(result2, outputCharLimit) {
|
|
95480
|
+
const lines = [];
|
|
95481
|
+
lines.push(`<!-- ralphy:baseline:${result2.fingerprint} -->`);
|
|
95482
|
+
lines.push("");
|
|
95483
|
+
lines.push("Ralph detected a failing command on the base branch.");
|
|
95484
|
+
lines.push("");
|
|
95485
|
+
lines.push("New issues will not be picked up by Ralph until this is resolved.");
|
|
95486
|
+
lines.push("Mark this Linear issue as Done to lift the pause.");
|
|
95487
|
+
lines.push("");
|
|
95488
|
+
for (const f2 of result2.failures) {
|
|
95489
|
+
lines.push(`### \`${f2.command}\` \u2014 exit ${f2.exitCode}`);
|
|
95490
|
+
lines.push("");
|
|
95491
|
+
if (f2.stdout.trim()) {
|
|
95492
|
+
lines.push("**stdout:**");
|
|
95493
|
+
lines.push("```");
|
|
95494
|
+
lines.push(truncateForBody(f2.stdout, outputCharLimit));
|
|
95495
|
+
lines.push("```");
|
|
95496
|
+
}
|
|
95497
|
+
if (f2.stderr.trim()) {
|
|
95498
|
+
lines.push("**stderr:**");
|
|
95499
|
+
lines.push("```");
|
|
95500
|
+
lines.push(truncateForBody(f2.stderr, outputCharLimit));
|
|
95501
|
+
lines.push("```");
|
|
95502
|
+
}
|
|
95503
|
+
lines.push("");
|
|
95504
|
+
}
|
|
95505
|
+
return lines.join(`
|
|
95506
|
+
`);
|
|
95507
|
+
}
|
|
95508
|
+
function truncateForBody(text, limit) {
|
|
95509
|
+
if (text.length <= limit)
|
|
95510
|
+
return text;
|
|
95511
|
+
return text.slice(0, limit) + `
|
|
95512
|
+
\u2026(truncated)`;
|
|
95513
|
+
}
|
|
95514
|
+
var FINGERPRINT_MARKER_RE;
|
|
95515
|
+
var init_gate = __esm(() => {
|
|
95516
|
+
init_runner();
|
|
95517
|
+
FINGERPRINT_MARKER_RE = /<!--\s*ralphy:baseline:([a-f0-9]+)\s*-->/i;
|
|
95518
|
+
});
|
|
95519
|
+
|
|
94995
95520
|
// apps/agent/src/agent/wire.ts
|
|
94996
95521
|
import { join as join21 } from "path";
|
|
94997
95522
|
import { mkdir as mkdir6 } from "fs/promises";
|
|
95523
|
+
async function pickOpenPrUrlFromAttachments(urls, issueIdent, cmd, cwd2, onLog) {
|
|
95524
|
+
const candidates = urls.filter((url2) => GITHUB_PR_URL_RE.test(url2));
|
|
95525
|
+
let sawNonOpenPr = false;
|
|
95526
|
+
for (const url2 of candidates) {
|
|
95527
|
+
try {
|
|
95528
|
+
const res = await cmd.run(["gh", "pr", "view", url2, "--json", "state"], cwd2);
|
|
95529
|
+
const parsed = JSON.parse(res.stdout.trim());
|
|
95530
|
+
if (parsed.state === "OPEN")
|
|
95531
|
+
return { url: url2, sawNonOpenPr };
|
|
95532
|
+
if (parsed.state === "MERGED" || parsed.state === "CLOSED")
|
|
95533
|
+
sawNonOpenPr = true;
|
|
95534
|
+
} catch (err) {
|
|
95535
|
+
onLog(`! gh pr view ${url2} failed for ${issueIdent}: ${err.message}`, "yellow");
|
|
95536
|
+
}
|
|
95537
|
+
}
|
|
95538
|
+
return { url: null, sawNonOpenPr };
|
|
95539
|
+
}
|
|
95540
|
+
function githubReactionSlug(emoji3) {
|
|
95541
|
+
switch (emoji3) {
|
|
95542
|
+
case "\uD83D\uDC40":
|
|
95543
|
+
return "eyes";
|
|
95544
|
+
case "\uD83D\uDC4D":
|
|
95545
|
+
return "+1";
|
|
95546
|
+
case "\uD83D\uDC4E":
|
|
95547
|
+
return "-1";
|
|
95548
|
+
case "\u2764\uFE0F":
|
|
95549
|
+
return "heart";
|
|
95550
|
+
case "\uD83C\uDF89":
|
|
95551
|
+
return "hooray";
|
|
95552
|
+
case "\uD83D\uDE80":
|
|
95553
|
+
return "rocket";
|
|
95554
|
+
case "\uD83D\uDE04":
|
|
95555
|
+
return "laugh";
|
|
95556
|
+
case "\uD83D\uDE15":
|
|
95557
|
+
return "confused";
|
|
95558
|
+
default:
|
|
95559
|
+
return emoji3;
|
|
95560
|
+
}
|
|
95561
|
+
}
|
|
94998
95562
|
function traceCmdRunner(base2, onStart, onEnd) {
|
|
94999
95563
|
return {
|
|
95000
95564
|
run: async (cmd, cwd2) => {
|
|
@@ -95111,6 +95675,7 @@ function buildAgentCoordinator(input) {
|
|
|
95111
95675
|
tasksDir,
|
|
95112
95676
|
apiKey,
|
|
95113
95677
|
onLog,
|
|
95678
|
+
onFileLog,
|
|
95114
95679
|
onWorkersChanged,
|
|
95115
95680
|
onWorkerStarted,
|
|
95116
95681
|
onWorkerExited,
|
|
@@ -95275,21 +95840,23 @@ function buildAgentCoordinator(input) {
|
|
|
95275
95840
|
return { workerCwd, scaffoldTasksDir, scaffoldStatesDir, branch };
|
|
95276
95841
|
const probeName = issue2.identifier.toLowerCase();
|
|
95277
95842
|
const baseBranch = baseBranchFromLabels(issue2.labels) ?? cfg.prBaseBranch;
|
|
95843
|
+
let wt;
|
|
95278
95844
|
try {
|
|
95279
|
-
|
|
95280
|
-
|
|
95281
|
-
|
|
95282
|
-
|
|
95283
|
-
|
|
95284
|
-
|
|
95285
|
-
|
|
95286
|
-
|
|
95287
|
-
|
|
95288
|
-
|
|
95289
|
-
|
|
95290
|
-
|
|
95845
|
+
wt = await createWorktree(projectRoot, probeName, baseBranch, gitRunner);
|
|
95846
|
+
} catch (err) {
|
|
95847
|
+
onLog(`! worktree create failed for ${issue2.identifier}: ${err.message} \u2014 skipping (useWorktree is required)`, "red");
|
|
95848
|
+
throw err;
|
|
95849
|
+
}
|
|
95850
|
+
workerCwd = wt.cwd;
|
|
95851
|
+
branch = wt.branch;
|
|
95852
|
+
const wtLayout = projectLayout(wt.cwd);
|
|
95853
|
+
scaffoldTasksDir = wtLayout.tasksDir;
|
|
95854
|
+
scaffoldStatesDir = wtLayout.statesDir;
|
|
95855
|
+
onLog(` ${issue2.identifier} worktree: ${wt.cwd} (${wt.branch})`, "gray");
|
|
95856
|
+
try {
|
|
95857
|
+
await seedWorktreeMcpConfig(projectRoot, wt.cwd);
|
|
95291
95858
|
} catch (err) {
|
|
95292
|
-
onLog(`!
|
|
95859
|
+
onLog(`! seeding .mcp.json failed for ${issue2.identifier}: ${err.message}`, "yellow");
|
|
95293
95860
|
}
|
|
95294
95861
|
return { workerCwd, scaffoldTasksDir, scaffoldStatesDir, branch };
|
|
95295
95862
|
}
|
|
@@ -95312,7 +95879,8 @@ function buildAgentCoordinator(input) {
|
|
|
95312
95879
|
identifier: issue2.identifier,
|
|
95313
95880
|
title: issue2.title,
|
|
95314
95881
|
description: issue2.description ?? "",
|
|
95315
|
-
url: issue2.url
|
|
95882
|
+
url: issue2.url,
|
|
95883
|
+
labels: issue2.labels
|
|
95316
95884
|
},
|
|
95317
95885
|
attempt: 1,
|
|
95318
95886
|
last_error: ""
|
|
@@ -95337,7 +95905,7 @@ function buildAgentCoordinator(input) {
|
|
|
95337
95905
|
branchByChange.set(changeName, branch);
|
|
95338
95906
|
if (mode === "review") {
|
|
95339
95907
|
const wtLayout = projectLayout(workerCwd);
|
|
95340
|
-
const tasksFile = join21(wtLayout.changeDir(changeName),
|
|
95908
|
+
const tasksFile = join21(wtLayout.changeDir(changeName), AGENT_TASKS_FILENAME);
|
|
95341
95909
|
let body;
|
|
95342
95910
|
let heading;
|
|
95343
95911
|
if (trigger) {
|
|
@@ -95362,7 +95930,7 @@ function buildAgentCoordinator(input) {
|
|
|
95362
95930
|
await reactivateState2(wtLayout.stateFile(changeName), changeName);
|
|
95363
95931
|
} else if (mode === "conflict-fix") {
|
|
95364
95932
|
const wtLayout = projectLayout(workerCwd);
|
|
95365
|
-
const tasksFile = join21(wtLayout.changeDir(changeName),
|
|
95933
|
+
const tasksFile = join21(wtLayout.changeDir(changeName), AGENT_TASKS_FILENAME);
|
|
95366
95934
|
const prUrl = prByChange.get(changeName);
|
|
95367
95935
|
const body = [
|
|
95368
95936
|
`The PR for this change has merge conflicts with \`${cfg.prBaseBranch}\`.`,
|
|
@@ -95681,9 +96249,13 @@ PR: ${prUrl}` : ""
|
|
|
95681
96249
|
if (byBranch)
|
|
95682
96250
|
return byBranch;
|
|
95683
96251
|
const fromLinear = await discoverPrUrlFromLinear(issue2);
|
|
95684
|
-
if (fromLinear) {
|
|
95685
|
-
onLog(` ${issue2.identifier}: PR discovered via Linear attachment (${fromLinear})`, "gray");
|
|
95686
|
-
return fromLinear;
|
|
96252
|
+
if (fromLinear.url) {
|
|
96253
|
+
onLog(` ${issue2.identifier}: PR discovered via Linear attachment (${fromLinear.url})`, "gray");
|
|
96254
|
+
return fromLinear.url;
|
|
96255
|
+
}
|
|
96256
|
+
if (fromLinear.sawNonOpenPr) {
|
|
96257
|
+
markPrUnavailable(changeName);
|
|
96258
|
+
return null;
|
|
95687
96259
|
}
|
|
95688
96260
|
onLog(` ${issue2.identifier}: no open PR found on head=${branch} or Linear attachments; conflict scan skipped for ${PR_UNAVAILABLE_TTL_MS / 60000}m`, "gray");
|
|
95689
96261
|
markPrUnavailable(changeName);
|
|
@@ -95729,14 +96301,14 @@ PR: ${prUrl}` : ""
|
|
|
95729
96301
|
return null;
|
|
95730
96302
|
}
|
|
95731
96303
|
async function discoverPrUrlFromLinear(issue2) {
|
|
96304
|
+
let attachments;
|
|
95732
96305
|
try {
|
|
95733
|
-
|
|
95734
|
-
const match = attachments.find((a) => /^https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/\d+/.test(a.url));
|
|
95735
|
-
return match?.url ?? null;
|
|
96306
|
+
attachments = await fetchIssueAttachments(apiKey, issue2.id);
|
|
95736
96307
|
} catch (err) {
|
|
95737
96308
|
onLog(`! Linear attachments fetch failed for ${issue2.identifier}: ${err.message}`, "yellow");
|
|
95738
|
-
return null;
|
|
96309
|
+
return { url: null, sawNonOpenPr: false };
|
|
95739
96310
|
}
|
|
96311
|
+
return pickOpenPrUrlFromAttachments(attachments.map((a) => a.url), issue2.identifier, cmdRunner, projectRoot, onLog);
|
|
95740
96312
|
}
|
|
95741
96313
|
async function fetchDoneCandidates() {
|
|
95742
96314
|
if (!indicators.setDone)
|
|
@@ -95789,6 +96361,11 @@ PR: ${prUrl}` : ""
|
|
|
95789
96361
|
url: issue2.url
|
|
95790
96362
|
}
|
|
95791
96363
|
});
|
|
96364
|
+
try {
|
|
96365
|
+
await addReactionToComment(apiKey, c.id, "\uD83D\uDC40");
|
|
96366
|
+
} catch (err) {
|
|
96367
|
+
onLog(`! mention scan: Linear reaction failed for ${issue2.identifier}: ${err.message}`, "yellow");
|
|
96368
|
+
}
|
|
95792
96369
|
queued.add(issue2.id);
|
|
95793
96370
|
break;
|
|
95794
96371
|
}
|
|
@@ -95800,6 +96377,7 @@ PR: ${prUrl}` : ""
|
|
|
95800
96377
|
continue;
|
|
95801
96378
|
if (wantMention) {
|
|
95802
96379
|
const ghComments = await fetchPrIssueComments(prUrl);
|
|
96380
|
+
const prMatch = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/\d+/.exec(prUrl);
|
|
95803
96381
|
for (const c of ghComments) {
|
|
95804
96382
|
if (!containsHandle(c.body, handle))
|
|
95805
96383
|
continue;
|
|
@@ -95815,6 +96393,14 @@ PR: ${prUrl}` : ""
|
|
|
95815
96393
|
url: c.url
|
|
95816
96394
|
}
|
|
95817
96395
|
});
|
|
96396
|
+
if (prMatch) {
|
|
96397
|
+
const [, owner, repo] = prMatch;
|
|
96398
|
+
try {
|
|
96399
|
+
await addGithubReactionToComment({ owner, repo, kind: "issue" }, c.id, "\uD83D\uDC40");
|
|
96400
|
+
} catch (err) {
|
|
96401
|
+
onLog(`! mention scan: GitHub reaction failed for ${prUrl}: ${err.message}`, "yellow");
|
|
96402
|
+
}
|
|
96403
|
+
}
|
|
95818
96404
|
queued.add(issue2.id);
|
|
95819
96405
|
break;
|
|
95820
96406
|
}
|
|
@@ -95982,6 +96568,11 @@ PR: ${prUrl}` : ""
|
|
|
95982
96568
|
prByChange.set(changeName, found);
|
|
95983
96569
|
return found;
|
|
95984
96570
|
}
|
|
96571
|
+
async function addGithubReactionToComment(source, commentId, emoji3) {
|
|
96572
|
+
const content = githubReactionSlug(emoji3);
|
|
96573
|
+
const path = source.kind === "issue" ? `repos/${source.owner}/${source.repo}/issues/comments/${commentId}/reactions` : `repos/${source.owner}/${source.repo}/pulls/comments/${commentId}/reactions`;
|
|
96574
|
+
await cmdRunner.run(["gh", "api", "-X", "POST", path, "-f", `content=${content}`], projectRoot);
|
|
96575
|
+
}
|
|
95985
96576
|
async function fetchPrIssueComments(prUrl) {
|
|
95986
96577
|
const m = /^https:\/\/github\.com\/([^/]+)\/([^/]+)\/pull\/(\d+)/.exec(prUrl);
|
|
95987
96578
|
if (!m)
|
|
@@ -95993,7 +96584,7 @@ PR: ${prUrl}` : ""
|
|
|
95993
96584
|
"api",
|
|
95994
96585
|
`repos/${owner}/${repo}/issues/${num}/comments`,
|
|
95995
96586
|
"--jq",
|
|
95996
|
-
"[.[] | {body: .body, createdAt: .created_at, author: .user.login, url: .html_url}]"
|
|
96587
|
+
"[.[] | {id: .id, body: .body, createdAt: .created_at, author: .user.login, url: .html_url}]"
|
|
95997
96588
|
], projectRoot);
|
|
95998
96589
|
const parsed = JSON.parse(res.stdout || "[]");
|
|
95999
96590
|
return parsed;
|
|
@@ -96020,6 +96611,7 @@ PR: ${prUrl}` : ""
|
|
|
96020
96611
|
},
|
|
96021
96612
|
checkPrStatus,
|
|
96022
96613
|
onLog,
|
|
96614
|
+
...onFileLog ? { onFileLog } : {},
|
|
96023
96615
|
onWorkersChanged,
|
|
96024
96616
|
getIterationCount: async (changeName) => {
|
|
96025
96617
|
const root = cwdByChange.get(changeName) ?? projectRoot;
|
|
@@ -96037,17 +96629,65 @@ PR: ${prUrl}` : ""
|
|
|
96037
96629
|
...indicators.setConflicted !== undefined ? { setConflicted: indicators.setConflicted } : {},
|
|
96038
96630
|
...indicators.clearConflicted !== undefined ? { clearConflicted: indicators.clearConflicted } : {},
|
|
96039
96631
|
...indicators.clearReview !== undefined ? { clearReview: indicators.clearReview } : {},
|
|
96632
|
+
...indicators.getAutoMerge !== undefined ? { getAutoMerge: indicators.getAutoMerge } : {},
|
|
96040
96633
|
postComments: cfg.linear.postComments,
|
|
96041
96634
|
commentEveryIterations: cfg.linear.updateEveryIterations,
|
|
96042
96635
|
...args.maxTickets > 0 ? { maxTickets: args.maxTickets } : {}
|
|
96043
96636
|
});
|
|
96044
96637
|
const filterDesc = describeIndicators(indicators, team, assignee);
|
|
96638
|
+
const baselineCfg = cfg.preExistingErrorCheck;
|
|
96639
|
+
const baselineCommands = resolveBaselineCommands(cfg);
|
|
96640
|
+
const baselineEnabled = (args.preExistingErrorCheck ?? baselineCfg.enabled) === true;
|
|
96641
|
+
const baselineTeam = team;
|
|
96642
|
+
const runBaselineGateOnce = async () => {
|
|
96643
|
+
if (!baselineEnabled)
|
|
96644
|
+
return;
|
|
96645
|
+
await runBaselineGate({
|
|
96646
|
+
enabled: true,
|
|
96647
|
+
commands: baselineCommands,
|
|
96648
|
+
baseBranch: baselineCfg.baseBranch,
|
|
96649
|
+
outputCharLimit: baselineCfg.outputCharLimit,
|
|
96650
|
+
cwd: projectRoot,
|
|
96651
|
+
cmdRunner,
|
|
96652
|
+
gitRunner,
|
|
96653
|
+
coordinator: coord,
|
|
96654
|
+
...baselineTeam && apiKey ? {
|
|
96655
|
+
linear: {
|
|
96656
|
+
findOpen: () => findOpenIssueByLabel(apiKey, baselineTeam, baselineCfg.label),
|
|
96657
|
+
create: async (title, description) => {
|
|
96658
|
+
const teamId = await fetchTeamIdByKey(apiKey, baselineTeam);
|
|
96659
|
+
if (!teamId)
|
|
96660
|
+
throw new Error("Linear team not found");
|
|
96661
|
+
let labelIds;
|
|
96662
|
+
try {
|
|
96663
|
+
const labelId = await resolveLabelIdForTeam(baselineTeam, baselineCfg.label);
|
|
96664
|
+
if (labelId)
|
|
96665
|
+
labelIds = [labelId];
|
|
96666
|
+
} catch {}
|
|
96667
|
+
return createIssue(apiKey, {
|
|
96668
|
+
teamId,
|
|
96669
|
+
title,
|
|
96670
|
+
description,
|
|
96671
|
+
...labelIds ? { labelIds } : {}
|
|
96672
|
+
});
|
|
96673
|
+
},
|
|
96674
|
+
updateDescription: (id, description) => updateIssueDescription(apiKey, id, description)
|
|
96675
|
+
}
|
|
96676
|
+
} : {},
|
|
96677
|
+
onLog
|
|
96678
|
+
});
|
|
96679
|
+
};
|
|
96680
|
+
async function resolveLabelIdForTeam(teamKey, labelName) {
|
|
96681
|
+
const fakeIssue = { identifier: `${teamKey}-0` };
|
|
96682
|
+
return resolveLabelId(fakeIssue, labelName);
|
|
96683
|
+
}
|
|
96045
96684
|
return {
|
|
96046
96685
|
coord,
|
|
96047
96686
|
filterDesc,
|
|
96048
96687
|
concurrency,
|
|
96049
96688
|
pollInterval,
|
|
96050
|
-
getWorkerCwd: (changeName) => cwdByChange.get(changeName)
|
|
96689
|
+
getWorkerCwd: (changeName) => cwdByChange.get(changeName),
|
|
96690
|
+
runBaselineGate: runBaselineGateOnce
|
|
96051
96691
|
};
|
|
96052
96692
|
}
|
|
96053
96693
|
function describeIndicators(indicators, team, assignee) {
|
|
@@ -96068,10 +96708,11 @@ function describeIndicators(indicators, team, assignee) {
|
|
|
96068
96708
|
}
|
|
96069
96709
|
return parts.join(", ");
|
|
96070
96710
|
}
|
|
96071
|
-
var bunGitRunner, bunCmdRunner;
|
|
96711
|
+
var GITHUB_PR_URL_RE, bunGitRunner, bunCmdRunner;
|
|
96072
96712
|
var init_wire = __esm(() => {
|
|
96073
96713
|
init_log();
|
|
96074
96714
|
init_layout();
|
|
96715
|
+
init_tasks_md();
|
|
96075
96716
|
init_workflow();
|
|
96076
96717
|
init_types2();
|
|
96077
96718
|
init_coordinator();
|
|
@@ -96079,6 +96720,9 @@ var init_wire = __esm(() => {
|
|
|
96079
96720
|
init_worktree();
|
|
96080
96721
|
init_ci();
|
|
96081
96722
|
init_post_task();
|
|
96723
|
+
init_gate();
|
|
96724
|
+
init_workflow();
|
|
96725
|
+
GITHUB_PR_URL_RE = /^https:\/\/github\.com\/[^/]+\/[^/]+\/pull\/\d+/;
|
|
96082
96726
|
bunGitRunner = {
|
|
96083
96727
|
run: async (args, cwd2) => {
|
|
96084
96728
|
const proc = Bun.spawn({ cmd: ["git", ...args], cwd: cwd2, stdout: "pipe", stderr: "pipe" });
|
|
@@ -96155,15 +96799,286 @@ function deriveOpenSpecPhase(inputs) {
|
|
|
96155
96799
|
return "implement";
|
|
96156
96800
|
return "tasks";
|
|
96157
96801
|
}
|
|
96802
|
+
function shouldShowPhasePipeline(phase) {
|
|
96803
|
+
return phase === "proposal" || phase === "design" || phase === "tasks";
|
|
96804
|
+
}
|
|
96805
|
+
function shouldShowSubtasksPanel(phase, showPendingTasks, hasSubtasks) {
|
|
96806
|
+
if (!showPendingTasks || !hasSubtasks)
|
|
96807
|
+
return false;
|
|
96808
|
+
return phase == null || phase === "implement" || phase === "done";
|
|
96809
|
+
}
|
|
96810
|
+
function shouldShowProgressBar(phase, showPendingTasks, hasProgress) {
|
|
96811
|
+
if (showPendingTasks || !hasProgress)
|
|
96812
|
+
return false;
|
|
96813
|
+
return phase == null || phase === "implement" || phase === "done";
|
|
96814
|
+
}
|
|
96815
|
+
function phasePipeline(phase) {
|
|
96816
|
+
if (phase === "done") {
|
|
96817
|
+
return PIPELINE_PHASES.map((p) => ({ phase: p, label: p, status: "done" }));
|
|
96818
|
+
}
|
|
96819
|
+
const idx = PIPELINE_PHASES.indexOf(phase);
|
|
96820
|
+
return PIPELINE_PHASES.map((p, i) => ({
|
|
96821
|
+
phase: p,
|
|
96822
|
+
label: p,
|
|
96823
|
+
status: i < idx ? "done" : i === idx ? "current" : "pending"
|
|
96824
|
+
}));
|
|
96825
|
+
}
|
|
96826
|
+
var PIPELINE_PHASES;
|
|
96827
|
+
var init_phase = __esm(() => {
|
|
96828
|
+
PIPELINE_PHASES = [
|
|
96829
|
+
"proposal",
|
|
96830
|
+
"design",
|
|
96831
|
+
"tasks",
|
|
96832
|
+
"implement"
|
|
96833
|
+
];
|
|
96834
|
+
});
|
|
96835
|
+
|
|
96836
|
+
// apps/agent/src/hooks/useTerminalSize.ts
|
|
96837
|
+
function readSize2() {
|
|
96838
|
+
return {
|
|
96839
|
+
columns: process.stdout.columns ?? 80,
|
|
96840
|
+
rows: process.stdout.rows ?? 24
|
|
96841
|
+
};
|
|
96842
|
+
}
|
|
96843
|
+
function useTerminalSize2() {
|
|
96844
|
+
const [size2, setSize] = import_react59.useState(() => ({
|
|
96845
|
+
...readSize2(),
|
|
96846
|
+
resizeKey: 0
|
|
96847
|
+
}));
|
|
96848
|
+
import_react59.useEffect(() => {
|
|
96849
|
+
if (!process.stdout.isTTY)
|
|
96850
|
+
return;
|
|
96851
|
+
const onResize = () => {
|
|
96852
|
+
const { columns, rows } = readSize2();
|
|
96853
|
+
setSize((prev) => {
|
|
96854
|
+
if (prev.columns === columns && prev.rows === rows)
|
|
96855
|
+
return prev;
|
|
96856
|
+
return { columns, rows, resizeKey: prev.resizeKey + 1 };
|
|
96857
|
+
});
|
|
96858
|
+
};
|
|
96859
|
+
process.stdout.on("resize", onResize);
|
|
96860
|
+
return () => {
|
|
96861
|
+
process.stdout.off("resize", onResize);
|
|
96862
|
+
};
|
|
96863
|
+
}, []);
|
|
96864
|
+
return size2;
|
|
96865
|
+
}
|
|
96866
|
+
var import_react59;
|
|
96867
|
+
var init_useTerminalSize2 = __esm(() => {
|
|
96868
|
+
import_react59 = __toESM(require_react(), 1);
|
|
96869
|
+
});
|
|
96870
|
+
|
|
96871
|
+
// apps/agent/src/components/SteeringField.tsx
|
|
96872
|
+
function reducer2(state, action) {
|
|
96873
|
+
switch (action.type) {
|
|
96874
|
+
case "toggleFocus":
|
|
96875
|
+
return { ...state, focused: !state.focused };
|
|
96876
|
+
case "clearAndBlur":
|
|
96877
|
+
return { ...state, buffer: "", cursor: 0, focused: false };
|
|
96878
|
+
case "insert": {
|
|
96879
|
+
const before2 = state.buffer.slice(0, state.cursor);
|
|
96880
|
+
const after2 = state.buffer.slice(state.cursor);
|
|
96881
|
+
return {
|
|
96882
|
+
...state,
|
|
96883
|
+
buffer: before2 + action.chars + after2,
|
|
96884
|
+
cursor: state.cursor + action.chars.length
|
|
96885
|
+
};
|
|
96886
|
+
}
|
|
96887
|
+
case "backspace": {
|
|
96888
|
+
if (state.cursor === 0)
|
|
96889
|
+
return state;
|
|
96890
|
+
return {
|
|
96891
|
+
...state,
|
|
96892
|
+
buffer: state.buffer.slice(0, state.cursor - 1) + state.buffer.slice(state.cursor),
|
|
96893
|
+
cursor: state.cursor - 1
|
|
96894
|
+
};
|
|
96895
|
+
}
|
|
96896
|
+
case "moveLeft":
|
|
96897
|
+
return { ...state, cursor: Math.max(0, state.cursor - 1) };
|
|
96898
|
+
case "moveRight":
|
|
96899
|
+
return { ...state, cursor: Math.min(state.buffer.length, state.cursor + 1) };
|
|
96900
|
+
case "status":
|
|
96901
|
+
return { ...state, status: action.value };
|
|
96902
|
+
}
|
|
96903
|
+
}
|
|
96904
|
+
function SteeringField({
|
|
96905
|
+
active,
|
|
96906
|
+
width,
|
|
96907
|
+
onSubmit,
|
|
96908
|
+
onFocusChange,
|
|
96909
|
+
initialBuffer = "",
|
|
96910
|
+
initialCursor,
|
|
96911
|
+
initialFocused = false,
|
|
96912
|
+
onStateChange
|
|
96913
|
+
}) {
|
|
96914
|
+
const [state, dispatch] = import_react60.useReducer(reducer2, { initialBuffer, initialCursor, initialFocused }, (init2) => ({
|
|
96915
|
+
buffer: init2.initialBuffer,
|
|
96916
|
+
cursor: init2.initialCursor ?? init2.initialBuffer.length,
|
|
96917
|
+
focused: init2.initialFocused,
|
|
96918
|
+
status: "idle"
|
|
96919
|
+
}));
|
|
96920
|
+
const { buffer, cursor: cursor4, focused, status } = state;
|
|
96921
|
+
const stateRef = import_react60.useRef(state);
|
|
96922
|
+
stateRef.current = state;
|
|
96923
|
+
const hintTimerRef = import_react60.useRef(null);
|
|
96924
|
+
import_react60.useEffect(() => {
|
|
96925
|
+
onFocusChange?.(focused);
|
|
96926
|
+
}, [focused, onFocusChange]);
|
|
96927
|
+
import_react60.useEffect(() => {
|
|
96928
|
+
onStateChange?.({ buffer, cursor: cursor4, focused });
|
|
96929
|
+
}, [buffer, cursor4, focused, onStateChange]);
|
|
96930
|
+
import_react60.useEffect(() => {
|
|
96931
|
+
return () => {
|
|
96932
|
+
if (hintTimerRef.current)
|
|
96933
|
+
clearTimeout(hintTimerRef.current);
|
|
96934
|
+
};
|
|
96935
|
+
}, []);
|
|
96936
|
+
function flashStatus(next) {
|
|
96937
|
+
dispatch({ type: "status", value: next });
|
|
96938
|
+
if (hintTimerRef.current)
|
|
96939
|
+
clearTimeout(hintTimerRef.current);
|
|
96940
|
+
hintTimerRef.current = setTimeout(() => dispatch({ type: "status", value: "idle" }), STATUS_HINT_MS);
|
|
96941
|
+
}
|
|
96942
|
+
use_input_default((input, key) => {
|
|
96943
|
+
if (key.ctrl && (input === "s" || input === "S")) {
|
|
96944
|
+
dispatch({ type: "toggleFocus" });
|
|
96945
|
+
return;
|
|
96946
|
+
}
|
|
96947
|
+
if (!stateRef.current.focused)
|
|
96948
|
+
return;
|
|
96949
|
+
if (key.escape) {
|
|
96950
|
+
dispatch({ type: "clearAndBlur" });
|
|
96951
|
+
return;
|
|
96952
|
+
}
|
|
96953
|
+
if (key.return) {
|
|
96954
|
+
const trimmed = stateRef.current.buffer.trim();
|
|
96955
|
+
if (trimmed.length === 0)
|
|
96956
|
+
return;
|
|
96957
|
+
Promise.resolve().then(() => onSubmit(trimmed)).then(() => {
|
|
96958
|
+
flashStatus("sent");
|
|
96959
|
+
}).catch(() => {
|
|
96960
|
+
flashStatus("failed");
|
|
96961
|
+
});
|
|
96962
|
+
dispatch({ type: "clearAndBlur" });
|
|
96963
|
+
return;
|
|
96964
|
+
}
|
|
96965
|
+
if (key.backspace || key.delete) {
|
|
96966
|
+
dispatch({ type: "backspace" });
|
|
96967
|
+
return;
|
|
96968
|
+
}
|
|
96969
|
+
if (key.leftArrow) {
|
|
96970
|
+
dispatch({ type: "moveLeft" });
|
|
96971
|
+
return;
|
|
96972
|
+
}
|
|
96973
|
+
if (key.rightArrow) {
|
|
96974
|
+
dispatch({ type: "moveRight" });
|
|
96975
|
+
return;
|
|
96976
|
+
}
|
|
96977
|
+
if (key.tab || key.upArrow || key.downArrow || key.ctrl || key.meta)
|
|
96978
|
+
return;
|
|
96979
|
+
if (!input)
|
|
96980
|
+
return;
|
|
96981
|
+
const printable = input.replace(/[\x00-\x1f\x7f]/g, "");
|
|
96982
|
+
if (!printable)
|
|
96983
|
+
return;
|
|
96984
|
+
dispatch({ type: "insert", chars: printable });
|
|
96985
|
+
}, { isActive: active });
|
|
96986
|
+
if (!active)
|
|
96987
|
+
return null;
|
|
96988
|
+
const placeholder = status === "sent" ? PLACEHOLDER_SENT : status === "failed" ? PLACEHOLDER_FAILED : PLACEHOLDER_IDLE;
|
|
96989
|
+
const borderColor = focused ? "yellow" : "gray";
|
|
96990
|
+
const placeholderColor = status === "sent" ? "green" : status === "failed" ? "red" : "gray";
|
|
96991
|
+
const innerWidth = Math.max(0, width - 4);
|
|
96992
|
+
const labelText = " STEER (CTRL+S) ";
|
|
96993
|
+
const dashes = Math.max(0, innerWidth - labelText.length);
|
|
96994
|
+
const left = Math.floor(dashes / 2);
|
|
96995
|
+
const right = dashes - left;
|
|
96996
|
+
const before2 = buffer.slice(0, cursor4);
|
|
96997
|
+
const at2 = buffer.slice(cursor4, cursor4 + 1) || " ";
|
|
96998
|
+
const after2 = buffer.slice(cursor4 + 1);
|
|
96999
|
+
return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
97000
|
+
flexDirection: "column",
|
|
97001
|
+
width,
|
|
97002
|
+
children: [
|
|
97003
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97004
|
+
color: borderColor,
|
|
97005
|
+
children: `\u256D${"\u2500".repeat(left)}${labelText}${"\u2500".repeat(right)}\u256E`
|
|
97006
|
+
}, undefined, false, undefined, this),
|
|
97007
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
97008
|
+
borderStyle: "round",
|
|
97009
|
+
borderTop: false,
|
|
97010
|
+
borderColor,
|
|
97011
|
+
width,
|
|
97012
|
+
paddingX: 1,
|
|
97013
|
+
children: focused ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
97014
|
+
children: [
|
|
97015
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97016
|
+
color: "white",
|
|
97017
|
+
children: "> "
|
|
97018
|
+
}, undefined, false, undefined, this),
|
|
97019
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97020
|
+
children: before2
|
|
97021
|
+
}, undefined, false, undefined, this),
|
|
97022
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97023
|
+
inverse: true,
|
|
97024
|
+
children: at2
|
|
97025
|
+
}, undefined, false, undefined, this),
|
|
97026
|
+
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97027
|
+
children: after2
|
|
97028
|
+
}, undefined, false, undefined, this)
|
|
97029
|
+
]
|
|
97030
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97031
|
+
color: placeholderColor,
|
|
97032
|
+
dimColor: status === "idle",
|
|
97033
|
+
children: placeholder
|
|
97034
|
+
}, undefined, false, undefined, this)
|
|
97035
|
+
}, undefined, false, undefined, this)
|
|
97036
|
+
]
|
|
97037
|
+
}, undefined, true, undefined, this);
|
|
97038
|
+
}
|
|
97039
|
+
var import_react60, jsx_dev_runtime9, STATUS_HINT_MS = 2000, PLACEHOLDER_IDLE = "CTRL+S to steer", PLACEHOLDER_SENT = "steered \u2192 next iteration", PLACEHOLDER_FAILED = "send failed";
|
|
97040
|
+
var init_SteeringField = __esm(async () => {
|
|
97041
|
+
await init_build2();
|
|
97042
|
+
import_react60 = __toESM(require_react(), 1);
|
|
97043
|
+
jsx_dev_runtime9 = __toESM(require_jsx_dev_runtime(), 1);
|
|
97044
|
+
});
|
|
96158
97045
|
|
|
96159
97046
|
// apps/agent/src/components/AgentMode.tsx
|
|
96160
97047
|
import { join as join22 } from "path";
|
|
97048
|
+
async function appendSteeringImpl(changeDir, message) {
|
|
97049
|
+
await runWithContext(createDefaultContext(), async () => {
|
|
97050
|
+
appendSteeringMessage(changeDir, message);
|
|
97051
|
+
});
|
|
97052
|
+
}
|
|
96161
97053
|
function nextId() {
|
|
96162
97054
|
lineCounter += 1;
|
|
96163
97055
|
return `${Date.now()}-${lineCounter}`;
|
|
96164
97056
|
}
|
|
96165
|
-
function
|
|
96166
|
-
|
|
97057
|
+
function parseSubtasks(tasksMd) {
|
|
97058
|
+
const out = [];
|
|
97059
|
+
let skipSection = false;
|
|
97060
|
+
for (const line of tasksMd.split(`
|
|
97061
|
+
`)) {
|
|
97062
|
+
const heading = line.match(/^##\s+(.+?)\s*$/);
|
|
97063
|
+
if (heading) {
|
|
97064
|
+
const title = heading[1].trim();
|
|
97065
|
+
skipSection = title.toLowerCase() === "planning" || isFlowTaskHeading(title);
|
|
97066
|
+
continue;
|
|
97067
|
+
}
|
|
97068
|
+
if (skipSection)
|
|
97069
|
+
continue;
|
|
97070
|
+
const m = line.match(/^- \[([ xX])\] (.+)$/);
|
|
97071
|
+
if (m)
|
|
97072
|
+
out.push({ done: m[1] !== " ", text: m[2].trim() });
|
|
97073
|
+
}
|
|
97074
|
+
return out;
|
|
97075
|
+
}
|
|
97076
|
+
function orderSubtasksForCappedDisplay(subtasks) {
|
|
97077
|
+
const pending = [];
|
|
97078
|
+
const done = [];
|
|
97079
|
+
for (const s of subtasks)
|
|
97080
|
+
(s.done ? done : pending).push(s);
|
|
97081
|
+
return [...pending, ...done];
|
|
96167
97082
|
}
|
|
96168
97083
|
function fmtCmd(argv) {
|
|
96169
97084
|
const joined = argv.join(" ");
|
|
@@ -96213,28 +97128,28 @@ function LabeledBox({
|
|
|
96213
97128
|
const dashes = Math.max(0, innerWidth - visualLen);
|
|
96214
97129
|
const left = Math.floor(dashes / 2);
|
|
96215
97130
|
const right = dashes - left;
|
|
96216
|
-
return /* @__PURE__ */
|
|
97131
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
96217
97132
|
flexDirection: "column",
|
|
96218
97133
|
width,
|
|
96219
97134
|
children: [
|
|
96220
|
-
labelNode ? /* @__PURE__ */
|
|
97135
|
+
labelNode ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
96221
97136
|
flexDirection: "row",
|
|
96222
97137
|
children: [
|
|
96223
|
-
/* @__PURE__ */
|
|
97138
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96224
97139
|
color: borderColor,
|
|
96225
97140
|
children: `\u256D${"\u2500".repeat(left)}`
|
|
96226
97141
|
}, undefined, false, undefined, this),
|
|
96227
97142
|
labelNode,
|
|
96228
|
-
/* @__PURE__ */
|
|
97143
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96229
97144
|
color: borderColor,
|
|
96230
97145
|
children: `${"\u2500".repeat(right)}\u256E`
|
|
96231
97146
|
}, undefined, false, undefined, this)
|
|
96232
97147
|
]
|
|
96233
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */
|
|
97148
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96234
97149
|
color: borderColor,
|
|
96235
97150
|
children: `\u256D${"\u2500".repeat(left)} ${label ?? ""} ${"\u2500".repeat(right)}\u256E`
|
|
96236
97151
|
}, undefined, false, undefined, this),
|
|
96237
|
-
/* @__PURE__ */
|
|
97152
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
96238
97153
|
borderStyle: "round",
|
|
96239
97154
|
borderTop: false,
|
|
96240
97155
|
borderColor,
|
|
@@ -96247,13 +97162,13 @@ function LabeledBox({
|
|
|
96247
97162
|
}
|
|
96248
97163
|
function Link({ url: url2, label, color }) {
|
|
96249
97164
|
if (!HYPERLINKS_SUPPORTED)
|
|
96250
|
-
return /* @__PURE__ */
|
|
97165
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96251
97166
|
color,
|
|
96252
97167
|
children: label
|
|
96253
97168
|
}, undefined, false, undefined, this);
|
|
96254
|
-
return /* @__PURE__ */
|
|
97169
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Transform, {
|
|
96255
97170
|
transform: (output) => `\x1B]8;;${url2}\x07${output}\x1B]8;;\x07`,
|
|
96256
|
-
children: /* @__PURE__ */
|
|
97171
|
+
children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96257
97172
|
color,
|
|
96258
97173
|
underline: true,
|
|
96259
97174
|
children: label
|
|
@@ -96369,19 +97284,36 @@ function displayTailLines(activeCount) {
|
|
|
96369
97284
|
return 8;
|
|
96370
97285
|
return 5;
|
|
96371
97286
|
}
|
|
96372
|
-
function AgentMode({
|
|
97287
|
+
function AgentMode({
|
|
97288
|
+
args,
|
|
97289
|
+
projectRoot,
|
|
97290
|
+
statesDir,
|
|
97291
|
+
tasksDir,
|
|
97292
|
+
appendSteering = appendSteeringImpl,
|
|
97293
|
+
buildCoordinator = buildAgentCoordinator,
|
|
97294
|
+
ensureConfig = ensureRalphyConfig,
|
|
97295
|
+
loadConfig = loadRalphyConfig
|
|
97296
|
+
}) {
|
|
96373
97297
|
const { exit } = use_app_default();
|
|
96374
97298
|
const { stdout } = use_stdout_default();
|
|
96375
97299
|
const { isRawModeSupported } = use_stdin_default();
|
|
96376
|
-
const
|
|
96377
|
-
|
|
96378
|
-
|
|
96379
|
-
|
|
96380
|
-
|
|
96381
|
-
|
|
96382
|
-
const
|
|
96383
|
-
const
|
|
96384
|
-
const [
|
|
97300
|
+
const { columns, rows, resizeKey } = useTerminalSize2();
|
|
97301
|
+
import_react61.useEffect(() => {
|
|
97302
|
+
if (resizeKey === 0)
|
|
97303
|
+
return;
|
|
97304
|
+
stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
97305
|
+
}, [resizeKey, stdout]);
|
|
97306
|
+
const [logs, setLogs] = import_react61.useState([]);
|
|
97307
|
+
const [, setTick] = import_react61.useState(0);
|
|
97308
|
+
const [clock, setClock] = import_react61.useState(0);
|
|
97309
|
+
const [focusedIdx, setFocusedIdx] = import_react61.useState(0);
|
|
97310
|
+
const [showPendingTasks, setShowPendingTasks] = import_react61.useState(true);
|
|
97311
|
+
const [showAllSubtasks, setShowAllSubtasks] = import_react61.useState(false);
|
|
97312
|
+
const coordRef = import_react61.useRef(null);
|
|
97313
|
+
const workerMetaRef = import_react61.useRef(new Map);
|
|
97314
|
+
const nextPollAtRef = import_react61.useRef(0);
|
|
97315
|
+
const cfgRef = import_react61.useRef(null);
|
|
97316
|
+
const [pollStatus, setPollStatus] = import_react61.useState({
|
|
96385
97317
|
state: "idle",
|
|
96386
97318
|
lastFound: null,
|
|
96387
97319
|
lastAdded: null,
|
|
@@ -96394,20 +97326,20 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96394
97326
|
setLogs((prev) => [...prev, { id: nextId(), text, color }]);
|
|
96395
97327
|
logCoord(text, workerLogFile);
|
|
96396
97328
|
}
|
|
96397
|
-
|
|
97329
|
+
import_react61.useEffect(() => {
|
|
96398
97330
|
let pollTimer = null;
|
|
96399
97331
|
let cancelled = false;
|
|
96400
97332
|
async function init2() {
|
|
96401
97333
|
logSession(`=== session start ${SESSION_START} ===`);
|
|
96402
|
-
const cfgPath = await
|
|
96403
|
-
const cfg2 = await
|
|
97334
|
+
const cfgPath = await ensureConfig(projectRoot);
|
|
97335
|
+
const cfg2 = await loadConfig(projectRoot);
|
|
96404
97336
|
cfgRef.current = cfg2;
|
|
96405
97337
|
appendLog(`agent mode v${VERSION} \u2014 config: ${cfgPath}`, "gray");
|
|
96406
97338
|
const apiKey = process.env["LINEAR_API_KEY"];
|
|
96407
97339
|
if (!apiKey) {
|
|
96408
97340
|
throw new Error("LINEAR_API_KEY not set \u2014 cannot poll Linear");
|
|
96409
97341
|
}
|
|
96410
|
-
const { coord: coord2, filterDesc, concurrency, pollInterval } =
|
|
97342
|
+
const { coord: coord2, filterDesc, concurrency, pollInterval, runBaselineGate: runBaselineGate2 } = buildCoordinator({
|
|
96411
97343
|
args,
|
|
96412
97344
|
cfg: cfg2,
|
|
96413
97345
|
projectRoot,
|
|
@@ -96415,6 +97347,7 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96415
97347
|
tasksDir,
|
|
96416
97348
|
apiKey,
|
|
96417
97349
|
onLog: appendLog,
|
|
97350
|
+
onFileLog: (text) => logCoord(text),
|
|
96418
97351
|
onWorkersChanged: () => setTick((t) => t + 1),
|
|
96419
97352
|
onWorkerStarted: (changeName, dir, logFile, changeDir) => {
|
|
96420
97353
|
logSession(`worker-started ${changeName} log=${logFile}`, logFile);
|
|
@@ -96428,6 +97361,7 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96428
97361
|
phaseDetail: "",
|
|
96429
97362
|
phaseStartedAt: Date.now(),
|
|
96430
97363
|
currentTask: null,
|
|
97364
|
+
subtasks: [],
|
|
96431
97365
|
taskProgress: null,
|
|
96432
97366
|
openspecPhase: null,
|
|
96433
97367
|
prUrl: null,
|
|
@@ -96483,6 +97417,13 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96483
97417
|
if (cancelled)
|
|
96484
97418
|
return;
|
|
96485
97419
|
setPollStatus((p) => ({ ...p, state: "polling", filterDesc }));
|
|
97420
|
+
try {
|
|
97421
|
+
await runBaselineGate2();
|
|
97422
|
+
} catch (err) {
|
|
97423
|
+
appendLog(`! baseline gate failed: ${err.message}`, "yellow");
|
|
97424
|
+
}
|
|
97425
|
+
if (cancelled)
|
|
97426
|
+
return;
|
|
96486
97427
|
const { found, added, buckets, prStatus } = await coord2.pollOnce();
|
|
96487
97428
|
if (cancelled)
|
|
96488
97429
|
return;
|
|
@@ -96554,7 +97495,7 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96554
97495
|
process.off("SIGTERM", onSig);
|
|
96555
97496
|
};
|
|
96556
97497
|
}, []);
|
|
96557
|
-
|
|
97498
|
+
import_react61.useEffect(() => {
|
|
96558
97499
|
let cancelled = false;
|
|
96559
97500
|
const interval = setInterval(() => {
|
|
96560
97501
|
if (cancelled)
|
|
@@ -96581,8 +97522,9 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96581
97522
|
designFile.exists().then((ok) => ok ? designFile.text() : null)
|
|
96582
97523
|
]);
|
|
96583
97524
|
if (tasksText !== null) {
|
|
96584
|
-
const
|
|
96585
|
-
meta3.
|
|
97525
|
+
const subtasks = parseSubtasks(tasksText);
|
|
97526
|
+
meta3.subtasks = subtasks;
|
|
97527
|
+
meta3.currentTask = subtasks.find((s) => !s.done)?.text ?? null;
|
|
96586
97528
|
const { checked, total } = countProgress(tasksText);
|
|
96587
97529
|
meta3.taskProgress = total > 0 ? { checked, total } : null;
|
|
96588
97530
|
}
|
|
@@ -96611,10 +97553,26 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96611
97553
|
const now2 = Date.now();
|
|
96612
97554
|
const secsToNextPoll = nextPollAtRef.current ? Math.max(0, Math.ceil((nextPollAtRef.current - now2) / 1000)) : null;
|
|
96613
97555
|
const activeCount = coord?.activeCount ?? 0;
|
|
96614
|
-
const termWidth =
|
|
96615
|
-
const termHeight =
|
|
97556
|
+
const termWidth = columns - 2;
|
|
97557
|
+
const termHeight = rows;
|
|
96616
97558
|
const safeFocusedIdx = activeCount > 0 ? Math.min(focusedIdx, activeCount - 1) : 0;
|
|
97559
|
+
const steeringFocusedRef = import_react61.useRef(false);
|
|
97560
|
+
const steeringBufferRef = import_react61.useRef("");
|
|
97561
|
+
const steeringCursorRef = import_react61.useRef(0);
|
|
97562
|
+
const steeringFocusedInitRef = import_react61.useRef(false);
|
|
96617
97563
|
use_input_default((input, key) => {
|
|
97564
|
+
if (steeringFocusedRef.current)
|
|
97565
|
+
return;
|
|
97566
|
+
if (key.ctrl && key.meta && (input === "t" || input === "T")) {
|
|
97567
|
+
if (activeCount > 0)
|
|
97568
|
+
setShowAllSubtasks((v) => !v);
|
|
97569
|
+
return;
|
|
97570
|
+
}
|
|
97571
|
+
if (key.ctrl && (input === "t" || input === "T")) {
|
|
97572
|
+
if (activeCount > 0)
|
|
97573
|
+
setShowPendingTasks((v) => !v);
|
|
97574
|
+
return;
|
|
97575
|
+
}
|
|
96618
97576
|
if (activeCount === 0)
|
|
96619
97577
|
return;
|
|
96620
97578
|
if (key.tab || key.rightArrow) {
|
|
@@ -96626,57 +97584,80 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96626
97584
|
if (!isNaN(n) && n >= 1 && n <= activeCount)
|
|
96627
97585
|
setFocusedIdx(n - 1);
|
|
96628
97586
|
}
|
|
96629
|
-
}, { isActive: isRawModeSupported && activeCount >
|
|
97587
|
+
}, { isActive: isRawModeSupported && activeCount > 0 });
|
|
97588
|
+
const focusedWorker = coordRef.current?.activeWorkers[safeFocusedIdx];
|
|
97589
|
+
const steeringActive = isRawModeSupported && activeCount > 0 && focusedWorker !== undefined;
|
|
96630
97590
|
const nonFocusedCount = Math.max(0, activeCount - 1);
|
|
96631
97591
|
const tasksBoxLines = activeCount > 1 ? 5 : 0;
|
|
96632
|
-
const
|
|
96633
|
-
const
|
|
96634
|
-
const FIXED_OVERHEAD = logsBoxLines + 5 + 6 + tasksBoxLines + 8 + nonFocusedCount * 4;
|
|
97592
|
+
const steeringBoxLines = steeringActive ? 3 : 0;
|
|
97593
|
+
const FIXED_OVERHEAD = 5 + 7 + tasksBoxLines + 8 + steeringBoxLines + nonFocusedCount * 4;
|
|
96635
97594
|
const focusedTailLines = Math.max(3, termHeight - FIXED_OVERHEAD);
|
|
96636
97595
|
const compactTailLines = displayTailLines(activeCount);
|
|
96637
|
-
return /* @__PURE__ */
|
|
97596
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
96638
97597
|
flexDirection: "column",
|
|
96639
97598
|
children: [
|
|
96640
|
-
|
|
96641
|
-
|
|
96642
|
-
|
|
96643
|
-
flexDirection: "column",
|
|
96644
|
-
paddingX: 1,
|
|
96645
|
-
width: termWidth,
|
|
96646
|
-
children: visibleLogWindow(logs).map((line) => line.color ? /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97599
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Static, {
|
|
97600
|
+
items: logs,
|
|
97601
|
+
children: (line) => line.color ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96647
97602
|
color: line.color,
|
|
96648
97603
|
children: line.text
|
|
96649
|
-
}, line.id, false, undefined, this) : /* @__PURE__ */
|
|
97604
|
+
}, line.id, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96650
97605
|
children: line.text
|
|
96651
|
-
}, line.id, false, undefined, this)
|
|
97606
|
+
}, line.id, false, undefined, this)
|
|
96652
97607
|
}, undefined, false, undefined, this),
|
|
96653
|
-
/* @__PURE__ */
|
|
97608
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
96654
97609
|
flexDirection: "column",
|
|
96655
97610
|
marginTop: 0,
|
|
96656
97611
|
children: [
|
|
96657
|
-
|
|
97612
|
+
(() => {
|
|
97613
|
+
const pause = coordRef.current?.getPause?.() ?? null;
|
|
97614
|
+
if (!pause)
|
|
97615
|
+
return null;
|
|
97616
|
+
const seconds = Math.floor((Date.now() - pause.since) / 1000);
|
|
97617
|
+
const duration3 = seconds < 60 ? `${seconds}s` : seconds < 3600 ? `${Math.floor(seconds / 60)}m` : `${Math.floor(seconds / 3600)}h${Math.floor(seconds % 3600 / 60)}m`;
|
|
97618
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
97619
|
+
borderStyle: "round",
|
|
97620
|
+
borderColor: "red",
|
|
97621
|
+
paddingX: 1,
|
|
97622
|
+
width: termWidth,
|
|
97623
|
+
children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97624
|
+
color: "red",
|
|
97625
|
+
bold: true,
|
|
97626
|
+
children: [
|
|
97627
|
+
"\u26D4 BASELINE BROKEN ",
|
|
97628
|
+
pause.issueIdentifier,
|
|
97629
|
+
" \xB7 ",
|
|
97630
|
+
duration3,
|
|
97631
|
+
" \xB7 `",
|
|
97632
|
+
pause.command,
|
|
97633
|
+
"`"
|
|
97634
|
+
]
|
|
97635
|
+
}, undefined, true, undefined, this)
|
|
97636
|
+
}, undefined, false, undefined, this);
|
|
97637
|
+
})(),
|
|
97638
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(LabeledBox, {
|
|
96658
97639
|
label: "\u25C8 RALPH AGENT",
|
|
96659
97640
|
borderColor: "blue",
|
|
96660
97641
|
width: termWidth,
|
|
96661
97642
|
paddingX: 1,
|
|
96662
97643
|
flexDirection: "column",
|
|
96663
97644
|
children: [
|
|
96664
|
-
/* @__PURE__ */
|
|
97645
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96665
97646
|
children: [
|
|
96666
|
-
/* @__PURE__ */
|
|
97647
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96667
97648
|
dimColor: true,
|
|
96668
97649
|
children: [
|
|
96669
97650
|
"v",
|
|
96670
97651
|
VERSION
|
|
96671
97652
|
]
|
|
96672
97653
|
}, undefined, true, undefined, this),
|
|
96673
|
-
cfg && /* @__PURE__ */
|
|
97654
|
+
cfg && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96674
97655
|
children: [
|
|
96675
|
-
/* @__PURE__ */
|
|
97656
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96676
97657
|
dimColor: true,
|
|
96677
97658
|
children: " \u2502 "
|
|
96678
97659
|
}, undefined, false, undefined, this),
|
|
96679
|
-
/* @__PURE__ */
|
|
97660
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96680
97661
|
color: "cyan",
|
|
96681
97662
|
bold: true,
|
|
96682
97663
|
children: [
|
|
@@ -96685,14 +97666,14 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96685
97666
|
cfg.model
|
|
96686
97667
|
]
|
|
96687
97668
|
}, undefined, true, undefined, this),
|
|
96688
|
-
/* @__PURE__ */
|
|
97669
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96689
97670
|
dimColor: true,
|
|
96690
97671
|
children: [
|
|
96691
97672
|
" \u2502 \xD7",
|
|
96692
97673
|
cfg.concurrency
|
|
96693
97674
|
]
|
|
96694
97675
|
}, undefined, true, undefined, this),
|
|
96695
|
-
/* @__PURE__ */
|
|
97676
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96696
97677
|
dimColor: true,
|
|
96697
97678
|
children: [
|
|
96698
97679
|
" \u2502 poll ",
|
|
@@ -96700,36 +97681,36 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96700
97681
|
"s"
|
|
96701
97682
|
]
|
|
96702
97683
|
}, undefined, true, undefined, this),
|
|
96703
|
-
cfg.maxIterationsPerTask > 0 && /* @__PURE__ */
|
|
97684
|
+
cfg.maxIterationsPerTask > 0 && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96704
97685
|
color: "yellow",
|
|
96705
97686
|
children: [
|
|
96706
97687
|
" \u2502 iter \u2264",
|
|
96707
97688
|
cfg.maxIterationsPerTask
|
|
96708
97689
|
]
|
|
96709
97690
|
}, undefined, true, undefined, this),
|
|
96710
|
-
cfg.maxCostUsdPerTask > 0 && /* @__PURE__ */
|
|
97691
|
+
cfg.maxCostUsdPerTask > 0 && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96711
97692
|
color: "yellow",
|
|
96712
97693
|
children: [
|
|
96713
97694
|
" \u2502 cost \u2264$",
|
|
96714
97695
|
cfg.maxCostUsdPerTask
|
|
96715
97696
|
]
|
|
96716
97697
|
}, undefined, true, undefined, this),
|
|
96717
|
-
args.maxTickets > 0 && /* @__PURE__ */
|
|
97698
|
+
args.maxTickets > 0 && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96718
97699
|
color: "yellow",
|
|
96719
97700
|
children: [
|
|
96720
97701
|
" \u2502 tickets \u2264",
|
|
96721
97702
|
args.maxTickets
|
|
96722
97703
|
]
|
|
96723
97704
|
}, undefined, true, undefined, this),
|
|
96724
|
-
cfg.createPrOnSuccess && /* @__PURE__ */
|
|
97705
|
+
cfg.createPrOnSuccess && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96725
97706
|
color: "green",
|
|
96726
97707
|
children: " \u25CF PR"
|
|
96727
97708
|
}, undefined, false, undefined, this),
|
|
96728
|
-
cfg.fixCiOnFailure && /* @__PURE__ */
|
|
97709
|
+
cfg.fixCiOnFailure && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96729
97710
|
color: "green",
|
|
96730
97711
|
children: " \u25CF fixCI"
|
|
96731
97712
|
}, undefined, false, undefined, this),
|
|
96732
|
-
cfg.useWorktree && /* @__PURE__ */
|
|
97713
|
+
cfg.useWorktree && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96733
97714
|
color: "green",
|
|
96734
97715
|
children: " \u25CF worktree"
|
|
96735
97716
|
}, undefined, false, undefined, this)
|
|
@@ -96749,7 +97730,7 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96749
97730
|
lines.push(remaining.slice(0, budget));
|
|
96750
97731
|
remaining = remaining.slice(budget);
|
|
96751
97732
|
}
|
|
96752
|
-
return lines.map((segment, i) => /* @__PURE__ */
|
|
97733
|
+
return lines.map((segment, i) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96753
97734
|
dimColor: true,
|
|
96754
97735
|
children: [
|
|
96755
97736
|
i === 0 ? prefix : indent,
|
|
@@ -96759,157 +97740,151 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96759
97740
|
})()
|
|
96760
97741
|
]
|
|
96761
97742
|
}, undefined, true, undefined, this),
|
|
96762
|
-
/* @__PURE__ */
|
|
97743
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
96763
97744
|
flexDirection: "row",
|
|
96764
97745
|
gap: 1,
|
|
96765
97746
|
marginTop: 0,
|
|
96766
97747
|
width: termWidth,
|
|
96767
97748
|
children: [
|
|
96768
|
-
/* @__PURE__ */
|
|
97749
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(LabeledBox, {
|
|
96769
97750
|
label: "POLL STATUS",
|
|
96770
97751
|
borderColor: "gray",
|
|
96771
|
-
width: termWidth -
|
|
97752
|
+
width: termWidth - 17,
|
|
96772
97753
|
paddingX: 1,
|
|
96773
97754
|
flexDirection: "column",
|
|
96774
97755
|
children: [
|
|
96775
|
-
/* @__PURE__ */
|
|
97756
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
96776
97757
|
gap: 2,
|
|
96777
97758
|
children: [
|
|
96778
|
-
/* @__PURE__ */
|
|
97759
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96779
97760
|
color: "gray",
|
|
96780
97761
|
children: spinnerFrame
|
|
96781
97762
|
}, undefined, false, undefined, this),
|
|
96782
|
-
/* @__PURE__ */
|
|
97763
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96783
97764
|
children: pollStatus.state === "polling" ? "Polling Linear\u2026" : pollStatus.lastAt !== null ? "Idle" : "Starting\u2026"
|
|
96784
97765
|
}, undefined, false, undefined, this),
|
|
96785
|
-
pollStatus.lastAt !== null && /* @__PURE__ */
|
|
97766
|
+
pollStatus.lastAt !== null && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(jsx_dev_runtime10.Fragment, {
|
|
97767
|
+
children: pollStatus.lastBuckets && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(jsx_dev_runtime10.Fragment, {
|
|
97768
|
+
children: [
|
|
97769
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97770
|
+
dimColor: true,
|
|
97771
|
+
children: "\u2502"
|
|
97772
|
+
}, undefined, false, undefined, this),
|
|
97773
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97774
|
+
dimColor: true,
|
|
97775
|
+
children: "todo"
|
|
97776
|
+
}, undefined, false, undefined, this),
|
|
97777
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97778
|
+
color: "white",
|
|
97779
|
+
children: pollStatus.lastBuckets.todo
|
|
97780
|
+
}, undefined, false, undefined, this),
|
|
97781
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97782
|
+
dimColor: true,
|
|
97783
|
+
children: "\xB7"
|
|
97784
|
+
}, undefined, false, undefined, this),
|
|
97785
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97786
|
+
dimColor: true,
|
|
97787
|
+
children: "resume"
|
|
97788
|
+
}, undefined, false, undefined, this),
|
|
97789
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97790
|
+
color: pollStatus.lastBuckets.inProgress > 0 ? "cyan" : "white",
|
|
97791
|
+
children: pollStatus.lastBuckets.inProgress
|
|
97792
|
+
}, undefined, false, undefined, this),
|
|
97793
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97794
|
+
dimColor: true,
|
|
97795
|
+
children: "\xB7"
|
|
97796
|
+
}, undefined, false, undefined, this),
|
|
97797
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97798
|
+
dimColor: true,
|
|
97799
|
+
children: "conflict"
|
|
97800
|
+
}, undefined, false, undefined, this),
|
|
97801
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97802
|
+
color: pollStatus.lastBuckets.conflicted > 0 ? "red" : "white",
|
|
97803
|
+
children: pollStatus.lastBuckets.conflicted
|
|
97804
|
+
}, undefined, false, undefined, this),
|
|
97805
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97806
|
+
dimColor: true,
|
|
97807
|
+
children: "\xB7"
|
|
97808
|
+
}, undefined, false, undefined, this),
|
|
97809
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97810
|
+
dimColor: true,
|
|
97811
|
+
children: "review"
|
|
97812
|
+
}, undefined, false, undefined, this),
|
|
97813
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97814
|
+
color: pollStatus.lastBuckets.review > 0 ? "yellow" : "white",
|
|
97815
|
+
children: pollStatus.lastBuckets.review
|
|
97816
|
+
}, undefined, false, undefined, this),
|
|
97817
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97818
|
+
dimColor: true,
|
|
97819
|
+
children: "\xB7"
|
|
97820
|
+
}, undefined, false, undefined, this),
|
|
97821
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97822
|
+
dimColor: true,
|
|
97823
|
+
children: "mentions"
|
|
97824
|
+
}, undefined, false, undefined, this),
|
|
97825
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97826
|
+
color: pollStatus.lastBuckets.mentions > 0 ? "magenta" : "white",
|
|
97827
|
+
children: pollStatus.lastBuckets.mentions
|
|
97828
|
+
}, undefined, false, undefined, this)
|
|
97829
|
+
]
|
|
97830
|
+
}, undefined, true, undefined, this)
|
|
97831
|
+
}, undefined, false, undefined, this)
|
|
97832
|
+
]
|
|
97833
|
+
}, undefined, true, undefined, this),
|
|
97834
|
+
pollStatus.lastAt !== null && pollStatus.lastPrStatus && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
97835
|
+
gap: 2,
|
|
97836
|
+
children: [
|
|
97837
|
+
secsToNextPoll !== null ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
97838
|
+
gap: 1,
|
|
96786
97839
|
children: [
|
|
96787
|
-
|
|
96788
|
-
|
|
96789
|
-
|
|
96790
|
-
|
|
96791
|
-
|
|
96792
|
-
|
|
96793
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96794
|
-
dimColor: true,
|
|
96795
|
-
children: "todo"
|
|
96796
|
-
}, undefined, false, undefined, this),
|
|
96797
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96798
|
-
color: "white",
|
|
96799
|
-
children: pollStatus.lastBuckets.todo
|
|
96800
|
-
}, undefined, false, undefined, this),
|
|
96801
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96802
|
-
dimColor: true,
|
|
96803
|
-
children: "\xB7"
|
|
96804
|
-
}, undefined, false, undefined, this),
|
|
96805
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96806
|
-
dimColor: true,
|
|
96807
|
-
children: "res"
|
|
96808
|
-
}, undefined, false, undefined, this),
|
|
96809
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96810
|
-
color: pollStatus.lastBuckets.inProgress > 0 ? "cyan" : "white",
|
|
96811
|
-
children: pollStatus.lastBuckets.inProgress
|
|
96812
|
-
}, undefined, false, undefined, this),
|
|
96813
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96814
|
-
dimColor: true,
|
|
96815
|
-
children: "\xB7"
|
|
96816
|
-
}, undefined, false, undefined, this),
|
|
96817
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96818
|
-
dimColor: true,
|
|
96819
|
-
children: "conf"
|
|
96820
|
-
}, undefined, false, undefined, this),
|
|
96821
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96822
|
-
color: pollStatus.lastBuckets.conflicted > 0 ? "red" : "white",
|
|
96823
|
-
children: pollStatus.lastBuckets.conflicted
|
|
96824
|
-
}, undefined, false, undefined, this),
|
|
96825
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96826
|
-
dimColor: true,
|
|
96827
|
-
children: "\xB7"
|
|
96828
|
-
}, undefined, false, undefined, this),
|
|
96829
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96830
|
-
dimColor: true,
|
|
96831
|
-
children: "rev"
|
|
96832
|
-
}, undefined, false, undefined, this),
|
|
96833
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96834
|
-
color: pollStatus.lastBuckets.review > 0 ? "yellow" : "white",
|
|
96835
|
-
children: pollStatus.lastBuckets.review
|
|
96836
|
-
}, undefined, false, undefined, this),
|
|
96837
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96838
|
-
dimColor: true,
|
|
96839
|
-
children: "\xB7"
|
|
96840
|
-
}, undefined, false, undefined, this),
|
|
96841
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96842
|
-
dimColor: true,
|
|
96843
|
-
children: "@"
|
|
96844
|
-
}, undefined, false, undefined, this),
|
|
96845
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96846
|
-
color: pollStatus.lastBuckets.mentions > 0 ? "magenta" : "white",
|
|
96847
|
-
children: pollStatus.lastBuckets.mentions
|
|
96848
|
-
}, undefined, false, undefined, this)
|
|
96849
|
-
]
|
|
96850
|
-
}, undefined, true, undefined, this),
|
|
96851
|
-
secsToNextPoll !== null && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(jsx_dev_runtime9.Fragment, {
|
|
97840
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97841
|
+
dimColor: true,
|
|
97842
|
+
children: "\u21BA"
|
|
97843
|
+
}, undefined, false, undefined, this),
|
|
97844
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97845
|
+
color: "gray",
|
|
96852
97846
|
children: [
|
|
96853
|
-
|
|
96854
|
-
|
|
96855
|
-
children: "\u2502"
|
|
96856
|
-
}, undefined, false, undefined, this),
|
|
96857
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96858
|
-
dimColor: true,
|
|
96859
|
-
children: "\u21BA"
|
|
96860
|
-
}, undefined, false, undefined, this),
|
|
96861
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
96862
|
-
color: "gray",
|
|
96863
|
-
children: [
|
|
96864
|
-
secsToNextPoll,
|
|
96865
|
-
"s"
|
|
96866
|
-
]
|
|
96867
|
-
}, undefined, true, undefined, this)
|
|
97847
|
+
secsToNextPoll,
|
|
97848
|
+
"s"
|
|
96868
97849
|
]
|
|
96869
97850
|
}, undefined, true, undefined, this)
|
|
96870
97851
|
]
|
|
96871
|
-
}, undefined, true, undefined, this)
|
|
96872
|
-
]
|
|
96873
|
-
}, undefined, true, undefined, this),
|
|
96874
|
-
pollStatus.lastAt !== null && pollStatus.lastPrStatus && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
96875
|
-
gap: 2,
|
|
96876
|
-
children: [
|
|
96877
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97852
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96878
97853
|
children: " ".repeat(7)
|
|
96879
97854
|
}, undefined, false, undefined, this),
|
|
96880
|
-
/* @__PURE__ */
|
|
97855
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96881
97856
|
dimColor: true,
|
|
96882
97857
|
children: "\u2502"
|
|
96883
97858
|
}, undefined, false, undefined, this),
|
|
96884
|
-
/* @__PURE__ */
|
|
97859
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96885
97860
|
dimColor: true,
|
|
96886
97861
|
children: "mergeable"
|
|
96887
97862
|
}, undefined, false, undefined, this),
|
|
96888
|
-
/* @__PURE__ */
|
|
97863
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96889
97864
|
color: pollStatus.lastPrStatus.mergeable > 0 ? "green" : "white",
|
|
96890
97865
|
children: pollStatus.lastPrStatus.mergeable
|
|
96891
97866
|
}, undefined, false, undefined, this),
|
|
96892
|
-
/* @__PURE__ */
|
|
97867
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96893
97868
|
dimColor: true,
|
|
96894
97869
|
children: "\xB7"
|
|
96895
97870
|
}, undefined, false, undefined, this),
|
|
96896
|
-
/* @__PURE__ */
|
|
97871
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96897
97872
|
dimColor: true,
|
|
96898
97873
|
children: "conflicted"
|
|
96899
97874
|
}, undefined, false, undefined, this),
|
|
96900
|
-
/* @__PURE__ */
|
|
97875
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96901
97876
|
color: pollStatus.lastPrStatus.conflicted > 0 ? "red" : "white",
|
|
96902
97877
|
children: pollStatus.lastPrStatus.conflicted
|
|
96903
97878
|
}, undefined, false, undefined, this),
|
|
96904
|
-
/* @__PURE__ */
|
|
97879
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96905
97880
|
dimColor: true,
|
|
96906
97881
|
children: "\xB7"
|
|
96907
97882
|
}, undefined, false, undefined, this),
|
|
96908
|
-
/* @__PURE__ */
|
|
97883
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96909
97884
|
dimColor: true,
|
|
96910
97885
|
children: "ci-failed"
|
|
96911
97886
|
}, undefined, false, undefined, this),
|
|
96912
|
-
/* @__PURE__ */
|
|
97887
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96913
97888
|
color: pollStatus.lastPrStatus.ciFailed > 0 ? "red" : "white",
|
|
96914
97889
|
children: pollStatus.lastPrStatus.ciFailed
|
|
96915
97890
|
}, undefined, false, undefined, this)
|
|
@@ -96917,35 +97892,35 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96917
97892
|
}, undefined, true, undefined, this)
|
|
96918
97893
|
]
|
|
96919
97894
|
}, undefined, true, undefined, this),
|
|
96920
|
-
/* @__PURE__ */
|
|
97895
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(LabeledBox, {
|
|
96921
97896
|
label: "WORKERS",
|
|
96922
97897
|
borderColor: "gray",
|
|
96923
|
-
width:
|
|
97898
|
+
width: 16,
|
|
96924
97899
|
paddingX: 1,
|
|
96925
97900
|
flexDirection: "column",
|
|
96926
97901
|
children: [
|
|
96927
|
-
/* @__PURE__ */
|
|
97902
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
96928
97903
|
gap: 1,
|
|
96929
97904
|
children: [
|
|
96930
|
-
/* @__PURE__ */
|
|
97905
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96931
97906
|
dimColor: true,
|
|
96932
|
-
children: "
|
|
97907
|
+
children: "active"
|
|
96933
97908
|
}, undefined, false, undefined, this),
|
|
96934
|
-
/* @__PURE__ */
|
|
97909
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96935
97910
|
color: activeCount > 0 ? "cyan" : "gray",
|
|
96936
97911
|
bold: true,
|
|
96937
97912
|
children: activeCount
|
|
96938
97913
|
}, undefined, false, undefined, this)
|
|
96939
97914
|
]
|
|
96940
97915
|
}, undefined, true, undefined, this),
|
|
96941
|
-
/* @__PURE__ */
|
|
97916
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
96942
97917
|
gap: 1,
|
|
96943
97918
|
children: [
|
|
96944
|
-
/* @__PURE__ */
|
|
97919
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96945
97920
|
dimColor: true,
|
|
96946
97921
|
children: "queue"
|
|
96947
97922
|
}, undefined, false, undefined, this),
|
|
96948
|
-
/* @__PURE__ */
|
|
97923
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96949
97924
|
color: (coord?.queuedCount ?? 0) > 0 ? "yellow" : "gray",
|
|
96950
97925
|
bold: true,
|
|
96951
97926
|
children: coord?.queuedCount ?? 0
|
|
@@ -96956,13 +97931,13 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96956
97931
|
}, undefined, true, undefined, this)
|
|
96957
97932
|
]
|
|
96958
97933
|
}, undefined, true, undefined, this),
|
|
96959
|
-
activeCount > 1 && /* @__PURE__ */
|
|
97934
|
+
activeCount > 1 && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(LabeledBox, {
|
|
96960
97935
|
label: `TASKS${activeCount > 1 ? " Tab/\u2190 \u2192 \xB7 1-9" : ""}`,
|
|
96961
97936
|
borderColor: "gray",
|
|
96962
97937
|
width: termWidth,
|
|
96963
97938
|
paddingX: 1,
|
|
96964
97939
|
flexDirection: "column",
|
|
96965
|
-
children: /* @__PURE__ */
|
|
97940
|
+
children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
96966
97941
|
gap: 3,
|
|
96967
97942
|
flexWrap: "wrap",
|
|
96968
97943
|
children: coord?.activeWorkers.map((w, idx) => {
|
|
@@ -96970,10 +97945,10 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96970
97945
|
const phase = meta3?.phase ?? "working";
|
|
96971
97946
|
const pBadge = priorityBadge(w.issue.priority);
|
|
96972
97947
|
const isFocused = idx === safeFocusedIdx;
|
|
96973
|
-
return /* @__PURE__ */
|
|
97948
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
96974
97949
|
gap: 1,
|
|
96975
97950
|
children: [
|
|
96976
|
-
/* @__PURE__ */
|
|
97951
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96977
97952
|
color: isFocused ? "white" : "gray",
|
|
96978
97953
|
bold: isFocused,
|
|
96979
97954
|
children: [
|
|
@@ -96982,7 +97957,7 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96982
97957
|
"]"
|
|
96983
97958
|
]
|
|
96984
97959
|
}, undefined, true, undefined, this),
|
|
96985
|
-
pBadge.label && /* @__PURE__ */
|
|
97960
|
+
pBadge.label && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96986
97961
|
color: pBadge.color,
|
|
96987
97962
|
children: [
|
|
96988
97963
|
pBadge.text,
|
|
@@ -96990,17 +97965,17 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
96990
97965
|
pBadge.label
|
|
96991
97966
|
]
|
|
96992
97967
|
}, undefined, true, undefined, this),
|
|
96993
|
-
/* @__PURE__ */
|
|
97968
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Link, {
|
|
96994
97969
|
url: w.issue.url,
|
|
96995
97970
|
label: w.issueIdentifier,
|
|
96996
97971
|
color: isFocused ? "cyan" : "gray"
|
|
96997
97972
|
}, undefined, false, undefined, this),
|
|
96998
|
-
/* @__PURE__ */
|
|
97973
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
96999
97974
|
color: phaseColor(phase),
|
|
97000
97975
|
dimColor: !isFocused,
|
|
97001
97976
|
children: phase
|
|
97002
97977
|
}, undefined, false, undefined, this),
|
|
97003
|
-
isFocused && /* @__PURE__ */
|
|
97978
|
+
isFocused && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97004
97979
|
color: "white",
|
|
97005
97980
|
children: "\u25C0"
|
|
97006
97981
|
}, undefined, false, undefined, this)
|
|
@@ -97023,6 +97998,7 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
97023
97998
|
const currentTask = meta3?.currentTask ?? null;
|
|
97024
97999
|
const taskProgress = meta3?.taskProgress ?? null;
|
|
97025
98000
|
const openspecPhase = meta3?.openspecPhase ?? null;
|
|
98001
|
+
const subtasks = meta3?.subtasks ?? [];
|
|
97026
98002
|
const pBadge = priorityBadge(w.issue.priority);
|
|
97027
98003
|
const mBadge = modeBadge(w.mode);
|
|
97028
98004
|
const pColor = phaseColor(phase);
|
|
@@ -97030,33 +98006,33 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
97030
98006
|
const visibleTailLines = isFocused ? focusedTailLines : compactTailLines;
|
|
97031
98007
|
if (!isFocused && activeCount > 1) {
|
|
97032
98008
|
const cardLabelWidth2 = (prUrl ? prLabel(prUrl).length + 3 : 0) + w.issueIdentifier.length + 2;
|
|
97033
|
-
const cardLabelNode2 = /* @__PURE__ */
|
|
98009
|
+
const cardLabelNode2 = /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(jsx_dev_runtime10.Fragment, {
|
|
97034
98010
|
children: [
|
|
97035
|
-
/* @__PURE__ */
|
|
98011
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97036
98012
|
color: "gray",
|
|
97037
98013
|
children: " "
|
|
97038
98014
|
}, undefined, false, undefined, this),
|
|
97039
|
-
prUrl && /* @__PURE__ */
|
|
98015
|
+
prUrl && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Link, {
|
|
97040
98016
|
url: prUrl,
|
|
97041
98017
|
label: prLabel(prUrl),
|
|
97042
98018
|
color: "green"
|
|
97043
98019
|
}, undefined, false, undefined, this),
|
|
97044
|
-
prUrl && /* @__PURE__ */
|
|
98020
|
+
prUrl && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97045
98021
|
color: "gray",
|
|
97046
98022
|
children: " \xB7 "
|
|
97047
98023
|
}, undefined, false, undefined, this),
|
|
97048
|
-
/* @__PURE__ */
|
|
98024
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Link, {
|
|
97049
98025
|
url: w.issue.url,
|
|
97050
98026
|
label: w.issueIdentifier,
|
|
97051
98027
|
color: "cyan"
|
|
97052
98028
|
}, undefined, false, undefined, this),
|
|
97053
|
-
/* @__PURE__ */
|
|
98029
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97054
98030
|
color: "gray",
|
|
97055
98031
|
children: " "
|
|
97056
98032
|
}, undefined, false, undefined, this)
|
|
97057
98033
|
]
|
|
97058
98034
|
}, undefined, true, undefined, this);
|
|
97059
|
-
return /* @__PURE__ */
|
|
98035
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(LabeledBox, {
|
|
97060
98036
|
labelNode: cardLabelNode2,
|
|
97061
98037
|
labelVisualWidth: cardLabelWidth2,
|
|
97062
98038
|
borderColor: "gray",
|
|
@@ -97064,7 +98040,7 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
97064
98040
|
gap: 2,
|
|
97065
98041
|
width: termWidth,
|
|
97066
98042
|
children: [
|
|
97067
|
-
/* @__PURE__ */
|
|
98043
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97068
98044
|
dimColor: true,
|
|
97069
98045
|
children: [
|
|
97070
98046
|
"[",
|
|
@@ -97072,54 +98048,54 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
97072
98048
|
"]"
|
|
97073
98049
|
]
|
|
97074
98050
|
}, undefined, true, undefined, this),
|
|
97075
|
-
pBadge.label && /* @__PURE__ */
|
|
98051
|
+
pBadge.label && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97076
98052
|
color: pBadge.color,
|
|
97077
98053
|
children: pBadge.text
|
|
97078
98054
|
}, undefined, false, undefined, this),
|
|
97079
|
-
/* @__PURE__ */
|
|
98055
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97080
98056
|
color: "gray",
|
|
97081
98057
|
bold: true,
|
|
97082
98058
|
children: w.issueIdentifier
|
|
97083
98059
|
}, undefined, false, undefined, this),
|
|
97084
|
-
/* @__PURE__ */
|
|
98060
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97085
98061
|
dimColor: true,
|
|
97086
98062
|
children: trunc(w.issue.title, 40)
|
|
97087
98063
|
}, undefined, false, undefined, this),
|
|
97088
|
-
/* @__PURE__ */
|
|
98064
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97089
98065
|
dimColor: true,
|
|
97090
98066
|
children: "\u2502"
|
|
97091
98067
|
}, undefined, false, undefined, this),
|
|
97092
|
-
/* @__PURE__ */
|
|
98068
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97093
98069
|
color: pColor,
|
|
97094
98070
|
dimColor: true,
|
|
97095
98071
|
children: phase
|
|
97096
98072
|
}, undefined, false, undefined, this),
|
|
97097
|
-
/* @__PURE__ */
|
|
98073
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97098
98074
|
dimColor: true,
|
|
97099
98075
|
children: "\u2502"
|
|
97100
98076
|
}, undefined, false, undefined, this),
|
|
97101
|
-
/* @__PURE__ */
|
|
98077
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97102
98078
|
dimColor: true,
|
|
97103
98079
|
children: elapsed
|
|
97104
98080
|
}, undefined, false, undefined, this),
|
|
97105
|
-
/* @__PURE__ */
|
|
98081
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97106
98082
|
dimColor: true,
|
|
97107
98083
|
children: "\xB7"
|
|
97108
98084
|
}, undefined, false, undefined, this),
|
|
97109
|
-
/* @__PURE__ */
|
|
98085
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97110
98086
|
dimColor: true,
|
|
97111
98087
|
children: [
|
|
97112
98088
|
"iter ",
|
|
97113
98089
|
iter
|
|
97114
98090
|
]
|
|
97115
98091
|
}, undefined, true, undefined, this),
|
|
97116
|
-
currentTask && /* @__PURE__ */
|
|
98092
|
+
currentTask && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(jsx_dev_runtime10.Fragment, {
|
|
97117
98093
|
children: [
|
|
97118
|
-
/* @__PURE__ */
|
|
98094
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97119
98095
|
dimColor: true,
|
|
97120
98096
|
children: "\u2502"
|
|
97121
98097
|
}, undefined, false, undefined, this),
|
|
97122
|
-
openspecPhase && /* @__PURE__ */
|
|
98098
|
+
openspecPhase && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97123
98099
|
color: openspecPhaseColor(openspecPhase),
|
|
97124
98100
|
children: [
|
|
97125
98101
|
"[",
|
|
@@ -97127,7 +98103,7 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
97127
98103
|
"]"
|
|
97128
98104
|
]
|
|
97129
98105
|
}, undefined, true, undefined, this),
|
|
97130
|
-
/* @__PURE__ */
|
|
98106
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97131
98107
|
dimColor: true,
|
|
97132
98108
|
children: [
|
|
97133
98109
|
"\u25B6 ",
|
|
@@ -97140,33 +98116,33 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
97140
98116
|
}, w.changeName, true, undefined, this);
|
|
97141
98117
|
}
|
|
97142
98118
|
const cardLabelWidth = (prUrl ? prLabel(prUrl).length + 3 : 0) + w.issueIdentifier.length + 2;
|
|
97143
|
-
const cardLabelNode = /* @__PURE__ */
|
|
98119
|
+
const cardLabelNode = /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(jsx_dev_runtime10.Fragment, {
|
|
97144
98120
|
children: [
|
|
97145
|
-
/* @__PURE__ */
|
|
98121
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97146
98122
|
color: bColor,
|
|
97147
98123
|
children: " "
|
|
97148
98124
|
}, undefined, false, undefined, this),
|
|
97149
|
-
prUrl && /* @__PURE__ */
|
|
98125
|
+
prUrl && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Link, {
|
|
97150
98126
|
url: prUrl,
|
|
97151
98127
|
label: prLabel(prUrl),
|
|
97152
98128
|
color: "green"
|
|
97153
98129
|
}, undefined, false, undefined, this),
|
|
97154
|
-
prUrl && /* @__PURE__ */
|
|
98130
|
+
prUrl && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97155
98131
|
color: bColor,
|
|
97156
98132
|
children: " \xB7 "
|
|
97157
98133
|
}, undefined, false, undefined, this),
|
|
97158
|
-
/* @__PURE__ */
|
|
98134
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Link, {
|
|
97159
98135
|
url: w.issue.url,
|
|
97160
98136
|
label: w.issueIdentifier,
|
|
97161
98137
|
color: "cyan"
|
|
97162
98138
|
}, undefined, false, undefined, this),
|
|
97163
|
-
/* @__PURE__ */
|
|
98139
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97164
98140
|
color: bColor,
|
|
97165
98141
|
children: " "
|
|
97166
98142
|
}, undefined, false, undefined, this)
|
|
97167
98143
|
]
|
|
97168
98144
|
}, undefined, true, undefined, this);
|
|
97169
|
-
return /* @__PURE__ */
|
|
98145
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(LabeledBox, {
|
|
97170
98146
|
labelNode: cardLabelNode,
|
|
97171
98147
|
labelVisualWidth: cardLabelWidth,
|
|
97172
98148
|
borderColor: bColor,
|
|
@@ -97174,18 +98150,18 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
97174
98150
|
paddingX: 1,
|
|
97175
98151
|
width: termWidth,
|
|
97176
98152
|
children: [
|
|
97177
|
-
/* @__PURE__ */
|
|
98153
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
97178
98154
|
gap: 2,
|
|
97179
98155
|
children: [
|
|
97180
|
-
/* @__PURE__ */
|
|
98156
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97181
98157
|
children: spinnerFrame
|
|
97182
98158
|
}, undefined, false, undefined, this),
|
|
97183
|
-
/* @__PURE__ */
|
|
98159
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97184
98160
|
color: "white",
|
|
97185
98161
|
bold: true,
|
|
97186
98162
|
children: trunc(w.issue.title, Math.max(20, termWidth - 55))
|
|
97187
98163
|
}, undefined, false, undefined, this),
|
|
97188
|
-
/* @__PURE__ */
|
|
98164
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97189
98165
|
color: mBadge.color,
|
|
97190
98166
|
bold: true,
|
|
97191
98167
|
children: [
|
|
@@ -97194,7 +98170,7 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
97194
98170
|
"]"
|
|
97195
98171
|
]
|
|
97196
98172
|
}, undefined, true, undefined, this),
|
|
97197
|
-
/* @__PURE__ */
|
|
98173
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97198
98174
|
color: pColor,
|
|
97199
98175
|
bold: true,
|
|
97200
98176
|
children: [
|
|
@@ -97202,79 +98178,39 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
97202
98178
|
phaseDetail ? ` (${phaseDetail})` : ""
|
|
97203
98179
|
]
|
|
97204
98180
|
}, undefined, true, undefined, this),
|
|
97205
|
-
/* @__PURE__ */
|
|
98181
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97206
98182
|
dimColor: true,
|
|
97207
98183
|
children: "\u2502"
|
|
97208
98184
|
}, undefined, false, undefined, this),
|
|
97209
|
-
/* @__PURE__ */
|
|
98185
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97210
98186
|
color: "white",
|
|
97211
98187
|
children: elapsed
|
|
97212
98188
|
}, undefined, false, undefined, this),
|
|
97213
|
-
/* @__PURE__ */
|
|
98189
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97214
98190
|
dimColor: true,
|
|
97215
98191
|
children: "\u2502"
|
|
97216
98192
|
}, undefined, false, undefined, this),
|
|
97217
|
-
/* @__PURE__ */
|
|
98193
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97218
98194
|
dimColor: true,
|
|
97219
98195
|
children: "\u21BA"
|
|
97220
98196
|
}, undefined, false, undefined, this),
|
|
97221
|
-
/* @__PURE__ */
|
|
98197
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97222
98198
|
color: "white",
|
|
97223
98199
|
bold: true,
|
|
97224
98200
|
children: iter
|
|
97225
98201
|
}, undefined, false, undefined, this)
|
|
97226
98202
|
]
|
|
97227
98203
|
}, undefined, true, undefined, this),
|
|
97228
|
-
|
|
97229
|
-
const bar = calcProgressBar(taskProgress.checked, taskProgress.total, termWidth - 4);
|
|
97230
|
-
if (!bar)
|
|
97231
|
-
return null;
|
|
97232
|
-
const { countStr, filledLeft, leftSlot, filledRight, rightSlot } = bar;
|
|
97233
|
-
return /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
97234
|
-
marginTop: 0,
|
|
97235
|
-
children: [
|
|
97236
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97237
|
-
dimColor: true,
|
|
97238
|
-
children: "["
|
|
97239
|
-
}, undefined, false, undefined, this),
|
|
97240
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97241
|
-
color: "green",
|
|
97242
|
-
children: "\u2588".repeat(filledLeft)
|
|
97243
|
-
}, undefined, false, undefined, this),
|
|
97244
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97245
|
-
dimColor: true,
|
|
97246
|
-
children: "\u2591".repeat(leftSlot - filledLeft)
|
|
97247
|
-
}, undefined, false, undefined, this),
|
|
97248
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97249
|
-
color: "white",
|
|
97250
|
-
bold: true,
|
|
97251
|
-
children: countStr
|
|
97252
|
-
}, undefined, false, undefined, this),
|
|
97253
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97254
|
-
color: "green",
|
|
97255
|
-
children: "\u2588".repeat(filledRight)
|
|
97256
|
-
}, undefined, false, undefined, this),
|
|
97257
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97258
|
-
dimColor: true,
|
|
97259
|
-
children: "\u2591".repeat(rightSlot - filledRight)
|
|
97260
|
-
}, undefined, false, undefined, this),
|
|
97261
|
-
/* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Text, {
|
|
97262
|
-
dimColor: true,
|
|
97263
|
-
children: "]"
|
|
97264
|
-
}, undefined, false, undefined, this)
|
|
97265
|
-
]
|
|
97266
|
-
}, undefined, true, undefined, this);
|
|
97267
|
-
})(),
|
|
97268
|
-
currentTask && /* @__PURE__ */ jsx_dev_runtime9.jsxDEV(Box_default, {
|
|
98204
|
+
currentTask && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
97269
98205
|
gap: 1,
|
|
97270
98206
|
marginTop: 0,
|
|
97271
98207
|
children: [
|
|
97272
|
-
/* @__PURE__ */
|
|
98208
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97273
98209
|
color: "yellow",
|
|
97274
98210
|
bold: true,
|
|
97275
98211
|
children: "\u25B6 TASK"
|
|
97276
98212
|
}, undefined, false, undefined, this),
|
|
97277
|
-
openspecPhase && /* @__PURE__ */
|
|
98213
|
+
openspecPhase && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97278
98214
|
color: openspecPhaseColor(openspecPhase),
|
|
97279
98215
|
bold: true,
|
|
97280
98216
|
children: [
|
|
@@ -97283,42 +98219,42 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
97283
98219
|
"]"
|
|
97284
98220
|
]
|
|
97285
98221
|
}, undefined, true, undefined, this),
|
|
97286
|
-
/* @__PURE__ */
|
|
98222
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97287
98223
|
color: "white",
|
|
97288
98224
|
children: trunc(currentTask, termWidth - 14 - (openspecPhase ? openspecPhase.length + 11 : 0))
|
|
97289
98225
|
}, undefined, false, undefined, this)
|
|
97290
98226
|
]
|
|
97291
98227
|
}, undefined, true, undefined, this),
|
|
97292
|
-
cmd && /* @__PURE__ */
|
|
98228
|
+
cmd && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
97293
98229
|
gap: 1,
|
|
97294
98230
|
marginTop: 0,
|
|
97295
98231
|
children: [
|
|
97296
|
-
/* @__PURE__ */
|
|
98232
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97297
98233
|
color: "yellow",
|
|
97298
98234
|
children: "\u23F5 CMD"
|
|
97299
98235
|
}, undefined, false, undefined, this),
|
|
97300
|
-
/* @__PURE__ */
|
|
98236
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97301
98237
|
color: "yellow",
|
|
97302
98238
|
children: fmtCmd(cmd.argv)
|
|
97303
98239
|
}, undefined, false, undefined, this),
|
|
97304
|
-
/* @__PURE__ */
|
|
98240
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97305
98241
|
dimColor: true,
|
|
97306
98242
|
children: cmdElapsed
|
|
97307
98243
|
}, undefined, false, undefined, this)
|
|
97308
98244
|
]
|
|
97309
98245
|
}, undefined, true, undefined, this),
|
|
97310
|
-
tail2.length > 0 && /* @__PURE__ */
|
|
98246
|
+
tail2.length > 0 && !(showPendingTasks && showAllSubtasks) && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
97311
98247
|
flexDirection: "column",
|
|
97312
98248
|
marginTop: 0,
|
|
97313
98249
|
children: [
|
|
97314
|
-
/* @__PURE__ */
|
|
98250
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97315
98251
|
dimColor: true,
|
|
97316
98252
|
children: [
|
|
97317
98253
|
"\u2500 OUTPUT ",
|
|
97318
98254
|
"\u2500".repeat(Math.max(4, termWidth - 14))
|
|
97319
98255
|
]
|
|
97320
98256
|
}, undefined, true, undefined, this),
|
|
97321
|
-
tail2.slice(-visibleTailLines).map((line, i) => /* @__PURE__ */
|
|
98257
|
+
tail2.slice(-visibleTailLines).map((line, i) => /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
97322
98258
|
dimColor: true,
|
|
97323
98259
|
children: [
|
|
97324
98260
|
"\u2502 ",
|
|
@@ -97326,24 +98262,185 @@ function AgentMode({ args, projectRoot, statesDir, tasksDir }) {
|
|
|
97326
98262
|
]
|
|
97327
98263
|
}, `${w.changeName}-tail-${i}`, true, undefined, this))
|
|
97328
98264
|
]
|
|
97329
|
-
}, undefined, true, undefined, this)
|
|
98265
|
+
}, undefined, true, undefined, this),
|
|
98266
|
+
shouldShowPhasePipeline(openspecPhase) && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
98267
|
+
marginTop: 0,
|
|
98268
|
+
children: phasePipeline(openspecPhase).map((seg, i, arr) => {
|
|
98269
|
+
const glyph = seg.status === "done" ? "\u2713" : seg.status === "current" ? "\u25CF" : "\u25CB";
|
|
98270
|
+
const node2 = seg.status === "done" ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98271
|
+
color: "green",
|
|
98272
|
+
children: [
|
|
98273
|
+
glyph,
|
|
98274
|
+
" ",
|
|
98275
|
+
seg.label
|
|
98276
|
+
]
|
|
98277
|
+
}, undefined, true, undefined, this) : seg.status === "current" ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98278
|
+
color: openspecPhaseColor(seg.phase),
|
|
98279
|
+
bold: true,
|
|
98280
|
+
children: [
|
|
98281
|
+
glyph,
|
|
98282
|
+
" ",
|
|
98283
|
+
seg.label
|
|
98284
|
+
]
|
|
98285
|
+
}, undefined, true, undefined, this) : /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98286
|
+
dimColor: true,
|
|
98287
|
+
children: [
|
|
98288
|
+
glyph,
|
|
98289
|
+
" ",
|
|
98290
|
+
seg.label
|
|
98291
|
+
]
|
|
98292
|
+
}, undefined, true, undefined, this);
|
|
98293
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
98294
|
+
children: [
|
|
98295
|
+
node2,
|
|
98296
|
+
i < arr.length - 1 && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98297
|
+
dimColor: true,
|
|
98298
|
+
children: " \u2500 "
|
|
98299
|
+
}, undefined, false, undefined, this)
|
|
98300
|
+
]
|
|
98301
|
+
}, seg.phase, true, undefined, this);
|
|
98302
|
+
})
|
|
98303
|
+
}, undefined, false, undefined, this),
|
|
98304
|
+
shouldShowSubtasksPanel(openspecPhase, showPendingTasks, subtasks.length > 0) && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
98305
|
+
flexDirection: "column",
|
|
98306
|
+
marginTop: 0,
|
|
98307
|
+
children: [
|
|
98308
|
+
(() => {
|
|
98309
|
+
const header = `\u2500 SUBTASKS (${subtasks.length}) CTRL+T to close `;
|
|
98310
|
+
const pad2 = "\u2500".repeat(Math.max(4, termWidth - header.length - 4));
|
|
98311
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98312
|
+
dimColor: true,
|
|
98313
|
+
children: `${header}${pad2}`
|
|
98314
|
+
}, undefined, false, undefined, this);
|
|
98315
|
+
})(),
|
|
98316
|
+
(showAllSubtasks ? subtasks : orderSubtasksForCappedDisplay(subtasks).slice(0, MAX_PENDING_DISPLAY)).map((s, i, arr) => {
|
|
98317
|
+
const ord = `${i + 1}.`.padStart(`${arr.length}.`.length, " ");
|
|
98318
|
+
const reserved = ord.length + 5;
|
|
98319
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98320
|
+
children: [
|
|
98321
|
+
s.done ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98322
|
+
dimColor: true,
|
|
98323
|
+
children: `${ord} [x] `
|
|
98324
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98325
|
+
children: `${ord} [ ] `
|
|
98326
|
+
}, undefined, false, undefined, this),
|
|
98327
|
+
s.done ? /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98328
|
+
dimColor: true,
|
|
98329
|
+
children: trunc(s.text, termWidth - reserved)
|
|
98330
|
+
}, undefined, false, undefined, this) : /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98331
|
+
children: trunc(s.text, termWidth - reserved)
|
|
98332
|
+
}, undefined, false, undefined, this)
|
|
98333
|
+
]
|
|
98334
|
+
}, `${w.changeName}-subtask-${i}`, true, undefined, this);
|
|
98335
|
+
}),
|
|
98336
|
+
!showAllSubtasks && subtasks.length > MAX_PENDING_DISPLAY && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98337
|
+
dimColor: true,
|
|
98338
|
+
children: ` \u2026 +${subtasks.length - MAX_PENDING_DISPLAY} more (CTRL+ALT+T to expand)`
|
|
98339
|
+
}, undefined, false, undefined, this)
|
|
98340
|
+
]
|
|
98341
|
+
}, undefined, true, undefined, this),
|
|
98342
|
+
steeringActive && idx === safeFocusedIdx && /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
98343
|
+
marginTop: 0,
|
|
98344
|
+
children: /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(SteeringField, {
|
|
98345
|
+
active: steeringActive,
|
|
98346
|
+
width: termWidth - 2,
|
|
98347
|
+
initialBuffer: steeringBufferRef.current,
|
|
98348
|
+
initialCursor: steeringCursorRef.current,
|
|
98349
|
+
initialFocused: steeringFocusedInitRef.current,
|
|
98350
|
+
onFocusChange: (f2) => {
|
|
98351
|
+
steeringFocusedRef.current = f2;
|
|
98352
|
+
steeringFocusedInitRef.current = f2;
|
|
98353
|
+
},
|
|
98354
|
+
onStateChange: (s) => {
|
|
98355
|
+
steeringBufferRef.current = s.buffer;
|
|
98356
|
+
steeringCursorRef.current = s.cursor;
|
|
98357
|
+
},
|
|
98358
|
+
onSubmit: async (message) => {
|
|
98359
|
+
try {
|
|
98360
|
+
await appendSteering(join22(tasksDir, w.changeName), message);
|
|
98361
|
+
} catch (err) {
|
|
98362
|
+
appendLog(`! steering append failed for ${w.changeName}: ${err.message}`, "red");
|
|
98363
|
+
throw err;
|
|
98364
|
+
}
|
|
98365
|
+
const restarted = await coordRef.current?.restartWorker(w.changeName);
|
|
98366
|
+
if (restarted) {
|
|
98367
|
+
appendLog(` ${w.changeName}: steering applied, restarting worker`, "cyan");
|
|
98368
|
+
} else {
|
|
98369
|
+
appendLog(` ${w.changeName}: steering queued \u2014 will apply on next iteration`, "gray");
|
|
98370
|
+
}
|
|
98371
|
+
}
|
|
98372
|
+
}, undefined, false, undefined, this)
|
|
98373
|
+
}, undefined, false, undefined, this),
|
|
98374
|
+
shouldShowProgressBar(openspecPhase, showPendingTasks, taskProgress !== null) && taskProgress && (() => {
|
|
98375
|
+
const hint = " CTRL+T to open";
|
|
98376
|
+
const bar = calcProgressBar(taskProgress.checked, taskProgress.total, termWidth - 4 - hint.length);
|
|
98377
|
+
if (!bar)
|
|
98378
|
+
return null;
|
|
98379
|
+
const { countStr, filledLeft, leftSlot, filledRight, rightSlot } = bar;
|
|
98380
|
+
return /* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Box_default, {
|
|
98381
|
+
marginTop: 0,
|
|
98382
|
+
children: [
|
|
98383
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98384
|
+
dimColor: true,
|
|
98385
|
+
children: "["
|
|
98386
|
+
}, undefined, false, undefined, this),
|
|
98387
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98388
|
+
color: "green",
|
|
98389
|
+
children: "\u2588".repeat(filledLeft)
|
|
98390
|
+
}, undefined, false, undefined, this),
|
|
98391
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98392
|
+
dimColor: true,
|
|
98393
|
+
children: "\u2591".repeat(leftSlot - filledLeft)
|
|
98394
|
+
}, undefined, false, undefined, this),
|
|
98395
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98396
|
+
color: "white",
|
|
98397
|
+
bold: true,
|
|
98398
|
+
children: countStr
|
|
98399
|
+
}, undefined, false, undefined, this),
|
|
98400
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98401
|
+
color: "green",
|
|
98402
|
+
children: "\u2588".repeat(filledRight)
|
|
98403
|
+
}, undefined, false, undefined, this),
|
|
98404
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98405
|
+
dimColor: true,
|
|
98406
|
+
children: "\u2591".repeat(rightSlot - filledRight)
|
|
98407
|
+
}, undefined, false, undefined, this),
|
|
98408
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98409
|
+
dimColor: true,
|
|
98410
|
+
children: "]"
|
|
98411
|
+
}, undefined, false, undefined, this),
|
|
98412
|
+
/* @__PURE__ */ jsx_dev_runtime10.jsxDEV(Text, {
|
|
98413
|
+
dimColor: true,
|
|
98414
|
+
children: hint
|
|
98415
|
+
}, undefined, false, undefined, this)
|
|
98416
|
+
]
|
|
98417
|
+
}, undefined, true, undefined, this);
|
|
98418
|
+
})()
|
|
97330
98419
|
]
|
|
97331
98420
|
}, w.changeName, true, undefined, this);
|
|
97332
98421
|
})
|
|
97333
98422
|
]
|
|
97334
98423
|
}, undefined, true, undefined, this)
|
|
97335
98424
|
]
|
|
97336
|
-
},
|
|
98425
|
+
}, resizeKey, true, undefined, this);
|
|
97337
98426
|
}
|
|
97338
|
-
var
|
|
98427
|
+
var import_react61, jsx_dev_runtime10, lineCounter = 0, TAIL_BUFFER_SIZE = 30, CMD_DISPLAY_MAX = 80, MAX_PENDING_DISPLAY = 15, SPINNER_FRAMES, HYPERLINKS_SUPPORTED, ANSI_STRIP_RE, BOX_ONLY_RE, STATUS_BAR_LINE_RE, ITER_HEADER_LINE_RE, SESSION_START;
|
|
97339
98428
|
var init_AgentMode = __esm(async () => {
|
|
97340
98429
|
init_cli2();
|
|
97341
98430
|
init_config();
|
|
97342
98431
|
init_wire();
|
|
98432
|
+
init_tasks_md();
|
|
98433
|
+
init_phase();
|
|
97343
98434
|
init_log();
|
|
97344
|
-
|
|
97345
|
-
|
|
97346
|
-
|
|
98435
|
+
init_useTerminalSize2();
|
|
98436
|
+
init_loop();
|
|
98437
|
+
init_context();
|
|
98438
|
+
await __promiseAll([
|
|
98439
|
+
init_build2(),
|
|
98440
|
+
init_SteeringField()
|
|
98441
|
+
]);
|
|
98442
|
+
import_react61 = __toESM(require_react(), 1);
|
|
98443
|
+
jsx_dev_runtime10 = __toESM(require_jsx_dev_runtime(), 1);
|
|
97347
98444
|
SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
|
|
97348
98445
|
HYPERLINKS_SUPPORTED = !process.env["TMUX"];
|
|
97349
98446
|
ANSI_STRIP_RE = /\x1b(?:\[[0-9;]*[A-Za-z]|\][^\x07\x1b]*(?:\x07|\x1b\\)|.)/g;
|
|
@@ -97353,6 +98450,112 @@ var init_AgentMode = __esm(async () => {
|
|
|
97353
98450
|
SESSION_START = new Date().toISOString();
|
|
97354
98451
|
});
|
|
97355
98452
|
|
|
98453
|
+
// apps/agent/src/pr-status.ts
|
|
98454
|
+
function bucketChecks(rollup, prState) {
|
|
98455
|
+
if (rollup === null || rollup === undefined || rollup.length === 0) {
|
|
98456
|
+
return prState === "MERGED" ? "pass" : "pending";
|
|
98457
|
+
}
|
|
98458
|
+
let anyPending = false;
|
|
98459
|
+
let anyFail = false;
|
|
98460
|
+
for (const c of rollup) {
|
|
98461
|
+
const status = (c.status ?? "").toUpperCase();
|
|
98462
|
+
const conclusion = (c.conclusion ?? "").toUpperCase();
|
|
98463
|
+
const state = (c.state ?? "").toUpperCase();
|
|
98464
|
+
if (status && status !== "COMPLETED") {
|
|
98465
|
+
anyPending = true;
|
|
98466
|
+
continue;
|
|
98467
|
+
}
|
|
98468
|
+
if (state === "PENDING" || state === "EXPECTED") {
|
|
98469
|
+
anyPending = true;
|
|
98470
|
+
continue;
|
|
98471
|
+
}
|
|
98472
|
+
const settled = conclusion || state;
|
|
98473
|
+
if (settled === "FAILURE" || settled === "TIMED_OUT" || settled === "CANCELLED" || settled === "ERROR") {
|
|
98474
|
+
anyFail = true;
|
|
98475
|
+
}
|
|
98476
|
+
}
|
|
98477
|
+
if (anyPending)
|
|
98478
|
+
return "pending";
|
|
98479
|
+
if (anyFail)
|
|
98480
|
+
return "fail";
|
|
98481
|
+
return "pass";
|
|
98482
|
+
}
|
|
98483
|
+
async function fetchPrStatus(url2, runner, cwd2) {
|
|
98484
|
+
let stdout;
|
|
98485
|
+
try {
|
|
98486
|
+
const out = await runner.run(["gh", "pr", "view", url2, "--json", PR_VIEW_FIELDS], cwd2);
|
|
98487
|
+
stdout = out.stdout;
|
|
98488
|
+
} catch (err) {
|
|
98489
|
+
const e = err;
|
|
98490
|
+
const msg = (e.stderr?.trim().split(`
|
|
98491
|
+
`)[0] ?? e.message ?? "gh failed").slice(0, 200);
|
|
98492
|
+
return { kind: "error", message: msg };
|
|
98493
|
+
}
|
|
98494
|
+
let raw;
|
|
98495
|
+
try {
|
|
98496
|
+
raw = JSON.parse(stdout || "{}");
|
|
98497
|
+
} catch (err) {
|
|
98498
|
+
return { kind: "error", message: `parse error: ${err.message}` };
|
|
98499
|
+
}
|
|
98500
|
+
const stateUpper = (raw.state ?? "").toUpperCase();
|
|
98501
|
+
const state = stateUpper === "OPEN" || stateUpper === "CLOSED" || stateUpper === "MERGED" ? stateUpper : "OPEN";
|
|
98502
|
+
const mergeableUpper = (raw.mergeable ?? "UNKNOWN").toUpperCase();
|
|
98503
|
+
const mergeable = mergeableUpper === "MERGEABLE" || mergeableUpper === "CONFLICTING" ? mergeableUpper : "UNKNOWN";
|
|
98504
|
+
return {
|
|
98505
|
+
kind: "ok",
|
|
98506
|
+
state,
|
|
98507
|
+
isDraft: Boolean(raw.isDraft),
|
|
98508
|
+
mergeable,
|
|
98509
|
+
ciBucket: bucketChecks(raw.statusCheckRollup, state),
|
|
98510
|
+
autoMergeEnabled: raw.autoMergeRequest !== null && raw.autoMergeRequest !== undefined,
|
|
98511
|
+
createdAt: raw.createdAt ?? ""
|
|
98512
|
+
};
|
|
98513
|
+
}
|
|
98514
|
+
var PR_VIEW_FIELDS = "state,isDraft,mergeable,statusCheckRollup,autoMergeRequest,createdAt";
|
|
98515
|
+
|
|
98516
|
+
// apps/agent/src/list-sort.ts
|
|
98517
|
+
function assignTier(status) {
|
|
98518
|
+
if (status === null || status.kind === "error")
|
|
98519
|
+
return 5;
|
|
98520
|
+
const conflict = status.mergeable === "CONFLICTING";
|
|
98521
|
+
const failing = status.ciBucket === "fail";
|
|
98522
|
+
if (conflict && status.autoMergeEnabled)
|
|
98523
|
+
return 1;
|
|
98524
|
+
if (failing && status.autoMergeEnabled)
|
|
98525
|
+
return 2;
|
|
98526
|
+
if (conflict)
|
|
98527
|
+
return 3;
|
|
98528
|
+
if (failing)
|
|
98529
|
+
return 4;
|
|
98530
|
+
return 5;
|
|
98531
|
+
}
|
|
98532
|
+
function createdAtOf(status) {
|
|
98533
|
+
if (status && status.kind === "ok")
|
|
98534
|
+
return status.createdAt;
|
|
98535
|
+
return "";
|
|
98536
|
+
}
|
|
98537
|
+
function sortRows(rows) {
|
|
98538
|
+
const cmp = chain((a, b) => assignTier(a.status) - assignTier(b.status), (a, b) => {
|
|
98539
|
+
const ia = a.issueCreatedAt;
|
|
98540
|
+
const ib = b.issueCreatedAt;
|
|
98541
|
+
if (ia === ib)
|
|
98542
|
+
return 0;
|
|
98543
|
+
if (ia === "")
|
|
98544
|
+
return 1;
|
|
98545
|
+
if (ib === "")
|
|
98546
|
+
return -1;
|
|
98547
|
+
return ia < ib ? -1 : 1;
|
|
98548
|
+
}, (a, b) => {
|
|
98549
|
+
const ca = createdAtOf(a.status);
|
|
98550
|
+
const cb = createdAtOf(b.status);
|
|
98551
|
+
if (ca === cb)
|
|
98552
|
+
return 0;
|
|
98553
|
+
return ca < cb ? -1 : 1;
|
|
98554
|
+
}, (a, b) => a.bucketOrder - b.bucketOrder, (a, b) => a.identifier.localeCompare(b.identifier));
|
|
98555
|
+
return [...rows].sort(cmp);
|
|
98556
|
+
}
|
|
98557
|
+
var init_list_sort = () => {};
|
|
98558
|
+
|
|
97356
98559
|
// apps/agent/src/list.ts
|
|
97357
98560
|
var exports_list = {};
|
|
97358
98561
|
__export(exports_list, {
|
|
@@ -97484,40 +98687,100 @@ async function fetchBucketIssues(apiKey, bucket, team, assignee) {
|
|
|
97484
98687
|
};
|
|
97485
98688
|
return fetchOpenIssues(apiKey, spec);
|
|
97486
98689
|
}
|
|
97487
|
-
|
|
97488
|
-
if (
|
|
97489
|
-
return;
|
|
97490
|
-
|
|
97491
|
-
|
|
97492
|
-
|
|
97493
|
-
|
|
97494
|
-
|
|
97495
|
-
|
|
97496
|
-
|
|
98690
|
+
function formatPrStatusMarker(status) {
|
|
98691
|
+
if (status === null)
|
|
98692
|
+
return "(no PR)";
|
|
98693
|
+
if (status.kind === "error")
|
|
98694
|
+
return "?";
|
|
98695
|
+
if (status.state === "MERGED")
|
|
98696
|
+
return "merged";
|
|
98697
|
+
if (status.state === "CLOSED")
|
|
98698
|
+
return "closed";
|
|
98699
|
+
const parts = [];
|
|
98700
|
+
if (status.mergeable === "CONFLICTING")
|
|
98701
|
+
parts.push("\u2717conflict");
|
|
98702
|
+
if (status.ciBucket === "fail")
|
|
98703
|
+
parts.push("\u2717ci");
|
|
98704
|
+
if (status.ciBucket === "pending")
|
|
98705
|
+
parts.push("\u23F3ci");
|
|
98706
|
+
if (status.isDraft)
|
|
98707
|
+
parts.push("draft");
|
|
98708
|
+
if (status.autoMergeEnabled)
|
|
98709
|
+
parts.push("auto-merge");
|
|
98710
|
+
if (parts.length === 0)
|
|
98711
|
+
return "ok";
|
|
98712
|
+
return parts.join(" ");
|
|
98713
|
+
}
|
|
98714
|
+
async function fetchAndPrintLinear(apiKey, buckets, team, assignee, cwd2, runner) {
|
|
98715
|
+
const bucketResults = await Promise.all(buckets.map(async (bucket) => {
|
|
98716
|
+
if (!bucket.indicator || bucket.indicator.filter.length === 0) {
|
|
98717
|
+
return { bucket, issues: [], error: null };
|
|
98718
|
+
}
|
|
98719
|
+
try {
|
|
98720
|
+
const issues = await fetchBucketIssues(apiKey, bucket, team, assignee);
|
|
98721
|
+
return { bucket, issues, error: null };
|
|
98722
|
+
} catch (err) {
|
|
98723
|
+
return {
|
|
98724
|
+
bucket,
|
|
98725
|
+
issues: [],
|
|
98726
|
+
error: err instanceof Error ? err.message : String(err)
|
|
98727
|
+
};
|
|
98728
|
+
}
|
|
98729
|
+
}));
|
|
98730
|
+
for (const { bucket, error: error48 } of bucketResults) {
|
|
98731
|
+
if (error48) {
|
|
98732
|
+
process.stdout.write(`
|
|
98733
|
+
${bucket.label}: error fetching from Linear \u2014 ${error48}
|
|
97497
98734
|
`);
|
|
97498
|
-
|
|
98735
|
+
}
|
|
98736
|
+
}
|
|
98737
|
+
const seen = new Map;
|
|
98738
|
+
let order = 0;
|
|
98739
|
+
for (const { bucket, issues } of bucketResults) {
|
|
98740
|
+
for (const issue2 of issues) {
|
|
98741
|
+
if (seen.has(issue2.id))
|
|
98742
|
+
continue;
|
|
98743
|
+
seen.set(issue2.id, {
|
|
98744
|
+
issueId: issue2.id,
|
|
98745
|
+
identifier: issue2.identifier,
|
|
98746
|
+
status: null,
|
|
98747
|
+
bucketOrder: order++,
|
|
98748
|
+
issueCreatedAt: issue2.createdAt,
|
|
98749
|
+
bucketLabel: bucket.label,
|
|
98750
|
+
stateName: issue2.state.name,
|
|
98751
|
+
title: issue2.title.slice(0, 60),
|
|
98752
|
+
prUrl: null
|
|
98753
|
+
});
|
|
98754
|
+
}
|
|
97499
98755
|
}
|
|
97500
|
-
const
|
|
98756
|
+
const rows = [...seen.values()];
|
|
98757
|
+
await Promise.all(rows.map(async (row) => {
|
|
98758
|
+
try {
|
|
98759
|
+
const attachments = await fetchIssueAttachments(apiKey, row.issueId);
|
|
98760
|
+
row.prUrl = findPullRequestUrl(attachments);
|
|
98761
|
+
} catch {}
|
|
98762
|
+
}));
|
|
98763
|
+
await Promise.all(rows.map(async (row) => {
|
|
98764
|
+
if (!row.prUrl)
|
|
98765
|
+
return;
|
|
98766
|
+
row.status = await fetchPrStatus(row.prUrl, runner, cwd2);
|
|
98767
|
+
}));
|
|
98768
|
+
const sorted = sortRows(rows);
|
|
97501
98769
|
process.stdout.write(`
|
|
97502
|
-
|
|
98770
|
+
Linear tickets: ${sorted.length} issue(s)
|
|
97503
98771
|
`);
|
|
97504
|
-
if (
|
|
98772
|
+
if (sorted.length === 0)
|
|
97505
98773
|
return;
|
|
97506
|
-
const
|
|
97507
|
-
|
|
97508
|
-
|
|
97509
|
-
|
|
97510
|
-
|
|
97511
|
-
|
|
97512
|
-
|
|
97513
|
-
|
|
97514
|
-
|
|
97515
|
-
|
|
97516
|
-
for (let index = 0;index < issues.length; index += 1) {
|
|
97517
|
-
const issue2 = issues[index];
|
|
97518
|
-
const pr = prUrls[index];
|
|
97519
|
-
const title = issue2.title.slice(0, 60);
|
|
97520
|
-
process.stdout.write(` ${pad2(issue2.identifier, idWidth)} ${pad2(issue2.state.name, stateWidth)} ${pad2(title, 60)} ${pr ?? "(no PR)"}
|
|
98774
|
+
const idWidth = Math.max(10, ...sorted.map((r) => r.identifier.length));
|
|
98775
|
+
const bucketWidth = Math.max(6, ...sorted.map((r) => r.bucketLabel.length));
|
|
98776
|
+
const stateWidth = Math.max(5, ...sorted.map((r) => r.stateName.length));
|
|
98777
|
+
const markers = sorted.map((r) => formatPrStatusMarker(r.status));
|
|
98778
|
+
const markerWidth = Math.max(9, ...markers.map((m) => m.length));
|
|
98779
|
+
process.stdout.write(` ${pad2("Identifier", idWidth)} ${pad2("Bucket", bucketWidth)} ${pad2("State", stateWidth)} ${pad2("Title", 60)} ${pad2("PR Status", markerWidth)} PR URL
|
|
98780
|
+
`);
|
|
98781
|
+
for (let i = 0;i < sorted.length; i += 1) {
|
|
98782
|
+
const r = sorted[i];
|
|
98783
|
+
process.stdout.write(` ${pad2(r.identifier, idWidth)} ${pad2(r.bucketLabel, bucketWidth)} ${pad2(r.stateName, stateWidth)} ${pad2(r.title, 60)} ${pad2(markers[i], markerWidth)} ${r.prUrl ?? "(no PR)"}
|
|
97521
98784
|
`);
|
|
97522
98785
|
}
|
|
97523
98786
|
}
|
|
@@ -97566,18 +98829,14 @@ Linear: LINEAR_API_KEY not set \u2014 cannot fetch tickets. Configured buckets:
|
|
|
97566
98829
|
}
|
|
97567
98830
|
return;
|
|
97568
98831
|
}
|
|
97569
|
-
process.stdout.write(`
|
|
97570
|
-
Linear tickets:
|
|
97571
|
-
`);
|
|
97572
98832
|
if (team)
|
|
97573
|
-
process.stdout.write(`
|
|
98833
|
+
process.stdout.write(`
|
|
98834
|
+
team: ${team}
|
|
97574
98835
|
`);
|
|
97575
98836
|
if (assignee)
|
|
97576
|
-
process.stdout.write(`
|
|
98837
|
+
process.stdout.write(`assignee: ${assignee}
|
|
97577
98838
|
`);
|
|
97578
|
-
|
|
97579
|
-
await printBucket(apiKey, bucket, team, assignee);
|
|
97580
|
-
}
|
|
98839
|
+
await fetchAndPrintLinear(apiKey, buckets, team, assignee, projectRoot, localCmdRunner);
|
|
97581
98840
|
}
|
|
97582
98841
|
function normalizeIdentifier(input) {
|
|
97583
98842
|
const match = input.match(/^([A-Za-z]+)-(\d+)(?:-.*)?$/);
|
|
@@ -97724,12 +98983,27 @@ Per-bucket diagnostics:
|
|
|
97724
98983
|
}
|
|
97725
98984
|
}
|
|
97726
98985
|
}
|
|
97727
|
-
var RALPHY_ATTACHMENT_TITLE2 = "Ralphy";
|
|
98986
|
+
var localCmdRunner, RALPHY_ATTACHMENT_TITLE2 = "Ralphy";
|
|
97728
98987
|
var init_list = __esm(() => {
|
|
97729
98988
|
init_context();
|
|
97730
98989
|
init_types2();
|
|
97731
98990
|
init_worktree();
|
|
97732
98991
|
init_config();
|
|
98992
|
+
init_list_sort();
|
|
98993
|
+
localCmdRunner = {
|
|
98994
|
+
run: async (cmd, cwd2) => {
|
|
98995
|
+
const proc = Bun.spawn({ cmd, cwd: cwd2, stdout: "pipe", stderr: "pipe" });
|
|
98996
|
+
const stdout = await new Response(proc.stdout).text();
|
|
98997
|
+
const stderr = await new Response(proc.stderr).text();
|
|
98998
|
+
const code = await proc.exited;
|
|
98999
|
+
if (code !== 0) {
|
|
99000
|
+
const err = new Error(`\`${cmd.join(" ")}\` exited ${code}`);
|
|
99001
|
+
err.stderr = stderr;
|
|
99002
|
+
throw err;
|
|
99003
|
+
}
|
|
99004
|
+
return { stdout, stderr };
|
|
99005
|
+
}
|
|
99006
|
+
};
|
|
97733
99007
|
});
|
|
97734
99008
|
|
|
97735
99009
|
// apps/agent/src/agent/json-runner.ts
|
|
@@ -97773,7 +99047,7 @@ async function runAgentJson({
|
|
|
97773
99047
|
process.exitCode = 1;
|
|
97774
99048
|
return;
|
|
97775
99049
|
}
|
|
97776
|
-
const { coord, filterDesc, concurrency, pollInterval } = buildAgentCoordinator({
|
|
99050
|
+
const { coord, filterDesc, concurrency, pollInterval, runBaselineGate: runBaselineGate2 } = buildAgentCoordinator({
|
|
97777
99051
|
args,
|
|
97778
99052
|
cfg,
|
|
97779
99053
|
projectRoot,
|
|
@@ -97836,6 +99110,17 @@ async function runAgentJson({
|
|
|
97836
99110
|
if (cancelled)
|
|
97837
99111
|
return;
|
|
97838
99112
|
emit({ type: "poll_start" });
|
|
99113
|
+
try {
|
|
99114
|
+
await runBaselineGate2();
|
|
99115
|
+
} catch (err) {
|
|
99116
|
+
emit({
|
|
99117
|
+
type: "log",
|
|
99118
|
+
text: `baseline gate failed: ${err.message}`,
|
|
99119
|
+
color: "yellow"
|
|
99120
|
+
});
|
|
99121
|
+
}
|
|
99122
|
+
if (cancelled)
|
|
99123
|
+
return;
|
|
97839
99124
|
const { found, added, buckets, prStatus } = await coord.pollOnce();
|
|
97840
99125
|
if (cancelled)
|
|
97841
99126
|
return;
|
|
@@ -97949,12 +99234,12 @@ async function main2(argv) {
|
|
|
97949
99234
|
return typeof process.exitCode === "number" ? process.exitCode : 0;
|
|
97950
99235
|
}
|
|
97951
99236
|
await runWithContext(createDefaultContext(), async () => {
|
|
97952
|
-
const { waitUntilExit } = render_default(
|
|
99237
|
+
const { waitUntilExit } = render_default(import_react62.createElement(AgentMode, { args, projectRoot, statesDir, tasksDir }));
|
|
97953
99238
|
await waitUntilExit();
|
|
97954
99239
|
});
|
|
97955
99240
|
return typeof process.exitCode === "number" ? process.exitCode : 0;
|
|
97956
99241
|
}
|
|
97957
|
-
var
|
|
99242
|
+
var import_react62;
|
|
97958
99243
|
var init_src6 = __esm(async () => {
|
|
97959
99244
|
init_context();
|
|
97960
99245
|
init_layout();
|
|
@@ -97964,7 +99249,7 @@ var init_src6 = __esm(async () => {
|
|
|
97964
99249
|
init_build2(),
|
|
97965
99250
|
init_AgentMode()
|
|
97966
99251
|
]);
|
|
97967
|
-
|
|
99252
|
+
import_react62 = __toESM(require_react(), 1);
|
|
97968
99253
|
});
|
|
97969
99254
|
|
|
97970
99255
|
// apps/shell/src/index.ts
|
|
@@ -98027,7 +99312,12 @@ ${HELP}
|
|
|
98027
99312
|
setDefaultProperties({ subcommand });
|
|
98028
99313
|
capture("command_run", { subcommand });
|
|
98029
99314
|
try {
|
|
98030
|
-
|
|
99315
|
+
const code = await dispatch(subcommand, argv.slice(1));
|
|
99316
|
+
capture("command_exit", { subcommand, exit_code: code });
|
|
99317
|
+
return code;
|
|
99318
|
+
} catch (err) {
|
|
99319
|
+
captureError("command_error", err, { subcommand });
|
|
99320
|
+
throw err;
|
|
98031
99321
|
} finally {
|
|
98032
99322
|
await shutdown();
|
|
98033
99323
|
}
|