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 +231 -171
- package/lib/types/client/composer.d.ts +158 -75
- package/lib/types/client/selection-popup.d.ts +8 -8
- package/package.json +1 -1
- package/src/client/CodeEditor.tsx +6 -3
- package/src/client/composer.ts +329 -220
- package/src/client/selection-popup.ts +12 -12
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
|
-
*
|
|
35131
|
-
*
|
|
35132
|
-
*
|
|
35133
|
-
*
|
|
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
|
|
35136
|
-
if (
|
|
35137
|
-
|
|
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
|
-
|
|
35140
|
-
|
|
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
|
-
*
|
|
35157
|
-
*
|
|
35158
|
-
*
|
|
35159
|
-
*
|
|
35160
|
-
*
|
|
35161
|
-
*
|
|
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
|
|
35164
|
-
|
|
35165
|
-
|
|
35166
|
-
|
|
35167
|
-
|
|
35168
|
-
|
|
35169
|
-
|
|
35170
|
-
|
|
35171
|
-
|
|
35172
|
-
|
|
35173
|
-
|
|
35174
|
-
|
|
35175
|
-
|
|
35176
|
-
|
|
35177
|
-
|
|
35178
|
-
|
|
35179
|
-
|
|
35180
|
-
|
|
35181
|
-
|
|
35182
|
-
|
|
35183
|
-
|
|
35184
|
-
|
|
35185
|
-
|
|
35186
|
-
|
|
35187
|
-
|
|
35188
|
-
|
|
35189
|
-
|
|
35190
|
-
|
|
35191
|
-
|
|
35192
|
-
|
|
35193
|
-
|
|
35194
|
-
|
|
35195
|
-
|
|
35196
|
-
|
|
35197
|
-
|
|
35198
|
-
|
|
35199
|
-
|
|
35200
|
-
|
|
35201
|
-
|
|
35202
|
-
|
|
35203
|
-
|
|
35204
|
-
|
|
35205
|
-
|
|
35206
|
-
|
|
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
|
-
*
|
|
35230
|
-
*
|
|
35231
|
-
*
|
|
35232
|
-
*
|
|
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
|
|
35237
|
-
if (
|
|
35238
|
-
|
|
35239
|
-
|
|
35240
|
-
|
|
35241
|
-
|
|
35242
|
-
|
|
35243
|
-
|
|
35244
|
-
|
|
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
|
-
|
|
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
|
-
*
|
|
35330
|
-
* text so DSH's folder decoration and completion
|
|
35331
|
-
* owns the binding gate (the session must belong to
|
|
35332
|
-
* see `use-remote-chat-target.ts`); an unrepresentable
|
|
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
|
|
35344
|
-
if (
|
|
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 (
|
|
35349
|
-
return
|
|
35350
|
-
|
|
35351
|
-
|
|
35352
|
-
|
|
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]
|
|
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
|
|
35407
|
-
*
|
|
35408
|
-
*
|
|
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
|
|
35413
|
-
|
|
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)
|
|
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-
|
|
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-
|
|
43906
|
-
children: "1027-
|
|
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",
|