@pugi/cli 0.1.0-alpha.5 → 0.1.0-alpha.7
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/core/auto-open-browser.js +128 -0
- package/dist/core/clipboard.js +70 -0
- package/dist/core/repl/clipboard-read.js +174 -0
- package/dist/core/repl/history-search.js +175 -0
- package/dist/core/repl/history.js +172 -0
- package/dist/core/repl/kill-ring.js +138 -0
- package/dist/core/repl/session.js +44 -0
- package/dist/core/repl/slash-commands.js +8 -0
- package/dist/core/settings.js +13 -0
- package/dist/runtime/cli.js +392 -66
- package/dist/runtime/update-check.js +294 -0
- package/dist/tools/registry.js +1 -0
- package/dist/tools/web-fetch.js +535 -0
- package/dist/tui/device-flow.js +142 -0
- package/dist/tui/input-box.js +410 -27
- package/dist/tui/render.js +57 -0
- package/dist/tui/repl-render.js +1 -1
- package/dist/tui/repl.js +8 -1
- package/dist/tui/slash-palette.js +69 -0
- package/dist/tui/update-banner.js +8 -0
- package/package.json +7 -2
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { SLASH_COMMAND_HELP } from '../core/repl/slash-commands.js';
|
|
4
|
+
export const PALETTE_ROW_LIMIT = 8;
|
|
5
|
+
/**
|
|
6
|
+
* Compute the visible palette window for a given input buffer.
|
|
7
|
+
* Centralises the "starts-with-slash → filter SLASH_COMMAND_HELP"
|
|
8
|
+
* logic so the input box and the unit test agree on the shape.
|
|
9
|
+
*
|
|
10
|
+
* Behaviour:
|
|
11
|
+
* - Empty / non-slash buffer → empty result; palette stays hidden.
|
|
12
|
+
* - `/` alone → all registry rows (the operator wants to browse).
|
|
13
|
+
* - `/he` → rows whose name starts with `he` (case-insensitive).
|
|
14
|
+
* - Capped at PALETTE_ROW_LIMIT; the input box renders a hint when
|
|
15
|
+
* `totalBeforeLimit > rows.length`.
|
|
16
|
+
*/
|
|
17
|
+
export function filterPalette(buffer) {
|
|
18
|
+
if (!buffer.startsWith('/')) {
|
|
19
|
+
return { rows: [], totalBeforeLimit: 0 };
|
|
20
|
+
}
|
|
21
|
+
// Treat anything past the first whitespace as args - palette only
|
|
22
|
+
// filters on the command name itself.
|
|
23
|
+
const headEnd = buffer.indexOf(' ');
|
|
24
|
+
const head = headEnd === -1 ? buffer.slice(1) : buffer.slice(1, headEnd);
|
|
25
|
+
const prefix = head.toLowerCase();
|
|
26
|
+
// Lowercase row.name too so a registry entry like `Help` still matches
|
|
27
|
+
// an operator typing `/he`. Today every entry is lowercase, but the
|
|
28
|
+
// type contract on SlashCommandHelp.name does not enforce that, and
|
|
29
|
+
// a future addition would silently disappear from the palette
|
|
30
|
+
// without this guard. Codex P2.
|
|
31
|
+
const all = prefix.length === 0
|
|
32
|
+
? SLASH_COMMAND_HELP
|
|
33
|
+
: SLASH_COMMAND_HELP.filter((row) => row.name.toLowerCase().startsWith(prefix));
|
|
34
|
+
return {
|
|
35
|
+
rows: all.slice(0, PALETTE_ROW_LIMIT),
|
|
36
|
+
totalBeforeLimit: all.length,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Compute the auto-complete result for the Tab key. Picks the focused
|
|
41
|
+
* row when there is one, falls back to the longest common prefix
|
|
42
|
+
* otherwise (bash-like behaviour). Returns the new buffer the input
|
|
43
|
+
* box should adopt, or `null` when there is nothing to complete.
|
|
44
|
+
*/
|
|
45
|
+
export function completePalette(buffer, rows, focusedIndex) {
|
|
46
|
+
if (rows.length === 0)
|
|
47
|
+
return null;
|
|
48
|
+
const target = rows[focusedIndex] ?? rows[0];
|
|
49
|
+
if (!target)
|
|
50
|
+
return null;
|
|
51
|
+
// Preserve any args the operator has already started typing after a
|
|
52
|
+
// space; only swap the head.
|
|
53
|
+
const headEnd = buffer.indexOf(' ');
|
|
54
|
+
const tail = headEnd === -1 ? '' : buffer.slice(headEnd);
|
|
55
|
+
return `/${target.name}${tail}`;
|
|
56
|
+
}
|
|
57
|
+
export function SlashPalette(props) {
|
|
58
|
+
if (props.rows.length === 0)
|
|
59
|
+
return null;
|
|
60
|
+
const total = props.totalBeforeLimit ?? props.rows.length;
|
|
61
|
+
const overflow = total - props.rows.length;
|
|
62
|
+
return (_jsxs(Box, { flexDirection: "column", marginTop: 0, paddingLeft: 2, children: [props.rows.map((row, idx) => {
|
|
63
|
+
const focused = idx === props.focusedIndex;
|
|
64
|
+
const glyph = focused ? '▸' : '·';
|
|
65
|
+
const cmd = `/${row.name}${row.args ? ` ${row.args}` : ''}`.padEnd(22, ' ');
|
|
66
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: focused ? 'cyan' : 'gray', children: `${glyph} ` }), _jsx(Text, { bold: focused, color: focused ? 'cyan' : undefined, dimColor: !focused, children: cmd }), _jsx(Text, { dimColor: true, children: row.gloss })] }, row.name));
|
|
67
|
+
}), overflow > 0 ? (_jsx(Box, { children: _jsx(Text, { dimColor: true, children: ` · ${overflow} more (keep typing to narrow)` }) })) : null, _jsx(Box, { children: _jsx(Text, { dimColor: true, children: ' ↑/↓ select · Tab complete · Enter run · Esc close' }) })] }));
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=slash-palette.js.map
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { upgradeCommand } from '../runtime/update-check.js';
|
|
4
|
+
export function UpdateBanner({ result }) {
|
|
5
|
+
const command = upgradeCommand(result.method);
|
|
6
|
+
return (_jsxs(Box, { flexDirection: "column", marginBottom: 1, children: [_jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: '─ ' }), _jsx(Text, { bold: true, color: "cyan", children: 'Pugi ' }), _jsx(Text, { children: result.installed }), _jsx(Text, { dimColor: true, children: ' (installed) → ' }), _jsx(Text, { bold: true, children: result.latest }), _jsx(Text, { dimColor: true, children: ' (latest)' })] }), _jsxs(Box, { children: [_jsx(Text, { dimColor: true, children: ' Update: ' }), _jsx(Text, { color: "cyan", children: command })] }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: ' Skip with PUGI_SKIP_UPDATE_BANNER=1' }) })] }));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=update-banner.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pugi/cli",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.7",
|
|
4
4
|
"description": "Pugi CLI — terminal-native software execution system",
|
|
5
5
|
"homepage": "https://pugi.io",
|
|
6
6
|
"repository": {
|
|
@@ -38,16 +38,21 @@
|
|
|
38
38
|
"access": "public"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
+
"@mozilla/readability": "^0.6.0",
|
|
41
42
|
"ink": "^5.0.1",
|
|
43
|
+
"linkedom": "^0.18.12",
|
|
42
44
|
"react": "^18.3.1",
|
|
43
45
|
"tinyglobby": "^0.2.16",
|
|
46
|
+
"turndown": "^7.2.4",
|
|
47
|
+
"undici": "^8.3.0",
|
|
44
48
|
"zod": "^3.23.0",
|
|
45
49
|
"@pugi/personas": "0.1.0",
|
|
46
|
-
"@pugi/sdk": "0.1.0-alpha.
|
|
50
|
+
"@pugi/sdk": "0.1.0-alpha.7"
|
|
47
51
|
},
|
|
48
52
|
"devDependencies": {
|
|
49
53
|
"@types/node": "^22.0.0",
|
|
50
54
|
"@types/react": "^18.3.3",
|
|
55
|
+
"@types/turndown": "^5.0.6",
|
|
51
56
|
"ink-testing-library": "^4.0.0",
|
|
52
57
|
"tsx": "^4.19.0",
|
|
53
58
|
"typescript": "~5.6.0"
|