@nexrall/code-core 1.4.76 → 1.4.78
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/agent/effortCap.d.ts +24 -0
- package/dist/agent/effortCap.d.ts.map +1 -0
- package/dist/agent/effortCap.js +66 -0
- package/dist/agent/goal.d.ts +55 -0
- package/dist/agent/goal.d.ts.map +1 -0
- package/dist/agent/goal.js +120 -0
- package/dist/agent/handoffBrief.d.ts +82 -0
- package/dist/agent/handoffBrief.d.ts.map +1 -0
- package/dist/agent/handoffBrief.js +121 -0
- package/dist/agent/hooks.d.ts +10 -2
- package/dist/agent/hooks.d.ts.map +1 -1
- package/dist/agent/hooks.js +9 -3
- package/dist/agent/modelCatalogue.d.ts +23 -0
- package/dist/agent/modelCatalogue.d.ts.map +1 -1
- package/dist/agent/modelCatalogue.js +28 -0
- package/dist/agent/outputStyles.d.ts +27 -0
- package/dist/agent/outputStyles.d.ts.map +1 -0
- package/dist/agent/outputStyles.js +174 -0
- package/dist/agent/skills.d.ts.map +1 -1
- package/dist/agent/skills.js +21 -1
- package/dist/api/billingLines.d.ts +11 -0
- package/dist/api/billingLines.d.ts.map +1 -0
- package/dist/api/billingLines.js +56 -0
- package/dist/api/client.d.ts +2 -0
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/scheduleLines.d.ts +53 -0
- package/dist/api/scheduleLines.d.ts.map +1 -0
- package/dist/api/scheduleLines.js +150 -0
- package/dist/context/contextFiles.d.ts +81 -0
- package/dist/context/contextFiles.d.ts.map +1 -0
- package/dist/context/contextFiles.js +310 -0
- package/dist/diff/collect.d.ts +25 -0
- package/dist/diff/collect.d.ts.map +1 -0
- package/dist/diff/collect.js +169 -0
- package/dist/diff/diffView.d.ts +57 -0
- package/dist/diff/diffView.d.ts.map +1 -0
- package/dist/diff/diffView.js +231 -0
- package/dist/diff/reviewQueue.d.ts +53 -0
- package/dist/diff/reviewQueue.d.ts.map +1 -0
- package/dist/diff/reviewQueue.js +349 -0
- package/dist/events/recap.d.ts +54 -0
- package/dist/events/recap.d.ts.map +1 -0
- package/dist/events/recap.js +161 -0
- package/dist/events/sessionEvents.d.ts +54 -0
- package/dist/events/sessionEvents.d.ts.map +1 -0
- package/dist/events/sessionEvents.js +324 -0
- package/dist/events/sessionStats.d.ts +89 -0
- package/dist/events/sessionStats.d.ts.map +1 -0
- package/dist/events/sessionStats.js +264 -0
- package/dist/import/claudeImport.d.ts +44 -0
- package/dist/import/claudeImport.d.ts.map +1 -0
- package/dist/import/claudeImport.js +337 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +38 -0
- package/dist/mcp/manager.d.ts +8 -0
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/mcp/manager.js +64 -57
- package/dist/permissions/destructiveTokens.d.ts +1 -0
- package/dist/permissions/destructiveTokens.d.ts.map +1 -1
- package/dist/permissions/destructiveTokens.js +93 -0
- package/dist/permissions/rules.d.ts +12 -0
- package/dist/permissions/rules.d.ts.map +1 -1
- package/dist/permissions/rules.js +89 -7
- package/dist/plugins/configStore.d.ts +43 -0
- package/dist/plugins/configStore.d.ts.map +1 -0
- package/dist/plugins/configStore.js +253 -0
- package/dist/plugins/files.d.ts +10 -0
- package/dist/plugins/files.d.ts.map +1 -0
- package/dist/plugins/files.js +85 -0
- package/dist/plugins/index.d.ts +3 -22
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/index.js +30 -40
- package/dist/plugins/resolve.d.ts +18 -0
- package/dist/plugins/resolve.d.ts.map +1 -0
- package/dist/plugins/resolve.js +152 -0
- package/dist/plugins/userConfig.d.ts +90 -0
- package/dist/plugins/userConfig.d.ts.map +1 -0
- package/dist/plugins/userConfig.js +332 -0
- package/dist/plugins/validate.d.ts +14 -0
- package/dist/plugins/validate.d.ts.map +1 -0
- package/dist/plugins/validate.js +222 -0
- package/dist/project/projectCommands.d.ts +33 -0
- package/dist/project/projectCommands.d.ts.map +1 -0
- package/dist/project/projectCommands.js +246 -0
- package/dist/search/conversationTurns.d.ts +53 -0
- package/dist/search/conversationTurns.d.ts.map +1 -0
- package/dist/search/conversationTurns.js +170 -0
- package/dist/search/globalSearch.d.ts +144 -0
- package/dist/search/globalSearch.d.ts.map +1 -0
- package/dist/search/globalSearch.js +350 -0
- package/dist/share/sessionChannel.d.ts +136 -0
- package/dist/share/sessionChannel.d.ts.map +1 -0
- package/dist/share/sessionChannel.js +373 -0
- package/dist/share/sessionShare.d.ts +104 -0
- package/dist/share/sessionShare.d.ts.map +1 -0
- package/dist/share/sessionShare.js +336 -0
- package/dist/ui/configCmd.d.ts +48 -0
- package/dist/ui/configCmd.d.ts.map +1 -0
- package/dist/ui/configCmd.js +146 -0
- package/dist/ui/deployPanel.d.ts +91 -0
- package/dist/ui/deployPanel.d.ts.map +1 -0
- package/dist/ui/deployPanel.js +442 -0
- package/dist/ui/mergeAssistant.d.ts +120 -0
- package/dist/ui/mergeAssistant.d.ts.map +1 -0
- package/dist/ui/mergeAssistant.js +391 -0
- package/dist/ui/notify.d.ts +114 -0
- package/dist/ui/notify.d.ts.map +1 -0
- package/dist/ui/notify.js +235 -0
- package/dist/ui/promptSuggest.d.ts +56 -0
- package/dist/ui/promptSuggest.d.ts.map +1 -0
- package/dist/ui/promptSuggest.js +160 -0
- package/dist/ui/taskGraph.d.ts +44 -0
- package/dist/ui/taskGraph.d.ts.map +1 -0
- package/dist/ui/taskGraph.js +289 -0
- package/dist/util/addDir.d.ts +31 -0
- package/dist/util/addDir.d.ts.map +1 -0
- package/dist/util/addDir.js +124 -0
- package/dist/util/batch.d.ts +16 -0
- package/dist/util/batch.d.ts.map +1 -0
- package/dist/util/batch.js +92 -0
- package/dist/util/cellWidth.d.ts +12 -0
- package/dist/util/cellWidth.d.ts.map +1 -0
- package/dist/util/cellWidth.js +161 -0
- package/dist/util/duration.d.ts +8 -0
- package/dist/util/duration.d.ts.map +1 -0
- package/dist/util/duration.js +50 -0
- package/dist/util/loopJobs.d.ts +67 -0
- package/dist/util/loopJobs.d.ts.map +1 -0
- package/dist/util/loopJobs.js +169 -0
- package/dist/util/settingsFile.d.ts +14 -0
- package/dist/util/settingsFile.d.ts.map +1 -0
- package/dist/util/settingsFile.js +99 -0
- package/dist/util/toolLabel.d.ts +2 -0
- package/dist/util/toolLabel.d.ts.map +1 -0
- package/dist/util/toolLabel.js +17 -0
- package/dist/verify/failureTimeline.d.ts +100 -0
- package/dist/verify/failureTimeline.d.ts.map +1 -0
- package/dist/verify/failureTimeline.js +253 -0
- package/dist/verify/verification.d.ts +75 -0
- package/dist/verify/verification.d.ts.map +1 -0
- package/dist/verify/verification.js +315 -0
- package/package.json +5 -4
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SessionShare = exports.MAX_REMOTE_INPUT_CHARS = exports.RECONNECT_FILL = exports.PULL_LIMIT = void 0;
|
|
4
|
+
exports.shareServerUrl = shareServerUrl;
|
|
5
|
+
exports.webLiveUrl = webLiveUrl;
|
|
6
|
+
exports.startSessionShare = startSessionShare;
|
|
7
|
+
exports.activeSessionShare = activeSessionShare;
|
|
8
|
+
exports.publishSharedEvent = publishSharedEvent;
|
|
9
|
+
exports.rebindSessionShare = rebindSessionShare;
|
|
10
|
+
exports.stopSessionShare = stopSessionShare;
|
|
11
|
+
// Lives in core (moved from the CLI's ui/sessionShare.ts, 2026-10-05) so the
|
|
12
|
+
// VS Code panel can share a session with the same relay client and the same
|
|
13
|
+
// S12b drive rules; the CLI module is a re-export shim. The singleton helpers
|
|
14
|
+
// at the bottom are for the one-REPL CLI; the panel instantiates SessionShare
|
|
15
|
+
// directly, one per chat tab.
|
|
16
|
+
// Spec §93 — terminal-to-web continuity. S12a made the stream READ-ONLY
|
|
17
|
+
// (watch); S12b adds the DRIVE half, behind an explicit terminal-side switch.
|
|
18
|
+
//
|
|
19
|
+
// While sharing is on, every §92 event this session writes to its local JSONL is ALSO
|
|
20
|
+
// published over an authenticated Socket.IO connection to the platform
|
|
21
|
+
// (ws-server/handlers/cliSessions.js), which relays it to the same account's other
|
|
22
|
+
// clients — the live viewer at app.nexrall.com/live/<id>, another machine, later a
|
|
23
|
+
// VS Code window. Nothing is stored server-side: the relay rebroadcasts within the
|
|
24
|
+
// publisher's own user room, so only the account that owns the session can watch it.
|
|
25
|
+
//
|
|
26
|
+
// S12b: the same room can send `cli:session-input` / `cli:session-answer` frames
|
|
27
|
+
// back. They are accepted ONLY while `/share drive on` is in effect (default:
|
|
28
|
+
// watch-only), only for THIS session id, and always re-validated here — the relay
|
|
29
|
+
// is a pipe, the terminal is the authority. Input goes to the chat loop's own
|
|
30
|
+
// injection points; answers go to the permission gate's race (see
|
|
31
|
+
// permissions/remoteAnswer.ts for the safety rule), never to the tools directly.
|
|
32
|
+
//
|
|
33
|
+
// Invariants, mirroring sessionEvents.ts's "telemetry must never fail a turn":
|
|
34
|
+
// · publish / publishSharedEvent never throw, and are no-ops when sharing is off.
|
|
35
|
+
// · An event produced while the socket is down is DROPPED, never buffered — the
|
|
36
|
+
// local JSONL is the source of truth, and the socket heals its own holes by
|
|
37
|
+
// re-pushing the tail (after a reconnect blip, and whenever a viewer attaches),
|
|
38
|
+
// so a dropped frame is exactly one replay away.
|
|
39
|
+
// · The connection is opt-in per session and dies with the process; the server
|
|
40
|
+
// cleans the live registry on disconnect, so a kill -9 needs no goodbye.
|
|
41
|
+
const socket_io_client_1 = require("socket.io-client");
|
|
42
|
+
const sessionEvents_1 = require("../events/sessionEvents");
|
|
43
|
+
/** Frames pushed when a viewer attaches — enough context to see what the session has been doing. */
|
|
44
|
+
exports.PULL_LIMIT = 200;
|
|
45
|
+
/** Frames re-pushed after a reconnect, to fill the hole the outage left in watching clients. */
|
|
46
|
+
exports.RECONNECT_FILL = 50;
|
|
47
|
+
/** Bound on a remote input line; matches the relay's own cap (defense in depth). */
|
|
48
|
+
exports.MAX_REMOTE_INPUT_CHARS = 8192;
|
|
49
|
+
/** Shape of a permission request id — what the permission mirror can mint. */
|
|
50
|
+
const REQUEST_ID_RE = /^[A-Za-z0-9_-]{1,64}$/;
|
|
51
|
+
function clipText(text, max) {
|
|
52
|
+
return text.length > max ? text.slice(0, max - 1) + '…' : text;
|
|
53
|
+
}
|
|
54
|
+
/** Where the relay lives. Overridable so a dev stack never needs production. */
|
|
55
|
+
function shareServerUrl(env = process.env) {
|
|
56
|
+
const raw = (env.NEXRALL_WS_URL ?? '').trim().replace(/\/+$/, '');
|
|
57
|
+
return raw || 'https://api.nexrall.com';
|
|
58
|
+
}
|
|
59
|
+
/** The link a human opens to watch — the CLI prints this, nothing else constructs it. */
|
|
60
|
+
function webLiveUrl(id, env = process.env) {
|
|
61
|
+
const base = (env.NEXRALL_WEB_URL ?? '').trim().replace(/\/+$/, '') || 'https://app.nexrall.com';
|
|
62
|
+
return `${base}/live/${encodeURIComponent(id)}`;
|
|
63
|
+
}
|
|
64
|
+
const defaultFactory = (url, opts) => (0, socket_io_client_1.io)(url, opts);
|
|
65
|
+
class SessionShare {
|
|
66
|
+
constructor(deps) {
|
|
67
|
+
this.deps = deps;
|
|
68
|
+
this.socket = null;
|
|
69
|
+
this.status = { state: 'connecting' };
|
|
70
|
+
/** A second connect means the first one dropped: heal the hole for watchers. */
|
|
71
|
+
this.everConnected = false;
|
|
72
|
+
this.refreshing = false;
|
|
73
|
+
this.stopped = false;
|
|
74
|
+
/** §93 S12b: remote driving — the terminal's switch, off until /share drive on. */
|
|
75
|
+
this.drive = false;
|
|
76
|
+
/** §93 S12b: the permission prompt currently open in this terminal (null: none). */
|
|
77
|
+
this.pendingPermission = null;
|
|
78
|
+
this.id = deps.sessionId;
|
|
79
|
+
}
|
|
80
|
+
get sessionId() {
|
|
81
|
+
return this.id;
|
|
82
|
+
}
|
|
83
|
+
get state() {
|
|
84
|
+
return this.status;
|
|
85
|
+
}
|
|
86
|
+
start() {
|
|
87
|
+
const factory = this.deps.ioFactory ?? defaultFactory;
|
|
88
|
+
const socket = factory(this.deps.url, {
|
|
89
|
+
path: '/socket.io',
|
|
90
|
+
// websocket-only: Engine.IO's polling fallback needs cookie-pinned session
|
|
91
|
+
// affinity, which a CLI has no reason to participate in.
|
|
92
|
+
transports: ['websocket'],
|
|
93
|
+
// Never keep the CLI process alive: sharing must cost nothing at exit.
|
|
94
|
+
autoUnref: true,
|
|
95
|
+
reconnection: true,
|
|
96
|
+
reconnectionDelay: 1000,
|
|
97
|
+
reconnectionDelayMax: 15000,
|
|
98
|
+
timeout: 10000,
|
|
99
|
+
// Function form: invoked before every connect attempt, so a token refreshed
|
|
100
|
+
// mid-session (or rotated by another command) is used by the next attempt.
|
|
101
|
+
auth: (cb) => {
|
|
102
|
+
cb({ token: this.deps.tokenProvider() ?? '' });
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
this.socket = socket;
|
|
106
|
+
socket.on('connect', () => {
|
|
107
|
+
this.setStatus({ state: 'live' });
|
|
108
|
+
this.emitHello();
|
|
109
|
+
if (this.everConnected)
|
|
110
|
+
this.pushTail(exports.RECONNECT_FILL);
|
|
111
|
+
this.everConnected = true;
|
|
112
|
+
});
|
|
113
|
+
socket.on('disconnect', (reason) => {
|
|
114
|
+
if (!this.stopped)
|
|
115
|
+
this.setStatus({ state: 'offline', detail: String(reason ?? 'disconnected') });
|
|
116
|
+
});
|
|
117
|
+
socket.on('connect_error', (err) => {
|
|
118
|
+
const detail = err?.message ?? 'connect error';
|
|
119
|
+
this.setStatus({ state: 'offline', detail });
|
|
120
|
+
// An expired access token is the one error the client itself can fix: the
|
|
121
|
+
// next automatic retry re-runs the auth callback, which then sees the new token.
|
|
122
|
+
if (this.deps.refreshToken && !this.refreshing && /invalid|expired/i.test(detail)) {
|
|
123
|
+
this.refreshing = true;
|
|
124
|
+
void this.deps
|
|
125
|
+
.refreshToken()
|
|
126
|
+
.catch(() => { })
|
|
127
|
+
.finally(() => {
|
|
128
|
+
this.refreshing = false;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
// A viewer attached: give it the tail of this session's log.
|
|
133
|
+
socket.on('cli:session-pull', (payload) => {
|
|
134
|
+
const wanted = payload?.id;
|
|
135
|
+
if (typeof wanted === 'string' && wanted === this.id) {
|
|
136
|
+
// The hello went out when this share connected — long before a viewer
|
|
137
|
+
// that opens the link later arrives, and nothing replays it on its own.
|
|
138
|
+
// Without it that viewer renders "waiting" forever and cannot know the
|
|
139
|
+
// meta or that driving is allowed, so re-announce alongside the tail.
|
|
140
|
+
this.emitHello();
|
|
141
|
+
this.pushTail(exports.PULL_LIMIT);
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
// §93 S12b — the DRIVE half. Frames from the account's other clients are
|
|
145
|
+
// considered only while THIS terminal has drive on; each is re-validated
|
|
146
|
+
// here rather than trusted from the relay (the relay is a pipe — it cannot
|
|
147
|
+
// know this session's switch, and must not decide it either).
|
|
148
|
+
socket.on('cli:session-input', (payload) => {
|
|
149
|
+
const p = payload;
|
|
150
|
+
if (!p || typeof p !== 'object' || p.id !== this.id)
|
|
151
|
+
return;
|
|
152
|
+
const text = typeof p.text === 'string' ? p.text : '';
|
|
153
|
+
if (!text.trim() || text.length > exports.MAX_REMOTE_INPUT_CHARS)
|
|
154
|
+
return;
|
|
155
|
+
if (!this.isDriveOn()) {
|
|
156
|
+
// A silently dropped line reads as a bug on the web — say why instead.
|
|
157
|
+
this.publishRemoteNote({ kind: 'input', status: 'refused', reason: 'remote drive is off', text });
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
try {
|
|
161
|
+
this.deps.onRemoteText?.(text);
|
|
162
|
+
}
|
|
163
|
+
catch {
|
|
164
|
+
/* the REPL survives any frame */
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
socket.on('cli:session-answer', (payload) => {
|
|
168
|
+
const p = payload;
|
|
169
|
+
if (!p || typeof p !== 'object' || p.id !== this.id)
|
|
170
|
+
return;
|
|
171
|
+
const requestId = typeof p.requestId === 'string' ? p.requestId : '';
|
|
172
|
+
const answer = p.answer === 'y' || p.answer === 'n' ? p.answer : null;
|
|
173
|
+
if (!answer || !REQUEST_ID_RE.test(requestId))
|
|
174
|
+
return;
|
|
175
|
+
if (!this.isDriveOn()) {
|
|
176
|
+
this.publishRemoteNote({ kind: 'answer', status: 'refused', reason: 'remote drive is off', requestId });
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
try {
|
|
180
|
+
this.deps.onRemoteAnswer?.(requestId, answer);
|
|
181
|
+
}
|
|
182
|
+
catch {
|
|
183
|
+
/* same */
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
return this;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* §93 S12b — turn remote driving on/off (returning the state now in effect).
|
|
190
|
+
* Off by default: a watch link is read-only until the person AT the terminal
|
|
191
|
+
* says otherwise, and the value is re-announced by every hello so a viewer
|
|
192
|
+
* that missed the toggle frame sees the truth after any reconnect. The
|
|
193
|
+
* terminal keeps every gate — drive can be revoked at any moment with
|
|
194
|
+
* /share drive off, and the destructive confirm stays terminal-only regardless.
|
|
195
|
+
*/
|
|
196
|
+
setDrive(on) {
|
|
197
|
+
if (this.stopped)
|
|
198
|
+
return false;
|
|
199
|
+
const next = Boolean(on);
|
|
200
|
+
if (next !== this.drive) {
|
|
201
|
+
this.drive = next;
|
|
202
|
+
this.emitTo('cli:session-drive', { id: this.id, on: this.drive });
|
|
203
|
+
}
|
|
204
|
+
return this.drive;
|
|
205
|
+
}
|
|
206
|
+
isDriveOn() {
|
|
207
|
+
return this.drive && !this.stopped;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* §93 S12b — the permission prompt currently open here, or null when none is.
|
|
211
|
+
* Kept so a viewer attaching MID-prompt is handed it again by the pull (the
|
|
212
|
+
* same healing rule the event tail follows); cleared by the gate when the
|
|
213
|
+
* prompt is done. Like every publish, a frame while disconnected is dropped
|
|
214
|
+
* rather than buffered — the pull replays the current one.
|
|
215
|
+
*/
|
|
216
|
+
publishPermission(frame) {
|
|
217
|
+
this.pendingPermission = frame ?? null;
|
|
218
|
+
if (this.stopped || !this.socket?.connected)
|
|
219
|
+
return;
|
|
220
|
+
this.emitTo('cli:session-permission', { id: this.id, frame: this.pendingPermission });
|
|
221
|
+
}
|
|
222
|
+
/** §93 S12b — tell the web what this terminal did with a remote frame. */
|
|
223
|
+
publishRemoteNote(note) {
|
|
224
|
+
if (this.stopped || !this.socket?.connected)
|
|
225
|
+
return;
|
|
226
|
+
this.emitTo('cli:session-remote', {
|
|
227
|
+
id: this.id,
|
|
228
|
+
kind: note.kind,
|
|
229
|
+
status: note.status,
|
|
230
|
+
...(note.reason ? { reason: clipText(note.reason, 160) } : {}),
|
|
231
|
+
...(note.text ? { text: clipText(note.text, 240) } : {}),
|
|
232
|
+
...(note.requestId ? { requestId: note.requestId } : {}),
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
publish(ev) {
|
|
236
|
+
if (this.stopped || !this.socket?.connected)
|
|
237
|
+
return; // dropped, not buffered — see header
|
|
238
|
+
this.emitTo('cli:session-event', { id: this.id, ev });
|
|
239
|
+
}
|
|
240
|
+
/** /clear and /fork move the session to a new id; watching follows it. */
|
|
241
|
+
rebind(id) {
|
|
242
|
+
if (this.stopped || !id || id === this.id)
|
|
243
|
+
return;
|
|
244
|
+
if (this.socket?.connected)
|
|
245
|
+
this.emitTo('cli:session-bye', { id: this.id, reason: 'rebound' });
|
|
246
|
+
this.id = id;
|
|
247
|
+
// A prompt (and its card) belonged to the OLD id; the new one starts clean.
|
|
248
|
+
this.pendingPermission = null;
|
|
249
|
+
if (this.socket?.connected)
|
|
250
|
+
this.emitHello();
|
|
251
|
+
}
|
|
252
|
+
stop(reason = 'closed') {
|
|
253
|
+
if (this.stopped)
|
|
254
|
+
return;
|
|
255
|
+
this.stopped = true;
|
|
256
|
+
// A dead share drives nothing and shows nothing: the drive switch and the
|
|
257
|
+
// prompt card die with the connection (a later /share starts watch-only).
|
|
258
|
+
this.drive = false;
|
|
259
|
+
this.pendingPermission = null;
|
|
260
|
+
if (this.socket?.connected)
|
|
261
|
+
this.emitTo('cli:session-bye', { id: this.id, reason });
|
|
262
|
+
try {
|
|
263
|
+
this.socket?.disconnect();
|
|
264
|
+
}
|
|
265
|
+
catch {
|
|
266
|
+
/* closing anyway */
|
|
267
|
+
}
|
|
268
|
+
this.setStatus({ state: 'stopped' });
|
|
269
|
+
}
|
|
270
|
+
emitTo(event, payload) {
|
|
271
|
+
try {
|
|
272
|
+
this.socket?.emit(event, payload);
|
|
273
|
+
}
|
|
274
|
+
catch {
|
|
275
|
+
/* the stream must never break the REPL */
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
/** One shape for every hello, so the two call sites cannot drift. */
|
|
279
|
+
emitHello() {
|
|
280
|
+
this.emitTo('cli:session-hello', { id: this.id, meta: this.deps.meta(), v: 1, drive: this.drive });
|
|
281
|
+
}
|
|
282
|
+
pushTail(limit) {
|
|
283
|
+
if (!this.socket?.connected)
|
|
284
|
+
return;
|
|
285
|
+
let events;
|
|
286
|
+
try {
|
|
287
|
+
events = (this.deps.recent ?? ((id) => (0, sessionEvents_1.readEvents)(id, { last: exports.PULL_LIMIT })))(this.id).slice(-limit);
|
|
288
|
+
}
|
|
289
|
+
catch {
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
292
|
+
for (const ev of events)
|
|
293
|
+
this.emitTo('cli:session-event', { id: this.id, ev, replay: true });
|
|
294
|
+
// S12b: a viewer attaching mid-prompt needs the prompt, not just the log.
|
|
295
|
+
if (this.pendingPermission) {
|
|
296
|
+
this.emitTo('cli:session-permission', { id: this.id, frame: this.pendingPermission, replay: true });
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
setStatus(next) {
|
|
300
|
+
const same = next.state === this.status.state && next.detail === this.status.detail;
|
|
301
|
+
this.status = next;
|
|
302
|
+
if (!same) {
|
|
303
|
+
try {
|
|
304
|
+
this.deps.onStatus?.(next);
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
/* status is cosmetic */
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
exports.SessionShare = SessionShare;
|
|
313
|
+
// ─── The one share a REPL can have ────────────────────────────────────────────
|
|
314
|
+
let current = null;
|
|
315
|
+
function startSessionShare(deps) {
|
|
316
|
+
current?.stop('replaced');
|
|
317
|
+
current = new SessionShare(deps).start();
|
|
318
|
+
return current;
|
|
319
|
+
}
|
|
320
|
+
function activeSessionShare() {
|
|
321
|
+
return current;
|
|
322
|
+
}
|
|
323
|
+
/** Called from the event funnel; free when sharing is off. */
|
|
324
|
+
function publishSharedEvent(ev) {
|
|
325
|
+
if (!ev)
|
|
326
|
+
return;
|
|
327
|
+
current?.publish(ev);
|
|
328
|
+
}
|
|
329
|
+
function rebindSessionShare(id) {
|
|
330
|
+
current?.rebind(id);
|
|
331
|
+
}
|
|
332
|
+
function stopSessionShare(reason = 'closed') {
|
|
333
|
+
current?.stop(reason);
|
|
334
|
+
current = null;
|
|
335
|
+
}
|
|
336
|
+
//# sourceMappingURL=sessionShare.js.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/** The `promptSuggestions` setting key — shared so the panel and the CLI's
|
|
2
|
+
* suggestion engine can never disagree on the spelling. */
|
|
3
|
+
export declare const SUGGESTIONS_SETTING = "promptSuggestions";
|
|
4
|
+
export interface ConfigKey {
|
|
5
|
+
key: string;
|
|
6
|
+
description: string;
|
|
7
|
+
/** Legal values, in the order shown. */
|
|
8
|
+
values: readonly string[];
|
|
9
|
+
/** What the value is when the settings file does not mention the key. */
|
|
10
|
+
defaultValue: string;
|
|
11
|
+
/** Turns a raw settings.json value into one of `values` (or the default). */
|
|
12
|
+
read: (raw: unknown) => string;
|
|
13
|
+
/** The slash command (without the value) that applies a change live and saves it. */
|
|
14
|
+
command: string;
|
|
15
|
+
}
|
|
16
|
+
export declare const CONFIG_KEYS: readonly ConfigKey[];
|
|
17
|
+
export type ConfigArgs = {
|
|
18
|
+
kind: 'list';
|
|
19
|
+
} | {
|
|
20
|
+
kind: 'show';
|
|
21
|
+
key: ConfigKey;
|
|
22
|
+
} | {
|
|
23
|
+
kind: 'set';
|
|
24
|
+
key: ConfigKey;
|
|
25
|
+
value: string;
|
|
26
|
+
scope: 'user' | 'project';
|
|
27
|
+
} | {
|
|
28
|
+
kind: 'error';
|
|
29
|
+
message: string;
|
|
30
|
+
};
|
|
31
|
+
/** Case-insensitive key lookup — people type `livediff` for `liveDiff`. */
|
|
32
|
+
export declare function findConfigKey(name: string): ConfigKey | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* `/config` → list
|
|
35
|
+
* `/config key` → show one
|
|
36
|
+
* `/config key=value` | `key value` → set (add `--project` to save it for this project only)
|
|
37
|
+
*/
|
|
38
|
+
export declare function parseConfigArgs(arg: string): ConfigArgs;
|
|
39
|
+
/** The slash line chat.ts runs to apply the change live and persist it. */
|
|
40
|
+
export declare function applyLine(a: {
|
|
41
|
+
key: ConfigKey;
|
|
42
|
+
value: string;
|
|
43
|
+
scope: 'user' | 'project';
|
|
44
|
+
}): string;
|
|
45
|
+
export declare function currentValue(key: ConfigKey, raw: Record<string, unknown> | undefined | null): string;
|
|
46
|
+
export declare function formatConfigList(raw: Record<string, unknown> | undefined | null): string[];
|
|
47
|
+
export declare function formatConfigKey(key: ConfigKey, raw: Record<string, unknown> | undefined | null): string[];
|
|
48
|
+
//# sourceMappingURL=configCmd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configCmd.d.ts","sourceRoot":"","sources":["../../src/ui/configCmd.ts"],"names":[],"mappings":"AAWA;4DAC4D;AAC5D,eAAO,MAAM,mBAAmB,sBAAsB,CAAC;AAEvD,MAAM,WAAW,SAAS;IACxB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,wCAAwC;IACxC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IAC1B,yEAAyE;IACzE,YAAY,EAAE,MAAM,CAAC;IACrB,6EAA6E;IAC7E,IAAI,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,MAAM,CAAC;IAC/B,qFAAqF;IACrF,OAAO,EAAE,MAAM,CAAC;CACjB;AAOD,eAAO,MAAM,WAAW,EAAE,SAAS,SAAS,EAoD3C,CAAC;AAEF,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,SAAS,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,GAAG,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvC,2EAA2E;AAC3E,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAGjE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,CA6BvD;AAED,2EAA2E;AAC3E,wBAAgB,SAAS,CAAC,CAAC,EAAE;IAAE,GAAG,EAAE,SAAS,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAAG,MAAM,CAEjG;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,CAEpG;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,CAU1F;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,CAOzG"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// Lives in core (moved from the CLI's ui/configCmd.ts, 2026-10-04) so the VS
|
|
3
|
+
// Code panel offers the same /config front door; the CLI module is a re-export shim.
|
|
4
|
+
// /config — one place to see and change the settings that already exist.
|
|
5
|
+
//
|
|
6
|
+
// The registry below is the single list of keys /config knows. Each entry says what
|
|
7
|
+
// values are legal and which slash command APPLIES it to the running session — /config
|
|
8
|
+
// never writes a file on its own for a key whose command would also change live state,
|
|
9
|
+
// because a saved setting that does nothing until the next launch looks like a bug.
|
|
10
|
+
// Pure: parsing, validation, formatting. chat.ts reads the merged settings and runs the
|
|
11
|
+
// command this module hands back.
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.CONFIG_KEYS = exports.SUGGESTIONS_SETTING = void 0;
|
|
14
|
+
exports.findConfigKey = findConfigKey;
|
|
15
|
+
exports.parseConfigArgs = parseConfigArgs;
|
|
16
|
+
exports.applyLine = applyLine;
|
|
17
|
+
exports.currentValue = currentValue;
|
|
18
|
+
exports.formatConfigList = formatConfigList;
|
|
19
|
+
exports.formatConfigKey = formatConfigKey;
|
|
20
|
+
/** The `promptSuggestions` setting key — shared so the panel and the CLI's
|
|
21
|
+
* suggestion engine can never disagree on the spelling. */
|
|
22
|
+
exports.SUGGESTIONS_SETTING = 'promptSuggestions';
|
|
23
|
+
const onOff = (raw, dflt) => {
|
|
24
|
+
if (raw === undefined)
|
|
25
|
+
return dflt;
|
|
26
|
+
return raw === false || raw === 'off' ? 'off' : 'on';
|
|
27
|
+
};
|
|
28
|
+
exports.CONFIG_KEYS = [
|
|
29
|
+
{
|
|
30
|
+
key: 'liveDiff',
|
|
31
|
+
description: 'Show the lines each edit changes as it happens',
|
|
32
|
+
values: ['on', 'off'],
|
|
33
|
+
defaultValue: 'on',
|
|
34
|
+
read: (r) => onOff(r, 'on'),
|
|
35
|
+
command: '/livediff',
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
key: 'mouse',
|
|
39
|
+
description: 'Wheel scrolling in fullscreen',
|
|
40
|
+
values: ['on', 'off'],
|
|
41
|
+
defaultValue: 'on',
|
|
42
|
+
read: (r) => onOff(r, 'on'),
|
|
43
|
+
command: '/mouse',
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
key: 'notifications',
|
|
47
|
+
description: 'Terminal notifications for background jobs and long turns',
|
|
48
|
+
values: ['auto', 'bell', 'osc', 'off'],
|
|
49
|
+
defaultValue: 'auto',
|
|
50
|
+
read: (r) => r === false ? 'off' : typeof r === 'string' && ['auto', 'bell', 'osc', 'off'].includes(r) ? r : 'auto',
|
|
51
|
+
command: '/notify',
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
key: 'editorMode',
|
|
55
|
+
description: 'Vim-style editing in the input box',
|
|
56
|
+
values: ['on', 'off'],
|
|
57
|
+
defaultValue: 'off',
|
|
58
|
+
read: (r) => (r === 'vim' ? 'on' : 'off'),
|
|
59
|
+
command: '/vim',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
// Names are open-ended (custom files), so the registry can't enumerate them: any
|
|
63
|
+
// lower-case style name is accepted here and /output-style rejects an unknown one.
|
|
64
|
+
key: 'outputStyle',
|
|
65
|
+
description: 'How the agent answers (see /output-style for the list)',
|
|
66
|
+
values: ['default', 'concise', 'explanatory', 'learning'],
|
|
67
|
+
defaultValue: 'default',
|
|
68
|
+
read: (r) => (typeof r === 'string' && r.trim() ? r.trim().toLowerCase() : 'default'),
|
|
69
|
+
command: '/output-style',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
key: 'promptSuggestions',
|
|
73
|
+
description: 'A suggested next prompt after each turn (a small background request)',
|
|
74
|
+
values: ['on', 'off'],
|
|
75
|
+
defaultValue: 'on',
|
|
76
|
+
read: (r) => onOff(r, 'on'),
|
|
77
|
+
command: '/suggestions',
|
|
78
|
+
},
|
|
79
|
+
];
|
|
80
|
+
/** Case-insensitive key lookup — people type `livediff` for `liveDiff`. */
|
|
81
|
+
function findConfigKey(name) {
|
|
82
|
+
const n = name.trim().toLowerCase();
|
|
83
|
+
return exports.CONFIG_KEYS.find((k) => k.key.toLowerCase() === n);
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* `/config` → list
|
|
87
|
+
* `/config key` → show one
|
|
88
|
+
* `/config key=value` | `key value` → set (add `--project` to save it for this project only)
|
|
89
|
+
*/
|
|
90
|
+
function parseConfigArgs(arg) {
|
|
91
|
+
const tokens = String(arg ?? '')
|
|
92
|
+
.trim()
|
|
93
|
+
.split(/\s+/)
|
|
94
|
+
.filter(Boolean);
|
|
95
|
+
const scope = tokens.includes('--project') ? 'project' : 'user';
|
|
96
|
+
const rest = tokens.filter((t) => t !== '--project' && t !== '--user');
|
|
97
|
+
if (rest.length === 0)
|
|
98
|
+
return { kind: 'list' };
|
|
99
|
+
let name = rest[0];
|
|
100
|
+
let value = rest[1];
|
|
101
|
+
const eq = name.indexOf('=');
|
|
102
|
+
if (eq >= 0) {
|
|
103
|
+
value = name.slice(eq + 1) || rest[1];
|
|
104
|
+
name = name.slice(0, eq);
|
|
105
|
+
}
|
|
106
|
+
const key = findConfigKey(name);
|
|
107
|
+
if (!key) {
|
|
108
|
+
return { kind: 'error', message: `Unknown setting "${name}". Known: ${exports.CONFIG_KEYS.map((k) => k.key).join(', ')}.` };
|
|
109
|
+
}
|
|
110
|
+
if (value === undefined || value === '')
|
|
111
|
+
return { kind: 'show', key };
|
|
112
|
+
if (rest.length > 2 && eq < 0)
|
|
113
|
+
return { kind: 'error', message: `Too many values. Use: /config ${key.key} <${key.values.join('|')}>` };
|
|
114
|
+
const v = value.toLowerCase();
|
|
115
|
+
if (!key.values.includes(v)) {
|
|
116
|
+
return { kind: 'error', message: `"${value}" is not valid for ${key.key}. Use one of: ${key.values.join(', ')}.` };
|
|
117
|
+
}
|
|
118
|
+
return { kind: 'set', key, value: v, scope };
|
|
119
|
+
}
|
|
120
|
+
/** The slash line chat.ts runs to apply the change live and persist it. */
|
|
121
|
+
function applyLine(a) {
|
|
122
|
+
return `${a.key.command} ${a.value}${a.scope === 'project' ? ' --project' : ''}`;
|
|
123
|
+
}
|
|
124
|
+
function currentValue(key, raw) {
|
|
125
|
+
return key.read((raw ?? {})[key.key]);
|
|
126
|
+
}
|
|
127
|
+
function formatConfigList(raw) {
|
|
128
|
+
const width = Math.max(...exports.CONFIG_KEYS.map((k) => k.key.length));
|
|
129
|
+
const lines = ['Settings (merged from your user and project settings.json):', ''];
|
|
130
|
+
for (const k of exports.CONFIG_KEYS) {
|
|
131
|
+
const cur = currentValue(k, raw);
|
|
132
|
+
const mark = cur === k.defaultValue ? '' : ' (changed)';
|
|
133
|
+
lines.push(` ${k.key.padEnd(width)} ${cur.padEnd(5)} ${k.description}${mark}`);
|
|
134
|
+
}
|
|
135
|
+
lines.push('', 'Change one: /config <key>=<value> e.g. /config liveDiff=off', 'Only this project: add --project');
|
|
136
|
+
return lines;
|
|
137
|
+
}
|
|
138
|
+
function formatConfigKey(key, raw) {
|
|
139
|
+
return [
|
|
140
|
+
`${key.key} = ${currentValue(key, raw)}`,
|
|
141
|
+
` ${key.description}`,
|
|
142
|
+
` values: ${key.values.join(' | ')} (default ${key.defaultValue})`,
|
|
143
|
+
` change: /config ${key.key}=<value>`,
|
|
144
|
+
];
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=configCmd.js.map
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
export type DeployEnv = 'local' | 'staging' | 'production' | 'unknown';
|
|
2
|
+
export interface DeployTarget {
|
|
3
|
+
/** What the user types: `/deploy <name>`. */
|
|
4
|
+
name: string;
|
|
5
|
+
command: string;
|
|
6
|
+
/** Where we learned about it (`package.json`, `vercel.json`, …). */
|
|
7
|
+
source: string;
|
|
8
|
+
env: DeployEnv;
|
|
9
|
+
/** Why that environment — printed so the user can disagree at a glance. */
|
|
10
|
+
why: string;
|
|
11
|
+
}
|
|
12
|
+
/** How strict a gate is. `unknown` sits WITH production, not below it. */
|
|
13
|
+
export declare const ENV_RANK: Record<DeployEnv, number>;
|
|
14
|
+
export declare const ENV_LABELS: Record<DeployEnv, string>;
|
|
15
|
+
/** The strictest of two environments — the rule that stops an override lowering a gate. */
|
|
16
|
+
export declare function strictestEnv(a: DeployEnv, b: DeployEnv): DeployEnv;
|
|
17
|
+
export declare function envFromFlags(command: string): DeployEnv | undefined;
|
|
18
|
+
/** The environment a target runs against, and the sentence that justifies it. */
|
|
19
|
+
export declare function inferEnv(name: string, command: string): {
|
|
20
|
+
env: DeployEnv;
|
|
21
|
+
why: string;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Every deploy target this folder can offer, in a stable order: package.json scripts, then
|
|
25
|
+
* recipes, then tool configs, then infrastructure. Duplicate commands are collapsed (a
|
|
26
|
+
* `deploy` script that merely calls `vercel deploy` is also matched by the vercel config).
|
|
27
|
+
*/
|
|
28
|
+
export declare function detectDeployTargets(workDir: string): DeployTarget[];
|
|
29
|
+
export interface ParsedDeployArgs {
|
|
30
|
+
name?: string;
|
|
31
|
+
/** `--env X`: a claim about the environment. Never lowers the gate (see strictestEnv). */
|
|
32
|
+
env?: DeployEnv;
|
|
33
|
+
yes: boolean;
|
|
34
|
+
dryRun: boolean;
|
|
35
|
+
list: boolean;
|
|
36
|
+
}
|
|
37
|
+
export declare const DEPLOY_USAGE = "/deploy [target] [--env local|staging|production] [--yes] [--dry-run] \u00B7 /deploy list";
|
|
38
|
+
export declare function parseDeployArgs(arg: string): ParsedDeployArgs | {
|
|
39
|
+
error: string;
|
|
40
|
+
};
|
|
41
|
+
export interface DeployGate {
|
|
42
|
+
ok: boolean;
|
|
43
|
+
/** Why it is refused — printed verbatim. */
|
|
44
|
+
reason?: string;
|
|
45
|
+
/**
|
|
46
|
+
* The word the user must TYPE to go ahead. Production (and unknown, which is gated the
|
|
47
|
+
* same way) always asks, even with --yes: a picker answer is too easy to give by reflex.
|
|
48
|
+
*/
|
|
49
|
+
confirmWord?: string;
|
|
50
|
+
/**
|
|
51
|
+
* A plain [Deploy]/[Cancel] answer is enough — set for local/staging unless `--yes`
|
|
52
|
+
* skipped it, and never alongside `confirmWord` (typing the word is the answer then).
|
|
53
|
+
*/
|
|
54
|
+
ask?: boolean;
|
|
55
|
+
}
|
|
56
|
+
export declare function deployGate(env: DeployEnv, opts?: {
|
|
57
|
+
readonly?: boolean;
|
|
58
|
+
yes?: boolean;
|
|
59
|
+
}): DeployGate;
|
|
60
|
+
export interface DeployCheck {
|
|
61
|
+
label: string;
|
|
62
|
+
/** true = ran and passed, false = ran and failed, null = not run this session. */
|
|
63
|
+
ok: boolean | null;
|
|
64
|
+
}
|
|
65
|
+
export interface DeployPanelInput {
|
|
66
|
+
/** The target picked, or null when none was (yet) — the panel still shows the choice. */
|
|
67
|
+
target: DeployTarget | null;
|
|
68
|
+
/** The environment the deploy will actually be gated on. */
|
|
69
|
+
env: DeployEnv;
|
|
70
|
+
/** Why that environment, printable. */
|
|
71
|
+
why: string;
|
|
72
|
+
/** Set when `--env` asked for something looser than the target's own answer. */
|
|
73
|
+
envOverrideIgnored?: string;
|
|
74
|
+
changes: string[];
|
|
75
|
+
/** Files changed beyond what fits — the caller counts, the panel only reports. */
|
|
76
|
+
changesHidden?: number;
|
|
77
|
+
/**
|
|
78
|
+
* `workDir` is not a git repository at all, so the changes count is unknowable — never
|
|
79
|
+
* print "nothing uncommitted", which would claim the deploy ships the last commit.
|
|
80
|
+
*/
|
|
81
|
+
noGit?: boolean;
|
|
82
|
+
checks: DeployCheck[];
|
|
83
|
+
dryRun?: boolean;
|
|
84
|
+
/** Set once the gate has decided (production/unknown ask for a typed word). */
|
|
85
|
+
gateNote?: string;
|
|
86
|
+
}
|
|
87
|
+
/** The environment word the user must type, in one sentence they can act on. */
|
|
88
|
+
export declare function confirmPrompt(env: DeployEnv): string;
|
|
89
|
+
/** True when `typed` is the confirmation word `env` asked for. */
|
|
90
|
+
export declare function confirmMatches(env: DeployEnv, typed: string): boolean;
|
|
91
|
+
//# sourceMappingURL=deployPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deployPanel.d.ts","sourceRoot":"","sources":["../../src/ui/deployPanel.ts"],"names":[],"mappings":"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"}
|