zelari-code 0.2.2 → 0.6.2

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 (126) hide show
  1. package/README.md +97 -2
  2. package/dist/agents/councilApi.js +7 -7
  3. package/dist/agents/councilApi.js.map +1 -1
  4. package/dist/agents/councilDirectives.js +3 -3
  5. package/dist/agents/promoteMember.js +2 -2
  6. package/dist/agents/roles.js +32 -32
  7. package/dist/agents/roles.js.map +1 -1
  8. package/dist/agents/skills/builtin/debugging.js +4 -4
  9. package/dist/agents/skills/builtin/debugging.js.map +1 -1
  10. package/dist/agents/skills/builtin/docs.js +13 -23
  11. package/dist/agents/skills/builtin/docs.js.map +1 -1
  12. package/dist/agents/skills/builtin/git-ops.js +3 -3
  13. package/dist/agents/skills/builtin/git-ops.js.map +1 -1
  14. package/dist/agents/skills/builtin/planning.js +4 -4
  15. package/dist/agents/skills/builtin/planning.js.map +1 -1
  16. package/dist/agents/skills/builtin/refactoring.js +3 -3
  17. package/dist/agents/skills/builtin/refactoring.js.map +1 -1
  18. package/dist/agents/skills/builtin/review.js +9 -9
  19. package/dist/agents/skills/builtin/review.js.map +1 -1
  20. package/dist/agents/skills/builtin/testing.js +3 -3
  21. package/dist/agents/skills/builtin/testing.js.map +1 -1
  22. package/dist/agents/tools.js +9 -2
  23. package/dist/agents/tools.js.map +1 -1
  24. package/dist/cli/app.js +94 -1861
  25. package/dist/cli/app.js.map +1 -1
  26. package/dist/cli/compaction.js.map +1 -1
  27. package/dist/cli/components/ChatStream.js +81 -14
  28. package/dist/cli/components/ChatStream.js.map +1 -1
  29. package/dist/cli/components/CollapsibleToolOutput.js +26 -3
  30. package/dist/cli/components/CollapsibleToolOutput.js.map +1 -1
  31. package/dist/cli/components/Header.js +20 -1
  32. package/dist/cli/components/Header.js.map +1 -1
  33. package/dist/cli/components/InputBar.js +34 -2
  34. package/dist/cli/components/InputBar.js.map +1 -1
  35. package/dist/cli/components/Sidebar.js +30 -10
  36. package/dist/cli/components/Sidebar.js.map +1 -1
  37. package/dist/cli/councilDispatcher.js +10 -2
  38. package/dist/cli/councilDispatcher.js.map +1 -1
  39. package/dist/cli/headless.js +137 -0
  40. package/dist/cli/headless.js.map +1 -0
  41. package/dist/cli/hooks/chatStats.js +28 -0
  42. package/dist/cli/hooks/chatStats.js.map +1 -0
  43. package/dist/cli/hooks/eventsToMessages.js +111 -0
  44. package/dist/cli/hooks/eventsToMessages.js.map +1 -0
  45. package/dist/cli/hooks/messageHelpers.js +125 -0
  46. package/dist/cli/hooks/messageHelpers.js.map +1 -0
  47. package/dist/cli/hooks/skillCompare.js +69 -0
  48. package/dist/cli/hooks/skillCompare.js.map +1 -0
  49. package/dist/cli/hooks/steer.js +28 -0
  50. package/dist/cli/hooks/steer.js.map +1 -0
  51. package/dist/cli/hooks/useBatchedMessages.js +67 -0
  52. package/dist/cli/hooks/useBatchedMessages.js.map +1 -0
  53. package/dist/cli/hooks/useChatTurn.js +363 -0
  54. package/dist/cli/hooks/useChatTurn.js.map +1 -0
  55. package/dist/cli/hooks/useSession.js +116 -0
  56. package/dist/cli/hooks/useSession.js.map +1 -0
  57. package/dist/cli/hooks/useSlashDispatch.js +303 -0
  58. package/dist/cli/hooks/useSlashDispatch.js.map +1 -0
  59. package/dist/cli/hooks/useTerminalSize.js +60 -0
  60. package/dist/cli/hooks/useTerminalSize.js.map +1 -0
  61. package/dist/cli/main.bundled.js +25212 -21722
  62. package/dist/cli/main.bundled.js.map +4 -4
  63. package/dist/cli/main.js +86 -2
  64. package/dist/cli/main.js.map +1 -1
  65. package/dist/cli/provider/openai-compatible.js +9 -2
  66. package/dist/cli/provider/openai-compatible.js.map +1 -1
  67. package/dist/cli/runHeadless.js +160 -0
  68. package/dist/cli/runHeadless.js.map +1 -0
  69. package/dist/cli/sessionManager.js +47 -1
  70. package/dist/cli/sessionManager.js.map +1 -1
  71. package/dist/cli/skillSuggest.js +1 -1
  72. package/dist/cli/slashCommands.js +72 -3
  73. package/dist/cli/slashCommands.js.map +1 -1
  74. package/dist/cli/slashHandlers/branch.js +57 -0
  75. package/dist/cli/slashHandlers/branch.js.map +1 -0
  76. package/dist/cli/slashHandlers/git.js +40 -0
  77. package/dist/cli/slashHandlers/git.js.map +1 -0
  78. package/dist/cli/slashHandlers/promoteMember.js +25 -0
  79. package/dist/cli/slashHandlers/promoteMember.js.map +1 -0
  80. package/dist/cli/slashHandlers/provider.js +199 -0
  81. package/dist/cli/slashHandlers/provider.js.map +1 -0
  82. package/dist/cli/slashHandlers/skills.js +82 -0
  83. package/dist/cli/slashHandlers/skills.js.map +1 -0
  84. package/dist/cli/slashHandlers/transcript.js +13 -0
  85. package/dist/cli/slashHandlers/transcript.js.map +1 -0
  86. package/dist/cli/slashHandlers/updater.js +40 -0
  87. package/dist/cli/slashHandlers/updater.js.map +1 -0
  88. package/dist/cli/slashHandlers/workspace.js +118 -0
  89. package/dist/cli/slashHandlers/workspace.js.map +1 -0
  90. package/dist/cli/toolRegistry.js +17 -8
  91. package/dist/cli/toolRegistry.js.map +1 -1
  92. package/dist/cli/utils/duration.js +34 -0
  93. package/dist/cli/utils/duration.js.map +1 -0
  94. package/dist/cli/wizard/firstRun.js +63 -0
  95. package/dist/cli/wizard/firstRun.js.map +1 -0
  96. package/dist/cli/wizard/index.js +150 -0
  97. package/dist/cli/wizard/index.js.map +1 -0
  98. package/dist/cli/wizard/runWizard.js +137 -0
  99. package/dist/cli/wizard/runWizard.js.map +1 -0
  100. package/dist/cli/wizard/useWizardState.js +151 -0
  101. package/dist/cli/wizard/useWizardState.js.map +1 -0
  102. package/dist/cli/workspace/agentsMd.js +314 -0
  103. package/dist/cli/workspace/agentsMd.js.map +1 -0
  104. package/dist/cli/workspace/index.js +24 -0
  105. package/dist/cli/workspace/index.js.map +1 -0
  106. package/dist/cli/workspace/paths.js +88 -0
  107. package/dist/cli/workspace/paths.js.map +1 -0
  108. package/dist/cli/workspace/postCouncilHook.js +38 -0
  109. package/dist/cli/workspace/postCouncilHook.js.map +1 -0
  110. package/dist/cli/workspace/storage.js +392 -0
  111. package/dist/cli/workspace/storage.js.map +1 -0
  112. package/dist/cli/workspace/stubs.js +528 -0
  113. package/dist/cli/workspace/stubs.js.map +1 -0
  114. package/dist/cli/workspace/toolRegistry.js +61 -0
  115. package/dist/cli/workspace/toolRegistry.js.map +1 -0
  116. package/dist/cli/workspace/types.js +10 -0
  117. package/dist/cli/workspace/types.js.map +1 -0
  118. package/dist/main/core/tools/builtin/_walk.js +129 -0
  119. package/dist/main/core/tools/builtin/_walk.js.map +1 -0
  120. package/dist/main/core/tools/builtin/diff.js +477 -0
  121. package/dist/main/core/tools/builtin/diff.js.map +1 -0
  122. package/dist/main/core/tools/builtin/listFiles.js +5 -43
  123. package/dist/main/core/tools/builtin/listFiles.js.map +1 -1
  124. package/dist/main/core/tools/builtin/search.js +120 -28
  125. package/dist/main/core/tools/builtin/search.js.map +1 -1
  126. package/package.json +10 -2
@@ -0,0 +1,363 @@
1
+ // @ts-nocheck — pre-existing strict-mode type narrowing issues carried over
2
+ // from app.tsx. Runtime is correct; tighten signatures in a follow-up.
3
+ import { useState, useRef, useCallback } from 'react';
4
+ import { AgentHarness } from '@zelari/core/harness';
5
+ import { getMetricsLogger } from '../metrics.js';
6
+ import { openaiCompatibleProvider, providerFromEnv, providerConfigFor } from '../provider/openai-compatible.js';
7
+ import { providerFailover } from '../providerFailover.js';
8
+ import { resolveFailoverStream } from '../crossProviderFailover.js';
9
+ import { PROVIDERS } from '../keyStore.js';
10
+ import { createBuiltinToolRegistry } from '../toolRegistry.js';
11
+ import { appendOrExtendStreamingAssistant, appendSystem, appendToolStart, finalizeStreamingAssistant, updateToolMessageEnd, } from './messageHelpers.js';
12
+ import { computeSessionStatsDelta } from './chatStats.js';
13
+ export function useChatTurn(params) {
14
+ const { sessionId, writerRef, setMessages, commitStreaming, flushStreaming, setBusy, setSessionActive, setSessionStats } = params;
15
+ const harnessRef = useRef(null);
16
+ const [queueCount, setQueueCount] = useState(0);
17
+ const dispatchPrompt = useCallback(async (userText) => {
18
+ // v0.4.3 audit fix: provider resolution + harness construction now
19
+ // live INSIDE the try block. Previously, throws from providerFromEnv,
20
+ // resolveFailoverStream, or createBuiltinToolRegistry happened
21
+ // BEFORE the try (which only wrapped the stream loop), so the
22
+ // rejected promise escaped unhandled (useSlashDispatch doesn't
23
+ // try/catch its await either). The user saw a hang with no
24
+ // feedback instead of an actionable error message.
25
+ let envConfig;
26
+ let harness;
27
+ try {
28
+ envConfig = await providerFromEnv();
29
+ if (!envConfig) {
30
+ appendSystem(setMessages, 'OPENAI_API_KEY not set. Export it before running zelari-code.');
31
+ return;
32
+ }
33
+ setBusy(true);
34
+ const { registry: toolRegistry } = createBuiltinToolRegistry();
35
+ const baseProviderStream = openaiCompatibleProvider(envConfig);
36
+ const failoverResolution = await resolveFailoverStream({
37
+ failoverEnabled: process.env.ANATHEMA_FAILOVER !== '0',
38
+ envValue: process.env.ANATHEMA_FAILOVER_PROVIDER,
39
+ primaryProviderId: envConfig.providerId,
40
+ primary: baseProviderStream,
41
+ validProviderIds: PROVIDERS.map((p) => p.id),
42
+ lookupFallbackConfig: async (id) => providerConfigFor(id),
43
+ buildStream: (config) => openaiCompatibleProvider(config),
44
+ });
45
+ if (failoverResolution.warning) {
46
+ // Surface in the chat instead of console.warn: writes that bypass
47
+ // Ink force a full repaint of the TUI frame (visible flicker).
48
+ appendSystem(setMessages, `[failover] ${failoverResolution.warning}`);
49
+ }
50
+ const providerStream = failoverResolution.fallbackLabel
51
+ ? providerFailover({
52
+ primary: baseProviderStream,
53
+ fallback: failoverResolution.fallback,
54
+ fallbackLabel: failoverResolution.fallbackLabel,
55
+ })
56
+ : providerFailover({
57
+ primary: baseProviderStream,
58
+ fallback: failoverResolution.fallback,
59
+ });
60
+ const cwd = process.cwd();
61
+ const toolList = toolRegistry.toOpenAITools().map((t) => `- ${t.function.name}: ${t.function.description}`).join('\n');
62
+ const systemPrompt = [
63
+ "You are Zelari Code, an interactive AI coding agent operating directly in the user's terminal.",
64
+ '',
65
+ 'You ARE connected to this machine and have real tools to read, modify, and explore the codebase.',
66
+ "Never claim you lack filesystem or shell access — you have it. Use your tools instead of asking the user to paste file contents.",
67
+ '',
68
+ '# Working Directory',
69
+ `You are running in: ${cwd}`,
70
+ 'All relative file paths are resolved against this directory. Always work with real files here.',
71
+ '',
72
+ '# Available Tools',
73
+ 'You can call these tools. Use them to take action and gather information autonomously:',
74
+ toolList,
75
+ '',
76
+ '# Guidelines',
77
+ '- When the user asks you to write code, debug, or explore, be proactive: list files (bash: ls, list_files) and read key files (read_file) to understand the project instead of asking the user to paste file contents.',
78
+ "- Only invoke tools when they are necessary to answer the user's prompt. If the user is just saying hello or greeting them (e.g., \"ciao\", \"hello\"), simply greet them back and ask how you can help, without running any commands or tools.",
79
+ '- When you finish a task, briefly summarize what you did.',
80
+ ].join('\n');
81
+ const harness = new AgentHarness({
82
+ model: envConfig.model,
83
+ provider: 'openai-compatible',
84
+ messages: [
85
+ { role: 'system', content: systemPrompt },
86
+ { role: 'user', content: userText },
87
+ ],
88
+ tools: toolRegistry.toOpenAITools().map((t) => ({
89
+ name: t.function.name,
90
+ description: t.function.description,
91
+ parameters: t.function.parameters,
92
+ })),
93
+ toolRegistry,
94
+ providerStream,
95
+ cwd,
96
+ });
97
+ harnessRef.current = harness;
98
+ setQueueCount(harness.queueLength);
99
+ // Total assistant output across the whole turn — feeds the token/cost
100
+ // estimate fallback in computeSessionStatsDelta.
101
+ let assistantContent = '';
102
+ // Display buffer for the CURRENT streamed message only. Reset on every
103
+ // message_end: without this, the post-tool-call message re-rendered the
104
+ // full accumulated turn text, duplicating everything said before the
105
+ // tool ran.
106
+ let streamContent = '';
107
+ // tool_execution_end doesn't carry toolName — remember it from the
108
+ // matching start event (keyed by toolCallId) for metrics.
109
+ const toolNameById = new Map();
110
+ const metrics = getMetricsLogger();
111
+ let realUsage = null;
112
+ try {
113
+ for await (const event of harness.run()) {
114
+ if (event.type === 'message_end') {
115
+ if (event.usage)
116
+ realUsage = event.usage;
117
+ // Message boundary: drain buffered deltas, then seal the streamed
118
+ // bubble so the next message starts fresh instead of merging.
119
+ flushStreaming();
120
+ finalizeStreamingAssistant(setMessages);
121
+ streamContent = '';
122
+ }
123
+ if (event.type === 'queue_update') {
124
+ setQueueCount(harness.queueLength);
125
+ }
126
+ if (writerRef.current) {
127
+ await writerRef.current.append(event);
128
+ }
129
+ if (event.type === 'agent_end') {
130
+ metrics.record({
131
+ kind: 'run',
132
+ sessionId,
133
+ provider: envConfig.providerId,
134
+ model: envConfig.model,
135
+ latencyMs: event.durationMs,
136
+ ok: event.reason === 'stop',
137
+ });
138
+ }
139
+ else if (event.type === 'error') {
140
+ metrics.record({
141
+ kind: 'error',
142
+ sessionId,
143
+ provider: envConfig.providerId,
144
+ model: envConfig.model,
145
+ error: event.message,
146
+ });
147
+ }
148
+ else if (event.type === 'tool_execution_end') {
149
+ metrics.record({
150
+ kind: 'tool',
151
+ sessionId,
152
+ provider: envConfig.providerId,
153
+ model: envConfig.model,
154
+ toolName: toolNameById.get(event.toolCallId) ?? 'unknown',
155
+ toolCallId: event.toolCallId,
156
+ durationMs: event.durationMs,
157
+ ok: !event.isError,
158
+ });
159
+ }
160
+ if (event.type === 'message_delta') {
161
+ assistantContent += event.delta;
162
+ streamContent += event.delta;
163
+ // Route through the throttled setter so per-token deltas (50-200/sec)
164
+ // coalesce into ≤60 renders/sec instead of flickering the TUI.
165
+ // v0.5.0: forward the council member identity when present so
166
+ // the UI can render `🜂 Caronte: …` headers.
167
+ appendOrExtendStreamingAssistant(commitStreaming, streamContent, Date.now(), {
168
+ ...(event.memberId ? { memberId: event.memberId } : {}),
169
+ ...(event.memberName ? { memberName: event.memberName } : {}),
170
+ });
171
+ }
172
+ else if (event.type === 'error') {
173
+ flushStreaming();
174
+ appendSystem(setMessages, `[error] ${event.message}`, Date.now());
175
+ }
176
+ else if (event.type === 'tool_execution_start') {
177
+ toolNameById.set(event.toolCallId, event.toolName);
178
+ // Drain buffered deltas FIRST so the text streamed before the
179
+ // call renders above the tool line, not below it — then seal
180
+ // that bubble: it's complete once the model starts calling tools.
181
+ flushStreaming();
182
+ finalizeStreamingAssistant(setMessages);
183
+ appendToolStart(setMessages, event.toolName, event.toolCallId, event.args, event.ts);
184
+ }
185
+ else if (event.type === 'tool_execution_end') {
186
+ updateToolMessageEnd(setMessages, event.toolCallId, event.isError, event.durationMs, event.result);
187
+ }
188
+ }
189
+ }
190
+ finally {
191
+ // Drain any buffered streaming deltas so the final assistant message
192
+ // is committed before busy flips to false (and the input re-enables).
193
+ flushStreaming();
194
+ finalizeStreamingAssistant(setMessages);
195
+ harnessRef.current = null;
196
+ setQueueCount(0);
197
+ setBusy(false);
198
+ setSessionStats((prev) => computeSessionStatsDelta(realUsage, userText, assistantContent, envConfig.model, prev));
199
+ }
200
+ }
201
+ catch (err) {
202
+ // v0.4.3 audit fix: catches throws from providerFromEnv /
203
+ // resolveFailoverStream / AgentHarness construction that were
204
+ // previously escaping the function unhandled. Surfaces the error
205
+ // to the chat instead of hanging silently.
206
+ // Flush first so any partial assistant content streamed before the
207
+ // throw is committed before the error message renders.
208
+ flushStreaming();
209
+ appendSystem(setMessages, `[dispatch error] ${err instanceof Error ? err.message : String(err)}`);
210
+ setBusy(false);
211
+ }
212
+ }, [sessionId, writerRef, setMessages, commitStreaming, flushStreaming, setBusy, setSessionActive, setSessionStats]);
213
+ const dispatchCouncilPrompt = useCallback(async (text) => {
214
+ await dispatchCouncilPromptImpl(text, {
215
+ sessionId,
216
+ writerRef,
217
+ setMessages,
218
+ commitStreaming,
219
+ flushStreaming,
220
+ setBusy,
221
+ setQueueCount,
222
+ });
223
+ }, [sessionId, writerRef, setMessages, commitStreaming, flushStreaming, setBusy, setQueueCount]);
224
+ return { dispatchPrompt, dispatchCouncilPrompt, harnessRef, queueCount, setQueueCount };
225
+ }
226
+ /**
227
+ * dispatchCouncilPrompt — multi-agent council dispatch.
228
+ *
229
+ * Surfaces tool_execution_start/end as 'tool' role messages so ChatStream
230
+ * renders CollapsibleToolOutput. Runs AGENTS.MD auto-maintenance after the
231
+ * council finishes (controlled by ZELARI_AGENTS_MD env var).
232
+ *
233
+ * Implementation lives outside the hook closure so it doesn't depend on the
234
+ * hook's identity for memoization. Callers receive a stable callback via the
235
+ * useChatTurn wrapper.
236
+ */
237
+ async function dispatchCouncilPromptImpl(text, deps) {
238
+ const { sessionId, writerRef, setMessages, commitStreaming, flushStreaming, setBusy } = deps;
239
+ const envConfig = await providerFromEnv();
240
+ if (!envConfig) {
241
+ appendSystem(setMessages, 'OPENAI_API_KEY not set. Export it before invoking /council.');
242
+ return;
243
+ }
244
+ setBusy(true);
245
+ // Import dynamically to avoid a circular dep at module-load time.
246
+ const { dispatchCouncil } = await import('../councilDispatcher.js');
247
+ const { createWorkspaceContext, createWorkspaceStubs } = await import('../workspace/stubs.js');
248
+ const { createWorkspaceToolRegistry } = await import('../workspace/toolRegistry.js');
249
+ const { setWorkspaceStubs } = await import('@zelari/core/skills');
250
+ const { runPostCouncilHook } = await import('../workspace/postCouncilHook.js');
251
+ const { FeedbackStore } = await import('../councilFeedback.js');
252
+ const { registry: councilToolRegistry } = createBuiltinToolRegistry();
253
+ const workspaceCtx = createWorkspaceContext();
254
+ const workspaceReg = createWorkspaceToolRegistry(workspaceCtx);
255
+ for (const name of workspaceReg.list()) {
256
+ const td = workspaceReg.get(name);
257
+ if (td)
258
+ councilToolRegistry.register(td);
259
+ }
260
+ setWorkspaceStubs(createWorkspaceStubs(workspaceCtx));
261
+ const councilFeedbackStore = new FeedbackStore();
262
+ try {
263
+ for await (const event of dispatchCouncil(text, {
264
+ apiKey: envConfig.apiKey,
265
+ model: envConfig.model,
266
+ provider: 'openai-compatible',
267
+ providerStream: openaiCompatibleProvider(envConfig),
268
+ sessionId,
269
+ tools: councilToolRegistry,
270
+ feedbackStore: councilFeedbackStore,
271
+ })) {
272
+ if (writerRef.current) {
273
+ await writerRef.current.append(event);
274
+ }
275
+ if (event.type === 'message_delta') {
276
+ // Coalesce streaming assistant content through the throttled setter so
277
+ // per-token deltas don't flicker the TUI (same as dispatchPrompt).
278
+ // v0.5.0: forward the council member identity when present so
279
+ // the UI can render `🜂 Caronte: …` headers above the streamed
280
+ // text. Extend the trailing streaming bubble only when it belongs
281
+ // to the SAME member — otherwise one specialist's text would be
282
+ // appended to (and attributed to) the previous one.
283
+ commitStreaming((prev) => {
284
+ const last = prev[prev.length - 1];
285
+ if (last &&
286
+ last.role === 'assistant' &&
287
+ last.id.startsWith('streaming-') &&
288
+ (last.memberId ?? null) === (event.memberId ?? null)) {
289
+ return [...prev.slice(0, -1), { ...last, content: last.content + event.delta }];
290
+ }
291
+ return [
292
+ ...prev,
293
+ {
294
+ id: `streaming-${crypto.randomUUID()}`,
295
+ role: 'assistant',
296
+ content: event.delta,
297
+ ts: event.ts,
298
+ ...(event.memberId ? { memberId: event.memberId } : {}),
299
+ ...(event.memberName ? { memberName: event.memberName } : {}),
300
+ },
301
+ ];
302
+ });
303
+ }
304
+ else if (event.type === 'message_end') {
305
+ // Member/turn boundary: drain buffered deltas and seal the bubble so
306
+ // the next streamed message starts fresh.
307
+ flushStreaming();
308
+ finalizeStreamingAssistant(setMessages);
309
+ }
310
+ else if (event.type === 'tool_execution_start') {
311
+ // Single 'tool' role message per invocation (CollapsibleToolOutput);
312
+ // the previous extra `▶ name(args)` system line duplicated it.
313
+ // Drain buffered deltas first so ordering matches reality, and seal
314
+ // the pre-tool bubble (complete once the member starts calling tools).
315
+ flushStreaming();
316
+ finalizeStreamingAssistant(setMessages);
317
+ appendToolStart(setMessages, event.toolName, event.toolCallId, event.args, event.ts);
318
+ }
319
+ else if (event.type === 'tool_execution_end') {
320
+ updateToolMessageEnd(setMessages, event.toolCallId, event.isError, event.durationMs, event.result);
321
+ }
322
+ else if (event.type === 'error') {
323
+ flushStreaming();
324
+ appendSystem(setMessages, `[error] ${event.message}`, event.ts);
325
+ }
326
+ }
327
+ }
328
+ catch (err) {
329
+ // Flush any partial streamed content before the error message renders.
330
+ flushStreaming();
331
+ appendSystem(setMessages, `[council error] ${err instanceof Error ? err.message : String(err)}`, Date.now());
332
+ }
333
+ finally {
334
+ // Drain any buffered streaming deltas before status messages / busy flip,
335
+ // so the final council output is committed to the chat.
336
+ flushStreaming();
337
+ finalizeStreamingAssistant(setMessages);
338
+ try {
339
+ const hook = await runPostCouncilHook(workspaceCtx);
340
+ if (hook.ran && hook.changed) {
341
+ appendSystem(setMessages, `[agents.md] updated: ${hook.sections.length} section(s) changed (${hook.sections.join(', ')})`, Date.now());
342
+ }
343
+ else if (hook.ran && hook.reason) {
344
+ if (!hook.reason.includes('disabled')) {
345
+ appendSystem(setMessages, `[agents.md] ${hook.reason}`, Date.now());
346
+ }
347
+ }
348
+ }
349
+ catch {
350
+ // Best-effort — never block on AGENTS.MD errors.
351
+ }
352
+ setBusy(false);
353
+ }
354
+ }
355
+ /**
356
+ * Public wrapper that captures the dispatchCouncilPromptImpl dependencies
357
+ * from the useChatTurn closure. Returns a stable callback the App can wire
358
+ * into the InputBar onSubmit.
359
+ */
360
+ export function makeCouncilDispatch(deps) {
361
+ return (text) => dispatchCouncilPromptImpl(text, deps);
362
+ }
363
+ //# sourceMappingURL=useChatTurn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useChatTurn.js","sourceRoot":"","sources":["../../../src/cli/hooks/useChatTurn.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,116 @@
1
+ // @ts-nocheck — pre-existing strict-mode type narrowing issues carried over
2
+ // from app.tsx. Runtime is correct; tighten signatures in a follow-up.
3
+ import { useState, useRef, useCallback, useEffect } from 'react';
4
+ import { getCurrentSessionId, setCurrentSessionId, clearCurrentSessionId, newSessionId, ensureSessionDir, listSessions, loadSessionEvents, } from '../sessionManager.js';
5
+ import { SessionJsonlWriter } from '@zelari/core/harness';
6
+ import { eventsToMessages } from './eventsToMessages.js';
7
+ import { useBatchedMessages } from './useBatchedMessages.js';
8
+ export function useSession() {
9
+ const [sessionId, setSessionId] = useState('');
10
+ const [messages, setMessages] = useState([]);
11
+ const [sessionActive, setSessionActive] = useState(false);
12
+ const writerRef = useRef(null);
13
+ // Throttle layer over `messages`/`setMessages`. `commitStreaming` coalesces
14
+ // the per-token streaming deltas (the LLM emits ~50-200/sec) into at most
15
+ // one render per ~16ms, which lets `React.memo(ChatStream)` finally take
16
+ // effect. `setMessages` is the passthrough — non-streaming calls (bootstrap
17
+ // restore, /new reset, system/error messages) apply instantly.
18
+ const { commit: commitStreaming, flush: flushStreaming } = useBatchedMessages(messages, setMessages);
19
+ // Bootstrap on mount: resume current session or create new one.
20
+ useEffect(() => {
21
+ let cancelled = false;
22
+ (async () => {
23
+ await ensureSessionDir();
24
+ let id = getCurrentSessionId();
25
+ let restoredMessages = [];
26
+ if (id) {
27
+ try {
28
+ const events = await loadSessionEvents(id);
29
+ if (!cancelled) {
30
+ restoredMessages = eventsToMessages(events);
31
+ }
32
+ }
33
+ catch {
34
+ // Corrupt session — fall through to create new.
35
+ id = null;
36
+ }
37
+ }
38
+ if (!id) {
39
+ id = newSessionId();
40
+ setCurrentSessionId(id);
41
+ }
42
+ if (cancelled)
43
+ return;
44
+ writerRef.current = new SessionJsonlWriter(id);
45
+ setSessionId(id);
46
+ setMessages(restoredMessages);
47
+ if (restoredMessages.length > 0) {
48
+ setMessages((prev) => [
49
+ ...prev,
50
+ {
51
+ id: crypto.randomUUID(),
52
+ role: 'system',
53
+ content: `[resume] loaded ${restoredMessages.length} messages from session ${id.slice(0, 8)}…`,
54
+ ts: Date.now(),
55
+ },
56
+ ]);
57
+ setSessionActive(true);
58
+ }
59
+ })();
60
+ return () => {
61
+ cancelled = true;
62
+ // Fire-and-forget close on unmount.
63
+ void writerRef.current?.close();
64
+ };
65
+ }, []);
66
+ /**
67
+ * Dispatch /sessions, /resume <id>, /new commands.
68
+ * Returns the system message to surface in chat.
69
+ */
70
+ const handleSessionKind = useCallback(async (kind, targetSessionId) => {
71
+ if (kind === 'session') {
72
+ try {
73
+ const sessions = await listSessions();
74
+ if (sessions.length === 0)
75
+ return '[sessions] no past sessions';
76
+ const lines = sessions.slice(0, 10).map((s) => {
77
+ const dt = new Date(s.mtimeMs).toISOString().replace('T', ' ').slice(0, 16);
78
+ return ` ${s.id.slice(0, 8)}… ${s.eventCount} events ${dt}`;
79
+ });
80
+ return `[sessions] showing ${Math.min(sessions.length, 10)} of ${sessions.length}:\n${lines.join('\n')}`;
81
+ }
82
+ catch (err) {
83
+ return `[sessions] error: ${err instanceof Error ? err.message : String(err)}`;
84
+ }
85
+ }
86
+ if (kind === 'resume' && targetSessionId) {
87
+ setCurrentSessionId(targetSessionId);
88
+ return `[resume] session ${targetSessionId.slice(0, 8)}… set as current — restart zelari-code to load it`;
89
+ }
90
+ if (kind === 'new') {
91
+ clearCurrentSessionId();
92
+ const id = newSessionId();
93
+ setCurrentSessionId(id);
94
+ writerRef.current?.close();
95
+ writerRef.current = new SessionJsonlWriter(id);
96
+ setSessionId(id);
97
+ setMessages([]);
98
+ setSessionActive(false);
99
+ return `[new] fresh session ${id.slice(0, 8)}… started`;
100
+ }
101
+ return `[${kind}] handled`;
102
+ }, []);
103
+ return {
104
+ sessionId,
105
+ setSessionId,
106
+ messages,
107
+ setMessages,
108
+ commitStreaming,
109
+ flushStreaming,
110
+ sessionActive,
111
+ setSessionActive,
112
+ writerRef,
113
+ handleSessionKind,
114
+ };
115
+ }
116
+ //# sourceMappingURL=useSession.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSession.js","sourceRoot":"","sources":["../../../src/cli/hooks/useSession.ts"],"names":[],"mappings":"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"}