archymedes-cli 2.3.0 → 2.6.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-sf9t1hz9.mjs → archymedes-086xsz64.mjs} +176 -77
- package/dist/{archymedes-d5wqcmdr.mjs → archymedes-0jxzsh4z.mjs} +97 -97
- package/dist/{archymedes-h13ap0za.mjs → archymedes-1g1y6q74.mjs} +1 -1
- package/dist/{archymedes-4kx65anz.mjs → archymedes-1jcn326m.mjs} +43 -12
- package/dist/{archymedes-g8y3rt6t.mjs → archymedes-kn6wtq32.mjs} +332 -9
- package/dist/archymedes-main.mjs +31010 -27842
- package/dist/archymedes-s4qcy0q4.mjs +1250 -0
- package/dist/{archymedes-twbks7g3.mjs → archymedes-t1jtzkmp.mjs} +214 -5
- package/dist/{archymedes-tsne2m7p.mjs → archymedes-twanftqk.mjs} +2 -2
- package/dist/archymedes-w4bjfye7.mjs +280 -0
- package/dist/{archymedes-dz59nvw7.mjs → archymedes-zvcs68bv.mjs} +21 -11
- package/dist/{editor-screen-g08zzt70.mjs → editor-screen-pf252j2r.mjs} +49 -14
- package/dist/{factory-7vtm2fed.mjs → factory-hyv8agr0.mjs} +326 -326
- package/dist/{file-screen-ma9yxq2b.mjs → file-screen-1j65f7b4.mjs} +11 -9
- package/dist/{guide-screen-gd129txd.mjs → guide-screen-9vxsk83x.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-ntdcgfq9.mjs +70 -0
- package/package.json +2 -2
- package/dist/archymedes-a10k8yrk.mjs +0 -464
- package/dist/workspace-screen-8cwk6jz9.mjs +0 -241
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import {
|
|
2
2
|
diffLines,
|
|
3
3
|
languageOf
|
|
4
|
-
} from "./archymedes-
|
|
5
|
-
import"./archymedes-
|
|
4
|
+
} from "./archymedes-zvcs68bv.mjs";
|
|
5
|
+
import"./archymedes-twanftqk.mjs";
|
|
6
6
|
import {
|
|
7
|
-
NO_COLOR_PALETTE
|
|
8
|
-
|
|
7
|
+
NO_COLOR_PALETTE,
|
|
8
|
+
exitTopTermUIApp
|
|
9
|
+
} from "./archymedes-s4qcy0q4.mjs";
|
|
9
10
|
import {
|
|
10
11
|
__require
|
|
11
12
|
} from "./archymedes-x67v3n58.mjs";
|
|
12
13
|
|
|
13
|
-
// src/ui/editor-screen.tsx
|
|
14
|
-
import { useInput, useState } from "@termuijs/jsx";
|
|
14
|
+
// packages/archymedes-cli/src/ui/editor-screen.tsx
|
|
15
|
+
import { useEffect, useInput, useRef, useState } from "@termuijs/jsx";
|
|
15
16
|
import { Box, Text } from "@termuijs/widgets";
|
|
16
17
|
|
|
17
|
-
// src/ui/editor.ts
|
|
18
|
+
// packages/archymedes-cli/src/ui/editor.ts
|
|
18
19
|
function initialEditorState(path, content, viewportRows = 20) {
|
|
19
20
|
const lines = content.split(`
|
|
20
21
|
`);
|
|
@@ -79,6 +80,15 @@ function keyToEditorAction(key, character, state) {
|
|
|
79
80
|
return { kind: "save" };
|
|
80
81
|
if (key.ctrl && (name === "q" || name === "c"))
|
|
81
82
|
return { kind: "quit" };
|
|
83
|
+
if (state.confirmLeave) {
|
|
84
|
+
if (character === "y" || character === "Y" || isEnter)
|
|
85
|
+
return { kind: "save" };
|
|
86
|
+
if (character === "n" || character === "N")
|
|
87
|
+
return { kind: "quit" };
|
|
88
|
+
if (isEscape)
|
|
89
|
+
return { kind: "cancelLeave" };
|
|
90
|
+
return { kind: "none" };
|
|
91
|
+
}
|
|
82
92
|
if (state.search.typing) {
|
|
83
93
|
if (isEscape)
|
|
84
94
|
return { kind: "searchCommit" };
|
|
@@ -116,7 +126,7 @@ function keyToEditorAction(key, character, state) {
|
|
|
116
126
|
if (state.pending === "g")
|
|
117
127
|
return name === "g" || character === "g" ? { kind: "jump", to: "fileStart" } : { kind: "normal" };
|
|
118
128
|
if (isEscape)
|
|
119
|
-
return { kind: "
|
|
129
|
+
return { kind: "leave" };
|
|
120
130
|
if (name === "up" || character === "k")
|
|
121
131
|
return { kind: "move", rows: -1 };
|
|
122
132
|
if (name === "down" || character === "j")
|
|
@@ -269,7 +279,15 @@ function applyEditorAction(state, action) {
|
|
|
269
279
|
case "save":
|
|
270
280
|
return { state: clamp({ ...state, dirty: false, message: `saved ${state.path}`, pending: undefined }), effect: { kind: "save" } };
|
|
271
281
|
case "quit":
|
|
272
|
-
return { state, effect: { kind: "quit" } };
|
|
282
|
+
return { state: { ...state, confirmLeave: false }, effect: { kind: "quit" } };
|
|
283
|
+
case "leave":
|
|
284
|
+
if (!state.dirty)
|
|
285
|
+
return { state, effect: { kind: "quit" } };
|
|
286
|
+
return { state: { ...state, pending: undefined, confirmLeave: true, message: "Save changes? y yes · n discard · Esc keep editing" }, effect: undefined };
|
|
287
|
+
case "cancelLeave":
|
|
288
|
+
return plain({ ...state, confirmLeave: false, message: undefined });
|
|
289
|
+
case "autosaved":
|
|
290
|
+
return editorContent(state) === action.content ? plain({ ...state, dirty: false, message: "auto-saved" }) : plain(state);
|
|
273
291
|
case "search":
|
|
274
292
|
return plain({ ...state, search: { query: "", typing: true }, message: undefined });
|
|
275
293
|
case "searchType":
|
|
@@ -311,7 +329,8 @@ function editorKeyBar(state, columns = Number.POSITIVE_INFINITY) {
|
|
|
311
329
|
{ text: "u undo" },
|
|
312
330
|
{ text: "/ find" },
|
|
313
331
|
{ text: "^S save", essential: true },
|
|
314
|
-
{ text: "^Q quit", essential: true }
|
|
332
|
+
{ text: "^Q quit", essential: true },
|
|
333
|
+
{ text: "esc back", essential: true }
|
|
315
334
|
];
|
|
316
335
|
const optional = hints.filter((hint) => !hint.essential);
|
|
317
336
|
for (let dropped = 0;dropped <= optional.length; dropped += 1) {
|
|
@@ -347,7 +366,7 @@ function caretInto(text, cursorCol) {
|
|
|
347
366
|
return `${padded.slice(0, cursorCol)}█${padded.slice(cursorCol + 1)}`;
|
|
348
367
|
}
|
|
349
368
|
|
|
350
|
-
// src/ui/explain-view.ts
|
|
369
|
+
// packages/archymedes-cli/src/ui/explain-view.ts
|
|
351
370
|
var PATTERNS = {
|
|
352
371
|
typescript: {
|
|
353
372
|
imports: /^\s*import\b.*from\s+["'](.+)["']/,
|
|
@@ -531,7 +550,7 @@ function composeExplainPanel(input, width, height, colors = DEFAULT_EXPLAIN_COLO
|
|
|
531
550
|
return padded;
|
|
532
551
|
}
|
|
533
552
|
|
|
534
|
-
// src/ui/editor-screen.tsx
|
|
553
|
+
// packages/archymedes-cli/src/ui/editor-screen.tsx
|
|
535
554
|
import { jsxDEV } from "@termuijs/jsx/jsx-dev-runtime";
|
|
536
555
|
var Panel = Box;
|
|
537
556
|
var Line = Text;
|
|
@@ -543,8 +562,22 @@ function panelWidthFor(columns) {
|
|
|
543
562
|
return 0;
|
|
544
563
|
return Math.min(MAX_PANEL_COLUMNS, Math.floor(columns * 0.38), columns - MIN_CODE_COLUMNS);
|
|
545
564
|
}
|
|
546
|
-
function EditorScreen({ columns, rows, path, content, onExit, palette = NO_COLOR_PALETTE, explain }) {
|
|
565
|
+
function EditorScreen({ columns, rows, path, content, onExit, palette = NO_COLOR_PALETTE, explain, autosave, autosaveDelayMs = 1000 }) {
|
|
547
566
|
const [state, setState] = useState(() => initialEditorState(path, content, Math.max(1, rows - CHROME_ROWS)));
|
|
567
|
+
const timer = useRef(undefined);
|
|
568
|
+
const text = editorContent(state);
|
|
569
|
+
useEffect(() => {
|
|
570
|
+
if (!autosave || !state.dirty || state.confirmLeave)
|
|
571
|
+
return;
|
|
572
|
+
const pending = text;
|
|
573
|
+
timer.current = setTimeout(() => {
|
|
574
|
+
autosave(pending).then(() => setState((current) => applyEditorAction(current, { kind: "autosaved", content: pending }).state), () => setState((current) => ({ ...current, message: "auto-save failed — Ctrl+S to retry" })));
|
|
575
|
+
}, autosaveDelayMs);
|
|
576
|
+
return () => {
|
|
577
|
+
if (timer.current)
|
|
578
|
+
clearTimeout(timer.current);
|
|
579
|
+
};
|
|
580
|
+
}, [text, state.dirty, state.confirmLeave]);
|
|
548
581
|
const [panel, setPanel] = useState(() => initialExplainPanelState());
|
|
549
582
|
const panelWidth = panel.open ? panelWidthFor(columns) : 0;
|
|
550
583
|
const codeWidth = panelWidth > 0 ? columns - panelWidth - 1 : columns;
|
|
@@ -554,7 +587,7 @@ function EditorScreen({ columns, rows, path, content, onExit, palette = NO_COLOR
|
|
|
554
587
|
return;
|
|
555
588
|
}
|
|
556
589
|
setPanel((current) => withAiExplanation(current, { status: "loading" }));
|
|
557
|
-
explain(currentContent, path).then((
|
|
590
|
+
explain(currentContent, path).then((text2) => setPanel((current) => withAiExplanation(current, { status: "ready", text: text2 })), (error) => setPanel((current) => withAiExplanation(current, { status: "error", message: error instanceof Error ? error.message : String(error) })));
|
|
558
591
|
};
|
|
559
592
|
useInput((input, key) => {
|
|
560
593
|
if (key?.ctrl && key?.key === "e") {
|
|
@@ -629,6 +662,7 @@ async function runEditorScreen(options) {
|
|
|
629
662
|
if (settled)
|
|
630
663
|
return;
|
|
631
664
|
settled = true;
|
|
665
|
+
exitTopTermUIApp();
|
|
632
666
|
resolve(saved);
|
|
633
667
|
};
|
|
634
668
|
renderApp(EditorScreen, {
|
|
@@ -638,6 +672,7 @@ async function runEditorScreen(options) {
|
|
|
638
672
|
content: options.content,
|
|
639
673
|
palette: options.palette,
|
|
640
674
|
explain: options.explain,
|
|
675
|
+
autosave: options.autosave,
|
|
641
676
|
onExit: finish,
|
|
642
677
|
fullscreen: true
|
|
643
678
|
}).catch(() => finish(undefined));
|