@volter/supercode-frontend-vscode 0.1.57 → 0.1.58

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 CHANGED
@@ -449,6 +449,13 @@ remains because the native model catalogue and participant identity are provider
449
449
 
450
450
  ### Native approval cards
451
451
 
452
+ A file approval names the harness-supplied path and shows its proposed replacement
453
+ text, new contents or patch before the answer buttons. Other requests show their
454
+ supplied arguments. Preview bounds are labelled, and a request with no supplied
455
+ preview says so. The frontend reads no workspace file to invent missing context
456
+ and never applies the preview. This source correction's real-editor qualification
457
+ is recorded separately in [the first-walk findings](../../docs/evidence/chat-first-walk-approvals-2026-10-09.md).
458
+
452
459
  A host advertising `volter.chat.inTurnApprovalCapability` version 1 presents
453
460
  actual approval requests in its native confirmation card. The original offered
454
461
  labels, order and response payloads are preserved. Clicking answers the pending
package/dist/extension.js CHANGED
@@ -255,7 +255,10 @@ function writePart(stream, part, state) {
255
255
  }
256
256
  // Stable API on purpose: a command button runs INSIDE the live turn,
257
257
  // which is when a supercode approval is raised. See `view.ts`.
258
- stream.markdown(`\n\n**${part.title}**\n\n${part.message}\n\n`);
258
+ // Native confirmation titles are plain text; escape only when the same
259
+ // title is embedded in the Markdown fallback (including Windows paths).
260
+ const title = new vscode.MarkdownString().appendText(part.title).value;
261
+ stream.markdown(`\n\n**${title}**\n\n${part.message}\n\n`);
259
262
  for (const answer of part.answers) {
260
263
  stream.button({
261
264
  title: answer.label,
package/dist/view.d.ts CHANGED
@@ -107,7 +107,7 @@ export declare function toolTitles(toolName: string, argumentsText: string): {
107
107
  };
108
108
  /** The command line of a shell tool call, read from its own arguments; undefined for any other tool. */
109
109
  export declare function shellCommand(toolName: string, argumentsText: string): string | undefined;
110
- /** The summary line this view shows for a request payload. */
110
+ /** The information this view shows for a request payload. */
111
111
  export declare function requestSummary(request: FrontendRequest): string;
112
112
  /** The answers this view offers for a request, one button each. */
113
113
  export declare function requestAnswers(request: FrontendRequest, connectionId: string): ChatAnswer[];
package/dist/view.js CHANGED
@@ -195,11 +195,75 @@ export function shellCommand(toolName, argumentsText) {
195
195
  catch { /* not JSON */ }
196
196
  return undefined;
197
197
  }
198
- /** The summary line this view shows for a request payload. */
198
+ /** The harness-supplied arguments of an approval; no files are read to reconstruct an edit. */
199
+ function approvalArguments(fields) {
200
+ const value = fields.arguments ?? fields.raw_args ?? fields.input;
201
+ if (typeof value !== 'string')
202
+ return value;
203
+ try {
204
+ return JSON.parse(value);
205
+ }
206
+ catch {
207
+ return value;
208
+ }
209
+ }
210
+ /** An approval preview is display text, never a patch to apply or an answer to the request. */
211
+ function approvalSummary(fields) {
212
+ const args = approvalArguments(fields);
213
+ const tool = text(fields.tool ?? fields.tool_name);
214
+ const values = args && typeof args === 'object' && !Array.isArray(args) ? args : undefined;
215
+ const path = values ? text(values.file_path ?? values.path ?? values.file ?? values.notebook_path) : '';
216
+ const heading = [tool, path || text(fields.subject ?? fields.message ?? fields.reason)].filter(Boolean)
217
+ .map(value => plain(clamp(stripControls(value), VSCODE_CHAT_LIMITS.titleCharacters))).join(' · ');
218
+ // Bound before adding fences, so truncation cannot leave an open code block.
219
+ const preview = (value, language = '') => {
220
+ const cleaned = stripControls(value);
221
+ const limited = clamp(cleaned, 24 * 1024);
222
+ return fence(limited, language) + (limited !== cleaned ? '\n\n_Preview truncated; the harness request is unchanged._' : '');
223
+ };
224
+ const changes = [];
225
+ const edits = values && Array.isArray(values.edits) ? values.edits : values ? [values] : [];
226
+ for (const edit of edits.slice(0, 4)) {
227
+ if (!edit || typeof edit !== 'object' || Array.isArray(edit))
228
+ continue;
229
+ if (typeof edit.old_string === 'string' && typeof edit.new_string === 'string') {
230
+ changes.push(`**Replace${edit.replace_all === true ? ' every match' : ''}**\n\n${preview(edit.old_string)}\n\n**With**\n\n${preview(edit.new_string)}`);
231
+ }
232
+ }
233
+ if (edits.length > 4)
234
+ changes.push('_Additional edits omitted from this preview; the harness request is unchanged._');
235
+ if (!changes.length && values) {
236
+ const patch = values.patch ?? values.diff;
237
+ const contents = values.content ?? values.new_source;
238
+ if (typeof patch === 'string')
239
+ changes.push(preview(patch, 'diff'));
240
+ else if (typeof contents === 'string')
241
+ changes.push(`**Proposed contents**\n\n${preview(contents)}`);
242
+ }
243
+ if (!changes.length && args !== undefined && args !== null) {
244
+ changes.push(preview(typeof args === 'string' ? args : JSON.stringify(args, null, 2), typeof args === 'string' ? '' : 'json'));
245
+ }
246
+ if (!changes.length)
247
+ changes.push('_The harness supplied no change preview._');
248
+ // Each edit is separately bounded; the overall card is bounded too. Retain
249
+ // complete fenced sections rather than cutting through their markup.
250
+ let result = heading;
251
+ for (const change of changes) {
252
+ if (result.length + change.length > VSCODE_CHAT_LIMITS.partCharacters - 128) {
253
+ result += '\n\n_Additional preview omitted; the harness request is unchanged._';
254
+ break;
255
+ }
256
+ result += `\n\n${change}`;
257
+ }
258
+ return result;
259
+ }
260
+ /** The information this view shows for a request payload. */
199
261
  export function requestSummary(request) {
200
262
  const payload = request.payload;
201
263
  if (payload && typeof payload === 'object' && !Array.isArray(payload)) {
202
264
  const fields = payload;
265
+ if (request.kind === 'approval')
266
+ return approvalSummary(fields);
203
267
  // `decide_approval` in crates/harness/src/server.rs publishes
204
268
  // `{tool, subject, raw_args}` and `ask_elicitation` publishes
205
269
  // `{message, requested_schema}`; the contract's own conformance fixture
@@ -348,11 +412,10 @@ export function requestSubject(request) {
348
412
  const tool = typeof fields.tool === 'string' ? fields.tool
349
413
  : typeof fields.tool_name === 'string' ? fields.tool_name
350
414
  : undefined;
415
+ const args = approvalArguments(fields);
351
416
  const subject = typeof fields.subject === 'string' ? fields.subject
352
- : typeof fields.raw_args === 'string' ? fields.raw_args
353
- : typeof fields.arguments === 'object' && fields.arguments !== null && !Array.isArray(fields.arguments)
354
- ? toolSubject(JSON.stringify(fields.arguments))
355
- : undefined;
417
+ : args && typeof args === 'object' ? toolSubject(JSON.stringify(args))
418
+ : undefined;
356
419
  if (tool && subject)
357
420
  return `${tool} on ${clamp(stripControls(subject), 120)}`;
358
421
  if (tool)
@@ -487,7 +550,7 @@ export function projectEvent(event, context) {
487
550
  const answers = requestAnswers(request, context.connectionId);
488
551
  const subject = requestSubject(request);
489
552
  const title = request.kind === 'approval'
490
- ? 'Approval required'
553
+ ? subject ? `Allow ${stripControls(subject)}?` : 'Approval required'
491
554
  : subject ? `Approve ${subject}` : `Assistant request #${request.id}`;
492
555
  // The host capability decides whether these original answers can use
493
556
  // a native in-turn confirmation card. Stock confirmation clicks start a
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@volter/supercode-frontend-vscode",
3
3
  "displayName": "Volter Harness",
4
- "version": "0.1.57",
4
+ "version": "0.1.58",
5
5
  "type": "module",
6
6
  "description": "VS Code chat-view frontend for an existing Volter Harness SDK runtime",
7
7
  "publisher": "volter-ai-dev",