@ordewell/cli 0.10.1 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +580 -468
- package/package.json +5 -3
package/dist/main.js
CHANGED
|
@@ -24,7 +24,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
24
24
|
));
|
|
25
25
|
|
|
26
26
|
// src/main.ts
|
|
27
|
-
var
|
|
27
|
+
var import_core49 = require("@ordewell/core");
|
|
28
28
|
|
|
29
29
|
// src/utils/env.ts
|
|
30
30
|
var import_fs = require("fs");
|
|
@@ -107,6 +107,23 @@ function moveAutonomyToSettings() {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
// src/runnerNames.ts
|
|
111
|
+
var import_core2 = require("@ordewell/core");
|
|
112
|
+
function manifests() {
|
|
113
|
+
return new import_core2.RunnerRegistry().list().map((entry) => entry.manifest);
|
|
114
|
+
}
|
|
115
|
+
function runnerIdList() {
|
|
116
|
+
return manifests().map((m) => m.name).join(", ");
|
|
117
|
+
}
|
|
118
|
+
function runnerIdChoice() {
|
|
119
|
+
return manifests().map((m) => m.name).join("|");
|
|
120
|
+
}
|
|
121
|
+
function runnerNamesOr() {
|
|
122
|
+
const names = manifests().map((m) => m.displayName);
|
|
123
|
+
if (names.length < 2) return names.join("");
|
|
124
|
+
return `${names.slice(0, -1).join(", ")} or ${names[names.length - 1]}`;
|
|
125
|
+
}
|
|
126
|
+
|
|
110
127
|
// src/help.ts
|
|
111
128
|
function printHelp() {
|
|
112
129
|
console.log(`
|
|
@@ -157,7 +174,7 @@ Planner, models and runners:
|
|
|
157
174
|
ordewell model [set <id>] Show or set the planner model (applies without a restart)
|
|
158
175
|
ordewell planner-effort [lvl] Thinking effort for a coding-agent planner
|
|
159
176
|
ordewell key [set <p> <key>] Show which providers have a key, or store one
|
|
160
|
-
ordewell runners [<id> on|off] Enable or disable runners (
|
|
177
|
+
ordewell runners [<id> on|off] Enable or disable runners (${runnerIdList()})
|
|
161
178
|
ordewell allowlist set|clear|show Limit which models a runner may use
|
|
162
179
|
ordewell auto [full|guarded] Autonomy level for new plans: Full or Guarded
|
|
163
180
|
ordewell supervisor [off|watch|act] Whether the planner watches or acts on your runs (default watch);
|
|
@@ -236,13 +253,13 @@ Quick Start:
|
|
|
236
253
|
then run: ordewell plan --goal "Your task description"
|
|
237
254
|
|
|
238
255
|
No API key? Plan with a coding agent you already pay for:
|
|
239
|
-
AI_PROVIDER
|
|
256
|
+
AI_PROVIDER=<runner> ordewell plan --goal "Your task description"
|
|
240
257
|
|
|
241
258
|
Environment:
|
|
242
259
|
OPENROUTER_API_KEY OpenRouter API key (recommended)
|
|
243
260
|
GEMINI_API_KEY Google Gemini API key (alternative)
|
|
244
261
|
AI_PROVIDER openrouter, google \u2014 auto-detected from keys
|
|
245
|
-
|
|
262
|
+
${runnerIdList()} \u2014 plan with that CLI,
|
|
246
263
|
no API key (uses its own subscription)
|
|
247
264
|
ORDEWELL_PLANNER_EFFORT Thinking effort for a coding-agent planner
|
|
248
265
|
ORCHESTRATOR_MODEL Default: deepseek/deepseek-v4-flash
|
|
@@ -275,9 +292,9 @@ var import_os = require("os");
|
|
|
275
292
|
var import_path2 = require("path");
|
|
276
293
|
var import_http = __toESM(require("http"));
|
|
277
294
|
var import_net = require("net");
|
|
278
|
-
var
|
|
295
|
+
var import_core3 = require("@ordewell/core");
|
|
279
296
|
var DEFAULT_PORT = 3742;
|
|
280
|
-
var CONFIG_DIR = (0,
|
|
297
|
+
var CONFIG_DIR = (0, import_core3.globalDataDir)();
|
|
281
298
|
var LEGACY_PID_FILE = (0, import_path2.join)(CONFIG_DIR, "server.pid");
|
|
282
299
|
var OLD_CONFIG_DIR = (0, import_path2.join)((0, import_os.homedir)(), ".config", "ordewell");
|
|
283
300
|
function pidFileFor(port) {
|
|
@@ -317,12 +334,12 @@ function getWebServerPath() {
|
|
|
317
334
|
);
|
|
318
335
|
}
|
|
319
336
|
async function isDaemonRunning(port = DEFAULT_PORT) {
|
|
320
|
-
const token = (0,
|
|
337
|
+
const token = (0, import_core3.readDaemonToken)(port);
|
|
321
338
|
try {
|
|
322
339
|
const res = await httpGet(
|
|
323
340
|
`http://127.0.0.1:${port}/api/workspaces`,
|
|
324
341
|
2e3,
|
|
325
|
-
token ? { Authorization: (0,
|
|
342
|
+
token ? { Authorization: (0, import_core3.bearerHeaderValue)(token) } : {}
|
|
326
343
|
);
|
|
327
344
|
return res.status === 200 || res.status === 401;
|
|
328
345
|
} catch {
|
|
@@ -378,7 +395,7 @@ async function stopDaemon(port = DEFAULT_PORT) {
|
|
|
378
395
|
const pid = parseInt(pidStr, 10);
|
|
379
396
|
if (!pid || isNaN(pid)) {
|
|
380
397
|
(0, import_fs2.unlinkSync)(pidFile);
|
|
381
|
-
(0,
|
|
398
|
+
(0, import_core3.clearDaemonToken)(port);
|
|
382
399
|
return false;
|
|
383
400
|
}
|
|
384
401
|
process.kill(pid, "SIGTERM");
|
|
@@ -391,7 +408,7 @@ async function stopDaemon(port = DEFAULT_PORT) {
|
|
|
391
408
|
(0, import_fs2.unlinkSync)(pidFile);
|
|
392
409
|
} catch {
|
|
393
410
|
}
|
|
394
|
-
(0,
|
|
411
|
+
(0, import_core3.clearDaemonToken)(port);
|
|
395
412
|
console.log("Server was not running (stale PID removed).");
|
|
396
413
|
return true;
|
|
397
414
|
}
|
|
@@ -444,7 +461,7 @@ function resolvePort(args = []) {
|
|
|
444
461
|
// src/apiClient.ts
|
|
445
462
|
var import_http2 = __toESM(require("http"));
|
|
446
463
|
var import_ws = __toESM(require("ws"));
|
|
447
|
-
var
|
|
464
|
+
var import_core4 = require("@ordewell/core");
|
|
448
465
|
var DEFAULT_HTTP_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
449
466
|
var DaemonError = class extends Error {
|
|
450
467
|
constructor(message, status, code) {
|
|
@@ -488,7 +505,7 @@ var ApiClient = class _ApiClient {
|
|
|
488
505
|
* A missing file is not an error here — the daemon's own 401 names the path.
|
|
489
506
|
*/
|
|
490
507
|
token() {
|
|
491
|
-
return (0,
|
|
508
|
+
return (0, import_core4.readDaemonToken)(this.port);
|
|
492
509
|
}
|
|
493
510
|
/**
|
|
494
511
|
* A daemon holds only the sessions adopted since it started, so after a
|
|
@@ -524,7 +541,7 @@ var ApiClient = class _ApiClient {
|
|
|
524
541
|
method,
|
|
525
542
|
headers: {
|
|
526
543
|
...body ? { "Content-Type": "application/json" } : {},
|
|
527
|
-
...token ? { Authorization: (0,
|
|
544
|
+
...token ? { Authorization: (0, import_core4.bearerHeaderValue)(token) } : {}
|
|
528
545
|
},
|
|
529
546
|
// Planner research on a real repository regularly exceeds two minutes.
|
|
530
547
|
// The benchmark harness uses the same 15-minute default explicitly;
|
|
@@ -554,7 +571,7 @@ var ApiClient = class _ApiClient {
|
|
|
554
571
|
req.end();
|
|
555
572
|
});
|
|
556
573
|
}
|
|
557
|
-
async generatePlan(goal, runners2, workspace, sessionId = (0,
|
|
574
|
+
async generatePlan(goal, runners2, workspace, sessionId = (0, import_core4.mintSessionId)()) {
|
|
558
575
|
const { plan, models, modelsByRunner, notes } = await this.call("POST", `/api/plans/${sessionId}/generate`, "Plan generation failed", {
|
|
559
576
|
goal,
|
|
560
577
|
runners: runners2 || void 0,
|
|
@@ -789,7 +806,7 @@ var ApiClient = class _ApiClient {
|
|
|
789
806
|
const token = this.token();
|
|
790
807
|
const socket = new import_ws.default(
|
|
791
808
|
`ws://127.0.0.1:${this.port}/ws/session/${sessionId}`,
|
|
792
|
-
token ? (0,
|
|
809
|
+
token ? (0, import_core4.tokenSubprotocols)(token) : void 0
|
|
793
810
|
);
|
|
794
811
|
socket.on("unexpected-response", (_req, res) => {
|
|
795
812
|
const chunks = [];
|
|
@@ -1012,15 +1029,15 @@ function positionals(args) {
|
|
|
1012
1029
|
}
|
|
1013
1030
|
|
|
1014
1031
|
// src/utils/tasks.ts
|
|
1015
|
-
var
|
|
1032
|
+
var import_core5 = require("@ordewell/core");
|
|
1016
1033
|
function allTasksOf(plan) {
|
|
1017
1034
|
const tasks = plan?.pendingTasks || plan?.tasks || [];
|
|
1018
1035
|
const executionLog = plan?.executionLog || [];
|
|
1019
|
-
return (0,
|
|
1036
|
+
return (0, import_core5.rejoinPlanTree)(tasks, executionLog);
|
|
1020
1037
|
}
|
|
1021
1038
|
function resolveTaskId(plan, identifier) {
|
|
1022
1039
|
const allTasks = allTasksOf(plan);
|
|
1023
|
-
const byRef = (0,
|
|
1040
|
+
const byRef = (0, import_core5.resolveTaskRef)(allTasks, identifier);
|
|
1024
1041
|
if (byRef) return byRef.id;
|
|
1025
1042
|
const prefixMatches = allTasks.filter((t) => typeof t.id === "string" && t.id.startsWith(identifier));
|
|
1026
1043
|
if (prefixMatches.length === 1) return prefixMatches[0].id;
|
|
@@ -1030,13 +1047,13 @@ function resolveTaskId(plan, identifier) {
|
|
|
1030
1047
|
// src/utils/session.ts
|
|
1031
1048
|
var import_fs3 = require("fs");
|
|
1032
1049
|
var import_path3 = require("path");
|
|
1033
|
-
var
|
|
1050
|
+
var import_core6 = require("@ordewell/core");
|
|
1034
1051
|
var LAST_SESSION_FILENAME = "last-session.json";
|
|
1035
1052
|
function lastSessionFile(workspace) {
|
|
1036
|
-
return (0, import_path3.join)((0,
|
|
1053
|
+
return (0, import_path3.join)((0, import_core6.getStateDir)(workspace), LAST_SESSION_FILENAME);
|
|
1037
1054
|
}
|
|
1038
1055
|
function saveLastSession(sessionId, goal, runners2, workspace) {
|
|
1039
|
-
const dir = (0,
|
|
1056
|
+
const dir = (0, import_core6.getStateDir)(workspace);
|
|
1040
1057
|
if (!(0, import_fs3.existsSync)(dir)) (0, import_fs3.mkdirSync)(dir, { recursive: true });
|
|
1041
1058
|
(0, import_fs3.writeFileSync)(
|
|
1042
1059
|
lastSessionFile(workspace),
|
|
@@ -1058,14 +1075,14 @@ function expandSessionId(id, workspace) {
|
|
|
1058
1075
|
if (id.startsWith(SESSION_PREFIX)) return id;
|
|
1059
1076
|
let files;
|
|
1060
1077
|
try {
|
|
1061
|
-
files = (0, import_fs3.readdirSync)((0, import_path3.join)((0,
|
|
1078
|
+
files = (0, import_fs3.readdirSync)((0, import_path3.join)((0, import_core6.getStateDir)(workspace), "sessions")).filter((f) => f.endsWith(".json"));
|
|
1062
1079
|
} catch {
|
|
1063
1080
|
return id;
|
|
1064
1081
|
}
|
|
1065
1082
|
const matches = /* @__PURE__ */ new Set();
|
|
1066
1083
|
for (const file of files) {
|
|
1067
1084
|
try {
|
|
1068
|
-
const full = JSON.parse((0, import_fs3.readFileSync)((0, import_path3.join)((0,
|
|
1085
|
+
const full = JSON.parse((0, import_fs3.readFileSync)((0, import_path3.join)((0, import_core6.getStateDir)(workspace), "sessions", file), "utf8"))?.meta?.id;
|
|
1069
1086
|
if (typeof full === "string" && (full.endsWith(id) || full.slice(SESSION_PREFIX.length).startsWith(id))) matches.add(full);
|
|
1070
1087
|
} catch {
|
|
1071
1088
|
}
|
|
@@ -1136,7 +1153,7 @@ ${describeApproval(event)}
|
|
|
1136
1153
|
}
|
|
1137
1154
|
|
|
1138
1155
|
// src/commands/researchLog.ts
|
|
1139
|
-
var
|
|
1156
|
+
var import_core7 = require("@ordewell/core");
|
|
1140
1157
|
var OUTCOME_MARK = {
|
|
1141
1158
|
success: "\u2713",
|
|
1142
1159
|
failure: "\u2717",
|
|
@@ -1148,7 +1165,7 @@ var RESULT_CHARS = 160;
|
|
|
1148
1165
|
var VERBOSE_RESULT_CHARS = 600;
|
|
1149
1166
|
var THINKING_CHARS = 300;
|
|
1150
1167
|
function summarize(tool, args, toolLabel) {
|
|
1151
|
-
const { name, keyArg } = (0,
|
|
1168
|
+
const { name, keyArg } = (0, import_core7.toolHeadline)(tool, args, toolLabel);
|
|
1152
1169
|
return `${name}(${keyArg})`;
|
|
1153
1170
|
}
|
|
1154
1171
|
function oneLine(text, max) {
|
|
@@ -1198,7 +1215,7 @@ function createStepLog(options = {}) {
|
|
|
1198
1215
|
}
|
|
1199
1216
|
|
|
1200
1217
|
// src/commands/plan.ts
|
|
1201
|
-
var
|
|
1218
|
+
var import_core8 = require("@ordewell/core");
|
|
1202
1219
|
function planTasks(plan) {
|
|
1203
1220
|
return plan ? allTasksOf(plan) : [];
|
|
1204
1221
|
}
|
|
@@ -1282,11 +1299,11 @@ Plan: ${tasks.length} task${tasks.length === 1 ? "" : "s"} (${aiCount} AI, ${man
|
|
|
1282
1299
|
for (const t of tasks) {
|
|
1283
1300
|
const typeIcon = t.type === "user" ? "[MAN]" : t.ops ? "[OPS]" : "[ AI]";
|
|
1284
1301
|
const deps = t.dependencies?.length ? ` \u2190 ${t.dependencies.join(", ")}` : "";
|
|
1285
|
-
console.log(` ${(0,
|
|
1302
|
+
console.log(` ${(0, import_core8.taskOrderLabel)(t).padStart(2)}. ${typeIcon} ${t.title}${modelSuffix(t)}${deps}`);
|
|
1286
1303
|
for (const sub of t.subtasks || []) {
|
|
1287
1304
|
const subTypeIcon = sub.type === "user" ? "[MAN]" : "[ AI]";
|
|
1288
1305
|
const subDeps = sub.dependencies?.length ? ` \u2190 ${sub.dependencies.join(", ")}` : "";
|
|
1289
|
-
console.log(` ${(0,
|
|
1306
|
+
console.log(` ${(0, import_core8.taskOrderLabel)(sub, t)}. ${subTypeIcon} ${sub.title}${modelSuffix(sub)}${subDeps}`);
|
|
1290
1307
|
}
|
|
1291
1308
|
}
|
|
1292
1309
|
if (manCount > 0) {
|
|
@@ -1336,7 +1353,7 @@ async function handlePlan(subArgs, deps = {}) {
|
|
|
1336
1353
|
runners2 = runnerFlags;
|
|
1337
1354
|
}
|
|
1338
1355
|
console.error(`Generating plan for: "${goal}"...`);
|
|
1339
|
-
const sessionId = (0,
|
|
1356
|
+
const sessionId = (0, import_core8.mintSessionId)();
|
|
1340
1357
|
const isTty = !!process.stderr.isTTY;
|
|
1341
1358
|
let lastLineLength = 0;
|
|
1342
1359
|
const stepLog = createStepLog({ verbose });
|
|
@@ -1442,7 +1459,7 @@ ${note}`);
|
|
|
1442
1459
|
}
|
|
1443
1460
|
|
|
1444
1461
|
// src/isolation.ts
|
|
1445
|
-
var
|
|
1462
|
+
var import_core9 = require("@ordewell/core");
|
|
1446
1463
|
var STATE_OF = {
|
|
1447
1464
|
active: "active",
|
|
1448
1465
|
merged: "integrated",
|
|
@@ -1526,9 +1543,9 @@ function repairedLanded(handoff) {
|
|
|
1526
1543
|
function repairedNotice(handoff) {
|
|
1527
1544
|
const repaired = repairedLanded(handoff);
|
|
1528
1545
|
if (repaired.length === 0) return "";
|
|
1529
|
-
const named = repaired.map((t) => `${t.title} (${(0,
|
|
1530
|
-
const
|
|
1531
|
-
return ` ${
|
|
1546
|
+
const named = repaired.map((t) => `${t.title} (${(0, import_core9.capConflictFiles)(t.repairedFiles)})`);
|
|
1547
|
+
const list2 = named.length === 1 ? named[0] : `${named.slice(0, -1).join(", ")} and ${named[named.length - 1]}`;
|
|
1548
|
+
return ` ${list2} landed through ${repaired.length === 1 ? "a conflict repair" : "conflict repairs"}.`;
|
|
1532
1549
|
}
|
|
1533
1550
|
function repoResultLines(handoff) {
|
|
1534
1551
|
return handoff.repos.map(({ path, landed }) => {
|
|
@@ -1541,14 +1558,14 @@ function mergeOutcome(result, branch, group, repaired = []) {
|
|
|
1541
1558
|
if (!group && result.outcome === "conflict") {
|
|
1542
1559
|
return { ok, message: `Merging ${branch} conflicted, so it was aborted \u2014 your tree is as it was. Merge it with git and resolve the conflict there.` };
|
|
1543
1560
|
}
|
|
1544
|
-
const { message } = (0,
|
|
1561
|
+
const { message } = (0, import_core9.describeMergeResult)(result, branch, group, repaired);
|
|
1545
1562
|
return { ok, message: ok || !group ? message : `${message} Each repository's ${branch} is a plain branch you can merge by hand.` };
|
|
1546
1563
|
}
|
|
1547
1564
|
|
|
1548
1565
|
// src/utils/output.ts
|
|
1549
|
-
var
|
|
1566
|
+
var import_core10 = require("@ordewell/core");
|
|
1550
1567
|
function iconFor(status) {
|
|
1551
|
-
switch ((0,
|
|
1568
|
+
switch ((0, import_core10.taskStatusKind)({ status })) {
|
|
1552
1569
|
case "done":
|
|
1553
1570
|
return "\x1B[32m\u2713\x1B[0m";
|
|
1554
1571
|
case "running":
|
|
@@ -1568,7 +1585,7 @@ function iconFor(status) {
|
|
|
1568
1585
|
}
|
|
1569
1586
|
|
|
1570
1587
|
// src/commands/run.ts
|
|
1571
|
-
var
|
|
1588
|
+
var import_core11 = require("@ordewell/core");
|
|
1572
1589
|
|
|
1573
1590
|
// src/commands/shared.ts
|
|
1574
1591
|
var import_readline2 = require("readline");
|
|
@@ -1727,11 +1744,11 @@ async function followExecution(api, sessionId, start, onBlocked) {
|
|
|
1727
1744
|
});
|
|
1728
1745
|
const stream = api.streamExecution(sessionId, (event) => {
|
|
1729
1746
|
if (event.type === "task_started") {
|
|
1730
|
-
process.stderr.write(`\xB7 ${(0,
|
|
1747
|
+
process.stderr.write(`\xB7 ${(0, import_core11.taskStartedNotice)(event.title, event.runner)}
|
|
1731
1748
|
`);
|
|
1732
1749
|
}
|
|
1733
1750
|
if (event.type === "checkpoint") {
|
|
1734
|
-
process.stderr.write(`\xB7 Checkpoint \u2014 ${event.taskTitle}: ${(0,
|
|
1751
|
+
process.stderr.write(`\xB7 Checkpoint \u2014 ${event.taskTitle}: ${(0, import_core11.truncateCheckpointSummary)(event.summary)} \u2014 \`ordewell checkpoint <id> approve|reject [reason]\` answers it
|
|
1735
1752
|
`);
|
|
1736
1753
|
}
|
|
1737
1754
|
if (event.type === "status_update" && event.tasks) {
|
|
@@ -1812,7 +1829,7 @@ async function handleRun(subArgs, injectedApi) {
|
|
|
1812
1829
|
}
|
|
1813
1830
|
|
|
1814
1831
|
// src/tui/blocks.ts
|
|
1815
|
-
var
|
|
1832
|
+
var import_core13 = require("@ordewell/core");
|
|
1816
1833
|
|
|
1817
1834
|
// src/tui/ansi.ts
|
|
1818
1835
|
var import_string_width = __toESM(require("string-width"));
|
|
@@ -2027,94 +2044,191 @@ var style = {
|
|
|
2027
2044
|
};
|
|
2028
2045
|
|
|
2029
2046
|
// src/tui/markdown.ts
|
|
2047
|
+
var import_core12 = require("@ordewell/core");
|
|
2030
2048
|
function renderMarkdown(source, cols) {
|
|
2031
|
-
|
|
2049
|
+
return blocks((0, import_core12.markdownTokens)(source), { room: Math.max(1, cols), base: [] });
|
|
2050
|
+
}
|
|
2051
|
+
function closeOf(tokens, open) {
|
|
2052
|
+
const { level } = tokens[open];
|
|
2053
|
+
for (let i = open + 1; i < tokens.length; i += 1) {
|
|
2054
|
+
if (tokens[i].nesting === -1 && tokens[i].level === level) return i;
|
|
2055
|
+
}
|
|
2056
|
+
return tokens.length - 1;
|
|
2057
|
+
}
|
|
2058
|
+
function lastLine(tokens) {
|
|
2059
|
+
let last = null;
|
|
2060
|
+
for (const token of tokens) {
|
|
2061
|
+
if (token.nesting === 0 && token.map && (last === null || token.map[1] > last)) last = token.map[1];
|
|
2062
|
+
}
|
|
2063
|
+
return last ?? tokens[0]?.map?.[1] ?? null;
|
|
2064
|
+
}
|
|
2065
|
+
function blocks(tokens, ctx) {
|
|
2032
2066
|
const out = [];
|
|
2033
|
-
let
|
|
2034
|
-
for (let i = 0; i <
|
|
2035
|
-
const
|
|
2036
|
-
if (
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
i = table.end;
|
|
2048
|
-
continue;
|
|
2049
|
-
}
|
|
2050
|
-
const heading = line.match(/^\s{0,3}(#{1,6})\s+(.+?)\s*#*\s*$/);
|
|
2051
|
-
if (heading) {
|
|
2052
|
-
const paint = heading[1].length <= 2 ? (text) => style.bold(style.brand(text)) : style.bold;
|
|
2053
|
-
out.push(...wrap(paint(inline(heading[2])), cols));
|
|
2054
|
-
continue;
|
|
2055
|
-
}
|
|
2056
|
-
if (/^\s{0,3}(?:[-*_]\s*){3,}$/.test(line)) {
|
|
2057
|
-
out.push(style.grey("\u2500".repeat(Math.max(1, cols))));
|
|
2058
|
-
continue;
|
|
2059
|
-
}
|
|
2060
|
-
const bullet = line.match(/^(\s*)[-*+]\s+(.+)$/);
|
|
2061
|
-
if (bullet) {
|
|
2062
|
-
out.push(...wrap(`${bullet[1]}\u2022 ${inline(bullet[2])}`, cols));
|
|
2063
|
-
continue;
|
|
2064
|
-
}
|
|
2065
|
-
const quote = line.match(/^\s*>\s?(.*)$/);
|
|
2066
|
-
if (quote) {
|
|
2067
|
-
out.push(...wrap(style.grey(`\u2502 ${inline(quote[1])}`), cols));
|
|
2068
|
-
continue;
|
|
2069
|
-
}
|
|
2070
|
-
out.push(...wrap(inline(line), cols));
|
|
2067
|
+
let previousEnd = null;
|
|
2068
|
+
for (let i = 0; i < tokens.length; i += 1) {
|
|
2069
|
+
const token = tokens[i];
|
|
2070
|
+
if (token.nesting === -1) continue;
|
|
2071
|
+
const end = token.nesting === 1 ? closeOf(tokens, i) : i;
|
|
2072
|
+
const children = tokens.slice(i + 1, end);
|
|
2073
|
+
const lines = block(token, children, ctx);
|
|
2074
|
+
const last = lastLine([token, ...children]);
|
|
2075
|
+
i = end;
|
|
2076
|
+
if (lines === null) continue;
|
|
2077
|
+
const start = token.map?.[0] ?? null;
|
|
2078
|
+
if (previousEnd !== null && start !== null && start > previousEnd && out.length > 0) out.push("");
|
|
2079
|
+
previousEnd = last ?? previousEnd;
|
|
2080
|
+
out.push(...lines);
|
|
2071
2081
|
}
|
|
2072
2082
|
return out;
|
|
2073
2083
|
}
|
|
2074
|
-
function
|
|
2075
|
-
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
|
|
2079
|
-
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2084
|
+
function block(token, children, ctx) {
|
|
2085
|
+
switch (token.type) {
|
|
2086
|
+
case "paragraph_open":
|
|
2087
|
+
return wrap(inline(children[0]?.children ?? [], ctx.base, "\n"), ctx.room);
|
|
2088
|
+
case "heading_open": {
|
|
2089
|
+
const level = Number(token.tag.slice(1));
|
|
2090
|
+
const base = level <= 2 ? [style.bold, style.brand] : [style.bold];
|
|
2091
|
+
return wrap(inline(children[0]?.children ?? [], [...ctx.base, ...base], "\n"), ctx.room);
|
|
2092
|
+
}
|
|
2093
|
+
case "fence":
|
|
2094
|
+
case "code_block":
|
|
2095
|
+
return token.content.replace(/\n$/, "").split("\n").flatMap((line) => wrap(` ${line}`, ctx.room)).map(style.grey);
|
|
2096
|
+
case "hr":
|
|
2097
|
+
return [style.grey("\u2500".repeat(ctx.room))];
|
|
2098
|
+
case "blockquote_open": {
|
|
2099
|
+
const inner = blocks(children, { room: Math.max(1, ctx.room - 2), base: [...ctx.base, style.grey] });
|
|
2100
|
+
return inner.map((line) => `${style.grey("\u2502")} ${line}`);
|
|
2101
|
+
}
|
|
2102
|
+
case "bullet_list_open":
|
|
2103
|
+
return list(children, ctx, () => "\u2022");
|
|
2104
|
+
case "ordered_list_open": {
|
|
2105
|
+
const start = Number(token.attrs?.find(([name]) => name === "start")?.[1] ?? 1);
|
|
2106
|
+
let n = start - 1;
|
|
2107
|
+
return list(children, ctx, (item) => {
|
|
2108
|
+
n += 1;
|
|
2109
|
+
return `${item.info || n}${item.markup || "."}`;
|
|
2110
|
+
});
|
|
2111
|
+
}
|
|
2112
|
+
case "table_open":
|
|
2113
|
+
return table(children, ctx);
|
|
2114
|
+
default:
|
|
2115
|
+
return null;
|
|
2085
2116
|
}
|
|
2086
|
-
return { headers, rows, end };
|
|
2087
2117
|
}
|
|
2088
|
-
function
|
|
2089
|
-
const
|
|
2090
|
-
|
|
2118
|
+
function list(items, ctx, marker2) {
|
|
2119
|
+
const out = [];
|
|
2120
|
+
let previousEnd = null;
|
|
2121
|
+
for (let i = 0; i < items.length; i += 1) {
|
|
2122
|
+
const item = items[i];
|
|
2123
|
+
if (item.type !== "list_item_open") continue;
|
|
2124
|
+
const end = closeOf(items, i);
|
|
2125
|
+
const mark = marker2(item);
|
|
2126
|
+
const hang = " ".repeat(width(mark) + 1);
|
|
2127
|
+
const content = items.slice(i + 1, end);
|
|
2128
|
+
const inner = blocks(content, { ...ctx, room: Math.max(1, ctx.room - hang.length) });
|
|
2129
|
+
i = end;
|
|
2130
|
+
const start = item.map?.[0] ?? null;
|
|
2131
|
+
if (previousEnd !== null && start !== null && start > previousEnd) out.push("");
|
|
2132
|
+
previousEnd = lastLine(content) ?? previousEnd;
|
|
2133
|
+
(inner.length > 0 ? inner : [""]).forEach((line, row) => out.push(row === 0 ? `${mark} ${line}` : line && `${hang}${line}`));
|
|
2134
|
+
}
|
|
2135
|
+
return out;
|
|
2091
2136
|
}
|
|
2092
|
-
function
|
|
2093
|
-
|
|
2137
|
+
function inline(tokens, base, lineBreak) {
|
|
2138
|
+
const active = [...base];
|
|
2139
|
+
const paint = (text) => text.split(" ").map((word) => word ? active.reduce((acc, apply) => apply(acc), word) : word).join(" ");
|
|
2140
|
+
let out = "";
|
|
2141
|
+
let href = null;
|
|
2142
|
+
let linkText = "";
|
|
2143
|
+
const emit = (text) => {
|
|
2144
|
+
out += paint(text);
|
|
2145
|
+
if (href !== null) linkText += text;
|
|
2146
|
+
};
|
|
2147
|
+
for (const token of tokens) {
|
|
2148
|
+
switch (token.type) {
|
|
2149
|
+
case "text":
|
|
2150
|
+
case "image":
|
|
2151
|
+
emit(token.content);
|
|
2152
|
+
break;
|
|
2153
|
+
case "code_inline":
|
|
2154
|
+
active.push(style.brand);
|
|
2155
|
+
emit(token.content);
|
|
2156
|
+
active.pop();
|
|
2157
|
+
break;
|
|
2158
|
+
case "softbreak":
|
|
2159
|
+
case "hardbreak":
|
|
2160
|
+
out += lineBreak;
|
|
2161
|
+
break;
|
|
2162
|
+
case "strong_open":
|
|
2163
|
+
active.push(style.bold);
|
|
2164
|
+
break;
|
|
2165
|
+
case "em_open":
|
|
2166
|
+
active.push(style.italic);
|
|
2167
|
+
break;
|
|
2168
|
+
case "s_open":
|
|
2169
|
+
active.push(style.dim);
|
|
2170
|
+
break;
|
|
2171
|
+
case "link_open":
|
|
2172
|
+
href = token.attrs?.find(([name]) => name === "href")?.[1] ?? null;
|
|
2173
|
+
linkText = "";
|
|
2174
|
+
if (href !== null) active.push(style.underline);
|
|
2175
|
+
break;
|
|
2176
|
+
case "link_close":
|
|
2177
|
+
if (href !== null) {
|
|
2178
|
+
active.pop();
|
|
2179
|
+
if (linkText !== href) out += paint(" ") + style.grey(`(${href})`);
|
|
2180
|
+
}
|
|
2181
|
+
href = null;
|
|
2182
|
+
break;
|
|
2183
|
+
case "strong_close":
|
|
2184
|
+
case "em_close":
|
|
2185
|
+
case "s_close":
|
|
2186
|
+
active.pop();
|
|
2187
|
+
break;
|
|
2188
|
+
default:
|
|
2189
|
+
if (token.content) emit(token.content);
|
|
2190
|
+
}
|
|
2191
|
+
}
|
|
2192
|
+
return out;
|
|
2193
|
+
}
|
|
2194
|
+
function table(tokens, ctx) {
|
|
2195
|
+
const headers = [];
|
|
2196
|
+
const rows = [];
|
|
2197
|
+
let inHead = false;
|
|
2198
|
+
let row = null;
|
|
2199
|
+
for (const token of tokens) {
|
|
2200
|
+
if (token.type === "thead_open") inHead = true;
|
|
2201
|
+
else if (token.type === "thead_close") inHead = false;
|
|
2202
|
+
else if (token.type === "tr_open") row = [];
|
|
2203
|
+
else if (token.type === "tr_close" && row) {
|
|
2204
|
+
if (inHead) headers.push(...row);
|
|
2205
|
+
else rows.push(row);
|
|
2206
|
+
row = null;
|
|
2207
|
+
} else if (token.type === "inline" && row) {
|
|
2208
|
+
row.push(inline(token.children ?? [], inHead ? [style.bold] : [], " "));
|
|
2209
|
+
}
|
|
2210
|
+
}
|
|
2211
|
+
return renderTable(headers, rows, ctx.room);
|
|
2094
2212
|
}
|
|
2095
2213
|
function renderTable(headers, rows, cols) {
|
|
2096
2214
|
const separator = " \u2502 ";
|
|
2097
2215
|
const separatorWidth = width(separator);
|
|
2098
2216
|
const available = Math.max(headers.length, cols - separatorWidth * (headers.length - 1));
|
|
2099
2217
|
const natural = headers.map(
|
|
2100
|
-
(header, column) => Math.max(width(
|
|
2218
|
+
(header, column) => Math.max(width(header), ...rows.map((row) => width(row[column] ?? "")))
|
|
2101
2219
|
);
|
|
2102
2220
|
const columnWidths = fitTableColumns(natural, available);
|
|
2103
|
-
if (columnWidths.some((size) => size < 4)) return
|
|
2104
|
-
const renderRow = (cells2
|
|
2105
|
-
const wrapped =
|
|
2221
|
+
if (columnWidths.some((size, index) => size < Math.min(4, natural[index]))) return renderRecords(headers, rows, cols);
|
|
2222
|
+
const renderRow = (cells2) => {
|
|
2223
|
+
const wrapped = headers.map((_, index) => wrap(cells2[index] ?? "", columnWidths[index]));
|
|
2106
2224
|
const height = Math.max(...wrapped.map((cell) => cell.length));
|
|
2107
2225
|
return Array.from(
|
|
2108
2226
|
{ length: height },
|
|
2109
|
-
(_, line) => wrapped.map((cell, column) => pad(
|
|
2227
|
+
(_, line) => wrapped.map((cell, column) => pad(cell[line] ?? "", columnWidths[column])).join(separator)
|
|
2110
2228
|
);
|
|
2111
2229
|
};
|
|
2112
2230
|
const rule = columnWidths.map((size) => style.grey("\u2500".repeat(size))).join(style.grey("\u2500\u253C\u2500"));
|
|
2113
|
-
return [
|
|
2114
|
-
...renderRow(headers, style.bold),
|
|
2115
|
-
rule,
|
|
2116
|
-
...rows.flatMap((row) => renderRow(row))
|
|
2117
|
-
];
|
|
2231
|
+
return [...renderRow(headers), rule, ...rows.flatMap(renderRow)];
|
|
2118
2232
|
}
|
|
2119
2233
|
function fitTableColumns(natural, available) {
|
|
2120
2234
|
const widths = [...natural];
|
|
@@ -2127,15 +2241,12 @@ function fitTableColumns(natural, available) {
|
|
|
2127
2241
|
}
|
|
2128
2242
|
return widths;
|
|
2129
2243
|
}
|
|
2130
|
-
function
|
|
2244
|
+
function renderRecords(headers, rows, cols) {
|
|
2131
2245
|
return rows.flatMap((row, rowIndex) => [
|
|
2132
|
-
...rowIndex === 0 ? [] : [""],
|
|
2133
|
-
...
|
|
2246
|
+
...rowIndex === 0 ? [] : [style.grey("\u2500".repeat(cols))],
|
|
2247
|
+
...headers.flatMap((header, column) => wrap(`${header}: ${row[column] ?? ""}`, cols))
|
|
2134
2248
|
]);
|
|
2135
2249
|
}
|
|
2136
|
-
function inline(text) {
|
|
2137
|
-
return text.replace(/!\[([^\]]*)\]\([^)]*\)/g, "$1").replace(/\[([^\]]+)\]\(([^\s)]+)(?:\s+[^)]*)?\)/g, "$1 ($2)").replace(/\*\*([^*]+)\*\*/g, (_, bold) => style.bold(bold)).replace(/__([^_]+)__/g, (_, bold) => style.bold(bold)).replace(/(^|[^\w])\*([^*]+)\*(?![\w*])/g, (_, prefix, italic) => `${prefix}${style.italic(italic)}`).replace(/(^|[^\w])_([^_]+)_(?![\w_])/g, (_, prefix, italic) => `${prefix}${style.italic(italic)}`).replace(/`([^`]+)`/g, (_, code) => style.brand(code));
|
|
2138
|
-
}
|
|
2139
2250
|
|
|
2140
2251
|
// src/tui/blocks.ts
|
|
2141
2252
|
function countOf(n, noun) {
|
|
@@ -2168,25 +2279,25 @@ var ROLE_CONTINUATION = {
|
|
|
2168
2279
|
error: style.red,
|
|
2169
2280
|
wake_up: style.yellow
|
|
2170
2281
|
};
|
|
2171
|
-
function messageLines(
|
|
2172
|
-
const text = sanitize(
|
|
2282
|
+
function messageLines(block2, cols) {
|
|
2283
|
+
const text = sanitize(block2.text);
|
|
2173
2284
|
const room = Math.max(1, cols - 2);
|
|
2174
|
-
const wrapped =
|
|
2175
|
-
const rest = ROLE_CONTINUATION[
|
|
2176
|
-
const rows = wrapped.map((line, i) => i === 0 ? ROLE_PREFIX[
|
|
2177
|
-
if (
|
|
2285
|
+
const wrapped = block2.role === "planner" || block2.role === "agent" || block2.role === "supervisor" ? renderMarkdown(text, room) : block2.skills ? skillPaintedLines(text, block2.skills, room) : wrap(text, room);
|
|
2286
|
+
const rest = ROLE_CONTINUATION[block2.role] ?? ((t) => t);
|
|
2287
|
+
const rows = wrapped.map((line, i) => i === 0 ? ROLE_PREFIX[block2.role](line) : rest(` ${line}`));
|
|
2288
|
+
if (block2.role === "user" && block2.forced) {
|
|
2178
2289
|
const note = style.grey(" \xB7 sent now");
|
|
2179
2290
|
if (width(rows[0]) + width(note) <= cols) rows[0] += note;
|
|
2180
2291
|
else rows.push(` ${note}`);
|
|
2181
2292
|
}
|
|
2182
|
-
return
|
|
2293
|
+
return block2.role === "user" ? onBand(rows, cols) : rows;
|
|
2183
2294
|
}
|
|
2184
2295
|
function onBand(rows, cols) {
|
|
2185
2296
|
const band = ["", ...rows, ""];
|
|
2186
2297
|
return style.enabled ? band.map((row) => style.band(pad(row, cols))) : band;
|
|
2187
2298
|
}
|
|
2188
2299
|
function skillPaintedLines(text, skills, room) {
|
|
2189
|
-
const tokens = (0,
|
|
2300
|
+
const tokens = (0, import_core13.loadedSkillTokens)(text, skills);
|
|
2190
2301
|
return wrapLines(text, room).map(({ line, start }) => {
|
|
2191
2302
|
let painted = "";
|
|
2192
2303
|
let at = 0;
|
|
@@ -2200,19 +2311,19 @@ function skillPaintedLines(text, skills, room) {
|
|
|
2200
2311
|
return painted + line.slice(at);
|
|
2201
2312
|
});
|
|
2202
2313
|
}
|
|
2203
|
-
function skillLoadLine(
|
|
2204
|
-
const head =
|
|
2205
|
-
const line = truncate(`${head}${truncatePath(sanitize(
|
|
2314
|
+
function skillLoadLine(block2, cols) {
|
|
2315
|
+
const head = block2.attaches ? `\u25CF /${sanitize(block2.name)} will be attached to fitting tasks \xB7 ` : block2.invokedBy === "planner" ? `\u25CF ${sanitize(block2.name)} skill loaded by planner \xB7 ` : `\u25CF /${sanitize(block2.name)} skill loaded \xB7 `;
|
|
2316
|
+
const line = truncate(`${head}${truncatePath(sanitize(block2.path), Math.max(1, cols - width(head)))}`, cols);
|
|
2206
2317
|
return `${style.green("\u25CF")}${style.grey(line.slice(1))}`;
|
|
2207
2318
|
}
|
|
2208
|
-
function thinkingLines(
|
|
2209
|
-
const text = sanitize(
|
|
2319
|
+
function thinkingLines(block2, cols, detailAll) {
|
|
2320
|
+
const text = sanitize(block2.text).trim();
|
|
2210
2321
|
const head = `\u2234 Thinking (${countOf(text ? text.split(/\s+/).length : 0, "word")})`;
|
|
2211
2322
|
if (detailAll) {
|
|
2212
2323
|
const body = text ? wrap(text, Math.max(1, cols - 2)).map((line) => style.grey(` ${line}`)) : [];
|
|
2213
2324
|
return [style.grey(truncate(head, cols)), ...body];
|
|
2214
2325
|
}
|
|
2215
|
-
const latest =
|
|
2326
|
+
const latest = block2.streaming ? (text.split("\n").at(-1) ?? "").trim() : "";
|
|
2216
2327
|
const room = cols - width(`${head} \xB7 `);
|
|
2217
2328
|
if (!latest || room < 2) return [style.grey(truncate(head, cols))];
|
|
2218
2329
|
const shown = width(latest) > room ? `\u2026${tailOf(latest, room - 1)}` : latest;
|
|
@@ -2224,21 +2335,21 @@ var PREVIEW_LINES = 3;
|
|
|
2224
2335
|
function underHeader(lines) {
|
|
2225
2336
|
return lines.map((line, i) => `${i === 0 ? style.grey(OUTPUT_HEAD) : OUTPUT_INDENT}${line}`);
|
|
2226
2337
|
}
|
|
2227
|
-
function unsettledOutcome(
|
|
2228
|
-
switch (
|
|
2338
|
+
function unsettledOutcome(block2) {
|
|
2339
|
+
switch (block2.status) {
|
|
2229
2340
|
case "error":
|
|
2230
2341
|
return { label: "Error", paint: style.red };
|
|
2231
2342
|
case "denied":
|
|
2232
|
-
return { label:
|
|
2343
|
+
return { label: block2.outcome === "refused" ? "Refused" : "Denied", paint: style.yellow };
|
|
2233
2344
|
case "interrupted":
|
|
2234
2345
|
return { label: "Interrupted", paint: style.grey };
|
|
2235
2346
|
default:
|
|
2236
2347
|
return null;
|
|
2237
2348
|
}
|
|
2238
2349
|
}
|
|
2239
|
-
function commandMark(
|
|
2240
|
-
if (
|
|
2241
|
-
return (unsettledOutcome(
|
|
2350
|
+
function commandMark(block2) {
|
|
2351
|
+
if (block2.status === "pending") return style.grey("\u25CB");
|
|
2352
|
+
return (unsettledOutcome(block2)?.paint ?? style.green)("\u25CF");
|
|
2242
2353
|
}
|
|
2243
2354
|
var PATH_LIKE = /^(?![a-z][a-z0-9+.-]*:\/\/)\S*\/\S*$/i;
|
|
2244
2355
|
function truncatePath(path, max) {
|
|
@@ -2251,17 +2362,17 @@ function truncatePath(path, max) {
|
|
|
2251
2362
|
const slash = tail.search(/[\\/]/);
|
|
2252
2363
|
return `\u2026${slash > 0 ? tail.slice(slash) : tail}`;
|
|
2253
2364
|
}
|
|
2254
|
-
function commandHeader(
|
|
2255
|
-
const name = sanitize(
|
|
2256
|
-
const keyArg = sanitize(
|
|
2365
|
+
function commandHeader(block2, cols, detailAll) {
|
|
2366
|
+
const name = sanitize(block2.headline.name);
|
|
2367
|
+
const keyArg = sanitize(block2.headline.keyArg);
|
|
2257
2368
|
if (detailAll) {
|
|
2258
|
-
return wrap(`${name}(${keyArg})`, Math.max(1, cols - 2)).map((line, i) => i === 0 ? `${commandMark(
|
|
2369
|
+
return wrap(`${name}(${keyArg})`, Math.max(1, cols - 2)).map((line, i) => i === 0 ? `${commandMark(block2)} ${line}` : ` ${line}`);
|
|
2259
2370
|
}
|
|
2260
2371
|
const open = `\u25CF ${name}(`;
|
|
2261
2372
|
const room = cols - width(open) - 1;
|
|
2262
2373
|
const cut = PATH_LIKE.test(keyArg) ? truncatePath(keyArg, room) : truncate(keyArg, room);
|
|
2263
2374
|
const text = room > 1 ? `${open}${cut})` : truncate(`${open}${keyArg})`, cols);
|
|
2264
|
-
return [`${commandMark(
|
|
2375
|
+
return [`${commandMark(block2)}${text.slice(1)}`];
|
|
2265
2376
|
}
|
|
2266
2377
|
function argumentLines(args) {
|
|
2267
2378
|
if (!args.trim()) return [];
|
|
@@ -2277,21 +2388,21 @@ function argumentLines(args) {
|
|
|
2277
2388
|
return [`${key}: ${first}`, ...rest];
|
|
2278
2389
|
});
|
|
2279
2390
|
}
|
|
2280
|
-
function resultLines(
|
|
2281
|
-
if (
|
|
2391
|
+
function resultLines(block2, room, detailAll) {
|
|
2392
|
+
if (block2.status === "pending") return [style.grey("Running\u2026")];
|
|
2282
2393
|
const fit2 = (line) => detailAll ? wrap(line, room) : [truncate(line, room)];
|
|
2283
|
-
const outcome = unsettledOutcome(
|
|
2394
|
+
const outcome = unsettledOutcome(block2);
|
|
2284
2395
|
if (outcome) {
|
|
2285
|
-
const [reason, ...rest] = (0,
|
|
2396
|
+
const [reason, ...rest] = (0, import_core13.outputLines)(block2.output).map(sanitize);
|
|
2286
2397
|
const status = fit2(reason ? `${outcome.label}: ${reason}` : outcome.label).map(outcome.paint);
|
|
2287
2398
|
return detailAll ? [...status, ...rest.flatMap(fit2).map(style.grey)] : status;
|
|
2288
2399
|
}
|
|
2289
2400
|
if (detailAll) {
|
|
2290
|
-
const lines2 = (0,
|
|
2401
|
+
const lines2 = (0, import_core13.outputLines)(block2.output).map(sanitize);
|
|
2291
2402
|
const note = lines2.length > PREVIEW_LINES ? ["\u2026 (ctrl+o to collapse)"] : [];
|
|
2292
2403
|
return lines2.length > 0 ? [...lines2.flatMap(fit2), ...note].map(style.grey) : [style.grey("(no output)")];
|
|
2293
2404
|
}
|
|
2294
|
-
const { lines, hiddenLineCount } = (0,
|
|
2405
|
+
const { lines, hiddenLineCount } = (0, import_core13.outputPreview)(block2.output, PREVIEW_LINES);
|
|
2295
2406
|
if (lines.length === 0) return [style.grey("(no output)")];
|
|
2296
2407
|
const more = hiddenLineCount > 0 ? [`\u2026 +${countOf(hiddenLineCount, "line")} (ctrl+o to expand)`] : [];
|
|
2297
2408
|
return [...lines.map(sanitize), ...more].map((line) => style.grey(truncate(line, room)));
|
|
@@ -2304,8 +2415,8 @@ var DIFF_PAINT = {
|
|
|
2304
2415
|
gap: style.grey
|
|
2305
2416
|
};
|
|
2306
2417
|
var DIFF_SIGN = { added: "+", removed: "-", context: " ", gap: "" };
|
|
2307
|
-
function diffLines(
|
|
2308
|
-
const rows = (0,
|
|
2418
|
+
function diffLines(block2, diff, room, detailAll) {
|
|
2419
|
+
const rows = (0, import_core13.diffRows)(block2.output);
|
|
2309
2420
|
const gutter = Math.max(0, ...rows.map((row) => String(row.line ?? "").length));
|
|
2310
2421
|
const draw = (row) => {
|
|
2311
2422
|
const text = row.kind === "gap" ? `${" ".repeat(gutter)} \u22EE` : `${String(row.line ?? "").padStart(gutter)} ${DIFF_SIGN[row.kind]} ${sanitize(row.text)}`;
|
|
@@ -2314,14 +2425,14 @@ function diffLines(block, diff, room, detailAll) {
|
|
|
2314
2425
|
const shown = detailAll ? rows : rows.slice(0, DIFF_PREVIEW_ROWS);
|
|
2315
2426
|
const hidden = rows.length - shown.length;
|
|
2316
2427
|
const more = hidden > 0 ? [style.grey(`\u2026 +${countOf(hidden, "line")} (ctrl+o to expand)`)] : [];
|
|
2317
|
-
return [(0,
|
|
2428
|
+
return [(0, import_core13.diffSummary)(diff), ...shown.flatMap(draw), ...more];
|
|
2318
2429
|
}
|
|
2319
|
-
function toolLines(
|
|
2430
|
+
function toolLines(block2, cols, detailAll) {
|
|
2320
2431
|
const room = Math.max(1, cols - OUTPUT_INDENT.length);
|
|
2321
|
-
const diff =
|
|
2322
|
-
const args = detailAll && !diff ? argumentLines(
|
|
2323
|
-
const result = diff ? diffLines(
|
|
2324
|
-
return [...commandHeader(
|
|
2432
|
+
const diff = block2.diff && block2.status === "ok" ? block2.diff : null;
|
|
2433
|
+
const args = detailAll && !diff ? argumentLines(block2.args).flatMap((line) => wrap(line, room)).map((line) => OUTPUT_INDENT + style.grey(line)) : [];
|
|
2434
|
+
const result = diff ? diffLines(block2, diff, room, detailAll) : resultLines(block2, room, detailAll);
|
|
2435
|
+
return [...commandHeader(block2, cols, detailAll), ...args, ...underHeader(result)];
|
|
2325
2436
|
}
|
|
2326
2437
|
var SUBAGENT_PAINT = {
|
|
2327
2438
|
running: style.yellow,
|
|
@@ -2330,24 +2441,24 @@ var SUBAGENT_PAINT = {
|
|
|
2330
2441
|
stopped: style.grey
|
|
2331
2442
|
};
|
|
2332
2443
|
var CHILD_INDENT = " ";
|
|
2333
|
-
function subagentHeader(
|
|
2334
|
-
const brief = firstLine(
|
|
2335
|
-
const steps =
|
|
2336
|
-
const status =
|
|
2444
|
+
function subagentHeader(block2, cols) {
|
|
2445
|
+
const brief = firstLine(block2.brief);
|
|
2446
|
+
const steps = block2.children.filter((c) => c.type === "tool").length;
|
|
2447
|
+
const status = block2.status === "running" && steps > 0 ? `running \xB7 ${countOf(steps, "step")}` : block2.status;
|
|
2337
2448
|
const head = brief ? " Agent: " : " Agent";
|
|
2338
2449
|
const briefRoom = cols - width(`\u25C6${head} ${status}`);
|
|
2339
2450
|
if (briefRoom < 4) return truncate(`\u25C6${head}${brief} ${status}`, cols);
|
|
2340
|
-
const named = `${style.brand("\u25C6")}${head}${truncate(brief, briefRoom)} ${SUBAGENT_PAINT[
|
|
2341
|
-
const digest = firstLine(
|
|
2451
|
+
const named = `${style.brand("\u25C6")}${head}${truncate(brief, briefRoom)} ${SUBAGENT_PAINT[block2.status](status)}`;
|
|
2452
|
+
const digest = firstLine(block2.digest);
|
|
2342
2453
|
const digestRoom = cols - width(named) - width(" \xB7 ");
|
|
2343
2454
|
return digest && digestRoom >= 4 ? `${named}${style.grey(` \xB7 ${truncate(digest, digestRoom)}`)}` : named;
|
|
2344
2455
|
}
|
|
2345
|
-
function subagentLines(
|
|
2346
|
-
const header = subagentHeader(
|
|
2456
|
+
function subagentLines(block2, cols, detailAll) {
|
|
2457
|
+
const header = subagentHeader(block2, cols);
|
|
2347
2458
|
if (!detailAll) return [header];
|
|
2348
2459
|
const childCols = Math.max(1, cols - CHILD_INDENT.length);
|
|
2349
|
-
const children =
|
|
2350
|
-
const digest = sanitize(
|
|
2460
|
+
const children = block2.children.flatMap((child) => blockLines(child, childCols, true).map((line) => CHILD_INDENT + line));
|
|
2461
|
+
const digest = sanitize(block2.digest).trim();
|
|
2351
2462
|
const handedBack = digest ? underHeader(wrap(digest, Math.max(1, cols - OUTPUT_INDENT.length)).map(style.grey)) : [];
|
|
2352
2463
|
return [header, ...children, ...handedBack];
|
|
2353
2464
|
}
|
|
@@ -2372,15 +2483,15 @@ var DECIDED_BY = {
|
|
|
2372
2483
|
budget: "web-read budget",
|
|
2373
2484
|
unsupported: "not usable on this runner version"
|
|
2374
2485
|
};
|
|
2375
|
-
function approvalLine(
|
|
2376
|
-
const policy =
|
|
2377
|
-
const [mark, status, paint] =
|
|
2378
|
-
const note =
|
|
2379
|
-
const line = `${mark} ${status} \xB7 ${APPROVAL_KIND[
|
|
2486
|
+
function approvalLine(block2, cols) {
|
|
2487
|
+
const policy = block2.decidedBy && block2.decidedBy !== "asked" ? DECIDED_BY[block2.decidedBy] : void 0;
|
|
2488
|
+
const [mark, status, paint] = block2.status === "pending" ? ["?", "Waiting for you", style.yellow] : block2.status === "granted" ? ["\u2713", policy ? `Auto-approved (${policy})` : block2.forTask ? "Approved for this task" : "Approved", style.green] : block2.status === "withdrawn" ? ["\xB7", "Withdrawn", style.grey] : ["\u2298", policy ? `Auto-denied (${policy})` : "Denied", style.yellow];
|
|
2489
|
+
const note = block2.note ? ` \u2014 \u201C${firstLine(block2.note)}\u201D` : "";
|
|
2490
|
+
const line = `${mark} ${status} \xB7 ${APPROVAL_KIND[block2.kind]}: ${firstLine(block2.subject)}${note}`;
|
|
2380
2491
|
return `${paint(mark)}${truncate(line, cols).slice(mark.length)}`;
|
|
2381
2492
|
}
|
|
2382
|
-
function approvalKeysLine(
|
|
2383
|
-
const keys = ["ctrl-y allow", ...
|
|
2493
|
+
function approvalKeysLine(block2, cols) {
|
|
2494
|
+
const keys = ["ctrl-y allow", ...block2.allowForTask ? ["ctrl-t allow for task"] : [], "ctrl-g deny (composer text is the note)"];
|
|
2384
2495
|
return style.grey(truncate(` ${keys.join(" \xB7 ")}`, cols));
|
|
2385
2496
|
}
|
|
2386
2497
|
function checkpointCardLines(order, question, cols, approvalFirst) {
|
|
@@ -2413,22 +2524,22 @@ var COMMAND_PAINT = {
|
|
|
2413
2524
|
failed: style.red,
|
|
2414
2525
|
stopped: style.grey
|
|
2415
2526
|
};
|
|
2416
|
-
function runnerCommandLines(
|
|
2417
|
-
const typed = sanitize(`/${
|
|
2418
|
-
const status = ` ${
|
|
2419
|
-
const head = `${style.accent("\u276F")} ${truncate(typed, Math.max(1, cols - 2 - width(status)))}${COMMAND_PAINT[
|
|
2527
|
+
function runnerCommandLines(block2, cols, detailAll) {
|
|
2528
|
+
const typed = sanitize(`/${block2.name}${block2.args ? ` ${block2.args}` : ""}`);
|
|
2529
|
+
const status = ` ${block2.status}`;
|
|
2530
|
+
const head = `${style.accent("\u276F")} ${truncate(typed, Math.max(1, cols - 2 - width(status)))}${COMMAND_PAINT[block2.status](status)}`;
|
|
2420
2531
|
const room = Math.max(1, cols - OUTPUT_INDENT.length);
|
|
2421
|
-
const printed = (0,
|
|
2532
|
+
const printed = (0, import_core13.outputLines)(block2.output).map(sanitize);
|
|
2422
2533
|
const shown = detailAll ? printed.flatMap((line) => wrap(line, room)) : printed.slice(0, PREVIEW_LINES).map((line) => truncate(line, room));
|
|
2423
2534
|
return [head, ...underHeader(shown.map(style.grey))];
|
|
2424
2535
|
}
|
|
2425
|
-
function compactionLine(
|
|
2426
|
-
const sizes =
|
|
2427
|
-
const text =
|
|
2536
|
+
function compactionLine(block2, cols) {
|
|
2537
|
+
const sizes = block2.preTokens !== void 0 && block2.postTokens !== void 0 ? ` \xB7 ${compactCount(block2.preTokens)} \u2192 ${compactCount(block2.postTokens)} tokens` : "";
|
|
2538
|
+
const text = block2.trigger === "auto" && !sizes ? "\u2261 Context compacted by the runner on its own" : `\u2261 Context compacted${sizes}`;
|
|
2428
2539
|
return style.grey(truncate(text, cols));
|
|
2429
2540
|
}
|
|
2430
|
-
function runnerLoadedLines(
|
|
2431
|
-
const of = (kind) =>
|
|
2541
|
+
function runnerLoadedLines(block2, cols, detailAll) {
|
|
2542
|
+
const of = (kind) => block2.commands.filter((c) => c.kind === kind).map((c) => `/${sanitize(c.name)}`);
|
|
2432
2543
|
const skills = of("skill");
|
|
2433
2544
|
const commands = of("command");
|
|
2434
2545
|
const builtins = of("builtin");
|
|
@@ -2436,66 +2547,66 @@ function runnerLoadedLines(block, cols, detailAll) {
|
|
|
2436
2547
|
countOf(skills.length, "skill"),
|
|
2437
2548
|
countOf(commands.length, "command"),
|
|
2438
2549
|
countOf(builtins.length, "built-in command"),
|
|
2439
|
-
countOf(
|
|
2550
|
+
countOf(block2.mcpServers.length, "MCP server")
|
|
2440
2551
|
];
|
|
2441
2552
|
const head = truncate(`\u25CF Runner loaded ${counts.join(", ")}`, cols);
|
|
2442
2553
|
const lines = [`${style.green("\u25CF")}${style.grey(head.slice(1))}`];
|
|
2443
2554
|
if (!detailAll) return lines;
|
|
2444
2555
|
const room = Math.max(1, cols - OUTPUT_INDENT.length);
|
|
2445
|
-
const
|
|
2446
|
-
const servers =
|
|
2556
|
+
const list2 = (label, names) => names.length > 0 ? wrap(`${label}: ${names.join(" ")}`, room) : [];
|
|
2557
|
+
const servers = block2.mcpServers.map((m) => `${sanitize(m.name)}${m.status ? ` (${sanitize(m.status)})` : ""}`);
|
|
2447
2558
|
return [
|
|
2448
2559
|
...lines,
|
|
2449
|
-
...[...
|
|
2560
|
+
...[...list2("skills", skills), ...list2("commands", commands), ...list2("built-in", builtins), ...servers.length > 0 ? wrap(`MCP servers: ${servers.join(", ")}`, room) : []].map((line) => OUTPUT_INDENT + style.grey(line))
|
|
2450
2561
|
];
|
|
2451
2562
|
}
|
|
2452
|
-
function planLine(
|
|
2453
|
-
const count =
|
|
2454
|
-
const text =
|
|
2563
|
+
function planLine(block2, cols) {
|
|
2564
|
+
const count = block2.taskCount === void 0 ? "" : ` (${countOf(block2.taskCount, "task")})`;
|
|
2565
|
+
const text = block2.status === "building" ? "Building plan\u2026" : `Plan ${block2.status}${count}`;
|
|
2455
2566
|
return `${style.brand("\u25C7")}${truncate(`\u25C7 ${text}`, cols).slice(1)}`;
|
|
2456
2567
|
}
|
|
2457
|
-
function blockLines(
|
|
2458
|
-
switch (
|
|
2568
|
+
function blockLines(block2, cols, detailAll) {
|
|
2569
|
+
switch (block2.type) {
|
|
2459
2570
|
case "message":
|
|
2460
|
-
return messageLines(
|
|
2571
|
+
return messageLines(block2, cols);
|
|
2461
2572
|
case "thinking":
|
|
2462
|
-
return thinkingLines(
|
|
2573
|
+
return thinkingLines(block2, cols, detailAll);
|
|
2463
2574
|
case "tool":
|
|
2464
|
-
return toolLines(
|
|
2575
|
+
return toolLines(block2, cols, detailAll);
|
|
2465
2576
|
case "subagent":
|
|
2466
|
-
return subagentLines(
|
|
2577
|
+
return subagentLines(block2, cols, detailAll);
|
|
2467
2578
|
case "approval":
|
|
2468
|
-
return [approvalLine(
|
|
2579
|
+
return [approvalLine(block2, cols)];
|
|
2469
2580
|
case "plan":
|
|
2470
|
-
return [planLine(
|
|
2581
|
+
return [planLine(block2, cols)];
|
|
2471
2582
|
case "skill_load":
|
|
2472
|
-
return [skillLoadLine(
|
|
2583
|
+
return [skillLoadLine(block2, cols)];
|
|
2473
2584
|
case "command":
|
|
2474
|
-
return runnerCommandLines(
|
|
2585
|
+
return runnerCommandLines(block2, cols, detailAll);
|
|
2475
2586
|
case "compaction":
|
|
2476
|
-
return [compactionLine(
|
|
2587
|
+
return [compactionLine(block2, cols)];
|
|
2477
2588
|
case "runner_loaded":
|
|
2478
|
-
return runnerLoadedLines(
|
|
2589
|
+
return runnerLoadedLines(block2, cols, detailAll);
|
|
2479
2590
|
// Pinned under the pane rather than drawn in it — see `tokenLine`.
|
|
2480
2591
|
case "usage":
|
|
2481
2592
|
return [];
|
|
2482
2593
|
}
|
|
2483
2594
|
}
|
|
2484
2595
|
var drawnBlocks = /* @__PURE__ */ new WeakMap();
|
|
2485
|
-
function drawn(
|
|
2486
|
-
const cached = drawnBlocks.get(
|
|
2596
|
+
function drawn(block2, cols, detailAll) {
|
|
2597
|
+
const cached = drawnBlocks.get(block2);
|
|
2487
2598
|
if (cached && cached.cols === cols && cached.detailAll === detailAll) return cached.lines;
|
|
2488
|
-
const lines = blockLines(
|
|
2489
|
-
drawnBlocks.set(
|
|
2599
|
+
const lines = blockLines(block2, cols, detailAll);
|
|
2600
|
+
drawnBlocks.set(block2, { cols, detailAll, lines });
|
|
2490
2601
|
return lines;
|
|
2491
2602
|
}
|
|
2492
|
-
function conversationLines(
|
|
2603
|
+
function conversationLines(blocks2, cols, detailAll, answering) {
|
|
2493
2604
|
const lines = [];
|
|
2494
|
-
for (const [i,
|
|
2495
|
-
if (
|
|
2496
|
-
lines.push(...drawn(
|
|
2497
|
-
if (
|
|
2498
|
-
if (
|
|
2605
|
+
for (const [i, block2] of blocks2.entries()) {
|
|
2606
|
+
if (block2.type === "usage") continue;
|
|
2607
|
+
lines.push(...drawn(block2, cols, detailAll));
|
|
2608
|
+
if (block2 === answering) lines.push(approvalKeysLine(block2, cols));
|
|
2609
|
+
if (blocks2[i + 1]?.type !== "skill_load") lines.push("");
|
|
2499
2610
|
}
|
|
2500
2611
|
return lines;
|
|
2501
2612
|
}
|
|
@@ -2509,8 +2620,8 @@ function formatCost(currency, amount) {
|
|
|
2509
2620
|
const value = `${whole}.${frac.padEnd(2, "0")}`;
|
|
2510
2621
|
return currency.toLowerCase() === "usd" ? `$${value}` : `${value} ${currency.toUpperCase()}`;
|
|
2511
2622
|
}
|
|
2512
|
-
function tokenLine(
|
|
2513
|
-
const usage =
|
|
2623
|
+
function tokenLine(blocks2, cols) {
|
|
2624
|
+
const usage = blocks2[blocks2.length - 1];
|
|
2514
2625
|
if (usage?.type !== "usage") return null;
|
|
2515
2626
|
const parts = usageMeasures(usage.totals, false);
|
|
2516
2627
|
if (usage.model && !usage.contextFill) parts.push("ctx unknown");
|
|
@@ -2536,7 +2647,7 @@ function taskUsageText(usage) {
|
|
|
2536
2647
|
|
|
2537
2648
|
// src/commands/status.ts
|
|
2538
2649
|
var import_fs4 = require("fs");
|
|
2539
|
-
var
|
|
2650
|
+
var import_core14 = require("@ordewell/core");
|
|
2540
2651
|
async function handleStatus(subArgs, injectedApi) {
|
|
2541
2652
|
const sessionId = flag(subArgs, "--session-id");
|
|
2542
2653
|
const workspace = flag(subArgs, "--workspace") || process.cwd();
|
|
@@ -2591,8 +2702,8 @@ function emitJson(payload, outputPath) {
|
|
|
2591
2702
|
}
|
|
2592
2703
|
function printOneSession(sessionId, meta, plan) {
|
|
2593
2704
|
const allTasks = allTasksOf(plan);
|
|
2594
|
-
const everyTask = (0,
|
|
2595
|
-
const blocked = (0,
|
|
2705
|
+
const everyTask = (0, import_core14.flattenTasks)(allTasks);
|
|
2706
|
+
const blocked = (0, import_core14.blockingFailures)(everyTask.map((t) => ({ ...t, subtasks: [], dependencies: t.dependencies ?? [] })));
|
|
2596
2707
|
const count = (status) => everyTask.filter((t) => t.status === status || status === "blocked" && blocked.has(t.id)).length;
|
|
2597
2708
|
console.log(`Session: ${sessionId}`);
|
|
2598
2709
|
console.log(`Goal: ${meta.goal}`);
|
|
@@ -2600,25 +2711,25 @@ function printOneSession(sessionId, meta, plan) {
|
|
|
2600
2711
|
console.log(`Phase: ${plan?.phase || "unknown"} | Created: ${meta.createdAt}`);
|
|
2601
2712
|
console.log(`Tasks: ${everyTask.length} total | ${count("completed")} done | ${count("failed")} failed | ${count("in_progress")} running | ${count("blocked")} blocked | ${count("skipped")} skipped
|
|
2602
2713
|
`);
|
|
2603
|
-
const usage = (0,
|
|
2714
|
+
const usage = (0, import_core14.planUsage)(allTasks);
|
|
2604
2715
|
if (usage.attempts) console.log(`Tasks total: ${taskUsageText(usage)}`);
|
|
2605
2716
|
for (const t of allTasks) {
|
|
2606
2717
|
const icon = iconFor(blocked.has(t.id) ? "blocked" : t.status);
|
|
2607
2718
|
const model = t.assignedModel ? ` (${t.assignedModel.modelLabel})` : "";
|
|
2608
2719
|
const shortId = (t.id ?? "").slice(-8);
|
|
2609
|
-
console.log(` ${(0,
|
|
2610
|
-
const row = (0,
|
|
2611
|
-
if (row.blockedBy) console.log(` ${(0,
|
|
2612
|
-
if (row.status === "skipped") console.log(` ${(0,
|
|
2720
|
+
console.log(` ${(0, import_core14.taskOrderLabel)(t).padStart(2)}. ${icon} [${shortId}] ${t.title}${model}`);
|
|
2721
|
+
const row = (0, import_core14.taskRowView)({ ...t, dependencies: t.dependencies ?? [] }, { tasks: allTasks });
|
|
2722
|
+
if (row.blockedBy) console.log(` ${(0, import_core14.blockedByLabel)(row.blockedBy)}`);
|
|
2723
|
+
if (row.status === "skipped") console.log(` ${(0, import_core14.skippedLabel)(row.skipReason)}`);
|
|
2613
2724
|
if (row.usage) console.log(` ${taskUsageText(row.usage)}`);
|
|
2614
2725
|
for (const sub of t.subtasks || []) {
|
|
2615
2726
|
const subIcon = iconFor(blocked.has(sub.id) ? "blocked" : sub.status);
|
|
2616
2727
|
const subModel = sub.assignedModel ? ` (${sub.assignedModel.modelLabel})` : "";
|
|
2617
2728
|
const subShortId = (sub.id ?? "").slice(-8);
|
|
2618
|
-
console.log(` ${(0,
|
|
2619
|
-
const subRow = (0,
|
|
2620
|
-
if (subRow.blockedBy) console.log(` ${(0,
|
|
2621
|
-
if (subRow.status === "skipped") console.log(` ${(0,
|
|
2729
|
+
console.log(` ${(0, import_core14.taskOrderLabel)(sub, t)}. ${subIcon} [${subShortId}] ${sub.title}${subModel}`);
|
|
2730
|
+
const subRow = (0, import_core14.taskRowView)({ ...sub, dependencies: sub.dependencies ?? [] }, { parent: t, tasks: allTasks });
|
|
2731
|
+
if (subRow.blockedBy) console.log(` ${(0, import_core14.blockedByLabel)(subRow.blockedBy)}`);
|
|
2732
|
+
if (subRow.status === "skipped") console.log(` ${(0, import_core14.skippedLabel)(subRow.skipReason)}`);
|
|
2622
2733
|
if (subRow.usage) console.log(` ${taskUsageText(subRow.usage)}`);
|
|
2623
2734
|
}
|
|
2624
2735
|
}
|
|
@@ -2671,10 +2782,10 @@ async function handleWeb(subArgs) {
|
|
|
2671
2782
|
}
|
|
2672
2783
|
|
|
2673
2784
|
// src/commands/models.ts
|
|
2674
|
-
var
|
|
2785
|
+
var import_core16 = require("@ordewell/core");
|
|
2675
2786
|
|
|
2676
2787
|
// src/commands/model.ts
|
|
2677
|
-
var
|
|
2788
|
+
var import_core15 = require("@ordewell/core");
|
|
2678
2789
|
var USAGE = "Usage: ordewell model [show | set <model-id>]";
|
|
2679
2790
|
async function handleModel(subArgs, injectedApi) {
|
|
2680
2791
|
const [action, modelId] = positionals(subArgs);
|
|
@@ -2689,7 +2800,7 @@ async function handleModel(subArgs, injectedApi) {
|
|
|
2689
2800
|
if (!modelId) fail(USAGE);
|
|
2690
2801
|
const settings = await api.getSettings();
|
|
2691
2802
|
const provider = typeof settings.aiProvider === "string" ? settings.aiProvider : "";
|
|
2692
|
-
const runner = (0,
|
|
2803
|
+
const runner = (0, import_core15.runnerForProvider)(provider);
|
|
2693
2804
|
if (runner) {
|
|
2694
2805
|
const known = (await fetchCatalog(api)).models.filter((m) => m.runners?.includes(runner));
|
|
2695
2806
|
if (known.length > 0 && !known.some((m) => m.id === modelId)) {
|
|
@@ -2712,7 +2823,7 @@ async function showModels(api) {
|
|
|
2712
2823
|
const [settings, catalog] = await Promise.all([api.getSettings(), fetchCatalog(api)]);
|
|
2713
2824
|
const provider = typeof settings.aiProvider === "string" ? settings.aiProvider : "";
|
|
2714
2825
|
const current = typeof settings.orchestratorModel === "string" ? settings.orchestratorModel : "";
|
|
2715
|
-
const runner = (0,
|
|
2826
|
+
const runner = (0, import_core15.runnerForProvider)(provider);
|
|
2716
2827
|
const options = runner ? catalog.models.filter((m) => m.runners?.includes(runner)) : catalog.orchestratorModels;
|
|
2717
2828
|
console.log(`
|
|
2718
2829
|
Planner model: ${current || "(backend default)"}`);
|
|
@@ -2746,8 +2857,8 @@ async function handleModels(subArgs) {
|
|
|
2746
2857
|
const rest = subArgs.filter((_, i) => i !== setIdx && i !== setIdx + 1);
|
|
2747
2858
|
return handleModel(["set", subArgs[setIdx + 1], ...rest]);
|
|
2748
2859
|
}
|
|
2749
|
-
const config = new
|
|
2750
|
-
const providers = (0,
|
|
2860
|
+
const config = new import_core16.EnvConfig();
|
|
2861
|
+
const providers = (0, import_core16.configuredProviders)(config);
|
|
2751
2862
|
if (providers.length === 0) {
|
|
2752
2863
|
console.error("No providers configured. Set an API key for a provider, e.g.:");
|
|
2753
2864
|
console.error(" OPENROUTER_API_KEY=... (OpenRouter)");
|
|
@@ -2756,19 +2867,19 @@ async function handleModels(subArgs) {
|
|
|
2756
2867
|
console.error(" OPENAI_COMPATIBLE_BASE_URL=... (self-hosted / OpenAI-compatible)");
|
|
2757
2868
|
process.exit(1);
|
|
2758
2869
|
}
|
|
2759
|
-
const { apiKeys, baseUrls } = (0,
|
|
2870
|
+
const { apiKeys, baseUrls } = (0, import_core16.collectProviderCredentials)(config);
|
|
2760
2871
|
let models;
|
|
2761
2872
|
let errors;
|
|
2762
2873
|
try {
|
|
2763
|
-
const result = await (0,
|
|
2764
|
-
models = (0,
|
|
2874
|
+
const result = await (0, import_core16.fetchAllProviderModels)({ apiKeys, baseUrls });
|
|
2875
|
+
models = (0, import_core16.toOrchestratorOptions)(result.models, import_core16.ORCHESTRATOR_SHORTCUTS);
|
|
2765
2876
|
errors = result.errors;
|
|
2766
2877
|
} catch (err) {
|
|
2767
2878
|
console.error(`Failed to fetch models: ${err instanceof Error ? err.message : String(err)}`);
|
|
2768
2879
|
process.exit(1);
|
|
2769
2880
|
return;
|
|
2770
2881
|
}
|
|
2771
|
-
const providerLabel = (p) => (0,
|
|
2882
|
+
const providerLabel = (p) => (0, import_core16.getProviderMeta)(p)?.label ?? p;
|
|
2772
2883
|
console.log(
|
|
2773
2884
|
`
|
|
2774
2885
|
Available models (${models.length}) across ${providers.length} configured provider(s):`
|
|
@@ -2808,7 +2919,7 @@ ${providerLabel(provider)}`);
|
|
|
2808
2919
|
|
|
2809
2920
|
// src/commands/setup.ts
|
|
2810
2921
|
var import_fs6 = require("fs");
|
|
2811
|
-
var
|
|
2922
|
+
var import_core17 = require("@ordewell/core");
|
|
2812
2923
|
function handleSetup(subArgs) {
|
|
2813
2924
|
const modelIdx = subArgs.indexOf("--model");
|
|
2814
2925
|
const chosenModel = modelIdx !== -1 ? subArgs[modelIdx + 1] : null;
|
|
@@ -2853,7 +2964,7 @@ function handleSetup(subArgs) {
|
|
|
2853
2964
|
|
|
2854
2965
|
# Or plan with a coding agent you already have installed \u2014 no API key needed,
|
|
2855
2966
|
# it uses that agent's own subscription. Set the model to one of its own.
|
|
2856
|
-
# AI_PROVIDER
|
|
2967
|
+
# AI_PROVIDER=${runnerIdChoice()}
|
|
2857
2968
|
# ORCHESTRATOR_MODEL=haiku
|
|
2858
2969
|
# ORDEWELL_PLANNER_EFFORT=low
|
|
2859
2970
|
|
|
@@ -2880,13 +2991,13 @@ function handleSetup(subArgs) {
|
|
|
2880
2991
|
# STEPFUN_API_KEY=...
|
|
2881
2992
|
# SILICONFLOW_API_KEY=...
|
|
2882
2993
|
`;
|
|
2883
|
-
(0,
|
|
2994
|
+
(0, import_core17.writePrivateFile)(envFile, content);
|
|
2884
2995
|
console.log(`Wrote: ${envFile}`);
|
|
2885
2996
|
console.log("Review and edit the file, then run: ordewell tui");
|
|
2886
2997
|
}
|
|
2887
2998
|
|
|
2888
2999
|
// src/commands/skills.ts
|
|
2889
|
-
var
|
|
3000
|
+
var import_core18 = require("@ordewell/core");
|
|
2890
3001
|
var import_path5 = require("path");
|
|
2891
3002
|
function invocation(skill) {
|
|
2892
3003
|
if (skill.userInvocable && skill.modelInvocable) return "both";
|
|
@@ -2899,22 +3010,22 @@ function handleSkills(subArgs) {
|
|
|
2899
3010
|
fail("Usage: ordewell skills [--workspace /path] [--json]");
|
|
2900
3011
|
}
|
|
2901
3012
|
const workspace = (0, import_path5.resolve)(flag(subArgs, "--workspace") || process.cwd());
|
|
2902
|
-
const catalog = (0,
|
|
3013
|
+
const catalog = (0, import_core18.createSkillsService)(workspace, new import_core18.EnvConfig().workspaceRepos).readCatalog();
|
|
2903
3014
|
const skills = catalog.skills.map((skill) => ({
|
|
2904
3015
|
name: skill.name,
|
|
2905
3016
|
scope: skill.source,
|
|
2906
3017
|
appliesTo: skill.appliesTo,
|
|
2907
3018
|
invocation: invocation(skill),
|
|
2908
|
-
path: (0,
|
|
3019
|
+
path: (0, import_core18.abbreviateHome)(skill.path)
|
|
2909
3020
|
}));
|
|
2910
3021
|
const shadowed = catalog.shadowed.map(({ skill, shadowedBy }) => ({
|
|
2911
3022
|
name: skill.name,
|
|
2912
|
-
path: (0,
|
|
2913
|
-
shadowedBy: { scope: shadowedBy.source, path: (0,
|
|
3023
|
+
path: (0, import_core18.abbreviateHome)(skill.path),
|
|
3024
|
+
shadowedBy: { scope: shadowedBy.source, path: (0, import_core18.abbreviateHome)(shadowedBy.path) }
|
|
2914
3025
|
}));
|
|
2915
3026
|
const invalid = catalog.invalid.map((skill) => ({
|
|
2916
3027
|
name: skill.name,
|
|
2917
|
-
path: (0,
|
|
3028
|
+
path: (0, import_core18.abbreviateHome)(skill.path),
|
|
2918
3029
|
reason: skill.reason
|
|
2919
3030
|
}));
|
|
2920
3031
|
if (hasFlag(subArgs, "--json")) {
|
|
@@ -3029,7 +3140,7 @@ async function handleShow(args, api) {
|
|
|
3029
3140
|
}
|
|
3030
3141
|
|
|
3031
3142
|
// src/commands/task-control.ts
|
|
3032
|
-
var
|
|
3143
|
+
var import_core19 = require("@ordewell/core");
|
|
3033
3144
|
var PAST_TENSE = {
|
|
3034
3145
|
run: "Task started.",
|
|
3035
3146
|
"force-start": "Task force-started.",
|
|
@@ -3072,7 +3183,7 @@ async function confirmPastGate(subArgs, api, sessionId, taskId, confirm2) {
|
|
|
3072
3183
|
if (hasFlag(subArgs, "--yes")) return;
|
|
3073
3184
|
const unmerged = await api.getMergeGate(sessionId, taskId).catch(() => []);
|
|
3074
3185
|
if (unmerged.length === 0) return;
|
|
3075
|
-
const question = `${(0,
|
|
3186
|
+
const question = `${(0, import_core19.pastGateConfirmation)(unmerged.map((d) => (0, import_core19.titledTaskRef)(d)))} Start it anyway?`;
|
|
3076
3187
|
if (!await confirm2(question)) fail("Not started \u2014 nothing was changed. Pass --yes to start it without a prompt.");
|
|
3077
3188
|
}
|
|
3078
3189
|
function makeHandler(action, command = action) {
|
|
@@ -3385,24 +3496,24 @@ async function handleRewind(subArgs, injectedApi) {
|
|
|
3385
3496
|
}
|
|
3386
3497
|
|
|
3387
3498
|
// src/tui/transcript.ts
|
|
3388
|
-
var
|
|
3499
|
+
var import_core20 = require("@ordewell/core");
|
|
3389
3500
|
function show(state, { view: conversation, gate: turnGate }) {
|
|
3390
3501
|
const gated = turnGate === state.turnGate ? state : { ...state, turnGate };
|
|
3391
3502
|
if (conversation === state.conversation) return gated;
|
|
3392
3503
|
return { ...gated, conversation };
|
|
3393
3504
|
}
|
|
3394
3505
|
function fold(state, input) {
|
|
3395
|
-
return show(state, { view: (0,
|
|
3506
|
+
return show(state, { view: (0, import_core20.reduceConversation)(state.conversation, input), gate: state.turnGate });
|
|
3396
3507
|
}
|
|
3397
3508
|
function say(state, role, text) {
|
|
3398
3509
|
const said = fold(state, { type: "local_entry", role, text });
|
|
3399
3510
|
return said.conversation.nextId > state.conversation.nextId ? { ...said, scroll: 0 } : said;
|
|
3400
3511
|
}
|
|
3401
3512
|
function hear(state, message) {
|
|
3402
|
-
return show(state, (0,
|
|
3513
|
+
return show(state, (0, import_core20.followTurn)(state.conversation, state.turnGate, message));
|
|
3403
3514
|
}
|
|
3404
3515
|
function cutTurn(state) {
|
|
3405
|
-
return show(state, (0,
|
|
3516
|
+
return show(state, (0, import_core20.stopTurn)(state.conversation, state.turnGate));
|
|
3406
3517
|
}
|
|
3407
3518
|
function wiped(view) {
|
|
3408
3519
|
return { ...view, blocks: view.blocks.filter((b) => b.type === "usage") };
|
|
@@ -3651,7 +3762,7 @@ async function handleHandoff(subArgs, injectedApi, confirm2 = askYesNo) {
|
|
|
3651
3762
|
}
|
|
3652
3763
|
|
|
3653
3764
|
// src/commands/planner.ts
|
|
3654
|
-
var
|
|
3765
|
+
var import_core21 = require("@ordewell/core");
|
|
3655
3766
|
|
|
3656
3767
|
// src/plannerModelSwitch.ts
|
|
3657
3768
|
function plannerSwitchRecall(settings) {
|
|
@@ -3661,7 +3772,6 @@ function plannerSwitchRecall(settings) {
|
|
|
3661
3772
|
}
|
|
3662
3773
|
|
|
3663
3774
|
// src/commands/planner.ts
|
|
3664
|
-
var isAiProvider = (id) => Object.hasOwn(import_core19.ALL_PROVIDERS, id);
|
|
3665
3775
|
async function handlePlanner(subArgs, injectedApi) {
|
|
3666
3776
|
const api = await connect(subArgs, injectedApi);
|
|
3667
3777
|
const [wanted] = positionals(subArgs);
|
|
@@ -3670,19 +3780,19 @@ async function handlePlanner(subArgs, injectedApi) {
|
|
|
3670
3780
|
return;
|
|
3671
3781
|
}
|
|
3672
3782
|
const provider = wanted.toLowerCase();
|
|
3673
|
-
|
|
3783
|
+
const meta = (0, import_core21.getProviderMeta)(provider);
|
|
3784
|
+
if (!meta) {
|
|
3674
3785
|
fail(`Unknown planner: ${provider}`, "Run `ordewell planner` with no arguments to see the list.");
|
|
3675
3786
|
}
|
|
3676
3787
|
const settings = await persistEnv(api, { AI_PROVIDER: provider });
|
|
3677
3788
|
const recall2 = plannerSwitchRecall(settings);
|
|
3678
3789
|
writeEnv({ ORCHESTRATOR_MODEL: recall2.model, ORDEWELL_PLANNER_EFFORT: recall2.effort });
|
|
3679
|
-
const meta = import_core19.ALL_PROVIDERS[provider];
|
|
3680
3790
|
const catalog = await fetchCatalog(api);
|
|
3681
3791
|
console.log(
|
|
3682
|
-
(0,
|
|
3792
|
+
(0, import_core21.isCliProvider)(provider) ? `Planning with ${meta.label} \u2014 no API key needed, it uses that agent's own subscription.` : `Planner set to ${meta.label}.`
|
|
3683
3793
|
);
|
|
3684
3794
|
console.log(plannerModelLine(recall2));
|
|
3685
|
-
if (
|
|
3795
|
+
if ((0, import_core21.isApiProvider)(provider) && !catalog.providers.includes(provider)) {
|
|
3686
3796
|
console.log(` No ${meta.apiKeyEnvVar} configured yet \u2014 set one with \`ordewell key set ${provider} <key>\`.`);
|
|
3687
3797
|
}
|
|
3688
3798
|
}
|
|
@@ -3700,15 +3810,15 @@ async function showPlanners(api) {
|
|
|
3700
3810
|
const [settings, catalog] = await Promise.all([api.getSettings(), fetchCatalog(api)]);
|
|
3701
3811
|
const current = typeof settings.aiProvider === "string" ? settings.aiProvider : "";
|
|
3702
3812
|
console.log("\nCoding agents (no API key \u2014 they use their own subscription)");
|
|
3703
|
-
for (const id of
|
|
3704
|
-
const runner = (0,
|
|
3813
|
+
for (const id of import_core21.CLI_PROVIDERS) {
|
|
3814
|
+
const runner = (0, import_core21.runnerForProvider)(id);
|
|
3705
3815
|
const discovered = runner ? catalog.models.some((m) => m.runners?.includes(runner)) : false;
|
|
3706
|
-
console.log(` ${marker(id === current)} ${id.padEnd(14)} ${
|
|
3816
|
+
console.log(` ${marker(id === current)} ${id.padEnd(14)} ${(0, import_core21.getProviderMeta)(id)?.label ?? id}${discovered ? "" : " (not detected)"}`);
|
|
3707
3817
|
}
|
|
3708
3818
|
console.log("\nAPI providers");
|
|
3709
|
-
for (const id of
|
|
3819
|
+
for (const id of import_core21.PROVIDER_PRIORITY) {
|
|
3710
3820
|
const configured = catalog.providers.includes(id);
|
|
3711
|
-
const meta =
|
|
3821
|
+
const meta = (0, import_core21.getProviderMeta)(id);
|
|
3712
3822
|
console.log(` ${marker(id === current)} ${id.padEnd(14)} ${meta.label}${configured ? "" : ` (no ${meta.apiKeyEnvVar})`}`);
|
|
3713
3823
|
}
|
|
3714
3824
|
console.log(`
|
|
@@ -3725,11 +3835,11 @@ async function handlePlannerEffort(subArgs, injectedApi) {
|
|
|
3725
3835
|
const provider = typeof settings.aiProvider === "string" ? settings.aiProvider : "";
|
|
3726
3836
|
const modelId = typeof settings.orchestratorModel === "string" ? settings.orchestratorModel : "";
|
|
3727
3837
|
const currentEffort = typeof settings.plannerThinkingEffort === "string" ? settings.plannerThinkingEffort : "";
|
|
3728
|
-
const runner =
|
|
3838
|
+
const runner = (0, import_core21.runnerForProvider)(provider);
|
|
3729
3839
|
if (!runner) {
|
|
3730
3840
|
fail(
|
|
3731
3841
|
"Thinking effort applies to a coding-agent planner.",
|
|
3732
|
-
|
|
3842
|
+
`Switch with: ordewell planner ${runnerIdChoice()}`
|
|
3733
3843
|
);
|
|
3734
3844
|
}
|
|
3735
3845
|
const model = catalog.models.find((m) => m.id === modelId && m.runners?.includes(runner));
|
|
@@ -3765,7 +3875,7 @@ async function handlePlannerEffort(subArgs, injectedApi) {
|
|
|
3765
3875
|
}
|
|
3766
3876
|
|
|
3767
3877
|
// src/commands/parallel.ts
|
|
3768
|
-
var
|
|
3878
|
+
var import_core22 = require("@ordewell/core");
|
|
3769
3879
|
var USAGE5 = "Usage: ordewell parallel [<number of tasks, 1 or more>]";
|
|
3770
3880
|
async function handleParallel(subArgs, injectedApi) {
|
|
3771
3881
|
const [wanted] = positionals(subArgs);
|
|
@@ -3775,14 +3885,14 @@ async function handleParallel(subArgs, injectedApi) {
|
|
|
3775
3885
|
console.log(`Up to ${String(settings.maxParallel ?? "?")} AI tasks run at once. Change with: ordewell parallel <n>`);
|
|
3776
3886
|
return;
|
|
3777
3887
|
}
|
|
3778
|
-
const limit = (0,
|
|
3888
|
+
const limit = (0, import_core22.parseMaxParallel)(wanted);
|
|
3779
3889
|
if (limit === null) fail(`"${wanted}" is not a number of tasks (1 or more).`, USAGE5);
|
|
3780
3890
|
await persistEnv(api, { ORDEWELL_MAX_PARALLEL: String(limit) });
|
|
3781
3891
|
console.log(`Up to ${limit} AI task${limit === 1 ? "" : "s"} now run at once.`);
|
|
3782
3892
|
}
|
|
3783
3893
|
|
|
3784
3894
|
// src/commands/runSettings.ts
|
|
3785
|
-
var
|
|
3895
|
+
var import_core23 = require("@ordewell/core");
|
|
3786
3896
|
var SUPERVISOR_USAGE = "Usage: ordewell supervisor [off|watch|act] \xB7 ordewell supervisor retries <n> \xB7 ordewell supervisor reads <n>";
|
|
3787
3897
|
var AUTOMERGE_USAGE = "Usage: ordewell automerge [on|off]";
|
|
3788
3898
|
var AUTORUN_USAGE = "Usage: ordewell autorun [on|off]";
|
|
@@ -3793,28 +3903,28 @@ async function handleSupervisor(subArgs, injectedApi) {
|
|
|
3793
3903
|
const [arg, value] = positionals(subArgs);
|
|
3794
3904
|
let changes = null;
|
|
3795
3905
|
if (arg === "off" || arg === "watch" || arg === "act") changes = { supervisorLevel: arg };
|
|
3796
|
-
else if (arg === "retries") changes = maybe((0,
|
|
3797
|
-
else if (arg === "reads") changes = maybe((0,
|
|
3906
|
+
else if (arg === "retries") changes = maybe((0, import_core23.parseCount)(value, 0), (n) => ({ supervisorRetryLimit: n }));
|
|
3907
|
+
else if (arg === "reads") changes = maybe((0, import_core23.parseCount)(value, 1), (n) => ({ wakeUpReadBudget: n }));
|
|
3798
3908
|
if (arg !== void 0 && changes === null) fail(SUPERVISOR_USAGE);
|
|
3799
3909
|
const api = await connect(subArgs, injectedApi);
|
|
3800
3910
|
if (!changes) {
|
|
3801
|
-
console.log((0,
|
|
3911
|
+
console.log((0, import_core23.supervisorSummary)((await api.getSettings()).run));
|
|
3802
3912
|
console.log(` ${SUPERVISOR_USAGE}`);
|
|
3803
3913
|
return;
|
|
3804
3914
|
}
|
|
3805
3915
|
await save(api, changes);
|
|
3806
|
-
if (changes.supervisorLevel) console.log(`Supervisor: ${
|
|
3807
|
-
if (changes.supervisorLevel === "act") console.log(
|
|
3916
|
+
if (changes.supervisorLevel) console.log(`Supervisor: ${import_core23.SUPERVISOR_LEVEL_LABEL[changes.supervisorLevel]}, from each session's next run.`);
|
|
3917
|
+
if (changes.supervisorLevel === "act") console.log(import_core23.ACT_RISK);
|
|
3808
3918
|
if (changes.supervisorRetryLimit !== void 0) console.log(`Supervisor retry limit: ${changes.supervisorRetryLimit} per task.`);
|
|
3809
3919
|
if (changes.wakeUpReadBudget !== void 0) console.log(`Wake-up read budget: ${changes.wakeUpReadBudget} reads.`);
|
|
3810
3920
|
}
|
|
3811
3921
|
async function handleAutomerge(subArgs, injectedApi) {
|
|
3812
3922
|
const [arg] = positionals(subArgs);
|
|
3813
|
-
const enabled = arg === void 0 ? null : (0,
|
|
3923
|
+
const enabled = arg === void 0 ? null : (0, import_core23.parseSwitch)(arg);
|
|
3814
3924
|
if (arg !== void 0 && enabled === null) fail(AUTOMERGE_USAGE);
|
|
3815
3925
|
const api = await connect(subArgs, injectedApi);
|
|
3816
3926
|
if (enabled === null) {
|
|
3817
|
-
console.log((0,
|
|
3927
|
+
console.log((0, import_core23.automergeSummary)((await api.getSettings()).run));
|
|
3818
3928
|
console.log(` ${AUTOMERGE_USAGE}`);
|
|
3819
3929
|
return;
|
|
3820
3930
|
}
|
|
@@ -3823,24 +3933,24 @@ async function handleAutomerge(subArgs, injectedApi) {
|
|
|
3823
3933
|
}
|
|
3824
3934
|
async function handleAutorun(subArgs, injectedApi) {
|
|
3825
3935
|
const [arg] = positionals(subArgs);
|
|
3826
|
-
const enabled = arg === void 0 ? null : (0,
|
|
3936
|
+
const enabled = arg === void 0 ? null : (0, import_core23.parseSwitch)(arg);
|
|
3827
3937
|
if (arg !== void 0 && enabled === null) fail(AUTORUN_USAGE);
|
|
3828
3938
|
const api = await connect(subArgs, injectedApi);
|
|
3829
3939
|
if (enabled === null) {
|
|
3830
|
-
console.log((0,
|
|
3940
|
+
console.log((0, import_core23.autorunSummary)((await api.getSettings()).run));
|
|
3831
3941
|
console.log(` ${AUTORUN_USAGE}`);
|
|
3832
3942
|
return;
|
|
3833
3943
|
}
|
|
3834
3944
|
await save(api, { autorun: enabled });
|
|
3835
3945
|
console.log(`Autorun: ${enabled ? "on \u2014 each plan the planner submits starts at once" : "off \u2014 plans wait for your review"}.`);
|
|
3836
|
-
if (enabled) console.log(
|
|
3946
|
+
if (enabled) console.log(import_core23.AUTORUN_RISK);
|
|
3837
3947
|
}
|
|
3838
3948
|
function maybe(n, wrap2) {
|
|
3839
3949
|
return n === null ? null : wrap2(n);
|
|
3840
3950
|
}
|
|
3841
3951
|
|
|
3842
3952
|
// src/commands/key.ts
|
|
3843
|
-
var
|
|
3953
|
+
var import_core24 = require("@ordewell/core");
|
|
3844
3954
|
var USAGE6 = "Usage: ordewell key [list | set <provider> <key>]";
|
|
3845
3955
|
async function handleKey(subArgs, injectedApi) {
|
|
3846
3956
|
const [action, provider, ...keyParts] = positionals(subArgs);
|
|
@@ -3851,8 +3961,8 @@ async function handleKey(subArgs, injectedApi) {
|
|
|
3851
3961
|
if (action !== "set") {
|
|
3852
3962
|
const catalog = await fetchCatalog(api);
|
|
3853
3963
|
console.log("\nAPI provider keys\n");
|
|
3854
|
-
for (const id2 of
|
|
3855
|
-
const meta2 =
|
|
3964
|
+
for (const id2 of import_core24.PROVIDER_PRIORITY) {
|
|
3965
|
+
const meta2 = (0, import_core24.getProviderMeta)(id2);
|
|
3856
3966
|
const configured = catalog.providers.includes(id2);
|
|
3857
3967
|
console.log(` ${configured ? "\u2713" : " "} ${id2.padEnd(14)} ${meta2.apiKeyEnvVar.padEnd(28)} ${meta2.label}`);
|
|
3858
3968
|
}
|
|
@@ -3862,10 +3972,10 @@ async function handleKey(subArgs, injectedApi) {
|
|
|
3862
3972
|
}
|
|
3863
3973
|
if (!provider) fail(USAGE6);
|
|
3864
3974
|
const id = provider.toLowerCase();
|
|
3865
|
-
|
|
3866
|
-
if (!meta) {
|
|
3975
|
+
if (!(0, import_core24.isApiProvider)(id)) {
|
|
3867
3976
|
fail(`Unknown provider: ${provider}`, "Run `ordewell key` to see the list.");
|
|
3868
3977
|
}
|
|
3978
|
+
const meta = (0, import_core24.getProviderMeta)(id);
|
|
3869
3979
|
const key = keyParts.join(" ").trim();
|
|
3870
3980
|
if (!key) fail(`Usage: ordewell key set ${id} <key>`);
|
|
3871
3981
|
await persistEnv(api, { [meta.apiKeyEnvVar]: key });
|
|
@@ -3873,7 +3983,7 @@ async function handleKey(subArgs, injectedApi) {
|
|
|
3873
3983
|
}
|
|
3874
3984
|
|
|
3875
3985
|
// src/commands/runners.ts
|
|
3876
|
-
var
|
|
3986
|
+
var import_core25 = require("@ordewell/core");
|
|
3877
3987
|
var USAGE7 = "Usage: ordewell runners [<runner-id> on|off]";
|
|
3878
3988
|
async function handleRunners(subArgs, injectedApi) {
|
|
3879
3989
|
const [runner, toggle] = positionals(subArgs);
|
|
@@ -3884,7 +3994,7 @@ async function handleRunners(subArgs, injectedApi) {
|
|
|
3884
3994
|
for (const r of state2.runners) {
|
|
3885
3995
|
console.log(` ${r.enabled ? "\u2713" : " "} ${r.id.padEnd(14)} ${r.name}${r.enabled ? "" : " (disabled)"}`);
|
|
3886
3996
|
}
|
|
3887
|
-
const notice = (0,
|
|
3997
|
+
const notice = (0, import_core25.codexSandboxNotice)((await fetchCatalog(api).catch(() => null))?.modesByRunner);
|
|
3888
3998
|
if (notice) console.log(`
|
|
3889
3999
|
${notice.line}
|
|
3890
4000
|
${notice.docs}`);
|
|
@@ -3905,17 +4015,17 @@ async function handleRunners(subArgs, injectedApi) {
|
|
|
3905
4015
|
var AUTO_USAGE = "Usage: ordewell auto [full|guarded]";
|
|
3906
4016
|
function handleAuto(subArgs) {
|
|
3907
4017
|
const [arg] = positionals(subArgs);
|
|
3908
|
-
const settings = new
|
|
4018
|
+
const settings = new import_core25.SettingsService();
|
|
3909
4019
|
const current = settings.autonomousMode();
|
|
3910
4020
|
if (!arg) {
|
|
3911
|
-
console.log(`Autonomy level: ${(0,
|
|
4021
|
+
console.log(`Autonomy level: ${(0, import_core25.autonomyLevelLabel)(current)}`);
|
|
3912
4022
|
console.log(` ${AUTO_USAGE}`);
|
|
3913
4023
|
return;
|
|
3914
4024
|
}
|
|
3915
|
-
const enabled = (0,
|
|
4025
|
+
const enabled = (0, import_core25.parseAutonomyLevel)(arg);
|
|
3916
4026
|
if (enabled === null) fail(AUTO_USAGE);
|
|
3917
4027
|
settings.setAutonomousMode(enabled);
|
|
3918
|
-
console.log(settings.autonomousModeOverridden() ? `${(0,
|
|
4028
|
+
console.log(settings.autonomousModeOverridden() ? `${(0, import_core25.autonomyLevelLabel)(enabled)} is saved, but ORDEWELL_AUTONOMOUS_MODE in the environment decides the level until it is unset.` : `Autonomy level: ${(0, import_core25.autonomyLevelLabel)(enabled)} for new plans.`);
|
|
3919
4029
|
}
|
|
3920
4030
|
async function handleRefresh(subArgs, injectedApi) {
|
|
3921
4031
|
const api = await connect(subArgs, injectedApi);
|
|
@@ -3945,7 +4055,7 @@ async function handleApprove(subArgs, injectedApi) {
|
|
|
3945
4055
|
}
|
|
3946
4056
|
|
|
3947
4057
|
// src/commands/task-assign.ts
|
|
3948
|
-
var
|
|
4058
|
+
var import_core27 = require("@ordewell/core");
|
|
3949
4059
|
var import_plan_utils = require("@ordewell/core/plan-utils");
|
|
3950
4060
|
|
|
3951
4061
|
// src/tui/taskAssignment.ts
|
|
@@ -3985,7 +4095,7 @@ function modesForTask(modesByRunner, task) {
|
|
|
3985
4095
|
}
|
|
3986
4096
|
|
|
3987
4097
|
// src/tui/state.ts
|
|
3988
|
-
var
|
|
4098
|
+
var import_core26 = require("@ordewell/core");
|
|
3989
4099
|
|
|
3990
4100
|
// src/tui/editor.ts
|
|
3991
4101
|
function emptyEditor() {
|
|
@@ -4143,7 +4253,7 @@ function queuedTarget(tv) {
|
|
|
4143
4253
|
for (let i = queued.length - 1; i >= 0; i--) if (!queued[i].forced) return i;
|
|
4144
4254
|
return -1;
|
|
4145
4255
|
}
|
|
4146
|
-
var anyTaskRunning = (state) => state.tasks.some(
|
|
4256
|
+
var anyTaskRunning = (state) => state.tasks.some(import_core26.isTaskRunning);
|
|
4147
4257
|
var plannerInFlight = (state) => state.planner !== "idle";
|
|
4148
4258
|
var planPaneOpen = (state) => state.focus === "plan" && !state.overlay && (!!state.taskEditor || !!state.expandedTaskId);
|
|
4149
4259
|
function planRows(state) {
|
|
@@ -4163,8 +4273,8 @@ function selectedPlanRow(state) {
|
|
|
4163
4273
|
}
|
|
4164
4274
|
function runnerCommands(tv) {
|
|
4165
4275
|
for (let i = tv.view.blocks.length - 1; i >= 0; i--) {
|
|
4166
|
-
const
|
|
4167
|
-
if (
|
|
4276
|
+
const block2 = tv.view.blocks[i];
|
|
4277
|
+
if (block2.type === "runner_loaded") return block2.commands;
|
|
4168
4278
|
}
|
|
4169
4279
|
return [];
|
|
4170
4280
|
}
|
|
@@ -4189,10 +4299,10 @@ function findTask(tasks, id) {
|
|
|
4189
4299
|
return void 0;
|
|
4190
4300
|
}
|
|
4191
4301
|
function refFor(state, task) {
|
|
4192
|
-
return (0,
|
|
4302
|
+
return (0, import_core26.taskRefOf)(state.tasks, task.id) ?? (0, import_core26.taskRef)(task);
|
|
4193
4303
|
}
|
|
4194
4304
|
function titledRefFor(state, task) {
|
|
4195
|
-
return (0,
|
|
4305
|
+
return (0, import_core26.titledTaskRefOf)(state.tasks, task.id) ?? (0, import_core26.titledTaskRef)(task);
|
|
4196
4306
|
}
|
|
4197
4307
|
function asRunTasks(tasks) {
|
|
4198
4308
|
return tasks.map((task) => ({ ...task, subtasks: asRunTasks(task.subtasks ?? []) }));
|
|
@@ -4200,7 +4310,7 @@ function asRunTasks(tasks) {
|
|
|
4200
4310
|
function seedRun(overrides) {
|
|
4201
4311
|
if (overrides.run) return overrides.run;
|
|
4202
4312
|
return {
|
|
4203
|
-
...
|
|
4313
|
+
...import_core26.EMPTY_RUN,
|
|
4204
4314
|
tasks: asRunTasks(overrides.tasks ?? []),
|
|
4205
4315
|
handoff: overrides.handoff ?? null,
|
|
4206
4316
|
runMerge: overrides.runMerge ? { waitingAtGate: overrides.runMerge.waitingAtGate, paused: overrides.runMerge.paused, repos: overrides.runMerge.handoff.repos, landed: overrides.runMerge.handoff.landed } : null
|
|
@@ -4209,9 +4319,9 @@ function seedRun(overrides) {
|
|
|
4209
4319
|
function initialState(overrides = {}) {
|
|
4210
4320
|
return {
|
|
4211
4321
|
editor: emptyEditor(),
|
|
4212
|
-
conversation:
|
|
4322
|
+
conversation: import_core26.EMPTY_CONVERSATION,
|
|
4213
4323
|
taskView: null,
|
|
4214
|
-
turnGate:
|
|
4324
|
+
turnGate: import_core26.NO_TURN,
|
|
4215
4325
|
detailAll: false,
|
|
4216
4326
|
status: "idle",
|
|
4217
4327
|
planner: "idle",
|
|
@@ -4237,11 +4347,11 @@ function initialState(overrides = {}) {
|
|
|
4237
4347
|
plannerProvider: "",
|
|
4238
4348
|
plannerEffort: "",
|
|
4239
4349
|
plannerModels: {},
|
|
4240
|
-
maxParallel:
|
|
4350
|
+
maxParallel: import_core26.DEFAULT_MAX_PARALLEL,
|
|
4241
4351
|
configuredProviders: [],
|
|
4242
4352
|
allowlist: {},
|
|
4243
4353
|
autonomous: true,
|
|
4244
|
-
runSettings: { ...
|
|
4354
|
+
runSettings: { ...import_core26.RUN_SETTINGS_DEFAULTS },
|
|
4245
4355
|
runAutoMerge: null,
|
|
4246
4356
|
runSupervisor: null,
|
|
4247
4357
|
mouseCapture: true,
|
|
@@ -4251,7 +4361,7 @@ function initialState(overrides = {}) {
|
|
|
4251
4361
|
runMerge: null,
|
|
4252
4362
|
overlay: null,
|
|
4253
4363
|
pendingApprovals: [],
|
|
4254
|
-
queuedPrompts:
|
|
4364
|
+
queuedPrompts: import_core26.EMPTY_HOLD,
|
|
4255
4365
|
stopArmed: false,
|
|
4256
4366
|
stopArmToken: 0,
|
|
4257
4367
|
stopRequested: false,
|
|
@@ -4385,7 +4495,7 @@ Mode \xB7 ${namedOf(tasks, task)}${task.assignedRunner ? ` (${task.assignedRunne
|
|
|
4385
4495
|
for (const m of modes) {
|
|
4386
4496
|
console.log(` ${m.id === task.taskMode ? "*" : " "} ${m.id.padEnd(14)} ${m.label}${m.unavailable ? " \u2014 unavailable on this host" : m.description ? ` \u2014 ${m.description}` : ""}`);
|
|
4387
4497
|
}
|
|
4388
|
-
const notice = (0,
|
|
4498
|
+
const notice = (0, import_core27.codexSandboxNotice)(catalog.modesByRunner);
|
|
4389
4499
|
if (notice) console.log(`
|
|
4390
4500
|
${notice.line}
|
|
4391
4501
|
${notice.docs}`);
|
|
@@ -4434,7 +4544,7 @@ var SKILLS_USAGE = "Usage: ordewell task-skills <task-id-or-order> [<name> [<nam
|
|
|
4434
4544
|
async function handleTaskSkills(subArgs, injectedApi) {
|
|
4435
4545
|
await withTask(subArgs, SKILLS_USAGE, injectedApi, async (api, sessionId, task, tasks, value) => {
|
|
4436
4546
|
if (task.type !== "ai") fail("Manual tasks do not run an executor, so they take no skills.");
|
|
4437
|
-
const catalog = (0,
|
|
4547
|
+
const catalog = (0, import_core27.createSkillsService)(flag(subArgs, "--workspace") || process.cwd(), new import_core27.EnvConfig().workspaceRepos).listSkills().filter((s) => s.appliesTo === "task");
|
|
4438
4548
|
if (!value) {
|
|
4439
4549
|
console.log(`
|
|
4440
4550
|
Skills \xB7 ${namedOf(tasks, task)}
|
|
@@ -4479,10 +4589,10 @@ ${namedOf(tasks, task)} is ${task.ops ? "an ops task: it runs in your checkout o
|
|
|
4479
4589
|
}
|
|
4480
4590
|
|
|
4481
4591
|
// src/tui/index.ts
|
|
4482
|
-
var
|
|
4592
|
+
var import_core48 = require("@ordewell/core");
|
|
4483
4593
|
|
|
4484
4594
|
// src/tui/slash.ts
|
|
4485
|
-
var
|
|
4595
|
+
var import_core28 = require("@ordewell/core");
|
|
4486
4596
|
var SLASH_COMMANDS = [
|
|
4487
4597
|
// Planning. There is deliberately no `/plan`: typing the goal *is* the way to
|
|
4488
4598
|
// start planning, and an alias for it only shadowed `/planner` on completion.
|
|
@@ -4515,7 +4625,7 @@ var SLASH_COMMANDS = [
|
|
|
4515
4625
|
{ name: "planner-effort", usage: "/planner-effort [<level>]", description: "Thinking effort for a coding-agent planner", category: "models" },
|
|
4516
4626
|
{ name: "key", usage: "/key [set <provider> <key>]", description: "Configure API provider keys", category: "models" },
|
|
4517
4627
|
{ name: "allowlist", usage: "/allowlist [set <runner> <ids> | clear <runner>]", description: "Limit which models a runner may use", category: "models" },
|
|
4518
|
-
{ name: "runners", usage: "/runners [<id> on|off]", description:
|
|
4628
|
+
{ name: "runners", usage: "/runners [<id> on|off]", description: `Enable or disable runners (${runnerIdList()})`, category: "models" },
|
|
4519
4629
|
{ name: "auto", usage: "/auto [full|guarded]", description: "Autonomy level for new plans: Full or Guarded", category: "models" },
|
|
4520
4630
|
{ name: "supervisor", usage: "/supervisor [off|watch|act] \xB7 retries <n> \xB7 reads <n>", description: "Whether the planner watches or acts on your runs, now and from then on", category: "models" },
|
|
4521
4631
|
{ name: "automerge", usage: "/automerge [on|off]", description: "Merge into your branch by itself at merge gates and at the end of a run", category: "models" },
|
|
@@ -4601,7 +4711,7 @@ function parseRunnerCommand(text) {
|
|
|
4601
4711
|
return match ? { name: match[1], args: (match[2] ?? "").trim() } : null;
|
|
4602
4712
|
}
|
|
4603
4713
|
function runnerCommandFor(commands, name) {
|
|
4604
|
-
return (0,
|
|
4714
|
+
return (0, import_core28.findRunnerCommand)(commands, name) ?? (0, import_core28.findRunnerCommand)(commands, name.toLowerCase());
|
|
4605
4715
|
}
|
|
4606
4716
|
function composerCompletions(token, runner) {
|
|
4607
4717
|
if (runner) return token.start === 0 ? runner.filter((c) => c.name.toLowerCase().startsWith(token.name)).map((c) => c.name) : [];
|
|
@@ -4648,10 +4758,10 @@ function chatEditorRoomFor(state, active) {
|
|
|
4648
4758
|
}
|
|
4649
4759
|
|
|
4650
4760
|
// src/tui/layout.ts
|
|
4651
|
-
var
|
|
4761
|
+
var import_core31 = require("@ordewell/core");
|
|
4652
4762
|
|
|
4653
4763
|
// src/tui/reducers/pickers.ts
|
|
4654
|
-
var
|
|
4764
|
+
var import_core29 = require("@ordewell/core");
|
|
4655
4765
|
var import_plan_utils2 = require("@ordewell/core/plan-utils");
|
|
4656
4766
|
var DEFAULT_EFFORT = "__runner_default__";
|
|
4657
4767
|
function picker(title, items, action, extra = {}) {
|
|
@@ -4670,11 +4780,11 @@ function modelDetail(m) {
|
|
|
4670
4780
|
function providerErrorHint(state) {
|
|
4671
4781
|
const failed = Object.keys(state.providerErrors ?? {});
|
|
4672
4782
|
if (failed.length === 0) return void 0;
|
|
4673
|
-
const names = failed.map((p) =>
|
|
4783
|
+
const names = failed.map((p) => (0, import_core29.getProviderMeta)(p)?.label ?? p);
|
|
4674
4784
|
return `\u26A0 Unavailable (key or fetch failed): ${names.join(", ")} \u2014 showing working providers only.`;
|
|
4675
4785
|
}
|
|
4676
4786
|
function plannerModelItems(state, provider, selectedId) {
|
|
4677
|
-
const runner = (0,
|
|
4787
|
+
const runner = (0, import_core29.runnerForProvider)(provider);
|
|
4678
4788
|
if (!runner) {
|
|
4679
4789
|
return state.orchestratorModels.map((m) => ({ id: m.id, label: m.label, detail: modelDetail(m), selected: m.id === selectedId }));
|
|
4680
4790
|
}
|
|
@@ -4690,11 +4800,11 @@ function plannerModelItems(state, provider, selectedId) {
|
|
|
4690
4800
|
return items.length > 0 ? items : [{ id: "", label: `No ${runner} models discovered yet`, detail: "run /refresh", disabled: true }];
|
|
4691
4801
|
}
|
|
4692
4802
|
function plannerHarnessModel(state, provider, modelId) {
|
|
4693
|
-
const runner = (0,
|
|
4803
|
+
const runner = (0, import_core29.runnerForProvider)(provider);
|
|
4694
4804
|
return runner ? state.models.find((m) => m.id === modelId && m.runners?.includes(runner)) : void 0;
|
|
4695
4805
|
}
|
|
4696
4806
|
function plannerEffortItems(state, provider, modelId, selectedEffort) {
|
|
4697
|
-
if (!(0,
|
|
4807
|
+
if (!(0, import_core29.runnerForProvider)(provider)) {
|
|
4698
4808
|
return [{ id: "", label: "Thinking effort applies to a coding-agent planner", detail: "switch with /planner", disabled: true }];
|
|
4699
4809
|
}
|
|
4700
4810
|
const model = plannerHarnessModel(state, provider, modelId);
|
|
@@ -4812,11 +4922,11 @@ function pickerItemsFor(state, action) {
|
|
|
4812
4922
|
function plannerItems(state) {
|
|
4813
4923
|
const installed = new Set(state.runners.map((r) => r.id));
|
|
4814
4924
|
const usability = {};
|
|
4815
|
-
for (const id of
|
|
4816
|
-
const runner = (0,
|
|
4925
|
+
for (const id of import_core29.CLI_PROVIDERS) {
|
|
4926
|
+
const runner = (0, import_core29.runnerForProvider)(id);
|
|
4817
4927
|
usability[runner] = installed.has(runner) ? { usable: true } : { usable: false, reason: "CLI not installed or not on PATH" };
|
|
4818
4928
|
}
|
|
4819
|
-
const entries = (0,
|
|
4929
|
+
const entries = (0, import_core29.plannerBackendEntries)(usability, state.configuredProviders);
|
|
4820
4930
|
const items = entries.map((entry) => ({
|
|
4821
4931
|
id: entry.id,
|
|
4822
4932
|
label: entry.label,
|
|
@@ -4841,7 +4951,7 @@ function cliVersion() {
|
|
|
4841
4951
|
}
|
|
4842
4952
|
|
|
4843
4953
|
// src/tui/planKeys.ts
|
|
4844
|
-
var
|
|
4954
|
+
var import_core30 = require("@ordewell/core");
|
|
4845
4955
|
var PLAN_KEYS = {
|
|
4846
4956
|
move: { keys: "up / down", meaning: "move between tasks", group: "Navigation" },
|
|
4847
4957
|
scroll: { keys: "pgup / pgdn", meaning: "scroll the plan", group: "Navigation" },
|
|
@@ -4868,7 +4978,7 @@ var PLAN_KEYS = {
|
|
|
4868
4978
|
meaning: "cancel the task's runner, or keep a task paused on a usage limit from resuming on its own",
|
|
4869
4979
|
group: "Run",
|
|
4870
4980
|
// `c` cancels the resume while the task has one; it has no runner to cancel then.
|
|
4871
|
-
hint: (task) => task && (0,
|
|
4981
|
+
hint: (task) => task && (0, import_core30.resumeLabel)(task) ? "c don't resume" : "c cancel"
|
|
4872
4982
|
},
|
|
4873
4983
|
resume: { keys: "r", meaning: "resume a task paused on a usage limit now, once the limit has reset", group: "Run", hint: "r resume now" },
|
|
4874
4984
|
resolve: { keys: "x", meaning: "resolve a merge conflict", group: "Run", hint: "x resolve conflict" },
|
|
@@ -4878,7 +4988,7 @@ var PLAN_KEYS = {
|
|
|
4878
4988
|
meaning: "mark the task done, or take it back",
|
|
4879
4989
|
group: "Status",
|
|
4880
4990
|
// `m` toggles, so the hint names the direction it will go for this task.
|
|
4881
|
-
hint: (task) => task && (0,
|
|
4991
|
+
hint: (task) => task && (0, import_core30.markAction)(task) === "uncomplete" ? "m undone" : "m done"
|
|
4882
4992
|
},
|
|
4883
4993
|
skip: { keys: "s", meaning: "skip the task: none of its work lands, and what depends on it goes ahead", group: "Status", hint: "s skip" },
|
|
4884
4994
|
remove: { keys: "d", meaning: "remove the task", group: "Status" },
|
|
@@ -4905,7 +5015,7 @@ function hintOf(id, task) {
|
|
|
4905
5015
|
}
|
|
4906
5016
|
function taskKeyIds(task, runActive) {
|
|
4907
5017
|
if (!task) return ["add"];
|
|
4908
|
-
const row = (0,
|
|
5018
|
+
const row = (0, import_core30.taskRowView)(task);
|
|
4909
5019
|
if (row.conflict) return ["resolve", "log"];
|
|
4910
5020
|
if (row.actions.includes("resume-now") || row.resumes) {
|
|
4911
5021
|
return [...row.actions.includes("resume-now") ? ["resume"] : [], ...row.resumes ? ["cancel"] : [], "skip", "log"];
|
|
@@ -4933,7 +5043,7 @@ function planFooterHints(task, runActive) {
|
|
|
4933
5043
|
}
|
|
4934
5044
|
|
|
4935
5045
|
// src/tui/layout.ts
|
|
4936
|
-
var
|
|
5046
|
+
var import_core32 = require("@ordewell/core");
|
|
4937
5047
|
var CHROME_ROWS = 1;
|
|
4938
5048
|
function chatInputWrap(state) {
|
|
4939
5049
|
const active = state.focus === "chat" && !state.overlay;
|
|
@@ -4959,7 +5069,7 @@ function footerHints(state) {
|
|
|
4959
5069
|
}
|
|
4960
5070
|
return [...escHint ? [escHint] : [], ...planFooterHints(selected, state.status === "executing")];
|
|
4961
5071
|
}
|
|
4962
|
-
const detailHint = (0,
|
|
5072
|
+
const detailHint = (0, import_core32.hasHiddenDetail)(state.taskView ? state.taskView.view.blocks : state.conversation.blocks) ? [state.detailAll ? "ctrl-o collapse all" : "ctrl-o expand all"] : [];
|
|
4963
5073
|
return [
|
|
4964
5074
|
"/help",
|
|
4965
5075
|
...checkpointHints,
|
|
@@ -5018,12 +5128,12 @@ function queuedTaskBubble(message, target, sends, cols) {
|
|
|
5018
5128
|
}
|
|
5019
5129
|
function taskActivity(task, working) {
|
|
5020
5130
|
if (task?.status === "completed" || task?.status === "failed") return task.status;
|
|
5021
|
-
const approvals = (0,
|
|
5131
|
+
const approvals = (0, import_core32.approvalLabel)(task?.awaitingApproval);
|
|
5022
5132
|
if (approvals) return inRow(approvals);
|
|
5023
5133
|
if (working) return "working";
|
|
5024
5134
|
if (task?.status === "awaiting_user") {
|
|
5025
|
-
const resumes = (0,
|
|
5026
|
-
return [inRow((0,
|
|
5135
|
+
const resumes = (0, import_core32.resumeLabel)(task);
|
|
5136
|
+
return [inRow((0, import_core32.awaitingLabel)(task) ?? "Waiting for your input"), resumes ? inRow(resumes) : ""].filter(Boolean).join(" \xB7 ");
|
|
5027
5137
|
}
|
|
5028
5138
|
return task?.status ?? "";
|
|
5029
5139
|
}
|
|
@@ -5036,7 +5146,7 @@ function taskHeaderLines(state, tv, cols) {
|
|
|
5036
5146
|
taskActivity(task, tv.view.working)
|
|
5037
5147
|
].filter(Boolean);
|
|
5038
5148
|
const approval = waitingApproval(tv);
|
|
5039
|
-
const hint = approval ? ["ctrl-y allow", ...approval.allowForTask ? ["ctrl-t allow for task"] : [], "ctrl-g deny (composer text is the note)"] : waitingCheckpoint(task) ? ["enter reply", "ctrl-y approve", "ctrl-g reject", "ctrl-x stop runner"] : task && (0,
|
|
5149
|
+
const hint = approval ? ["ctrl-y allow", ...approval.allowForTask ? ["ctrl-t allow for task"] : [], "ctrl-g deny (composer text is the note)"] : waitingCheckpoint(task) ? ["enter reply", "ctrl-y approve", "ctrl-g reject", "ctrl-x stop runner"] : task && (0, import_core32.resumeLabel)(task) ? ["ctrl-x don't resume"] : [...runnerStoppable(state) ? ["ctrl-x stop runner"] : [], "ctrl-r remove queued", "ctrl-s send now"];
|
|
5040
5150
|
if (approval && waitingCheckpoint(task)) hint.push("then the checkpoint");
|
|
5041
5151
|
const index = tv.attempts.indexOf(tv.attempt);
|
|
5042
5152
|
if (tv.attempts.length > 1) hint.push(`alt\u2190/\u2192 attempt ${index >= 0 ? index + 1 : 1}/${tv.attempts.length}`);
|
|
@@ -5066,9 +5176,9 @@ function chatActivity(state) {
|
|
|
5066
5176
|
const own = findTask(state.tasks, tv.taskId);
|
|
5067
5177
|
const task = state.tasks.find((t) => t.subtasks?.some((s) => s.id === tv.taskId)) ?? own;
|
|
5068
5178
|
if (!task) return null;
|
|
5069
|
-
if ((0,
|
|
5179
|
+
if ((0, import_core26.isTaskRunning)(task) || own && (0, import_core26.isTaskRunning)(own)) return { label: "Working\u2026", busy: true };
|
|
5070
5180
|
const at = task.status === "awaiting_user" && task.awaitingReason === "usage-limit" && task.resumeAt ? new Date(task.resumeAt) : null;
|
|
5071
|
-
if (at && !Number.isNaN(at.getTime())) return { label: `paused \xB7 resumes ${(0,
|
|
5181
|
+
if (at && !Number.isNaN(at.getTime())) return { label: `paused \xB7 resumes ${(0, import_core32.resumeTime)(at)}`, busy: false };
|
|
5072
5182
|
return null;
|
|
5073
5183
|
}
|
|
5074
5184
|
function runHints(state) {
|
|
@@ -5097,41 +5207,41 @@ function bodyRows(state) {
|
|
|
5097
5207
|
return Math.max(0, state.rows - CHROME_ROWS - composerRows(state) - footer);
|
|
5098
5208
|
}
|
|
5099
5209
|
var chatBodyMemo = null;
|
|
5100
|
-
function chatBodyLines(
|
|
5210
|
+
function chatBodyLines(blocks2, cols, detailAll, answering) {
|
|
5101
5211
|
const memo = chatBodyMemo;
|
|
5102
|
-
if (memo && memo.blocks ===
|
|
5103
|
-
const lines = conversationLines(
|
|
5104
|
-
chatBodyMemo = { blocks, cols, detailAll, lines };
|
|
5212
|
+
if (memo && memo.blocks === blocks2 && memo.cols === cols && memo.detailAll === detailAll) return memo.lines;
|
|
5213
|
+
const lines = conversationLines(blocks2, cols, detailAll, answering);
|
|
5214
|
+
chatBodyMemo = { blocks: blocks2, cols, detailAll, lines };
|
|
5105
5215
|
return lines;
|
|
5106
5216
|
}
|
|
5107
5217
|
function chatLayout(state, rows, cols) {
|
|
5108
5218
|
const tv = state.taskView;
|
|
5109
|
-
const
|
|
5219
|
+
const blocks2 = tv ? tv.view.blocks : state.conversation.blocks;
|
|
5110
5220
|
const welcome = !tv && state.tasks.length === 0;
|
|
5111
5221
|
const checkpoint = tv ? waitingCheckpoint(findTask(state.tasks, tv.taskId)) : void 0;
|
|
5112
5222
|
const card = tv && checkpoint ? checkpointCardLines(findTask(state.tasks, tv.taskId)?.order ?? 0, checkpoint, cols, waitingApproval(tv) !== void 0) : [];
|
|
5113
|
-
const answering = chatBodyLines(
|
|
5223
|
+
const answering = chatBodyLines(blocks2, cols, state.detailAll, tv ? waitingApproval(tv) : void 0);
|
|
5114
5224
|
const body = card.length > 0 ? [...answering, ...card] : answering;
|
|
5115
5225
|
const transcript = !welcome ? body : body.length === 0 ? welcomeLines(state, rows, cols) : [...welcomeLines(state, rows, cols), "", ...body];
|
|
5116
5226
|
const bubbles = tv ? taskQueuedRows(state, cols) : queuedPromptRows(state, cols);
|
|
5117
5227
|
const content = [...transcript, ...bubbles.length > 0 ? ["", ...bubbles] : []];
|
|
5118
5228
|
const taskHeader = tv ? taskHeaderLines(state, tv, cols) : [];
|
|
5119
|
-
const usage = rows <= 1 ? [] : tv ? taskUsageFooter(state, tv,
|
|
5229
|
+
const usage = rows <= 1 ? [] : tv ? taskUsageFooter(state, tv, blocks2, cols) : tokenRow(blocks2, cols);
|
|
5120
5230
|
const footer = usage.slice(0, Math.max(1, rows - taskHeader.length - 1));
|
|
5121
5231
|
const space = Math.max(0, rows - taskHeader.length - footer.length);
|
|
5122
5232
|
return { lines: content, header: taskHeader, footer, anchor: content.length > space ? "bottom" : "top", maxScroll: Math.max(0, content.length - space) };
|
|
5123
5233
|
}
|
|
5124
|
-
var tokenRow = (
|
|
5125
|
-
const line = tokenLine(
|
|
5234
|
+
var tokenRow = (blocks2, cols) => {
|
|
5235
|
+
const line = tokenLine(blocks2, cols);
|
|
5126
5236
|
return line ? [line] : [];
|
|
5127
5237
|
};
|
|
5128
|
-
function taskUsageFooter(state, tv,
|
|
5238
|
+
function taskUsageFooter(state, tv, blocks2, cols) {
|
|
5129
5239
|
const task = findTask(state.tasks, tv.taskId);
|
|
5130
5240
|
const reported = task?.attemptUsage ?? [];
|
|
5131
5241
|
const onScreen = tv.attempt > 0 ? reported.find((a) => a.attempt === tv.attempt) : reported.at(-1);
|
|
5132
|
-
if (!task || !onScreen) return tokenRow(
|
|
5133
|
-
const usage = (0,
|
|
5134
|
-
if (!usage) return tokenRow(
|
|
5242
|
+
if (!task || !onScreen) return tokenRow(blocks2, cols);
|
|
5243
|
+
const usage = (0, import_core32.taskRowView)({ ...task, attemptUsage: [onScreen] }).usage;
|
|
5244
|
+
if (!usage) return tokenRow(blocks2, cols);
|
|
5135
5245
|
const models = usage.byModel ?? [];
|
|
5136
5246
|
return [
|
|
5137
5247
|
style.grey(truncate(taskUsageText(usage), cols)),
|
|
@@ -5143,17 +5253,17 @@ function chatScrollMax(state) {
|
|
|
5143
5253
|
}
|
|
5144
5254
|
function plannerSetup(state) {
|
|
5145
5255
|
const provider = state.plannerProvider;
|
|
5146
|
-
const registration =
|
|
5256
|
+
const registration = (0, import_core32.getProviderMeta)(provider);
|
|
5147
5257
|
if (!registration) return { label: "not set", ready: false };
|
|
5148
|
-
const runner = (0,
|
|
5149
|
-
const ready = runner ? state.runners.some((r) => r.id === runner) : state.configuredProviders.includes(provider);
|
|
5258
|
+
const runner = (0, import_core32.runnerForProvider)(provider);
|
|
5259
|
+
const ready = runner ? state.runners.some((r) => r.id === runner) : (0, import_core32.isApiProvider)(provider) && state.configuredProviders.includes(provider);
|
|
5150
5260
|
return { label: registration.label, ready };
|
|
5151
5261
|
}
|
|
5152
5262
|
var SETUP_KEY_COLS = 10;
|
|
5153
5263
|
var SETUP_VALUE_COLS = 32;
|
|
5154
5264
|
function runSettingsValue(state) {
|
|
5155
5265
|
const { supervisorLevel, mergeAtGatesAutomatically, autorun } = state.runSettings;
|
|
5156
|
-
const level = `supervisor ${
|
|
5266
|
+
const level = `supervisor ${import_core31.SUPERVISOR_LEVEL_LABEL[supervisorLevel]}`;
|
|
5157
5267
|
return [
|
|
5158
5268
|
supervisorLevel === "act" ? style.yellow(level) : level,
|
|
5159
5269
|
`auto-merge ${mergeAtGatesAutomatically ? "on" : "off"}`,
|
|
@@ -5254,7 +5364,7 @@ function welcomeLines(state, rows, cols) {
|
|
|
5254
5364
|
];
|
|
5255
5365
|
const notice = canPlan ? [] : [
|
|
5256
5366
|
...wrap(
|
|
5257
|
-
style.yellow(
|
|
5367
|
+
style.yellow(`Ordewell needs one coding agent installed (${runnerNamesOr()}) \u2014 or an API key from a provider such as OpenRouter, added with /key.`),
|
|
5258
5368
|
Math.max(1, cols - 1)
|
|
5259
5369
|
),
|
|
5260
5370
|
""
|
|
@@ -5288,7 +5398,7 @@ var STATUS_ICON = {
|
|
|
5288
5398
|
var inRow = (label) => label.charAt(0).toLowerCase() + label.slice(1);
|
|
5289
5399
|
function planLayout(state, rows, cols) {
|
|
5290
5400
|
const done = state.tasks.filter((t) => t.status === "completed").length;
|
|
5291
|
-
const totalUsage = (0,
|
|
5401
|
+
const totalUsage = (0, import_core32.planUsage)(state.tasks);
|
|
5292
5402
|
const unmerged = state.runMerge?.handoff.landed.length ?? 0;
|
|
5293
5403
|
const count = `${done}/${state.tasks.length}`;
|
|
5294
5404
|
const hints = runHints(state);
|
|
@@ -5366,7 +5476,7 @@ function planScrollExtent(state) {
|
|
|
5366
5476
|
}
|
|
5367
5477
|
function taskLines(state, planRow, index, cols) {
|
|
5368
5478
|
const { task, parent } = planRow;
|
|
5369
|
-
const row = (0,
|
|
5479
|
+
const row = (0, import_core32.taskRowView)(task, { parent, tasks: state.tasks, modes: modesForTask(state.modesByRunner, task) });
|
|
5370
5480
|
const selected = state.focus === "plan" && index === state.selectedTask;
|
|
5371
5481
|
const expanded = state.expandedTaskId === task.id;
|
|
5372
5482
|
const rawIcon = row.status === "running" ? SPINNER[state.spinnerFrame % SPINNER.length] : STATUS_ICON[row.status];
|
|
@@ -5417,10 +5527,10 @@ function taskLines(state, planRow, index, cols) {
|
|
|
5417
5527
|
lines.push(style.yellow(truncate(`${bodyPad}\u23F8 waits for Merge all \u2014 ${row.mergeGate.join(", ")} not merged into your branch yet`, cols)));
|
|
5418
5528
|
}
|
|
5419
5529
|
if (row.blockedBy) {
|
|
5420
|
-
lines.push(style.red(truncate(`${bodyPad}\u2298 ${inRow((0,
|
|
5530
|
+
lines.push(style.red(truncate(`${bodyPad}\u2298 ${inRow((0, import_core32.blockedByLabel)(row.blockedBy))} \u2014 runs once ${row.blockedBy.length === 1 ? "it is retried and passes" : "they are retried and pass"}`, cols)));
|
|
5421
5531
|
}
|
|
5422
5532
|
if (row.status === "skipped") {
|
|
5423
|
-
lines.push(style.grey(truncate(`${bodyPad}\xBB ${inRow((0,
|
|
5533
|
+
lines.push(style.grey(truncate(`${bodyPad}\xBB ${inRow((0, import_core32.skippedLabel)(row.skipReason))} \u2014 nothing of it landed; m done lands its kept work`, cols)));
|
|
5424
5534
|
}
|
|
5425
5535
|
const resumable = row.actions.includes("resume-now");
|
|
5426
5536
|
if (row.resumes) {
|
|
@@ -5555,8 +5665,8 @@ function helpScrollMax(state) {
|
|
|
5555
5665
|
}
|
|
5556
5666
|
|
|
5557
5667
|
// src/tui/render.ts
|
|
5558
|
-
var
|
|
5559
|
-
var
|
|
5668
|
+
var import_core33 = require("@ordewell/core");
|
|
5669
|
+
var import_core34 = require("@ordewell/core");
|
|
5560
5670
|
function render(state) {
|
|
5561
5671
|
const { rows, cols } = state;
|
|
5562
5672
|
const rowsForBody = bodyRows(state);
|
|
@@ -5655,8 +5765,8 @@ function runSettingsBadge(state) {
|
|
|
5655
5765
|
const { supervisorLevel, mergeAtGatesAutomatically, autorun } = state.runSettings;
|
|
5656
5766
|
const paint = (text, warn) => warn ? style.yellow(text) : style.grey(text);
|
|
5657
5767
|
const run = state.status === "executing" ? state.runSupervisor : null;
|
|
5658
|
-
const actual = run?.unsupervised ? "unsupervised" : run && run.level !== supervisorLevel ?
|
|
5659
|
-
const level = `supervisor ${
|
|
5768
|
+
const actual = run?.unsupervised ? "unsupervised" : run && run.level !== supervisorLevel ? import_core34.SUPERVISOR_LEVEL_LABEL[run.level] : null;
|
|
5769
|
+
const level = `supervisor ${import_core34.SUPERVISOR_LEVEL_LABEL[supervisorLevel]}${actual ? ` \u2192 ${actual}` : ""}`;
|
|
5660
5770
|
return [
|
|
5661
5771
|
paint(level, supervisorLevel === "act"),
|
|
5662
5772
|
...mergeAtGatesAutomatically ? [style.grey("auto-merge")] : [],
|
|
@@ -5853,8 +5963,8 @@ function renderHandoff(state, overlay, rows, cols) {
|
|
|
5853
5963
|
return frame(`Diff \u2014 ${handoffBranch(handoff)}`, [...shown, "", style.grey(`${more}enter or esc goes back`)], rows, cols);
|
|
5854
5964
|
}
|
|
5855
5965
|
const landed = handoff.landed.length === 0 ? [style.grey("Nothing landed on it.")] : handoff.landed.map((task) => {
|
|
5856
|
-
const repaired = task.repairedFiles?.length ? style.yellow(` \u2014 repaired (${(0,
|
|
5857
|
-
return ` ${style.green("\u2713")} ${(0,
|
|
5966
|
+
const repaired = task.repairedFiles?.length ? style.yellow(` \u2014 repaired (${(0, import_core33.capConflictFiles)(task.repairedFiles)})`) : "";
|
|
5967
|
+
return ` ${style.green("\u2713")} ${(0, import_core33.titledTaskRefOf)(state.tasks, task.taskId) ?? (0, import_core33.titledTaskRef)(task)}${repaired}`;
|
|
5858
5968
|
});
|
|
5859
5969
|
const actions = handoffActions(handoff).map((action, index) => {
|
|
5860
5970
|
const active = index === overlay.index;
|
|
@@ -5902,8 +6012,8 @@ function renderPicker(picker2, rows, cols) {
|
|
|
5902
6012
|
...picker2.filterable ? [["type", "to filter"]] : []
|
|
5903
6013
|
]);
|
|
5904
6014
|
const room = Math.max(1, rows - head.length - 3);
|
|
5905
|
-
const
|
|
5906
|
-
return frame(picker2.title, [...head, ...
|
|
6015
|
+
const list2 = items.length === 0 ? [style.grey(picker2.filter ? "Nothing matches that filter." : "Nothing to show yet\u2026")] : pickerRows({ items, index: picker2.index, numbered: !picker2.filterable, chosen: picker2.multi ? picker2.chosen : void 0 }, room, inner);
|
|
6016
|
+
return frame(picker2.title, [...head, ...list2, "", footer], rows, cols);
|
|
5907
6017
|
}
|
|
5908
6018
|
function renderStepper(stepper, rows, cols) {
|
|
5909
6019
|
const { definition, trail } = stepper;
|
|
@@ -5934,13 +6044,13 @@ function renderStepper(stepper, rows, cols) {
|
|
|
5934
6044
|
cancel
|
|
5935
6045
|
]);
|
|
5936
6046
|
const room = Math.max(1, rows - head.length - 3);
|
|
5937
|
-
const
|
|
5938
|
-
return frame(definition.title, [...head, ...
|
|
6047
|
+
const list2 = items.length === 0 ? [style.grey(stepper.filter ? "Nothing matches that filter." : "Nothing to show yet\u2026")] : pickerRows({ items, index: stepper.index, numbered: !active.filterable }, room, inner);
|
|
6048
|
+
return frame(definition.title, [...head, ...list2, "", footer], rows, cols);
|
|
5939
6049
|
}
|
|
5940
6050
|
var DETAIL_GAP = 2;
|
|
5941
|
-
function pickerRows(
|
|
5942
|
-
const { items, numbered, chosen } =
|
|
5943
|
-
const index = Math.max(0, Math.min(
|
|
6051
|
+
function pickerRows(list2, room, inner) {
|
|
6052
|
+
const { items, numbered, chosen } = list2;
|
|
6053
|
+
const index = Math.max(0, Math.min(list2.index, items.length - 1));
|
|
5944
6054
|
const digits = String(items.length).length;
|
|
5945
6055
|
const prefixWidth = 2 + (numbered ? digits + 2 : 0) + (chosen ? 4 : 0);
|
|
5946
6056
|
const rowWidth = Math.max(1, inner - prefixWidth);
|
|
@@ -5949,7 +6059,7 @@ function pickerRows(list, room, inner) {
|
|
|
5949
6059
|
const labelWidth = items.some((item) => item.detail) ? Math.min(widest, Math.max(8, rowWidth - DETAIL_GAP - Math.max(16, Math.floor(rowWidth / 3)))) : Math.min(widest, rowWidth);
|
|
5950
6060
|
const detailWidth = Math.max(1, rowWidth - labelWidth - DETAIL_GAP);
|
|
5951
6061
|
const detailIndent = " ".repeat(prefixWidth + labelWidth + DETAIL_GAP);
|
|
5952
|
-
const
|
|
6062
|
+
const block2 = (item, i) => {
|
|
5953
6063
|
const active = i === index;
|
|
5954
6064
|
const current = isCurrent(item);
|
|
5955
6065
|
const number = numbered ? `${String(i + 1).padStart(digits)}. ` : "";
|
|
@@ -5966,29 +6076,29 @@ function pickerRows(list, room, inner) {
|
|
|
5966
6076
|
];
|
|
5967
6077
|
return active ? lines.map((line) => style.highlight(pad(line, inner))) : lines;
|
|
5968
6078
|
};
|
|
5969
|
-
const
|
|
5970
|
-
if (
|
|
6079
|
+
const blocks2 = items.map(block2);
|
|
6080
|
+
if (blocks2.reduce((n, b) => n + b.length, 0) <= room) return blocks2.flat();
|
|
5971
6081
|
const fit2 = Math.max(1, room - 2);
|
|
5972
6082
|
let lo = index;
|
|
5973
6083
|
let hi = index;
|
|
5974
|
-
let used =
|
|
6084
|
+
let used = blocks2[index].length;
|
|
5975
6085
|
for (let grew = true; grew; ) {
|
|
5976
6086
|
grew = false;
|
|
5977
|
-
if (hi + 1 <
|
|
6087
|
+
if (hi + 1 < blocks2.length && used + blocks2[hi + 1].length <= fit2) {
|
|
5978
6088
|
hi += 1;
|
|
5979
|
-
used +=
|
|
6089
|
+
used += blocks2[hi].length;
|
|
5980
6090
|
grew = true;
|
|
5981
6091
|
}
|
|
5982
|
-
if (lo > 0 && used +
|
|
6092
|
+
if (lo > 0 && used + blocks2[lo - 1].length <= fit2) {
|
|
5983
6093
|
lo -= 1;
|
|
5984
|
-
used +=
|
|
6094
|
+
used += blocks2[lo].length;
|
|
5985
6095
|
grew = true;
|
|
5986
6096
|
}
|
|
5987
6097
|
}
|
|
5988
6098
|
return [
|
|
5989
6099
|
...lo > 0 ? [style.grey(` \u2191 \u2026 +${lo} more`)] : [],
|
|
5990
|
-
...
|
|
5991
|
-
...hi <
|
|
6100
|
+
...blocks2.slice(lo, hi + 1).flat().slice(0, fit2),
|
|
6101
|
+
...hi < blocks2.length - 1 ? [style.grey(` \u2193 \u2026 +${blocks2.length - 1 - hi} more`)] : []
|
|
5992
6102
|
];
|
|
5993
6103
|
}
|
|
5994
6104
|
function keyHints(hints) {
|
|
@@ -6028,7 +6138,10 @@ function frame(title, body, rows, cols) {
|
|
|
6028
6138
|
}
|
|
6029
6139
|
|
|
6030
6140
|
// src/tui/reducer.ts
|
|
6031
|
-
var
|
|
6141
|
+
var import_core46 = require("@ordewell/core");
|
|
6142
|
+
|
|
6143
|
+
// src/tui/reducers/overlays.ts
|
|
6144
|
+
var import_core45 = require("@ordewell/core");
|
|
6032
6145
|
|
|
6033
6146
|
// src/tui/reducers/shared.ts
|
|
6034
6147
|
function step(state, effects = []) {
|
|
@@ -6087,10 +6200,10 @@ function handleApprovalKey(state, overlay, key) {
|
|
|
6087
6200
|
}
|
|
6088
6201
|
|
|
6089
6202
|
// src/tui/reducers/commands.ts
|
|
6090
|
-
var
|
|
6203
|
+
var import_core44 = require("@ordewell/core");
|
|
6091
6204
|
|
|
6092
6205
|
// src/tui/reducers/plannerStepper.ts
|
|
6093
|
-
var
|
|
6206
|
+
var import_core35 = require("@ordewell/core");
|
|
6094
6207
|
var offered = (items) => new Set(items.filter((i) => !i.disabled).map((i) => i.id));
|
|
6095
6208
|
function preferredModel(state, provider) {
|
|
6096
6209
|
const listed = offered(plannerModelItems(state, provider, ""));
|
|
@@ -6138,7 +6251,7 @@ var plannerStepper = {
|
|
|
6138
6251
|
const model = plannerModelItems(state, provider, "").find((m) => m.id === modelId);
|
|
6139
6252
|
const level = plannerEffortItems(state, provider, modelId, "").find((e) => e.id === effort);
|
|
6140
6253
|
const parts = [
|
|
6141
|
-
|
|
6254
|
+
(0, import_core35.getProviderMeta)(provider)?.label ?? provider,
|
|
6142
6255
|
model?.label ?? modelId,
|
|
6143
6256
|
...effort ? [effortLabel(level?.label ?? effort)] : []
|
|
6144
6257
|
];
|
|
@@ -6153,10 +6266,10 @@ var plannerStepper = {
|
|
|
6153
6266
|
};
|
|
6154
6267
|
|
|
6155
6268
|
// src/tui/reducers/stepper.ts
|
|
6156
|
-
var
|
|
6269
|
+
var import_core36 = require("@ordewell/core");
|
|
6157
6270
|
function openStepper(state, definition) {
|
|
6158
6271
|
const { choices, lists } = settle(state, definition, {});
|
|
6159
|
-
const first = lists.findIndex((
|
|
6272
|
+
const first = lists.findIndex((list2) => list2 !== null);
|
|
6160
6273
|
if (first === -1) return definition.save(state, choices);
|
|
6161
6274
|
return step({ ...state, overlay: { kind: "stepper", stepper: show2(state, definition, choices, first) } });
|
|
6162
6275
|
}
|
|
@@ -6176,11 +6289,11 @@ function handleStepperKey(state, stepper, key) {
|
|
|
6176
6289
|
const reopen = (next) => step({ ...state, overlay: { kind: "stepper", stepper: next } });
|
|
6177
6290
|
const { definition, current, entry, choices } = stepper;
|
|
6178
6291
|
const def = definition.steps[current];
|
|
6179
|
-
const typed = def.number && entry ? (0,
|
|
6292
|
+
const typed = def.number && entry ? (0, import_core36.parseCount)(entry.text, def.number.min) : null;
|
|
6180
6293
|
const { lists } = settle(state, definition, choices);
|
|
6181
6294
|
const items = matchingItems(stepper.items, stepper.filter);
|
|
6182
6295
|
const before = lastIndexBefore(lists, current);
|
|
6183
|
-
const after = lists.findIndex((
|
|
6296
|
+
const after = lists.findIndex((list2, i) => i > current && list2 !== null);
|
|
6184
6297
|
if (key.name === "escape") return step({ ...state, overlay: null });
|
|
6185
6298
|
if (key.name === "tab" || key.name === "right") return after === -1 ? reopen(stepper) : reopen(show2(state, definition, choices, after));
|
|
6186
6299
|
if (key.name === "shift-tab" || key.name === "left") return before === -1 ? reopen(stepper) : reopen(show2(state, definition, choices, before));
|
|
@@ -6226,14 +6339,14 @@ function choose(state, stepper, value) {
|
|
|
6226
6339
|
const saved = definition.save(open, choices);
|
|
6227
6340
|
if (saved.state.overlay !== open.overlay) return saved;
|
|
6228
6341
|
const { lists } = settle(saved.state, definition, choices);
|
|
6229
|
-
const next = !definition.advanceOnEnter ? current : lists.findIndex((
|
|
6342
|
+
const next = !definition.advanceOnEnter ? current : lists.findIndex((list2, i) => i > current && list2 !== null);
|
|
6230
6343
|
if (next === -1 || lists[next] === null) return { ...saved, state: { ...saved.state, overlay: null } };
|
|
6231
6344
|
return { ...saved, state: { ...saved.state, overlay: { kind: "stepper", stepper: show2(saved.state, definition, choices, next) } } };
|
|
6232
6345
|
}
|
|
6233
6346
|
function reopenStepper(state, stepper) {
|
|
6234
6347
|
const { definition, current } = stepper;
|
|
6235
6348
|
const { lists } = settle(state, definition, {});
|
|
6236
|
-
const at = lists[current] !== null ? current : lists.findIndex((
|
|
6349
|
+
const at = lists[current] !== null ? current : lists.findIndex((list2) => list2 !== null);
|
|
6237
6350
|
if (at === -1) return { ...state, overlay: null };
|
|
6238
6351
|
return { ...state, overlay: { kind: "stepper", stepper: show2(state, definition, {}, at) } };
|
|
6239
6352
|
}
|
|
@@ -6242,7 +6355,7 @@ function settle(state, definition, wanted) {
|
|
|
6242
6355
|
const lists = definition.steps.map((def) => {
|
|
6243
6356
|
if (def.skip?.(state, { ...choices })) return null;
|
|
6244
6357
|
if (def.number) {
|
|
6245
|
-
choices[def.id] = String((0,
|
|
6358
|
+
choices[def.id] = String((0, import_core36.parseCount)(wanted[def.id], def.number.min) ?? def.number.current(state, { ...choices }));
|
|
6246
6359
|
return [];
|
|
6247
6360
|
}
|
|
6248
6361
|
const items = def.items(state, { ...choices });
|
|
@@ -6256,10 +6369,10 @@ function settle(state, definition, wanted) {
|
|
|
6256
6369
|
function show2(state, definition, wanted, current) {
|
|
6257
6370
|
const { choices, lists } = settle(state, definition, wanted);
|
|
6258
6371
|
const items = lists[current] ?? [];
|
|
6259
|
-
const trail = lists.flatMap((
|
|
6260
|
-
if (
|
|
6372
|
+
const trail = lists.flatMap((list2, i) => {
|
|
6373
|
+
if (list2 === null) return [];
|
|
6261
6374
|
const def2 = definition.steps[i];
|
|
6262
|
-
const value = i >= current ? void 0 : def2.number ? choices[def2.id] :
|
|
6375
|
+
const value = i >= current ? void 0 : def2.number ? choices[def2.id] : list2.find((item) => item.id === choices[def2.id])?.label;
|
|
6263
6376
|
return [{ label: def2.label, active: i === current, ...value !== void 0 ? { value } : {} }];
|
|
6264
6377
|
});
|
|
6265
6378
|
const def = definition.steps[current];
|
|
@@ -6281,7 +6394,7 @@ function lastIndexBefore(lists, index) {
|
|
|
6281
6394
|
}
|
|
6282
6395
|
|
|
6283
6396
|
// src/tui/reducers/planPane.ts
|
|
6284
|
-
var
|
|
6397
|
+
var import_core39 = require("@ordewell/core");
|
|
6285
6398
|
|
|
6286
6399
|
// src/tui/reducers/pointer.ts
|
|
6287
6400
|
var WHEEL_NOTCH = 3;
|
|
@@ -6359,13 +6472,13 @@ function handleMouseSelect(state, key) {
|
|
|
6359
6472
|
}
|
|
6360
6473
|
|
|
6361
6474
|
// src/tui/reducers/taskView.ts
|
|
6362
|
-
var
|
|
6475
|
+
var import_core37 = require("@ordewell/core");
|
|
6363
6476
|
function openTaskView(state, sessionId, taskId) {
|
|
6364
6477
|
const task = findTask(state.tasks, taskId);
|
|
6365
6478
|
if (!task) return step(say(state, "system", `No task ${taskId} in this plan.`));
|
|
6366
6479
|
const taskView = {
|
|
6367
6480
|
taskId,
|
|
6368
|
-
view:
|
|
6481
|
+
view: import_core37.EMPTY_TASK_LOG,
|
|
6369
6482
|
attempts: [],
|
|
6370
6483
|
attempt: 0,
|
|
6371
6484
|
pending: [],
|
|
@@ -6395,13 +6508,13 @@ function applyLive(tv, attempt, events) {
|
|
|
6395
6508
|
}
|
|
6396
6509
|
next = {
|
|
6397
6510
|
...next,
|
|
6398
|
-
view:
|
|
6511
|
+
view: import_core37.EMPTY_TASK_LOG,
|
|
6399
6512
|
attempt,
|
|
6400
6513
|
attempts: next.attempts.includes(attempt) ? next.attempts : [...next.attempts, attempt]
|
|
6401
6514
|
};
|
|
6402
6515
|
}
|
|
6403
6516
|
if (attempt < next.attempt) return next;
|
|
6404
|
-
return clampQueueIndex({ ...next, view: events.reduce(
|
|
6517
|
+
return clampQueueIndex({ ...next, view: events.reduce(import_core37.reduceTaskLog, next.view) });
|
|
6405
6518
|
}
|
|
6406
6519
|
function taskLogAbandoned(state) {
|
|
6407
6520
|
const tv = state.taskView;
|
|
@@ -6422,14 +6535,14 @@ function announceApprovals(state, action) {
|
|
|
6422
6535
|
if (state.taskView?.taskId === action.taskId) return state;
|
|
6423
6536
|
const task = findTask(state.tasks, action.taskId);
|
|
6424
6537
|
const way = task ? `tab to the plan, select task ${task.order} and press enter (or /open ${task.order})` : "tab to the plan, select it and press enter";
|
|
6425
|
-
const spoken = action.events.reduce((s, event) => event.type === "approval_requested" && !event.decided ? say(s, "system", `Task ${task?.order ?? "?"} waits for approval: ${(0,
|
|
6538
|
+
const spoken = action.events.reduce((s, event) => event.type === "approval_requested" && !event.decided ? say(s, "system", `Task ${task?.order ?? "?"} waits for approval: ${(0, import_core37.runnerToolSubject)(event.tool, event.args)} \u2014 ${way}, then ctrl-y allows or ctrl-g denies`) : s, state);
|
|
6426
6539
|
return spoken !== state ? { ...spoken, scroll: state.scroll } : spoken;
|
|
6427
6540
|
}
|
|
6428
6541
|
function announceCheckpoint(state, action) {
|
|
6429
6542
|
const task = findTask(state.tasks, action.taskId) ?? state.tasks.find((t) => t.title === action.title);
|
|
6430
6543
|
const label = task ? `Task ${task.order}` : action.title;
|
|
6431
6544
|
const where = task ? `tab to the plan, select task ${task.order} and press enter (or /open ${task.order}) to answer` : "tab to the plan, select it and press enter to answer";
|
|
6432
|
-
const spoken = say(state, "system", `${label} asks: ${(0,
|
|
6545
|
+
const spoken = say(state, "system", `${label} asks: ${(0, import_core37.truncateCheckpointSummary)(action.summary)} \u2014 ${where}`);
|
|
6433
6546
|
return { ...spoken, scroll: state.scroll };
|
|
6434
6547
|
}
|
|
6435
6548
|
function taskLogLoaded(state, action) {
|
|
@@ -6437,7 +6550,7 @@ function taskLogLoaded(state, action) {
|
|
|
6437
6550
|
if (!tv || tv.taskId !== action.taskId) return state;
|
|
6438
6551
|
const loaded = action.attempt >= 1 ? {
|
|
6439
6552
|
...tv,
|
|
6440
|
-
view: (0,
|
|
6553
|
+
view: (0, import_core37.replayTaskLog)(action.events),
|
|
6441
6554
|
attempts: action.attempts ?? tv.attempts,
|
|
6442
6555
|
attempt: action.attempt
|
|
6443
6556
|
} : { ...tv, attempts: action.attempts ?? tv.attempts };
|
|
@@ -6511,7 +6624,7 @@ function handleTaskViewKey(state, key) {
|
|
|
6511
6624
|
if (key.name === "ctrl-s") return sendNow(state, tv, state.sessionId);
|
|
6512
6625
|
if (key.name === "ctrl-x") {
|
|
6513
6626
|
const task = findTask(state.tasks, tv.taskId);
|
|
6514
|
-
if (task && (0,
|
|
6627
|
+
if (task && (0, import_core37.resumeLabel)(task)) return step(state, [{ type: "taskAction", sessionId: state.sessionId, taskId: tv.taskId, action: "cancel-resume" }]);
|
|
6515
6628
|
return step(state, [{ type: "interruptTask", sessionId: state.sessionId, taskId: tv.taskId }]);
|
|
6516
6629
|
}
|
|
6517
6630
|
if (key.name === "ctrl-y") return answerWaiting(state, tv, state.sessionId, "allow");
|
|
@@ -6529,7 +6642,7 @@ function handleTaskViewKey(state, key) {
|
|
|
6529
6642
|
}
|
|
6530
6643
|
|
|
6531
6644
|
// src/tui/reducers/taskEdits.ts
|
|
6532
|
-
var
|
|
6645
|
+
var import_core38 = require("@ordewell/core");
|
|
6533
6646
|
var import_plan_utils3 = require("@ordewell/core/plan-utils");
|
|
6534
6647
|
function openTaskRunnerPicker(state, task) {
|
|
6535
6648
|
if (task.type !== "ai") return fail3(state, "Manual tasks do not run on an executor, so they have no runner.");
|
|
@@ -6640,7 +6753,7 @@ function openTaskModePicker(state, task) {
|
|
|
6640
6753
|
overlay: {
|
|
6641
6754
|
kind: "picker",
|
|
6642
6755
|
picker: picker(`Mode \xB7 ${refFor(state, task)}`, pickerItemsFor(state, action), action, {
|
|
6643
|
-
hint: [`Modes declared by ${task.assignedRunner}.`, (0,
|
|
6756
|
+
hint: [`Modes declared by ${task.assignedRunner}.`, (0, import_core38.codexSandboxNotice)(state.modesByRunner)?.line].filter(Boolean).join(" ")
|
|
6644
6757
|
})
|
|
6645
6758
|
}
|
|
6646
6759
|
}
|
|
@@ -6868,11 +6981,11 @@ function handlePlanKey(state, key) {
|
|
|
6868
6981
|
if (!state.sessionId || key.name !== "char") return step(state);
|
|
6869
6982
|
if (key.char === "E") return step(state, [{ type: "execute", sessionId: state.sessionId }]);
|
|
6870
6983
|
if (key.char === "S") return step(state, [{ type: "stopExecution", sessionId: state.sessionId }]);
|
|
6871
|
-
const shortcut = key.char === "c" && (0,
|
|
6984
|
+
const shortcut = key.char === "c" && (0, import_core39.resumeLabel)(task) ? "cancel-resume" : PLAN_SHORTCUTS[key.char ?? ""];
|
|
6872
6985
|
if (key.char === "r") {
|
|
6873
|
-
return (0,
|
|
6986
|
+
return (0, import_core39.taskRowActions)(task).includes("resume-now") ? step(state, [taskActionEffect(state, state.sessionId, task.id, "resume-now")]) : step(state);
|
|
6874
6987
|
}
|
|
6875
|
-
const action = key.char === "m" ? (0,
|
|
6988
|
+
const action = key.char === "m" ? (0, import_core39.markAction)(task) : shortcut;
|
|
6876
6989
|
if (action === "force-start" && task.mergeGate?.length) return confirmForceStartPastGate(state, task);
|
|
6877
6990
|
if (action) {
|
|
6878
6991
|
return step(state, [taskActionEffect(state, state.sessionId, task.id, action)]);
|
|
@@ -6912,9 +7025,9 @@ function commitTaskEdit(state, task, editor) {
|
|
|
6912
7025
|
}
|
|
6913
7026
|
|
|
6914
7027
|
// src/tui/reducers/turnQueue.ts
|
|
6915
|
-
var
|
|
7028
|
+
var import_core40 = require("@ordewell/core");
|
|
6916
7029
|
function drainQueue(state, settled) {
|
|
6917
|
-
const next = (0,
|
|
7030
|
+
const next = (0, import_core40.drainNext)(state.queuedPrompts);
|
|
6918
7031
|
const ended = disarmStop({ ...settled, stopRequested: false, forceSendPending: null });
|
|
6919
7032
|
if (!next) return step(ended);
|
|
6920
7033
|
const spoken = say(ended, "user", next.text);
|
|
@@ -6929,7 +7042,7 @@ function restoreForced(state) {
|
|
|
6929
7042
|
if (!forced) return state;
|
|
6930
7043
|
const cleared = { ...state, forceSendPending: null };
|
|
6931
7044
|
if (forced.queueIndex === void 0) {
|
|
6932
|
-
const text = (0,
|
|
7045
|
+
const text = (0, import_core40.aheadOfDraft)(forced.text, state.editor.text);
|
|
6933
7046
|
return { ...cleared, editor: { ...state.editor, text, cursor: text.length } };
|
|
6934
7047
|
}
|
|
6935
7048
|
const queued = [...state.queuedPrompts];
|
|
@@ -6945,14 +7058,14 @@ function stopPlanning(state, sessionId) {
|
|
|
6945
7058
|
return step(queueToEditor(cutTurn({ ...dismissed, stopArmed: false, stopRequested: true, forceSendPending: null })), [{ type: "cancelPlanning", sessionId }]);
|
|
6946
7059
|
}
|
|
6947
7060
|
function queueToEditor(state) {
|
|
6948
|
-
const all = (0,
|
|
7061
|
+
const all = (0, import_core40.unsendAll)(state.queuedPrompts);
|
|
6949
7062
|
if (!all) return state;
|
|
6950
7063
|
return { ...state, queuedPrompts: all.rest, editor: { ...state.editor, text: all.text, cursor: all.text.length } };
|
|
6951
7064
|
}
|
|
6952
7065
|
function unsendLatest(state) {
|
|
6953
|
-
const latest = (0,
|
|
7066
|
+
const latest = (0, import_core40.unsendLatest)(state.queuedPrompts);
|
|
6954
7067
|
if (!latest) return step(state);
|
|
6955
|
-
const text = (0,
|
|
7068
|
+
const text = (0, import_core40.aheadOfDraft)(latest.text, state.editor.text);
|
|
6956
7069
|
return step({
|
|
6957
7070
|
...state,
|
|
6958
7071
|
queuedPrompts: latest.rest,
|
|
@@ -6968,7 +7081,7 @@ function forceSendPlanner(state) {
|
|
|
6968
7081
|
{ type: "forceSendPlannerMessage", sessionId: state.sessionId, message: text }
|
|
6969
7082
|
]);
|
|
6970
7083
|
}
|
|
6971
|
-
const latest = (0,
|
|
7084
|
+
const latest = (0, import_core40.unsendLatest)(state.queuedPrompts);
|
|
6972
7085
|
if (!latest) return step(say(state, "system", "Nothing to send now: type a message, or queue one with enter."));
|
|
6973
7086
|
const forced = { text: latest.text, queueIndex: latest.rest.length };
|
|
6974
7087
|
return step({ ...state, queuedPrompts: latest.rest, stopRequested: false, forceSendPending: forced }, [
|
|
@@ -6984,7 +7097,7 @@ function plannerEscape(state) {
|
|
|
6984
7097
|
}
|
|
6985
7098
|
|
|
6986
7099
|
// src/tui/reducers/incoming.ts
|
|
6987
|
-
var
|
|
7100
|
+
var import_core41 = require("@ordewell/core");
|
|
6988
7101
|
var planText = (value, fallback = "") => sanitize(String(value ?? fallback));
|
|
6989
7102
|
var planLabel = (value, fallback = "") => planText(value, fallback).replace(/\n+/g, " ");
|
|
6990
7103
|
var asRecord = (value) => typeof value === "object" && value !== null ? value : {};
|
|
@@ -7023,7 +7136,7 @@ function runTaskToView(t) {
|
|
|
7023
7136
|
...Array.isArray(model.availableVariants) ? { availableVariants: model.availableVariants.map((variant) => planLabel(variant)) } : {}
|
|
7024
7137
|
} : void 0,
|
|
7025
7138
|
isolation: t.isolation,
|
|
7026
|
-
awaitingReason: t.status === "awaiting_user" && (0,
|
|
7139
|
+
awaitingReason: t.status === "awaiting_user" && (0, import_core41.isAwaitingReason)(t.awaitingReason) ? t.awaitingReason : void 0,
|
|
7027
7140
|
...t.status === "awaiting_user" && t.awaitingReason === "usage-limit" && typeof t.resumeAt === "string" ? { resumeAt: t.resumeAt } : {},
|
|
7028
7141
|
...t.status === "skipped" && typeof t.skipReason === "string" ? { skipReason: sanitize(t.skipReason) } : {},
|
|
7029
7142
|
checkpoint: typeof t.checkpoint === "string" ? sanitize(t.checkpoint) : void 0,
|
|
@@ -7042,7 +7155,7 @@ function supervisorOfRun(runSettings) {
|
|
|
7042
7155
|
const unsupervised = typeof runSettings.unsupervised === "string" ? runSettings.unsupervised : void 0;
|
|
7043
7156
|
return {
|
|
7044
7157
|
runSupervisor: {
|
|
7045
|
-
level: (0,
|
|
7158
|
+
level: (0, import_core41.isSupervisorLevel)(runSettings.supervisorLevel) ? runSettings.supervisorLevel : "off",
|
|
7046
7159
|
...unsupervised ? { unsupervised } : {}
|
|
7047
7160
|
}
|
|
7048
7161
|
};
|
|
@@ -7059,7 +7172,7 @@ function withRun(state, run) {
|
|
|
7059
7172
|
};
|
|
7060
7173
|
}
|
|
7061
7174
|
function foldRun(state, input) {
|
|
7062
|
-
const run = (0,
|
|
7175
|
+
const run = (0, import_core41.reduceRun)(state.run, input);
|
|
7063
7176
|
return run === state.run ? state : withRun(state, run);
|
|
7064
7177
|
}
|
|
7065
7178
|
function mapRunTasks(tasks, map) {
|
|
@@ -7107,21 +7220,21 @@ function followSession(state, message) {
|
|
|
7107
7220
|
}
|
|
7108
7221
|
|
|
7109
7222
|
// src/tui/reducers/runSettings.ts
|
|
7110
|
-
var
|
|
7223
|
+
var import_core42 = require("@ordewell/core");
|
|
7111
7224
|
function runSettingsEffect(state, changes) {
|
|
7112
7225
|
return { type: "setRunSettings", changes, ...state.sessionId ? { sessionId: state.sessionId } : {} };
|
|
7113
7226
|
}
|
|
7114
7227
|
function supervisorCommand(state, args) {
|
|
7115
7228
|
const [arg, value] = args;
|
|
7116
7229
|
if (arg === void 0) {
|
|
7117
|
-
return step(say(state, "system", `${(0,
|
|
7230
|
+
return step(say(state, "system", `${(0, import_core42.supervisorSummary)(state.runSettings)} \u2014 /supervisor off|watch|act, /supervisor retries <n>, /supervisor reads <n>.`));
|
|
7118
7231
|
}
|
|
7119
7232
|
if (arg === "retries") {
|
|
7120
|
-
const n = (0,
|
|
7233
|
+
const n = (0, import_core42.parseCount)(value, 0);
|
|
7121
7234
|
return n === null ? fail3(state, "Usage: /supervisor retries <whole number, 0 or more>") : step(state, [runSettingsEffect(state, { supervisorRetryLimit: n })]);
|
|
7122
7235
|
}
|
|
7123
7236
|
if (arg === "reads") {
|
|
7124
|
-
const n = (0,
|
|
7237
|
+
const n = (0, import_core42.parseCount)(value, 1);
|
|
7125
7238
|
return n === null ? fail3(state, "Usage: /supervisor reads <whole number, 1 or more>") : step(state, [runSettingsEffect(state, { wakeUpReadBudget: n })]);
|
|
7126
7239
|
}
|
|
7127
7240
|
if (arg === "act") return confirmSupervisorAct(state);
|
|
@@ -7130,17 +7243,17 @@ function supervisorCommand(state, args) {
|
|
|
7130
7243
|
}
|
|
7131
7244
|
function automergeCommand(state, arg) {
|
|
7132
7245
|
if (arg === void 0) {
|
|
7133
|
-
return step(say(state, "system", `${(0,
|
|
7246
|
+
return step(say(state, "system", `${(0, import_core42.automergeSummary)(state.runSettings)} \u2014 /automerge on|off.`));
|
|
7134
7247
|
}
|
|
7135
|
-
const enabled = (0,
|
|
7248
|
+
const enabled = (0, import_core42.parseSwitch)(arg);
|
|
7136
7249
|
if (enabled === null) return fail3(state, "Usage: /automerge [on|off]");
|
|
7137
7250
|
return step(state, [runSettingsEffect(state, { mergeAtGatesAutomatically: enabled })]);
|
|
7138
7251
|
}
|
|
7139
7252
|
function autorunCommand(state, arg) {
|
|
7140
7253
|
if (arg === void 0) {
|
|
7141
|
-
return step(say(state, "system", `${(0,
|
|
7254
|
+
return step(say(state, "system", `${(0, import_core42.autorunSummary)(state.runSettings)} \u2014 /autorun on starts each plan the planner submits, without review.`));
|
|
7142
7255
|
}
|
|
7143
|
-
const enabled = (0,
|
|
7256
|
+
const enabled = (0, import_core42.parseSwitch)(arg);
|
|
7144
7257
|
if (enabled === null) return fail3(state, "Usage: /autorun [on|off]");
|
|
7145
7258
|
if (enabled) return confirmAutorun(state);
|
|
7146
7259
|
return step(state, [runSettingsEffect(state, { autorun: false })]);
|
|
@@ -7152,7 +7265,7 @@ function confirmSupervisorAct(state) {
|
|
|
7152
7265
|
kind: "confirm",
|
|
7153
7266
|
title: "Let the supervisor act?",
|
|
7154
7267
|
message: "At Act the supervisor runs, stops and retries tasks, answers their requests (never allowing), edits the plan and merges, without asking you.",
|
|
7155
|
-
note: `${
|
|
7268
|
+
note: `${import_core42.ACT_RISK}
|
|
7156
7269
|
It applies to this session's run now, and to every later run.`,
|
|
7157
7270
|
action: { kind: "supervisor-act" }
|
|
7158
7271
|
}
|
|
@@ -7165,14 +7278,14 @@ function confirmAutorun(state) {
|
|
|
7165
7278
|
kind: "confirm",
|
|
7166
7279
|
title: "Start plans without review?",
|
|
7167
7280
|
message: "With autorun on, each plan the planner submits starts at once, as if you had pressed Execute. The planner still asks when something is unclear.",
|
|
7168
|
-
note:
|
|
7281
|
+
note: import_core42.AUTORUN_RISK,
|
|
7169
7282
|
action: { kind: "autorun-on" }
|
|
7170
7283
|
}
|
|
7171
7284
|
});
|
|
7172
7285
|
}
|
|
7173
7286
|
|
|
7174
7287
|
// src/tui/reducers/settings.ts
|
|
7175
|
-
var
|
|
7288
|
+
var import_core43 = require("@ordewell/core");
|
|
7176
7289
|
var SUPERVISOR_DETAIL = {
|
|
7177
7290
|
off: "The planner speaks only when you write",
|
|
7178
7291
|
watch: "The planner follows your runs and suggests what to do",
|
|
@@ -7197,7 +7310,7 @@ var SETTINGS = {
|
|
|
7197
7310
|
{
|
|
7198
7311
|
id: "guarded",
|
|
7199
7312
|
label: "Guarded",
|
|
7200
|
-
detail: [`New plans run tasks in each runner's safer mode`, (0,
|
|
7313
|
+
detail: [`New plans run tasks in each runner's safer mode`, (0, import_core43.codexSandboxNotice)(state.modesByRunner)?.line].filter(Boolean).join(" \xB7 "),
|
|
7201
7314
|
selected: !state.autonomous
|
|
7202
7315
|
}
|
|
7203
7316
|
]
|
|
@@ -7207,7 +7320,7 @@ var SETTINGS = {
|
|
|
7207
7320
|
label: "Supervisor",
|
|
7208
7321
|
items: (state) => ["off", "watch", "act"].map((level) => ({
|
|
7209
7322
|
id: level,
|
|
7210
|
-
label:
|
|
7323
|
+
label: import_core43.SUPERVISOR_LEVEL_LABEL[level],
|
|
7211
7324
|
detail: SUPERVISOR_DETAIL[level],
|
|
7212
7325
|
selected: state.runSettings.supervisorLevel === level
|
|
7213
7326
|
}))
|
|
@@ -7261,12 +7374,12 @@ function saveChoices(state, choices) {
|
|
|
7261
7374
|
const autonomous = choices.autonomy === "full";
|
|
7262
7375
|
if (autonomous !== state.autonomous) {
|
|
7263
7376
|
save2.autonomous = autonomous;
|
|
7264
|
-
changed.push(`Autonomy ${(0,
|
|
7377
|
+
changed.push(`Autonomy ${(0, import_core43.autonomyLevelLabel)(autonomous)}`);
|
|
7265
7378
|
}
|
|
7266
7379
|
const level = choices.supervisor;
|
|
7267
7380
|
if (level !== state.runSettings.supervisorLevel) {
|
|
7268
7381
|
run.supervisorLevel = level;
|
|
7269
|
-
changed.push(`Supervisor ${
|
|
7382
|
+
changed.push(`Supervisor ${import_core43.SUPERVISOR_LEVEL_LABEL[level]}`);
|
|
7270
7383
|
}
|
|
7271
7384
|
if (choices.retries !== void 0 && Number(choices.retries) !== state.runSettings.supervisorRetryLimit) {
|
|
7272
7385
|
run.supervisorRetryLimit = Number(choices.retries);
|
|
@@ -7293,7 +7406,7 @@ function saveChoices(state, choices) {
|
|
|
7293
7406
|
}
|
|
7294
7407
|
if (changed.length === 0) return step(state);
|
|
7295
7408
|
const effect = { ...save2, message: `Settings: ${changed.join(" \xB7 ")}` };
|
|
7296
|
-
const risks = [...run.supervisorLevel === "act" ? [
|
|
7409
|
+
const risks = [...run.supervisorLevel === "act" ? [import_core43.ACT_RISK] : [], ...run.autorun ? [import_core43.AUTORUN_RISK] : []];
|
|
7297
7410
|
if (risks.length === 0) return saveSettings(state, effect);
|
|
7298
7411
|
return step({
|
|
7299
7412
|
...state,
|
|
@@ -7322,7 +7435,6 @@ function saveSettings(state, effect) {
|
|
|
7322
7435
|
}
|
|
7323
7436
|
|
|
7324
7437
|
// src/tui/reducers/commands.ts
|
|
7325
|
-
var KNOWN_PROVIDERS = Object.keys(import_core42.ALL_PROVIDERS);
|
|
7326
7438
|
var unknownCommand = (state, name) => fail3(state, `Unknown command: /${name} \u2014 type /help to see what's available.`);
|
|
7327
7439
|
function runCommand(state, { name, args }) {
|
|
7328
7440
|
if (!findCommand(name)) return unknownCommand(state, name);
|
|
@@ -7485,8 +7597,8 @@ function newSession(state) {
|
|
|
7485
7597
|
goal: "",
|
|
7486
7598
|
taskView: null,
|
|
7487
7599
|
planApproved: false,
|
|
7488
|
-
conversation:
|
|
7489
|
-
turnGate:
|
|
7600
|
+
conversation: import_core44.EMPTY_CONVERSATION,
|
|
7601
|
+
turnGate: import_core44.NO_TURN,
|
|
7490
7602
|
selectedTask: 0,
|
|
7491
7603
|
expandedTaskId: null,
|
|
7492
7604
|
taskEditor: null,
|
|
@@ -7497,15 +7609,15 @@ function newSession(state) {
|
|
|
7497
7609
|
// Prompts belong to the session that raised them; the old planner is gone
|
|
7498
7610
|
// and its pending requests deny on their own timeout.
|
|
7499
7611
|
pendingApprovals: [],
|
|
7500
|
-
queuedPrompts:
|
|
7612
|
+
queuedPrompts: import_core44.EMPTY_HOLD,
|
|
7501
7613
|
stopArmed: false,
|
|
7502
7614
|
forceSendPending: null,
|
|
7503
7615
|
overlay: state.overlay?.kind === "approval" ? null : state.overlay
|
|
7504
|
-
},
|
|
7616
|
+
}, import_core44.EMPTY_RUN), closeEffects);
|
|
7505
7617
|
}
|
|
7506
7618
|
function setModel(state, args) {
|
|
7507
7619
|
if (args[0] === "set" && args[1]) {
|
|
7508
|
-
const runner = (0,
|
|
7620
|
+
const runner = (0, import_core44.runnerForProvider)(state.plannerProvider);
|
|
7509
7621
|
const known = runner ? modelsForRunner(state.models, runner) : [];
|
|
7510
7622
|
if (runner && known.length > 0 && !known.some((m) => m.id === args[1])) {
|
|
7511
7623
|
return fail3(state, `${args[1]} was not discovered for ${runner}.`);
|
|
@@ -7528,7 +7640,7 @@ function setModel(state, args) {
|
|
|
7528
7640
|
function setPlanner(state, args) {
|
|
7529
7641
|
if (args[0]) {
|
|
7530
7642
|
const id = args[0].toLowerCase();
|
|
7531
|
-
if (!
|
|
7643
|
+
if (!(0, import_core44.isPlannerBackend)(id)) {
|
|
7532
7644
|
return fail3(state, `Unknown planner: ${id}. Run /planner with no arguments to see the list.`);
|
|
7533
7645
|
}
|
|
7534
7646
|
return step(state, [{ type: "setPlanner", provider: id }]);
|
|
@@ -7560,7 +7672,7 @@ function setPlannerEffort(state, args) {
|
|
|
7560
7672
|
function setKey(state, args) {
|
|
7561
7673
|
if (args[0] === "set" && args[1]) {
|
|
7562
7674
|
const provider = args[1].toLowerCase();
|
|
7563
|
-
if (!
|
|
7675
|
+
if (!(0, import_core44.isApiProvider)(provider)) {
|
|
7564
7676
|
return fail3(state, `Unknown provider: ${provider}. Run /key with no arguments to see the list.`);
|
|
7565
7677
|
}
|
|
7566
7678
|
if (!args[2]) {
|
|
@@ -7571,16 +7683,16 @@ function setKey(state, args) {
|
|
|
7571
7683
|
}
|
|
7572
7684
|
return step(state, [{ type: "setApiKey", provider, key: args.slice(2).join(" ") }]);
|
|
7573
7685
|
}
|
|
7574
|
-
const items =
|
|
7686
|
+
const items = import_core44.PROVIDER_PRIORITY.map((id) => ({
|
|
7575
7687
|
id,
|
|
7576
|
-
label:
|
|
7577
|
-
detail:
|
|
7688
|
+
label: (0, import_core44.getProviderMeta)(id).label,
|
|
7689
|
+
detail: (0, import_core44.getProviderMeta)(id).apiKeyEnvVar,
|
|
7578
7690
|
selected: state.configuredProviders.includes(id)
|
|
7579
7691
|
}));
|
|
7580
7692
|
return step({ ...state, overlay: { kind: "picker", picker: picker("API provider key", items, { kind: "set-key" }) } });
|
|
7581
7693
|
}
|
|
7582
7694
|
function keyPrompt(provider) {
|
|
7583
|
-
const meta =
|
|
7695
|
+
const meta = (0, import_core44.getProviderMeta)(provider);
|
|
7584
7696
|
return {
|
|
7585
7697
|
kind: "prompt",
|
|
7586
7698
|
title: `${meta.label} API key`,
|
|
@@ -7657,13 +7769,13 @@ function runners(state, args) {
|
|
|
7657
7769
|
}
|
|
7658
7770
|
function setMaxParallel(state, arg) {
|
|
7659
7771
|
if (!arg) return step(say(state, "system", `Up to ${state.maxParallel} AI task${state.maxParallel === 1 ? "" : "s"} run at once \u2014 /parallel <n> changes it.`));
|
|
7660
|
-
const limit = (0,
|
|
7772
|
+
const limit = (0, import_core44.parseMaxParallel)(arg);
|
|
7661
7773
|
if (limit === null) return fail3(state, "Usage: /parallel [<number of tasks, 1 or more>]");
|
|
7662
7774
|
return step({ ...state, maxParallel: limit }, [{ type: "setMaxParallel", limit }]);
|
|
7663
7775
|
}
|
|
7664
7776
|
function setAutonomous(state, arg) {
|
|
7665
|
-
if (arg === void 0) return step(say(state, "system", `Autonomy level: ${(0,
|
|
7666
|
-
const enabled = (0,
|
|
7777
|
+
if (arg === void 0) return step(say(state, "system", `Autonomy level: ${(0, import_core44.autonomyLevelLabel)(state.autonomous)} \u2014 /auto full or /auto guarded changes it for new plans.`));
|
|
7778
|
+
const enabled = (0, import_core44.parseAutonomyLevel)(arg);
|
|
7667
7779
|
if (enabled === null) return fail3(state, "Usage: /auto [full|guarded]");
|
|
7668
7780
|
return step({ ...state, autonomous: enabled }, [{ type: "setAutonomous", enabled }]);
|
|
7669
7781
|
}
|
|
@@ -7872,7 +7984,7 @@ function choose2(state, picker2, item) {
|
|
|
7872
7984
|
case "delete-session":
|
|
7873
7985
|
return step(closed, [{ type: "deleteSession", sessionId: item.id }]);
|
|
7874
7986
|
case "set-key":
|
|
7875
|
-
return step({ ...state, overlay: keyPrompt(item.id) });
|
|
7987
|
+
return (0, import_core45.isApiProvider)(item.id) ? step({ ...state, overlay: keyPrompt(item.id) }) : step(closed);
|
|
7876
7988
|
case "choose-allowlist-runner": {
|
|
7877
7989
|
const action = { kind: "set-allowlist", runner: item.id };
|
|
7878
7990
|
const items = pickerItemsFor(state, action);
|
|
@@ -7948,7 +8060,7 @@ function reduceAction(state, action) {
|
|
|
7948
8060
|
// (`task-1`), so nothing of the last one's — a merge gate, a checkpoint, its
|
|
7949
8061
|
// tasks — may carry over into this.
|
|
7950
8062
|
case "sessionStarted":
|
|
7951
|
-
return step(withRun({ ...state, sessionId: action.sessionId, goal: action.goal, taskView: null },
|
|
8063
|
+
return step(withRun({ ...state, sessionId: action.sessionId, goal: action.goal, taskView: null }, import_core46.EMPTY_RUN));
|
|
7952
8064
|
// The daemon registers a session only once planning succeeds; when it does
|
|
7953
8065
|
// not, holding on to the id would send every next message to a session the
|
|
7954
8066
|
// server never had.
|
|
@@ -7959,18 +8071,18 @@ function reduceAction(state, action) {
|
|
|
7959
8071
|
goal: "",
|
|
7960
8072
|
taskView: null,
|
|
7961
8073
|
pendingApprovals: [],
|
|
7962
|
-
queuedPrompts:
|
|
8074
|
+
queuedPrompts: import_core46.EMPTY_HOLD,
|
|
7963
8075
|
stopArmed: false,
|
|
7964
8076
|
forceSendPending: null,
|
|
7965
8077
|
overlay: state.overlay?.kind === "approval" ? null : state.overlay
|
|
7966
|
-
},
|
|
8078
|
+
}, import_core46.EMPTY_RUN));
|
|
7967
8079
|
// Deleting the session on screen stops it in the daemon; a view left on it
|
|
7968
8080
|
// would answer every next message with a session-not-found.
|
|
7969
8081
|
case "sessionDeleted":
|
|
7970
8082
|
return action.sessionId === state.sessionId ? newSession(state) : step(state);
|
|
7971
8083
|
case "chatRestored":
|
|
7972
8084
|
if (stale(state, action.sessionId)) return step(state);
|
|
7973
|
-
return step({ ...state, conversation: (0,
|
|
8085
|
+
return step({ ...state, conversation: (0, import_core46.fromTranscript)(action.history, action.researchLog, action.plannerUsage, action.pendingTurns), scroll: 0 });
|
|
7974
8086
|
case "planUpdated": {
|
|
7975
8087
|
if (stale(state, action.sessionId)) return step(state);
|
|
7976
8088
|
const settled = { ...showPlan(state, action.plan), planner: "idle" };
|
|
@@ -8010,15 +8122,15 @@ function reduceAction(state, action) {
|
|
|
8010
8122
|
case "taskStarted": {
|
|
8011
8123
|
if (stale(state, action.sessionId)) return step(state);
|
|
8012
8124
|
const existing = findTask(state.tasks, action.taskId);
|
|
8013
|
-
if (existing && (0,
|
|
8125
|
+
if (existing && (0, import_core26.isTaskRunning)(existing)) return step(state);
|
|
8014
8126
|
const folded = foldRun(state, {
|
|
8015
8127
|
type: "task_started",
|
|
8016
8128
|
taskId: action.taskId,
|
|
8017
8129
|
order: action.order ?? 0,
|
|
8018
8130
|
title: action.title,
|
|
8019
|
-
runner: action.runner ??
|
|
8131
|
+
runner: action.runner ?? import_core46.DEFAULT_RUNNERS[0]
|
|
8020
8132
|
});
|
|
8021
|
-
const spoken = say(folded, "system", (0,
|
|
8133
|
+
const spoken = say(folded, "system", (0, import_core46.taskStartedNotice)(action.title, action.runner));
|
|
8022
8134
|
return step({ ...spoken, status: "executing" });
|
|
8023
8135
|
}
|
|
8024
8136
|
case "taskCheckpoint":
|
|
@@ -8064,7 +8176,7 @@ function reduceAction(state, action) {
|
|
|
8064
8176
|
completed: state.tasks.filter((t) => t.status === "completed").length,
|
|
8065
8177
|
total: state.tasks.length,
|
|
8066
8178
|
failed: state.tasks.filter((t) => t.status === "failed").length,
|
|
8067
|
-
blocked: (0,
|
|
8179
|
+
blocked: (0, import_core46.blockingFailures)(state.tasks).size,
|
|
8068
8180
|
skipped: state.tasks.filter((t) => t.status === "skipped").length
|
|
8069
8181
|
};
|
|
8070
8182
|
const failures = `${failed > 0 ? ` \xB7 ${failed} failed` : ""}${blocked ? ` \xB7 ${blocked} blocked` : ""}${skipped ? ` \xB7 ${skipped} skipped` : ""}`;
|
|
@@ -8128,11 +8240,11 @@ function reduceAction(state, action) {
|
|
|
8128
8240
|
planner: "idle",
|
|
8129
8241
|
planApproved: false,
|
|
8130
8242
|
pendingApprovals: [],
|
|
8131
|
-
queuedPrompts:
|
|
8243
|
+
queuedPrompts: import_core46.EMPTY_HOLD,
|
|
8132
8244
|
stopArmed: false,
|
|
8133
8245
|
forceSendPending: null,
|
|
8134
8246
|
overlay: state.overlay?.kind === "approval" ? null : state.overlay
|
|
8135
|
-
},
|
|
8247
|
+
}, import_core46.EMPTY_RUN));
|
|
8136
8248
|
// The rewound message comes back as a draft to edit and resend, so it lands
|
|
8137
8249
|
// as if just typed: history is not being browsed, and nothing is parked.
|
|
8138
8250
|
case "inputPrefilled":
|
|
@@ -8204,7 +8316,7 @@ function showPlan(state, plan) {
|
|
|
8204
8316
|
});
|
|
8205
8317
|
}
|
|
8206
8318
|
function runStatus(state, tasks) {
|
|
8207
|
-
if (tasks.some(
|
|
8319
|
+
if (tasks.some(import_core26.isTaskRunning)) return "executing";
|
|
8208
8320
|
if (tasks.some((t) => t.status === "awaiting_user") || state.runMerge?.paused) return "executing";
|
|
8209
8321
|
return "idle";
|
|
8210
8322
|
}
|
|
@@ -8296,7 +8408,7 @@ function submit(state) {
|
|
|
8296
8408
|
const builtIn = builtInCommand(text);
|
|
8297
8409
|
if (builtIn) return runCommand(cleared, builtIn);
|
|
8298
8410
|
if (plannerInFlight(state)) {
|
|
8299
|
-
return step({ ...cleared, queuedPrompts: (0,
|
|
8411
|
+
return step({ ...cleared, queuedPrompts: (0, import_core46.holdPrompt)(state.queuedPrompts, text) });
|
|
8300
8412
|
}
|
|
8301
8413
|
const spoken = say(cleared, "user", text);
|
|
8302
8414
|
const effect = state.sessionId ? { type: "sendMessage", sessionId: state.sessionId, message: text } : { type: "startConversation", goal: text };
|
|
@@ -8371,7 +8483,7 @@ function createApp(deps) {
|
|
|
8371
8483
|
|
|
8372
8484
|
// src/tui/effects.ts
|
|
8373
8485
|
var import_child_process3 = require("child_process");
|
|
8374
|
-
var
|
|
8486
|
+
var import_core47 = require("@ordewell/core");
|
|
8375
8487
|
|
|
8376
8488
|
// src/tui/inbound.ts
|
|
8377
8489
|
var CONVERSATION_TYPES = /* @__PURE__ */ new Set([
|
|
@@ -8780,13 +8892,13 @@ async function perform(effect, deps) {
|
|
|
8780
8892
|
await refreshPlan(deps, sessionId);
|
|
8781
8893
|
return;
|
|
8782
8894
|
}
|
|
8783
|
-
const request = action === "cancel" || action === "retry" || action === "force-start" ? () => api.taskControl(sessionId, taskId, action) : action === "resume-now" ? () => api.resumeNow(sessionId, taskId) : action === "skip" ? () => api.skipTask(sessionId, taskId) : (0,
|
|
8895
|
+
const request = action === "cancel" || action === "retry" || action === "force-start" ? () => api.taskControl(sessionId, taskId, action) : action === "resume-now" ? () => api.resumeNow(sessionId, taskId) : action === "skip" ? () => api.skipTask(sessionId, taskId) : (0, import_core47.markRequestFor)(action) === "uncomplete" ? () => api.markTaskIncomplete(sessionId, taskId) : () => api.markTaskComplete(sessionId, taskId);
|
|
8784
8896
|
await (effect.watch ? withExecutionStream(deps, sessionId, request) : request());
|
|
8785
8897
|
await refreshPlan(deps, sessionId);
|
|
8786
8898
|
return;
|
|
8787
8899
|
}
|
|
8788
8900
|
case "addTask": {
|
|
8789
|
-
const fields = (0,
|
|
8901
|
+
const fields = (0, import_core47.newTaskFields)(effect.title);
|
|
8790
8902
|
if (!fields) return;
|
|
8791
8903
|
await api.addTask(effect.sessionId, { ...fields });
|
|
8792
8904
|
await refreshPlan(deps, effect.sessionId);
|
|
@@ -8894,7 +9006,7 @@ async function perform(effect, deps) {
|
|
|
8894
9006
|
return;
|
|
8895
9007
|
}
|
|
8896
9008
|
case "setPlanner": {
|
|
8897
|
-
const meta =
|
|
9009
|
+
const meta = (0, import_core47.getProviderMeta)(effect.provider);
|
|
8898
9010
|
if (!meta) throw new Error(`Unknown planner: ${effect.provider}`);
|
|
8899
9011
|
const env = { AI_PROVIDER: effect.provider };
|
|
8900
9012
|
const settings = await api.updateSettings({ env });
|
|
@@ -8906,7 +9018,7 @@ async function perform(effect, deps) {
|
|
|
8906
9018
|
});
|
|
8907
9019
|
dispatch({
|
|
8908
9020
|
type: "notice",
|
|
8909
|
-
message: `${(0,
|
|
9021
|
+
message: `${(0, import_core47.isCliProvider)(effect.provider) ? `Planning with ${meta.label} \u2014 no API key needed.` : `Planner set to ${meta.label}.`} ${plannerModelNotice(recall2)}`
|
|
8910
9022
|
});
|
|
8911
9023
|
await loadModels(deps);
|
|
8912
9024
|
return;
|
|
@@ -8934,7 +9046,7 @@ async function perform(effect, deps) {
|
|
|
8934
9046
|
dispatch({ type: "notice", message: `Planner effort set to ${effect.effort || "the runner default"}.` });
|
|
8935
9047
|
return;
|
|
8936
9048
|
case "setApiKey": {
|
|
8937
|
-
const meta =
|
|
9049
|
+
const meta = (0, import_core47.isApiProvider)(effect.provider) ? (0, import_core47.getProviderMeta)(effect.provider) : void 0;
|
|
8938
9050
|
if (!meta) throw new Error(`Unknown provider: ${effect.provider}`);
|
|
8939
9051
|
await api.updateSettings({ env: { [meta.apiKeyEnvVar]: effect.key } });
|
|
8940
9052
|
deps.setEnvVar(meta.apiKeyEnvVar, effect.key);
|
|
@@ -8982,7 +9094,7 @@ async function perform(effect, deps) {
|
|
|
8982
9094
|
}
|
|
8983
9095
|
case "setAutonomous": {
|
|
8984
9096
|
const { overridden } = deps.saveAutonomy(effect.enabled);
|
|
8985
|
-
const level = (0,
|
|
9097
|
+
const level = (0, import_core47.autonomyLevelLabel)(effect.enabled);
|
|
8986
9098
|
dispatch({ type: "notice", message: overridden ? `${level} is saved, but ORDEWELL_AUTONOMOUS_MODE in the environment decides the level until it is unset.` : `Autonomy level: ${level} for new plans.` });
|
|
8987
9099
|
return;
|
|
8988
9100
|
}
|
|
@@ -9146,7 +9258,7 @@ async function saveMaxParallel(deps, limit) {
|
|
|
9146
9258
|
function copySelection(deps, text) {
|
|
9147
9259
|
if (!text) return;
|
|
9148
9260
|
const lines = text.split("\n").length;
|
|
9149
|
-
const command = (0,
|
|
9261
|
+
const command = (0, import_core47.clipboardCopyCommand)(deps.hasBin);
|
|
9150
9262
|
if (command) {
|
|
9151
9263
|
try {
|
|
9152
9264
|
(deps.pipeToClipboard ?? pipeToClipboardDefault)(command, text);
|
|
@@ -9251,7 +9363,7 @@ function lastAssistantMessage(plan) {
|
|
|
9251
9363
|
const history = plan?.conversationHistory ?? [];
|
|
9252
9364
|
for (let i = history.length - 1; i >= 0; i--) {
|
|
9253
9365
|
const entry = history[i];
|
|
9254
|
-
if ((0,
|
|
9366
|
+
if ((0, import_core47.isUserMessage)(entry)) return null;
|
|
9255
9367
|
if (entry.role === "assistant" && entry.kind === void 0) {
|
|
9256
9368
|
const { content, timestamp } = entry;
|
|
9257
9369
|
return { content, ...timestamp ? { timestamp } : {} };
|
|
@@ -9273,14 +9385,14 @@ async function loadModels(deps) {
|
|
|
9273
9385
|
}
|
|
9274
9386
|
async function loadSessions(deps) {
|
|
9275
9387
|
const sessions = await deps.api.getSessions(deps.workspace);
|
|
9276
|
-
const
|
|
9388
|
+
const list2 = sessions.map((s) => ({
|
|
9277
9389
|
id: String(s.id),
|
|
9278
9390
|
goal: String(s.goal ?? ""),
|
|
9279
9391
|
taskCount: Number(s.taskCount ?? 0),
|
|
9280
9392
|
status: String(s.status ?? ""),
|
|
9281
9393
|
createdAt: String(s.createdAt ?? "")
|
|
9282
9394
|
}));
|
|
9283
|
-
deps.dispatch({ type: "sessionsLoaded", sessions:
|
|
9395
|
+
deps.dispatch({ type: "sessionsLoaded", sessions: list2 });
|
|
9284
9396
|
}
|
|
9285
9397
|
async function loadRunners(deps) {
|
|
9286
9398
|
const state = await deps.api.getRunners();
|
|
@@ -9606,7 +9718,7 @@ async function handleTui(subArgs) {
|
|
|
9606
9718
|
}
|
|
9607
9719
|
const workspace = flag(subArgs, "--workspace") || process.cwd();
|
|
9608
9720
|
try {
|
|
9609
|
-
(0,
|
|
9721
|
+
(0, import_core48.assertWorkspaceExists)(workspace);
|
|
9610
9722
|
} catch {
|
|
9611
9723
|
console.error(
|
|
9612
9724
|
`Workspace "${workspace}" does not exist.
|
|
@@ -9615,7 +9727,7 @@ cd into a directory that exists, or pass --workspace <path> naming one that does
|
|
|
9615
9727
|
);
|
|
9616
9728
|
process.exit(1);
|
|
9617
9729
|
}
|
|
9618
|
-
const discoveredSkills = (0,
|
|
9730
|
+
const discoveredSkills = (0, import_core48.createSkillsService)(workspace, new import_core48.EnvConfig().workspaceRepos).listSkills();
|
|
9619
9731
|
registerSkillCommands(discoveredSkills);
|
|
9620
9732
|
const taskSkills = discoveredSkills.filter((s) => s.appliesTo === "task").map((s) => ({ name: s.name, description: s.description }));
|
|
9621
9733
|
const explicitPort = flag(subArgs, "--port") || process.env.ORDEWELL_PORT;
|
|
@@ -9627,20 +9739,20 @@ cd into a directory that exists, or pass --workspace <path> naming one that does
|
|
|
9627
9739
|
const mouseCapture = process.env.ORDEWELL_TUI_MOUSE !== "false" && process.env.ORDEWELL_TUI_MOUSE !== "0";
|
|
9628
9740
|
const app = createApp({
|
|
9629
9741
|
// The level the daemon plans with: the saved one, unless the environment overrides it (ADR-0030).
|
|
9630
|
-
initial: { workspace, autonomous: new
|
|
9742
|
+
initial: { workspace, autonomous: new import_core48.SettingsService().autonomousMode(), mouseCapture, taskSkills },
|
|
9631
9743
|
draw: (frame2) => terminal?.draw(frame2),
|
|
9632
9744
|
perform: (effect) => runEffect(effect, {
|
|
9633
9745
|
api,
|
|
9634
9746
|
workspace,
|
|
9635
9747
|
port,
|
|
9636
9748
|
dispatch: (action) => app.dispatch(action),
|
|
9637
|
-
newSessionId: () => (0,
|
|
9749
|
+
newSessionId: () => (0, import_core48.mintSessionId)(),
|
|
9638
9750
|
setEnvVar: (key, value) => {
|
|
9639
9751
|
writeEnvVar(findEnvFile(), key, value);
|
|
9640
9752
|
process.env[key] = value;
|
|
9641
9753
|
},
|
|
9642
9754
|
saveAutonomy: (enabled) => {
|
|
9643
|
-
const settings = new
|
|
9755
|
+
const settings = new import_core48.SettingsService();
|
|
9644
9756
|
settings.setAutonomousMode(enabled);
|
|
9645
9757
|
return { overridden: settings.autonomousModeOverridden() };
|
|
9646
9758
|
},
|
|
@@ -9754,7 +9866,7 @@ var COMMANDS = {
|
|
|
9754
9866
|
// src/main.ts
|
|
9755
9867
|
var TUI_FLAGS = /* @__PURE__ */ new Set(["--workspace", "--port"]);
|
|
9756
9868
|
async function main() {
|
|
9757
|
-
(0,
|
|
9869
|
+
(0, import_core49.migrateOldConfigDir)();
|
|
9758
9870
|
moveAutonomyToSettings();
|
|
9759
9871
|
loadEnvFile();
|
|
9760
9872
|
const argv = process.argv.slice(2);
|