@north-light/crouter 0.3.221 → 0.3.223
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/api/client.d.ts +21 -1
- package/dist/api/client.js +34 -0
- package/dist/api/dto/chat-inventory.d.ts +13 -0
- package/dist/api/dto/human-requests.d.ts +88 -0
- package/dist/api/dto/human-requests.js +4 -0
- package/dist/api/dto/human.d.ts +3 -0
- package/dist/api/dto/reviews.d.ts +2 -0
- package/dist/api/index.d.ts +1 -0
- package/dist/api/index.js +1 -0
- package/dist/api/routes.d.ts +7 -0
- package/dist/api/routes.js +10 -0
- package/dist/builtin-memory/00-runtime-base/00-authoring.md +31 -0
- package/dist/builtin-memory/00-runtime-base/01-escalation.md +14 -0
- package/dist/builtin-memory/{insights/listen.md → 00-runtime-base/02-insight-capture.md} +1 -0
- package/dist/builtin-memory/02-turn-lifecycle/00-ending-a-turn.md +27 -0
- package/dist/builtin-memory/{02-lifecycle/01-resident.md → 02-turn-lifecycle/02-resident.md} +5 -0
- package/dist/builtin-memory/04-base-worker.md +4 -8
- package/dist/builtin-memory/04-orchestration-kernel.md +1 -1
- package/dist/builtin-memory/05-kinds/advisor/01-orchestrator.md +1 -0
- package/dist/builtin-memory/05-kinds/advisor/advice-contract.md +1 -0
- package/dist/builtin-memory/05-kinds/design/00-base.md +2 -1
- package/dist/builtin-memory/05-kinds/design/01-orchestrator.md +2 -1
- package/dist/builtin-memory/05-kinds/design/design-contract.md +19 -0
- package/dist/builtin-memory/05-kinds/developer/00-base.md +1 -0
- package/dist/builtin-memory/05-kinds/developer/01-orchestrator.md +1 -0
- package/dist/builtin-memory/05-kinds/explore/00-base.md +1 -0
- package/dist/builtin-memory/05-kinds/explore/01-orchestrator.md +1 -0
- package/dist/builtin-memory/05-kinds/general/00-base.md +1 -0
- package/dist/builtin-memory/05-kinds/plan/00-base.md +2 -1
- package/dist/builtin-memory/05-kinds/plan/01-orchestrator.md +2 -1
- package/dist/builtin-memory/05-kinds/plan/plan-contract.md +28 -0
- package/dist/builtin-memory/05-kinds/plan/reviewers/architecture-fit.md +1 -0
- package/dist/builtin-memory/05-kinds/plan/reviewers/code-smells.md +1 -0
- package/dist/builtin-memory/05-kinds/plan/reviewers/lens-contract.md +1 -0
- package/dist/builtin-memory/05-kinds/plan/reviewers/pattern-consistency.md +1 -0
- package/dist/builtin-memory/05-kinds/plan/reviewers/requirements-coverage.md +1 -0
- package/dist/builtin-memory/05-kinds/plan/reviewers/security.md +1 -0
- package/dist/builtin-memory/05-kinds/review/00-base.md +1 -0
- package/dist/builtin-memory/05-kinds/review/01-orchestrator.md +1 -0
- package/dist/builtin-memory/05-kinds/review/companion/00-base.md +1 -0
- package/dist/builtin-memory/05-kinds/review/security-findings.md +1 -0
- package/dist/builtin-memory/05-kinds/spec/00-base.md +4 -3
- package/dist/builtin-memory/05-kinds/spec/01-orchestrator.md +1 -0
- package/dist/builtin-memory/05-kinds/spec/requirements.md +1 -0
- package/dist/builtin-memory/design/guide.md +35 -0
- package/dist/builtin-memory/design/roadmap.md +21 -0
- package/dist/builtin-memory/insights/capture.md +1 -1
- package/dist/builtin-memory/internal/memory-loading.md +4 -4
- package/dist/builtin-memory/internal/plugins.md +10 -1
- package/dist/builtin-memory/internal/storage-tiers.md +1 -1
- package/dist/builtin-memory/plan/roadmap.md +6 -28
- package/dist/builtin-memory/spec/guide.md +19 -8
- package/dist/builtin-pi-packages/pi-crtr-extensions/extensions/memory-slash-commands.ts +28 -15
- package/dist/clients/attach/render/markdown-source.js +106 -1
- package/dist/clients/attach/session/file-links.d.ts +13 -4
- package/dist/clients/attach/session/file-links.js +54 -58
- package/dist/clients/attach/viewer.js +545 -543
- package/dist/clients/inbox/controller.js +1 -1
- package/dist/clients/inbox/page-adapter.js +2 -1
- package/dist/clients/inbox/resolve.d.ts +1 -0
- package/dist/clients/inbox/review/review-client.js +3 -1
- package/dist/clients/inbox/tui/panel.js +23 -4
- package/dist/clients/inbox/tui/render.js +6 -0
- package/dist/clients/inbox/tui/types.d.ts +8 -0
- package/dist/commands/__tests__/human.test.js +2 -2
- package/dist/commands/human/request.d.ts +2 -0
- package/dist/commands/human/request.js +281 -0
- package/dist/commands/human.js +5 -2
- package/dist/commands/memory/shared.d.ts +2 -2
- package/dist/commands/memory/shared.js +11 -6
- package/dist/commands/pkg/browse/doc-view.js +2 -0
- package/dist/commands/sys/config.js +2 -2
- package/dist/commands/sys/doctor.js +54 -2
- package/dist/core/__tests__/broker-extension-canvas-db-boundary.test.js +7 -4
- package/dist/core/__tests__/fixtures/memory-slash-live-probe.d.ts +1 -0
- package/dist/core/__tests__/fixtures/memory-slash-live-probe.js +71 -0
- package/dist/core/__tests__/human-action-delivery.test.d.ts +1 -0
- package/dist/core/__tests__/human-action-delivery.test.js +140 -0
- package/dist/core/__tests__/human-actions.test.d.ts +1 -0
- package/dist/core/__tests__/human-actions.test.js +116 -0
- package/dist/core/__tests__/inline-memory-refs.test.js +1 -1
- package/dist/core/__tests__/profile-project-memory-delivery.test.js +70 -3
- package/dist/core/__tests__/prospective-inventory-capability-parity.test.d.ts +1 -0
- package/dist/core/__tests__/prospective-inventory-capability-parity.test.js +91 -0
- package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.d.ts +1 -0
- package/dist/core/__tests__/seam/memory-slash-node-relative-inventory.test.js +127 -0
- package/dist/core/__tests__/seam/prospective-inventory-stdout.test.d.ts +1 -0
- package/dist/core/__tests__/seam/prospective-inventory-stdout.test.js +31 -0
- package/dist/core/canvas/db.js +23 -0
- package/dist/core/canvas/human-deliveries.d.ts +53 -0
- package/dist/core/canvas/human-deliveries.js +75 -0
- package/dist/core/config.d.ts +13 -1
- package/dist/core/config.js +51 -1
- package/dist/core/feed/inbox.d.ts +6 -0
- package/dist/core/feed/inbox.js +9 -1
- package/dist/core/human/action-binding.d.ts +21 -0
- package/dist/core/human/action-binding.js +40 -0
- package/dist/core/human/completion.d.ts +38 -0
- package/dist/core/human/completion.js +27 -0
- package/dist/core/human/convention.d.ts +2 -0
- package/dist/core/human/convention.js +2 -0
- package/dist/core/human/tickets.d.ts +25 -6
- package/dist/core/human/tickets.js +19 -13
- package/dist/core/human/types.d.ts +5 -0
- package/dist/core/human-actions.d.ts +25 -0
- package/dist/core/human-actions.js +101 -0
- package/dist/core/memory-resolver.js +1 -1
- package/dist/core/profiles/select.d.ts +2 -0
- package/dist/core/profiles/select.js +21 -4
- package/dist/core/runtime/broker/frame-dispatch.js +2 -5
- package/dist/core/runtime/broker-inventory.d.ts +1 -2
- package/dist/core/runtime/broker-inventory.js +2 -77
- package/dist/core/runtime/broker-persona-guidance.js +1 -1
- package/dist/core/runtime/broker.js +4 -4
- package/dist/core/runtime/chat-inventory-rows.d.ts +8 -0
- package/dist/core/runtime/chat-inventory-rows.js +105 -0
- package/dist/core/runtime/command-surface.d.ts +8 -3
- package/dist/core/runtime/command-surface.js +42 -6
- package/dist/core/runtime/launch-target.d.ts +25 -0
- package/dist/core/runtime/launch-target.js +54 -0
- package/dist/core/runtime/persona.js +3 -3
- package/dist/core/runtime/prospective-inventory-cli.d.ts +1 -0
- package/dist/core/runtime/prospective-inventory-cli.js +61 -0
- package/dist/core/runtime/prospective-inventory.d.ts +10 -0
- package/dist/core/runtime/prospective-inventory.js +88 -0
- package/dist/core/runtime/spawn.d.ts +3 -1
- package/dist/core/runtime/spawn.js +5 -3
- package/dist/core/substrate/frontmatter-validation.d.ts +2 -5
- package/dist/core/substrate/frontmatter-validation.js +8 -4
- package/dist/core/substrate/gate.d.ts +4 -1
- package/dist/core/substrate/gate.js +5 -0
- package/dist/core/substrate/on-read.js +21 -32
- package/dist/core/substrate/render-node.d.ts +3 -2
- package/dist/core/substrate/render-node.js +3 -2
- package/dist/core/substrate/render.js +64 -37
- package/dist/core/substrate/schema.d.ts +17 -8
- package/dist/core/substrate/schema.js +14 -10
- package/dist/core/substrate/surface-match.d.ts +8 -7
- package/dist/core/substrate/surface-match.js +15 -14
- package/dist/core/user-settings.d.ts +4 -0
- package/dist/core/user-settings.js +1 -0
- package/dist/daemon/api/__tests__/profile-launch-gates.test.js +52 -3
- package/dist/daemon/api/handlers/human-requests.d.ts +2 -0
- package/dist/daemon/api/handlers/human-requests.js +409 -0
- package/dist/daemon/api/handlers/human.js +3 -0
- package/dist/daemon/api/handlers/inbox.js +3 -0
- package/dist/daemon/api/handlers/nodes.d.ts +1 -3
- package/dist/daemon/api/handlers/nodes.js +11 -46
- package/dist/daemon/api/handlers/prospective-chat-inventory.d.ts +2 -0
- package/dist/daemon/api/handlers/prospective-chat-inventory.js +59 -0
- package/dist/daemon/api/handlers/reviews.js +10 -2
- package/dist/daemon/api/server.js +4 -0
- package/dist/daemon/crtrd.js +6 -0
- package/dist/daemon/human/deliver-action.d.ts +16 -0
- package/dist/daemon/human/deliver-action.js +168 -0
- package/dist/daemon/human/finish.d.ts +8 -5
- package/dist/daemon/human/finish.js +45 -6
- package/dist/daemon/human/sweep.js +4 -1
- package/dist/daemon/reconcilers/human-delivery-lane.d.ts +10 -0
- package/dist/daemon/reconcilers/human-delivery-lane.js +41 -0
- package/dist/daemon/review/finish.d.ts +8 -3
- package/dist/daemon/review/finish.js +19 -1
- package/dist/types.d.ts +8 -0
- package/dist/types.js +1 -0
- package/package.json +1 -1
- package/runtime.lock.json +2 -2
- package/dist/builtin-memory/00-runtime-base.md +0 -55
- package/dist/builtin-memory/design.md +0 -55
- /package/dist/builtin-memory/{02-lifecycle/00-terminal.md → 02-turn-lifecycle/01-terminal.md} +0 -0
|
@@ -22,6 +22,7 @@
|
|
|
22
22
|
// GLYPHS. Private-use `U+XXXX` references become their glyphs (see
|
|
23
23
|
// glyph-codepoints.ts), so an agent that cannot type a Nerd Font character can
|
|
24
24
|
// still put one on screen.
|
|
25
|
+
import { pathToFileURL } from 'node:url';
|
|
25
26
|
import { expandGlyphCodepoints } from './glyph-codepoints.js';
|
|
26
27
|
const ATX_HEADING = /^(\s{0,3})(#{3,6})(?:[ \t]+|$)(.*?)([ \t]+#+[ \t]*)?$/;
|
|
27
28
|
const FENCE_OPEN = /^\s{0,3}(`{3,}|~{3,})/;
|
|
@@ -126,7 +127,111 @@ export function styleAttachMarkdownSource(markdown) {
|
|
|
126
127
|
* message keeps `styleAttachMarkdownSource` alone — the `U+XXXX` escape hatch
|
|
127
128
|
* exists for agents that cannot type a Nerd Font character. */
|
|
128
129
|
export function styleAttachAgentMarkdown(markdown) {
|
|
129
|
-
return expandGlyphCodepoints(styleAttachMarkdownSource(markdown));
|
|
130
|
+
return expandGlyphCodepoints(styleAttachMarkdownSource(rewriteAbsoluteFileLinks(markdown)));
|
|
131
|
+
}
|
|
132
|
+
/** Give iTerm a hidden fragment so its Semantic History action receives the local target. */
|
|
133
|
+
function rewriteAbsoluteFileLinks(markdown) {
|
|
134
|
+
let fence;
|
|
135
|
+
return markdown.split('\n').map((line) => {
|
|
136
|
+
const fenceMatch = FENCE_OPEN.exec(line);
|
|
137
|
+
if (fence !== undefined) {
|
|
138
|
+
if (fenceMatch?.[1][0] === fence)
|
|
139
|
+
fence = undefined;
|
|
140
|
+
return line;
|
|
141
|
+
}
|
|
142
|
+
if (fenceMatch) {
|
|
143
|
+
fence = fenceMatch[1][0];
|
|
144
|
+
return line;
|
|
145
|
+
}
|
|
146
|
+
return rewriteInlineFileLinks(line);
|
|
147
|
+
}).join('\n');
|
|
148
|
+
}
|
|
149
|
+
function rewriteInlineFileLinks(line) {
|
|
150
|
+
let result = '';
|
|
151
|
+
let rest = line;
|
|
152
|
+
while (rest !== '') {
|
|
153
|
+
const opening = rest.match(/`+/);
|
|
154
|
+
const prose = opening === null ? rest : rest.slice(0, opening.index);
|
|
155
|
+
result += rewriteProseFileLinks(prose);
|
|
156
|
+
if (opening === null)
|
|
157
|
+
break;
|
|
158
|
+
const delimiter = opening[0];
|
|
159
|
+
const end = rest.indexOf(delimiter, prose.length + delimiter.length);
|
|
160
|
+
if (end === -1)
|
|
161
|
+
return result + rest.slice(prose.length);
|
|
162
|
+
result += rest.slice(prose.length, end + delimiter.length);
|
|
163
|
+
rest = rest.slice(end + delimiter.length);
|
|
164
|
+
}
|
|
165
|
+
return result;
|
|
166
|
+
}
|
|
167
|
+
function rewriteProseFileLinks(prose) {
|
|
168
|
+
let result = '';
|
|
169
|
+
let index = 0;
|
|
170
|
+
while (index < prose.length) {
|
|
171
|
+
const start = prose.indexOf('[', index);
|
|
172
|
+
if (start === -1)
|
|
173
|
+
return result + prose.slice(index);
|
|
174
|
+
const link = parseLocalMarkdownLink(prose, start);
|
|
175
|
+
if (link === undefined) {
|
|
176
|
+
result += prose.slice(index, start + 1);
|
|
177
|
+
index = start + 1;
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
result += prose.slice(index, start) + `[${link.label}](${pathToFileURL(link.path).href}#crtr-file-open)`;
|
|
181
|
+
index = link.end;
|
|
182
|
+
}
|
|
183
|
+
return result;
|
|
184
|
+
}
|
|
185
|
+
function parseLocalMarkdownLink(line, start) {
|
|
186
|
+
const labelEnd = closingDelimiter(line, start + 1, ']');
|
|
187
|
+
if (labelEnd === undefined || line[labelEnd + 1] !== '(')
|
|
188
|
+
return undefined;
|
|
189
|
+
const destinationStart = labelEnd + 2;
|
|
190
|
+
if (line[destinationStart] === '<') {
|
|
191
|
+
const destinationEnd = closingDelimiter(line, destinationStart + 1, '>');
|
|
192
|
+
if (destinationEnd === undefined || line[destinationEnd + 1] !== ')')
|
|
193
|
+
return undefined;
|
|
194
|
+
const path = localPathFromDestination(line.slice(destinationStart + 1, destinationEnd));
|
|
195
|
+
return path === undefined ? undefined : { label: line.slice(start + 1, labelEnd), path, end: destinationEnd + 2 };
|
|
196
|
+
}
|
|
197
|
+
let depth = 0;
|
|
198
|
+
for (let index = destinationStart; index < line.length; index++) {
|
|
199
|
+
if (line[index] === '\\') {
|
|
200
|
+
index++;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (line[index] === '(') {
|
|
204
|
+
depth++;
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
if (line[index] !== ')' || depth-- > 0)
|
|
208
|
+
continue;
|
|
209
|
+
const path = localPathFromDestination(line.slice(destinationStart, index));
|
|
210
|
+
return path === undefined ? undefined : { label: line.slice(start + 1, labelEnd), path, end: index + 1 };
|
|
211
|
+
}
|
|
212
|
+
return undefined;
|
|
213
|
+
}
|
|
214
|
+
function closingDelimiter(text, start, delimiter) {
|
|
215
|
+
for (let index = start; index < text.length; index++) {
|
|
216
|
+
if (text[index] === '\\') {
|
|
217
|
+
index++;
|
|
218
|
+
continue;
|
|
219
|
+
}
|
|
220
|
+
if (text[index] === delimiter)
|
|
221
|
+
return index;
|
|
222
|
+
}
|
|
223
|
+
return undefined;
|
|
224
|
+
}
|
|
225
|
+
function localPathFromDestination(destination) {
|
|
226
|
+
const unescaped = destination.replace(/\\([!"#$%&'()*+,./:;<=>?@[\\\]^_`{|}~-])/g, '$1');
|
|
227
|
+
let path = unescaped;
|
|
228
|
+
try {
|
|
229
|
+
path = decodeURIComponent(unescaped);
|
|
230
|
+
}
|
|
231
|
+
catch {
|
|
232
|
+
// A literal percent is legal in a path but not in URI decoding.
|
|
233
|
+
}
|
|
234
|
+
return path.startsWith('/') ? path : undefined;
|
|
130
235
|
}
|
|
131
236
|
/** Copy a pi message for terminal rendering and decorate only Markdown-bearing
|
|
132
237
|
* text/thinking blocks. The broker's source event is never mutated. */
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export
|
|
3
|
-
|
|
1
|
+
/** A local file requested through iTerm Semantic History. */
|
|
2
|
+
export interface FileOpenInput {
|
|
3
|
+
file: string | undefined;
|
|
4
|
+
remaining: string;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Strip the private iTerm Semantic History input and return its local path.
|
|
8
|
+
* iTerm expands `\\1` as a shell-escaped word, so decode that representation
|
|
9
|
+
* without ever evaluating it as shell input.
|
|
10
|
+
*/
|
|
11
|
+
export declare function extractFileOpenInput(data: string): FileOpenInput | undefined;
|
|
12
|
+
export type LinkedFileOpenResult = 'opened' | 'missing' | 'failed';
|
|
4
13
|
/** Replace this local viewer pane with Neovim, then reattach it when Neovim exits. */
|
|
5
14
|
export declare function openLinkedFileInPane(opts: {
|
|
6
|
-
|
|
15
|
+
file: string;
|
|
7
16
|
pane: string;
|
|
8
17
|
cwd: string;
|
|
9
18
|
nodeId: string;
|
|
@@ -1,72 +1,68 @@
|
|
|
1
|
-
// session/file-links.ts —
|
|
1
|
+
// session/file-links.ts — iTerm Semantic History file-open bridge.
|
|
2
2
|
//
|
|
3
|
-
//
|
|
4
|
-
//
|
|
5
|
-
// and OSC-8 boundaries have all already been composed there.
|
|
3
|
+
// iTerm sends the clicked path through a private input sequence. The viewer
|
|
4
|
+
// validates it, replaces its pane with Neovim, then reattaches after exit.
|
|
6
5
|
import { existsSync } from 'node:fs';
|
|
7
|
-
import { fileURLToPath } from 'node:url';
|
|
8
|
-
import { walkRow } from '../ansi-cells.js';
|
|
9
6
|
import { respawnPaneInBackground, shellQuote, viewerSplitEnv } from '../../../core/runtime/placement-tmux.js';
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
7
|
+
const FILE_OPEN_PREFIX = '\x1b_crtr-file-open;';
|
|
8
|
+
const STRING_TERMINATOR = '\x1b\\';
|
|
9
|
+
/**
|
|
10
|
+
* Strip the private iTerm Semantic History input and return its local path.
|
|
11
|
+
* iTerm expands `\\1` as a shell-escaped word, so decode that representation
|
|
12
|
+
* without ever evaluating it as shell input.
|
|
13
|
+
*/
|
|
14
|
+
export function extractFileOpenInput(data) {
|
|
15
|
+
const start = data.indexOf(FILE_OPEN_PREFIX);
|
|
16
|
+
if (start === -1)
|
|
13
17
|
return undefined;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
return scanned.uri;
|
|
21
|
-
}
|
|
22
|
-
return undefined;
|
|
18
|
+
const pathStart = start + FILE_OPEN_PREFIX.length;
|
|
19
|
+
const end = data.indexOf(STRING_TERMINATOR, pathStart);
|
|
20
|
+
if (end === -1)
|
|
21
|
+
return undefined;
|
|
22
|
+
const file = decodeShellEscapedPath(data.slice(pathStart, end));
|
|
23
|
+
return { file, remaining: data.slice(0, start) + data.slice(end + STRING_TERMINATOR.length) };
|
|
23
24
|
}
|
|
24
|
-
function
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
walkRow(line, {
|
|
28
|
-
onEscape: (escape) => {
|
|
29
|
-
const osc8 = parseOsc8(escape);
|
|
30
|
-
if (osc8 !== null)
|
|
31
|
-
activeUri = osc8 === '' ? undefined : osc8;
|
|
32
|
-
},
|
|
33
|
-
onGlyph: (glyph) => {
|
|
34
|
-
if (uri !== undefined || hitColumn === undefined || activeUri === undefined || glyph.width === 0)
|
|
35
|
-
return;
|
|
36
|
-
const cell = hitColumn - 1;
|
|
37
|
-
if (cell >= glyph.cell && cell < glyph.cell + glyph.width)
|
|
38
|
-
uri = activeUri;
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
return { activeUri, uri };
|
|
25
|
+
function decodeShellEscapedPath(value) {
|
|
26
|
+
const decoded = value.startsWith("'") ? decodeSingleQuotedPath(value) : decodeBackslashPath(value);
|
|
27
|
+
return decoded !== undefined && decoded.startsWith('/') && !/[\x00-\x1f\x7f]/.test(decoded) ? decoded : undefined;
|
|
42
28
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
29
|
+
function decodeSingleQuotedPath(value) {
|
|
30
|
+
let result = '';
|
|
31
|
+
let index = 1;
|
|
32
|
+
while (true) {
|
|
33
|
+
const end = value.indexOf("'", index);
|
|
34
|
+
if (end === -1)
|
|
35
|
+
return undefined;
|
|
36
|
+
result += value.slice(index, end);
|
|
37
|
+
index = end + 1;
|
|
38
|
+
if (index === value.length)
|
|
39
|
+
return result;
|
|
40
|
+
if (value.slice(index, index + 3) !== "\\''")
|
|
41
|
+
return undefined;
|
|
42
|
+
result += "'";
|
|
43
|
+
index += 3;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function decodeBackslashPath(value) {
|
|
47
|
+
let result = '';
|
|
48
|
+
for (let index = 0; index < value.length; index++) {
|
|
49
|
+
if (value[index] !== '\\') {
|
|
50
|
+
result += value[index];
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
const escaped = value[++index];
|
|
54
|
+
if (escaped === undefined)
|
|
55
|
+
return undefined;
|
|
56
|
+
result += escaped;
|
|
57
|
+
}
|
|
58
|
+
return result;
|
|
53
59
|
}
|
|
54
60
|
/** Replace this local viewer pane with Neovim, then reattach it when Neovim exits. */
|
|
55
61
|
export function openLinkedFileInPane(opts) {
|
|
56
|
-
|
|
57
|
-
try {
|
|
58
|
-
const url = new URL(opts.uri);
|
|
59
|
-
if (url.protocol !== 'file:')
|
|
60
|
-
return 'invalid';
|
|
61
|
-
file = fileURLToPath(url);
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
return 'invalid';
|
|
65
|
-
}
|
|
66
|
-
if (!existsSync(file))
|
|
62
|
+
if (!existsSync(opts.file))
|
|
67
63
|
return 'missing';
|
|
68
64
|
const attach = `crtr surface attach to ${shellQuote(opts.nodeId)}${opts.observer ? ' --observer' : ''}`;
|
|
69
|
-
const command = `nvim ${shellQuote(file)} || :; exec ${attach}`;
|
|
65
|
+
const command = `nvim ${shellQuote(opts.file)} || :; exec ${attach}`;
|
|
70
66
|
opts.beforeRespawn();
|
|
71
67
|
return respawnPaneInBackground({ pane: opts.pane, cwd: opts.cwd, env: viewerSplitEnv(), command }) ? 'opened' : 'failed';
|
|
72
68
|
}
|