@volter/supercode-frontend-vscode 0.1.63 → 0.1.65
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 +110 -72
- package/dist/extension.js +245 -104
- package/dist/host-controls.d.ts +0 -1
- package/dist/proposals.d.ts +1 -1
- package/dist/proposals.js +18 -2
- package/dist/session.d.ts +2 -21
- package/dist/session.js +3 -35
- package/dist/view.d.ts +58 -5
- package/dist/view.js +234 -109
- package/package.json +5 -2
package/dist/host-controls.d.ts
CHANGED
|
@@ -52,7 +52,6 @@ export interface ChatSetupState {
|
|
|
52
52
|
}
|
|
53
53
|
export interface HostState {
|
|
54
54
|
history?: ChatMessage[];
|
|
55
|
-
historyTruncated?: boolean;
|
|
56
55
|
activeSession: string | null;
|
|
57
56
|
openSessionCommand?: string;
|
|
58
57
|
/** Automatic ready-session reveal checks the observed native focus through its queued commit. */
|
package/dist/proposals.d.ts
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
* unconditionally, so a `typeof vscode.ChatResponseConfirmationPart` probe
|
|
14
14
|
* cannot answer this question — only the description can.
|
|
15
15
|
*/
|
|
16
|
-
export declare const REQUESTED_PROPOSALS: readonly ["defaultChatParticipant", "chatParticipantPrivate", "chatParticipantAdditions", "chatSessionsProvider", "chatProvider"];
|
|
16
|
+
export declare const REQUESTED_PROPOSALS: readonly ["defaultChatParticipant", "chatParticipantPrivate", "chatParticipantAdditions", "chatSessionsProvider", "chatProvider", "chatSessionResponses", "chatSystemNotification", "chatConfirmationResolution"];
|
|
17
17
|
export type ProposalName = (typeof REQUESTED_PROPOSALS)[number];
|
|
18
18
|
/** What each requested proposal buys, and what this frontend does without it. */
|
|
19
19
|
export declare const PROPOSAL_EFFECTS: Readonly<Record<ProposalName, {
|
package/dist/proposals.js
CHANGED
|
@@ -19,6 +19,10 @@ export const REQUESTED_PROPOSALS = Object.freeze([
|
|
|
19
19
|
'chatParticipantAdditions',
|
|
20
20
|
'chatSessionsProvider',
|
|
21
21
|
'chatProvider',
|
|
22
|
+
// Volter's Code-OSS fork (volter-ai/code-oss); a host without them drops the names ("DOES NOT EXIST").
|
|
23
|
+
'chatSessionResponses',
|
|
24
|
+
'chatSystemNotification',
|
|
25
|
+
'chatConfirmationResolution',
|
|
22
26
|
]);
|
|
23
27
|
/** What each requested proposal buys, and what this frontend does without it. */
|
|
24
28
|
export const PROPOSAL_EFFECTS = Object.freeze({
|
|
@@ -27,8 +31,8 @@ export const PROPOSAL_EFFECTS = Object.freeze({
|
|
|
27
31
|
without: 'the ordinary `@supercode` participant answers; a mention is required',
|
|
28
32
|
},
|
|
29
33
|
chatParticipantPrivate: {
|
|
30
|
-
grants: 'the dynamic-participant and
|
|
31
|
-
without: '
|
|
34
|
+
grants: 'the dynamic-participant identity, and an interrupted turn ending with a warning-level, expected error',
|
|
35
|
+
without: 'a static participant identity; an interrupted turn ends with an ordinary error',
|
|
32
36
|
},
|
|
33
37
|
chatParticipantAdditions: {
|
|
34
38
|
grants: 'tool-invocation, confirmation, warning and codeblock-uri response parts',
|
|
@@ -39,6 +43,18 @@ export const PROPOSAL_EFFECTS = Object.freeze({
|
|
|
39
43
|
grants: 'the runtime’s sessions in the Chat view’s session picker, each reopening with its history',
|
|
40
44
|
without: 'the participant still attaches; there is no session list',
|
|
41
45
|
},
|
|
46
|
+
chatSessionResponses: {
|
|
47
|
+
grants: 'a re-joined or saved response ending with its error; questions on a re-joined response as the carousel; a conversation that could not be opened anchored as Code-OSS anchors one',
|
|
48
|
+
without: 'a re-joined or saved response’s error as a warning part; questions there as buttons; that conversation’s error under the marker request',
|
|
49
|
+
},
|
|
50
|
+
chatSystemNotification: {
|
|
51
|
+
grants: 'a harness notice (a background task finishing, an interruption record) as the system notification row',
|
|
52
|
+
without: 'the notice as a plain line',
|
|
53
|
+
},
|
|
54
|
+
chatConfirmationResolution: {
|
|
55
|
+
grants: 'an approval card answered elsewhere losing its buttons',
|
|
56
|
+
without: 'the card stays and one plain line beneath it says the answer',
|
|
57
|
+
},
|
|
42
58
|
});
|
|
43
59
|
/** Read the proposals the HOST granted this extension, never the ones it asked for. */
|
|
44
60
|
export function grantedProposals(packageJSON) {
|
package/dist/session.d.ts
CHANGED
|
@@ -16,9 +16,6 @@ export interface VscodeRuntimeClient {
|
|
|
16
16
|
steer(prompt: string): Promise<{
|
|
17
17
|
queued: boolean;
|
|
18
18
|
}>;
|
|
19
|
-
stopTask(taskId: string): Promise<{
|
|
20
|
-
stopped: boolean;
|
|
21
|
-
}>;
|
|
22
19
|
interrupt(): Promise<{
|
|
23
20
|
interrupted: boolean;
|
|
24
21
|
}>;
|
|
@@ -66,12 +63,6 @@ export declare const TURN_TERMINAL_KINDS: readonly ["turn_succeeded", "turn_fail
|
|
|
66
63
|
* the view reports.
|
|
67
64
|
*/
|
|
68
65
|
export declare const LEASE_ERROR_NAMES: readonly string[];
|
|
69
|
-
/** One of the harness's own background tasks (a Monitor, a background shell), as it last listed them. */
|
|
70
|
-
export interface BackgroundTask {
|
|
71
|
-
id: string;
|
|
72
|
-
kind: string;
|
|
73
|
-
description: string;
|
|
74
|
-
}
|
|
75
66
|
/**
|
|
76
67
|
* One attachment to one already-running Volter Harness SDK runtime: cursor-safe
|
|
77
68
|
* event projection, permission narrowing, and the semantic actions the runtime
|
|
@@ -87,7 +78,6 @@ export declare class VscodeFrontendSession {
|
|
|
87
78
|
history: ChatMessage[];
|
|
88
79
|
historyCursor: number;
|
|
89
80
|
historyEvents: FrontendEvent[];
|
|
90
|
-
historyEventsDropped: number;
|
|
91
81
|
cursor: number;
|
|
92
82
|
/**
|
|
93
83
|
* Every event this attachment has seen, in order — NOT just the last
|
|
@@ -99,15 +89,8 @@ export declare class VscodeFrontendSession {
|
|
|
99
89
|
replay: FrontendEvent[];
|
|
100
90
|
pendingRequests: Map<number, FrontendRequest>;
|
|
101
91
|
/**
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*/
|
|
105
|
-
backgroundTasks: BackgroundTask[];
|
|
106
|
-
/**
|
|
107
|
-
* Requests this attachment has seen resolved. `request_resolved` deletes the
|
|
108
|
-
* pending entry while it is being projected, so without this the resolution
|
|
109
|
-
* could only say "request #1" — it would have lost the very thing it needs to
|
|
110
|
-
* name. Bounded, because a long session resolves a lot of them.
|
|
92
|
+
* Requests this attachment has seen resolved, so a resolution can still name what it answered once the pending
|
|
93
|
+
* entry is gone. Bounded, because a long session resolves a lot of them.
|
|
111
94
|
*/
|
|
112
95
|
resolvedRequests: Map<number, FrontendRequest>;
|
|
113
96
|
connection: 'disconnected' | 'connected' | 'closed';
|
|
@@ -158,8 +141,6 @@ export declare class VscodeFrontendSession {
|
|
|
158
141
|
submit(prompt: string, throwIfCancelled?: () => void): Promise<void>;
|
|
159
142
|
steer(prompt: string): Promise<void>;
|
|
160
143
|
interrupt(): Promise<void>;
|
|
161
|
-
/** Stop one of the harness's own background tasks, by the id it listed it with. */
|
|
162
|
-
stopTask(taskId: string): Promise<boolean>;
|
|
163
144
|
respond(response: FrontendResponse): Promise<void>;
|
|
164
145
|
detach(): Promise<void>;
|
|
165
146
|
close(): Promise<void>;
|
package/dist/session.js
CHANGED
|
@@ -48,7 +48,6 @@ export class VscodeFrontendSession {
|
|
|
48
48
|
history = [];
|
|
49
49
|
historyCursor = 0;
|
|
50
50
|
historyEvents = [];
|
|
51
|
-
historyEventsDropped = 0;
|
|
52
51
|
cursor = 0;
|
|
53
52
|
/**
|
|
54
53
|
* Every event this attachment has seen, in order — NOT just the last
|
|
@@ -60,15 +59,8 @@ export class VscodeFrontendSession {
|
|
|
60
59
|
replay = [];
|
|
61
60
|
pendingRequests = new Map();
|
|
62
61
|
/**
|
|
63
|
-
*
|
|
64
|
-
*
|
|
65
|
-
*/
|
|
66
|
-
backgroundTasks = [];
|
|
67
|
-
/**
|
|
68
|
-
* Requests this attachment has seen resolved. `request_resolved` deletes the
|
|
69
|
-
* pending entry while it is being projected, so without this the resolution
|
|
70
|
-
* could only say "request #1" — it would have lost the very thing it needs to
|
|
71
|
-
* name. Bounded, because a long session resolves a lot of them.
|
|
62
|
+
* Requests this attachment has seen resolved, so a resolution can still name what it answered once the pending
|
|
63
|
+
* entry is gone. Bounded, because a long session resolves a lot of them.
|
|
72
64
|
*/
|
|
73
65
|
resolvedRequests = new Map();
|
|
74
66
|
connection = 'disconnected';
|
|
@@ -130,23 +122,12 @@ export class VscodeFrontendSession {
|
|
|
130
122
|
descriptor: structuredClone(snapshot.descriptor),
|
|
131
123
|
pendingRequests: new Map((authoritative ? snapshot.pending_requests : [...this.pendingRequests.values()])
|
|
132
124
|
.map(request => [request.id, structuredClone(request)])),
|
|
133
|
-
backgroundTasks: structuredClone(this.backgroundTasks),
|
|
134
125
|
cursor: authoritative ? recovery.captureCursor : Math.max(this.cursor, snapshot.history_cursor),
|
|
135
126
|
};
|
|
136
127
|
// Validate and project the whole attachment before any observable field
|
|
137
128
|
// moves or a live listener is registered.
|
|
138
129
|
if (authoritative) {
|
|
139
130
|
// Snapshot state is authoritative at capture, before any later events.
|
|
140
|
-
// Background listings have no separate snapshot field; retain their
|
|
141
|
-
// latest original event without replaying historical request state.
|
|
142
|
-
for (const event of recovery.replay) {
|
|
143
|
-
const payload = (event.payload ?? {});
|
|
144
|
-
if (event.kind === 'background_tasks' && Array.isArray(payload.tasks)) {
|
|
145
|
-
staged.backgroundTasks = payload.tasks
|
|
146
|
-
.filter(task => task && typeof task.id === 'string')
|
|
147
|
-
.map(task => ({ id: task.id, kind: String(task.kind ?? 'task'), description: String(task.description ?? '') }));
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
131
|
for (const event of recovery.later)
|
|
151
132
|
this.projectEvent(staged, event);
|
|
152
133
|
}
|
|
@@ -197,10 +178,8 @@ export class VscodeFrontendSession {
|
|
|
197
178
|
this.history = structuredClone(snapshot.history);
|
|
198
179
|
this.historyCursor = snapshot.history_cursor;
|
|
199
180
|
this.historyEvents = structuredClone(snapshot.history_events ?? []);
|
|
200
|
-
this.historyEventsDropped = snapshot.history_events_dropped ?? 0;
|
|
201
181
|
this.appendTranscript(structuredClone(recovery.replay));
|
|
202
182
|
this.pendingRequests = staged.pendingRequests;
|
|
203
|
-
this.backgroundTasks = staged.backgroundTasks;
|
|
204
183
|
const previousCursor = this.cursor;
|
|
205
184
|
this.cursor = staged.cursor;
|
|
206
185
|
this.connection = 'connected';
|
|
@@ -392,18 +371,12 @@ export class VscodeFrontendSession {
|
|
|
392
371
|
if (request && typeof request.id === 'number')
|
|
393
372
|
state.pendingRequests.set(request.id, structuredClone(request));
|
|
394
373
|
}
|
|
395
|
-
if (event.kind === 'background_tasks' && Array.isArray(payload.tasks)) {
|
|
396
|
-
state.backgroundTasks = payload.tasks
|
|
397
|
-
.filter(task => task && typeof task.id === 'string')
|
|
398
|
-
.map(task => ({ id: task.id, kind: String(task.kind ?? 'task'), description: String(task.description ?? '') }));
|
|
399
|
-
}
|
|
400
374
|
if (event.kind === 'request_resolved' && typeof payload.request_id === 'number') {
|
|
401
375
|
const resolved = state.pendingRequests.get(payload.request_id);
|
|
402
376
|
if (resolved) {
|
|
403
377
|
this.resolvedRequests.set(payload.request_id, resolved);
|
|
404
|
-
while (this.resolvedRequests.size > 50)
|
|
378
|
+
while (this.resolvedRequests.size > 50)
|
|
405
379
|
this.resolvedRequests.delete(this.resolvedRequests.keys().next().value);
|
|
406
|
-
}
|
|
407
380
|
}
|
|
408
381
|
state.pendingRequests.delete(payload.request_id);
|
|
409
382
|
}
|
|
@@ -480,11 +453,6 @@ export class VscodeFrontendSession {
|
|
|
480
453
|
this.require('interrupt');
|
|
481
454
|
await this.withControl(() => this.client.interrupt());
|
|
482
455
|
}
|
|
483
|
-
/** Stop one of the harness's own background tasks, by the id it listed it with. */
|
|
484
|
-
async stopTask(taskId) {
|
|
485
|
-
const result = await this.withControl(() => this.client.stopTask(taskId));
|
|
486
|
-
return result?.stopped === true;
|
|
487
|
-
}
|
|
488
456
|
async respond(response) {
|
|
489
457
|
this.require('respond');
|
|
490
458
|
if (!this.pendingRequests.has(response.request_id))
|
package/dist/view.d.ts
CHANGED
|
@@ -34,6 +34,14 @@ export type ChatPart = {
|
|
|
34
34
|
} | {
|
|
35
35
|
part: 'progress';
|
|
36
36
|
value: string;
|
|
37
|
+
}
|
|
38
|
+
/** A record of the harness that is neither the agent's words nor the person's (a background task finishing, an
|
|
39
|
+
* interruption record, a scheduled prompt's start): Code-OSS's system notification row where the host has it
|
|
40
|
+
* (`chatSystemNotification`), with `icon` where it reports no completion, else a plain line. Markdown-safe text. */
|
|
41
|
+
| {
|
|
42
|
+
part: 'notice';
|
|
43
|
+
value: string;
|
|
44
|
+
icon?: string;
|
|
37
45
|
} | {
|
|
38
46
|
part: 'warning';
|
|
39
47
|
value: string;
|
|
@@ -79,11 +87,28 @@ export type ChatPart = {
|
|
|
79
87
|
background?: boolean;
|
|
80
88
|
} | {
|
|
81
89
|
part: 'answers';
|
|
90
|
+
connectionId: string;
|
|
91
|
+
requestId: number;
|
|
82
92
|
approval: boolean;
|
|
83
93
|
title: string;
|
|
84
94
|
message: string;
|
|
95
|
+
/** None: a request this window cannot answer, drawn read-only. */
|
|
85
96
|
answers: ChatAnswer[];
|
|
86
97
|
}
|
|
98
|
+
/** How a request drawn in this stream was answered, said only when the answer did not come through that card in
|
|
99
|
+
* this window (`writePart`), so a card answered elsewhere is not left looking open. Markdown-safe. */
|
|
100
|
+
| {
|
|
101
|
+
part: 'resolution';
|
|
102
|
+
connectionId: string;
|
|
103
|
+
requestId: number;
|
|
104
|
+
value: string;
|
|
105
|
+
}
|
|
106
|
+
/** A record that is not conversation (an event kind this version does not know, a malformed request): written to
|
|
107
|
+
* the output channel, never to the transcript. */
|
|
108
|
+
| {
|
|
109
|
+
part: 'unshown';
|
|
110
|
+
value: string;
|
|
111
|
+
}
|
|
87
112
|
/** A harness's questions (`requestQuestions`): VS Code's question carousel on a turn this window runs, its
|
|
88
113
|
* `answers` part anywhere else. */
|
|
89
114
|
| {
|
|
@@ -187,7 +212,11 @@ export interface SubagentCall {
|
|
|
187
212
|
/** A subagent call's description, kind and prompt (Claude Code's Task and Agent tools: `description`,
|
|
188
213
|
* `subagent_type`, `prompt`), read from its own arguments; undefined for any other tool. */
|
|
189
214
|
export declare function subagentCall(toolName: string, argumentsText: string): SubagentCall | undefined;
|
|
190
|
-
/**
|
|
215
|
+
/**
|
|
216
|
+
* The command line of a shell tool call, read from its own arguments; undefined for any other tool. Claude Code's
|
|
217
|
+
* BashOutput and KillBash are terminal rows too, as Code-OSS's own Claude host draws them (`claudeToolDisplay.ts`
|
|
218
|
+
* `TOOL_ROWS`): their command line is their `command`, else their input (`getClaudeToolInputString`).
|
|
219
|
+
*/
|
|
191
220
|
export declare function shellCommand(toolName: string, argumentsText: string): string | undefined;
|
|
192
221
|
/** The information this view shows for a request payload. */
|
|
193
222
|
export declare function requestSummary(request: FrontendRequest): string;
|
|
@@ -218,6 +247,15 @@ export declare function requestNeedsTypedReply(request: FrontendRequest): boolea
|
|
|
218
247
|
export declare function resolutionSentence(response: FrontendResponse | undefined, request: FrontendRequest | undefined, requestId: number): string;
|
|
219
248
|
/** `write_file on hello.txt`, read from the request's own payload. */
|
|
220
249
|
export declare function requestSubject(request: FrontendRequest): string | undefined;
|
|
250
|
+
/**
|
|
251
|
+
* How a turn that did not succeed ends the response its request handler runs, as VS Code's own agent host ends one
|
|
252
|
+
* (`agentHostSessionHandler.ts` `_getTurnErrorDetails`): a failed turn is the response's error, an interrupted one its
|
|
253
|
+
* warning-level, expected error. Undefined for any other event.
|
|
254
|
+
*/
|
|
255
|
+
export declare function turnOutcome(event: FrontendEvent): {
|
|
256
|
+
message: string;
|
|
257
|
+
interrupted: boolean;
|
|
258
|
+
} | undefined;
|
|
221
259
|
export interface ProjectionContext {
|
|
222
260
|
/** Identifies which attached runtime a confirmation click must answer. */
|
|
223
261
|
connectionId: string;
|
|
@@ -225,8 +263,14 @@ export interface ProjectionContext {
|
|
|
225
263
|
echoOwnPrompts?: boolean;
|
|
226
264
|
/** Show input arriving in an observed turn, without inventing a native request turn. */
|
|
227
265
|
liveUserMessages?: boolean;
|
|
228
|
-
/** The request a `request_resolved` answers, so its
|
|
266
|
+
/** The request a `request_resolved` answers, so its line can name it. */
|
|
229
267
|
pendingRequest?: (requestId: number) => FrontendRequest | undefined;
|
|
268
|
+
/** The calls whose background task's notification this stream has drawn (`firstNotice`), so a task finishing is one
|
|
269
|
+
* line: Claude Code reports it both as `system/task_notification` (a `status`) and as the user-role record that
|
|
270
|
+
* wakes the agent (a `user_message` notice). */
|
|
271
|
+
notices?: Set<string>;
|
|
272
|
+
/** Where a record that is not conversation goes when there is no writer to log it (history). */
|
|
273
|
+
unshown?: (value: string) => void;
|
|
230
274
|
/**
|
|
231
275
|
* Whether the runtime's own descriptor advertises `respond`. A HOSTED
|
|
232
276
|
* harness runtime sets `actions.respond: false` — the portable contract
|
|
@@ -252,10 +296,11 @@ export declare function projectEvent(event: FrontendEvent, context: ProjectionCo
|
|
|
252
296
|
/** Replace every part whose proposal the host did not grant with its fallback. */
|
|
253
297
|
export declare function resolveParts(parts: readonly ProjectedPart[], granted: ReadonlySet<string>): ChatPart[];
|
|
254
298
|
/**
|
|
255
|
-
* The prompt of the marker turn that carries runtime history with no user turn
|
|
256
|
-
*
|
|
299
|
+
* The prompt of the marker turn that carries runtime history with no user turn of its own: VS Code's own words for a
|
|
300
|
+
* turn whose request is not in the transcript (`claudeReplayMapper.ts` `missingPromptPlaceholder`), so nothing is
|
|
301
|
+
* presented as a person's words.
|
|
257
302
|
*/
|
|
258
|
-
export declare const HISTORY_MARKER_PROMPT = "
|
|
303
|
+
export declare const HISTORY_MARKER_PROMPT = "Message content could not be retrieved";
|
|
259
304
|
export type TurnRole = 'user' | 'assistant';
|
|
260
305
|
export interface ProjectedTurn {
|
|
261
306
|
role: TurnRole;
|
|
@@ -263,6 +308,14 @@ export interface ProjectedTurn {
|
|
|
263
308
|
prompt?: string;
|
|
264
309
|
/** Rendered parts for an assistant turn. */
|
|
265
310
|
parts?: ChatPart[];
|
|
311
|
+
/** How an assistant turn ended when it did not succeed, kept as the saved response's own error where the host
|
|
312
|
+
* shows one (`chatSessionResponses`); otherwise it is a warning part among `parts`. */
|
|
313
|
+
error?: {
|
|
314
|
+
message: string;
|
|
315
|
+
interrupted: boolean;
|
|
316
|
+
};
|
|
317
|
+
/** The record `error` came from, drawn as its warning part where anything follows it. */
|
|
318
|
+
errorEvent?: FrontendEvent;
|
|
266
319
|
}
|
|
267
320
|
export declare function projectReplayTurns(events: readonly FrontendEvent[], granted: ReadonlySet<string>, context: ProjectionContext, history?: readonly ProjectedTurn[]): ProjectedTurn[];
|
|
268
321
|
/**
|