@north-light/crouter 0.3.154 → 0.3.157
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -1
- package/dist/api/client.d.ts +1 -4
- package/dist/api/client.js +0 -5
- package/dist/api/dto/broker.d.ts +1 -1
- package/dist/api/dto/nodes.d.ts +0 -15
- package/dist/api/routes.d.ts +0 -1
- package/dist/api/routes.js +0 -1
- package/dist/builtin-views/chat/core.mjs +51 -6
- package/dist/builtin-views/chat/tui.mjs +14 -6
- package/dist/builtin-views/chat/web.jsx +7 -2
- package/dist/clients/attach/__tests__/oauth-dialog-lifecycle.test.js +1 -1
- package/dist/clients/attach/chrome/roster.d.ts +1 -1
- package/dist/clients/attach/chrome/roster.js +1 -9
- package/dist/clients/attach/command.js +5 -5
- package/dist/clients/attach/input/controller.d.ts +8 -23
- package/dist/clients/attach/input/controller.js +29 -59
- package/dist/clients/attach/overlays/dialogs.d.ts +2 -1
- package/dist/clients/attach/overlays/graph.d.ts +1 -4
- package/dist/clients/attach/overlays/graph.js +7 -25
- package/dist/clients/attach/session/context.d.ts +0 -7
- package/dist/clients/attach/session/frames.js +8 -1
- package/dist/clients/attach/session/input-wiring.d.ts +1 -1
- package/dist/clients/attach/session/input-wiring.js +11 -21
- package/dist/clients/attach/session/mode.d.ts +3 -4
- package/dist/clients/attach/session/mode.js +1 -6
- package/dist/clients/attach/session/reconnect.d.ts +3 -3
- package/dist/clients/attach/session/reconnect.js +7 -6
- package/dist/clients/attach/session/state-sync.d.ts +1 -1
- package/dist/clients/attach/session/state-sync.js +2 -2
- package/dist/clients/attach/slash/dispatch.d.ts +1 -13
- package/dist/clients/attach/slash/dispatch.js +17 -65
- package/dist/clients/attach/viewer.js +523 -523
- package/dist/clients/web/web-client/shared/protocol.d.ts +3 -5
- package/dist/core/__tests__/broker-sdk-wiring.test.js +18 -18
- package/dist/core/__tests__/chat-view-reconnect.test.js +23 -44
- package/dist/core/__tests__/full/broker-attach-limits.test.js +36 -60
- package/dist/core/__tests__/full/broker-attach-stream.test.js +4 -4
- package/dist/core/__tests__/full/broker-control-preempt.test.d.ts +1 -0
- package/dist/core/__tests__/full/broker-control-preempt.test.js +61 -0
- package/dist/core/__tests__/full/broker-dialogs.test.js +62 -121
- package/dist/core/__tests__/helpers/broker-clients.js +2 -2
- package/dist/core/__tests__/session-model.test.js +26 -15
- package/dist/core/keybindings/__tests__/resolve.test.js +1 -1
- package/dist/core/keybindings/catalog.d.ts +2 -2
- package/dist/core/keybindings/catalog.js +2 -0
- package/dist/core/runtime/auth-reload.d.ts +4 -4
- package/dist/core/runtime/auth-reload.js +13 -9
- package/dist/core/runtime/boot-root.d.ts +2 -2
- package/dist/core/runtime/boot-root.js +7 -7
- package/dist/core/runtime/broker-protocol.d.ts +27 -23
- package/dist/core/runtime/broker-protocol.js +1 -1
- package/dist/core/runtime/broker-request.js +11 -5
- package/dist/core/runtime/broker.d.ts +13 -21
- package/dist/core/runtime/broker.js +186 -151
- package/dist/core/runtime/interactive-deliver.js +5 -4
- package/dist/core/runtime/model-swap.d.ts +3 -2
- package/dist/core/runtime/model-swap.js +4 -3
- package/dist/core/runtime/node-read.d.ts +0 -20
- package/dist/core/runtime/node-read.js +1 -34
- package/dist/core/runtime/resume-root.d.ts +1 -1
- package/dist/core/runtime/resume-root.js +6 -6
- package/dist/core/runtime/spawn.js +3 -3
- package/dist/core/session-model/session-state.d.ts +6 -8
- package/dist/core/session-model/session-state.js +16 -6
- package/dist/daemon/api/handlers/nodes.js +1 -18
- package/dist/daemon/manage.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/web-client/assets/index--SsQYcKu.js +79 -0
- package/dist/web-client/assets/{index-CpEl9LTS.css → index-DJhQZoAj.css} +1 -1
- package/dist/web-client/index.html +2 -2
- package/dist/web-client/sw.js +1 -1
- package/docs/compat/hearth-crtr-v1.md +1 -1
- package/docs/compat/hearth-crtr-v2.md +1 -1
- package/docs/compat/hearth-crtr-v3.md +1 -1
- package/docs/compat/hearth-crtr-v4.md +3 -1
- package/docs/public-api.md +2 -2
- package/package.json +4 -4
- package/runtime.lock.json +2 -2
- package/dist/web-client/assets/index-BpyZGBhI.js +0 -79
- package/docs/compat/hearth-crtr-v5.md +0 -175
|
@@ -52,17 +52,6 @@ const CANVAS_NAMES = new Set(CANVAS_SLASH_COMMANDS.map((c) => c.name));
|
|
|
52
52
|
* (the in-process GRAPH overlay, already remote-safe — see overlays/graph.ts)
|
|
53
53
|
* and `/view` (a self-contained popup unrelated to `nodeId`) stay available. */
|
|
54
54
|
const REMOTE_UNSAFE_CANVAS_NAMES = new Set(['promote', 'resume-node', 'context', 'node-metadata', 'rename', 'clear', 'mcp']);
|
|
55
|
-
/** Native canvas commands an OBSERVER may not run — the ones that drive the
|
|
56
|
-
* engine or mutate the node, whether by frame or by shelling the crtr CLI:
|
|
57
|
-
* `/clear` sends `new_session`; `/promote` shells `crtr node promote` and then
|
|
58
|
-
* triggers a turn; `/rename` sends `set_session_name` and shells `crtr node
|
|
59
|
-
* config --name`; `/resume-node` opens the navigator whose Enter path focuses
|
|
60
|
-
* (and so revives) a node; `/mcp`'s panel actions ride a `prompt` frame into
|
|
61
|
-
* the engine. Deliberately NOT here — genuinely read-only or viewer-local:
|
|
62
|
-
* `/graph` (in-process overlay), `/context` and `/node-metadata` (read-only
|
|
63
|
-
* inspection popups), `/color` (this pane's tmux border + this viewer's name
|
|
64
|
-
* chip). */
|
|
65
|
-
const OBSERVER_UNSAFE_CANVAS_NAMES = new Set(['clear', 'promote', 'rename', 'resume-node', 'view', 'mcp']);
|
|
66
55
|
/** tmux named colours accepted by `/color` (plus `colourN`/`#rrggbb`, validated
|
|
67
56
|
* by pattern). Mirrors tmux's colour-name table so a typo is rejected with the
|
|
68
57
|
* options rather than silently ignored by tmux. */
|
|
@@ -89,53 +78,17 @@ const THINKING_LEVELS = new Set(Object.keys({
|
|
|
89
78
|
max: true,
|
|
90
79
|
}));
|
|
91
80
|
const BUILTIN_NAMES = new Set(BUILTIN_SLASH_COMMANDS.map((c) => c.name));
|
|
92
|
-
/** Builtin slash commands safe to run
|
|
93
|
-
* attach (`--canvas`) or an `--observer` one —
|
|
81
|
+
/** Builtin slash commands safe to run against a REMOTE attach (`--canvas`) —
|
|
94
82
|
* everything else in `BUILTIN_SLASH_COMMANDS` either drives the engine
|
|
95
83
|
* (`/model`, `/new`, `/compact`, `/name`, `/resume`, `/fork`, `/tree`,
|
|
96
84
|
* `/settings`, `/share`, `/clone`, `/import`, `/reload`, `/scoped-models`
|
|
97
85
|
* selection) or is viewer-local but operates on the WRONG host for a remote
|
|
98
86
|
* node (`/login`, `/logout` — LOCAL `auth.json` via `defaultAgentDir()`, not
|
|
99
|
-
* the remote broker's
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
|
|
104
|
-
const READ_ONLY_SAFE_BUILTIN_NAMES = new Set(['copy', 'session', 'changelog', 'hotkeys', 'quit']);
|
|
105
|
-
/** THE capability gate for a read-only viewer, keyed on the two fixed facts a
|
|
106
|
-
* session resolves once (`remote`, `role`) — so the answer for a given command
|
|
107
|
-
* cannot change mid-session. Returns the refusal notice, or `undefined` when
|
|
108
|
-
* this viewer may run the command. Both `dispatchSlashCommand` (so a direct
|
|
109
|
-
* caller is safe) and the InputController's submit path (so a refusal is
|
|
110
|
-
* reported before command dispatch) consult this one function; there is no
|
|
111
|
-
* second policy anywhere. */
|
|
112
|
-
function readOnlyRefusal(name, ctx) {
|
|
113
|
-
const canvas = CANVAS_NAMES.has(name);
|
|
114
|
-
const builtinUnsafe = BUILTIN_NAMES.has(name) && !READ_ONLY_SAFE_BUILTIN_NAMES.has(name);
|
|
115
|
-
if (ctx.remote === true) {
|
|
116
|
-
if (canvas && REMOTE_UNSAFE_CANVAS_NAMES.has(name)) {
|
|
117
|
-
return `/${name} is not available for a remote attach (--canvas) — it acts on this machine's local canvas`;
|
|
118
|
-
}
|
|
119
|
-
if (builtinUnsafe)
|
|
120
|
-
return `/${name} is not available for a remote attach (--canvas) — view-only`;
|
|
121
|
-
}
|
|
122
|
-
if (ctx.remote !== true && (ctx.role ?? 'controller') !== 'controller') {
|
|
123
|
-
if ((canvas && OBSERVER_UNSAFE_CANVAS_NAMES.has(name)) || builtinUnsafe) {
|
|
124
|
-
return `/${name} is not available to a read-only observer attach (--observer) — it would drive this node`;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return undefined;
|
|
128
|
-
}
|
|
129
|
-
/** The same gate, entered from raw editor text: the InputController asks BEFORE
|
|
130
|
-
* dispatching so a refused command is reported without reaching command
|
|
131
|
-
* dispatch. Unrecognized (extension) commands answer `undefined` here — they
|
|
132
|
-
* ride the normal `prompt` path, which the controller's own drive gate covers. */
|
|
133
|
-
export function readOnlySlashRefusal(text, ctx) {
|
|
134
|
-
const m = /^\/(\S+)\s*([\s\S]*)$/.exec(text.trim());
|
|
135
|
-
if (!m)
|
|
136
|
-
return undefined;
|
|
137
|
-
return readOnlyRefusal(m[1], ctx);
|
|
138
|
-
}
|
|
87
|
+
* the remote broker's). Blocked here BEFORE the switch so a remote attach
|
|
88
|
+
* never even opens the picker only to have the eventual selection frame
|
|
89
|
+
* swallowed by InputController's `emitCommand` gate (defense-in-depth #2,
|
|
90
|
+
* not the only defense — see input/controller.ts DRIVE_FRAME_TYPES). */
|
|
91
|
+
const REMOTE_SAFE_BUILTIN_NAMES = new Set(['copy', 'session', 'changelog', 'hotkeys', 'quit']);
|
|
139
92
|
/** Every leading-command name this viewer consumes ENTIRELY locally — the
|
|
140
93
|
* message never reaches the engine as prose, whether dispatched or blocked
|
|
141
94
|
* with a notice (a remote-unsafe canvas/builtin command still returns
|
|
@@ -172,20 +125,13 @@ export function dispatchSlashCommand(text, ctx) {
|
|
|
172
125
|
}
|
|
173
126
|
// Canvas commands (reimplemented native in the viewer) — handled before the
|
|
174
127
|
// builtin gate since they are neither pi builtins nor engine-extension commands.
|
|
175
|
-
if (CANVAS_NAMES.has(name))
|
|
176
|
-
const refusal = readOnlyRefusal(name, ctx);
|
|
177
|
-
if (refusal !== undefined) {
|
|
178
|
-
ctx.notify(refusal);
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
128
|
+
if (CANVAS_NAMES.has(name))
|
|
181
129
|
return dispatchCanvasCommand(name, arg, ctx);
|
|
182
|
-
}
|
|
183
130
|
// Unknown to us AND not a builtin → let the engine's extension runner have it.
|
|
184
131
|
if (!BUILTIN_NAMES.has(name))
|
|
185
132
|
return false;
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
ctx.notify(refusal);
|
|
133
|
+
if (ctx.remote === true && !REMOTE_SAFE_BUILTIN_NAMES.has(name)) {
|
|
134
|
+
ctx.notify(`/${name} is not available for a remote attach (--canvas) — view-only`);
|
|
189
135
|
return true;
|
|
190
136
|
}
|
|
191
137
|
switch (name) {
|
|
@@ -340,8 +286,14 @@ export function commandAutocompleteItems(commands = BUILTIN_SLASH_COMMANDS, remo
|
|
|
340
286
|
/** Dispatch one of the native canvas commands. Always returns `true` (the
|
|
341
287
|
* command is viewer-owned — never forwarded to the engine as a prompt). */
|
|
342
288
|
function dispatchCanvasCommand(name, arg, ctx) {
|
|
343
|
-
//
|
|
344
|
-
//
|
|
289
|
+
// Structural omission (withCanvasCommands) keeps these out of remote-mode
|
|
290
|
+
// autocomplete; this gate is the belt-and-suspenders that also makes them
|
|
291
|
+
// NOT EXECUTABLE if typed by hand — a remote node id has no relationship to
|
|
292
|
+
// this machine's local canvas.db (or, worse, collides with one that does).
|
|
293
|
+
if (ctx.remote && REMOTE_UNSAFE_CANVAS_NAMES.has(name)) {
|
|
294
|
+
ctx.notify(`/${name} is not available for a remote attach (--canvas) — it acts on this machine's local canvas`);
|
|
295
|
+
return true;
|
|
296
|
+
}
|
|
345
297
|
switch (name) {
|
|
346
298
|
case 'clear':
|
|
347
299
|
// Claude-Code ergonomics: `/clear` == `/new` — drop the conversation and
|