cvc-tui 0.4.0 → 0.4.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 (133) hide show
  1. package/dist/entry.js +71148 -61
  2. package/package.json +2 -2
  3. package/dist/app/completion.js +0 -102
  4. package/dist/app/createGatewayEventHandler.js +0 -508
  5. package/dist/app/createSlashHandler.js +0 -101
  6. package/dist/app/delegationStore.js +0 -51
  7. package/dist/app/gatewayContext.js +0 -17
  8. package/dist/app/historyStore.js +0 -123
  9. package/dist/app/inputBuffer.js +0 -120
  10. package/dist/app/inputSelectionStore.js +0 -8
  11. package/dist/app/inputStore.js +0 -28
  12. package/dist/app/interfaces.js +0 -6
  13. package/dist/app/overlayStore.js +0 -40
  14. package/dist/app/promptStore.js +0 -44
  15. package/dist/app/queueStore.js +0 -25
  16. package/dist/app/scroll.js +0 -44
  17. package/dist/app/setupHandoff.js +0 -28
  18. package/dist/app/slash/commands/core.js +0 -479
  19. package/dist/app/slash/commands/debug.js +0 -44
  20. package/dist/app/slash/commands/ops.js +0 -498
  21. package/dist/app/slash/commands/session.js +0 -431
  22. package/dist/app/slash/commands/setup.js +0 -20
  23. package/dist/app/slash/commands/toggles.js +0 -40
  24. package/dist/app/slash/registry.js +0 -18
  25. package/dist/app/slash/types.js +0 -1
  26. package/dist/app/spawnHistoryStore.js +0 -105
  27. package/dist/app/turnController.js +0 -650
  28. package/dist/app/turnStore.js +0 -48
  29. package/dist/app/uiStore.js +0 -36
  30. package/dist/app/useComposerState.js +0 -265
  31. package/dist/app/useConfigSync.js +0 -144
  32. package/dist/app/useInputHandlers.js +0 -403
  33. package/dist/app/useLongRunToolCharms.js +0 -50
  34. package/dist/app/useMainApp.js +0 -629
  35. package/dist/app/useSessionLifecycle.js +0 -175
  36. package/dist/app/useSubmission.js +0 -287
  37. package/dist/app.js +0 -15
  38. package/dist/banner.js +0 -57
  39. package/dist/components/agentsOverlay.js +0 -474
  40. package/dist/components/appChrome.js +0 -252
  41. package/dist/components/appLayout.js +0 -121
  42. package/dist/components/appOverlays.js +0 -65
  43. package/dist/components/branding.js +0 -97
  44. package/dist/components/fpsOverlay.js +0 -22
  45. package/dist/components/helpHint.js +0 -21
  46. package/dist/components/markdown.js +0 -501
  47. package/dist/components/maskedPrompt.js +0 -12
  48. package/dist/components/messageLine.js +0 -82
  49. package/dist/components/modelPicker.js +0 -254
  50. package/dist/components/overlayControls.js +0 -30
  51. package/dist/components/overlays/confirmPrompt.js +0 -25
  52. package/dist/components/overlays/helpOverlay.js +0 -76
  53. package/dist/components/overlays/historySearch.js +0 -49
  54. package/dist/components/overlays/modelPicker.js +0 -60
  55. package/dist/components/overlays/overlayUtils.js +0 -19
  56. package/dist/components/overlays/secretPrompt.js +0 -36
  57. package/dist/components/overlays/sessionPicker.js +0 -93
  58. package/dist/components/overlays/skillsHub.js +0 -71
  59. package/dist/components/prompts.js +0 -95
  60. package/dist/components/queuedMessages.js +0 -24
  61. package/dist/components/sessionPicker.js +0 -130
  62. package/dist/components/skillsHub.js +0 -165
  63. package/dist/components/streamingAssistant.js +0 -35
  64. package/dist/components/streamingMarkdown.js +0 -144
  65. package/dist/components/textInput.js +0 -794
  66. package/dist/components/themed.js +0 -12
  67. package/dist/components/thinking.js +0 -496
  68. package/dist/components/todoPanel.js +0 -40
  69. package/dist/components/transcript.js +0 -22
  70. package/dist/config/env.js +0 -18
  71. package/dist/config/limits.js +0 -22
  72. package/dist/config/timing.js +0 -18
  73. package/dist/content/charms.js +0 -5
  74. package/dist/content/faces.js +0 -21
  75. package/dist/content/fortunes.js +0 -29
  76. package/dist/content/hotkeys.js +0 -38
  77. package/dist/content/placeholders.js +0 -15
  78. package/dist/content/setup.js +0 -14
  79. package/dist/content/verbs.js +0 -41
  80. package/dist/domain/details.js +0 -53
  81. package/dist/domain/messages.js +0 -63
  82. package/dist/domain/paths.js +0 -16
  83. package/dist/domain/providers.js +0 -11
  84. package/dist/domain/roles.js +0 -6
  85. package/dist/domain/slash.js +0 -11
  86. package/dist/domain/usage.js +0 -1
  87. package/dist/domain/viewport.js +0 -33
  88. package/dist/gateway/client.js +0 -312
  89. package/dist/gatewayClient.js +0 -574
  90. package/dist/gatewayTypes.js +0 -1
  91. package/dist/hooks/useCompletion.js +0 -86
  92. package/dist/hooks/useGitBranch.js +0 -58
  93. package/dist/hooks/useInputHistory.js +0 -12
  94. package/dist/hooks/useQueue.js +0 -57
  95. package/dist/hooks/useVirtualHistory.js +0 -401
  96. package/dist/lib/circularBuffer.js +0 -43
  97. package/dist/lib/clipboard.js +0 -126
  98. package/dist/lib/editor.js +0 -41
  99. package/dist/lib/editor.test.js +0 -58
  100. package/dist/lib/emoji.js +0 -49
  101. package/dist/lib/externalCli.js +0 -11
  102. package/dist/lib/forceTruecolor.js +0 -26
  103. package/dist/lib/fpsStore.js +0 -36
  104. package/dist/lib/gracefulExit.js +0 -29
  105. package/dist/lib/history.js +0 -69
  106. package/dist/lib/inputMetrics.js +0 -143
  107. package/dist/lib/liveProgress.js +0 -51
  108. package/dist/lib/liveProgress.test.js +0 -89
  109. package/dist/lib/mathUnicode.js +0 -685
  110. package/dist/lib/memory.js +0 -123
  111. package/dist/lib/memoryMonitor.js +0 -76
  112. package/dist/lib/messages.js +0 -3
  113. package/dist/lib/messages.test.js +0 -25
  114. package/dist/lib/osc52.js +0 -53
  115. package/dist/lib/perfPane.js +0 -94
  116. package/dist/lib/platform.js +0 -312
  117. package/dist/lib/precisionWheel.js +0 -25
  118. package/dist/lib/reasoning.js +0 -39
  119. package/dist/lib/rpc.js +0 -26
  120. package/dist/lib/subagentTree.js +0 -287
  121. package/dist/lib/syntax.js +0 -89
  122. package/dist/lib/terminalModes.js +0 -46
  123. package/dist/lib/terminalParity.js +0 -48
  124. package/dist/lib/terminalSetup.js +0 -321
  125. package/dist/lib/text.js +0 -203
  126. package/dist/lib/text.test.js +0 -18
  127. package/dist/lib/todo.js +0 -2
  128. package/dist/lib/todo.test.js +0 -22
  129. package/dist/lib/viewportStore.js +0 -82
  130. package/dist/lib/virtualHeights.js +0 -61
  131. package/dist/lib/wheelAccel.js +0 -143
  132. package/dist/theme.js +0 -398
  133. package/dist/types.js +0 -1
@@ -1,312 +0,0 @@
1
- // Real subprocess GatewayClient.
2
- //
3
- // Spawns `python -m cvc.tui_gateway.entry` (or attaches to a configured
4
- // `cvc-tui-gateway` binary), speaks newline-delimited JSON-RPC 2.0 over
5
- // stdio, and surfaces:
6
- // * request/response RPCs — `send(method, params)` → Promise<result>
7
- // * server-push events — `on('event', ev => …)` (e.g. chat.delta,
8
- // chat.done, chat.start)
9
- // * stderr lines — `on('stderr', line => …)`
10
- // * lifecycle — `on('exit', code => …)`,
11
- // `on('connected', info => …)`
12
- //
13
- // The protocol contract matches the Python gateway in cvc/tui_gateway/:
14
- // request : {jsonrpc:'2.0', id, method, params}
15
- // response: {jsonrpc:'2.0', id, result|error}
16
- // event : {jsonrpc:'2.0', method, params} (no id)
17
- //
18
- // During `connect()` we issue a `session.info` handshake; the resolved
19
- // session payload (version, model, provider, session_id, cwd) is emitted
20
- // as `connected` and also returned from connect().
21
- //
22
- // Tests inject a fake transport via the `transport` constructor option.
23
- // In production the transport is a child_process spawned with
24
- // `stdio: ['pipe','pipe','pipe']`.
25
- import { spawn } from 'node:child_process';
26
- import { EventEmitter } from 'node:events';
27
- import { existsSync } from 'node:fs';
28
- import { delimiter, resolve } from 'node:path';
29
- import { createInterface } from 'node:readline';
30
- const DEFAULT_TIMEOUT_MS = Math.max(10000, parseInt(process.env.CVC_TUI_RPC_TIMEOUT_MS ?? '120000', 10) || 120000);
31
- const STARTUP_TIMEOUT_MS = Math.max(3000, parseInt(process.env.CVC_TUI_STARTUP_TIMEOUT_MS ?? '15000', 10) || 15000);
32
- const resolvePython = (root) => {
33
- const configured = process.env.CVC_PYTHON?.trim() || process.env.PYTHON?.trim();
34
- if (configured)
35
- return configured;
36
- const venv = process.env.VIRTUAL_ENV?.trim();
37
- const candidates = [
38
- venv && resolve(venv, 'bin/python'),
39
- venv && resolve(venv, 'bin/python3'),
40
- venv && resolve(venv, 'Scripts/python.exe'),
41
- resolve(root, '.venv/bin/python'),
42
- resolve(root, '.venv/bin/python3'),
43
- resolve(root, 'venv/bin/python'),
44
- resolve(root, 'venv/bin/python3'),
45
- ];
46
- for (const c of candidates) {
47
- if (c && existsSync(c))
48
- return c;
49
- }
50
- return process.platform === 'win32' ? 'python' : 'python3';
51
- };
52
- const findCvcRoot = () => {
53
- // entry.tsx is typically at <root>/cvc-tui/src/entry.tsx
54
- // dist/entry.js at <root>/cvc-tui/dist/entry.js
55
- // Walk up looking for a "cvc/tui_gateway" sibling.
56
- if (process.env.CVC_PYTHON_SRC_ROOT)
57
- return process.env.CVC_PYTHON_SRC_ROOT;
58
- let dir = process.cwd();
59
- for (let i = 0; i < 6; i++) {
60
- if (existsSync(resolve(dir, 'cvc', 'tui_gateway', 'entry.py')))
61
- return dir;
62
- const parent = resolve(dir, '..');
63
- if (parent === dir)
64
- break;
65
- dir = parent;
66
- }
67
- return process.cwd();
68
- };
69
- export class GatewayClient extends EventEmitter {
70
- opts;
71
- proc = null;
72
- transport = null;
73
- stdoutRl = null;
74
- stderrRl = null;
75
- pending = new Map();
76
- reqId = 0;
77
- session = null;
78
- connected = false;
79
- exited = false;
80
- constructor(opts = {}) {
81
- super();
82
- this.setMaxListeners(0);
83
- this.opts = opts;
84
- }
85
- /** Spawn (or attach) the gateway and run the session.info handshake. */
86
- async connect() {
87
- if (this.connected) {
88
- return this.session;
89
- }
90
- if (this.opts.transport) {
91
- this.transport = this.opts.transport;
92
- this.wireTransport();
93
- }
94
- else {
95
- this.spawnGateway();
96
- }
97
- // Handshake — single session.info round-trip with bounded timeout.
98
- const info = (await this.send('session.info', {}, { timeoutMs: STARTUP_TIMEOUT_MS }));
99
- this.session = info;
100
- this.connected = true;
101
- this.emit('connected', info);
102
- return info;
103
- }
104
- spawnGateway() {
105
- const root = this.opts.cwd ?? findCvcRoot();
106
- const python = this.opts.python ?? resolvePython(root);
107
- const env = { ...process.env };
108
- const pyPath = env.PYTHONPATH?.trim();
109
- env.PYTHONPATH = pyPath ? `${root}${delimiter}${pyPath}` : root;
110
- const proc = spawn(python, ['-m', 'cvc.tui_gateway.entry'], {
111
- cwd: root,
112
- env,
113
- stdio: ['pipe', 'pipe', 'pipe'],
114
- });
115
- this.proc = proc;
116
- this.transport = {
117
- stdin: proc.stdin,
118
- stdout: proc.stdout,
119
- stderr: proc.stderr,
120
- kill: () => proc.kill(),
121
- on: (event, cb) => {
122
- proc.on(event, cb);
123
- },
124
- };
125
- proc.on('error', (err) => {
126
- this.emit('stderr', `[spawn] ${err.message}`);
127
- this.handleExit(1);
128
- });
129
- proc.on('exit', (code) => this.handleExit(code));
130
- this.wireTransport();
131
- }
132
- wireTransport() {
133
- const t = this.transport;
134
- this.stdoutRl = createInterface({ input: t.stdout });
135
- this.stdoutRl.on('line', (line) => this.handleLine(line));
136
- if (t.stderr) {
137
- this.stderrRl = createInterface({ input: t.stderr });
138
- this.stderrRl.on('line', (line) => {
139
- const trimmed = line.trim();
140
- if (!trimmed)
141
- return;
142
- this.emit('stderr', trimmed);
143
- if (this.opts.forwardStderr) {
144
- process.stderr.write(`[cvc-gateway] ${trimmed}\n`);
145
- }
146
- });
147
- }
148
- // Lifecycle: injected transports surface exit through their own `on()`.
149
- // The real subprocess path also calls handleExit via proc.on('exit')
150
- // registered in spawnGateway, so guard with `exited` to dedupe.
151
- t.on?.('exit', (code) => this.handleExit(code));
152
- }
153
- handleLine(raw) {
154
- const line = raw.trim();
155
- if (!line)
156
- return;
157
- let frame;
158
- try {
159
- frame = JSON.parse(line);
160
- }
161
- catch {
162
- this.emit('stderr', `[protocol] malformed stdout: ${line.slice(0, 200)}`);
163
- return;
164
- }
165
- this.dispatch(frame);
166
- }
167
- dispatch(frame) {
168
- // Response — has `id` and (`result` xor `error`).
169
- if ('id' in frame && (('result' in frame) || ('error' in frame))) {
170
- const id = String(frame.id);
171
- const p = this.pending.get(id);
172
- if (!p)
173
- return;
174
- this.pending.delete(id);
175
- clearTimeout(p.timer);
176
- if ('error' in frame && frame.error) {
177
- const err = frame.error;
178
- p.reject(new Error(`${p.method}: ${err.message ?? 'rpc error'} (code=${err.code ?? '?'})`));
179
- }
180
- else {
181
- p.resolve(frame.result);
182
- }
183
- return;
184
- }
185
- // Event — has `method` but no `id`.
186
- if (typeof frame.method === 'string' && !('id' in frame)) {
187
- const ev = {
188
- method: frame.method,
189
- params: frame.params ?? {},
190
- };
191
- this.emit('event', ev);
192
- this.emit(`event:${ev.method}`, ev.params);
193
- return;
194
- }
195
- // Anything else is malformed — log but don't crash.
196
- this.emit('stderr', `[protocol] unexpected frame: ${JSON.stringify(frame).slice(0, 200)}`);
197
- }
198
- handleExit(code) {
199
- if (this.exited)
200
- return;
201
- this.exited = true;
202
- for (const p of Array.from(this.pending.values())) {
203
- clearTimeout(p.timer);
204
- p.reject(new Error(`gateway exited (code=${code ?? 'null'})`));
205
- }
206
- this.pending.clear();
207
- this.stdoutRl?.close();
208
- this.stderrRl?.close();
209
- this.connected = false;
210
- this.emit('exit', code);
211
- }
212
- /** Issue a JSON-RPC request and await its response. */
213
- send(method, params = {}, opts = {}) {
214
- if (!this.transport) {
215
- return Promise.reject(new Error('GatewayClient: not connected'));
216
- }
217
- if (this.exited) {
218
- return Promise.reject(new Error('GatewayClient: gateway has exited'));
219
- }
220
- const id = String(++this.reqId);
221
- const frame = JSON.stringify({ jsonrpc: '2.0', id, method, params }) + '\n';
222
- const timeoutMs = opts.timeoutMs ?? this.opts.defaultTimeoutMs ?? DEFAULT_TIMEOUT_MS;
223
- return new Promise((resolve, reject) => {
224
- const timer = setTimeout(() => {
225
- this.pending.delete(id);
226
- reject(new Error(`${method}: timeout after ${timeoutMs}ms`));
227
- }, timeoutMs);
228
- this.pending.set(id, { id, method, resolve, reject, timer });
229
- try {
230
- this.transport.stdin.write(frame);
231
- }
232
- catch (err) {
233
- clearTimeout(timer);
234
- this.pending.delete(id);
235
- reject(err);
236
- }
237
- });
238
- }
239
- /**
240
- * Streaming chat helper. Wires `chat.start` / `chat.delta` / `chat.done`
241
- * to the supplied handlers, then issues `chat.send`. Resolves with the
242
- * `chat.done` summary; rejects on RPC error.
243
- */
244
- async sendChat(params, handlers = {}) {
245
- const onStart = (p) => {
246
- handlers.onStart?.({ provider: String(p.provider ?? ''), model: String(p.model ?? '') });
247
- };
248
- const onDelta = (p) => {
249
- const t = typeof p.text === 'string' ? p.text : '';
250
- if (t)
251
- handlers.onDelta?.(t);
252
- };
253
- const onDone = (p) => {
254
- handlers.onDone?.(p);
255
- };
256
- this.on('event:chat.start', onStart);
257
- this.on('event:chat.delta', onDelta);
258
- this.on('event:chat.done', onDone);
259
- try {
260
- const summary = (await this.send('chat.send', params));
261
- return summary;
262
- }
263
- catch (err) {
264
- handlers.onError?.(err);
265
- throw err;
266
- }
267
- finally {
268
- this.off('event:chat.start', onStart);
269
- this.off('event:chat.delta', onDelta);
270
- this.off('event:chat.done', onDone);
271
- }
272
- }
273
- /** Resolved session info from the handshake. */
274
- getSession() {
275
- return this.session;
276
- }
277
- isConnected() {
278
- return this.connected && !this.exited;
279
- }
280
- /** Best-effort orderly shutdown — issues system.shutdown and kills proc. */
281
- async close() {
282
- if (!this.transport || this.exited)
283
- return;
284
- try {
285
- await this.send('system.shutdown', {}, { timeoutMs: 1000 });
286
- }
287
- catch {
288
- // ignore — the gateway may already be tearing down.
289
- }
290
- try {
291
- this.transport.kill?.();
292
- }
293
- catch {
294
- // ignore
295
- }
296
- if (this.proc && !this.proc.killed) {
297
- try {
298
- this.proc.kill();
299
- }
300
- catch {
301
- // ignore
302
- }
303
- }
304
- this.handleExit(0);
305
- }
306
- }
307
- /**
308
- * Render an OSC 8 hyperlink escape sequence: `\x1b]8;;URL\x1b\\TEXT\x1b]8;;\x1b\\`.
309
- * Re-exported here for tests + downstream consumers that don't want a hard
310
- * dependency on the markdown component.
311
- */
312
- export const osc8Link = (url, label) => `\x1b]8;;${url}\x1b\\${label}\x1b]8;;\x1b\\`;