archymedes-cli 2.3.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{archymedes-aj30app4.mjs → archymedes-06fh0z84.mjs} +370 -159
- package/dist/{archymedes-d5wqcmdr.mjs → archymedes-0jxzsh4z.mjs} +97 -97
- package/dist/archymedes-130jt0wr.mjs +1231 -0
- package/dist/{archymedes-twbks7g3.mjs → archymedes-138genyy.mjs} +214 -5
- package/dist/{archymedes-h13ap0za.mjs → archymedes-1g1y6q74.mjs} +1 -1
- package/dist/{archymedes-dz59nvw7.mjs → archymedes-2kvjaajw.mjs} +21 -11
- package/dist/{archymedes-g8y3rt6t.mjs → archymedes-5vhvv8kr.mjs} +332 -9
- package/dist/{archymedes-4kx65anz.mjs → archymedes-a3ms7jvr.mjs} +43 -12
- package/dist/{archymedes-tsne2m7p.mjs → archymedes-bmtdqqwt.mjs} +2 -2
- package/dist/{archymedes-sf9t1hz9.mjs → archymedes-d3azqkay.mjs} +176 -77
- package/dist/archymedes-main.mjs +31312 -28352
- package/dist/archymedes-w4bjfye7.mjs +280 -0
- package/dist/{editor-screen-g08zzt70.mjs → editor-screen-e01mn7dd.mjs} +49 -14
- package/dist/{factory-7vtm2fed.mjs → factory-hyv8agr0.mjs} +326 -326
- package/dist/{file-screen-ma9yxq2b.mjs → file-screen-stcxznwy.mjs} +11 -9
- package/dist/{guide-screen-gd129txd.mjs → guide-screen-w5nb9sry.mjs} +10 -8
- package/dist/{index-qvgcwsvm.mjs → index-teq1cta4.mjs} +1 -1
- package/dist/{node-mdgzx68h.mjs → node-0fh63p8z.mjs} +7 -7
- package/dist/pager-screen-aamt6xv0.mjs +155 -0
- package/dist/projection-x6x6hm9t.mjs +248 -0
- package/dist/{sandbox-templates-9jcjws23.mjs → sandbox-templates-8sd1psez.mjs} +2 -2
- package/dist/workspace-screen-62k6hnq7.mjs +70 -0
- package/package.json +2 -2
- package/dist/archymedes-a10k8yrk.mjs +0 -464
- package/dist/workspace-screen-8cwk6jz9.mjs +0 -241
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
import {
|
|
2
2
|
padToWidth,
|
|
3
3
|
progressBar,
|
|
4
|
+
scrollIndicator,
|
|
5
|
+
scrollPercent,
|
|
4
6
|
sliceToWidth
|
|
5
|
-
} from "./archymedes-
|
|
7
|
+
} from "./archymedes-5vhvv8kr.mjs";
|
|
8
|
+
import {
|
|
9
|
+
clip
|
|
10
|
+
} from "./archymedes-bmtdqqwt.mjs";
|
|
6
11
|
import {
|
|
7
12
|
ASCII_GLYPHS,
|
|
8
13
|
UNICODE_GLYPHS,
|
|
9
14
|
visibleWidth
|
|
10
|
-
} from "./archymedes-
|
|
15
|
+
} from "./archymedes-130jt0wr.mjs";
|
|
11
16
|
|
|
12
|
-
// src/render/canvas.ts
|
|
17
|
+
// packages/archymedes-cli/src/render/canvas.ts
|
|
13
18
|
var BRAILLE_DOTS = [
|
|
14
19
|
[1, 2, 4, 64],
|
|
15
20
|
[8, 16, 32, 128]
|
|
@@ -95,7 +100,7 @@ function seriesBounds(values) {
|
|
|
95
100
|
return { low, high, span: high - low === 0 ? 1 : high - low };
|
|
96
101
|
}
|
|
97
102
|
|
|
98
|
-
// src/render/charts.ts
|
|
103
|
+
// packages/archymedes-cli/src/render/charts.ts
|
|
99
104
|
function barChart(data, options) {
|
|
100
105
|
if (data.length === 0)
|
|
101
106
|
return [];
|
|
@@ -253,4 +258,208 @@ function heatStrip(data, options) {
|
|
|
253
258
|
});
|
|
254
259
|
}
|
|
255
260
|
|
|
256
|
-
|
|
261
|
+
// packages/archymedes-cli/src/ui/workspace-model.ts
|
|
262
|
+
function paneHeight(rows) {
|
|
263
|
+
return Math.max(1, rows - 4);
|
|
264
|
+
}
|
|
265
|
+
function selectedPane(snapshot) {
|
|
266
|
+
if (snapshot.panes.length === 0)
|
|
267
|
+
return;
|
|
268
|
+
const index = Math.max(0, Math.min(snapshot.selected, snapshot.panes.length - 1));
|
|
269
|
+
return snapshot.panes[index];
|
|
270
|
+
}
|
|
271
|
+
function visibleLines(pane, height, scroll) {
|
|
272
|
+
const clamped = Math.max(0, Math.min(scroll, Math.max(0, pane.lines.length - height)));
|
|
273
|
+
const end = pane.lines.length - clamped;
|
|
274
|
+
return pane.lines.slice(Math.max(0, end - height), end);
|
|
275
|
+
}
|
|
276
|
+
function atLiveEdge(pane, height, scroll) {
|
|
277
|
+
return Math.min(scroll, Math.max(0, pane.lines.length - height)) === 0;
|
|
278
|
+
}
|
|
279
|
+
function keyToAction(key, character) {
|
|
280
|
+
const name = key.name ?? "";
|
|
281
|
+
const isEscape = name === "escape" || name === "\x1B";
|
|
282
|
+
const isEnter = name === "return" || name === "enter" || name === "\r" || name === `
|
|
283
|
+
`;
|
|
284
|
+
if (isEscape || name === "q" && !key.ctrl || key.ctrl && name === "c")
|
|
285
|
+
return { kind: "exit" };
|
|
286
|
+
if (isEnter)
|
|
287
|
+
return { kind: "focus" };
|
|
288
|
+
if (name === "tab")
|
|
289
|
+
return { kind: "cycle", step: key.shift ? -1 : 1 };
|
|
290
|
+
if (name === "left")
|
|
291
|
+
return { kind: "cycle", step: -1 };
|
|
292
|
+
if (name === "right")
|
|
293
|
+
return { kind: "cycle", step: 1 };
|
|
294
|
+
if (name === "up" || name === "k")
|
|
295
|
+
return { kind: "scroll", lines: 1 };
|
|
296
|
+
if (name === "down" || name === "j")
|
|
297
|
+
return { kind: "scroll", lines: -1 };
|
|
298
|
+
if (name === "pageup")
|
|
299
|
+
return { kind: "scroll", lines: 10 };
|
|
300
|
+
if (name === "pagedown")
|
|
301
|
+
return { kind: "scroll", lines: -10 };
|
|
302
|
+
if (name === "home" || character === "g")
|
|
303
|
+
return { kind: "top" };
|
|
304
|
+
if (name === "end" || character === "G")
|
|
305
|
+
return { kind: "bottom" };
|
|
306
|
+
const digit = character && /^[1-9]$/.test(character) ? Number(character) : undefined;
|
|
307
|
+
if (digit !== undefined)
|
|
308
|
+
return { kind: "select", index: digit - 1 };
|
|
309
|
+
return { kind: "none" };
|
|
310
|
+
}
|
|
311
|
+
function applyAction(snapshot, action) {
|
|
312
|
+
const count = snapshot.panes.length;
|
|
313
|
+
if (count === 0 || action.kind === "none" || action.kind === "exit" || action.kind === "focus")
|
|
314
|
+
return snapshot;
|
|
315
|
+
if (action.kind === "select") {
|
|
316
|
+
if (action.index < 0 || action.index >= count)
|
|
317
|
+
return snapshot;
|
|
318
|
+
return { ...snapshot, selected: action.index, scroll: 0 };
|
|
319
|
+
}
|
|
320
|
+
if (action.kind === "cycle") {
|
|
321
|
+
const next = ((snapshot.selected + action.step) % count + count) % count;
|
|
322
|
+
return { ...snapshot, selected: next, scroll: 0 };
|
|
323
|
+
}
|
|
324
|
+
const pane = selectedPane(snapshot);
|
|
325
|
+
const height = paneHeight(snapshot.rows);
|
|
326
|
+
const furthest = Math.max(0, (pane?.lines.length ?? 0) - height);
|
|
327
|
+
if (action.kind === "bottom")
|
|
328
|
+
return { ...snapshot, scroll: 0 };
|
|
329
|
+
if (action.kind === "top")
|
|
330
|
+
return { ...snapshot, scroll: furthest };
|
|
331
|
+
return { ...snapshot, scroll: Math.max(0, Math.min(snapshot.scroll + action.lines, furthest)) };
|
|
332
|
+
}
|
|
333
|
+
function paneTabs(snapshot) {
|
|
334
|
+
const selected = Math.max(0, Math.min(snapshot.selected, snapshot.panes.length - 1));
|
|
335
|
+
return snapshot.panes.map((pane, index) => ({
|
|
336
|
+
label: `${index + 1} ${pane.title}`,
|
|
337
|
+
active: index === selected,
|
|
338
|
+
status: pane.status
|
|
339
|
+
}));
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
class PaneActivity {
|
|
343
|
+
capacity;
|
|
344
|
+
series = new Map;
|
|
345
|
+
seen = new Map;
|
|
346
|
+
constructor(capacity = 48) {
|
|
347
|
+
this.capacity = capacity;
|
|
348
|
+
}
|
|
349
|
+
sample(panes) {
|
|
350
|
+
const live = new Set(panes.map((pane) => pane.key));
|
|
351
|
+
for (const key of [...this.series.keys()]) {
|
|
352
|
+
if (!live.has(key)) {
|
|
353
|
+
this.series.delete(key);
|
|
354
|
+
this.seen.delete(key);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
const result = new Map;
|
|
358
|
+
for (const pane of panes) {
|
|
359
|
+
const produced = pane.lines.length + pane.dropped;
|
|
360
|
+
const previous = this.seen.get(pane.key);
|
|
361
|
+
this.seen.set(pane.key, produced);
|
|
362
|
+
const stream = this.series.get(pane.key) ?? new StreamSeries(this.capacity);
|
|
363
|
+
this.series.set(pane.key, stream);
|
|
364
|
+
if (previous !== undefined)
|
|
365
|
+
stream.push(Math.max(0, produced - previous));
|
|
366
|
+
result.set(pane.key, stream.values());
|
|
367
|
+
}
|
|
368
|
+
return result;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
function tabPanes(views, linesFor) {
|
|
372
|
+
return views.map((view) => {
|
|
373
|
+
const record = linesFor(view.id);
|
|
374
|
+
const where = view.backend && view.backend !== "local" ? ` · ${view.backend}` : "";
|
|
375
|
+
return {
|
|
376
|
+
kind: "tab",
|
|
377
|
+
key: `${view.id}`,
|
|
378
|
+
title: view.title,
|
|
379
|
+
subtitle: `${view.model ?? "model unknown"}${where}${view.cost ? ` · ${view.cost}` : ""}`,
|
|
380
|
+
status: view.status,
|
|
381
|
+
lines: record.lines,
|
|
382
|
+
dropped: record.dropped
|
|
383
|
+
};
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
var STATUS_MARK = {
|
|
387
|
+
running: "●",
|
|
388
|
+
failed: "✕",
|
|
389
|
+
done: "✓",
|
|
390
|
+
idle: " "
|
|
391
|
+
};
|
|
392
|
+
var WORKSPACE_LEGEND = "1-9 pane · ←→ move · ↑↓ scroll · g/G ends · Esc back";
|
|
393
|
+
function paneBar(snapshot, columns) {
|
|
394
|
+
const tabs = paneTabs(snapshot);
|
|
395
|
+
const cells = tabs.map((tab) => ` ${STATUS_MARK[tab.status] ?? " "}${tab.label} `);
|
|
396
|
+
const full = cells.join("");
|
|
397
|
+
if (full.length <= columns)
|
|
398
|
+
return full || " no panes ";
|
|
399
|
+
const selected = Math.max(0, Math.min(snapshot.selected, tabs.length - 1));
|
|
400
|
+
return `${selected > 0 ? "‹ " : ""}${cells[selected] ?? " no panes "}${selected < tabs.length - 1 ? " ›" : ""}`;
|
|
401
|
+
}
|
|
402
|
+
function composeFrame(snapshot) {
|
|
403
|
+
const rows = [];
|
|
404
|
+
const columns = Math.max(1, Math.floor(snapshot.columns));
|
|
405
|
+
const rowCount = Math.max(1, Math.floor(snapshot.rows));
|
|
406
|
+
const pane = selectedPane(snapshot);
|
|
407
|
+
const height = paneHeight(rowCount);
|
|
408
|
+
const theme = snapshot.palette.tokens;
|
|
409
|
+
const bar = paneBar(snapshot, columns);
|
|
410
|
+
rows.push({ text: bar || " no panes ", bold: true, color: theme.primary });
|
|
411
|
+
const scrolled = pane && !atLiveEdge(pane, height, snapshot.scroll);
|
|
412
|
+
const position = (() => {
|
|
413
|
+
if (!pane || !scrolled)
|
|
414
|
+
return "";
|
|
415
|
+
const maxOffset = Math.max(0, pane.lines.length - height);
|
|
416
|
+
const offsetFromTop = maxOffset - Math.min(snapshot.scroll, maxOffset);
|
|
417
|
+
return scrollIndicator(scrollPercent(offsetFromTop, pane.lines.length, height));
|
|
418
|
+
})();
|
|
419
|
+
const dropped = pane && pane.dropped > 0 ? ` (${pane.dropped} earlier lines dropped)` : "";
|
|
420
|
+
const header = pane ? `${pane.title} ${pane.subtitle}${dropped}` : "nothing open";
|
|
421
|
+
const activityWidth = Math.min(24, Math.max(0, columns - visibleWidth(header) - 3));
|
|
422
|
+
const activity = pane?.activity && pane.activity.length > 1 && activityWidth >= 8 ? ` ${waveLine(pane.activity, { width: activityWidth })}` : "";
|
|
423
|
+
rows.push({
|
|
424
|
+
text: pane ? `${header}${activity}` : header,
|
|
425
|
+
bold: true,
|
|
426
|
+
color: pane?.status === "failed" ? theme.error : pane?.status === "running" ? theme.success : theme.accent
|
|
427
|
+
});
|
|
428
|
+
const body = pane ? visibleLines(pane, height, snapshot.scroll) : [];
|
|
429
|
+
for (let index = 0;index < height; index += 1)
|
|
430
|
+
rows.push({ text: body[index] ?? "" });
|
|
431
|
+
while (rows.length < rowCount - 1)
|
|
432
|
+
rows.push({ text: "" });
|
|
433
|
+
rows.length = Math.max(0, rowCount - 1);
|
|
434
|
+
rows.push({
|
|
435
|
+
text: `${WORKSPACE_LEGEND}${scrolled ? ` ▲ scrolled back ${position}` : ""}`,
|
|
436
|
+
dim: true,
|
|
437
|
+
color: theme.textMuted
|
|
438
|
+
});
|
|
439
|
+
return rows.map((row) => ({ ...row, text: clip(row.text, columns) }));
|
|
440
|
+
}
|
|
441
|
+
function buildWorkspaceSnapshot(input) {
|
|
442
|
+
const panes = [
|
|
443
|
+
...tabPanes(input.views, input.linesFor),
|
|
444
|
+
...input.jobs.map((job) => ({
|
|
445
|
+
kind: "job",
|
|
446
|
+
key: job.id,
|
|
447
|
+
title: `job ${job.id.slice(-6)}`,
|
|
448
|
+
subtitle: job.objective,
|
|
449
|
+
status: job.done ? "done" : "running",
|
|
450
|
+
lines: job.lines,
|
|
451
|
+
dropped: job.dropped
|
|
452
|
+
}))
|
|
453
|
+
];
|
|
454
|
+
const activity = input.activity.sample(panes);
|
|
455
|
+
return {
|
|
456
|
+
panes: panes.map((pane) => ({ ...pane, activity: activity.get(pane.key) })),
|
|
457
|
+
selected: Math.max(0, input.views.findIndex((view) => view.active)),
|
|
458
|
+
scroll: 0,
|
|
459
|
+
palette: input.palette,
|
|
460
|
+
columns: input.columns,
|
|
461
|
+
rows: input.rows
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
export { barChart, lineChart, plotSeries, scatterChart, waveLine, heatStrip, keyToAction, applyAction, PaneActivity, composeFrame, buildWorkspaceSnapshot };
|
|
@@ -2,18 +2,21 @@ import {
|
|
|
2
2
|
GUTTER,
|
|
3
3
|
clip,
|
|
4
4
|
panel
|
|
5
|
-
} from "./archymedes-
|
|
5
|
+
} from "./archymedes-bmtdqqwt.mjs";
|
|
6
6
|
import {
|
|
7
7
|
BOLD,
|
|
8
8
|
DIM,
|
|
9
9
|
UNICODE_GLYPHS,
|
|
10
|
+
codeStyle,
|
|
11
|
+
highlightSyntax,
|
|
12
|
+
newSyntaxState,
|
|
10
13
|
paint,
|
|
11
14
|
paintAll,
|
|
12
15
|
roleCode,
|
|
13
16
|
visibleWidth
|
|
14
|
-
} from "./archymedes-
|
|
17
|
+
} from "./archymedes-130jt0wr.mjs";
|
|
15
18
|
|
|
16
|
-
// src/render/code-view.ts
|
|
19
|
+
// packages/archymedes-cli/src/render/code-view.ts
|
|
17
20
|
var MAX_DIFF_CELLS = 250000;
|
|
18
21
|
function diffLines(before, after) {
|
|
19
22
|
const left = before === "" ? [] : before.split(`
|
|
@@ -193,7 +196,9 @@ var KEYWORDS = new Set([
|
|
|
193
196
|
"yield"
|
|
194
197
|
]);
|
|
195
198
|
var LITERALS = new Set(["true", "false", "null", "nil", "None", "True", "False", "undefined", "self", "this"]);
|
|
196
|
-
function highlightCode(line, depth, palette) {
|
|
199
|
+
function highlightCode(line, depth, palette, language, state) {
|
|
200
|
+
if (codeStyle().colors === "vscode")
|
|
201
|
+
return highlightSyntax(line, { depth, palette, ...language ? { language } : {}, ...state ? { state } : {} });
|
|
197
202
|
if (depth === "none")
|
|
198
203
|
return line;
|
|
199
204
|
const commentAt = findCommentStart(line);
|
|
@@ -246,11 +251,14 @@ function renderCode(content, style, options = {}) {
|
|
|
246
251
|
const start = options.startLine ?? 1;
|
|
247
252
|
const numberWidth = String(start + lines.length - 1).length;
|
|
248
253
|
const bodyWidth = Math.max(8, style.width - GUTTER.length - numberWidth - 4);
|
|
249
|
-
const render = (from, to) =>
|
|
250
|
-
const
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
+
const render = (from, to) => {
|
|
255
|
+
const syntax = newSyntaxState();
|
|
256
|
+
return lines.slice(from, to).map((line, index) => {
|
|
257
|
+
const number = paint(String(start + from + index).padStart(numberWidth), DIM, style.depth);
|
|
258
|
+
const painted = options.highlight === false ? line : highlightCode(line, style.depth, style.palette, options.language, syntax);
|
|
259
|
+
return `${number} ${clip(painted, bodyWidth, glyphs)}`;
|
|
260
|
+
});
|
|
261
|
+
};
|
|
254
262
|
const hidden = Math.max(0, lines.length - maxLines);
|
|
255
263
|
const shown = render(0, hidden > 0 ? maxLines : lines.length);
|
|
256
264
|
return {
|
|
@@ -266,12 +274,14 @@ function renderDiff(diff, style, options = {}) {
|
|
|
266
274
|
const maxLines = options.maxLines ?? 16;
|
|
267
275
|
const condensed = condenseDiff(diff);
|
|
268
276
|
const bodyWidth = Math.max(8, style.width - GUTTER.length - 4);
|
|
277
|
+
const vscode = codeStyle().colors === "vscode" && style.depth !== "none";
|
|
278
|
+
const bandWidth = Math.min(bodyWidth, Math.max(0, ...diff.map((line) => [...line.text].length)));
|
|
269
279
|
const row = (line) => {
|
|
270
280
|
if (line.kind === "gap")
|
|
271
281
|
return paint(`${glyphs.middot.repeat(3)} ${line.text}`, DIM, style.depth);
|
|
272
282
|
const mark = line.kind === "add" ? glyphs.plus : line.kind === "remove" ? glyphs.minus : " ";
|
|
273
283
|
const code = line.kind === "add" ? roleCode("success", style.palette, style.depth) : line.kind === "remove" ? roleCode("error", style.palette, style.depth) : DIM;
|
|
274
|
-
const body = line.kind === "context" ? paint(line.text, DIM, style.depth) : highlightCode(line.text, style.depth, style.palette);
|
|
284
|
+
const body = line.kind === "context" ? vscode ? highlightCode(line.text, style.depth, style.palette, options.language) : paint(line.text, DIM, style.depth) : vscode ? highlightSyntax(line.text, { depth: style.depth, palette: style.palette, band: line.kind, padTo: bandWidth, ...options.language ? { language: options.language } : {} }) : highlightCode(line.text, style.depth, style.palette);
|
|
275
285
|
return `${paint(mark, code, style.depth)} ${clip(body, bodyWidth, glyphs)}`;
|
|
276
286
|
};
|
|
277
287
|
const rows = condensed.map(row);
|
|
@@ -286,7 +296,7 @@ function renderDiff(diff, style, options = {}) {
|
|
|
286
296
|
}
|
|
287
297
|
function renderFileChange(change, style, options = {}) {
|
|
288
298
|
const language = languageOf(change.path);
|
|
289
|
-
const block = change.kind === "edit" ? renderDiff(diffLines(change.before ?? "", change.after ?? ""), style, { maxLines: options.maxLines }) : renderCode(change.content ?? "", style, { maxLines: options.maxLines, language });
|
|
299
|
+
const block = change.kind === "edit" ? renderDiff(diffLines(change.before ?? "", change.after ?? ""), style, { maxLines: options.maxLines, language }) : renderCode(change.content ?? "", style, { maxLines: options.maxLines, language });
|
|
290
300
|
const badge = change.kind === "edit" ? (() => {
|
|
291
301
|
const stat = diffStat(diffLines(change.before ?? "", change.after ?? ""));
|
|
292
302
|
return `+${stat.added} -${stat.removed}`;
|