zelari-code 0.7.9 β 0.7.10
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/README.md +68 -43
- package/dist/cli/app.js +33 -3
- package/dist/cli/app.js.map +1 -1
- package/dist/cli/components/LiveRegion.js +7 -3
- package/dist/cli/components/LiveRegion.js.map +1 -1
- package/dist/cli/components/SelectList.js +67 -0
- package/dist/cli/components/SelectList.js.map +1 -0
- package/dist/cli/components/Spinner.js +51 -0
- package/dist/cli/components/Spinner.js.map +1 -0
- package/dist/cli/components/StatusBar.js +42 -34
- package/dist/cli/components/StatusBar.js.map +1 -1
- package/dist/cli/hooks/useSlashDispatch.js +11 -1
- package/dist/cli/hooks/useSlashDispatch.js.map +1 -1
- package/dist/cli/main.bundled.js +11982 -11775
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/main.js +1 -1
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/slashCommands.js +21 -4
- package/dist/cli/slashCommands.js.map +1 -1
- package/dist/cli/slashHandlers/provider.js +101 -4
- package/dist/cli/slashHandlers/provider.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -29,6 +29,8 @@
|
|
|
29
29
|

|
|
30
30
|

|
|
31
31
|
|
|
32
|
+
π **[Guida completa all'uso (IT)](./docs/GUIDA.md)** β installazione, TUI, comandi slash, council, skills, workspace, headless, MCP.
|
|
33
|
+
|
|
32
34
|
**Zelari Code** is a standalone CLI extracted from [AnathemaBrain](https://github.com/N-THEM-Studio/AnathemaBrain). It brings the multi-agent council (Caronte, Nettuno, Gerione, Plutone, Minosse, Lucifero) directly into your terminal with a rich TUI (Ink + React), slash command system, and provider-agnostic LLM streaming (OpenAI-compatible, xAI Grok with OAuth, GLM/Z.AI).
|
|
33
35
|
|
|
34
36
|
> **Upgrading from β€ 0.4.x?** See [MIGRATION.md](./MIGRATION.md) β the internal
|
|
@@ -120,33 +122,42 @@ zelari-code
|
|
|
120
122
|
|
|
121
123
|
## Slash Commands
|
|
122
124
|
|
|
125
|
+
Full reference: **[docs/GUIDA.md](./docs/GUIDA.md#comandi-slash)** (all flags, examples, skill IDs).
|
|
126
|
+
|
|
123
127
|
| Command | Description |
|
|
124
128
|
|---|---|
|
|
125
|
-
| `/help` | List all
|
|
126
|
-
| `/
|
|
127
|
-
| `/
|
|
128
|
-
| `/
|
|
129
|
-
| `/
|
|
129
|
+
| `/help` | List all commands + loaded skills |
|
|
130
|
+
| `/exit` | Exit the CLI |
|
|
131
|
+
| `/login <provider> [key]` | Set API key; `/login grok` starts OAuth |
|
|
132
|
+
| `/provider`, `/provider <id>` | Show / switch LLM provider |
|
|
133
|
+
| `/provider custom <url>` | Self-hosted endpoint (Ollama, LM Studio, β¦) |
|
|
134
|
+
| `/model <name>`, `/models` | Set model / list discovered models |
|
|
135
|
+
| `/skill <id> [input]` | Invoke a coding skill (23 built-in + SKILL.md) |
|
|
136
|
+
| `/skill-stats [id]` | Skill invocation stats |
|
|
130
137
|
| `/skill-compare <id1> <id2>` | Compare two skills' stats |
|
|
131
|
-
| `/
|
|
132
|
-
| `/
|
|
133
|
-
| `/
|
|
134
|
-
| `/
|
|
135
|
-
| `/
|
|
136
|
-
| `/
|
|
137
|
-
| `/
|
|
138
|
-
| `/
|
|
139
|
-
| `/
|
|
140
|
-
| `/
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
138
|
+
| `/council <input>` | Run the 6-member council pipeline |
|
|
139
|
+
| `/council-feedback <id> <1-5>` | Rate a council member |
|
|
140
|
+
| `/promote-member <id>` | Promote a council member to a skill |
|
|
141
|
+
| `/sessions`, `/resume <id>`, `/new` | Session management |
|
|
142
|
+
| `/branch <name>`, `/branches`, `/checkout <name>` | Session branches |
|
|
143
|
+
| `/compact`, `/clear` | Compact / clear transcript |
|
|
144
|
+
| `/diff [--staged]`, `/undo --yes` | Git diff / revert (destructive) |
|
|
145
|
+
| `/steer <text>`, `/steer --interrupt <text>` | Queue follow-up during a run |
|
|
146
|
+
| `/workspace β¦` | `.zelari/` artifacts + `AGENTS.MD` |
|
|
147
|
+
| `/update`, `/update --yes` | Check / install CLI updates |
|
|
148
|
+
|
|
149
|
+
**TUI:** `shift+tab` toggles **agent** β **council** mode for free-form prompts.
|
|
150
|
+
|
|
151
|
+
## Headless Mode
|
|
152
|
+
|
|
153
|
+
Run a single task without the TUI (CI/scripts):
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
zelari-code --headless --task "Explain src/cli/main.ts" --output plain
|
|
157
|
+
zelari-code --headless --task "Design a REST API" --council --output json
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
See **[docs/GUIDA.md](./docs/GUIDA.md#modalitΓ -headless-ciscript)** for exit codes and all flags.
|
|
150
161
|
|
|
151
162
|
## Self-Update
|
|
152
163
|
|
|
@@ -156,12 +167,11 @@ Zelari Code includes a built-in update mechanism:
|
|
|
156
167
|
# Inside the TUI:
|
|
157
168
|
/update # check for updates (prints current vs latest)
|
|
158
169
|
/update --yes # apply update (runs npm install -g zelari-code@latest)
|
|
159
|
-
/update force # reinstall latest (even if already on latest)
|
|
160
170
|
```
|
|
161
171
|
|
|
162
172
|
On startup, the CLI silently checks the npm registry. If a newer version is available, it prints a one-line hint to stderr.
|
|
163
173
|
|
|
164
|
-
Disable auto-check: `
|
|
174
|
+
Disable auto-check: `ANATHEMA_DEV=1 zelari-code`
|
|
165
175
|
|
|
166
176
|
## Features
|
|
167
177
|
|
|
@@ -171,32 +181,32 @@ Disable auto-check: `ZELARI_DEV=1 zelari-code`
|
|
|
171
181
|
- ποΈ **Live git sidebar** β right-hand panel with the N-THEM emblem and the working-tree changes (`+added`/`-removed` per file, refreshed every 4s; auto-hidden on narrow terminals)
|
|
172
182
|
- β±οΈ **Execution timer** β elapsed time of the in-flight turn in the status line (`β± 12s`), frozen as `last 34s` when the run completes
|
|
173
183
|
- π§ **Provider-agnostic** β OpenAI-compatible APIs (OpenAI, Together, Groq, custom), xAI Grok with OAuth refresh, GLM/Z.AI
|
|
174
|
-
- π οΈ **Built-in tools** β filesystem (read/write/edit), shell (bash), search (grep),
|
|
175
|
-
- π **
|
|
184
|
+
- π οΈ **Built-in tools** β filesystem (read/write/edit), shell (bash), search (grep), web fetch/search
|
|
185
|
+
- π **23 coding skills** (+ user `SKILL.md` from `.zelari/skills/`, `.claude/skills/`, β¦)
|
|
176
186
|
- π **Cross-provider failover** β automatic retry with provider swap on transient errors
|
|
177
|
-
- π° **Cost tracking** β per-turn + cumulative USD cost via model pricing registry
|
|
178
187
|
- π **Metrics + skill history** β fire-and-forget logging to `~/.tmp/zelari-code/`
|
|
179
188
|
- ποΈ **Session management** β JSONL transcripts, resume across restarts, compaction
|
|
180
|
-
- πΏ **Branch isolation** β
|
|
181
|
-
- π **
|
|
189
|
+
- πΏ **Branch isolation** β session snapshots per branch
|
|
190
|
+
- π **MCP** β external MCP servers via `.zelari/mcp.json`
|
|
182
191
|
- π **Self-update** β `/update` slash command + silent registry check on startup
|
|
183
192
|
|
|
184
193
|
## Architecture
|
|
185
194
|
|
|
186
195
|
```
|
|
187
|
-
zelari-code (CLI)
|
|
188
|
-
βββ src/cli/ # Ink
|
|
189
|
-
β βββ components/ #
|
|
190
|
-
β βββ
|
|
191
|
-
β βββ
|
|
192
|
-
|
|
193
|
-
βββ
|
|
194
|
-
|
|
195
|
-
βββ
|
|
196
|
-
|
|
196
|
+
zelari-code (CLI, proprietary)
|
|
197
|
+
βββ src/cli/ # Ink TUI, provider config, workspace, wizard, MCP
|
|
198
|
+
β βββ components/ # ChatStream, InputBar, Sidebar, StatusBar, β¦
|
|
199
|
+
β βββ slashHandlers/ # /provider, /workspace, /update, β¦
|
|
200
|
+
β βββ workspace/ # .zelari/ persistence + AGENTS.MD curation
|
|
201
|
+
βββ packages/core/ # @zelari/core (MIT, npm)
|
|
202
|
+
βββ core/ # AgentHarness β provider-neutral agent loop
|
|
203
|
+
βββ agents/ # Council API, roles, 23 skills, tool schemas
|
|
204
|
+
βββ harness/tools/ # Tool registry + filesystem/shell/search/web
|
|
205
|
+
βββ events/ # BrainEvent contract
|
|
206
|
+
βββ council/ # Run mode, tier banners
|
|
197
207
|
```
|
|
198
208
|
|
|
199
|
-
`AgentHarness`
|
|
209
|
+
`AgentHarness` takes (model, provider, messages, tools) + a streaming function and yields `AsyncIterable<BrainEvent>`. The CLI subscribes and renders via `eventsToMessages()`. See [MIGRATION.md](./MIGRATION.md) for the v0.5+ package boundary.
|
|
200
210
|
|
|
201
211
|
## Environment Variables
|
|
202
212
|
|
|
@@ -207,9 +217,14 @@ zelari-code (CLI)
|
|
|
207
217
|
| `OPENAI_BASE_URL` | Custom OpenAI-compatible endpoint |
|
|
208
218
|
| `GLM_API_KEY` | GLM/Z.AI API key |
|
|
209
219
|
| `GROK_API_KEY` | xAI Grok API key (alternative to OAuth) |
|
|
210
|
-
| `
|
|
220
|
+
| `ANATHEMA_DEV=1` | Disable silent update check on startup |
|
|
221
|
+
| `ZELARI_NO_WIZARD=1` | Skip first-run wizard |
|
|
222
|
+
| `ZELARI_COUNCIL_TIER=lite` | Council with 3 members instead of 6 |
|
|
223
|
+
| `ZELARI_MCP=0` | Disable MCP servers |
|
|
211
224
|
| `ANATHEMA_FAILOVER=0` | Disable cross-provider failover |
|
|
212
225
|
|
|
226
|
+
See **[docs/GUIDA.md](./docs/GUIDA.md#variabili-dambiente)** for the full list.
|
|
227
|
+
|
|
213
228
|
## Council Workspace
|
|
214
229
|
|
|
215
230
|
The CLI persists council output (decisions, risks, docs, plan, reviews) into a **project-local** `.zelari/` directory and auto-curates an `AGENTS.MD` at the project root.
|
|
@@ -263,6 +278,15 @@ Set `ZELARI_AGENTS_MD=0` to disable AGENTS.MD auto-curation.
|
|
|
263
278
|
|
|
264
279
|
See [`docs/plans/2026-07-01-council-workspace-cli-stubs.md`](./docs/plans/2026-07-01-council-workspace-cli-stubs.md) for the full schema.
|
|
265
280
|
|
|
281
|
+
## Documentation
|
|
282
|
+
|
|
283
|
+
| Doc | Description |
|
|
284
|
+
|---|---|
|
|
285
|
+
| [docs/GUIDA.md](./docs/GUIDA.md) | **Guida utente completa** (IT) |
|
|
286
|
+
| [docs/TOOLS.md](./docs/TOOLS.md) | Tool builtin, workspace, MCP |
|
|
287
|
+
| [MIGRATION.md](./MIGRATION.md) | Upgrade from β€ 0.4.x |
|
|
288
|
+
| [docs/decisions/](./docs/decisions/) | ADRs (monorepo, npm publish, API policy) |
|
|
289
|
+
|
|
266
290
|
## Development
|
|
267
291
|
|
|
268
292
|
```bash
|
|
@@ -290,6 +314,7 @@ npm run typecheck
|
|
|
290
314
|
|
|
291
315
|
- [AnathemaBrain](https://github.com/N-THEM-Studio/AnathemaBrain) β the Electron desktop GUI that shares the agent runtime + council system with this CLI
|
|
292
316
|
- Zelari Coder originated as the `npm run coder` script inside AnathemaBrain
|
|
317
|
+
- [@zelari/core on npm](https://www.npmjs.com/package/@zelari/core) β reusable agent runtime (MIT)
|
|
293
318
|
|
|
294
319
|
## License
|
|
295
320
|
|
package/dist/cli/app.js
CHANGED
|
@@ -2,12 +2,14 @@
|
|
|
2
2
|
// the v3-N monolithic app. Behavior is correct; a future pass will tighten the
|
|
3
3
|
// hook signatures and remove this annotation. The split is documented in
|
|
4
4
|
// `docs/plans/2026-07-01-app-split.md`.
|
|
5
|
-
import React, { useState, useMemo, useCallback } from 'react';
|
|
5
|
+
import React, { useState, useMemo, useCallback, useEffect } from 'react';
|
|
6
6
|
import { Box, Static, useInput, useStdin } from 'ink';
|
|
7
7
|
import { InputBar } from './components/InputBar.js';
|
|
8
8
|
import { LiveRegion } from './components/LiveRegion.js';
|
|
9
9
|
import { StatusBar } from './components/StatusBar.js';
|
|
10
|
+
import { SelectList } from './components/SelectList.js';
|
|
10
11
|
import { Sidebar, shouldShowSidebar } from './components/Sidebar.js';
|
|
12
|
+
import { discoverModelsInBackground, isModelsCacheStale } from './modelDiscovery.js';
|
|
11
13
|
import { renderMessage } from './components/ChatStream.js';
|
|
12
14
|
import { listCodingSkills } from '@zelari/core/skills';
|
|
13
15
|
import { useGitChanges } from './hooks/useGitChanges.js';
|
|
@@ -67,6 +69,9 @@ export function App() {
|
|
|
67
69
|
// v0.7.9: dispatch mode for free-form prompts β 'agent' (single harness
|
|
68
70
|
// turn) or 'council' (6-member pipeline). Toggled with shift+tab.
|
|
69
71
|
const [mode, setMode] = useState('agent');
|
|
72
|
+
// v0.7.10: interactive picker (/provider, /model). While open it replaces
|
|
73
|
+
// the InputBar so ink-text-input never competes for arrow keys.
|
|
74
|
+
const [picker, setPicker] = useState(null);
|
|
70
75
|
const activeProviderSpec = getActiveProviderSpec();
|
|
71
76
|
const activeModel = providerConfig.modelByProvider[activeProviderSpec.id];
|
|
72
77
|
const session = useSession();
|
|
@@ -84,6 +89,19 @@ export function App() {
|
|
|
84
89
|
setMode((m) => (m === 'agent' ? 'council' : 'agent'));
|
|
85
90
|
}
|
|
86
91
|
}, { isActive: isRawModeSupported === true });
|
|
92
|
+
// v0.7.10: startup model discovery β refresh the /v1/models cache in the
|
|
93
|
+
// background when it's missing or older than 6h, so the /model picker and
|
|
94
|
+
// tab-completion show current choices without an explicit /discover.
|
|
95
|
+
useEffect(() => {
|
|
96
|
+
const id = activeProviderSpec.id;
|
|
97
|
+
if (!['grok', 'glm', 'minimax', 'openai-compatible'].includes(id))
|
|
98
|
+
return;
|
|
99
|
+
if (!isModelsCacheStale(id))
|
|
100
|
+
return;
|
|
101
|
+
discoverModelsInBackground(id, {});
|
|
102
|
+
// Run once at mount for the provider active at startup.
|
|
103
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
104
|
+
}, []);
|
|
87
105
|
// Throttle layer for the `live` region β coalesces per-token streaming
|
|
88
106
|
// updates (~50-200/sec) into β€60 renders/sec. The finalized array uses the
|
|
89
107
|
// raw setter (its appends are rare and user-facing).
|
|
@@ -135,10 +153,22 @@ export function App() {
|
|
|
135
153
|
dispatchPrompt: chatTurn.dispatchPrompt,
|
|
136
154
|
dispatchCouncilPrompt: chatTurn.dispatchCouncilPrompt,
|
|
137
155
|
mode,
|
|
156
|
+
openPicker: setPicker,
|
|
138
157
|
onNewSession,
|
|
139
158
|
onExit,
|
|
140
159
|
onClear,
|
|
141
160
|
});
|
|
161
|
+
// Picker selection re-enters the normal slash pipeline ('/provider <id>' /
|
|
162
|
+
// '/model <id>') so persistence, config refresh and the system message all
|
|
163
|
+
// come from the same code path as a typed command.
|
|
164
|
+
const onPickerSelect = useCallback((value) => {
|
|
165
|
+
if (!picker)
|
|
166
|
+
return;
|
|
167
|
+
const cmd = `${picker.commandPrefix} ${value}`;
|
|
168
|
+
setPicker(null);
|
|
169
|
+
void handleSubmit(cmd);
|
|
170
|
+
}, [picker, handleSubmit]);
|
|
171
|
+
const onPickerCancel = useCallback(() => setPicker(null), []);
|
|
142
172
|
// The one-shot banner: printed once as the first Static item. v0.7.9: the
|
|
143
173
|
// skill list is gone (it doubled the banner height and duplicated /help);
|
|
144
174
|
// the banner is now just the wordmark line + cwd + a hint.
|
|
@@ -174,8 +204,8 @@ export function App() {
|
|
|
174
204
|
React.createElement(Static, { key: staticKey, items: staticItems }, (item) => renderMessage(item)),
|
|
175
205
|
React.createElement(Box, { flexDirection: "row" },
|
|
176
206
|
React.createElement(Box, { flexDirection: "column", flexGrow: 1, paddingX: 1 },
|
|
177
|
-
React.createElement(LiveRegion, { live: session.live, busy: busy }),
|
|
178
|
-
React.createElement(InputBar, { value: input, onChange: setInput, onSubmit: handleSubmit, disabled: busy }),
|
|
207
|
+
React.createElement(LiveRegion, { live: session.live, busy: busy, elapsedMs: timer.elapsedMs }),
|
|
208
|
+
picker ? (React.createElement(SelectList, { title: picker.title, items: picker.items, onSelect: onPickerSelect, onCancel: onPickerCancel, maxVisible: Math.max(4, Math.min(10, size.rows - 10)) })) : (React.createElement(InputBar, { value: input, onChange: setInput, onSubmit: handleSubmit, disabled: busy })),
|
|
179
209
|
React.createElement(StatusBar, { model: activeModel, provider: activeProviderSpec.id, sessionId: session.sessionId ? session.sessionId.slice(0, 8) : '...', sessionActive: session.sessionActive, queueCount: chatTurn.queueCount, busy: busy, mode: mode, cwd: cwd, elapsedMs: timer.elapsedMs, lastMs: timer.lastMs })),
|
|
180
210
|
showSidebar && (React.createElement(Sidebar, { version: VERSION, changes: gitChanges, rows: size.rows })))));
|
|
181
211
|
}
|
package/dist/cli/app.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/cli/app.tsx"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,+EAA+E;AAC/E,yEAAyE;AACzE,wCAAwC;AACxC,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,WAAW,EAAU,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/cli/app.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
3
|
import { renderMessage } from './ChatStream.js';
|
|
4
|
+
import { WorkingIndicator } from './Spinner.js';
|
|
4
5
|
/**
|
|
5
6
|
* Max lines of the streaming bubble kept in the dynamic region. The full
|
|
6
7
|
* text is never lost β it lands complete in `<Static>` at finalize. This
|
|
@@ -21,14 +22,17 @@ const LIVE_STREAM_TAIL_LINES = 10;
|
|
|
21
22
|
* repaint β no flicker, by construction. Finalized messages live in the
|
|
22
23
|
* terminal's native scrollback via `<Static>` (printed exactly once).
|
|
23
24
|
*/
|
|
24
|
-
export function LiveRegion({ live, busy }) {
|
|
25
|
+
export function LiveRegion({ live, busy, elapsedMs = null }) {
|
|
25
26
|
const { streaming, runningTools } = live;
|
|
26
|
-
|
|
27
|
+
// v0.7.10: `busy` keeps the region alive so the animated WorkingIndicator
|
|
28
|
+
// shows between dispatch and the first streamed token / tool call. (The
|
|
29
|
+
// old check dropped `busy`, which made the fallback line dead code.)
|
|
30
|
+
if (!streaming && runningTools.length === 0 && !busy)
|
|
27
31
|
return null;
|
|
28
32
|
return (React.createElement(Box, { flexDirection: "column", paddingX: 1 },
|
|
29
33
|
streaming && streaming.role === 'assistant' && (React.createElement(StreamingTail, { id: streaming.id, content: streaming.content, ts: streaming.ts, memberName: streaming.memberName, memberId: streaming.memberId })),
|
|
30
34
|
runningTools.map((t) => (React.createElement(Box, { key: t.id, flexDirection: "column" }, renderMessage(t, true)))),
|
|
31
|
-
busy && runningTools.length === 0 && !streaming && (React.createElement(
|
|
35
|
+
busy && runningTools.length === 0 && !streaming && (React.createElement(WorkingIndicator, { elapsedMs: elapsedMs }))));
|
|
32
36
|
}
|
|
33
37
|
/**
|
|
34
38
|
* Render the streaming bubble, clamped to the last N content lines. A leading
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LiveRegion.js","sourceRoot":"","sources":["../../../src/cli/components/LiveRegion.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGhD;;;;;GAKG;AACH,MAAM,sBAAsB,GAAG,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"LiveRegion.js","sourceRoot":"","sources":["../../../src/cli/components/LiveRegion.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAGhD;;;;;GAKG;AACH,MAAM,sBAAsB,GAAG,EAAE,CAAC;AASlC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,GAAG,IAAI,EAAmB;IAC1E,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;IAEzC,0EAA0E;IAC1E,wEAAwE;IACxE,qEAAqE;IACrE,IAAI,CAAC,SAAS,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAElE,OAAO,CACL,oBAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,EAAC,QAAQ,EAAE,CAAC;QACpC,SAAS,IAAI,SAAS,CAAC,IAAI,KAAK,WAAW,IAAI,CAC9C,oBAAC,aAAa,IACZ,EAAE,EAAE,SAAS,CAAC,EAAE,EAChB,OAAO,EAAE,SAAS,CAAC,OAAO,EAC1B,EAAE,EAAE,SAAS,CAAC,EAAE,EAChB,UAAU,EAAE,SAAS,CAAC,UAAU,EAChC,QAAQ,EAAE,SAAS,CAAC,QAAQ,GAC5B,CACH;QACA,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACvB,oBAAC,GAAG,IAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,aAAa,EAAC,QAAQ,IACnC,aAAa,CAAC,CAAC,EAAE,IAAI,CAAC,CACnB,CACP,CAAC;QACD,IAAI,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAClD,oBAAC,gBAAgB,IAAC,SAAS,EAAE,SAAS,GAAI,CAC3C,CACG,CACP,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,SAAS,aAAa,CAAC,CAMtB;IACC,MAAM,KAAK,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,GAAG,sBAAsB,CAAC;IACxD,MAAM,IAAI,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACtE,OAAO,CACL,oBAAC,GAAG,IAAC,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,aAAa,EAAC,QAAQ,EAAC,YAAY,EAAE,CAAC;QACpD,oBAAC,IAAI,IAAC,KAAK,EAAC,OAAO,EAAC,IAAI;;YAErB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,oBAAC,IAAI,IAAC,KAAK,EAAC,SAAS;;gBAAK,CAAC,CAAC,UAAU,CAAQ,CAAC,CAAC,CAAC,IAAI,CAChE;QACP,oBAAC,GAAG,IAAC,UAAU,EAAE,CAAC,EAAE,aAAa,EAAC,QAAQ;YACvC,SAAS,IAAI,oBAAC,IAAI,IAAC,QAAQ,mBAAS;YACrC,oBAAC,IAAI,QAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAQ,CAC1B,CACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Box, Text, useInput, useStdin } from 'ink';
|
|
3
|
+
/**
|
|
4
|
+
* Pure windowing helper (exported for tests): index of the first visible
|
|
5
|
+
* item so the cursor stays roughly centered while the list scrolls.
|
|
6
|
+
*/
|
|
7
|
+
export function windowStart(index, count, maxVisible) {
|
|
8
|
+
if (count <= maxVisible)
|
|
9
|
+
return 0;
|
|
10
|
+
const half = Math.floor(maxVisible / 2);
|
|
11
|
+
return Math.max(0, Math.min(index - half, count - maxVisible));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* SelectList β arrow-key picker rendered in the dynamic region (v0.7.10).
|
|
15
|
+
*
|
|
16
|
+
* Used by `/provider` and `/model` (no args) to make providers and models
|
|
17
|
+
* selectable instead of typed. The App swaps it in for the InputBar while
|
|
18
|
+
* open, so ink-text-input never competes for keystrokes. β/β move (with
|
|
19
|
+
* wrap-around), enter selects, esc cancels. Long lists scroll inside a
|
|
20
|
+
* `maxVisible` window so the dynamic region stays under a screen.
|
|
21
|
+
*/
|
|
22
|
+
export function SelectList({ title, items, onSelect, onCancel, maxVisible = 8, }) {
|
|
23
|
+
const firstCurrent = items.findIndex((i) => i.current);
|
|
24
|
+
const [index, setIndex] = useState(firstCurrent === -1 ? 0 : firstCurrent);
|
|
25
|
+
const { isRawModeSupported } = useStdin();
|
|
26
|
+
useInput((_input, key) => {
|
|
27
|
+
if (key.upArrow) {
|
|
28
|
+
setIndex((i) => (i - 1 + items.length) % items.length);
|
|
29
|
+
}
|
|
30
|
+
else if (key.downArrow) {
|
|
31
|
+
setIndex((i) => (i + 1) % items.length);
|
|
32
|
+
}
|
|
33
|
+
else if (key.return) {
|
|
34
|
+
const item = items[index];
|
|
35
|
+
if (item)
|
|
36
|
+
onSelect(item.value);
|
|
37
|
+
}
|
|
38
|
+
else if (key.escape) {
|
|
39
|
+
onCancel();
|
|
40
|
+
}
|
|
41
|
+
}, { isActive: isRawModeSupported === true });
|
|
42
|
+
const start = windowStart(index, items.length, maxVisible);
|
|
43
|
+
const visible = items.slice(start, start + maxVisible);
|
|
44
|
+
const below = items.length - (start + visible.length);
|
|
45
|
+
return (React.createElement(Box, { flexDirection: "column", borderStyle: "round", borderColor: "cyan", paddingX: 1 },
|
|
46
|
+
React.createElement(Text, { bold: true, color: "cyan" }, title),
|
|
47
|
+
start > 0 && React.createElement(Text, { dimColor: true },
|
|
48
|
+
" \u2191 ",
|
|
49
|
+
start,
|
|
50
|
+
" more"),
|
|
51
|
+
visible.map((item, i) => {
|
|
52
|
+
const selected = start + i === index;
|
|
53
|
+
return (React.createElement(Text, { key: item.value, wrap: "truncate", color: selected ? 'cyan' : undefined },
|
|
54
|
+
selected ? 'β― ' : ' ',
|
|
55
|
+
React.createElement(Text, { bold: selected }, item.label),
|
|
56
|
+
item.current ? React.createElement(Text, { color: "green" }, " \u2713") : null,
|
|
57
|
+
item.hint ? React.createElement(Text, { dimColor: true },
|
|
58
|
+
" ",
|
|
59
|
+
item.hint) : null));
|
|
60
|
+
}),
|
|
61
|
+
below > 0 && React.createElement(Text, { dimColor: true },
|
|
62
|
+
" \u2193 ",
|
|
63
|
+
below,
|
|
64
|
+
" more"),
|
|
65
|
+
React.createElement(Text, { dimColor: true }, "\u2191/\u2193 move \u00B7 enter select \u00B7 esc cancel")));
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=SelectList.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectList.js","sourceRoot":"","sources":["../../../src/cli/components/SelectList.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { Text } from 'ink';
|
|
3
|
+
import { formatDuration } from '../utils/duration.js';
|
|
4
|
+
/** Braille spinner frames β one step every FRAME_MS. */
|
|
5
|
+
const FRAMES = ['β ', 'β ', 'β Ή', 'β Έ', 'β Ό', 'β ΄', 'β ¦', 'β §', 'β ', 'β '];
|
|
6
|
+
const FRAME_MS = 100;
|
|
7
|
+
/** Rotating activity verbs shown by <WorkingIndicator>, one every VERB_MS. */
|
|
8
|
+
const VERBS = ['thinking', 'working', 'reasoning', 'assembling'];
|
|
9
|
+
const VERB_MS = 2500;
|
|
10
|
+
/** Trailing-dots animation period (β¦β . β .. β ...). */
|
|
11
|
+
const DOTS_MS = 400;
|
|
12
|
+
/**
|
|
13
|
+
* Shared ticker hook: increments every FRAME_MS while mounted. Both animated
|
|
14
|
+
* components derive spinner frame / verb / dots from the same counter so a
|
|
15
|
+
* single interval drives everything.
|
|
16
|
+
*/
|
|
17
|
+
function useTick() {
|
|
18
|
+
const [tick, setTick] = useState(0);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
const id = setInterval(() => setTick((t) => t + 1), FRAME_MS);
|
|
21
|
+
return () => clearInterval(id);
|
|
22
|
+
}, []);
|
|
23
|
+
return tick;
|
|
24
|
+
}
|
|
25
|
+
/** Minimal animated braille spinner (single glyph, no label). */
|
|
26
|
+
export function Spinner({ color = 'yellow' }) {
|
|
27
|
+
const tick = useTick();
|
|
28
|
+
return React.createElement(Text, { color: color }, FRAMES[tick % FRAMES.length]);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* WorkingIndicator β replaces the static `β― workingβ¦` line (v0.7.10).
|
|
32
|
+
* Animated spinner + a verb that rotates every ~2.5s + trailing dots, plus
|
|
33
|
+
* the elapsed run time when the caller provides it. The motion makes it
|
|
34
|
+
* obvious the run is alive even before the first streamed token arrives.
|
|
35
|
+
*/
|
|
36
|
+
export function WorkingIndicator({ elapsedMs = null, }) {
|
|
37
|
+
const tick = useTick();
|
|
38
|
+
const frame = FRAMES[tick % FRAMES.length];
|
|
39
|
+
const verb = VERBS[Math.floor((tick * FRAME_MS) / VERB_MS) % VERBS.length];
|
|
40
|
+
const dots = '.'.repeat(1 + (Math.floor((tick * FRAME_MS) / DOTS_MS) % 3));
|
|
41
|
+
return (React.createElement(Text, { color: "yellow" },
|
|
42
|
+
frame,
|
|
43
|
+
" ",
|
|
44
|
+
verb,
|
|
45
|
+
dots,
|
|
46
|
+
typeof elapsedMs === 'number' ? (React.createElement(Text, { dimColor: true },
|
|
47
|
+
" (",
|
|
48
|
+
formatDuration(elapsedMs),
|
|
49
|
+
")")) : null));
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=Spinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Spinner.js","sourceRoot":"","sources":["../../../src/cli/components/Spinner.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAC3B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAEtD,wDAAwD;AACxD,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAC;AAC3E,MAAM,QAAQ,GAAG,GAAG,CAAC;AAErB,8EAA8E;AAC9E,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,YAAY,CAAU,CAAC;AAC1E,MAAM,OAAO,GAAG,IAAI,CAAC;AACrB,wDAAwD;AACxD,MAAM,OAAO,GAAG,GAAG,CAAC;AAEpB;;;;GAIG;AACH,SAAS,OAAO;IACd,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACpC,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,EAAE,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAC9D,OAAO,GAAG,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;IACjC,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,OAAO,IAAI,CAAC;AACd,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,EAAsB;IAC9D,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,OAAO,oBAAC,IAAI,IAAC,KAAK,EAAE,KAAK,IAAG,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAQ,CAAC;AACnE,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,gBAAgB,CAAC,EAC/B,SAAS,GAAG,IAAI,GAGjB;IACC,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,GAAG,QAAQ,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;IAC3E,OAAO,CACL,oBAAC,IAAI,IAAC,KAAK,EAAC,QAAQ;QACjB,KAAK;;QAAG,IAAI;QAAE,IAAI;QAClB,OAAO,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAC/B,oBAAC,IAAI,IAAC,QAAQ;;YAAI,cAAc,CAAC,SAAS,CAAC;gBAAS,CACrD,CAAC,CAAC,CAAC,IAAI,CACH,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -1,46 +1,54 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { Box, Text } from 'ink';
|
|
3
3
|
import { formatDuration } from '../utils/duration.js';
|
|
4
|
+
import { Spinner } from './Spinner.js';
|
|
4
5
|
/**
|
|
5
|
-
* StatusBar β single one-line status bar
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
6
|
+
* StatusBar β single one-line status bar rendered below the input box.
|
|
7
|
+
*
|
|
8
|
+
* v0.7.10: extended to the full terminal width. Two groups justified with
|
|
9
|
+
* space-between: identity on the left (mode Β· provider Β· model Β· cwd) and
|
|
10
|
+
* run state on the right (spinner+timer / last, queue, session). Both groups
|
|
11
|
+
* truncate instead of wrapping, so the bar is always exactly one row β the
|
|
12
|
+
* old layout wrapped on narrow terminals, squashing the dynamic region.
|
|
9
13
|
*
|
|
10
14
|
* Why one line: the static-scrollback model (v0.7.0) needs the dynamic
|
|
11
15
|
* region as short as possible. A single status line + the input bar + the
|
|
12
16
|
* streaming tail is always well under a screen, so no full repaint.
|
|
13
17
|
*/
|
|
14
18
|
export function StatusBar({ model, provider, sessionId, sessionActive, queueCount = 0, busy = false, mode = 'agent', cwd, elapsedMs = null, lastMs = null, }) {
|
|
15
|
-
return (React.createElement(Box, { paddingX: 1 },
|
|
16
|
-
React.createElement(
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
React.createElement(Text, {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
19
|
+
return (React.createElement(Box, { paddingX: 1, width: "100%", justifyContent: "space-between", gap: 2 },
|
|
20
|
+
React.createElement(Box, { flexShrink: 2 },
|
|
21
|
+
React.createElement(Text, { wrap: "truncate" },
|
|
22
|
+
React.createElement(Text, { color: sessionActive ? 'green' : 'gray' }, sessionActive ? 'β' : 'β'),
|
|
23
|
+
React.createElement(Text, { dimColor: true }, " "),
|
|
24
|
+
React.createElement(Text, { bold: true, color: mode === 'council' ? 'magenta' : 'cyan' }, mode === 'council' ? 'β¬ council' : 'β΅ agent'),
|
|
25
|
+
React.createElement(Text, { dimColor: true }, " (shift+tab)"),
|
|
26
|
+
React.createElement(Text, { dimColor: true }, " \u00B7 "),
|
|
27
|
+
React.createElement(Text, { bold: true, color: "cyan" }, provider),
|
|
28
|
+
React.createElement(Text, { dimColor: true }, " \u00B7 "),
|
|
29
|
+
React.createElement(Text, null, model),
|
|
30
|
+
cwd ? (React.createElement(React.Fragment, null,
|
|
31
|
+
React.createElement(Text, { dimColor: true }, " \u00B7 "),
|
|
32
|
+
React.createElement(Text, { color: "blue" }, cwd))) : null)),
|
|
33
|
+
React.createElement(Box, { flexShrink: 1 },
|
|
34
|
+
React.createElement(Text, { wrap: "truncate" },
|
|
35
|
+
busy && elapsedMs !== null ? (React.createElement(React.Fragment, null,
|
|
36
|
+
React.createElement(Spinner, { color: "yellow" }),
|
|
37
|
+
React.createElement(Text, { color: "yellow" },
|
|
38
|
+
" ",
|
|
39
|
+
formatDuration(elapsedMs)),
|
|
40
|
+
React.createElement(Text, { dimColor: true }, " \u00B7 "))) : lastMs !== null ? (React.createElement(React.Fragment, null,
|
|
41
|
+
React.createElement(Text, { dimColor: true },
|
|
42
|
+
"last ",
|
|
43
|
+
formatDuration(lastMs)),
|
|
44
|
+
React.createElement(Text, { dimColor: true }, " \u00B7 "))) : null,
|
|
45
|
+
queueCount > 0 ? (React.createElement(React.Fragment, null,
|
|
46
|
+
React.createElement(Text, { color: "magenta" },
|
|
47
|
+
"queue ",
|
|
48
|
+
queueCount),
|
|
49
|
+
React.createElement(Text, { dimColor: true }, " \u00B7 "))) : null,
|
|
50
|
+
React.createElement(Text, { dimColor: true },
|
|
51
|
+
"session ",
|
|
52
|
+
sessionId)))));
|
|
45
53
|
}
|
|
46
54
|
//# sourceMappingURL=StatusBar.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/cli/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"StatusBar.js","sourceRoot":"","sources":["../../../src/cli/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAqBvC;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CAAC,EACxB,KAAK,EACL,QAAQ,EACR,SAAS,EACT,aAAa,EACb,UAAU,GAAG,CAAC,EACd,IAAI,GAAG,KAAK,EACZ,IAAI,GAAG,OAAO,EACd,GAAG,EACH,SAAS,GAAG,IAAI,EAChB,MAAM,GAAG,IAAI,GACE;IACf,OAAO,CACL,oBAAC,GAAG,IAAC,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAC,MAAM,EAAC,cAAc,EAAC,eAAe,EAAC,GAAG,EAAE,CAAC;QAElE,oBAAC,GAAG,IAAC,UAAU,EAAE,CAAC;YAClB,oBAAC,IAAI,IAAC,IAAI,EAAC,UAAU;gBACnB,oBAAC,IAAI,IAAC,KAAK,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAC1C,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CACrB;gBACP,oBAAC,IAAI,IAAC,QAAQ,cAAS;gBACvB,oBAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAE,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,IACtD,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CACxC;gBACP,oBAAC,IAAI,IAAC,QAAQ,yBAAoB;gBAClC,oBAAC,IAAI,IAAC,QAAQ,qBAAW;gBACzB,oBAAC,IAAI,IAAC,IAAI,QAAC,KAAK,EAAC,MAAM,IAAE,QAAQ,CAAQ;gBACzC,oBAAC,IAAI,IAAC,QAAQ,qBAAW;gBACzB,oBAAC,IAAI,QAAE,KAAK,CAAQ;gBACnB,GAAG,CAAC,CAAC,CAAC,CACL;oBACE,oBAAC,IAAI,IAAC,QAAQ,qBAAW;oBACzB,oBAAC,IAAI,IAAC,KAAK,EAAC,MAAM,IAAE,GAAG,CAAQ,CAC9B,CACJ,CAAC,CAAC,CAAC,IAAI,CACH,CACD;QACN,oBAAC,GAAG,IAAC,UAAU,EAAE,CAAC;YAClB,oBAAC,IAAI,IAAC,IAAI,EAAC,UAAU;gBAClB,IAAI,IAAI,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC,CAC5B;oBACE,oBAAC,OAAO,IAAC,KAAK,EAAC,QAAQ,GAAG;oBAC1B,oBAAC,IAAI,IAAC,KAAK,EAAC,QAAQ;;wBAAG,cAAc,CAAC,SAAS,CAAC,CAAQ;oBACxD,oBAAC,IAAI,IAAC,QAAQ,qBAAW,CACxB,CACJ,CAAC,CAAC,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,CACpB;oBACE,oBAAC,IAAI,IAAC,QAAQ;;wBAAO,cAAc,CAAC,MAAM,CAAC,CAAQ;oBACnD,oBAAC,IAAI,IAAC,QAAQ,qBAAW,CACxB,CACJ,CAAC,CAAC,CAAC,IAAI;gBACP,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAChB;oBACE,oBAAC,IAAI,IAAC,KAAK,EAAC,SAAS;;wBAAQ,UAAU,CAAQ;oBAC/C,oBAAC,IAAI,IAAC,QAAQ,qBAAW,CACxB,CACJ,CAAC,CAAC,CAAC,IAAI;gBACR,oBAAC,IAAI,IAAC,QAAQ;;oBAAU,SAAS,CAAQ,CACpC,CACD,CACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -11,7 +11,7 @@ import { handleUpdateCheck, handleUpdatePerform } from '../slashHandlers/updater
|
|
|
11
11
|
import { handlePromoteMember } from '../slashHandlers/promoteMember.js';
|
|
12
12
|
import { handleBranchCreate, handleBranchList, handleBranchCheckout, } from '../slashHandlers/branch.js';
|
|
13
13
|
import { handleWorkspaceShow, handleWorkspaceSync, handleWorkspaceReset, } from '../slashHandlers/workspace.js';
|
|
14
|
-
import { handleProviderList, handleProviderSet, handleProviderCustom, handleProviderRefresh, handleProviderStatus, handleLoginKey, handleLoginOAuthGrok, handleModelShow, handleModelSet, handleModelsList, handleModelsRefresh, } from '../slashHandlers/provider.js';
|
|
14
|
+
import { handleProviderList, handleProviderSet, handleProviderPicker, handleProviderCustom, handleProviderRefresh, handleProviderStatus, handleLoginKey, handleLoginOAuthGrok, handleModelShow, handleModelSet, handleModelPicker, handleModelsList, handleModelsRefresh, } from '../slashHandlers/provider.js';
|
|
15
15
|
import { handleSkillStats, handleSkillCompare, handleCouncilFeedback, handleSteer, handleClearChat, } from '../slashHandlers/skills.js';
|
|
16
16
|
export function useSlashDispatch(params) {
|
|
17
17
|
const { skills, sessionId, messages, setMessages, setInput, setBusy, setSessionId, setSessionActive, setProviderConfig, activeProviderSpec, activeModel, providerDefaults, harnessRef, setQueueCount, dispatchPrompt, dispatchCouncilPrompt, mode = 'agent', } = params;
|
|
@@ -101,6 +101,11 @@ export function useSlashDispatch(params) {
|
|
|
101
101
|
setInput('');
|
|
102
102
|
return;
|
|
103
103
|
}
|
|
104
|
+
if (result.kind === 'provider_picker') {
|
|
105
|
+
handleProviderPicker(providerCtx, params.openPicker);
|
|
106
|
+
setInput('');
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
104
109
|
if (result.kind === 'provider_list') {
|
|
105
110
|
handleProviderList(providerCtx);
|
|
106
111
|
setInput('');
|
|
@@ -142,6 +147,11 @@ export function useSlashDispatch(params) {
|
|
|
142
147
|
setInput('');
|
|
143
148
|
return;
|
|
144
149
|
}
|
|
150
|
+
if (result.kind === 'model_picker') {
|
|
151
|
+
await handleModelPicker(providerCtx, params.openPicker);
|
|
152
|
+
setInput('');
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
145
155
|
if (result.kind === 'model_show') {
|
|
146
156
|
handleModelShow(providerCtx);
|
|
147
157
|
setInput('');
|