@ritualai/cli 0.25.0 → 0.36.8

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 (61) hide show
  1. package/dist/commands/build.js +89 -0
  2. package/dist/commands/build.js.map +1 -0
  3. package/dist/commands/init.js +93 -109
  4. package/dist/commands/init.js.map +1 -1
  5. package/dist/commands/uninstall.js +6 -1
  6. package/dist/commands/uninstall.js.map +1 -1
  7. package/dist/index.js +18 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/lib/agents/configure-mcp.js +63 -0
  10. package/dist/lib/agents/configure-mcp.js.map +1 -1
  11. package/dist/lib/agents/launch.js +70 -0
  12. package/dist/lib/agents/launch.js.map +1 -0
  13. package/dist/lib/agents/providers.js +8 -2
  14. package/dist/lib/agents/providers.js.map +1 -1
  15. package/dist/lib/final-cta-box.js +22 -10
  16. package/dist/lib/final-cta-box.js.map +1 -1
  17. package/dist/lib/help-style.js +65 -0
  18. package/dist/lib/help-style.js.map +1 -0
  19. package/dist/lib/onboarding-state.js +9 -8
  20. package/dist/lib/onboarding-state.js.map +1 -1
  21. package/dist/lib/uninstall-plan.js +18 -1
  22. package/dist/lib/uninstall-plan.js.map +1 -1
  23. package/dist/lib/workspace-explainer.js +42 -111
  24. package/dist/lib/workspace-explainer.js.map +1 -1
  25. package/dist/lib/workspace-flow.js +4 -1
  26. package/dist/lib/workspace-flow.js.map +1 -1
  27. package/package.json +1 -1
  28. package/skills/claude-code/ritual/.ritual-bundle.json +3 -2
  29. package/skills/claude-code/ritual/SKILL.md +8 -0
  30. package/skills/claude-code/ritual/references/build-flow.md +474 -414
  31. package/skills/claude-code/ritual/references/cli-output-contract.md +90 -34
  32. package/skills/claude-code/ritual/references/lite-flow.md +484 -421
  33. package/skills/codex/ritual/.ritual-bundle.json +3 -2
  34. package/skills/codex/ritual/SKILL.md +8 -0
  35. package/skills/codex/ritual/references/build-flow.md +474 -414
  36. package/skills/codex/ritual/references/cli-output-contract.md +90 -34
  37. package/skills/codex/ritual/references/lite-flow.md +484 -421
  38. package/skills/cursor/ritual/.ritual-bundle.json +3 -2
  39. package/skills/cursor/ritual/SKILL.md +8 -0
  40. package/skills/cursor/ritual/references/build-flow.md +474 -414
  41. package/skills/cursor/ritual/references/cli-output-contract.md +90 -34
  42. package/skills/cursor/ritual/references/lite-flow.md +484 -421
  43. package/skills/gemini/ritual/.ritual-bundle.json +3 -2
  44. package/skills/gemini/ritual/SKILL.md +8 -0
  45. package/skills/gemini/ritual/references/build-flow.md +474 -414
  46. package/skills/gemini/ritual/references/cli-output-contract.md +90 -34
  47. package/skills/gemini/ritual/references/lite-flow.md +484 -421
  48. package/skills/kiro/ritual/.ritual-bundle.json +3 -2
  49. package/skills/kiro/ritual/SKILL.md +8 -0
  50. package/skills/kiro/ritual/references/build-flow.md +474 -414
  51. package/skills/kiro/ritual/references/cli-output-contract.md +90 -34
  52. package/skills/kiro/ritual/references/lite-flow.md +484 -421
  53. package/skills/vscode/ritual/.ritual-bundle.json +3 -2
  54. package/skills/vscode/ritual/SKILL.md +8 -0
  55. package/skills/vscode/ritual/references/build-flow.md +474 -414
  56. package/skills/vscode/ritual/references/cli-output-contract.md +90 -34
  57. package/skills/vscode/ritual/references/lite-flow.md +484 -421
  58. package/dist/lib/build-flow-explainer.js +0 -226
  59. package/dist/lib/build-flow-explainer.js.map +0 -1
  60. package/dist/lib/persona-picker.js +0 -171
  61. package/dist/lib/persona-picker.js.map +0 -1
@@ -1,226 +0,0 @@
1
- "use strict";
2
- /**
3
- * Build-flow explainer — onboarding screen #3 of 3.
4
- *
5
- * Shown once per machine on first `ritual init` (gated by
6
- * onboarding-state.ts), AFTER the persona picker and workspace
7
- * explainer. Teaches the user the end-to-end shape of /ritual build:
8
- *
9
- * 1. Ritual zone (5 phases): problem scope → discovery →
10
- * agentic run → explainable recommendations → build brief
11
- * 2. Handover: the build brief becomes the input for the user's
12
- * coding agent. This is the most important conceptual beat —
13
- * it's where Ritual ends and the user's familiar tools resume.
14
- * 3. Coding-agent zone: whichever agents we detected on this
15
- * machine (Claude Code / Cursor / Copilot / etc.) consume the
16
- * brief. Empty list → render the "any coding agent" pill.
17
- * 4. PR zone: what lands in the PR thanks to having gone through
18
- * the flow (code + rationale + decisions + tests).
19
- * 5. Close-the-loop: `/ritual sync` feeds the PR outcome back into
20
- * the workspace knowledge graph so the next exploration starts
21
- * with the prior implementation already accounted for.
22
- *
23
- * Vocabulary (locked 2026-05-19):
24
- * - problem scope, discovery, agentic run, explainable
25
- * recommendations, build brief, handover, coding agent,
26
- * pull request, /ritual sync, workspace knowledge graph
27
- * - Header: "from prompt to PR, without context drift"
28
- * - Footer: "planning inherits validated context · no copy-paste"
29
- *
30
- * Non-TTY fallback: terse multi-line summary via
31
- * printBuildFlowExplainerTerse(). Caller checks tty + onboarding
32
- * state before invoking the rich version.
33
- */
34
- Object.defineProperty(exports, "__esModule", { value: true });
35
- exports.printBuildFlowExplainer = printBuildFlowExplainer;
36
- exports.printBuildFlowExplainerTerse = printBuildFlowExplainerTerse;
37
- const colors_1 = require("./colors");
38
- const persona_samples_1 = require("./persona-samples");
39
- /** Width target. Matches welcome-banner + workspace-explainer. */
40
- const BOX_WIDTH = 78;
41
- /** Accent used for the handover divider + coding-agent zone. The
42
- * contrast against the persona accent is what makes the handover
43
- * visually legible: Ritual zone in persona color, agent zone in
44
- * amber, PR zone in green. Tuned to read on dark + light themes. */
45
- const HANDOVER_AMBER = [0xe0, 0xa8, 0x4f];
46
- const PR_GREEN = [0x60, 0xc7, 0x70];
47
- /**
48
- * Render the build-flow explainer to stdout. Always renders (caller
49
- * decides whether to skip based on TTY + onboarding-state).
50
- *
51
- * Rich version assumes ≥80-char terminal width. For narrower
52
- * terminals, callers should prefer printBuildFlowExplainerTerse().
53
- */
54
- function printBuildFlowExplainer(opts) {
55
- const persona = (0, persona_samples_1.findPersona)(opts.personaSlug) ?? persona_samples_1.GENERIC_PERSONA;
56
- const accent = persona.accent;
57
- const lines = [];
58
- // Title bar
59
- lines.push(box.top(BOX_WIDTH, (0, colors_1.color)(accent, '─ /ritual build ─ from prompt to PR, without context drift ')));
60
- lines.push(box.padded(BOX_WIDTH, ''));
61
- // ─── Zone 1: Ritual phases ─────────────────────────────────────────
62
- lines.push(box.padded(BOX_WIDTH, ` ${(0, colors_1.boldColor)(accent, 'ritual — plan with context')}`));
63
- lines.push(box.padded(BOX_WIDTH, ''));
64
- for (const row of renderPhaseChain(accent)) {
65
- lines.push(box.padded(BOX_WIDTH, ' ' + row));
66
- }
67
- lines.push(box.padded(BOX_WIDTH, ''));
68
- // ─── Zone 2: Handover ──────────────────────────────────────────────
69
- lines.push(box.padded(BOX_WIDTH, ' ' + (0, colors_1.color)(HANDOVER_AMBER, '↓ handover — the build brief becomes the input prompt')));
70
- lines.push(box.padded(BOX_WIDTH, ''));
71
- // ─── Zone 3: Coding-agent zone ─────────────────────────────────────
72
- lines.push(box.padded(BOX_WIDTH, ` ${(0, colors_1.boldColor)(HANDOVER_AMBER, 'your coding agent — implement with that context')}`));
73
- lines.push(box.padded(BOX_WIDTH, ''));
74
- for (const row of renderAgentZone(opts.detectedAgents)) {
75
- lines.push(box.padded(BOX_WIDTH, ' ' + row));
76
- }
77
- lines.push(box.padded(BOX_WIDTH, ''));
78
- // ─── Zone 4: PR contents ───────────────────────────────────────────
79
- lines.push(box.padded(BOX_WIDTH, ' ' + (0, colors_1.color)(PR_GREEN, '↓ ships as a pull request that carries the why, not just the what')));
80
- lines.push(box.padded(BOX_WIDTH, ''));
81
- for (const row of renderPrZone()) {
82
- lines.push(box.padded(BOX_WIDTH, ' ' + row));
83
- }
84
- lines.push(box.padded(BOX_WIDTH, ''));
85
- // ─── Zone 5: Close the loop ────────────────────────────────────────
86
- lines.push(box.padded(BOX_WIDTH, ' ' + (0, colors_1.color)(colors_1.RITUAL_TEAL, '↺ /ritual sync — feed the PR back into the workspace knowledge graph')));
87
- lines.push(box.padded(BOX_WIDTH, ` ${(0, colors_1.dim)('next exploration starts with this implementation already in context')}`));
88
- lines.push(box.padded(BOX_WIDTH, ''));
89
- // Footer slogan
90
- lines.push(box.padded(BOX_WIDTH, ` ${(0, colors_1.dim)('planning inherits validated context · no copy-paste')}`));
91
- lines.push(box.padded(BOX_WIDTH, ''));
92
- lines.push(box.bottom(BOX_WIDTH));
93
- for (const line of lines) {
94
- process.stdout.write(line + '\n');
95
- }
96
- }
97
- /**
98
- * Terse fallback for non-TTY or narrow terminals. No colors, no
99
- * boxes — just the teaching, in linear form.
100
- */
101
- function printBuildFlowExplainerTerse(opts) {
102
- const agentList = opts.detectedAgents.length > 0
103
- ? opts.detectedAgents.join(', ')
104
- : 'your coding agent';
105
- process.stdout.write('\n /ritual build — from prompt to PR, without context drift\n\n');
106
- process.stdout.write(' Plan (Ritual):\n');
107
- process.stdout.write(' problem scope → discovery → agentic run → recommendations → build brief\n');
108
- process.stdout.write('\n');
109
- process.stdout.write(` Handover: the build brief becomes the input prompt for ${agentList}.\n`);
110
- process.stdout.write('\n');
111
- process.stdout.write(' PR includes: the code change, the rationale, decisions, anti-goals, tests.\n');
112
- process.stdout.write('\n');
113
- process.stdout.write(' /ritual sync — feed the PR back into the workspace knowledge graph,\n');
114
- process.stdout.write(' so the next exploration starts with this implementation in context.\n');
115
- process.stdout.write('\n');
116
- process.stdout.write(' planning inherits validated context · no copy-paste\n');
117
- process.stdout.write('\n');
118
- }
119
- // ─── helpers ────────────────────────────────────────────────────────────────
120
- /**
121
- * The 5 Ritual phases rendered as a chain of pill-shaped chips with
122
- * arrows between them. Fits in a single row at BOX_WIDTH-4 = 74 cols.
123
- *
124
- * Phase widths are tuned so the row totals to <= 74 chars including
125
- * separators. If you add a phase, re-measure or wrap onto two rows.
126
- */
127
- function renderPhaseChain(accent) {
128
- // Each phase rendered as a chip. The full 5-chip chain is ~91
129
- // chars visible — too wide for the 74-char inner budget — so we
130
- // wrap it onto 2 rows. Row 1: scope → discovery → agentic-run.
131
- // Row 2: → recommendations → build-brief. The leading-arrow on
132
- // row 2 makes the continuation read naturally.
133
- const phases = [
134
- 'problem scope',
135
- 'discovery',
136
- 'agentic run',
137
- 'recommendations',
138
- 'build brief',
139
- ];
140
- const descriptors = [
141
- 'what + why',
142
- 'open questions',
143
- 'parallel answers',
144
- 'with rationale',
145
- 'code-ready',
146
- ];
147
- const chip = (p) => (0, colors_1.color)(accent, `( ${p} )`);
148
- const arrow = (0, colors_1.dim)(' → ');
149
- const row1 = [chip(phases[0]), chip(phases[1]), chip(phases[2])].join(arrow);
150
- const row2 = ' ' + arrow + [chip(phases[3]), chip(phases[4])].join(arrow);
151
- // Descriptor block — one phase per line so we don't have to
152
- // column-align under the (variable-width) chips. Reads as a
153
- // glossary block under the chain.
154
- const descriptorLines = phases.map((p, i) => (0, colors_1.dim)(` · ${p}: ${descriptors[i]}`));
155
- return [row1, row2, '', ...descriptorLines];
156
- }
157
- /**
158
- * The coding-agent zone. If we detected agents, render their names
159
- * as chips; otherwise render a single generic pill.
160
- */
161
- function renderAgentZone(detected) {
162
- if (detected.length === 0) {
163
- return [
164
- (0, colors_1.color)(HANDOVER_AMBER, '( any coding agent )') +
165
- (0, colors_1.dim)(' ← no agent detected on this machine yet — that\'s fine'),
166
- ];
167
- }
168
- // Up to 4 chips on the first line; overflow chips wrap to a second
169
- // line. Tuned for the common 1-2 agent case (Claude Code + Cursor).
170
- const chips = detected.map((name) => (0, colors_1.color)(HANDOVER_AMBER, `( ${name} )`));
171
- const lines = [];
172
- let current = '';
173
- const sep = (0, colors_1.dim)(' ');
174
- for (const chip of chips) {
175
- const candidate = current ? current + sep + chip : chip;
176
- if (visibleLength(candidate) > BOX_WIDTH - 8 && current) {
177
- lines.push(current);
178
- current = chip;
179
- }
180
- else {
181
- current = candidate;
182
- }
183
- }
184
- if (current)
185
- lines.push(current);
186
- lines.push((0, colors_1.dim)('each consumes the build brief — uses it as the input prompt to implement'));
187
- return lines;
188
- }
189
- /** What the resulting pull request carries — the value of the flow. */
190
- function renderPrZone() {
191
- return [
192
- (0, colors_1.color)(PR_GREEN, '( pull request )'),
193
- (0, colors_1.dim)(' ✓ the code change'),
194
- (0, colors_1.dim)(' ✓ the rationale — which recommendation, which decisions'),
195
- (0, colors_1.dim)(' ✓ the anti-goals you set (so reviewers see what was out of scope)'),
196
- (0, colors_1.dim)(' ✓ links back to the exploration so the why is one click away'),
197
- ];
198
- }
199
- // ─── shared box / text utilities ────────────────────────────────────────────
200
- const box = {
201
- top(width, title) {
202
- const stripped = stripAnsi(title);
203
- const fillWidth = width - stripped.length - 4;
204
- return `╭ ${title} ${'─'.repeat(Math.max(0, fillWidth))}╮`;
205
- },
206
- bottom(width) {
207
- return '╰' + '─'.repeat(width - 2) + '╯';
208
- },
209
- padded(width, content) {
210
- const stripped = stripAnsi(content);
211
- const pad = ' '.repeat(Math.max(0, width - 2 - stripped.length));
212
- return `│${content}${pad}│`;
213
- },
214
- };
215
- /** Strip ANSI escape sequences so padding math is correct. */
216
- function stripAnsi(s) {
217
- // eslint-disable-next-line no-control-regex
218
- return s.replace(/\x1b\[[0-9;]*m/g, '');
219
- }
220
- /** Visible length = char count after stripping ANSI. Used by the
221
- * coding-agent zone's chip-wrapping (avoids overflowing a row of
222
- * detected agents past BOX_WIDTH-8). */
223
- function visibleLength(s) {
224
- return stripAnsi(s).length;
225
- }
226
- //# sourceMappingURL=build-flow-explainer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"build-flow-explainer.js","sourceRoot":"","sources":["../../src/lib/build-flow-explainer.ts"],"names":[],"mappings":"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"}
@@ -1,171 +0,0 @@
1
- "use strict";
2
- /**
3
- * Persona picker — onboarding screen #1 of 3.
4
- *
5
- * Shown once per machine on first `ritual init` (gated by
6
- * onboarding-state.ts). Determines two downstream things:
7
- *
8
- * 1. The default template `/ritual build` will reach for. Persona
9
- * slug equals the template's schema.id, so a user who picks
10
- * "Backend Services" gets the backend-services Engineering
11
- * template by default — they can still override per build.
12
- * 2. The accent + framing used in screens #2 and #3 so the whole
13
- * onboarding cohort feels personal.
14
- *
15
- * UI version (this file): numbered-list with color accents, chip
16
- * tags ("APIs · workers · idempotency"), and a "see more" gate so
17
- * we surface the 5 most-common personas first and the long tail
18
- * only when asked. This is the pragmatic version; an Ink-based
19
- * card UI is a polish pass we can layer on later without changing
20
- * the contract here.
21
- *
22
- * Non-TTY fallback: returns `null` immediately. Callers must check
23
- * `process.stdin.isTTY` before invoking the interactive version —
24
- * see init.ts for the pattern. The seed value can also be supplied
25
- * via `--persona <slug>` on the command line for CI bootstrapping.
26
- */
27
- Object.defineProperty(exports, "__esModule", { value: true });
28
- exports.__test = void 0;
29
- exports.pickPersona = pickPersona;
30
- const colors_1 = require("./colors");
31
- const prompt_1 = require("./prompt");
32
- const persona_samples_1 = require("./persona-samples");
33
- /**
34
- * Run the persona picker. Returns the picked persona, or `null` if
35
- * the user skipped explicitly (entered empty / "skip" / etc).
36
- *
37
- * Throws on non-TTY stdin (Node's readline doesn't support it). The
38
- * caller must gate on `process.stdin.isTTY` first.
39
- */
40
- async function pickPersona(opts = {}) {
41
- const featured = orderByFeatured(persona_samples_1.PERSONA_SAMPLES, persona_samples_1.FEATURED_PERSONA_SLUGS);
42
- let showingAll = opts.showAll ?? false;
43
- let visibleCount = showingAll ? featured.length : Math.min(persona_samples_1.FEATURED_PERSONA_SLUGS.length, featured.length);
44
- printHeader();
45
- printPersonaList(featured.slice(0, visibleCount));
46
- // Initial prompt: number, "more", or skip
47
- while (true) {
48
- const answer = (await (0, prompt_1.prompt)(formatPickPrompt(visibleCount, showingAll))).trim();
49
- if (!answer || answer.toLowerCase() === 'skip') {
50
- process.stdout.write('\n' + (0, colors_1.dim)(' no persona set — /ritual build will ask you per exploration.') + '\n\n');
51
- return null;
52
- }
53
- // Allow "more" to expand the list (one-way; once expanded, the
54
- // long-tail personas are shown until pick / skip).
55
- if (answer.toLowerCase() === 'more' && !showingAll) {
56
- const tail = featured.slice(visibleCount);
57
- process.stdout.write('\n');
58
- printPersonaList(tail, visibleCount);
59
- showingAll = true;
60
- visibleCount = featured.length;
61
- continue;
62
- }
63
- const idx = parseChoice(answer, featured.length);
64
- if (idx === null) {
65
- process.stdout.write((0, colors_1.dim)(` didn't recognize "${answer}" — try a number, "more", or "skip".`) + '\n');
66
- continue;
67
- }
68
- const picked = featured[idx];
69
- process.stdout.write('\n ' +
70
- (0, colors_1.boldColor)(picked.accent, `✓ ${picked.label}`) +
71
- (0, colors_1.dim)(` · default template for /ritual build`) +
72
- '\n\n');
73
- return { slug: picked.slug, label: picked.label };
74
- }
75
- }
76
- // ─── rendering ──────────────────────────────────────────────────────────────
77
- function printHeader() {
78
- const lines = [
79
- '',
80
- ' ' + (0, colors_1.boldColor)(colors_1.RITUAL_TEAL, 'What kind of code do you work on most?'),
81
- ' ' + (0, colors_1.dim)('you can always change this later — it\'s a default, not a lock-in.'),
82
- '',
83
- ];
84
- for (const l of lines)
85
- process.stdout.write(l + '\n');
86
- }
87
- /**
88
- * Render a list of personas as `N) Label tag · tag · tag`.
89
- *
90
- * `startIndex` is the 0-based index of the FIRST persona in the slice,
91
- * so when we render the long-tail after "more", the numbering continues
92
- * from where the featured list left off (6, 7, 8…).
93
- */
94
- function printPersonaList(personas, startIndex = 0) {
95
- const numWidth = String(startIndex + personas.length).length;
96
- const labelWidth = Math.max(...personas.map((p) => p.label.length));
97
- for (let i = 0; i < personas.length; i++) {
98
- const p = personas[i];
99
- const n = String(startIndex + i + 1).padStart(numWidth, ' ');
100
- const label = (0, colors_1.boldColor)(p.accent, p.label.padEnd(labelWidth, ' '));
101
- const tags = p.caresAbout.slice(0, 4).join(' · ');
102
- process.stdout.write(` ${(0, colors_1.color)(p.accent, n + ')')} ${label} ${(0, colors_1.dim)(tags)}\n`);
103
- }
104
- process.stdout.write('\n');
105
- }
106
- function formatPickPrompt(visibleCount, showingAll) {
107
- const hint = showingAll
108
- ? `pick a number (1-${visibleCount}), or "skip"`
109
- : `pick a number (1-${visibleCount}), "more" to see the rest, or "skip"`;
110
- return ` ${(0, colors_1.dim)(hint)}\n ${(0, colors_1.color)(colors_1.RITUAL_TEAL, '›')} `;
111
- }
112
- // ─── helpers ────────────────────────────────────────────────────────────────
113
- /**
114
- * Reorder `samples` so the featured slugs come first (in the order
115
- * given by `featuredSlugs`) and the rest follow in their natural
116
- * order. Defensive against missing slugs — if a featured slug has no
117
- * matching sample, we just skip it.
118
- */
119
- function orderByFeatured(samples, featuredSlugs) {
120
- const bySlug = new Map(samples.map((s) => [s.slug, s]));
121
- const featured = [];
122
- for (const slug of featuredSlugs) {
123
- const s = bySlug.get(slug);
124
- if (s)
125
- featured.push(s);
126
- }
127
- const tail = samples.filter((s) => !featuredSlugs.includes(s.slug));
128
- return [...featured, ...tail];
129
- }
130
- /**
131
- * Parse a user's text answer into a 0-based index into the full
132
- * persona list. Returns null if the answer doesn't resolve. We
133
- * accept 1-based numbers (matching the rendered list) and a tiny
134
- * set of label aliases — "backend", "frontend" — for hand-typers.
135
- *
136
- * Exported (alongside `orderByFeatured`) under `__test` so the spec
137
- * can exercise parsing without spinning up readline. Not part of the
138
- * public API; treat the underscore prefix as the contract.
139
- */
140
- function parseChoice(answer, listLength) {
141
- const trimmed = answer.trim().toLowerCase();
142
- // Empty input is never a match — defense-in-depth even though
143
- // the caller short-circuits "" as "skip". Without this, the
144
- // substring loop below would resolve "" against every label.
145
- if (!trimmed)
146
- return null;
147
- const asNumber = Number(trimmed);
148
- if (Number.isInteger(asNumber) && asNumber >= 1 && asNumber <= listLength) {
149
- return asNumber - 1;
150
- }
151
- // Word aliases — substring match against label or shortLabel. We
152
- // keep this loose because the picker isn't latency-sensitive and
153
- // it's friendlier than rejecting "frontend" because the label is
154
- // "Frontend Web".
155
- for (let i = 0; i < persona_samples_1.PERSONA_SAMPLES.length; i++) {
156
- const p = persona_samples_1.PERSONA_SAMPLES[i];
157
- if (trimmed === p.slug ||
158
- p.label.toLowerCase().includes(trimmed) ||
159
- p.shortLabel.toLowerCase() === trimmed) {
160
- return i;
161
- }
162
- }
163
- return null;
164
- }
165
- /**
166
- * Test seam — internal pure helpers exported solely for unit
167
- * coverage. Do not consume from non-spec code; the underscore
168
- * prefix is the contract.
169
- */
170
- exports.__test = { parseChoice, orderByFeatured };
171
- //# sourceMappingURL=persona-picker.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"persona-picker.js","sourceRoot":"","sources":["../../src/lib/persona-picker.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;;;AAkCH,kCA4CC;AA5ED,qCAA8D;AAC9D,qCAAkC;AAClC,uDAK2B;AAkB3B;;;;;;GAMG;AACI,KAAK,UAAU,WAAW,CAChC,OAA6B,EAAE;IAE/B,MAAM,QAAQ,GAAG,eAAe,CAAC,iCAAe,EAAE,wCAAsB,CAAC,CAAC;IAC1E,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,IAAI,KAAK,CAAC;IACvC,IAAI,YAAY,GAAG,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,wCAAsB,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAE3G,WAAW,EAAE,CAAC;IACd,gBAAgB,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,CAAC;IAElD,0CAA0C;IAC1C,OAAO,IAAI,EAAE,CAAC;QACb,MAAM,MAAM,GAAG,CAAC,MAAM,IAAA,eAAM,EAAC,gBAAgB,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACjF,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,MAAM,EAAE,CAAC;YAChD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,GAAG,IAAA,YAAG,EAAC,gEAAgE,CAAC,GAAG,MAAM,CAAC,CAAC;YAC5G,OAAO,IAAI,CAAC;QACb,CAAC;QAED,+DAA+D;QAC/D,mDAAmD;QACnD,IAAI,MAAM,CAAC,WAAW,EAAE,KAAK,MAAM,IAAI,CAAC,UAAU,EAAE,CAAC;YACpD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,YAAY,CAAC,CAAC;YAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC3B,gBAAgB,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;YACrC,UAAU,GAAG,IAAI,CAAC;YAClB,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC;YAC/B,SAAS;QACV,CAAC;QAED,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;QACjD,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAA,YAAG,EAAC,uBAAuB,MAAM,sCAAsC,CAAC,GAAG,IAAI,CAAC,CAAC;YACtG,SAAS;QACV,CAAC;QAED,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;QAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CACnB,MAAM;YACL,IAAA,kBAAS,EAAC,MAAM,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC;YAC7C,IAAA,YAAG,EAAC,yCAAyC,CAAC;YAC9C,MAAM,CACP,CAAC;QACF,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IACnD,CAAC;AACF,CAAC;AAED,+EAA+E;AAE/E,SAAS,WAAW;IACnB,MAAM,KAAK,GAAG;QACb,EAAE;QACF,IAAI,GAAG,IAAA,kBAAS,EAAC,oBAAW,EAAE,wCAAwC,CAAC;QACvE,IAAI,GAAG,IAAA,YAAG,EAAC,oEAAoE,CAAC;QAChF,EAAE;KACF,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACvD,CAAC;AAED;;;;;;GAMG;AACH,SAAS,gBAAgB,CAAC,QAAyB,EAAE,UAAU,GAAG,CAAC;IAClE,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC;IAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAEpE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1C,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACtB,MAAM,CAAC,GAAG,MAAM,CAAC,UAAU,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAG,IAAA,kBAAS,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;QACnE,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAClD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,IAAA,cAAK,EAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,KAAK,KAAK,IAAA,YAAG,EAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChF,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,SAAS,gBAAgB,CAAC,YAAoB,EAAE,UAAmB;IAClE,MAAM,IAAI,GAAG,UAAU;QACtB,CAAC,CAAC,oBAAoB,YAAY,cAAc;QAChD,CAAC,CAAC,oBAAoB,YAAY,sCAAsC,CAAC;IAC1E,OAAO,KAAK,IAAA,YAAG,EAAC,IAAI,CAAC,OAAO,IAAA,cAAK,EAAC,oBAAW,EAAE,GAAG,CAAC,GAAG,CAAC;AACxD,CAAC;AAED,+EAA+E;AAE/E;;;;;GAKG;AACH,SAAS,eAAe,CACvB,OAAiC,EACjC,aAAqC;IAErC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAU,CAAC,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;QAClC,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC;YAAE,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACzB,CAAC;IACD,MAAM,IAAI,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC,CAAC;AAC/B,CAAC;AAED;;;;;;;;;GASG;AACH,SAAS,WAAW,CAAC,MAAc,EAAE,UAAkB;IACtD,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC5C,8DAA8D;IAC9D,4DAA4D;IAC5D,6DAA6D;IAC7D,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,IAAI,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,QAAQ,IAAI,CAAC,IAAI,QAAQ,IAAI,UAAU,EAAE,CAAC;QAC3E,OAAO,QAAQ,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,iEAAiE;IACjE,iEAAiE;IACjE,iEAAiE;IACjE,kBAAkB;IAClB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,iCAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACjD,MAAM,CAAC,GAAG,iCAAe,CAAC,CAAC,CAAC,CAAC;QAC7B,IACC,OAAO,KAAK,CAAC,CAAC,IAAI;YAClB,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YACvC,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,KAAK,OAAO,EACrC,CAAC;YACF,OAAO,CAAC,CAAC;QACV,CAAC;IACF,CAAC;IACD,OAAO,IAAI,CAAC;AACb,CAAC;AAED;;;;GAIG;AACU,QAAA,MAAM,GAAG,EAAE,WAAW,EAAE,eAAe,EAAE,CAAC"}