dsh-remote-vs 0.9.1 → 0.9.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.
package/lib/client.js CHANGED
@@ -2725,7 +2725,7 @@ window.__ModuleLoader__.load({
2725
2725
  let text = from <= 0 && to >= this.length ? this : new TextLeaf(sliceText(this.text, from, to), Math.min(to, this.length) - Math.max(0, from));
2726
2726
  if (open & 1) {
2727
2727
  let prev = target.pop();
2728
- let joined = appendText(text.text, prev.text.slice(), 0, text.length);
2728
+ let joined = appendText$1(text.text, prev.text.slice(), 0, text.length);
2729
2729
  if (joined.length <= 32) target.push(new TextLeaf(joined, prev.length + text.length));
2730
2730
  else {
2731
2731
  let mid = joined.length >> 1;
@@ -2736,7 +2736,7 @@ window.__ModuleLoader__.load({
2736
2736
  replace(from, to, text) {
2737
2737
  if (!(text instanceof TextLeaf)) return super.replace(from, to, text);
2738
2738
  [from, to] = clip(this, from, to);
2739
- let lines = appendText(this.text, appendText(text.text, sliceText(this.text, 0, from)), to);
2739
+ let lines = appendText$1(this.text, appendText$1(text.text, sliceText(this.text, 0, from)), to);
2740
2740
  let newLen = this.length + text.length - (to - from);
2741
2741
  if (lines.length <= 32) return new TextLeaf(lines, newLen);
2742
2742
  return TextNode.from(TextLeaf.split(lines, []), newLen);
@@ -2897,7 +2897,7 @@ window.__ModuleLoader__.load({
2897
2897
  for (let line of text) length += line.length + 1;
2898
2898
  return length;
2899
2899
  }
2900
- function appendText(text, target, from = 0, to = 1e9) {
2900
+ function appendText$1(text, target, from = 0, to = 1e9) {
2901
2901
  for (let pos = 0, i = 0, first = true; i < text.length && pos <= to; i++) {
2902
2902
  let line = text[i], end = pos + line.length;
2903
2903
  if (end >= from) {
@@ -2913,7 +2913,7 @@ window.__ModuleLoader__.load({
2913
2913
  return target;
2914
2914
  }
2915
2915
  function sliceText(text, from, to) {
2916
- return appendText(text, [""], from, to);
2916
+ return appendText$1(text, [""], from, to);
2917
2917
  }
2918
2918
  var RawTextCursor = class {
2919
2919
  constructor(text, dir = 1) {
@@ -35127,127 +35127,202 @@ window.__ModuleLoader__.load({
35127
35127
  }
35128
35128
  }
35129
35129
  /**
35130
- * Splice `text` into `draft` at `caret` (replacing any live selection) with
35131
- * whitespace-aware joins and report the caret position right after the
35132
- * inserted text. `caret === null` (position unknown) appends at the end,
35133
- * exactly like the original behavior.
35130
+ * The separating space an append needs on its left — one space, but never
35131
+ * doubled against existing whitespace. Both the string append and the span
35132
+ * channel (which does no splice math of its own) obey this single rule. A blank
35133
+ * draft takes no separator: it is replaced outright.
35134
35134
  */
35135
- function spliceInsert(draft, text, caret) {
35136
- if (caret === null || draft === "") {
35137
- const next = draft.trim() === "" ? text : `${draft}${/\s$/.test(draft) ? "" : " "}${text}`;
35135
+ function leadFor(draft) {
35136
+ if (draft.trim() === "") return "";
35137
+ return /\s$/.test(draft) ? "" : " ";
35138
+ }
35139
+ /** `draft` with `text` appended behind one separating space when needed. */
35140
+ function appendText(draft, text) {
35141
+ return `${draft}${leadFor(draft)}${text}`;
35142
+ }
35143
+ /**
35144
+ * Fold one clipboard-projection offset to its detect-projection twin.
35145
+ *
35146
+ * An offset inside a chip's expansion snaps to that chip's trailing edge (the
35147
+ * host only ever replaces whole chips, never splits one). An offset exactly at
35148
+ * a chip's START resolves to the position BEFORE the chip — the host's own
35149
+ * `detectOffsetOfClipboardOffset` reads that case as "inside" and would move a
35150
+ * caret one chip too far right.
35151
+ */
35152
+ function foldClipboardOffset(draft, occurrences, offset) {
35153
+ const target = Math.max(0, Math.min(offset, draft.length));
35154
+ let shrink = 0;
35155
+ for (const occurrence of occurrences) {
35156
+ if (target >= occurrence.offset + occurrence.length) {
35157
+ shrink += occurrence.length - 1;
35158
+ continue;
35159
+ }
35160
+ if (target > occurrence.offset) return occurrence.offset - shrink + 1;
35161
+ break;
35162
+ }
35163
+ return target - shrink;
35164
+ }
35165
+ /**
35166
+ * The detect-projection offset that appends at the document end, or
35167
+ * `undefined` when it cannot be derived.
35168
+ *
35169
+ * `foldClipboardOffset` alone is not enough: a command chip (`/goal `, present
35170
+ * while `phase === 'claimed'`) collapses to one detect character but never
35171
+ * appears in `occurrences` — the host only collects REFERENCE chips.
35172
+ *
35173
+ * CORRECTION over the upstream 0.28.1 formula: the chip's clipboard text is
35174
+ * `claim.token.trimEnd()` and the separator is a SEPARATE text node, so the
35175
+ * detect projection is `1 (chip) + separator.length + rest`. Upstream folds the
35176
+ * whole `claim.token` into that one placeholder, which lands one character
35177
+ * short — a selection or `@file` appended while a slash command is claimed then
35178
+ * splices INSIDE the command's last argument word (`/goal do it` became
35179
+ * `/goal do i <payload>t`). Verified against the installed host:
35180
+ * `CommandChipNode.getTextContent()` returns the token without its separator,
35181
+ * and `insertCommand` inserts the separator as its own text node.
35182
+ */
35183
+ function appendOffset(snapshot) {
35184
+ const { draft, claim } = snapshot;
35185
+ const occurrences = snapshot.occurrences ?? [];
35186
+ const token = snapshot.phase === "claimed" && claim !== void 0 && draft.startsWith(claim.token) ? claim.token : "";
35187
+ if (token === "") return foldClipboardOffset(draft, occurrences, draft.length);
35188
+ const separator = token.slice(token.trimEnd().length);
35189
+ const rest = draft.slice(token.length);
35190
+ return 1 + separator.length + foldClipboardOffset(rest, occurrences.filter((occurrence) => occurrence.offset >= token.length).map((occurrence) => ({
35191
+ offset: occurrence.offset - token.length,
35192
+ length: occurrence.length
35193
+ })), rest.length);
35194
+ }
35195
+ /**
35196
+ * Whether the session's draft revision moved past `revision` — the only
35197
+ * trustworthy success signal after an exception swallowed the host's answer.
35198
+ */
35199
+ function revisionChanged(ctx, sessionId, revision) {
35200
+ try {
35201
+ const actx = sessionScope(ctx, sessionId);
35202
+ if (actx === void 0) return false;
35203
+ const now = conversationOf(ctx)?.input.for(actx).state.getSnapshot().draftRev;
35204
+ if (now === void 0 || revision === void 0) return false;
35205
+ return now !== revision;
35206
+ } catch {
35207
+ return false;
35208
+ }
35209
+ }
35210
+ /** One session's resolved input facade, or a logged reason why not. */
35211
+ function inputFor(ctx, sessionId, reason) {
35212
+ const actx = sessionScope(ctx, sessionId);
35213
+ if (actx === void 0) {
35214
+ console.warn(`[dsh-remote-vs] ${reason}: no session scope`, sessionId);
35215
+ return;
35216
+ }
35217
+ const conversation = conversationOf(ctx);
35218
+ if (conversation === void 0) {
35219
+ console.warn(`[dsh-remote-vs] ${reason}: conversation service unavailable`);
35220
+ return;
35221
+ }
35222
+ try {
35138
35223
  return {
35139
- draft: next,
35140
- caretAfter: next.length
35224
+ actx,
35225
+ input: conversation.input.for(actx)
35141
35226
  };
35227
+ } catch (error) {
35228
+ console.warn(`[dsh-remote-vs] ${reason}: input facade unavailable`, error);
35229
+ return;
35142
35230
  }
35143
- const prefix = draft.slice(0, caret.start);
35144
- const suffix = draft.slice(caret.end);
35145
- if (prefix === "" && suffix === "") return {
35146
- draft: text,
35147
- caretAfter: text.length
35148
- };
35149
- const left = prefix === "" || /\s$/.test(prefix) ? "" : " ";
35150
- return {
35151
- draft: `${prefix}${left}${text}${suffix === "" || /^\s/.test(suffix) || /\s$/.test(text) ? "" : " "}${suffix}`,
35152
- caretAfter: prefix.length + left.length + text.length
35153
- };
35154
35231
  }
35155
35232
  /**
35156
- * Locate the composer `<textarea>` in the conversation column: prefer the
35157
- * `data-phase`-tagged textarea (the composer's marker), falling back to any
35158
- * textarea in the column, then to a bare data-phase textarea (older host
35159
- * layouts without the column attribute). Null in jsdom-less hosts — and on
35160
- * DSH 0.2.1, whose composer is a Lexical contenteditable (the probe then
35161
- * misses and callers append at the end, matching the local explorer).
35233
+ * Mint one reference chip through the host's public `insertReference` facade —
35234
+ * the same method the native `@` picker's event listener calls, so the
35235
+ * composer shows a compact chip while the model receives `reference.text`.
35236
+ * The host runs its own admission-phase and revision guards and reports whether
35237
+ * the edit applied.
35238
+ *
35239
+ * The chip's `clipboardText` is the compact `label` by default, not the full
35240
+ * payload: other draft consumers (copy, plain projections) stay short, and the
35241
+ * full payload rides in `text` for send.
35242
+ *
35243
+ * @returns false when the host refused the insert (stale revision, frozen
35244
+ * submission phase, or no chip channel) so the caller can fall back.
35162
35245
  */
35163
- function findComposerTextarea() {
35164
- if (typeof document === "undefined") return null;
35165
- const column = document.querySelector("#root [data-slot=\"conversation\"]");
35166
- const find = (scope) => scope.querySelector("textarea[data-phase]") ?? scope.querySelector("textarea");
35167
- return column !== null ? find(column) : document.querySelector("textarea[data-phase]");
35168
- }
35169
- /**
35170
- * Resolve the composer's live caret from its DOM `<textarea>`. The draft
35171
- * store has no caret API, so the value-sync check (`el.value === draft`)
35172
- * discards stale or wrong-composer reads — a caret must never be applied
35173
- * against a draft it was not measured on.
35174
- *
35175
- * Returns null when the composer is missing, disabled/read-only, out of
35176
- * sync with the store draft, or has no measurable selection (jsdom/odd
35177
- * hosts report null selectionStart/End).
35178
- */
35179
- function probeComposerCaret(draft) {
35180
- const el = findComposerTextarea();
35181
- if (el === null || el.disabled || el.readOnly) return null;
35182
- if (el.value !== draft) return null;
35183
- let start = el.selectionStart;
35184
- let end = el.selectionEnd;
35185
- if (typeof start !== "number" || typeof end !== "number") return null;
35186
- if (!Number.isFinite(start) || !Number.isFinite(end)) return null;
35187
- start = Math.max(0, Math.min(start, draft.length));
35188
- end = Math.max(start, Math.min(end, draft.length));
35189
- return {
35190
- start,
35191
- end
35192
- };
35193
- }
35194
- /**
35195
- * Restore the composer caret to `caretIndex` after a programmatic
35196
- * `setDraft` commit. A controlled textarea update resets the caret (React
35197
- * commits the value asynchronously and the browser moves the caret to the
35198
- * start/end), so the placement is scheduled and retried across at most two
35199
- * animation frames (setTimeout fallback for jsdom), and only applied when
35200
- * the textarea still matches `expectedDraft` — a newer edit or a different
35201
- * composer wins the race untouched. The caret is clamped into the value
35202
- * bounds, mirroring how browsers clamp type-in positions.
35203
- */
35204
- function placeComposerCaretAfterInsert(expectedDraft, caretIndex) {
35205
- let remaining = 2;
35206
- let scheduled = false;
35207
- const schedule = (fn) => {
35208
- if (scheduled) return;
35209
- scheduled = true;
35210
- if (typeof requestAnimationFrame === "function") requestAnimationFrame(fn);
35211
- else setTimeout(fn, 0);
35212
- };
35213
- const place = () => {
35214
- scheduled = false;
35215
- if (remaining <= 0) return;
35216
- remaining -= 1;
35217
- const el = findComposerTextarea();
35218
- if (el === null || el.disabled || el.readOnly) return;
35219
- if (el.value !== expectedDraft) {
35220
- schedule(place);
35221
- return;
35222
- }
35223
- const clamped = Math.max(0, Math.min(caretIndex, el.value.length));
35224
- el.setSelectionRange(clamped, clamped);
35225
- };
35226
- schedule(place);
35246
+ function insertDraftReference(ctx, sessionId, reference) {
35247
+ let before;
35248
+ try {
35249
+ const resolved = inputFor(ctx, sessionId, "reference chip skipped");
35250
+ if (resolved === void 0) return false;
35251
+ const { actx, input } = resolved;
35252
+ const snapshot = input.state.getSnapshot();
35253
+ if (input.insertReference === void 0 || snapshot.draftRev === void 0) return false;
35254
+ if (snapshot.phase === "adjudicating" || snapshot.phase === "submitting") return false;
35255
+ before = snapshot.draftRev;
35256
+ const at = appendOffset(snapshot);
35257
+ if (at === void 0) return false;
35258
+ let rev = snapshot.draftRev;
35259
+ let start = at;
35260
+ if (leadFor(snapshot.draft) !== "") {
35261
+ actx.emit?.("slash/input-insert-text", {
35262
+ text: " ",
35263
+ span: {
35264
+ draftRev: rev,
35265
+ start: at,
35266
+ end: at
35267
+ }
35268
+ });
35269
+ const afterSpace = input.state.getSnapshot();
35270
+ if (afterSpace.draftRev === rev) return false;
35271
+ rev = afterSpace.draftRev ?? rev;
35272
+ start = at + 1;
35273
+ }
35274
+ const chip = {
35275
+ source: "reference",
35276
+ ref: reference.text,
35277
+ label: reference.label,
35278
+ ...reference.appearance === void 0 ? {} : { appearance: reference.appearance },
35279
+ clipboardText: reference.clipboardText ?? reference.label
35280
+ };
35281
+ return input.insertReference(chip, {
35282
+ draftRev: rev,
35283
+ start,
35284
+ end: start
35285
+ });
35286
+ } catch (error) {
35287
+ console.warn("[dsh-remote-vs] reference chip insert failed:", error);
35288
+ return revisionChanged(ctx, sessionId, before);
35289
+ }
35227
35290
  }
35228
35291
  /**
35229
- * Insert `text` into the session's composer draft at the composer's live
35230
- * caret (see {@link probeComposerCaret}), falling back to appending at the
35231
- * end when the caret cannot be resolved. Returns false — and logs — when the
35232
- * conversation service or the session scope is unavailable.
35292
+ * Append `text` to the session's composer draft. Returns false — and logs —
35293
+ * when the conversation service or the session scope is unavailable.
35294
+ *
35295
+ * A chipless draft takes the plain `setDraft` path. A draft that CARRIES chips
35296
+ * is written through `slash/input-insert-text` at the folded end offset
35297
+ * instead: `setDraft` rebuilds the document from a string and flattens every
35298
+ * chip, which quietly destroys references the user placed by hand. The same
35299
+ * span path covers a claimed `/command`, whose prefix chip is not in
35300
+ * `occurrences` (see {@link appendOffset}).
35233
35301
  */
35234
35302
  function appendToDraft(ctx, sessionId, text) {
35235
35303
  try {
35236
- const actx = sessionScope(ctx, sessionId);
35237
- if (actx === void 0) {
35238
- console.warn("[dsh-remote-vs] draft insert skipped: no session scope", sessionId);
35239
- return false;
35240
- }
35241
- const conversation = conversationOf(ctx);
35242
- if (conversation === void 0) {
35243
- console.warn("[dsh-remote-vs] draft insert skipped: conversation service unavailable");
35244
- return false;
35304
+ const resolved = inputFor(ctx, sessionId, "draft insert skipped");
35305
+ if (resolved === void 0) return false;
35306
+ const { actx, input } = resolved;
35307
+ const snapshot = input.state.getSnapshot();
35308
+ const draft = snapshot.draft;
35309
+ if ((snapshot.occurrences ?? []).length > 0 || snapshot.phase === "claimed") {
35310
+ const at = appendOffset(snapshot);
35311
+ if (snapshot.draftRev === void 0 || at === void 0) {
35312
+ console.warn("[dsh-remote-vs] draft insert skipped: chip draft without a revision");
35313
+ return false;
35314
+ }
35315
+ actx.emit?.("slash/input-insert-text", {
35316
+ text: `${leadFor(draft)}${text}`,
35317
+ span: {
35318
+ draftRev: snapshot.draftRev,
35319
+ start: at,
35320
+ end: at
35321
+ }
35322
+ });
35323
+ return input.state.getSnapshot().draftRev !== snapshot.draftRev;
35245
35324
  }
35246
- const input = conversation.input.for(actx);
35247
- const draft = input.state.getSnapshot().draft;
35248
- const { draft: next, caretAfter } = spliceInsert(draft, text, probeComposerCaret(draft));
35249
- input.setDraft(next);
35250
- placeComposerCaretAfterInsert(next, caretAfter);
35325
+ input.setDraft(appendText(draft, text));
35251
35326
  return true;
35252
35327
  } catch (error) {
35253
35328
  console.warn("[dsh-remote-vs] draft insert failed:", error);
@@ -35255,6 +35330,15 @@ window.__ModuleLoader__.load({
35255
35330
  }
35256
35331
  }
35257
35332
  /**
35333
+ * Insert one reference as a chip, degrading to its plain-text form when the
35334
+ * host has no chip channel or refuses the insert. This is the ONE place the
35335
+ * fallback policy lives: the explorer's `@` button and the viewer selection
35336
+ * popup both come through here.
35337
+ */
35338
+ function insertReferenceOrText(ctx, sessionId, reference) {
35339
+ return insertDraftReference(ctx, sessionId, reference) || appendToDraft(ctx, sessionId, reference.text);
35340
+ }
35341
+ /**
35258
35342
  * The DSH `@` spelling for one relative path, mirroring the host grammar
35259
35343
  * (`formatFileMention` in `@deepseek-ai/dsh-file-reference`): plain when
35260
35344
  * there is no whitespace, quoted when there is, and `undefined` when the
@@ -35325,12 +35409,12 @@ window.__ModuleLoader__.load({
35325
35409
  }
35326
35410
  /**
35327
35411
  * Insert one remote explorer entry into the session's composer draft. Files
35328
- * mint a structured chip like the native `@` picker
35329
- * (`insertFileReference`); directories append the folder mention as plain
35330
- * text so DSH's folder decoration and completion keep working. The caller
35331
- * owns the binding gate (the session must belong to the viewed binding —
35332
- * see `use-remote-chat-target.ts`); an unrepresentable path is a logged
35333
- * no-op, never an absolute mention.
35412
+ * mint a structured chip exactly like the native `@` picker (same facade the
35413
+ * viewer selection popup uses, with a plain-text fallback); directories append
35414
+ * the folder mention as plain text so DSH's folder decoration and completion
35415
+ * keep working. The caller owns the binding gate (the session must belong to
35416
+ * the viewed binding — see `use-remote-chat-target.ts`); an unrepresentable
35417
+ * path is a logged no-op, never an absolute mention.
35334
35418
  */
35335
35419
  function insertRemoteReference(ctx, sessionId, remoteRoot, absPath, isDir) {
35336
35420
  if (ctx === void 0) return false;
@@ -35340,55 +35424,20 @@ window.__ModuleLoader__.load({
35340
35424
  console.warn("[dsh-remote-vs] reference insert skipped: path outside the remote workspace root");
35341
35425
  return false;
35342
35426
  }
35343
- const mention = isDir ? directoryMention(relative) : mentionFor(relative, "file")?.mention;
35344
- if (mention === void 0) {
35427
+ const token = isDir ? directoryMention(relative) : mentionFor(relative, "file")?.mention;
35428
+ if (token === void 0) {
35345
35429
  console.warn("[dsh-remote-vs] reference insert skipped: path cannot be represented as a mention");
35346
35430
  return false;
35347
35431
  }
35348
- if (!isDir && insertFileReference(ctx, sessionId, relative)) return true;
35349
- return appendToDraft(ctx, sessionId, isDir ? `${mention} ` : mention);
35350
- } catch (error) {
35351
- console.warn("[dsh-remote-vs] remote-reference insert failed:", error);
35352
- return false;
35353
- }
35354
- }
35355
- /**
35356
- * Insert one FILE reference as a structured chip (like DSH's own `@` picker).
35357
- * The chip displays `@<basename>` but serializes to `@<relative path>` on
35358
- * send, so the reference stays a single link from trigger to basename.
35359
- *
35360
- * Directories keep the plain-text completion behavior (`@dir/`) through
35361
- * `insertRemoteReference`. The rc.1 picker also supports folder chips on
35362
- * explicit selection; its drill action still inserts plain text.
35363
- */
35364
- function insertFileReference(ctx, sessionId, relativePath) {
35365
- const reference = mentionFor(relativePath, "file");
35366
- if (reference === void 0) return false;
35367
- try {
35368
- const actx = sessionScope(ctx, sessionId);
35369
- if (actx === void 0) return false;
35370
- const conversation = conversationOf(ctx);
35371
- if (conversation === void 0) return false;
35372
- const input = conversation.input.for(actx);
35373
- const before = input.state.getSnapshot();
35374
- if (before.draftRev === void 0) return false;
35375
- actx.emit("slash/input-insert-reference", {
35376
- reference: {
35377
- source: "reference",
35378
- ref: reference.mention,
35379
- label: reference.label,
35380
- appearance: "file",
35381
- clipboardText: reference.mention
35382
- },
35383
- span: {
35384
- draftRev: before.draftRev,
35385
- start: before.draft.length,
35386
- end: before.draft.length
35387
- }
35432
+ if (isDir) return appendToDraft(ctx, sessionId, `${token} `);
35433
+ return insertReferenceOrText(ctx, sessionId, {
35434
+ label: mentionFor(relative, "file")?.label ?? token,
35435
+ text: token,
35436
+ clipboardText: token,
35437
+ appearance: "file"
35388
35438
  });
35389
- return input.state.getSnapshot().draftRev !== before.draftRev;
35390
35439
  } catch (error) {
35391
- console.warn("[dsh-remote-vs] file-reference insert failed:", error);
35440
+ console.warn("[dsh-remote-vs] remote-reference insert failed:", error);
35392
35441
  return false;
35393
35442
  }
35394
35443
  }
@@ -35403,14 +35452,25 @@ window.__ModuleLoader__.load({
35403
35452
  return `${rel}:${lines.start}`;
35404
35453
  }
35405
35454
  /**
35406
- * The full text appended to the composer draft for one selection.
35407
- * Over the limit the content is dropped: the plain path line is the whole
35408
- * payload (an empty fenced block would just occupy the draft).
35455
+ * The composer payload for one selection: the chip label and the model text.
35456
+ *
35457
+ * The chip reads as `rel:start-end` (compact, and it is what the draft
35458
+ * projection carries); the model receives the whole fenced block. Over the
35459
+ * limit the content is dropped and BOTH halves are the plain path line — an
35460
+ * empty fenced block would just occupy the draft. No `appearance` is set: the
35461
+ * host can make `'file'` chips openable, and a selection's `text` is not a
35462
+ * path, so a click must not hand a fenced block to the file opener.
35409
35463
  */
35410
35464
  function buildRemoteSelectionInsert(absPath, remoteRoot, lines, selected) {
35411
35465
  const header = remoteHeaderOf(remoteRoot, absPath, lines);
35412
- if (selected.length > 500) return header;
35413
- return `\`\`\`${header}\n${selected}\n\`\`\``;
35466
+ if (selected.length > 500) return {
35467
+ label: header,
35468
+ text: header
35469
+ };
35470
+ return {
35471
+ label: header,
35472
+ text: `\`\`\`${header}\n${selected}\n\`\`\``
35473
+ };
35414
35474
  }
35415
35475
  //#endregion
35416
35476
  //#region src/client/selection-popup.ts
@@ -37485,7 +37545,7 @@ Integer Float Double Long Int32 Int64 Uint8 uint32_t int32_t uint64_t int64_t si
37485
37545
  onCommit: (insert) => {
37486
37546
  const ctx = ctxRef.current;
37487
37547
  const sessionId = targetRef.current.sessionId;
37488
- if (ctx !== void 0 && sessionId !== void 0) appendToDraft(ctx, sessionId, insert);
37548
+ if (ctx !== void 0 && sessionId !== void 0) insertReferenceOrText(ctx, sessionId, insert);
37489
37549
  },
37490
37550
  getSurface: () => hostRef.current
37491
37551
  });
@@ -38061,7 +38121,7 @@ Integer Float Double Long Int32 Int64 Uint8 uint32_t int32_t uint64_t int64_t si
38061
38121
  const primary = host.querySelectorAll("[class*=\"rvs-ck-\"]").length;
38062
38122
  const fallback = host.querySelectorAll("span[class^=\"rvs-t-\"]").length;
38063
38123
  const count = primary > 0 ? primary : fallback;
38064
- console.info(`[dsh-remote-vs] build 1027-1824 · ${source} · colored tokens: ${count} (${propsRef.current.path})`);
38124
+ console.info(`[dsh-remote-vs] build 1027-1916 · ${source} · colored tokens: ${count} (${propsRef.current.path})`);
38065
38125
  propsRef.current.onTokens?.(count);
38066
38126
  };
38067
38127
  const armFallback = () => {
@@ -43902,8 +43962,8 @@ Integer Float Double Long Int32 Int64 Uint8 uint32_t int32_t uint64_t int64_t si
43902
43962
  }),
43903
43963
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
43904
43964
  className: "rvs-build",
43905
- title: `dsh-remote-vs build 1027-1824`,
43906
- children: "1027-1824"
43965
+ title: `dsh-remote-vs build 1027-1916`,
43966
+ children: "1027-1916"
43907
43967
  }),
43908
43968
  tokenCount !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
43909
43969
  className: "rvs-build",