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.
Files changed (25) hide show
  1. package/dist/{archymedes-aj30app4.mjs → archymedes-06fh0z84.mjs} +370 -159
  2. package/dist/{archymedes-d5wqcmdr.mjs → archymedes-0jxzsh4z.mjs} +97 -97
  3. package/dist/archymedes-130jt0wr.mjs +1231 -0
  4. package/dist/{archymedes-twbks7g3.mjs → archymedes-138genyy.mjs} +214 -5
  5. package/dist/{archymedes-h13ap0za.mjs → archymedes-1g1y6q74.mjs} +1 -1
  6. package/dist/{archymedes-dz59nvw7.mjs → archymedes-2kvjaajw.mjs} +21 -11
  7. package/dist/{archymedes-g8y3rt6t.mjs → archymedes-5vhvv8kr.mjs} +332 -9
  8. package/dist/{archymedes-4kx65anz.mjs → archymedes-a3ms7jvr.mjs} +43 -12
  9. package/dist/{archymedes-tsne2m7p.mjs → archymedes-bmtdqqwt.mjs} +2 -2
  10. package/dist/{archymedes-sf9t1hz9.mjs → archymedes-d3azqkay.mjs} +176 -77
  11. package/dist/archymedes-main.mjs +31312 -28352
  12. package/dist/archymedes-w4bjfye7.mjs +280 -0
  13. package/dist/{editor-screen-g08zzt70.mjs → editor-screen-e01mn7dd.mjs} +49 -14
  14. package/dist/{factory-7vtm2fed.mjs → factory-hyv8agr0.mjs} +326 -326
  15. package/dist/{file-screen-ma9yxq2b.mjs → file-screen-stcxznwy.mjs} +11 -9
  16. package/dist/{guide-screen-gd129txd.mjs → guide-screen-w5nb9sry.mjs} +10 -8
  17. package/dist/{index-qvgcwsvm.mjs → index-teq1cta4.mjs} +1 -1
  18. package/dist/{node-mdgzx68h.mjs → node-0fh63p8z.mjs} +7 -7
  19. package/dist/pager-screen-aamt6xv0.mjs +155 -0
  20. package/dist/projection-x6x6hm9t.mjs +248 -0
  21. package/dist/{sandbox-templates-9jcjws23.mjs → sandbox-templates-8sd1psez.mjs} +2 -2
  22. package/dist/workspace-screen-62k6hnq7.mjs +70 -0
  23. package/package.json +2 -2
  24. package/dist/archymedes-a10k8yrk.mjs +0 -464
  25. 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-g8y3rt6t.mjs";
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-a10k8yrk.mjs";
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
- export { barChart, lineChart, plotSeries, scatterChart, waveLine, StreamSeries, heatStrip };
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 };
@@ -1,4 +1,4 @@
1
- // ../core/src/sandbox-policy.ts
1
+ // packages/core/src/sandbox-policy.ts
2
2
  var ALLOWED_SANDBOX_PROGRAMS = [
3
3
  "bun",
4
4
  "npm",
@@ -2,18 +2,21 @@ import {
2
2
  GUTTER,
3
3
  clip,
4
4
  panel
5
- } from "./archymedes-tsne2m7p.mjs";
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-a10k8yrk.mjs";
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) => lines.slice(from, to).map((line, index) => {
250
- const number = paint(String(start + from + index).padStart(numberWidth), DIM, style.depth);
251
- const painted = options.highlight === false ? line : highlightCode(line, style.depth, style.palette);
252
- return `${number} ${clip(painted, bodyWidth, glyphs)}`;
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}`;