@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.
Files changed (40) hide show
  1. package/dist/core/bare-mode/index.js +107 -0
  2. package/dist/core/diagnostics/probes/bare-mode.js +42 -0
  3. package/dist/core/engine/native-pugi.js +21 -10
  4. package/dist/core/engine/prompts.js +30 -2
  5. package/dist/core/engine/tool-bridge.js +32 -0
  6. package/dist/core/feedback/queue.js +177 -0
  7. package/dist/core/feedback/submitter.js +145 -0
  8. package/dist/core/onboarding/marker.js +111 -0
  9. package/dist/core/onboarding/telemetry-state.js +108 -0
  10. package/dist/core/output-style/presets.js +176 -0
  11. package/dist/core/output-style/state.js +185 -0
  12. package/dist/core/permissions/index.js +1 -1
  13. package/dist/core/permissions/state.js +55 -0
  14. package/dist/core/repl/session.js +375 -12
  15. package/dist/core/repl/slash-commands.js +99 -1
  16. package/dist/core/repl/workspace-context.js +22 -0
  17. package/dist/core/share/formatter.js +271 -0
  18. package/dist/core/share/redactor.js +221 -0
  19. package/dist/core/share/uploader.js +267 -0
  20. package/dist/core/todos/invariant.js +10 -0
  21. package/dist/core/todos/state.js +177 -0
  22. package/dist/runtime/cli.js +386 -1
  23. package/dist/runtime/commands/doctor.js +8 -0
  24. package/dist/runtime/commands/feedback.js +184 -0
  25. package/dist/runtime/commands/onboarding.js +275 -0
  26. package/dist/runtime/commands/plan.js +143 -0
  27. package/dist/runtime/commands/share.js +316 -0
  28. package/dist/runtime/commands/stickers.js +82 -0
  29. package/dist/runtime/commands/style.js +194 -0
  30. package/dist/runtime/version.js +1 -1
  31. package/dist/tools/registry.js +8 -0
  32. package/dist/tools/todo-write.js +184 -0
  33. package/dist/tui/compact-banner.js +28 -1
  34. package/dist/tui/conversation-pane.js +13 -0
  35. package/dist/tui/feedback-prompt.js +156 -0
  36. package/dist/tui/onboarding-wizard.js +240 -0
  37. package/dist/tui/repl-render.js +9 -1
  38. package/dist/tui/stickers-art.js +136 -0
  39. package/dist/tui/style-table.js +22 -0
  40. package/package.json +2 -2
@@ -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
- if (process.env.PUGI_NO_AUTO_INIT !== '1' && isProjectRoot(process.cwd())) {
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.21",
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.21"
57
+ "@pugi/sdk": "0.1.0-beta.22"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@types/node": "^22.0.0",