archymedes-cli 2.2.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/README.md +17 -7
- package/dist/{archymedes-76z6n643.mjs → archymedes-06fh0z84.mjs} +233 -12
- package/dist/archymedes-130jt0wr.mjs +1231 -0
- package/dist/{archymedes-pg3pvh9r.mjs → archymedes-138genyy.mjs} +214 -5
- package/dist/{archymedes-sc3mwttb.mjs → archymedes-2kvjaajw.mjs} +66 -25
- package/dist/archymedes-5vhvv8kr.mjs +1169 -0
- package/dist/{archymedes-wjaqydyg.mjs → archymedes-a3ms7jvr.mjs} +45 -29
- package/dist/{archymedes-cdgejs3p.mjs → archymedes-bmtdqqwt.mjs} +17 -44
- package/dist/{archymedes-npcrm9a0.mjs → archymedes-d3azqkay.mjs} +537 -9
- package/dist/archymedes-main.mjs +31452 -25912
- package/dist/archymedes-w4bjfye7.mjs +280 -0
- package/dist/{editor-screen-1b3z96tn.mjs → editor-screen-e01mn7dd.mjs} +62 -26
- package/dist/{factory-96yy6mxr.mjs → factory-hyv8agr0.mjs} +1 -1
- package/dist/{file-screen-m7q1xcer.mjs → file-screen-stcxznwy.mjs} +10 -8
- package/dist/guide-screen-w5nb9sry.mjs +273 -0
- package/dist/pager-screen-aamt6xv0.mjs +155 -0
- package/dist/projection-x6x6hm9t.mjs +248 -0
- package/dist/workspace-screen-62k6hnq7.mjs +70 -0
- package/package.json +1 -1
- package/dist/archymedes-5zn4zp84.mjs +0 -646
- package/dist/archymedes-r54qthg5.mjs +0 -495
- package/dist/guide-screen-aj9n9v80.mjs +0 -569
- package/dist/workspace-screen-w88mcw4w.mjs +0 -241
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
SpringAnimator,
|
|
3
3
|
paginator
|
|
4
|
-
} from "./archymedes-
|
|
4
|
+
} from "./archymedes-5vhvv8kr.mjs";
|
|
5
5
|
import {
|
|
6
6
|
UNICODE_GLYPHS,
|
|
7
|
+
clipTo,
|
|
7
8
|
visibleWidth
|
|
8
|
-
} from "./archymedes-
|
|
9
|
+
} from "./archymedes-130jt0wr.mjs";
|
|
9
10
|
|
|
10
|
-
// packages/archymedes-cli/src/chooser.ts
|
|
11
|
+
// packages/archymedes-cli/src/ui/chooser.ts
|
|
11
12
|
var ALL_CHROME = { title: true, status: true, pagination: true, help: true };
|
|
12
13
|
function chromeOf(chrome) {
|
|
13
14
|
return { ...ALL_CHROME, ...chrome };
|
|
@@ -49,6 +50,7 @@ function advanceChooser(state, items, input, options = {}) {
|
|
|
49
50
|
const last = Math.max(0, visible.length - 1);
|
|
50
51
|
const page = options.page ?? 8;
|
|
51
52
|
const clamp = (index) => Math.max(0, Math.min(last, index));
|
|
53
|
+
state = { ...state, selected: clamp(state.selected) };
|
|
52
54
|
const keep = state.chrome === undefined ? {} : { chrome: state.chrome };
|
|
53
55
|
if (name === "escape" && options.filter && state.query !== "")
|
|
54
56
|
return { state: { selected: 0, query: "", ...keep } };
|
|
@@ -121,7 +123,7 @@ function renderChooser(state, items, options) {
|
|
|
121
123
|
const fadingOut = !active && index === options.transitionFrom;
|
|
122
124
|
const number = offset < 9 ? `${offset + 1}.` : " ";
|
|
123
125
|
const furniture = visibleWidth(` ${active ? ">" : " "} ${number} `) + 2;
|
|
124
|
-
if (width < furniture) {
|
|
126
|
+
if (width < furniture + 1) {
|
|
125
127
|
lines.push(active ? paint.green(clip(`${glyphs.prompt}${item.label}`, width)) : clip(item.label, width));
|
|
126
128
|
continue;
|
|
127
129
|
}
|
|
@@ -141,7 +143,8 @@ function renderChooser(state, items, options) {
|
|
|
141
143
|
}
|
|
142
144
|
const position = visible.length > height && chrome.pagination ? ` ${paginator(state.selected, visible.length)}` : "";
|
|
143
145
|
if (chrome.help) {
|
|
144
|
-
|
|
146
|
+
const legend = options.legend !== undefined && options.filter && state.query !== "" ? options.legend.replace(/Esc\b[^·]*$/, "Esc clear filter") : options.legend;
|
|
147
|
+
lines.push(paint.dim(clip(` ${legend ?? `${glyphs.arrowUp}${glyphs.arrowDown} move ${glyphs.middot} Enter choose ${glyphs.middot} ${options.filter ? `type to filter ${glyphs.middot} ` : ""}${options.filter ? "Esc clear/back" : "Esc back"}`}${position}`, width)));
|
|
145
148
|
} else if (position) {
|
|
146
149
|
lines.push(paint.dim(clip(position, width)));
|
|
147
150
|
}
|
|
@@ -150,22 +153,6 @@ function renderChooser(state, items, options) {
|
|
|
150
153
|
return lines.join(`
|
|
151
154
|
`);
|
|
152
155
|
}
|
|
153
|
-
function clipTo(text, width, glyphs = UNICODE_GLYPHS) {
|
|
154
|
-
if (width <= 0)
|
|
155
|
-
return "";
|
|
156
|
-
if (visibleWidth(text) <= width)
|
|
157
|
-
return text;
|
|
158
|
-
const mark = visibleWidth(glyphs.ellipsis) < width ? glyphs.ellipsis : "";
|
|
159
|
-
const budget = width - visibleWidth(mark);
|
|
160
|
-
let out = "";
|
|
161
|
-
const segments = typeof Intl.Segmenter === "function" ? [...new Intl.Segmenter(undefined, { granularity: "grapheme" }).segment(text)].map((entry) => entry.segment) : [...text];
|
|
162
|
-
for (const segment of segments) {
|
|
163
|
-
if (visibleWidth(out + segment) > budget)
|
|
164
|
-
break;
|
|
165
|
-
out += segment;
|
|
166
|
-
}
|
|
167
|
-
return `${out}${mark}`;
|
|
168
|
-
}
|
|
169
156
|
async function runChooser(keys, items, paint, options) {
|
|
170
157
|
let state = { selected: Math.max(0, Math.min(options.initialIndex ?? 0, Math.max(0, items.length - 1))), query: "" };
|
|
171
158
|
const liveOptions = () => {
|
|
@@ -173,7 +160,9 @@ async function runChooser(keys, items, paint, options) {
|
|
|
173
160
|
const height = Math.max(1, Math.min(options.height ?? 10, size?.height ?? Number.POSITIVE_INFINITY));
|
|
174
161
|
return { ...options, width: size?.width ?? options.width, height };
|
|
175
162
|
};
|
|
176
|
-
|
|
163
|
+
let list = items;
|
|
164
|
+
let pendingDelete;
|
|
165
|
+
paint(renderChooser(state, list, liveOptions()));
|
|
177
166
|
let glide;
|
|
178
167
|
const settleGlide = () => {
|
|
179
168
|
glide?.stop();
|
|
@@ -181,9 +170,36 @@ async function runChooser(keys, items, paint, options) {
|
|
|
181
170
|
};
|
|
182
171
|
try {
|
|
183
172
|
for await (const input of keys) {
|
|
173
|
+
if (pendingDelete && options.onDelete) {
|
|
174
|
+
const target = pendingDelete;
|
|
175
|
+
pendingDelete = undefined;
|
|
176
|
+
if (input.str === "y" || input.str === "Y") {
|
|
177
|
+
const outcome = await options.onDelete(target);
|
|
178
|
+
if (outcome.deleted) {
|
|
179
|
+
list = list.filter((item) => item !== target);
|
|
180
|
+
const remaining = filterItems(list, state.query).length;
|
|
181
|
+
state = { ...state, selected: Math.max(0, Math.min(state.selected, remaining - 1)), status: `deleted "${target.label}"` };
|
|
182
|
+
} else {
|
|
183
|
+
state = { ...state, status: outcome.reason };
|
|
184
|
+
}
|
|
185
|
+
} else {
|
|
186
|
+
state = { ...state, status: "kept" };
|
|
187
|
+
}
|
|
188
|
+
paint(renderChooser(state, list, liveOptions()));
|
|
189
|
+
continue;
|
|
190
|
+
}
|
|
191
|
+
if (options.onDelete && (input.key.name === "delete" || input.key.ctrl && input.key.name === "d")) {
|
|
192
|
+
const target = filterItems(list, state.query)[state.selected];
|
|
193
|
+
if (target && !target.pinned) {
|
|
194
|
+
pendingDelete = target;
|
|
195
|
+
state = { ...state, status: `Delete "${target.label}"? y/n` };
|
|
196
|
+
paint(renderChooser(state, list, liveOptions()));
|
|
197
|
+
}
|
|
198
|
+
continue;
|
|
199
|
+
}
|
|
184
200
|
const current = liveOptions();
|
|
185
201
|
const previousSelected = state.selected;
|
|
186
|
-
const step = advanceChooser(state,
|
|
202
|
+
const step = advanceChooser(state, list, input, {
|
|
187
203
|
filter: options.filter ?? false,
|
|
188
204
|
page: options.page ?? current.height ?? 8,
|
|
189
205
|
...current.height === undefined ? {} : { height: current.height }
|
|
@@ -193,24 +209,24 @@ async function runChooser(keys, items, paint, options) {
|
|
|
193
209
|
settleGlide();
|
|
194
210
|
if (step.done.index === undefined)
|
|
195
211
|
return;
|
|
196
|
-
return filterItems(
|
|
212
|
+
return filterItems(list, state.query)[step.done.index]?.value;
|
|
197
213
|
}
|
|
198
214
|
settleGlide();
|
|
199
215
|
const isSingleStep = (input.key.name === "up" || input.key.name === "down") && Math.abs(state.selected - previousSelected) === 1;
|
|
200
216
|
const motion = options.motion ?? (process.env.ARCHYMEDES_NO_MOTION !== "1" && process.env.NO_COLOR === undefined && process.env.TERM !== "dumb");
|
|
201
217
|
if (!motion || !isSingleStep || previousSelected === state.selected) {
|
|
202
|
-
paint(renderChooser(state,
|
|
218
|
+
paint(renderChooser(state, list, liveOptions()));
|
|
203
219
|
continue;
|
|
204
220
|
}
|
|
205
|
-
paint(renderChooser(state,
|
|
221
|
+
paint(renderChooser(state, list, { ...liveOptions(), transitionFrom: previousSelected, focusProgress: 0 }));
|
|
206
222
|
const animator = new SpringAnimator(0, (value) => {
|
|
207
223
|
if (value < 0.95) {
|
|
208
|
-
paint(renderChooser(state,
|
|
224
|
+
paint(renderChooser(state, list, { ...liveOptions(), transitionFrom: value < 0.5 ? previousSelected : undefined, focusProgress: value }));
|
|
209
225
|
return;
|
|
210
226
|
}
|
|
211
227
|
animator.stop();
|
|
212
228
|
glide = undefined;
|
|
213
|
-
paint(renderChooser(state,
|
|
229
|
+
paint(renderChooser(state, list, liveOptions()));
|
|
214
230
|
}, { intervalMs: 30 });
|
|
215
231
|
glide = animator;
|
|
216
232
|
animator.retarget(1);
|
|
@@ -221,4 +237,4 @@ async function runChooser(keys, items, paint, options) {
|
|
|
221
237
|
return;
|
|
222
238
|
}
|
|
223
239
|
|
|
224
|
-
export { INITIAL_CHOOSER_STATE, windowStart, terminalColumns, renderChooser,
|
|
240
|
+
export { INITIAL_CHOOSER_STATE, filterItems, windowStart, terminalColumns, renderChooser, runChooser };
|
|
@@ -1,52 +1,25 @@
|
|
|
1
1
|
import {
|
|
2
|
+
BOLD,
|
|
3
|
+
DIM,
|
|
2
4
|
UNICODE_GLYPHS,
|
|
3
5
|
borderGlyphsFor,
|
|
6
|
+
paint,
|
|
7
|
+
paintAll,
|
|
8
|
+
roleCode,
|
|
4
9
|
visibleWidth
|
|
5
|
-
} from "./archymedes-
|
|
10
|
+
} from "./archymedes-130jt0wr.mjs";
|
|
6
11
|
|
|
7
|
-
// packages/archymedes-cli/src/
|
|
8
|
-
var
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
var GREEN = "\x1B[32m";
|
|
14
|
-
var YELLOW = "\x1B[33m";
|
|
15
|
-
var MAGENTA = "\x1B[35m";
|
|
16
|
-
var CYAN = "\x1B[36m";
|
|
17
|
-
function paint(text, code, depth) {
|
|
18
|
-
return depth === "none" || code === "" ? text : `${code}${text}${RESET}`;
|
|
19
|
-
}
|
|
20
|
-
function paintAll(text, codes, depth) {
|
|
21
|
-
return depth === "none" || codes.length === 0 ? text : `${codes.join("")}${text}${RESET}`;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// packages/archymedes-cli/src/sections.ts
|
|
25
|
-
var FALLBACK_TONE_CODE = {
|
|
26
|
-
neutral: DIM,
|
|
27
|
-
good: GREEN,
|
|
28
|
-
bad: RED,
|
|
29
|
-
warn: YELLOW,
|
|
30
|
-
accent: CYAN
|
|
12
|
+
// packages/archymedes-cli/src/render/sections.ts
|
|
13
|
+
var TONE_ROLE = {
|
|
14
|
+
good: "success",
|
|
15
|
+
bad: "error",
|
|
16
|
+
warn: "warning",
|
|
17
|
+
accent: "primary"
|
|
31
18
|
};
|
|
32
19
|
function toneCode(tone, style) {
|
|
33
20
|
if (style.depth === "none")
|
|
34
21
|
return "";
|
|
35
|
-
|
|
36
|
-
if (!palette)
|
|
37
|
-
return FALLBACK_TONE_CODE[tone];
|
|
38
|
-
switch (tone) {
|
|
39
|
-
case "neutral":
|
|
40
|
-
return DIM;
|
|
41
|
-
case "good":
|
|
42
|
-
return palette.success || FALLBACK_TONE_CODE.good;
|
|
43
|
-
case "bad":
|
|
44
|
-
return palette.error || FALLBACK_TONE_CODE.bad;
|
|
45
|
-
case "warn":
|
|
46
|
-
return palette.warning || FALLBACK_TONE_CODE.warn;
|
|
47
|
-
case "accent":
|
|
48
|
-
return palette.primary || FALLBACK_TONE_CODE.accent;
|
|
49
|
-
}
|
|
22
|
+
return tone === "neutral" ? DIM : roleCode(TONE_ROLE[tone], style.palette, style.depth);
|
|
50
23
|
}
|
|
51
24
|
var GUTTER = " ";
|
|
52
25
|
function setOf(style) {
|
|
@@ -153,13 +126,13 @@ function outcomeMark(outcome, style) {
|
|
|
153
126
|
const glyphs = setOf(style);
|
|
154
127
|
switch (outcome) {
|
|
155
128
|
case "pass":
|
|
156
|
-
return paint(glyphs.check,
|
|
129
|
+
return paint(glyphs.check, toneCode("good", style), style.depth);
|
|
157
130
|
case "fail":
|
|
158
|
-
return paint(glyphs.cross,
|
|
131
|
+
return paint(glyphs.cross, toneCode("bad", style), style.depth);
|
|
159
132
|
case "skip":
|
|
160
133
|
return paint(glyphs.circleEmpty, DIM, style.depth);
|
|
161
134
|
default:
|
|
162
|
-
return paint(glyphs.pending,
|
|
135
|
+
return paint(glyphs.pending, toneCode("accent", style), style.depth);
|
|
163
136
|
}
|
|
164
137
|
}
|
|
165
138
|
function keyValues(rows, style) {
|
|
@@ -168,4 +141,4 @@ function keyValues(rows, style) {
|
|
|
168
141
|
`);
|
|
169
142
|
}
|
|
170
143
|
|
|
171
|
-
export {
|
|
144
|
+
export { toneCode, GUTTER, rule, heading, note, panel, clip, outcomeMark, keyValues };
|