@ordewell/core 0.6.4 → 0.7.1
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 +1 -1
- package/dist/{IFileSystem-Qj2MWHn_.d.mts → IFileSystem-BnLh-_SK.d.mts} +1 -1
- package/dist/{IFileSystem-DQEKyC6H.d.ts → IFileSystem-DofiRcCo.d.ts} +1 -1
- package/dist/{ModeResolver-rqaY_4Ex.d.mts → ModeResolver-DZzJSdIU.d.mts} +3 -3
- package/dist/{ModeResolver-ByNpC0EP.d.ts → ModeResolver-DkMYf4uS.d.ts} +3 -3
- package/dist/{Task-xqdxugt2.d.mts → Task-BnLxkVQF.d.mts} +414 -22
- package/dist/{Task-xqdxugt2.d.ts → Task-BnLxkVQF.d.ts} +414 -22
- package/dist/{chunk-JRZPSNRO.mjs → chunk-LGQNXPBX.mjs} +10 -2
- package/dist/chunk-LGQNXPBX.mjs.map +1 -0
- package/dist/{chunk-N66ZHFGN.mjs → chunk-OYUSADFM.mjs} +11 -1
- package/dist/chunk-OYUSADFM.mjs.map +1 -0
- package/dist/{chunk-HPNUFBIT.mjs → chunk-V3JHS7AX.mjs} +9 -1
- package/dist/chunk-V3JHS7AX.mjs.map +1 -0
- package/dist/{chunk-I6U3PVHL.mjs → chunk-Y36NIASW.mjs} +255 -32
- package/dist/chunk-Y36NIASW.mjs.map +1 -0
- package/dist/{chunk-M4KXBEFJ.mjs → chunk-ZV5LDNCO.mjs} +44 -43
- package/dist/chunk-ZV5LDNCO.mjs.map +1 -0
- package/dist/index.d.mts +518 -238
- package/dist/index.d.ts +518 -238
- package/dist/index.js +3925 -1568
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +3525 -1393
- package/dist/index.mjs.map +1 -1
- package/dist/order-labels.d.mts +16 -2
- package/dist/order-labels.d.ts +16 -2
- package/dist/order-labels.js +12 -2
- package/dist/order-labels.js.map +1 -1
- package/dist/order-labels.mjs +7 -3
- package/dist/{parsing-DDZ1rUYa.d.mts → parsing-B6ctfF80.d.mts} +24 -3
- package/dist/{parsing-COPG8-Ep.d.ts → parsing-ddZXZFP4.d.ts} +24 -3
- package/dist/parsing.d.mts +4 -3
- package/dist/parsing.d.ts +4 -3
- package/dist/parsing.js +42 -41
- package/dist/parsing.js.map +1 -1
- package/dist/parsing.mjs +3 -3
- package/dist/{plan-utils-Br8UAoiu.d.ts → plan-utils--kQRzSE-.d.ts} +251 -7
- package/dist/{plan-utils-DMgajMvd.d.mts → plan-utils-CKgNtDwQ.d.mts} +251 -7
- package/dist/plan-utils.d.mts +5 -3
- package/dist/plan-utils.d.ts +5 -3
- package/dist/plan-utils.js +313 -61
- package/dist/plan-utils.js.map +1 -1
- package/dist/plan-utils.mjs +46 -3
- package/dist/testing.d.mts +26 -5
- package/dist/testing.d.ts +26 -5
- package/dist/testing.js +62 -2
- package/dist/testing.js.map +1 -1
- package/dist/testing.mjs +62 -4
- package/dist/testing.mjs.map +1 -1
- package/package.json +4 -2
- package/dist/chunk-HPNUFBIT.mjs.map +0 -1
- package/dist/chunk-I6U3PVHL.mjs.map +0 -1
- package/dist/chunk-JRZPSNRO.mjs.map +0 -1
- package/dist/chunk-M4KXBEFJ.mjs.map +0 -1
- package/dist/chunk-N66ZHFGN.mjs.map +0 -1
package/dist/plan-utils.d.mts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { a as ApprovalBlock, b as ApprovalStatus, C as CHECKPOINT_TRUNCATE_LENGTH, c as ConversationInput, d as ConversationView, D as DisplayBlock, E as EMPTY_CONVERSATION,
|
|
2
|
-
|
|
1
|
+
export { a as ApprovalBlock, b as ApprovalStatus, C as CHECKPOINT_TRUNCATE_LENGTH, c as ConversationInput, d as ConversationView, D as DiffRow, e as DiffRowKind, f as DiffStat, g as DisplayBlock, E as EMPTY_CONVERSATION, h as EMPTY_HOLD, i as EMPTY_TASK_LOG, G as GatedConversation, L as LocalEntry, j as MessageBlock, k as MessageRole, N as NOT_STARTED, l as NO_TURN, m as NewTaskFields, O as OutputPreview, P as PlanBlock, n as PlanMarkerStatus, o as PromptHold, u as SubagentBlock, v as SubagentChild, w as SubagentStatus, T as TakenPrompt, y as TaskLogView, B as TaskRef, F as TaskRowAction, H as TaskRowContext, I as TaskRowIsolation, J as TaskRowKind, K as TaskRowPlacement, Q as TaskRowSubject, R as TaskRowView, U as TaskStatusKind, V as ThinkingDisplayBlock, W as ToolBlock, X as ToolHeadline, Y as ToolStatus, Z as TurnGate, _ as UsageBlock, $ as aheadOfDraft, a1 as approvalLabel, a2 as awaitingLabel, a3 as canMergeTasks, a4 as canSetDependencies, a5 as canSplitTask, a6 as capConflictFiles, a9 as dependencyCandidates, aa as dependentsNotice, ab as dependentsOf, ac as diffRows, ad as diffStat, ae as diffSummary, ag as drainNext, ai as followTurn, aj as fromTranscript, ak as hasHiddenDetail, al as holdPrompt, am as isTaskRunning, an as markAction, ao as markRequestFor, ap as namedRepos, aq as newTaskFields, ar as opsEditable, as as outputLines, at as outputPreview, av as pastGateConfirmation, aw as reduceConversation, ax as reduceTaskLog, ay as replayTaskLog, az as runnerToolSubject, aD as stopTurn, aE as summarizeToolCall, aF as taskRowActions, aG as taskRowView, aH as taskStartedNotice, aI as taskStatusKind, aK as titledRefs, aM as toolHeadline, aO as truncateCheckpointSummary, aP as unsendAll, aQ as unsendLatest } from './plan-utils-CKgNtDwQ.mjs';
|
|
2
|
+
export { taskOrderLabel, taskRef, titledTaskRef } from './order-labels.mjs';
|
|
3
|
+
import './Task-BnLxkVQF.mjs';
|
|
3
4
|
import 'child_process';
|
|
4
5
|
import 'events';
|
|
5
|
-
import '
|
|
6
|
+
import 'zod/v4';
|
|
7
|
+
import './ModeResolver-DZzJSdIU.mjs';
|
package/dist/plan-utils.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
export { a as ApprovalBlock, b as ApprovalStatus, C as CHECKPOINT_TRUNCATE_LENGTH, c as ConversationInput, d as ConversationView, D as DisplayBlock, E as EMPTY_CONVERSATION,
|
|
2
|
-
|
|
1
|
+
export { a as ApprovalBlock, b as ApprovalStatus, C as CHECKPOINT_TRUNCATE_LENGTH, c as ConversationInput, d as ConversationView, D as DiffRow, e as DiffRowKind, f as DiffStat, g as DisplayBlock, E as EMPTY_CONVERSATION, h as EMPTY_HOLD, i as EMPTY_TASK_LOG, G as GatedConversation, L as LocalEntry, j as MessageBlock, k as MessageRole, N as NOT_STARTED, l as NO_TURN, m as NewTaskFields, O as OutputPreview, P as PlanBlock, n as PlanMarkerStatus, o as PromptHold, u as SubagentBlock, v as SubagentChild, w as SubagentStatus, T as TakenPrompt, y as TaskLogView, B as TaskRef, F as TaskRowAction, H as TaskRowContext, I as TaskRowIsolation, J as TaskRowKind, K as TaskRowPlacement, Q as TaskRowSubject, R as TaskRowView, U as TaskStatusKind, V as ThinkingDisplayBlock, W as ToolBlock, X as ToolHeadline, Y as ToolStatus, Z as TurnGate, _ as UsageBlock, $ as aheadOfDraft, a1 as approvalLabel, a2 as awaitingLabel, a3 as canMergeTasks, a4 as canSetDependencies, a5 as canSplitTask, a6 as capConflictFiles, a9 as dependencyCandidates, aa as dependentsNotice, ab as dependentsOf, ac as diffRows, ad as diffStat, ae as diffSummary, ag as drainNext, ai as followTurn, aj as fromTranscript, ak as hasHiddenDetail, al as holdPrompt, am as isTaskRunning, an as markAction, ao as markRequestFor, ap as namedRepos, aq as newTaskFields, ar as opsEditable, as as outputLines, at as outputPreview, av as pastGateConfirmation, aw as reduceConversation, ax as reduceTaskLog, ay as replayTaskLog, az as runnerToolSubject, aD as stopTurn, aE as summarizeToolCall, aF as taskRowActions, aG as taskRowView, aH as taskStartedNotice, aI as taskStatusKind, aK as titledRefs, aM as toolHeadline, aO as truncateCheckpointSummary, aP as unsendAll, aQ as unsendLatest } from './plan-utils--kQRzSE-.js';
|
|
2
|
+
export { taskOrderLabel, taskRef, titledTaskRef } from './order-labels.js';
|
|
3
|
+
import './Task-BnLxkVQF.js';
|
|
3
4
|
import 'child_process';
|
|
4
5
|
import 'events';
|
|
5
|
-
import '
|
|
6
|
+
import 'zod/v4';
|
|
7
|
+
import './ModeResolver-DkMYf4uS.js';
|
package/dist/plan-utils.js
CHANGED
|
@@ -24,28 +24,49 @@ __export(plan_utils_exports, {
|
|
|
24
24
|
EMPTY_CONVERSATION: () => EMPTY_CONVERSATION,
|
|
25
25
|
EMPTY_HOLD: () => EMPTY_HOLD,
|
|
26
26
|
EMPTY_TASK_LOG: () => EMPTY_TASK_LOG,
|
|
27
|
+
NOT_STARTED: () => NOT_STARTED,
|
|
27
28
|
NO_TURN: () => NO_TURN,
|
|
28
29
|
aheadOfDraft: () => aheadOfDraft,
|
|
30
|
+
approvalLabel: () => approvalLabel,
|
|
31
|
+
awaitingLabel: () => awaitingLabel,
|
|
29
32
|
canMergeTasks: () => canMergeTasks,
|
|
30
33
|
canSetDependencies: () => canSetDependencies,
|
|
31
34
|
canSplitTask: () => canSplitTask,
|
|
32
35
|
capConflictFiles: () => capConflictFiles,
|
|
33
36
|
dependencyCandidates: () => dependencyCandidates,
|
|
37
|
+
dependentsNotice: () => dependentsNotice,
|
|
34
38
|
dependentsOf: () => dependentsOf,
|
|
39
|
+
diffRows: () => diffRows,
|
|
40
|
+
diffStat: () => diffStat,
|
|
41
|
+
diffSummary: () => diffSummary,
|
|
35
42
|
drainNext: () => drainNext,
|
|
36
43
|
followTurn: () => followTurn,
|
|
37
44
|
fromTranscript: () => fromTranscript,
|
|
38
45
|
hasHiddenDetail: () => hasHiddenDetail,
|
|
39
46
|
holdPrompt: () => holdPrompt,
|
|
47
|
+
isTaskRunning: () => isTaskRunning,
|
|
48
|
+
markAction: () => markAction,
|
|
49
|
+
markRequestFor: () => markRequestFor,
|
|
50
|
+
namedRepos: () => namedRepos,
|
|
51
|
+
newTaskFields: () => newTaskFields,
|
|
52
|
+
opsEditable: () => opsEditable,
|
|
40
53
|
outputLines: () => outputLines,
|
|
41
54
|
outputPreview: () => outputPreview,
|
|
55
|
+
pastGateConfirmation: () => pastGateConfirmation,
|
|
42
56
|
reduceConversation: () => reduceConversation,
|
|
43
57
|
reduceTaskLog: () => reduceTaskLog,
|
|
44
58
|
replayTaskLog: () => replayTaskLog,
|
|
45
59
|
runnerToolSubject: () => runnerToolSubject,
|
|
46
60
|
stopTurn: () => stopTurn,
|
|
47
61
|
summarizeToolCall: () => summarizeToolCall,
|
|
62
|
+
taskOrderLabel: () => taskOrderLabel,
|
|
63
|
+
taskRef: () => taskRef,
|
|
64
|
+
taskRowActions: () => taskRowActions,
|
|
65
|
+
taskRowView: () => taskRowView,
|
|
48
66
|
taskStartedNotice: () => taskStartedNotice,
|
|
67
|
+
taskStatusKind: () => taskStatusKind,
|
|
68
|
+
titledRefs: () => titledRefs,
|
|
69
|
+
titledTaskRef: () => titledTaskRef,
|
|
49
70
|
toolHeadline: () => toolHeadline,
|
|
50
71
|
truncateCheckpointSummary: () => truncateCheckpointSummary,
|
|
51
72
|
unsendAll: () => unsendAll,
|
|
@@ -55,6 +76,50 @@ module.exports = __toCommonJS(plan_utils_exports);
|
|
|
55
76
|
|
|
56
77
|
// src/services/TaskOps.ts
|
|
57
78
|
var import_uuid = require("uuid");
|
|
79
|
+
|
|
80
|
+
// src/order-labels.ts
|
|
81
|
+
function taskOrderLabel(task, parent) {
|
|
82
|
+
return parent ? `${parent.order}.${task.order}` : String(task.order);
|
|
83
|
+
}
|
|
84
|
+
function taskRef(task, parent) {
|
|
85
|
+
return `#${taskOrderLabel(task, parent)}`;
|
|
86
|
+
}
|
|
87
|
+
function titledTaskRef(task, parent) {
|
|
88
|
+
return `${taskRef(task, parent)} ${task.title}`;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// src/taskRow/status.ts
|
|
92
|
+
var isTaskRunning = (task) => task.status === "in_progress" || task.status === "running";
|
|
93
|
+
var NOT_STARTED = /* @__PURE__ */ new Set(["pending", "approved", "blocked"]);
|
|
94
|
+
function taskStatusKind(task) {
|
|
95
|
+
switch (task.status) {
|
|
96
|
+
case "completed":
|
|
97
|
+
return "done";
|
|
98
|
+
case "failed":
|
|
99
|
+
return "failed";
|
|
100
|
+
case "blocked":
|
|
101
|
+
return "blocked";
|
|
102
|
+
case "awaiting_user":
|
|
103
|
+
return "awaiting";
|
|
104
|
+
}
|
|
105
|
+
if (!isTaskRunning(task)) return "todo";
|
|
106
|
+
return task.status === "in_progress" && task.idleSince ? "quiet" : "running";
|
|
107
|
+
}
|
|
108
|
+
var AWAITING_LABELS = {
|
|
109
|
+
input: "Waiting for your input",
|
|
110
|
+
checkpoint: "Checkpoint",
|
|
111
|
+
conflict: "Merge conflict",
|
|
112
|
+
"files-changed": "Changed tracked files"
|
|
113
|
+
};
|
|
114
|
+
function awaitingLabel(task) {
|
|
115
|
+
return task.status === "awaiting_user" && task.awaitingReason ? AWAITING_LABELS[task.awaitingReason] : null;
|
|
116
|
+
}
|
|
117
|
+
function approvalLabel(count) {
|
|
118
|
+
if (!count) return null;
|
|
119
|
+
return count > 1 ? `Waiting for approval (${count})` : "Waiting for approval";
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// src/services/TaskOps.ts
|
|
58
123
|
function detectCycle(tasks) {
|
|
59
124
|
const byId = new Map(tasks.map((t) => [t.id, t]));
|
|
60
125
|
const visiting = /* @__PURE__ */ new Set();
|
|
@@ -268,9 +333,9 @@ function oneLine(text2) {
|
|
|
268
333
|
return text2.replace(/\s+/g, " ").trim();
|
|
269
334
|
}
|
|
270
335
|
function firstLineOf(command) {
|
|
271
|
-
const
|
|
272
|
-
const more =
|
|
273
|
-
return more > 0 ? `${
|
|
336
|
+
const lines2 = command.trim().split(/\r?\n/);
|
|
337
|
+
const more = lines2.length - 1;
|
|
338
|
+
return more > 0 ? `${lines2[0]} \u2026 +${more} line${more === 1 ? "" : "s"}` : lines2[0];
|
|
274
339
|
}
|
|
275
340
|
function text(value) {
|
|
276
341
|
return typeof value === "string" ? value : "";
|
|
@@ -317,14 +382,108 @@ function toolHeadline(tool, args, toolLabel) {
|
|
|
317
382
|
return { name, keyArg: parsed ? keyArgOf(tool, parsed) : oneLine(args) };
|
|
318
383
|
}
|
|
319
384
|
function outputLines(output) {
|
|
320
|
-
const
|
|
321
|
-
while (
|
|
322
|
-
return
|
|
385
|
+
const lines2 = output.replace(/\r\n?/g, "\n").replace(ANSI_OR_CTRL_RE, "").split("\n");
|
|
386
|
+
while (lines2.length > 0 && lines2[lines2.length - 1].trim() === "") lines2.pop();
|
|
387
|
+
return lines2;
|
|
323
388
|
}
|
|
324
389
|
function outputPreview(output, maxLines) {
|
|
325
|
-
const
|
|
326
|
-
const shown =
|
|
327
|
-
return { lines: shown, hiddenLineCount:
|
|
390
|
+
const lines2 = outputLines(output);
|
|
391
|
+
const shown = lines2.slice(0, Math.max(0, maxLines));
|
|
392
|
+
return { lines: shown, hiddenLineCount: lines2.length - shown.length };
|
|
393
|
+
}
|
|
394
|
+
function diffStat(output) {
|
|
395
|
+
const lines2 = outputLines(output);
|
|
396
|
+
let added = 0;
|
|
397
|
+
let removed = 0;
|
|
398
|
+
for (const line of lines2) {
|
|
399
|
+
if (line.startsWith("+")) added += 1;
|
|
400
|
+
else if (line.startsWith("-")) removed += 1;
|
|
401
|
+
else if (!(line.startsWith("@@") || line.startsWith(" ") || line === "" || line.startsWith("\\"))) return null;
|
|
402
|
+
}
|
|
403
|
+
return added + removed > 0 ? { added, removed } : null;
|
|
404
|
+
}
|
|
405
|
+
var HUNK_RANGE = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@/;
|
|
406
|
+
function diffRows(output) {
|
|
407
|
+
const rows = [];
|
|
408
|
+
let oldLine = 1;
|
|
409
|
+
let newLine = 1;
|
|
410
|
+
for (const line of outputLines(output)) {
|
|
411
|
+
const range = HUNK_RANGE.exec(line);
|
|
412
|
+
if (range) {
|
|
413
|
+
if (rows.length > 0) rows.push({ kind: "gap", text: "" });
|
|
414
|
+
oldLine = Number(range[1]);
|
|
415
|
+
newLine = Number(range[2]);
|
|
416
|
+
} else if (line.startsWith("+")) {
|
|
417
|
+
rows.push({ kind: "added", line: newLine++, text: line.slice(1) });
|
|
418
|
+
} else if (line.startsWith("-")) {
|
|
419
|
+
rows.push({ kind: "removed", line: oldLine++, text: line.slice(1) });
|
|
420
|
+
} else if (!line.startsWith("\\")) {
|
|
421
|
+
rows.push({ kind: "context", line: newLine, text: line.slice(1) });
|
|
422
|
+
oldLine += 1;
|
|
423
|
+
newLine += 1;
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return rows;
|
|
427
|
+
}
|
|
428
|
+
function lines(count) {
|
|
429
|
+
return `${count} line${count === 1 ? "" : "s"}`;
|
|
430
|
+
}
|
|
431
|
+
function diffSummary({ added, removed }) {
|
|
432
|
+
if (!removed) return `Added ${lines(added)}`;
|
|
433
|
+
if (!added) return `Removed ${lines(removed)}`;
|
|
434
|
+
return `Added ${lines(added)}, removed ${lines(removed)}`;
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// src/services/harness/agentTools.ts
|
|
438
|
+
var KNOWN_TOOLS = {
|
|
439
|
+
// Claude Code
|
|
440
|
+
read: "read_file",
|
|
441
|
+
grep: "grep",
|
|
442
|
+
glob: "glob",
|
|
443
|
+
bash: "bash",
|
|
444
|
+
ls: "list_dir",
|
|
445
|
+
webfetch: "fetch",
|
|
446
|
+
websearch: "web_search",
|
|
447
|
+
// Codex — its sandboxed command tool is a shell by another name
|
|
448
|
+
shell: "bash",
|
|
449
|
+
exec_command: "bash",
|
|
450
|
+
local_shell: "bash",
|
|
451
|
+
// OpenCode
|
|
452
|
+
list: "list_dir",
|
|
453
|
+
fetch: "fetch"
|
|
454
|
+
};
|
|
455
|
+
var FILE_EDIT_TOOLS = /* @__PURE__ */ new Set(["edit", "write", "multiedit", "notebookedit", "applypatch", "patch", "add", "update", "delete", "filechange"]);
|
|
456
|
+
function isFileEditTool(name) {
|
|
457
|
+
return FILE_EDIT_TOOLS.has(name.trim().toLowerCase().replace(/[_-]/g, ""));
|
|
458
|
+
}
|
|
459
|
+
function mapAgentTool(name) {
|
|
460
|
+
const normalized = name.trim().toLowerCase().replace(/[_-]/g, "");
|
|
461
|
+
const direct = KNOWN_TOOLS[normalized] ?? KNOWN_TOOLS[name.trim().toLowerCase()];
|
|
462
|
+
if (direct) {
|
|
463
|
+
return { tool: direct, toolLabel: name };
|
|
464
|
+
}
|
|
465
|
+
return { tool: "agent_tool", toolLabel: name };
|
|
466
|
+
}
|
|
467
|
+
function normalizeAgentArgs(tool, args) {
|
|
468
|
+
const out = { ...args };
|
|
469
|
+
const alias = (from, to) => {
|
|
470
|
+
if (out[to] === void 0 && out[from] !== void 0) out[to] = out[from];
|
|
471
|
+
};
|
|
472
|
+
if (tool === "read_file" || tool === "list_dir") {
|
|
473
|
+
alias("filePath", "path");
|
|
474
|
+
alias("file_path", "path");
|
|
475
|
+
alias("target", "path");
|
|
476
|
+
}
|
|
477
|
+
if (tool === "bash") {
|
|
478
|
+
alias("cmd", "command");
|
|
479
|
+
alias("script", "command");
|
|
480
|
+
if (typeof out.command !== "string" && Array.isArray(out.command)) {
|
|
481
|
+
out.command = out.command.join(" ");
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
if (tool === "fetch") alias("uri", "url");
|
|
485
|
+
if (tool === "web_search") alias("q", "query");
|
|
486
|
+
return out;
|
|
328
487
|
}
|
|
329
488
|
|
|
330
489
|
// src/conversation/records.ts
|
|
@@ -353,7 +512,8 @@ var STATUS_OF_OUTCOME = {
|
|
|
353
512
|
not_executed: "interrupted"
|
|
354
513
|
};
|
|
355
514
|
function finishedTool(call, output, outcome) {
|
|
356
|
-
|
|
515
|
+
const diff = outcome === "success" && isFileEditTool(call.toolLabel ?? call.tool) ? diffStat(output) : null;
|
|
516
|
+
return { ...call, status: STATUS_OF_OUTCOME[outcome], outcome, output, outputLineCount: outputLines(output).length, ...diff ? { diff } : {} };
|
|
357
517
|
}
|
|
358
518
|
function settledTool(call, step) {
|
|
359
519
|
return finishedTool(call, step.result, step.outcome);
|
|
@@ -788,54 +948,6 @@ function fromTranscript(conversationHistory, researchLog, plannerUsage) {
|
|
|
788
948
|
return { blocks, nextId, ...transcriptAt ? { transcriptAt } : {} };
|
|
789
949
|
}
|
|
790
950
|
|
|
791
|
-
// src/services/harness/agentTools.ts
|
|
792
|
-
var KNOWN_TOOLS = {
|
|
793
|
-
// Claude Code
|
|
794
|
-
read: "read_file",
|
|
795
|
-
grep: "grep",
|
|
796
|
-
glob: "glob",
|
|
797
|
-
bash: "bash",
|
|
798
|
-
ls: "list_dir",
|
|
799
|
-
webfetch: "fetch",
|
|
800
|
-
websearch: "web_search",
|
|
801
|
-
// Codex — its sandboxed command tool is a shell by another name
|
|
802
|
-
shell: "bash",
|
|
803
|
-
exec_command: "bash",
|
|
804
|
-
local_shell: "bash",
|
|
805
|
-
// OpenCode
|
|
806
|
-
list: "list_dir",
|
|
807
|
-
fetch: "fetch"
|
|
808
|
-
};
|
|
809
|
-
function mapAgentTool(name) {
|
|
810
|
-
const normalized = name.trim().toLowerCase().replace(/[_-]/g, "");
|
|
811
|
-
const direct = KNOWN_TOOLS[normalized] ?? KNOWN_TOOLS[name.trim().toLowerCase()];
|
|
812
|
-
if (direct) {
|
|
813
|
-
return { tool: direct, toolLabel: name };
|
|
814
|
-
}
|
|
815
|
-
return { tool: "agent_tool", toolLabel: name };
|
|
816
|
-
}
|
|
817
|
-
function normalizeAgentArgs(tool, args) {
|
|
818
|
-
const out = { ...args };
|
|
819
|
-
const alias = (from, to) => {
|
|
820
|
-
if (out[to] === void 0 && out[from] !== void 0) out[to] = out[from];
|
|
821
|
-
};
|
|
822
|
-
if (tool === "read_file" || tool === "list_dir") {
|
|
823
|
-
alias("filePath", "path");
|
|
824
|
-
alias("file_path", "path");
|
|
825
|
-
alias("target", "path");
|
|
826
|
-
}
|
|
827
|
-
if (tool === "bash") {
|
|
828
|
-
alias("cmd", "command");
|
|
829
|
-
alias("script", "command");
|
|
830
|
-
if (typeof out.command !== "string" && Array.isArray(out.command)) {
|
|
831
|
-
out.command = out.command.join(" ");
|
|
832
|
-
}
|
|
833
|
-
}
|
|
834
|
-
if (tool === "fetch") alias("uri", "url");
|
|
835
|
-
if (tool === "web_search") alias("q", "query");
|
|
836
|
-
return out;
|
|
837
|
-
}
|
|
838
|
-
|
|
839
951
|
// src/conversation/taskLog.ts
|
|
840
952
|
var EMPTY_TASK_LOG = { blocks: [], nextId: 1, queued: [], working: false, streams: {} };
|
|
841
953
|
var TEXT_STREAM = "text";
|
|
@@ -981,9 +1093,25 @@ function endTurn2(view, { reason }) {
|
|
|
981
1093
|
const closed = closeOpenBlocks({ ...view, working: false, lastTurnEnd: reason, streams: {} }, CUT[reason]);
|
|
982
1094
|
return reason === "interrupted" ? append(closed, (id) => settledMessage(id, "system", "Interrupted.")) : closed;
|
|
983
1095
|
}
|
|
984
|
-
function queueMessage(view, { messageId, text: text2 }) {
|
|
985
|
-
|
|
986
|
-
|
|
1096
|
+
function queueMessage(view, { messageId, text: text2, forced }) {
|
|
1097
|
+
const listed = view.queued.find((m) => m.id === messageId);
|
|
1098
|
+
if (forced) {
|
|
1099
|
+
const rest = view.queued.filter((m) => m !== listed);
|
|
1100
|
+
const at = rest.findIndex((m) => !m.forced);
|
|
1101
|
+
const placed = at < 0 ? rest.length : at;
|
|
1102
|
+
return { ...view, queued: [...rest.slice(0, placed), { id: messageId, text: text2, forced: true }, ...rest.slice(placed)] };
|
|
1103
|
+
}
|
|
1104
|
+
if (!listed) return { ...view, queued: [...view.queued, { id: messageId, text: text2 }] };
|
|
1105
|
+
if (!listed.handedOver) return view;
|
|
1106
|
+
return { ...view, queued: view.queued.map((m) => m === listed ? { id: m.id, text: m.text } : m) };
|
|
1107
|
+
}
|
|
1108
|
+
function handOver(view, { messageId }) {
|
|
1109
|
+
const listed = view.queued.find((m) => m.id === messageId);
|
|
1110
|
+
if (!listed || listed.handedOver) return view;
|
|
1111
|
+
return { ...view, queued: view.queued.map((m) => m === listed ? { ...m, handedOver: true } : m) };
|
|
1112
|
+
}
|
|
1113
|
+
function deliverMidTurn(view, event) {
|
|
1114
|
+
return appendOutput(unqueueMessage(view, event), null, (id) => settledMessage(id, "user", event.text));
|
|
987
1115
|
}
|
|
988
1116
|
function unqueueMessage(view, { messageId }) {
|
|
989
1117
|
const queued = view.queued.filter((m) => m.id !== messageId);
|
|
@@ -1017,6 +1145,12 @@ function reduceTaskLog(view, event) {
|
|
|
1017
1145
|
return queueMessage(view, event);
|
|
1018
1146
|
case "message_removed":
|
|
1019
1147
|
return unqueueMessage(view, event);
|
|
1148
|
+
case "message_handed_over":
|
|
1149
|
+
return handOver(view, event);
|
|
1150
|
+
case "message_delivered":
|
|
1151
|
+
return deliverMidTurn(view, event);
|
|
1152
|
+
case "message_undelivered":
|
|
1153
|
+
return append(unqueueMessage(view, event), (id) => settledMessage(id, "system", `${event.text} \xB7 not delivered`));
|
|
1020
1154
|
case "error":
|
|
1021
1155
|
return appendOutput(view, null, (id) => settledMessage(id, "error", event.message));
|
|
1022
1156
|
case "approval_requested":
|
|
@@ -1105,34 +1239,152 @@ function hasHiddenDetail(blocks) {
|
|
|
1105
1239
|
function taskStartedNotice(title, runner) {
|
|
1106
1240
|
return runner ? `Started "${title}" \xB7 ${runner}` : `Started "${title}"`;
|
|
1107
1241
|
}
|
|
1242
|
+
|
|
1243
|
+
// src/taskRow/actions.ts
|
|
1244
|
+
var UNSTARTED_AI = (t) => t.type === "ai" && NOT_STARTED.has(t.status);
|
|
1245
|
+
var QUEUED = (t) => t.status === "pending" || t.status === "approved";
|
|
1246
|
+
var TASK_RULES = [
|
|
1247
|
+
["cancel", (t) => t.status === "in_progress"],
|
|
1248
|
+
["skip", (t) => t.status === "blocked"],
|
|
1249
|
+
["force-start", UNSTARTED_AI],
|
|
1250
|
+
// A manual task has no runner to report it done, so it can always be marked.
|
|
1251
|
+
["complete", (t) => t.status === "awaiting_user" || t.type === "user"],
|
|
1252
|
+
["uncomplete", (t) => t.status === "completed"]
|
|
1253
|
+
];
|
|
1254
|
+
var SUBTASK_RULES = [
|
|
1255
|
+
["cancel", (t) => t.status === "in_progress"],
|
|
1256
|
+
["complete", (t) => t.status === "in_progress" && t.type === "ai"],
|
|
1257
|
+
["force-start", (t) => t.type === "ai" && QUEUED(t)],
|
|
1258
|
+
["skip", QUEUED],
|
|
1259
|
+
["complete", (t) => t.status === "awaiting_user"],
|
|
1260
|
+
["uncomplete", (t) => t.status === "completed"]
|
|
1261
|
+
];
|
|
1262
|
+
function taskRowActions(task, placement = "task") {
|
|
1263
|
+
const rules = placement === "subtask" ? SUBTASK_RULES : TASK_RULES;
|
|
1264
|
+
return rules.filter(([, applies]) => applies(task)).map(([action]) => action);
|
|
1265
|
+
}
|
|
1266
|
+
function markAction(task) {
|
|
1267
|
+
return task.status === "completed" ? "uncomplete" : "complete";
|
|
1268
|
+
}
|
|
1269
|
+
function markRequestFor(action) {
|
|
1270
|
+
if (action === "complete" || action === "skip") return "complete";
|
|
1271
|
+
if (action === "uncomplete") return "uncomplete";
|
|
1272
|
+
return null;
|
|
1273
|
+
}
|
|
1274
|
+
function opsEditable(task) {
|
|
1275
|
+
return UNSTARTED_AI(task);
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
// src/taskRow/view.ts
|
|
1279
|
+
var refsOf = (ids, orderOf) => ids.map((id) => {
|
|
1280
|
+
const order = orderOf?.get(id);
|
|
1281
|
+
return order === void 0 ? id : taskRef({ order });
|
|
1282
|
+
});
|
|
1283
|
+
var namedRepo = (repo) => repo && repo !== "." ? repo : null;
|
|
1284
|
+
var namedRepos = (repos) => (repos ?? []).filter((r) => r !== ".");
|
|
1285
|
+
var filesOf = (files) => files?.length ? capConflictFiles(files) : null;
|
|
1286
|
+
function taskRowView(task, context = {}) {
|
|
1287
|
+
const parent = context.parent ?? void 0;
|
|
1288
|
+
const isolation = task.isolation && task.isolation.state !== "none" ? task.isolation : null;
|
|
1289
|
+
return {
|
|
1290
|
+
orderLabel: taskOrderLabel(task, parent),
|
|
1291
|
+
kind: task.type === "user" ? "user" : task.ops ? "ops" : "ai",
|
|
1292
|
+
status: taskStatusKind(task),
|
|
1293
|
+
running: isTaskRunning(task),
|
|
1294
|
+
awaiting: awaitingLabel(task),
|
|
1295
|
+
approvals: approvalLabel(task.awaitingApproval),
|
|
1296
|
+
autonomous: task.type === "ai" && context.modes?.find((m) => m.id === task.taskMode)?.autonomous === true,
|
|
1297
|
+
repos: namedRepos(isolation?.repos),
|
|
1298
|
+
conflict: isolation?.state === "conflict" ? { repo: namedRepo(isolation.conflictRepo), files: filesOf(isolation.conflictFiles) } : null,
|
|
1299
|
+
repairing: isolation?.state === "repairing" ? { files: filesOf(isolation.conflictFiles), attempt: isolation.repair ?? null } : null,
|
|
1300
|
+
repaired: isolation?.repairedFiles?.length ? { files: capConflictFiles(isolation.repairedFiles), landed: isolation.state === "integrated" } : null,
|
|
1301
|
+
mergeGate: task.mergeGate?.length ? refsOf(task.mergeGate, context.orderOf) : null,
|
|
1302
|
+
opsChangedFiles: task.status === "awaiting_user" && task.awaitingReason === "files-changed",
|
|
1303
|
+
forcedPastGate: task.forcedPastGate?.length ? task.forcedPastGate : null,
|
|
1304
|
+
dependencies: refsOf(task.dependencies, context.orderOf),
|
|
1305
|
+
actions: taskRowActions(task, context.placement ?? (parent ? "subtask" : "task")),
|
|
1306
|
+
mark: markAction(task),
|
|
1307
|
+
opsEditable: opsEditable(task)
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
// src/taskRow/texts.ts
|
|
1312
|
+
function findNamed(tasks, id) {
|
|
1313
|
+
for (const task of tasks) {
|
|
1314
|
+
if (task.id === id) return task;
|
|
1315
|
+
const nested = findNamed(task.subtasks ?? [], id);
|
|
1316
|
+
if (nested) return nested;
|
|
1317
|
+
}
|
|
1318
|
+
return void 0;
|
|
1319
|
+
}
|
|
1320
|
+
function titledRefs(ids, tasks) {
|
|
1321
|
+
return ids.map((id) => {
|
|
1322
|
+
const task = findNamed(tasks, id);
|
|
1323
|
+
return task ? titledTaskRef(task) : id;
|
|
1324
|
+
});
|
|
1325
|
+
}
|
|
1326
|
+
function dependentsNotice(dependents) {
|
|
1327
|
+
if (dependents.length === 0) return null;
|
|
1328
|
+
const subject = dependents.length === 1 ? "1 task depends" : `${dependents.length} tasks depend`;
|
|
1329
|
+
return `${subject} on it and will lose that dependency: ${dependents.map((t) => titledTaskRef(t)).join(", ")}.`;
|
|
1330
|
+
}
|
|
1331
|
+
function pastGateConfirmation(unmerged, subject = "This task") {
|
|
1332
|
+
return `${subject} waits for Merge all: the work of ${unmerged.join(", ")} is not merged into your branch yet, so it would act without it. Starting it now is kept on the task.`;
|
|
1333
|
+
}
|
|
1334
|
+
function newTaskFields(title, prompt) {
|
|
1335
|
+
const name = title.trim();
|
|
1336
|
+
if (!name) return null;
|
|
1337
|
+
return { title: name, description: name, prompt: prompt?.trim() ? prompt : name, type: "ai" };
|
|
1338
|
+
}
|
|
1108
1339
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1109
1340
|
0 && (module.exports = {
|
|
1110
1341
|
CHECKPOINT_TRUNCATE_LENGTH,
|
|
1111
1342
|
EMPTY_CONVERSATION,
|
|
1112
1343
|
EMPTY_HOLD,
|
|
1113
1344
|
EMPTY_TASK_LOG,
|
|
1345
|
+
NOT_STARTED,
|
|
1114
1346
|
NO_TURN,
|
|
1115
1347
|
aheadOfDraft,
|
|
1348
|
+
approvalLabel,
|
|
1349
|
+
awaitingLabel,
|
|
1116
1350
|
canMergeTasks,
|
|
1117
1351
|
canSetDependencies,
|
|
1118
1352
|
canSplitTask,
|
|
1119
1353
|
capConflictFiles,
|
|
1120
1354
|
dependencyCandidates,
|
|
1355
|
+
dependentsNotice,
|
|
1121
1356
|
dependentsOf,
|
|
1357
|
+
diffRows,
|
|
1358
|
+
diffStat,
|
|
1359
|
+
diffSummary,
|
|
1122
1360
|
drainNext,
|
|
1123
1361
|
followTurn,
|
|
1124
1362
|
fromTranscript,
|
|
1125
1363
|
hasHiddenDetail,
|
|
1126
1364
|
holdPrompt,
|
|
1365
|
+
isTaskRunning,
|
|
1366
|
+
markAction,
|
|
1367
|
+
markRequestFor,
|
|
1368
|
+
namedRepos,
|
|
1369
|
+
newTaskFields,
|
|
1370
|
+
opsEditable,
|
|
1127
1371
|
outputLines,
|
|
1128
1372
|
outputPreview,
|
|
1373
|
+
pastGateConfirmation,
|
|
1129
1374
|
reduceConversation,
|
|
1130
1375
|
reduceTaskLog,
|
|
1131
1376
|
replayTaskLog,
|
|
1132
1377
|
runnerToolSubject,
|
|
1133
1378
|
stopTurn,
|
|
1134
1379
|
summarizeToolCall,
|
|
1380
|
+
taskOrderLabel,
|
|
1381
|
+
taskRef,
|
|
1382
|
+
taskRowActions,
|
|
1383
|
+
taskRowView,
|
|
1135
1384
|
taskStartedNotice,
|
|
1385
|
+
taskStatusKind,
|
|
1386
|
+
titledRefs,
|
|
1387
|
+
titledTaskRef,
|
|
1136
1388
|
toolHeadline,
|
|
1137
1389
|
truncateCheckpointSummary,
|
|
1138
1390
|
unsendAll,
|