@agentworkforce/cli 2.0.1 → 2.1.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/CHANGELOG.md +7 -0
- package/dist/cli.d.ts +8 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +69 -2
- package/dist/cli.js.map +1 -1
- package/dist/persona-tui.d.ts +85 -0
- package/dist/persona-tui.d.ts.map +1 -0
- package/dist/persona-tui.js +390 -0
- package/dist/persona-tui.js.map +1 -0
- package/dist/persona-tui.test.d.ts +2 -0
- package/dist/persona-tui.test.d.ts.map +1 -0
- package/dist/persona-tui.test.js +130 -0
- package/dist/persona-tui.test.js.map +1 -0
- package/package.json +3 -3
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname, join } from 'node:path';
|
|
3
|
+
import { defaultWorkforceHomeDir } from './local-personas.js';
|
|
4
|
+
const RECENTS_FILENAME = 'recents.json';
|
|
5
|
+
const RECENTS_CAP = 20;
|
|
6
|
+
const RECENT_DEFAULT_VISIBLE = 3;
|
|
7
|
+
export function defaultRecentsPath(workforceHomeDir = defaultWorkforceHomeDir()) {
|
|
8
|
+
return join(workforceHomeDir, RECENTS_FILENAME);
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Parse the on-disk recents file. Returns an empty list on any shape problem —
|
|
12
|
+
* the recents store is best-effort UX and must never block the CLI from
|
|
13
|
+
* launching an agent.
|
|
14
|
+
*/
|
|
15
|
+
export function parseRecents(text) {
|
|
16
|
+
let parsed;
|
|
17
|
+
try {
|
|
18
|
+
parsed = JSON.parse(text);
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return [];
|
|
22
|
+
}
|
|
23
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
24
|
+
return [];
|
|
25
|
+
const ids = parsed.ids;
|
|
26
|
+
if (!Array.isArray(ids))
|
|
27
|
+
return [];
|
|
28
|
+
const out = [];
|
|
29
|
+
const seen = new Set();
|
|
30
|
+
for (const id of ids) {
|
|
31
|
+
if (typeof id !== 'string')
|
|
32
|
+
continue;
|
|
33
|
+
const trimmed = id.trim();
|
|
34
|
+
if (!trimmed || seen.has(trimmed))
|
|
35
|
+
continue;
|
|
36
|
+
seen.add(trimmed);
|
|
37
|
+
out.push(trimmed);
|
|
38
|
+
if (out.length >= RECENTS_CAP)
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
return out;
|
|
42
|
+
}
|
|
43
|
+
export function loadRecents(path = defaultRecentsPath()) {
|
|
44
|
+
if (!existsSync(path))
|
|
45
|
+
return [];
|
|
46
|
+
try {
|
|
47
|
+
return parseRecents(readFileSync(path, 'utf8'));
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Move `id` to the front of the recents list, dedup, cap. Pure so tests don't
|
|
55
|
+
* need a temp dir.
|
|
56
|
+
*/
|
|
57
|
+
export function nextRecents(prev, id, cap = RECENTS_CAP) {
|
|
58
|
+
const filtered = prev.filter((x) => x !== id);
|
|
59
|
+
return [id, ...filtered].slice(0, cap);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Persist a persona id at the top of the recents list. Swallows IO errors —
|
|
63
|
+
* a corrupt or unwritable recents file should never block a launch.
|
|
64
|
+
*/
|
|
65
|
+
export function recordRecent(id, path = defaultRecentsPath()) {
|
|
66
|
+
if (!id)
|
|
67
|
+
return;
|
|
68
|
+
try {
|
|
69
|
+
const prev = loadRecents(path);
|
|
70
|
+
const next = nextRecents(prev, id);
|
|
71
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
72
|
+
writeFileSync(path, `${JSON.stringify({ version: 1, ids: next }, null, 2)}\n`, 'utf8');
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
/* best-effort */
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Subsequence fuzzy match. Returns null when not all query chars appear in
|
|
80
|
+
* order; otherwise returns a numeric score where smaller is a better match.
|
|
81
|
+
* Score combines leading offset and gap size so prefix / dense matches sort
|
|
82
|
+
* above scattered ones.
|
|
83
|
+
*/
|
|
84
|
+
export function fuzzyScore(query, target) {
|
|
85
|
+
if (!query)
|
|
86
|
+
return 0;
|
|
87
|
+
const q = query.toLowerCase();
|
|
88
|
+
const t = target.toLowerCase();
|
|
89
|
+
let qi = 0;
|
|
90
|
+
let firstIdx = -1;
|
|
91
|
+
let lastIdx = -1;
|
|
92
|
+
let totalGap = 0;
|
|
93
|
+
for (let ti = 0; ti < t.length && qi < q.length; ti++) {
|
|
94
|
+
if (t[ti] === q[qi]) {
|
|
95
|
+
if (firstIdx === -1)
|
|
96
|
+
firstIdx = ti;
|
|
97
|
+
if (lastIdx !== -1)
|
|
98
|
+
totalGap += ti - lastIdx - 1;
|
|
99
|
+
lastIdx = ti;
|
|
100
|
+
qi += 1;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
if (qi < q.length)
|
|
104
|
+
return null;
|
|
105
|
+
return firstIdx + totalGap * 2 + Math.floor(t.length / 32);
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Rank candidates by best fuzzy match across name OR description. Name matches
|
|
109
|
+
* outrank description matches at equal score to keep the picker feeling
|
|
110
|
+
* direct — typing "rev" should surface "code-reviewer" not whichever persona
|
|
111
|
+
* happens to mention "reviews" in prose.
|
|
112
|
+
*/
|
|
113
|
+
export function rankCandidates(candidates, query) {
|
|
114
|
+
const trimmed = query.trim();
|
|
115
|
+
if (!trimmed)
|
|
116
|
+
return [...candidates];
|
|
117
|
+
const DESCRIPTION_PENALTY = 5;
|
|
118
|
+
const scored = [];
|
|
119
|
+
for (const c of candidates) {
|
|
120
|
+
const nameScore = fuzzyScore(trimmed, c.id);
|
|
121
|
+
const descScore = fuzzyScore(trimmed, c.description);
|
|
122
|
+
let score = null;
|
|
123
|
+
if (nameScore !== null && descScore !== null) {
|
|
124
|
+
score = Math.min(nameScore, descScore + DESCRIPTION_PENALTY);
|
|
125
|
+
}
|
|
126
|
+
else if (nameScore !== null) {
|
|
127
|
+
score = nameScore;
|
|
128
|
+
}
|
|
129
|
+
else if (descScore !== null) {
|
|
130
|
+
score = descScore + DESCRIPTION_PENALTY;
|
|
131
|
+
}
|
|
132
|
+
if (score !== null)
|
|
133
|
+
scored.push({ c, s: score });
|
|
134
|
+
}
|
|
135
|
+
scored.sort((a, b) => a.s - b.s || a.c.id.localeCompare(b.c.id));
|
|
136
|
+
return scored.map((r) => r.c);
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Project recent ids onto the candidate list, preserving recency order and
|
|
140
|
+
* dropping ids that no longer resolve (uninstalled pack, renamed local
|
|
141
|
+
* persona, etc.).
|
|
142
|
+
*/
|
|
143
|
+
export function recentCandidates(candidates, recentIds, cap = RECENT_DEFAULT_VISIBLE) {
|
|
144
|
+
const byId = new Map(candidates.map((c) => [c.id, c]));
|
|
145
|
+
const out = [];
|
|
146
|
+
for (const id of recentIds) {
|
|
147
|
+
const c = byId.get(id);
|
|
148
|
+
if (!c)
|
|
149
|
+
continue;
|
|
150
|
+
out.push(c);
|
|
151
|
+
if (out.length >= cap)
|
|
152
|
+
break;
|
|
153
|
+
}
|
|
154
|
+
return out;
|
|
155
|
+
}
|
|
156
|
+
const ESC = '\x1b';
|
|
157
|
+
const SEQ = {
|
|
158
|
+
enterAlt: `${ESC}[?1049h`,
|
|
159
|
+
leaveAlt: `${ESC}[?1049l`,
|
|
160
|
+
hideCursor: `${ESC}[?25l`,
|
|
161
|
+
showCursor: `${ESC}[?25h`,
|
|
162
|
+
clear: `${ESC}[2J${ESC}[H`,
|
|
163
|
+
reset: `${ESC}[0m`,
|
|
164
|
+
inverse: `${ESC}[7m`,
|
|
165
|
+
dim: `${ESC}[2m`,
|
|
166
|
+
bold: `${ESC}[1m`,
|
|
167
|
+
cyan: `${ESC}[36m`
|
|
168
|
+
};
|
|
169
|
+
function truncate(text, max) {
|
|
170
|
+
if (text.length <= max)
|
|
171
|
+
return text;
|
|
172
|
+
if (max <= 1)
|
|
173
|
+
return text.slice(0, Math.max(0, max));
|
|
174
|
+
return `${text.slice(0, max - 1)}…`;
|
|
175
|
+
}
|
|
176
|
+
const DEFAULT_VISIBLE_CAP = 20;
|
|
177
|
+
/**
|
|
178
|
+
* Window we wait for the rest of an escape sequence before treating a bare
|
|
179
|
+
* `\x1b` as a quit keystroke. Arrow keys arrive as `\x1b[A` / `\x1b[B`, and
|
|
180
|
+
* over slow connections (SSH, multiplexers, low-baud serial) those bytes can
|
|
181
|
+
* land in separate `data` events. 50ms is well below the human-perceptible
|
|
182
|
+
* delay for a real Esc press but plenty of slack for fragmented sequences.
|
|
183
|
+
*/
|
|
184
|
+
const DEFAULT_ESCAPE_TIMEOUT_MS = 50;
|
|
185
|
+
/**
|
|
186
|
+
* Decide what the picker should show given the candidate set, recents list,
|
|
187
|
+
* and current query. Exported (and pure) so the recents-header logic can be
|
|
188
|
+
* unit-tested without spinning up a TTY.
|
|
189
|
+
*
|
|
190
|
+
* - `recents` — empty query AND at least one recent id still resolves to a
|
|
191
|
+
* known candidate.
|
|
192
|
+
* - `all` — empty query AND no recent ids resolve (fresh install, or all
|
|
193
|
+
* previously-used personas have been uninstalled/renamed).
|
|
194
|
+
* - `matches` — non-empty query; items are the ranked fuzzy hits.
|
|
195
|
+
*/
|
|
196
|
+
export function computeTuiView(candidates, recentIds, query, visibleCap = DEFAULT_VISIBLE_CAP) {
|
|
197
|
+
if (!query.trim()) {
|
|
198
|
+
const recents = recentCandidates(candidates, recentIds, RECENT_DEFAULT_VISIBLE);
|
|
199
|
+
if (recents.length > 0)
|
|
200
|
+
return { mode: 'recents', items: recents };
|
|
201
|
+
return { mode: 'all', items: [...candidates].slice(0, visibleCap) };
|
|
202
|
+
}
|
|
203
|
+
return {
|
|
204
|
+
mode: 'matches',
|
|
205
|
+
items: rankCandidates(candidates, query).slice(0, visibleCap)
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Interactive persona picker. Renders inside the alternate screen buffer so
|
|
210
|
+
* scrollback survives, raw-mode reads single keystrokes for arrow/enter/esc
|
|
211
|
+
* handling, and resolves with the chosen persona id (or undefined on quit).
|
|
212
|
+
*
|
|
213
|
+
* Falls back to undefined immediately when stdin or stderr isn't a TTY — the
|
|
214
|
+
* caller should print the regular help text in that case.
|
|
215
|
+
*/
|
|
216
|
+
export async function runPersonaPickerTui(opts) {
|
|
217
|
+
const stdin = opts.stdin ?? process.stdin;
|
|
218
|
+
const stderr = opts.stderr ?? process.stderr;
|
|
219
|
+
if (!stdin.isTTY || !stderr.isTTY)
|
|
220
|
+
return undefined;
|
|
221
|
+
const visibleCap = opts.visibleCap ?? DEFAULT_VISIBLE_CAP;
|
|
222
|
+
const escapeTimeoutMs = opts.escapeTimeoutMs ?? DEFAULT_ESCAPE_TIMEOUT_MS;
|
|
223
|
+
let query = '';
|
|
224
|
+
let cursor = 0;
|
|
225
|
+
let view = computeTuiView(opts.candidates, opts.recentIds, query, visibleCap);
|
|
226
|
+
function render() {
|
|
227
|
+
const cols = stderr.columns ?? 100;
|
|
228
|
+
const items = view.items;
|
|
229
|
+
let out = SEQ.clear;
|
|
230
|
+
out += `${SEQ.bold}agentworkforce${SEQ.reset} · pick a persona\n`;
|
|
231
|
+
out += `${SEQ.dim}↑↓ navigate · enter run · esc quit · type to search${SEQ.reset}\n\n`;
|
|
232
|
+
out += `${SEQ.cyan}›${SEQ.reset} ${query || `${SEQ.dim}(type to search by name or description)${SEQ.reset}`}\n\n`;
|
|
233
|
+
const header = items.length === 0
|
|
234
|
+
? 'NO MATCHES'
|
|
235
|
+
: view.mode === 'recents'
|
|
236
|
+
? 'RECENT'
|
|
237
|
+
: 'PERSONAS';
|
|
238
|
+
out += `${SEQ.dim}${header}${SEQ.reset}\n`;
|
|
239
|
+
if (items.length === 0) {
|
|
240
|
+
out += `${SEQ.dim}(no persona name or description matches "${query}")${SEQ.reset}\n`;
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
const nameWidth = Math.min(32, Math.max(8, ...items.map((c) => c.id.length)));
|
|
244
|
+
const sourceWidth = Math.min(14, Math.max(7, ...items.map((c) => c.source.length)));
|
|
245
|
+
const descBudget = Math.max(20, cols - nameWidth - sourceWidth - 7);
|
|
246
|
+
for (let i = 0; i < items.length; i += 1) {
|
|
247
|
+
const c = items[i];
|
|
248
|
+
const isSel = i === cursor;
|
|
249
|
+
const marker = isSel ? `${SEQ.cyan}›${SEQ.reset}` : ' ';
|
|
250
|
+
const desc = truncate(c.description.replace(/\s+/g, ' ').trim(), descBudget);
|
|
251
|
+
const body = `${c.id.padEnd(nameWidth)} ${c.source.padEnd(sourceWidth)} ${desc}`;
|
|
252
|
+
const styled = isSel ? `${SEQ.inverse}${body}${SEQ.reset}` : `${SEQ.dim}${body}${SEQ.reset}`;
|
|
253
|
+
out += `${marker} ${styled}\n`;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
stderr.write(out);
|
|
257
|
+
}
|
|
258
|
+
function refresh() {
|
|
259
|
+
view = computeTuiView(opts.candidates, opts.recentIds, query, visibleCap);
|
|
260
|
+
if (cursor >= view.items.length)
|
|
261
|
+
cursor = Math.max(0, view.items.length - 1);
|
|
262
|
+
render();
|
|
263
|
+
}
|
|
264
|
+
return new Promise((resolve) => {
|
|
265
|
+
let settled = false;
|
|
266
|
+
// Buffered bare-Escape: stays set while we wait for the rest of a possible
|
|
267
|
+
// escape sequence. If `escapeTimer` fires first the user pressed Esc on
|
|
268
|
+
// its own; if more bytes arrive first we glue them together and dispatch.
|
|
269
|
+
let pendingEscape = '';
|
|
270
|
+
let escapeTimer;
|
|
271
|
+
function clearEscapeBuffer() {
|
|
272
|
+
pendingEscape = '';
|
|
273
|
+
if (escapeTimer) {
|
|
274
|
+
clearTimeout(escapeTimer);
|
|
275
|
+
escapeTimer = undefined;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
function settle(value) {
|
|
279
|
+
if (settled)
|
|
280
|
+
return;
|
|
281
|
+
settled = true;
|
|
282
|
+
clearEscapeBuffer();
|
|
283
|
+
stdin.removeListener('data', onData);
|
|
284
|
+
try {
|
|
285
|
+
stdin.setRawMode?.(false);
|
|
286
|
+
}
|
|
287
|
+
catch {
|
|
288
|
+
/* not a TTY anymore */
|
|
289
|
+
}
|
|
290
|
+
stdin.pause();
|
|
291
|
+
stderr.write(`${SEQ.showCursor}${SEQ.leaveAlt}`);
|
|
292
|
+
resolve(value);
|
|
293
|
+
}
|
|
294
|
+
function handleKey(text) {
|
|
295
|
+
// Ctrl-C — quit.
|
|
296
|
+
if (text === '\x03') {
|
|
297
|
+
settle(undefined);
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
// Bare Escape that has already cleared the debounce window.
|
|
301
|
+
if (text === '\x1b') {
|
|
302
|
+
settle(undefined);
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
// Enter — accept current selection.
|
|
306
|
+
if (text === '\r' || text === '\n') {
|
|
307
|
+
const sel = view.items[cursor];
|
|
308
|
+
settle(sel?.id);
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
// Arrow Up / Ctrl-P
|
|
312
|
+
if (text === '\x1b[A' || text === '\x10') {
|
|
313
|
+
if (view.items.length === 0)
|
|
314
|
+
return;
|
|
315
|
+
cursor = (cursor - 1 + view.items.length) % view.items.length;
|
|
316
|
+
render();
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
// Arrow Down / Ctrl-N
|
|
320
|
+
if (text === '\x1b[B' || text === '\x0e') {
|
|
321
|
+
if (view.items.length === 0)
|
|
322
|
+
return;
|
|
323
|
+
cursor = (cursor + 1) % view.items.length;
|
|
324
|
+
render();
|
|
325
|
+
return;
|
|
326
|
+
}
|
|
327
|
+
// Backspace
|
|
328
|
+
if (text === '\x7f' || text === '\b') {
|
|
329
|
+
if (query.length > 0) {
|
|
330
|
+
query = query.slice(0, -1);
|
|
331
|
+
cursor = 0;
|
|
332
|
+
refresh();
|
|
333
|
+
}
|
|
334
|
+
return;
|
|
335
|
+
}
|
|
336
|
+
// Anything else that *starts* with ESC is an unrecognized CSI / SS3 /
|
|
337
|
+
// function-key sequence — swallow it rather than typing the bytes into
|
|
338
|
+
// the search box.
|
|
339
|
+
if (text.startsWith('\x1b'))
|
|
340
|
+
return;
|
|
341
|
+
// Strip any remaining control bytes and append printable input.
|
|
342
|
+
let printable = '';
|
|
343
|
+
for (const ch of text) {
|
|
344
|
+
const code = ch.charCodeAt(0);
|
|
345
|
+
if (code >= 0x20 && code !== 0x7f)
|
|
346
|
+
printable += ch;
|
|
347
|
+
}
|
|
348
|
+
if (printable.length > 0) {
|
|
349
|
+
query += printable;
|
|
350
|
+
cursor = 0;
|
|
351
|
+
refresh();
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
function onData(chunk) {
|
|
355
|
+
const text = typeof chunk === 'string' ? chunk : chunk.toString('utf8');
|
|
356
|
+
// Mid-sequence: the previous tick buffered a lone ESC. Glue and
|
|
357
|
+
// dispatch as a single keystroke so `\x1b` + `[A` is treated as an
|
|
358
|
+
// arrow press, not Esc-then-`[A`.
|
|
359
|
+
if (pendingEscape) {
|
|
360
|
+
const combined = pendingEscape + text;
|
|
361
|
+
clearEscapeBuffer();
|
|
362
|
+
handleKey(combined);
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
// Lone ESC: wait briefly for the rest of a possible sequence.
|
|
366
|
+
if (text === '\x1b' && escapeTimeoutMs > 0) {
|
|
367
|
+
pendingEscape = text;
|
|
368
|
+
escapeTimer = setTimeout(() => {
|
|
369
|
+
if (pendingEscape !== '\x1b')
|
|
370
|
+
return;
|
|
371
|
+
clearEscapeBuffer();
|
|
372
|
+
handleKey('\x1b');
|
|
373
|
+
}, escapeTimeoutMs);
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
handleKey(text);
|
|
377
|
+
}
|
|
378
|
+
try {
|
|
379
|
+
stdin.setRawMode?.(true);
|
|
380
|
+
}
|
|
381
|
+
catch {
|
|
382
|
+
/* not a TTY */
|
|
383
|
+
}
|
|
384
|
+
stdin.resume();
|
|
385
|
+
stderr.write(`${SEQ.enterAlt}${SEQ.hideCursor}`);
|
|
386
|
+
stdin.on('data', onData);
|
|
387
|
+
render();
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=persona-tui.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona-tui.js","sourceRoot":"","sources":["../src/persona-tui.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona-tui.test.d.ts","sourceRoot":"","sources":["../src/persona-tui.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import test from 'node:test';
|
|
2
|
+
import assert from 'node:assert/strict';
|
|
3
|
+
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
|
|
4
|
+
import { tmpdir } from 'node:os';
|
|
5
|
+
import { join } from 'node:path';
|
|
6
|
+
import { computeTuiView, fuzzyScore, nextRecents, parseRecents, rankCandidates, recentCandidates, recordRecent, loadRecents } from './persona-tui.js';
|
|
7
|
+
const CANDIDATES = [
|
|
8
|
+
{
|
|
9
|
+
id: 'code-reviewer',
|
|
10
|
+
description: 'Reviews pull requests for quality, correctness and security.',
|
|
11
|
+
source: 'library'
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
id: 'fix-flaky',
|
|
15
|
+
description: 'Repairs flaky tests across the test suite.',
|
|
16
|
+
source: 'user'
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
id: 'persona-maker',
|
|
20
|
+
description: 'Scaffolds a new persona via interactive Q&A.',
|
|
21
|
+
source: 'library'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: 'my-reviewer',
|
|
25
|
+
description: 'Local reviewer override with team-specific style rules.',
|
|
26
|
+
source: 'cwd'
|
|
27
|
+
}
|
|
28
|
+
];
|
|
29
|
+
test('fuzzyScore returns null when chars are absent or out of order', () => {
|
|
30
|
+
assert.equal(fuzzyScore('zzz', 'code-reviewer'), null);
|
|
31
|
+
assert.equal(fuzzyScore('reverse', 'reviewer'), null);
|
|
32
|
+
});
|
|
33
|
+
test('fuzzyScore prefers prefix and dense matches', () => {
|
|
34
|
+
const prefix = fuzzyScore('code', 'code-reviewer');
|
|
35
|
+
const scattered = fuzzyScore('code', 'committed-old-de');
|
|
36
|
+
assert.ok(prefix !== null && scattered !== null);
|
|
37
|
+
assert.ok(prefix < scattered, `expected prefix=${prefix} < scattered=${scattered}`);
|
|
38
|
+
});
|
|
39
|
+
test('rankCandidates surfaces name matches over description matches', () => {
|
|
40
|
+
// Both reviewer ids match by name; "review" doesn't subsequence-match
|
|
41
|
+
// anything else, so the two name matches are the only results and rank
|
|
42
|
+
// by leading-offset (my-reviewer first because "r" appears earlier).
|
|
43
|
+
const ranked = rankCandidates(CANDIDATES, 'review');
|
|
44
|
+
assert.deepEqual(ranked.map((c) => c.id), ['my-reviewer', 'code-reviewer']);
|
|
45
|
+
});
|
|
46
|
+
test('rankCandidates returns empty array when nothing matches', () => {
|
|
47
|
+
assert.deepEqual(rankCandidates(CANDIDATES, 'xxxxxxxx'), []);
|
|
48
|
+
});
|
|
49
|
+
test('rankCandidates returns all candidates with empty query', () => {
|
|
50
|
+
const ranked = rankCandidates(CANDIDATES, ' ');
|
|
51
|
+
assert.equal(ranked.length, CANDIDATES.length);
|
|
52
|
+
});
|
|
53
|
+
test('rankCandidates can match purely from description text', () => {
|
|
54
|
+
const ranked = rankCandidates(CANDIDATES, 'flaky');
|
|
55
|
+
assert.equal(ranked[0].id, 'fix-flaky');
|
|
56
|
+
});
|
|
57
|
+
test('recentCandidates preserves order and drops unknown ids', () => {
|
|
58
|
+
const recents = recentCandidates(CANDIDATES, ['fix-flaky', 'gone-persona', 'code-reviewer', 'my-reviewer'], 3);
|
|
59
|
+
assert.deepEqual(recents.map((c) => c.id), ['fix-flaky', 'code-reviewer', 'my-reviewer']);
|
|
60
|
+
});
|
|
61
|
+
test('nextRecents moves an existing id to the front and caps the list', () => {
|
|
62
|
+
const result = nextRecents(['a', 'b', 'c', 'd', 'e'], 'c', 3);
|
|
63
|
+
assert.deepEqual(result, ['c', 'a', 'b']);
|
|
64
|
+
});
|
|
65
|
+
test('nextRecents prepends a new id', () => {
|
|
66
|
+
assert.deepEqual(nextRecents(['a', 'b'], 'z'), ['z', 'a', 'b']);
|
|
67
|
+
});
|
|
68
|
+
test('parseRecents tolerates garbage input', () => {
|
|
69
|
+
assert.deepEqual(parseRecents('not json'), []);
|
|
70
|
+
assert.deepEqual(parseRecents('null'), []);
|
|
71
|
+
assert.deepEqual(parseRecents('{"ids": "nope"}'), []);
|
|
72
|
+
assert.deepEqual(parseRecents('{"ids": [1, "ok", " ", "ok"]}'), ['ok']);
|
|
73
|
+
});
|
|
74
|
+
test('recordRecent + loadRecents round-trip via the filesystem', () => {
|
|
75
|
+
const dir = mkdtempSync(join(tmpdir(), 'aw-tui-'));
|
|
76
|
+
const path = join(dir, 'nested', 'recents.json');
|
|
77
|
+
try {
|
|
78
|
+
recordRecent('code-reviewer', path);
|
|
79
|
+
recordRecent('fix-flaky', path);
|
|
80
|
+
recordRecent('code-reviewer', path);
|
|
81
|
+
assert.deepEqual(loadRecents(path), ['code-reviewer', 'fix-flaky']);
|
|
82
|
+
const onDisk = JSON.parse(readFileSync(path, 'utf8'));
|
|
83
|
+
assert.equal(onDisk.version, 1);
|
|
84
|
+
assert.deepEqual(onDisk.ids, ['code-reviewer', 'fix-flaky']);
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
rmSync(dir, { recursive: true, force: true });
|
|
88
|
+
}
|
|
89
|
+
});
|
|
90
|
+
test('computeTuiView: empty query with resolved recents → recents mode', () => {
|
|
91
|
+
const view = computeTuiView(CANDIDATES, ['fix-flaky', 'code-reviewer'], '');
|
|
92
|
+
assert.equal(view.mode, 'recents');
|
|
93
|
+
assert.deepEqual(view.items.map((c) => c.id), ['fix-flaky', 'code-reviewer']);
|
|
94
|
+
});
|
|
95
|
+
test('computeTuiView: recents pointing only at unknown ids → all mode (regression)', () => {
|
|
96
|
+
// Prior bug: header said "RECENT" because recentIds was non-empty even
|
|
97
|
+
// though every id had been uninstalled/renamed and the full catalog was
|
|
98
|
+
// being shown.
|
|
99
|
+
const view = computeTuiView(CANDIDATES, ['ghost-persona', 'also-gone'], '');
|
|
100
|
+
assert.equal(view.mode, 'all');
|
|
101
|
+
assert.equal(view.items.length, CANDIDATES.length);
|
|
102
|
+
});
|
|
103
|
+
test('computeTuiView: empty query with no recents → all mode', () => {
|
|
104
|
+
const view = computeTuiView(CANDIDATES, [], '');
|
|
105
|
+
assert.equal(view.mode, 'all');
|
|
106
|
+
});
|
|
107
|
+
test('computeTuiView: non-empty query → matches mode', () => {
|
|
108
|
+
const view = computeTuiView(CANDIDATES, ['fix-flaky'], 'review');
|
|
109
|
+
assert.equal(view.mode, 'matches');
|
|
110
|
+
assert.ok(view.items.length > 0);
|
|
111
|
+
assert.ok(view.items.every((c) => c.id.includes('review')));
|
|
112
|
+
});
|
|
113
|
+
test('computeTuiView: matches mode honors visibleCap', () => {
|
|
114
|
+
const view = computeTuiView(CANDIDATES, [], 'e', 2);
|
|
115
|
+
assert.equal(view.mode, 'matches');
|
|
116
|
+
assert.ok(view.items.length <= 2);
|
|
117
|
+
});
|
|
118
|
+
test('loadRecents returns [] when the file is absent or corrupt', () => {
|
|
119
|
+
const dir = mkdtempSync(join(tmpdir(), 'aw-tui-'));
|
|
120
|
+
const path = join(dir, 'recents.json');
|
|
121
|
+
try {
|
|
122
|
+
assert.deepEqual(loadRecents(path), []);
|
|
123
|
+
writeFileSync(path, '{ not json', 'utf8');
|
|
124
|
+
assert.deepEqual(loadRecents(path), []);
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
rmSync(dir, { recursive: true, force: true });
|
|
128
|
+
}
|
|
129
|
+
});
|
|
130
|
+
//# sourceMappingURL=persona-tui.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"persona-tui.test.js","sourceRoot":"","sources":["../src/persona-tui.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentworkforce/cli",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -13,8 +13,8 @@
|
|
|
13
13
|
"@relayburn/sdk": "^2.5.2",
|
|
14
14
|
"@relayfile/local-mount": "^0.7.0",
|
|
15
15
|
"ora": "^9.4.0",
|
|
16
|
-
"@agentworkforce/
|
|
17
|
-
"@agentworkforce/
|
|
16
|
+
"@agentworkforce/workload-router": "2.1.0",
|
|
17
|
+
"@agentworkforce/persona-kit": "2.1.0"
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|