@pugi/cli 0.1.0-beta.21 → 0.1.0-beta.22
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/bare-mode/index.js +107 -0
- package/dist/core/diagnostics/probes/bare-mode.js +42 -0
- package/dist/core/engine/native-pugi.js +21 -10
- package/dist/core/engine/prompts.js +30 -2
- package/dist/core/engine/tool-bridge.js +32 -0
- package/dist/core/feedback/queue.js +177 -0
- package/dist/core/feedback/submitter.js +145 -0
- package/dist/core/onboarding/marker.js +111 -0
- package/dist/core/onboarding/telemetry-state.js +108 -0
- package/dist/core/output-style/presets.js +176 -0
- package/dist/core/output-style/state.js +185 -0
- package/dist/core/permissions/index.js +1 -1
- package/dist/core/permissions/state.js +55 -0
- package/dist/core/repl/session.js +375 -12
- package/dist/core/repl/slash-commands.js +99 -1
- package/dist/core/repl/workspace-context.js +22 -0
- package/dist/core/share/formatter.js +271 -0
- package/dist/core/share/redactor.js +221 -0
- package/dist/core/share/uploader.js +267 -0
- package/dist/core/todos/invariant.js +10 -0
- package/dist/core/todos/state.js +177 -0
- package/dist/runtime/cli.js +386 -1
- package/dist/runtime/commands/doctor.js +8 -0
- package/dist/runtime/commands/feedback.js +184 -0
- package/dist/runtime/commands/onboarding.js +275 -0
- package/dist/runtime/commands/plan.js +143 -0
- package/dist/runtime/commands/share.js +316 -0
- package/dist/runtime/commands/stickers.js +82 -0
- package/dist/runtime/commands/style.js +194 -0
- package/dist/runtime/version.js +1 -1
- package/dist/tools/registry.js +8 -0
- package/dist/tools/todo-write.js +184 -0
- package/dist/tui/compact-banner.js +28 -1
- package/dist/tui/conversation-pane.js +13 -0
- package/dist/tui/feedback-prompt.js +156 -0
- package/dist/tui/onboarding-wizard.js +240 -0
- package/dist/tui/repl-render.js +9 -1
- package/dist/tui/stickers-art.js +136 -0
- package/dist/tui/style-table.js +22 -0
- package/package.json +2 -2
package/dist/tui/repl-render.js
CHANGED
|
@@ -70,7 +70,15 @@ export async function renderRepl(options) {
|
|
|
70
70
|
// the same auto-init UX as a Node operator. Already-bound `.pugi/`
|
|
71
71
|
// dirs also opt back in so the scaffold can fill any missing
|
|
72
72
|
// sub-artifacts the operator deleted.
|
|
73
|
-
|
|
73
|
+
// Leak L22 (2026-05-27): `--bare` (PUGI_BARE=1) ALSO suppresses the
|
|
74
|
+
// auto-init scaffold. Bare mode is the deterministic "fresh install
|
|
75
|
+
// anywhere" path — no `.pugi/` writes, no PUGI.md scaffold, no
|
|
76
|
+
// settings.json seed. The pre-existing PUGI_NO_AUTO_INIT escape
|
|
77
|
+
// hatch stays — bare mode just unions with it.
|
|
78
|
+
const { isBareMode } = await import('../core/bare-mode/index.js');
|
|
79
|
+
if (process.env.PUGI_NO_AUTO_INIT !== '1' &&
|
|
80
|
+
!isBareMode() &&
|
|
81
|
+
isProjectRoot(process.cwd())) {
|
|
74
82
|
try {
|
|
75
83
|
const { scaffoldPugiWorkspace } = await import('../runtime/cli.js');
|
|
76
84
|
await scaffoldPugiWorkspace({
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
/**
|
|
4
|
+
* Curated ASCII pug corpus. Five variants — wide enough that repeat
|
|
5
|
+
* invocations look fresh, narrow enough that every entry stays
|
|
6
|
+
* hand-vetted (no procedural slop). Each art block intentionally fits
|
|
7
|
+
* inside an 80-column terminal so the surrounding box border does not
|
|
8
|
+
* wrap on narrow shells.
|
|
9
|
+
*
|
|
10
|
+
* The trailing newline at the end of each `art` string is intentional —
|
|
11
|
+
* keeps the renderer's join logic uniform between the boxed and the
|
|
12
|
+
* `--ascii-only` paths.
|
|
13
|
+
*/
|
|
14
|
+
export const PUG_STICKERS = Object.freeze([
|
|
15
|
+
{
|
|
16
|
+
id: 'classic-face',
|
|
17
|
+
caption: 'classic pug face',
|
|
18
|
+
art: [
|
|
19
|
+
' _._ _,-\'""`-._',
|
|
20
|
+
' (,-.`._,\'( |\\`-/|',
|
|
21
|
+
' `-.-\' \\ )-`( , o o)',
|
|
22
|
+
' `- \\`_`"\'-',
|
|
23
|
+
].join('\n'),
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: 'sit-pose',
|
|
27
|
+
caption: 'sit, stay, ship',
|
|
28
|
+
art: [
|
|
29
|
+
' /\\___/\\',
|
|
30
|
+
' ( o o )',
|
|
31
|
+
' ( =^= )',
|
|
32
|
+
' (______)',
|
|
33
|
+
].join('\n'),
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
id: 'peek',
|
|
37
|
+
caption: 'peek-a-pug',
|
|
38
|
+
art: [
|
|
39
|
+
' __',
|
|
40
|
+
' ___/ \\___',
|
|
41
|
+
' / o o \\',
|
|
42
|
+
' | > ^ < |',
|
|
43
|
+
' \\__________/',
|
|
44
|
+
].join('\n'),
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
id: 'sleepy',
|
|
48
|
+
caption: 'sleepy pug, no Zzz today',
|
|
49
|
+
art: [
|
|
50
|
+
' .--.',
|
|
51
|
+
' / - -\\',
|
|
52
|
+
' ( ^ ^ )',
|
|
53
|
+
' \\ ^^ /',
|
|
54
|
+
' `----\'',
|
|
55
|
+
].join('\n'),
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'shipping',
|
|
59
|
+
caption: 'shipping pug',
|
|
60
|
+
art: [
|
|
61
|
+
' .---. .---.',
|
|
62
|
+
' |o_o| |o_o|',
|
|
63
|
+
' \\_^_/ \\_^_/',
|
|
64
|
+
' /| |\\ /| |\\',
|
|
65
|
+
' shipped • shipped',
|
|
66
|
+
].join('\n'),
|
|
67
|
+
},
|
|
68
|
+
]);
|
|
69
|
+
/**
|
|
70
|
+
* Curated rotating-quote pool. Brand voice gate (brandbook §08):
|
|
71
|
+
* `brief / dispatch / stop / agents / quit / shipped` are the power
|
|
72
|
+
* words; quotes lean on those and на the operator-mode register.
|
|
73
|
+
* Adding lines: keep each ≤ 64 chars so the boxed renderer never wraps,
|
|
74
|
+
* stay в the operator's voice, no AI attribution, no hype.
|
|
75
|
+
*/
|
|
76
|
+
export const PUG_QUOTES = Object.freeze([
|
|
77
|
+
'Pugi: your engineering co-pilot.',
|
|
78
|
+
'Brief it. It ships.',
|
|
79
|
+
'Built for operators, not for benchmarks.',
|
|
80
|
+
'Pugi: твой инженерный напарник.',
|
|
81
|
+
'Dispatch agents, not promises.',
|
|
82
|
+
'Small CLI. Loud workforce.',
|
|
83
|
+
'Engineering at the speed of brief.',
|
|
84
|
+
'Pugi: shipping is the default mode.',
|
|
85
|
+
]);
|
|
86
|
+
/**
|
|
87
|
+
* Clamp a raw rng draw to a safe array index. Handles every hostile
|
|
88
|
+
* shape the spec exercises:
|
|
89
|
+
* - rng returns NaN → fall back to 0
|
|
90
|
+
* - rng returns 1.0 → clamp to length-1 (Math.floor would land at n)
|
|
91
|
+
* - rng returns -ε → clamp to 0
|
|
92
|
+
* The caller hands в the corpus length; the helper never touches the
|
|
93
|
+
* corpus itself so it stays trivially testable.
|
|
94
|
+
*/
|
|
95
|
+
function safeIndex(raw, length) {
|
|
96
|
+
if (!Number.isFinite(raw))
|
|
97
|
+
return 0;
|
|
98
|
+
const floored = Math.floor(raw);
|
|
99
|
+
if (floored < 0)
|
|
100
|
+
return 0;
|
|
101
|
+
if (floored >= length)
|
|
102
|
+
return length - 1;
|
|
103
|
+
return floored;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Pick one art variant. Defaults to `Math.random` but the caller can
|
|
107
|
+
* inject a deterministic source — the spec uses a sequence-driven
|
|
108
|
+
* stub to assert the picker hits each entry в the corpus.
|
|
109
|
+
*/
|
|
110
|
+
export function pickArtVariant(rng = Math.random) {
|
|
111
|
+
const raw = rng() * PUG_STICKERS.length;
|
|
112
|
+
return PUG_STICKERS[safeIndex(raw, PUG_STICKERS.length)];
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Pick one rotating brand quote. Same contract as `pickArtVariant` —
|
|
116
|
+
* test-injectable rng so the spec can pin the chosen index.
|
|
117
|
+
*/
|
|
118
|
+
export function pickQuote(rng = Math.random) {
|
|
119
|
+
const raw = rng() * PUG_QUOTES.length;
|
|
120
|
+
return PUG_QUOTES[safeIndex(raw, PUG_QUOTES.length)];
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Plain-text renderer for the `--ascii-only` flag and the non-TTY shell
|
|
124
|
+
* path. Emits the art verbatim, then a blank line, then the quote.
|
|
125
|
+
* No box border — scripting use-case (`pugi stickers --ascii-only`
|
|
126
|
+
* piped to `figlet`, `lolcat`, or a regression-fixture file) gets a
|
|
127
|
+
* stable contract free of decorative ANSI noise.
|
|
128
|
+
*/
|
|
129
|
+
export function renderPugStickersText(art, quote) {
|
|
130
|
+
return `${art.art}\n\n${quote}`;
|
|
131
|
+
}
|
|
132
|
+
export function PugStickersArt({ art, quote }) {
|
|
133
|
+
const lines = art.art.split('\n');
|
|
134
|
+
return (_jsxs(Box, { flexDirection: "column", borderStyle: "round", paddingX: 1, children: [_jsxs(Box, { marginBottom: 1, children: [_jsx(Text, { bold: true, children: "Pugi stickers" }), _jsxs(Text, { dimColor: true, children: [" \u2014 ", art.caption] })] }), _jsx(Box, { flexDirection: "column", children: lines.map((line, i) => (_jsx(Text, { children: line }, `art-${i}`))) }), _jsx(Box, { marginTop: 1, children: _jsxs(Text, { dimColor: true, children: ["\"", quote, "\""] }) })] }));
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=stickers-art.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Text } from 'ink';
|
|
3
|
+
import { OUTPUT_STYLES, OUTPUT_STYLE_SLUGS, } from '../core/output-style/presets.js';
|
|
4
|
+
/**
|
|
5
|
+
* Banner above the table. Plain text (not bold) so the prefix `*`
|
|
6
|
+
* remains the dominant active-row cue.
|
|
7
|
+
*/
|
|
8
|
+
function buildBanner(active, source) {
|
|
9
|
+
return `Active style: ${active} (${source})`;
|
|
10
|
+
}
|
|
11
|
+
export function StyleTable({ active, source }) {
|
|
12
|
+
const slugWidth = Math.max('NAME'.length, ...OUTPUT_STYLE_SLUGS.map((slug) => slug.length));
|
|
13
|
+
return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Box, { marginBottom: 1, children: _jsx(Text, { bold: true, children: "Pugi output styles" }) }), _jsx(Box, { children: _jsx(Text, { dimColor: true, children: ` ${'NAME'.padEnd(slugWidth)} GLOSS` }) }), OUTPUT_STYLE_SLUGS.map((slug) => (_jsx(StyleRow, { slug: slug, active: active, slugWidth: slugWidth }, slug))), _jsx(Box, { marginTop: 1, children: _jsx(Text, { children: buildBanner(active, source) }) })] }));
|
|
14
|
+
}
|
|
15
|
+
function StyleRow({ slug, active, slugWidth }) {
|
|
16
|
+
const isActive = slug === active;
|
|
17
|
+
const marker = isActive ? '*' : ' ';
|
|
18
|
+
const slugPart = slug.padEnd(slugWidth, ' ');
|
|
19
|
+
const gloss = OUTPUT_STYLES[slug].gloss;
|
|
20
|
+
return (_jsxs(Box, { children: [_jsx(Text, { color: isActive ? 'green' : undefined, bold: isActive, children: `${marker} ${slugPart}` }), _jsx(Text, { children: ` ${gloss}` })] }));
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=style-table.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pugi/cli",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.22",
|
|
4
4
|
"description": "Pugi CLI - terminal-native software execution system",
|
|
5
5
|
"homepage": "https://pugi.io",
|
|
6
6
|
"repository": {
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"undici": "^8.3.0",
|
|
55
55
|
"zod": "^3.23.0",
|
|
56
56
|
"@pugi/personas": "0.1.2",
|
|
57
|
-
"@pugi/sdk": "0.1.0-beta.
|
|
57
|
+
"@pugi/sdk": "0.1.0-beta.22"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@types/node": "^22.0.0",
|