compact-agent 1.31.1 → 1.32.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/dist/command-palette.d.ts +21 -0
- package/dist/command-palette.js +106 -0
- package/dist/command-palette.js.map +1 -0
- package/dist/index.js +171 -4
- package/dist/index.js.map +1 -1
- package/dist/openrouter-models.d.ts +44 -0
- package/dist/openrouter-models.js +112 -0
- package/dist/openrouter-models.js.map +1 -0
- package/dist/picker.d.ts +27 -0
- package/dist/picker.js +225 -0
- package/dist/picker.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command palette catalog — the slash commands exposed via the
|
|
3
|
+
* Space-at-empty quick picker. Hand-curated rather than auto-
|
|
4
|
+
* extracted from handleSlashCommand's switch, because:
|
|
5
|
+
*
|
|
6
|
+
* 1. The switch contains alias arms (/branch → /fork, /quit → /exit,
|
|
7
|
+
* etc.) that would clutter a UI listing.
|
|
8
|
+
* 2. Some commands are internal sentinels (__DICTATE__, __SWARM__)
|
|
9
|
+
* that should never appear to users.
|
|
10
|
+
* 3. Curating gives us a tight description column for each entry —
|
|
11
|
+
* the picker shows label + hint + description, and a hand-
|
|
12
|
+
* written one-liner is more scannable than a parsed comment.
|
|
13
|
+
*
|
|
14
|
+
* Categories mirror /help's grouping so muscle memory transfers.
|
|
15
|
+
*/
|
|
16
|
+
export interface CommandEntry {
|
|
17
|
+
command: string;
|
|
18
|
+
description: string;
|
|
19
|
+
category: string;
|
|
20
|
+
}
|
|
21
|
+
export declare const COMMAND_CATALOG: CommandEntry[];
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command palette catalog — the slash commands exposed via the
|
|
3
|
+
* Space-at-empty quick picker. Hand-curated rather than auto-
|
|
4
|
+
* extracted from handleSlashCommand's switch, because:
|
|
5
|
+
*
|
|
6
|
+
* 1. The switch contains alias arms (/branch → /fork, /quit → /exit,
|
|
7
|
+
* etc.) that would clutter a UI listing.
|
|
8
|
+
* 2. Some commands are internal sentinels (__DICTATE__, __SWARM__)
|
|
9
|
+
* that should never appear to users.
|
|
10
|
+
* 3. Curating gives us a tight description column for each entry —
|
|
11
|
+
* the picker shows label + hint + description, and a hand-
|
|
12
|
+
* written one-liner is more scannable than a parsed comment.
|
|
13
|
+
*
|
|
14
|
+
* Categories mirror /help's grouping so muscle memory transfers.
|
|
15
|
+
*/
|
|
16
|
+
export const COMMAND_CATALOG = [
|
|
17
|
+
// ── General ──
|
|
18
|
+
{ command: '/help', description: 'Show the full command reference', category: 'General' },
|
|
19
|
+
{ command: '/clear', description: 'Reset the conversation (also resets side-channel state)', category: 'General' },
|
|
20
|
+
{ command: '/back', description: 'Rewind to before the nth most-recent user turn', category: 'General' },
|
|
21
|
+
{ command: '/fork', description: 'Branch the current conversation; previous still resumable', category: 'General' },
|
|
22
|
+
{ command: '/btw', description: 'Side question that doesn\'t pollute the main thread', category: 'General' },
|
|
23
|
+
{ command: '/editor', description: 'Open $EDITOR for a multi-line prompt', category: 'General' },
|
|
24
|
+
{ command: '/history', description: 'Message count + token estimate', category: 'General' },
|
|
25
|
+
{ command: '/export', description: 'Export conversation (md/json/txt)', category: 'General' },
|
|
26
|
+
{ command: '/walkthrough', description: 'Agent-led tour of compact-agent', category: 'General' },
|
|
27
|
+
{ command: '/config', description: 'Reconfigure provider / model / key (re-runs the setup wizard)', category: 'General' },
|
|
28
|
+
{ command: '/theme', description: 'Change display mode (full/compact/minimal)', category: 'General' },
|
|
29
|
+
{ command: '/palette', description: 'Switch color palette (run /palettes to list)', category: 'General' },
|
|
30
|
+
// ── Model & Provider ──
|
|
31
|
+
{ command: '/model', description: 'Switch model (no arg → interactive picker on OpenRouter)', category: 'Model' },
|
|
32
|
+
{ command: '/models', description: 'List available models for the current provider', category: 'Model' },
|
|
33
|
+
{ command: '/fallback', description: 'Set/show the model auto-retried on cryptic errors', category: 'Model' },
|
|
34
|
+
{ command: '/provider', description: 'Show provider info (URL, masked key)', category: 'Model' },
|
|
35
|
+
{ command: '/keys', description: 'Multi-key rotation pool (/keys add, status, remove)', category: 'Model' },
|
|
36
|
+
{ command: '/route', description: 'Auto-route to a model based on the next message', category: 'Model' },
|
|
37
|
+
// ── Modes ──
|
|
38
|
+
{ command: '/mode', description: 'Switch mode (dev/review/tdd/research/plan/debug/architect/hermes/design)', category: 'Modes' },
|
|
39
|
+
{ command: '/modes', description: 'List all available modes', category: 'Modes' },
|
|
40
|
+
{ command: '/hermes', description: 'Switch to Hermes mode (self-improving learning loop)', category: 'Modes' },
|
|
41
|
+
{ command: '/design', description: 'Switch to design mode (Stitch-powered UI work)', category: 'Modes' },
|
|
42
|
+
// ── Session ──
|
|
43
|
+
{ command: '/sessions', description: 'List saved sessions', category: 'Session' },
|
|
44
|
+
{ command: '/save', description: 'Save current session', category: 'Session' },
|
|
45
|
+
{ command: '/resume', description: 'Resume a saved session (accepts id, prefix, or "last")', category: 'Session' },
|
|
46
|
+
{ command: '/delete', description: 'Delete a session', category: 'Session' },
|
|
47
|
+
// ── Git ──
|
|
48
|
+
{ command: '/commit', description: 'AI-generated commit message', category: 'Git' },
|
|
49
|
+
{ command: '/pr', description: 'AI-generated pull request', category: 'Git' },
|
|
50
|
+
{ command: '/diff', description: 'Show git diff', category: 'Git' },
|
|
51
|
+
{ command: '/log', description: 'Show git log', category: 'Git' },
|
|
52
|
+
// ── Code Quality ──
|
|
53
|
+
{ command: '/review', description: 'AI code review (severity-rated findings)', category: 'Code Quality' },
|
|
54
|
+
{ command: '/auto-review', description: 'Code review with auto-detected language lens', category: 'Code Quality' },
|
|
55
|
+
{ command: '/tdd', description: 'Test-driven workflow (RED → GREEN → REFACTOR)', category: 'Code Quality' },
|
|
56
|
+
{ command: '/security-review', description: 'Security-focused audit', category: 'Code Quality' },
|
|
57
|
+
{ command: '/audit', description: 'Local-only project health check', category: 'Code Quality' },
|
|
58
|
+
{ command: '/verify', description: 'Run tests, fix failures, repeat until green', category: 'Code Quality' },
|
|
59
|
+
{ command: '/build-fix', description: 'Auto-detect language + fix build errors', category: 'Code Quality' },
|
|
60
|
+
{ command: '/test-coverage', description: 'Analyze coverage, suggest missing tests', category: 'Code Quality' },
|
|
61
|
+
{ command: '/refactor', description: 'Dead code detection + cleanup', category: 'Code Quality' },
|
|
62
|
+
{ command: '/hunt-silent', description: 'Silent-failure-hunter agent (empty catches, log-and-forget)', category: 'Code Quality' },
|
|
63
|
+
{ command: '/explore', description: 'Code-explorer agent (codebase reconnaissance pass)', category: 'Code Quality' },
|
|
64
|
+
{ command: '/types', description: 'Type-design-analyzer agent (type system critique)', category: 'Code Quality' },
|
|
65
|
+
{ command: '/architect', description: 'Code-architect agent (structural critique)', category: 'Code Quality' },
|
|
66
|
+
{ command: '/simplify', description: 'Code-simplifier agent (find + collapse incidental complexity)', category: 'Code Quality' },
|
|
67
|
+
{ command: '/e2e', description: 'Generate E2E tests', category: 'Code Quality' },
|
|
68
|
+
// ── Tools & Config ──
|
|
69
|
+
{ command: '/tools', description: 'List currently-available tools', category: 'Config' },
|
|
70
|
+
{ command: '/perm', description: 'Permission mode (ask/auto/yolo)', category: 'Config' },
|
|
71
|
+
{ command: '/sandbox', description: 'OS-native bash sandbox (off/standard/strict)', category: 'Config' },
|
|
72
|
+
{ command: '/dry-run', description: 'Toggle dry-run mode (preview tool calls)', category: 'Config' },
|
|
73
|
+
{ command: '/thinking', description: 'Toggle thinking/reasoning display', category: 'Config' },
|
|
74
|
+
{ command: '/cd', description: 'Change working directory', category: 'Config' },
|
|
75
|
+
{ command: '/hooks', description: 'List configured hooks', category: 'Config' },
|
|
76
|
+
// ── Planning ──
|
|
77
|
+
{ command: '/plan', description: 'Structured implementation planning', category: 'Planning' },
|
|
78
|
+
{ command: '/checkpoint', description: 'Save git-state checkpoint inside this session', category: 'Planning' },
|
|
79
|
+
{ command: '/search-first', description: 'Research before coding', category: 'Planning' },
|
|
80
|
+
{ command: '/update-docs', description: 'Sync documentation with code', category: 'Planning' },
|
|
81
|
+
// ── Orchestration ──
|
|
82
|
+
{ command: '/orchestrate', description: 'Decompose into parallel sub-agents', category: 'Orchestration' },
|
|
83
|
+
{ command: '/swarm', description: 'Parallel fan-out: N agents on the same task', category: 'Orchestration' },
|
|
84
|
+
{ command: '/multi-plan', description: 'Multi-agent planning', category: 'Orchestration' },
|
|
85
|
+
// ── Skills & Memory ──
|
|
86
|
+
{ command: '/skills', description: 'List learned + bundled ECC skills', category: 'Skills' },
|
|
87
|
+
{ command: '/skill-show', description: 'Print the full prompt of a specific skill', category: 'Skills' },
|
|
88
|
+
{ command: '/ecc-guide', description: 'Browse the bundled ECC corpus', category: 'Skills' },
|
|
89
|
+
{ command: '/memory', description: 'MemPalace: status, search, recall, list', category: 'Skills' },
|
|
90
|
+
{ command: '/learn', description: 'Extract patterns from this session into instincts', category: 'Skills' },
|
|
91
|
+
// ── Cost & Usage ──
|
|
92
|
+
{ command: '/usage', description: 'Token + cost summary', category: 'Cost' },
|
|
93
|
+
{ command: '/budget', description: 'Set daily/monthly USD budget', category: 'Cost' },
|
|
94
|
+
// ── Debug ──
|
|
95
|
+
{ command: '/debug', description: 'Toggle debug instrumentation + tail event log', category: 'Debug' },
|
|
96
|
+
// ── Voice / Accessibility ──
|
|
97
|
+
{ command: '/voice', description: 'Voice config + master switch', category: 'Voice' },
|
|
98
|
+
{ command: '/accessibility', description: 'Screen-reader mode, audio cues, destructive-confirm', category: 'Voice' },
|
|
99
|
+
{ command: '/dictate', description: 'One-shot record + transcribe', category: 'Voice' },
|
|
100
|
+
// ── Stitch ──
|
|
101
|
+
{ command: '/stitch', description: 'Show Stitch config status', category: 'Stitch' },
|
|
102
|
+
{ command: '/stitch-config', description: 'Save your Stitch API key', category: 'Stitch' },
|
|
103
|
+
// ── Exit ──
|
|
104
|
+
{ command: '/exit', description: 'Quit the REPL', category: 'General' },
|
|
105
|
+
];
|
|
106
|
+
//# sourceMappingURL=command-palette.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"command-palette.js","sourceRoot":"","sources":["../src/command-palette.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -306,6 +306,50 @@ function printResumedHistory(messages, sessionName) {
|
|
|
306
306
|
console.log(d(sep));
|
|
307
307
|
console.log('');
|
|
308
308
|
}
|
|
309
|
+
/**
|
|
310
|
+
* Render the decorative prompt parts (session timer + mode tag)
|
|
311
|
+
* via direct stdout writes, then call rl.question with ONLY the
|
|
312
|
+
* raw glyph + a trailing space.
|
|
313
|
+
*
|
|
314
|
+
* Why: readline counts every byte of its prompt argument toward
|
|
315
|
+
* cursor-positioning math, including ANSI color escape sequences
|
|
316
|
+
* which take ~10 chars to emit but contribute 0 visible width.
|
|
317
|
+
* When the user's typed input crosses the terminal's wrap boundary,
|
|
318
|
+
* readline does `cursorTo + clearScreenDown + redraw`. If its
|
|
319
|
+
* prompt-width count is off, the redraw lands on the wrong row and
|
|
320
|
+
* the visible prompt prefix gets duplicated mid-line (observed in
|
|
321
|
+
* user testing on Windows ConHost with our themed `[5s] [design] ❯`
|
|
322
|
+
* prompt).
|
|
323
|
+
*
|
|
324
|
+
* The fix: bypass readline's accounting for the decorative parts.
|
|
325
|
+
* Write them directly via process.stdout.write (terminal handles
|
|
326
|
+
* them as cursor-visible output, readline never sees them). Pass
|
|
327
|
+
* only the bare glyph (no ANSI codes) to rl.question. With the
|
|
328
|
+
* prompt argument now byte-accurate to its visible width, the
|
|
329
|
+
* wrap-redraw math is correct.
|
|
330
|
+
*
|
|
331
|
+
* Trade-offs:
|
|
332
|
+
* - If the user edits the line (backspace, Ctrl+U, etc.), the
|
|
333
|
+
* decorative prefix doesn't update — but it doesn't NEED to,
|
|
334
|
+
* it's not part of the input.
|
|
335
|
+
* - Screen readers still see the decorative tags (they're plain
|
|
336
|
+
* stdout output) AND the glyph (as the actual prompt).
|
|
337
|
+
* - In screen-reader mode the caller passes an empty sessionTag
|
|
338
|
+
* and modeTag, so this is effectively a no-op there.
|
|
339
|
+
*/
|
|
340
|
+
async function askWithDecoratedPrompt(rl, sessionTag, modeTag, promptGlyph) {
|
|
341
|
+
const decorative = sessionTag + modeTag;
|
|
342
|
+
if (decorative.length > 0) {
|
|
343
|
+
process.stdout.write(decorative);
|
|
344
|
+
}
|
|
345
|
+
// theme.prompt wraps in ANSI codes; we keep the styled glyph for
|
|
346
|
+
// visual continuity, but the rest of readline's prompt argument
|
|
347
|
+
// is now a single short colored string instead of three. The
|
|
348
|
+
// remaining mismatch (color codes around the glyph) is bounded
|
|
349
|
+
// and small enough that wrap math stays correct for typical
|
|
350
|
+
// terminal widths.
|
|
351
|
+
return rl.question(theme.prompt(promptGlyph));
|
|
352
|
+
}
|
|
309
353
|
/**
|
|
310
354
|
* Parse slash command respecting quoted strings
|
|
311
355
|
*/
|
|
@@ -766,10 +810,20 @@ export function handleSlashCommand(input, config, messages, session, mode) {
|
|
|
766
810
|
resetClient();
|
|
767
811
|
console.log(chalk.green(` Model: ${config.model} (custom)`));
|
|
768
812
|
}
|
|
813
|
+
return { handled: true };
|
|
769
814
|
}
|
|
770
|
-
|
|
771
|
-
|
|
815
|
+
// No args. On OpenRouter, the user wants the interactive
|
|
816
|
+
// picker (catalog + pricing). On other providers we don't
|
|
817
|
+
// have an equivalent catalog endpoint, so keep the legacy
|
|
818
|
+
// "show current" behavior.
|
|
819
|
+
if (/openrouter/i.test(config.provider)) {
|
|
820
|
+
// The picker is async; handleSlashCommand is sync. Use the
|
|
821
|
+
// sentinel-injectPrompt pattern that /dictate + /swarm
|
|
822
|
+
// already use to defer async work to the main REPL loop.
|
|
823
|
+
return { handled: true, injectPrompt: '__PICK_MODEL__' };
|
|
772
824
|
}
|
|
825
|
+
console.log(chalk.dim(` Current: ${config.model}`));
|
|
826
|
+
console.log(chalk.dim(' (interactive picker is OpenRouter-only — pass a model name explicitly with /model <id>)'));
|
|
773
827
|
return { handled: true };
|
|
774
828
|
case '/models':
|
|
775
829
|
printModelOptions(config);
|
|
@@ -2671,10 +2725,17 @@ async function main() {
|
|
|
2671
2725
|
'tab', // Shift+Tab cycles perm modes
|
|
2672
2726
|
'escape', // Esc-Esc rewind at empty prompt
|
|
2673
2727
|
',', '.', // Alt+, / Alt+. reasoning effort
|
|
2728
|
+
'space', // Space at empty prompt → command palette
|
|
2674
2729
|
// Shifted F-keys carry the Tier-2 and Tier-3 a11y functions. Each
|
|
2675
2730
|
// is checked alongside key.shift below, so a bare F1 still routes
|
|
2676
2731
|
// to "status" while Shift+F1 routes to "queued input."
|
|
2677
2732
|
]);
|
|
2733
|
+
// Re-entry guard for the picker. The keypress listener can fire
|
|
2734
|
+
// again while the picker is still in alt-screen mode (the user
|
|
2735
|
+
// pressed something the picker handled but we still saw the
|
|
2736
|
+
// 'keypress' event), so we need to make sure we don't open a
|
|
2737
|
+
// second picker on top of the first.
|
|
2738
|
+
let pickerActive = false;
|
|
2678
2739
|
// Define the hotkey listener as a NAMED, TAGGED function so
|
|
2679
2740
|
// suppressInputDuringStream() in query.ts can isolate it among stdin's
|
|
2680
2741
|
// 'keypress' listeners. During streaming we detach readline's own
|
|
@@ -2705,6 +2766,12 @@ async function main() {
|
|
|
2705
2766
|
return;
|
|
2706
2767
|
if (name === 'escape' && (shift || ctrl || meta))
|
|
2707
2768
|
return;
|
|
2769
|
+
// Space is ours ONLY when the input buffer is empty and we're
|
|
2770
|
+
// at a prompt (not mid-streaming). The check happens in the
|
|
2771
|
+
// dedicated branch below; here we just defer if there's any
|
|
2772
|
+
// modifier (Shift+Space, Ctrl+Space, etc. aren't us).
|
|
2773
|
+
if (name === 'space' && (shift || ctrl || meta))
|
|
2774
|
+
return;
|
|
2708
2775
|
const a = getAccessibilityConfig(config);
|
|
2709
2776
|
const tts = getTtsConfig(config);
|
|
2710
2777
|
// Helper: print to stdout (always — picked up by the OS screen reader)
|
|
@@ -2877,6 +2944,70 @@ async function main() {
|
|
|
2877
2944
|
// Any other shifted F-key: no-op (don't fall through to bare).
|
|
2878
2945
|
return;
|
|
2879
2946
|
}
|
|
2947
|
+
// ── Space (bare): command palette at empty prompt ──
|
|
2948
|
+
// Pressing Space when the input buffer is empty opens the
|
|
2949
|
+
// command palette — an alt-screen picker showing every slash
|
|
2950
|
+
// command, arrow-key navigable, type-to-filter, Enter to run.
|
|
2951
|
+
// When the buffer has content (the user is typing a real
|
|
2952
|
+
// message that begins with a space-separated word) the keypress
|
|
2953
|
+
// listener stays out of the way and lets readline handle the
|
|
2954
|
+
// space normally.
|
|
2955
|
+
if (name === 'space') {
|
|
2956
|
+
if (pickerActive)
|
|
2957
|
+
return;
|
|
2958
|
+
const buf = rl.line ?? '';
|
|
2959
|
+
if (buf.length > 0)
|
|
2960
|
+
return; // mid-input — let readline insert the space
|
|
2961
|
+
// Mid-stream space is suppressed by the input guard already;
|
|
2962
|
+
// this listener still fires but we shouldn't open a picker
|
|
2963
|
+
// on top of a streaming turn.
|
|
2964
|
+
const turnCtl = globalThis.__turnAbortCtl;
|
|
2965
|
+
if (turnCtl && !turnCtl.signal.aborted)
|
|
2966
|
+
return;
|
|
2967
|
+
// Open the palette. The picker is async and takes stdin into
|
|
2968
|
+
// raw mode for its lifetime — we fire-and-forget here. On
|
|
2969
|
+
// selection, queue the command and resolve rl.question so the
|
|
2970
|
+
// main loop dispatches it.
|
|
2971
|
+
pickerActive = true;
|
|
2972
|
+
// The space character is already in readline's buffer at
|
|
2973
|
+
// this point (the keypress listener is an observer, not a
|
|
2974
|
+
// gate). Clear it so the prompt is clean once the picker
|
|
2975
|
+
// exits — without this, the selected command would be
|
|
2976
|
+
// appended after the stray space.
|
|
2977
|
+
try {
|
|
2978
|
+
const rlAny = rl;
|
|
2979
|
+
rlAny.line = '';
|
|
2980
|
+
rlAny._refreshLine?.();
|
|
2981
|
+
}
|
|
2982
|
+
catch { /* noop */ }
|
|
2983
|
+
void (async () => {
|
|
2984
|
+
try {
|
|
2985
|
+
const { pick } = await import('./picker.js');
|
|
2986
|
+
const { COMMAND_CATALOG } = await import('./command-palette.js');
|
|
2987
|
+
const items = COMMAND_CATALOG.map((c) => ({
|
|
2988
|
+
label: c.command,
|
|
2989
|
+
hint: c.category,
|
|
2990
|
+
description: c.description,
|
|
2991
|
+
value: c.command,
|
|
2992
|
+
}));
|
|
2993
|
+
const selected = await pick(items, {
|
|
2994
|
+
title: 'compact-agent · command palette',
|
|
2995
|
+
footer: 'type to filter · ↑↓ to navigate · Enter to run · Esc to cancel',
|
|
2996
|
+
});
|
|
2997
|
+
if (selected) {
|
|
2998
|
+
globalThis.__crowcoderQueuedInput = selected + '\n';
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
finally {
|
|
3002
|
+
pickerActive = false;
|
|
3003
|
+
try {
|
|
3004
|
+
rl.emit('line', '');
|
|
3005
|
+
}
|
|
3006
|
+
catch { /* noop */ }
|
|
3007
|
+
}
|
|
3008
|
+
})();
|
|
3009
|
+
return;
|
|
3010
|
+
}
|
|
2880
3011
|
// ── Esc (bare): rewind chord at empty prompt ───────
|
|
2881
3012
|
// Two bare Esc presses within 500ms at an empty input buffer
|
|
2882
3013
|
// triggers /back (rewind one user turn). Matches the muscle
|
|
@@ -3235,7 +3366,7 @@ async function main() {
|
|
|
3235
3366
|
input = next;
|
|
3236
3367
|
}
|
|
3237
3368
|
else {
|
|
3238
|
-
input = await rl
|
|
3369
|
+
input = await askWithDecoratedPrompt(rl, sessionTag, modeTag, promptGlyph);
|
|
3239
3370
|
}
|
|
3240
3371
|
}
|
|
3241
3372
|
else {
|
|
@@ -3244,7 +3375,7 @@ async function main() {
|
|
|
3244
3375
|
// can paste/retype at the prompt.
|
|
3245
3376
|
console.log(theme.dim(` (queued during last chain: "${queued.trim().slice(0, 80)}${queued.length > 80 ? '…' : ''}")`));
|
|
3246
3377
|
}
|
|
3247
|
-
input = await rl
|
|
3378
|
+
input = await askWithDecoratedPrompt(rl, sessionTag, modeTag, promptGlyph);
|
|
3248
3379
|
}
|
|
3249
3380
|
}
|
|
3250
3381
|
catch {
|
|
@@ -3305,6 +3436,42 @@ async function main() {
|
|
|
3305
3436
|
console.log(theme.dim(' [dictate] ') + chalk.white(transcript));
|
|
3306
3437
|
messages.push({ role: 'user', content: transcript });
|
|
3307
3438
|
}
|
|
3439
|
+
else if (result.injectPrompt === '__PICK_MODEL__') {
|
|
3440
|
+
// OpenRouter model picker — same sentinel-into-the-REPL
|
|
3441
|
+
// pattern as /dictate + /swarm because handleSlashCommand
|
|
3442
|
+
// is sync but fetching the catalog + showing the picker
|
|
3443
|
+
// is async. Selection sets config.model + saves; no
|
|
3444
|
+
// injectPrompt cascades into runQuery.
|
|
3445
|
+
const { pick } = await import('./picker.js');
|
|
3446
|
+
const { fetchOpenRouterModels, formatPricing } = await import('./openrouter-models.js');
|
|
3447
|
+
console.log(chalk.dim(' Fetching OpenRouter catalog…'));
|
|
3448
|
+
const models = await fetchOpenRouterModels();
|
|
3449
|
+
if (models.length === 0) {
|
|
3450
|
+
console.log(chalk.yellow(' Could not fetch model catalog (network error or rate limit).'));
|
|
3451
|
+
console.log(chalk.dim(' Use /model <id> with a known model name, or check your connection.'));
|
|
3452
|
+
continue;
|
|
3453
|
+
}
|
|
3454
|
+
const items = models.map((m) => ({
|
|
3455
|
+
label: m.id,
|
|
3456
|
+
hint: formatPricing(m),
|
|
3457
|
+
description: m.name !== m.id ? m.name : undefined,
|
|
3458
|
+
value: m.id,
|
|
3459
|
+
}));
|
|
3460
|
+
const selected = await pick(items, {
|
|
3461
|
+
title: `compact-agent · OpenRouter models (current: ${config.model})`,
|
|
3462
|
+
footer: 'type to filter · ↑↓ to navigate · Enter to pick · Esc to cancel · free models float to the top',
|
|
3463
|
+
});
|
|
3464
|
+
if (selected) {
|
|
3465
|
+
config.model = selected;
|
|
3466
|
+
saveConfig(config);
|
|
3467
|
+
resetClient();
|
|
3468
|
+
console.log(chalk.green(` Model: ${config.model}`));
|
|
3469
|
+
}
|
|
3470
|
+
else {
|
|
3471
|
+
console.log(chalk.dim(' Cancelled — model unchanged.'));
|
|
3472
|
+
}
|
|
3473
|
+
continue;
|
|
3474
|
+
}
|
|
3308
3475
|
else if (result.injectPrompt.startsWith('__SWARM__')) {
|
|
3309
3476
|
// Swarm dispatch: __SWARM__<agentsCsv>|||<task>. Same sentinel
|
|
3310
3477
|
// trick as /dictate so the slash handler stays sync; the async
|