@north-light/crouter 0.3.277 → 0.3.278
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/clients/attach/input/capabilities.js +2 -1
- package/dist/clients/attach/slash/dispatch.js +42 -19
- package/dist/clients/attach/viewer.js +523 -523
- package/dist/commands/canvas-browse.js +2 -2
- package/dist/core/canvas/browse/app.d.ts +1 -1
- package/dist/core/canvas/browse/app.js +32 -7
- package/dist/core/canvas/browse/render.d.ts +17 -2
- package/dist/core/canvas/browse/render.js +342 -242
- package/dist/core/canvas/render-source.d.ts +26 -0
- package/dist/core/canvas/render-source.js +73 -0
- package/dist/core/keybindings/catalog.d.ts +2 -2
- package/dist/core/keybindings/catalog.js +1 -0
- package/dist/core/runtime/tmux-bindings.js +1 -1
- package/package.json +1 -1
- package/runtime.lock.json +2 -2
|
@@ -103,6 +103,15 @@ export interface DashboardRow {
|
|
|
103
103
|
/** Lazy-enrichment guard (internal): true once loadPreview has read goal + the
|
|
104
104
|
* session (prompts + lastAssistant). Idempotency marker for the selected row. */
|
|
105
105
|
previewLoaded?: boolean;
|
|
106
|
+
/** The node's conversation as ORDERED user/assistant turns — what the preview panel
|
|
107
|
+
* paints as a chat transcript. Populated LAZILY by loadTranscript for the SELECTED
|
|
108
|
+
* row only (never on the background warm pass): one transcript per row is a few KB,
|
|
109
|
+
* and holding one for every node on a multi-thousand-node canvas is what `prompts`
|
|
110
|
+
* and `lastAssistant` exist to avoid. Undefined until asked for; an empty array
|
|
111
|
+
* means "read, and the node has no session turns". */
|
|
112
|
+
transcript?: TranscriptTurn[];
|
|
113
|
+
/** Lazy guard (internal): true once loadTranscript has read the session for this row. */
|
|
114
|
+
transcriptLoaded?: boolean;
|
|
106
115
|
/** The source `NodeRow` this row was built from (dashboardRowFromNodeRow only).
|
|
107
116
|
* Carries every column listNodes already fetched — the runtime fields
|
|
108
117
|
* (host_kind/parent/waiting_for/final_report/finalized_at/pi_pid) plus the
|
|
@@ -132,6 +141,17 @@ interface SessionParts {
|
|
|
132
141
|
lastAssistant?: string;
|
|
133
142
|
}
|
|
134
143
|
export declare function readSessionParts(sessionFile: string | null | undefined): SessionParts;
|
|
144
|
+
/** One conversation turn as the preview panel paints it. */
|
|
145
|
+
export interface TranscriptTurn {
|
|
146
|
+
role: 'user' | 'assistant';
|
|
147
|
+
text: string;
|
|
148
|
+
}
|
|
149
|
+
/** The node's conversation as ordered user/assistant turns, newest-last, capped to
|
|
150
|
+
* the last TRANSCRIPT_TURNS. Generated context cards are dropped (they are runtime
|
|
151
|
+
* scaffolding, not something the user or the agent said) and so are assistant turns
|
|
152
|
+
* with no text (tool-only turns), so the result reads as a chat rather than a log.
|
|
153
|
+
* One file read; never throws; empty for a node that was never revived. */
|
|
154
|
+
export declare function readTranscript(sessionFile: string | null | undefined): TranscriptTurn[];
|
|
135
155
|
/** Did this node's engine ever PRODUCE something — an assistant message with real
|
|
136
156
|
* text, a tool call, or non-empty reasoning? The signal that a node did work and
|
|
137
157
|
* is not an empty shell. A never-revived node (no session file) is trivially
|
|
@@ -174,4 +194,10 @@ export declare function enrichRowsFromSource(_source: CanvasSource, rows: Dashbo
|
|
|
174
194
|
/** goal (initial-prompt.md) and session parts are local disk reads — suppressed
|
|
175
195
|
* to undefined for a remote source. */
|
|
176
196
|
export declare function loadPreviewFromSource(source: CanvasSource, row: DashboardRow): Promise<DashboardRow>;
|
|
197
|
+
/** Fold the ordered conversation onto `row` — the preview panel's chat body. Kept
|
|
198
|
+
* OUT of loadPreviewFromSource because that runs over every row on the background
|
|
199
|
+
* warm pass, and a per-row transcript across a whole canvas is exactly the memory
|
|
200
|
+
* cost the capped `prompts` string avoids. Call it for the selected row only.
|
|
201
|
+
* Remote sources have no local session file, so the transcript stays empty. */
|
|
202
|
+
export declare function loadTranscriptFromSource(source: CanvasSource, row: DashboardRow): Promise<DashboardRow>;
|
|
177
203
|
export {};
|
|
@@ -307,6 +307,61 @@ export function readSessionParts(sessionFile) {
|
|
|
307
307
|
}
|
|
308
308
|
return { prompts, lastAssistant };
|
|
309
309
|
}
|
|
310
|
+
/** How many trailing turns the transcript keeps. A preview panel can paint a few
|
|
311
|
+
* dozen lines, and search only ever windows to a match, so the whole history is
|
|
312
|
+
* never needed — but the window has to be wide enough that a match found in
|
|
313
|
+
* `prompts` (which spans the whole session) is usually still present here. */
|
|
314
|
+
const TRANSCRIPT_TURNS = 120;
|
|
315
|
+
const TRANSCRIPT_MSG_CAP = 4096;
|
|
316
|
+
/** The node's conversation as ordered user/assistant turns, newest-last, capped to
|
|
317
|
+
* the last TRANSCRIPT_TURNS. Generated context cards are dropped (they are runtime
|
|
318
|
+
* scaffolding, not something the user or the agent said) and so are assistant turns
|
|
319
|
+
* with no text (tool-only turns), so the result reads as a chat rather than a log.
|
|
320
|
+
* One file read; never throws; empty for a node that was never revived. */
|
|
321
|
+
export function readTranscript(sessionFile) {
|
|
322
|
+
if (sessionFile === undefined || sessionFile === null || sessionFile === '')
|
|
323
|
+
return [];
|
|
324
|
+
let lines;
|
|
325
|
+
try {
|
|
326
|
+
if (!existsSync(sessionFile))
|
|
327
|
+
return [];
|
|
328
|
+
lines = readFileSync(sessionFile, 'utf8').split('\n');
|
|
329
|
+
}
|
|
330
|
+
catch {
|
|
331
|
+
return [];
|
|
332
|
+
}
|
|
333
|
+
const turns = [];
|
|
334
|
+
for (const line of lines) {
|
|
335
|
+
// Same cheap prefilter as readSessionParts: skip every line that cannot be a
|
|
336
|
+
// user or assistant message before paying for JSON.parse.
|
|
337
|
+
if (line === '')
|
|
338
|
+
continue;
|
|
339
|
+
const isUser = line.indexOf('"role":"user"') !== -1 || line.indexOf('"role": "user"') !== -1;
|
|
340
|
+
const isAssistant = !isUser
|
|
341
|
+
&& (line.indexOf('"role":"assistant"') !== -1 || line.indexOf('"role": "assistant"') !== -1);
|
|
342
|
+
if (!isUser && !isAssistant)
|
|
343
|
+
continue;
|
|
344
|
+
let rec;
|
|
345
|
+
try {
|
|
346
|
+
rec = JSON.parse(line);
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
continue;
|
|
350
|
+
}
|
|
351
|
+
if (rec.type !== 'message')
|
|
352
|
+
continue;
|
|
353
|
+
const role = rec.message?.role;
|
|
354
|
+
if (role !== 'user' && role !== 'assistant')
|
|
355
|
+
continue;
|
|
356
|
+
const text = extractUserText(rec.message?.content);
|
|
357
|
+
if (text === '')
|
|
358
|
+
continue;
|
|
359
|
+
if (parseCard({ role, content: text }) !== null)
|
|
360
|
+
continue;
|
|
361
|
+
turns.push({ role, text: text.length > TRANSCRIPT_MSG_CAP ? text.slice(0, TRANSCRIPT_MSG_CAP) : text });
|
|
362
|
+
}
|
|
363
|
+
return turns.length > TRANSCRIPT_TURNS ? turns.slice(turns.length - TRANSCRIPT_TURNS) : turns;
|
|
364
|
+
}
|
|
310
365
|
/** Did this node's engine ever PRODUCE something — an assistant message with real
|
|
311
366
|
* text, a tool call, or non-empty reasoning? The signal that a node did work and
|
|
312
367
|
* is not an empty shell. A never-revived node (no session file) is trivially
|
|
@@ -550,3 +605,21 @@ export async function loadPreviewFromSource(source, row) {
|
|
|
550
605
|
row.previewLoaded = true;
|
|
551
606
|
return row;
|
|
552
607
|
}
|
|
608
|
+
/** Fold the ordered conversation onto `row` — the preview panel's chat body. Kept
|
|
609
|
+
* OUT of loadPreviewFromSource because that runs over every row on the background
|
|
610
|
+
* warm pass, and a per-row transcript across a whole canvas is exactly the memory
|
|
611
|
+
* cost the capped `prompts` string avoids. Call it for the selected row only.
|
|
612
|
+
* Remote sources have no local session file, so the transcript stays empty. */
|
|
613
|
+
export async function loadTranscriptFromSource(source, row) {
|
|
614
|
+
if (row.transcriptLoaded === true)
|
|
615
|
+
return row;
|
|
616
|
+
if (source instanceof RemoteCanvasSource) {
|
|
617
|
+
row.transcript = [];
|
|
618
|
+
row.transcriptLoaded = true;
|
|
619
|
+
return row;
|
|
620
|
+
}
|
|
621
|
+
const meta = await source.getNode(row.node_id);
|
|
622
|
+
row.transcript = readTranscript(meta?.pi_session_file);
|
|
623
|
+
row.transcriptLoaded = true;
|
|
624
|
+
return row;
|
|
625
|
+
}
|
|
@@ -3,13 +3,13 @@ import type { AttachBindingId, AttachMenuBindingId } from './attach-control.js';
|
|
|
3
3
|
type TmuxMenuAction = 'open' | 'attach' | 'show' | 'view-settings' | 'fold-tools' | 'metadata' | 'promote' | 'demote-mode' | 'resume' | 'fork' | 'demote' | 'make-resident' | 'detach' | 'close-subtree' | 'background-bash' | 'file-review' | 'pin' | 'reload-viewer' | 'recap' | 'context' | 'context-admin' | 'providers' | 'plugins' | 'graph' | 'focus-manager' | 'copy-id' | 'issues';
|
|
4
4
|
type TmuxMenuEntryAction = Exclude<TmuxMenuAction, 'open' | 'attach'> | `issue.${'idea' | 'bug'}`;
|
|
5
5
|
type GraphAction = 'down' | 'up' | 'first' | 'last' | 'collapse-or-manager' | 'expand-or-child' | 'focus' | 'revive' | 'focus-manager' | 'close-subtree' | 'dismiss';
|
|
6
|
-
type BrowseAction = 'quit' | 'down' | 'up' | 'first' | 'last' | 'expand-or-child' | 'collapse-or-parent' | 'toggle-fold' | 'tab-next' | 'tab-previous' | `tab.${1 | 2 | 3 | 4 | 5}` | 'close-subtree' | 'confirm-close' | 'sort' | 'scope' | 'profile' | 'residents' | 'preview' | 'pin' | 'search' | 'revive-now' | 'focus' | 'focus-background' | 'yank-id';
|
|
6
|
+
type BrowseAction = 'quit' | 'down' | 'up' | 'first' | 'last' | 'expand-or-child' | 'collapse-or-parent' | 'toggle-fold' | 'tab-next' | 'tab-previous' | `tab.${1 | 2 | 3 | 4 | 5}` | 'close-subtree' | 'confirm-close' | 'sort' | 'scope' | 'profile' | 'residents' | 'preview' | 'report' | 'pin' | 'search' | 'revive-now' | 'focus' | 'focus-background' | 'yank-id';
|
|
7
7
|
type ProfileMenuAction = 'up' | 'down' | 'select' | 'accept-default' | 'abort' | `slot.${1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9}` | 'create' | 'search-existing' | 'use-root' | 'set-default' | 'add-directory' | 'unpin' | 'manage';
|
|
8
8
|
type SetupAction = 'cancel' | 'tab-next' | 'tab-previous' | 'open' | 'list-down' | 'list-up' | 'toggle' | 'details' | 'advance' | 'cell-previous' | 'cell-next';
|
|
9
9
|
type SetupKeybindingAction = 'edit' | 'commit-edit' | 'cancel-edit' | 'unbind' | 'reset-row' | 'reset-all' | 'save' | 'discard' | 'page-up' | 'page-down' | 'filter' | 'filter-delete' | 'filter-clear';
|
|
10
10
|
type SetupModelsAction = 'open' | 'commit' | 'cancel' | 'scope-next';
|
|
11
11
|
export type BindingId = `crtr.tmux.menu.${TmuxMenuAction}` | `crtr.tmux.menu.issue.${'idea' | 'bug'}` | AttachMenuBindingId | `crtr.tmux.menu-global.${TmuxMenuEntryAction}` | `crtr.tmux.node.${'next' | 'previous'}` | 'crtr.tmux.inbox.toggle' | `crtr.attach.scroll.${'up' | 'down' | 'page-up' | 'page-down' | 'live'}` | 'crtr.attach.mouse.toggle' | 'crtr.attach.copy.message' | 'crtr.attach.help.toggle' | `crtr.attach.search.${'next' | 'previous' | 'edit' | 'close'}` | AttachBindingId | `crtr.graph.${GraphAction}` | `crtr.graph.confirm.${'accept' | 'cancel'}` | `crtr.inspector.${'force-quit' | 'down' | 'up' | 'section-next' | 'section-prev' | 'page-down' | 'page-up' | 'toggle-detail' | 'cancel-item' | 'open-log' | 'confirm' | 'dismiss' | 'retarget' | 'refresh' | 'quit'}` | `crtr.browse.${BrowseAction}` | `crtr.browse.search.${'cancel' | 'commit' | 'delete' | 'quit'}` | `crtr.profile.menu.${ProfileMenuAction}` | `crtr.profile.search.${'up' | 'down' | 'pick' | 'back' | 'delete' | 'abort'}` | `crtr.setup.${SetupAction}` | `crtr.setup.confirm.${'accept' | 'back'}` | `crtr.setup.keybindings.${SetupKeybindingAction}` | `crtr.setup.models.${SetupModelsAction}`;
|
|
12
|
-
export declare const BINDING_CATALOG: readonly [BindingDefinition<"crtr.tmux.menu.open">, BindingDefinition<"crtr.tmux.menu.attach">, ...(BindingDefinition<BindingId> | BindingDefinition<"crtr.tmux.node.next"> | BindingDefinition<"crtr.tmux.node.previous"> | BindingDefinition<"crtr.tmux.inbox.toggle"> | BindingDefinition<"crtr.attach.scroll.up"> | BindingDefinition<"crtr.attach.scroll.down"> | BindingDefinition<"crtr.attach.scroll.page-up"> | BindingDefinition<"crtr.attach.scroll.page-down"> | BindingDefinition<"crtr.attach.scroll.live"> | BindingDefinition<"crtr.attach.mouse.toggle"> | BindingDefinition<"crtr.attach.copy.message"> | BindingDefinition<"crtr.attach.search.next"> | BindingDefinition<"crtr.attach.search.previous"> | BindingDefinition<"crtr.attach.search.edit"> | BindingDefinition<"crtr.attach.search.close"> | BindingDefinition<"crtr.graph.down"> | BindingDefinition<"crtr.graph.up"> | BindingDefinition<"crtr.graph.first"> | BindingDefinition<"crtr.graph.last"> | BindingDefinition<"crtr.graph.collapse-or-manager"> | BindingDefinition<"crtr.graph.expand-or-child"> | BindingDefinition<"crtr.graph.focus"> | BindingDefinition<"crtr.graph.revive"> | BindingDefinition<"crtr.graph.focus-manager"> | BindingDefinition<"crtr.graph.close-subtree"> | BindingDefinition<"crtr.graph.dismiss"> | BindingDefinition<"crtr.graph.confirm.accept"> | BindingDefinition<"crtr.graph.confirm.cancel"> | BindingDefinition<"crtr.inspector.force-quit"> | BindingDefinition<"crtr.inspector.down"> | BindingDefinition<"crtr.inspector.up"> | BindingDefinition<"crtr.inspector.section-next"> | BindingDefinition<"crtr.inspector.section-prev"> | BindingDefinition<"crtr.inspector.page-down"> | BindingDefinition<"crtr.inspector.page-up"> | BindingDefinition<"crtr.inspector.toggle-detail"> | BindingDefinition<"crtr.inspector.cancel-item"> | BindingDefinition<"crtr.inspector.open-log"> | BindingDefinition<"crtr.inspector.confirm"> | BindingDefinition<"crtr.inspector.dismiss"> | BindingDefinition<"crtr.inspector.retarget"> | BindingDefinition<"crtr.inspector.refresh"> | BindingDefinition<"crtr.inspector.quit"> | BindingDefinition<"crtr.browse.quit"> | BindingDefinition<"crtr.browse.down"> | BindingDefinition<"crtr.browse.up"> | BindingDefinition<"crtr.browse.first"> | BindingDefinition<"crtr.browse.last"> | BindingDefinition<"crtr.browse.expand-or-child"> | BindingDefinition<"crtr.browse.collapse-or-parent"> | BindingDefinition<"crtr.browse.toggle-fold"> | BindingDefinition<"crtr.browse.tab-next"> | BindingDefinition<"crtr.browse.tab-previous"> | BindingDefinition<"crtr.browse.tab.2" | "crtr.browse.tab.1" | "crtr.browse.tab.3" | "crtr.browse.tab.4" | "crtr.browse.tab.5"> | BindingDefinition<"crtr.browse.close-subtree"> | BindingDefinition<"crtr.browse.confirm-close"> | BindingDefinition<"crtr.browse.sort"> | BindingDefinition<"crtr.browse.scope"> | BindingDefinition<"crtr.browse.profile"> | BindingDefinition<"crtr.browse.residents"> | BindingDefinition<"crtr.browse.preview"> | BindingDefinition<"crtr.browse.pin"> | BindingDefinition<"crtr.browse.search"> | BindingDefinition<"crtr.browse.revive-now"> | BindingDefinition<"crtr.browse.focus"> | BindingDefinition<"crtr.browse.focus-background"> | BindingDefinition<"crtr.browse.yank-id"> | BindingDefinition<"crtr.browse.search.cancel"> | BindingDefinition<"crtr.browse.search.commit"> | BindingDefinition<"crtr.browse.search.delete"> | BindingDefinition<"crtr.browse.search.quit"> | BindingDefinition<"crtr.profile.menu.up"> | BindingDefinition<"crtr.profile.menu.down"> | BindingDefinition<"crtr.profile.menu.select"> | BindingDefinition<"crtr.profile.menu.accept-default"> | BindingDefinition<"crtr.profile.menu.abort"> | BindingDefinition<"crtr.profile.menu.slot.2" | "crtr.profile.menu.slot.1" | "crtr.profile.menu.slot.3" | "crtr.profile.menu.slot.4" | "crtr.profile.menu.slot.5" | "crtr.profile.menu.slot.6" | "crtr.profile.menu.slot.7" | "crtr.profile.menu.slot.8" | "crtr.profile.menu.slot.9">)[], BindingDefinition<"crtr.profile.menu.create">, BindingDefinition<"crtr.profile.menu.search-existing">, BindingDefinition<"crtr.profile.menu.use-root">, BindingDefinition<"crtr.profile.menu.set-default">, BindingDefinition<"crtr.profile.menu.add-directory">, BindingDefinition<"crtr.profile.menu.unpin">, BindingDefinition<"crtr.profile.menu.manage">, BindingDefinition<"crtr.profile.search.up">, BindingDefinition<"crtr.profile.search.down">, BindingDefinition<"crtr.profile.search.pick">, BindingDefinition<"crtr.profile.search.back">, BindingDefinition<"crtr.profile.search.delete">, BindingDefinition<"crtr.profile.search.abort">, BindingDefinition<"crtr.setup.cancel">, BindingDefinition<"crtr.setup.tab-next">, BindingDefinition<"crtr.setup.tab-previous">, BindingDefinition<"crtr.setup.open">, BindingDefinition<"crtr.setup.list-down">, BindingDefinition<"crtr.setup.list-up">, BindingDefinition<"crtr.setup.toggle">, BindingDefinition<"crtr.setup.details">, BindingDefinition<"crtr.setup.advance">, BindingDefinition<"crtr.setup.confirm.accept">, BindingDefinition<"crtr.setup.confirm.back">, BindingDefinition<"crtr.setup.keybindings.edit">, BindingDefinition<"crtr.setup.keybindings.commit-edit">, BindingDefinition<"crtr.setup.keybindings.cancel-edit">, BindingDefinition<"crtr.setup.keybindings.unbind">, BindingDefinition<"crtr.setup.keybindings.reset-row">, BindingDefinition<"crtr.setup.keybindings.reset-all">, BindingDefinition<"crtr.setup.keybindings.save">, BindingDefinition<"crtr.setup.keybindings.discard">, BindingDefinition<"crtr.setup.keybindings.page-up">, BindingDefinition<"crtr.setup.keybindings.page-down">, BindingDefinition<"crtr.setup.keybindings.filter">, BindingDefinition<"crtr.setup.keybindings.filter-delete">, BindingDefinition<"crtr.setup.keybindings.filter-clear">, BindingDefinition<"crtr.setup.cell-previous">, BindingDefinition<"crtr.setup.cell-next">, BindingDefinition<"crtr.setup.models.open">, BindingDefinition<"crtr.setup.models.scope-next">, BindingDefinition<"crtr.setup.models.commit">, BindingDefinition<"crtr.setup.models.cancel">];
|
|
12
|
+
export declare const BINDING_CATALOG: readonly [BindingDefinition<"crtr.tmux.menu.open">, BindingDefinition<"crtr.tmux.menu.attach">, ...(BindingDefinition<BindingId> | BindingDefinition<"crtr.tmux.node.next"> | BindingDefinition<"crtr.tmux.node.previous"> | BindingDefinition<"crtr.tmux.inbox.toggle"> | BindingDefinition<"crtr.attach.scroll.up"> | BindingDefinition<"crtr.attach.scroll.down"> | BindingDefinition<"crtr.attach.scroll.page-up"> | BindingDefinition<"crtr.attach.scroll.page-down"> | BindingDefinition<"crtr.attach.scroll.live"> | BindingDefinition<"crtr.attach.mouse.toggle"> | BindingDefinition<"crtr.attach.copy.message"> | BindingDefinition<"crtr.attach.search.next"> | BindingDefinition<"crtr.attach.search.previous"> | BindingDefinition<"crtr.attach.search.edit"> | BindingDefinition<"crtr.attach.search.close"> | BindingDefinition<"crtr.graph.down"> | BindingDefinition<"crtr.graph.up"> | BindingDefinition<"crtr.graph.first"> | BindingDefinition<"crtr.graph.last"> | BindingDefinition<"crtr.graph.collapse-or-manager"> | BindingDefinition<"crtr.graph.expand-or-child"> | BindingDefinition<"crtr.graph.focus"> | BindingDefinition<"crtr.graph.revive"> | BindingDefinition<"crtr.graph.focus-manager"> | BindingDefinition<"crtr.graph.close-subtree"> | BindingDefinition<"crtr.graph.dismiss"> | BindingDefinition<"crtr.graph.confirm.accept"> | BindingDefinition<"crtr.graph.confirm.cancel"> | BindingDefinition<"crtr.inspector.force-quit"> | BindingDefinition<"crtr.inspector.down"> | BindingDefinition<"crtr.inspector.up"> | BindingDefinition<"crtr.inspector.section-next"> | BindingDefinition<"crtr.inspector.section-prev"> | BindingDefinition<"crtr.inspector.page-down"> | BindingDefinition<"crtr.inspector.page-up"> | BindingDefinition<"crtr.inspector.toggle-detail"> | BindingDefinition<"crtr.inspector.cancel-item"> | BindingDefinition<"crtr.inspector.open-log"> | BindingDefinition<"crtr.inspector.confirm"> | BindingDefinition<"crtr.inspector.dismiss"> | BindingDefinition<"crtr.inspector.retarget"> | BindingDefinition<"crtr.inspector.refresh"> | BindingDefinition<"crtr.inspector.quit"> | BindingDefinition<"crtr.browse.quit"> | BindingDefinition<"crtr.browse.down"> | BindingDefinition<"crtr.browse.up"> | BindingDefinition<"crtr.browse.first"> | BindingDefinition<"crtr.browse.last"> | BindingDefinition<"crtr.browse.expand-or-child"> | BindingDefinition<"crtr.browse.collapse-or-parent"> | BindingDefinition<"crtr.browse.toggle-fold"> | BindingDefinition<"crtr.browse.tab-next"> | BindingDefinition<"crtr.browse.tab-previous"> | BindingDefinition<"crtr.browse.tab.2" | "crtr.browse.tab.1" | "crtr.browse.tab.3" | "crtr.browse.tab.4" | "crtr.browse.tab.5"> | BindingDefinition<"crtr.browse.close-subtree"> | BindingDefinition<"crtr.browse.confirm-close"> | BindingDefinition<"crtr.browse.sort"> | BindingDefinition<"crtr.browse.scope"> | BindingDefinition<"crtr.browse.profile"> | BindingDefinition<"crtr.browse.residents"> | BindingDefinition<"crtr.browse.preview"> | BindingDefinition<"crtr.browse.report"> | BindingDefinition<"crtr.browse.pin"> | BindingDefinition<"crtr.browse.search"> | BindingDefinition<"crtr.browse.revive-now"> | BindingDefinition<"crtr.browse.focus"> | BindingDefinition<"crtr.browse.focus-background"> | BindingDefinition<"crtr.browse.yank-id"> | BindingDefinition<"crtr.browse.search.cancel"> | BindingDefinition<"crtr.browse.search.commit"> | BindingDefinition<"crtr.browse.search.delete"> | BindingDefinition<"crtr.browse.search.quit"> | BindingDefinition<"crtr.profile.menu.up"> | BindingDefinition<"crtr.profile.menu.down"> | BindingDefinition<"crtr.profile.menu.select"> | BindingDefinition<"crtr.profile.menu.accept-default"> | BindingDefinition<"crtr.profile.menu.abort"> | BindingDefinition<"crtr.profile.menu.slot.2" | "crtr.profile.menu.slot.1" | "crtr.profile.menu.slot.3" | "crtr.profile.menu.slot.4" | "crtr.profile.menu.slot.5" | "crtr.profile.menu.slot.6" | "crtr.profile.menu.slot.7" | "crtr.profile.menu.slot.8" | "crtr.profile.menu.slot.9">)[], BindingDefinition<"crtr.profile.menu.create">, BindingDefinition<"crtr.profile.menu.search-existing">, BindingDefinition<"crtr.profile.menu.use-root">, BindingDefinition<"crtr.profile.menu.set-default">, BindingDefinition<"crtr.profile.menu.add-directory">, BindingDefinition<"crtr.profile.menu.unpin">, BindingDefinition<"crtr.profile.menu.manage">, BindingDefinition<"crtr.profile.search.up">, BindingDefinition<"crtr.profile.search.down">, BindingDefinition<"crtr.profile.search.pick">, BindingDefinition<"crtr.profile.search.back">, BindingDefinition<"crtr.profile.search.delete">, BindingDefinition<"crtr.profile.search.abort">, BindingDefinition<"crtr.setup.cancel">, BindingDefinition<"crtr.setup.tab-next">, BindingDefinition<"crtr.setup.tab-previous">, BindingDefinition<"crtr.setup.open">, BindingDefinition<"crtr.setup.list-down">, BindingDefinition<"crtr.setup.list-up">, BindingDefinition<"crtr.setup.toggle">, BindingDefinition<"crtr.setup.details">, BindingDefinition<"crtr.setup.advance">, BindingDefinition<"crtr.setup.confirm.accept">, BindingDefinition<"crtr.setup.confirm.back">, BindingDefinition<"crtr.setup.keybindings.edit">, BindingDefinition<"crtr.setup.keybindings.commit-edit">, BindingDefinition<"crtr.setup.keybindings.cancel-edit">, BindingDefinition<"crtr.setup.keybindings.unbind">, BindingDefinition<"crtr.setup.keybindings.reset-row">, BindingDefinition<"crtr.setup.keybindings.reset-all">, BindingDefinition<"crtr.setup.keybindings.save">, BindingDefinition<"crtr.setup.keybindings.discard">, BindingDefinition<"crtr.setup.keybindings.page-up">, BindingDefinition<"crtr.setup.keybindings.page-down">, BindingDefinition<"crtr.setup.keybindings.filter">, BindingDefinition<"crtr.setup.keybindings.filter-delete">, BindingDefinition<"crtr.setup.keybindings.filter-clear">, BindingDefinition<"crtr.setup.cell-previous">, BindingDefinition<"crtr.setup.cell-next">, BindingDefinition<"crtr.setup.models.open">, BindingDefinition<"crtr.setup.models.scope-next">, BindingDefinition<"crtr.setup.models.commit">, BindingDefinition<"crtr.setup.models.cancel">];
|
|
13
13
|
export declare const BINDING_IDS: ReadonlySet<string>;
|
|
14
14
|
/** True for an action whose direct gesture is handled inside an attach viewer.
|
|
15
15
|
* Tmux menu selectors and root shortcuts are chrome, not pane input. */
|
|
@@ -148,6 +148,7 @@ function browseBindings() {
|
|
|
148
148
|
b('crtr.browse.profile', 'Browse and pickers', 'Toggle profile', 'Toggle the browse profile scope.', ['shift+p'], 'terminal', [nav]),
|
|
149
149
|
b('crtr.browse.residents', 'Browse and pickers', 'Toggle residents', 'Toggle resident display.', ['r'], 'terminal', [nav]),
|
|
150
150
|
b('crtr.browse.preview', 'Browse and pickers', 'Toggle preview', 'Toggle the preview panel.', ['v'], 'terminal', [nav]),
|
|
151
|
+
b('crtr.browse.report', 'Browse and pickers', 'Toggle report', 'Swap the preview panel between the conversation and the node\'s newest report.', ['shift+v'], 'terminal', [nav]),
|
|
151
152
|
b('crtr.browse.pin', 'Browse and pickers', 'Pin node', 'Star or unstar the selected node.', ['p'], 'terminal', [nav]),
|
|
152
153
|
b('crtr.browse.search', 'Browse and pickers', 'Search', 'Open browse search.', ['/'], 'terminal', [nav]),
|
|
153
154
|
b('crtr.browse.revive-now', 'Browse and pickers', 'Revive now', 'Revive the selected node now.', ['shift+k'], 'terminal', [nav]),
|
|
@@ -15,7 +15,7 @@ const TMUX_BINDING_MANIFEST = '@crtr_keybindings_manifest';
|
|
|
15
15
|
const ROOT_TABLE = 'root';
|
|
16
16
|
const LEAF_MENU_ACTIONS = {
|
|
17
17
|
'crtr.tmux.menu.promote': { description: 'promote to orchestrator', action: { kind: 'keys', keys: '/promote' } },
|
|
18
|
-
'crtr.tmux.menu.resume': { description: 'find node', action: { kind: 'keys', keys: '/resume
|
|
18
|
+
'crtr.tmux.menu.resume': { description: 'find node', action: { kind: 'keys', keys: '/resume' } },
|
|
19
19
|
'crtr.tmux.menu.fork': { description: 'fork into idle root', action: { kind: 'direct', run: 'node fork --pane {pane}' } },
|
|
20
20
|
// Mode demote is the mirror of `/promote`: `node config` persists the change;
|
|
21
21
|
// the broker appends its pending context before the next provider response.
|
package/package.json
CHANGED
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/crouter",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.278",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@north-light/crouter",
|
|
9
|
-
"version": "0.3.
|
|
9
|
+
"version": "0.3.278",
|
|
10
10
|
"hasInstallScript": true,
|
|
11
11
|
"license": "MIT",
|
|
12
12
|
"dependencies": {
|