nexrall-code 0.5.107 → 0.5.108
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/audit.js +102 -0
- package/dist/commands/auth.js +134 -0
- package/dist/commands/chat.js +2715 -0
- package/dist/commands/plugin.js +393 -0
- package/dist/commands/sessions.js +62 -0
- package/dist/commands/update.js +174 -0
- package/dist/index.js +1677 -36
- package/dist/permissions/handler.js +332 -0
- package/dist/terminal/terminalSetup.js +395 -0
- package/dist/trust.js +137 -0
- package/dist/ui/diff.js +51 -0
- package/dist/ui/inkReadlineAdapter.js +116 -0
- package/dist/ui/inkTerminal.js +1097 -0
- package/dist/ui/resizeRepaint.js +36 -0
- package/dist/ui/screen.js +482 -0
- package/dist/ui/theme.js +385 -0
- package/dist/ui/trustPrompt.js +126 -0
- package/package.json +1 -1
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { EventEmitter } from 'events';
|
|
2
|
+
// ─── readline.Interface-shaped Adapter over Ink ────────────────────────────
|
|
3
|
+
//
|
|
4
|
+
// chat.ts's ~1500 lines of business logic (slash commands, session
|
|
5
|
+
// persistence, agent-turn orchestration…) only ever touch 7 members of the
|
|
6
|
+
// readline.Interface surface: `.on('line', …)`, `.line`, `.cursor`, `.pause()`,
|
|
7
|
+
// `.resume()`, `.prompt()`, `.close()` — plus `.question(query, cb)` for the
|
|
8
|
+
// shared-interface permission-prompt reuse in permissions/handler.ts. Rather
|
|
9
|
+
// than rewriting every one of those call sites to talk to Ink directly (a
|
|
10
|
+
// much larger, much riskier change), this adapter implements exactly that
|
|
11
|
+
// surface backed by the Ink app's input state — so chat.ts's existing
|
|
12
|
+
// `rl.on('line', …)`/`rl.pause()`/`rl.resume()` code keeps working verbatim,
|
|
13
|
+
// it just now reads from/writes to Ink's React state under the hood instead
|
|
14
|
+
// of a real readline.Interface.
|
|
15
|
+
//
|
|
16
|
+
// ─── `pause()`/`resume()` no longer disable the input box ──────────────────
|
|
17
|
+
//
|
|
18
|
+
// They used to call `ink.setInputEnabled(false/true)`, which made Ink's
|
|
19
|
+
// `useInput` bail out on EVERY keystroke while an agent turn was running —
|
|
20
|
+
// no typing, no cursor movement, and (the worst of it) no Ctrl+C and no
|
|
21
|
+
// answering a permission y/n prompt fired mid-turn via `question()`, because
|
|
22
|
+
// that prompt is answered through the SAME input pipeline. A permission
|
|
23
|
+
// question asked while `rl.pause()` was in effect could never be answered at
|
|
24
|
+
// all — verified directly with an isolated harness that called `askLine()`
|
|
25
|
+
// after `setInputEnabled(false)`: it hung indefinitely.
|
|
26
|
+
//
|
|
27
|
+
// `pause()`/`resume()` now toggle `ink.setBusy()` instead, which keeps every
|
|
28
|
+
// keystroke flowing (see inkTerminal.tsx's useInput) and only changes what a
|
|
29
|
+
// submitted line does: while busy, Enter without an outstanding askLine()
|
|
30
|
+
// question queues the text (mirrors the VS Code panel's `_pendingInjections`)
|
|
31
|
+
// instead of emitting `'line'` — which would otherwise start a SECOND
|
|
32
|
+
// concurrent turn on top of the one already running.
|
|
33
|
+
export class InkReadlineAdapter extends EventEmitter {
|
|
34
|
+
// Kept for API parity with readline.Interface; Ink owns the actual typed
|
|
35
|
+
// text internally (the input box's own React state), so these are not
|
|
36
|
+
// read from live — chat.ts never reads them for this adapter's usage.
|
|
37
|
+
line = '';
|
|
38
|
+
cursor = 0;
|
|
39
|
+
ink;
|
|
40
|
+
busy = false;
|
|
41
|
+
pendingInput = [];
|
|
42
|
+
constructor(ink) {
|
|
43
|
+
super();
|
|
44
|
+
this.ink = ink;
|
|
45
|
+
this.ink.onLine((text) => {
|
|
46
|
+
// Historically this checked `this.paused` and dropped the line
|
|
47
|
+
// entirely — the mechanism that made typing during a turn a dead end.
|
|
48
|
+
// Ordinary (non-busy) submits always reach chat.ts's `rl.on('line', …)`
|
|
49
|
+
// now; busy-time submits go through onQueuedLine below instead, so
|
|
50
|
+
// this handler firing at all already implies "not busy" (inkTerminal's
|
|
51
|
+
// Enter branch routes to onLine vs onQueuedLine based on the same
|
|
52
|
+
// `busy` flag chat.ts sets here).
|
|
53
|
+
this.emit('line', text);
|
|
54
|
+
});
|
|
55
|
+
this.ink.onQueuedLine((text) => {
|
|
56
|
+
this.pendingInput.push(text);
|
|
57
|
+
});
|
|
58
|
+
this.ink.onInterrupt(() => {
|
|
59
|
+
this.emit('interrupt');
|
|
60
|
+
});
|
|
61
|
+
// Ink is exiting (a confirmed Ctrl+C quit, or stdin ending). A real
|
|
62
|
+
// readline.Interface emits 'close' when its input ends, and chat.ts's
|
|
63
|
+
// `rl.on('close')` is the ONLY place an interactive session persists the
|
|
64
|
+
// conversation on the way out — it saves, prints "Goodbye." and exits.
|
|
65
|
+
//
|
|
66
|
+
// Nothing used to trigger it for this adapter: `close()` below called
|
|
67
|
+
// straight through to Ink and never emitted the event, and the main Ink
|
|
68
|
+
// app's exit was never observed at all (no waitUntilExit subscriber). So
|
|
69
|
+
// quitting an interactive session with Ctrl+C silently DISCARDED the
|
|
70
|
+
// whole conversation — verified with an isolated harness: rl.close()
|
|
71
|
+
// fired no 'close' listener. That was survivable while Ctrl+C was an
|
|
72
|
+
// undocumented instant-kill; now that it is the confirmed, deliberate way
|
|
73
|
+
// to leave a session, losing the transcript is not acceptable.
|
|
74
|
+
this.ink.onExit(() => {
|
|
75
|
+
this.emit('close');
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
prompt(_preserveCursor) {
|
|
79
|
+
// No-op: Ink re-renders the input box reactively on every state change,
|
|
80
|
+
// there is no separate "draw the prompt now" step to trigger — unlike
|
|
81
|
+
// the previous hand-rolled split-screen renderer, which needed an
|
|
82
|
+
// explicit redraw call at specific points.
|
|
83
|
+
}
|
|
84
|
+
pause() {
|
|
85
|
+
this.busy = true;
|
|
86
|
+
this.ink.setBusy(true);
|
|
87
|
+
return this;
|
|
88
|
+
}
|
|
89
|
+
resume() {
|
|
90
|
+
this.busy = false;
|
|
91
|
+
this.ink.setBusy(false);
|
|
92
|
+
return this;
|
|
93
|
+
}
|
|
94
|
+
close() {
|
|
95
|
+
this.ink.close();
|
|
96
|
+
}
|
|
97
|
+
/** Compatible with readline.Interface#question — used by permissions/handler.ts's shared-interface reuse. */
|
|
98
|
+
question(query, cb) {
|
|
99
|
+
this.ink.askLine(query).then(cb);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Drains and returns every follow-up message the user typed and sent while
|
|
103
|
+
* `pause()` was active (i.e. during a running agent turn). Intended to be
|
|
104
|
+
* passed straight through as `AgentLoopOptions.takePendingInput` — see
|
|
105
|
+
* loop.ts, and the VS Code panel's `_pendingInjections.splice(0)` for the
|
|
106
|
+
* pattern this mirrors. Returns `[]` when nothing is queued, and empties
|
|
107
|
+
* the queue on every call so the same follow-up is never folded in twice.
|
|
108
|
+
*/
|
|
109
|
+
takePendingInput() {
|
|
110
|
+
return this.pendingInput.splice(0);
|
|
111
|
+
}
|
|
112
|
+
/** True while a `pause()`/`resume()` pair is in effect (an agent turn is running). */
|
|
113
|
+
isBusy() {
|
|
114
|
+
return this.busy;
|
|
115
|
+
}
|
|
116
|
+
}
|