acrylblends 1.0.10 → 1.1.0
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/index.d.ts +15 -1
- package/dist/index.js +13 -7
- package/dist/index.js.map +1 -1
- package/docs/framework/api/summary.md +1 -1
- package/docs/framework/guides/production.md +20 -0
- package/docs/framework/workshop/README.md +177 -274
- package/docs/framework/workshop/facilitator.md +107 -84
- package/lib/{audit-Dw-siYTp.d.ts → audit-BFpULBCj.d.ts} +15 -3
- package/lib/cordis/door.d.ts +3 -1
- package/lib/cordis/door.js +11 -1
- package/lib/cordis/state.d.ts +3 -2
- package/lib/cordis/state.js +370 -6
- package/lib/door/host.d.ts +1 -1
- package/lib/door/host.js +1 -1
- package/lib/door/page.d.ts +10 -0
- package/lib/door/page.js +29 -7
- package/lib/{snapshot-text-BfEbEOjA.js → snapshot-text-BwM6T2nG.js} +36 -4
- package/package.json +1 -1
- package/plugins/acryl-door/src/host/channel.ts +42 -4
- package/plugins/acryl-door/src/host/door.ts +5 -0
- package/plugins/acryl-door/src/host/page-routes.ts +1 -1
- package/plugins/acryl-door/src/host/page-socket.ts +1 -1
- package/plugins/acryl-door/src/page/channel.ts +8 -0
- package/plugins/acryl-door/src/page/driver/driver.ts +17 -3
- package/plugins/acryl-door/src/page/index.ts +6 -1
- package/plugins/acryl-door/src/page/indicator.ts +14 -6
- package/plugins/acryl-state/plugin.json +4 -3
- package/plugins/acryl-state/src/client-source.ts +244 -0
- package/plugins/acryl-state/src/service.ts +33 -6
- package/plugins/acryl-state/src/socket.ts +96 -0
- package/plugins/agent-panel/client/main.ts +105 -55
- package/plugins/agent-panel/index.ts +42 -5
- package/plugins/instance/index.ts +6 -3
- package/templates/agent/AGENTS.md +3 -1
- package/templates/agent/src/routes.ts +38 -5
- package/templates/agent/test/app.test.ts +38 -2
- package/templates/chat/src/main.ts +1 -6
- package/templates/nodejs/src/main.ts +1 -6
- package/templates/notes/src/main.ts +1 -6
|
@@ -1,108 +1,131 @@
|
|
|
1
|
-
# Facilitator notes:
|
|
1
|
+
# Facilitator notes: an app that builds and drives itself
|
|
2
2
|
|
|
3
|
-
Read the
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
Read the handout first (`docs/framework/workshop/README.md`); this page is the room around it. The workshop changed shape on 2026-10-29: the agent living in
|
|
4
|
+
the app both builds its interface and drives it (clicks, sidebars, dialogs, settings), on the web and in a desktop window. The data layer and the template
|
|
5
|
+
tour are asides now, and `/hello` is only the introduction to the framework core. The handout is written for **acrylblends 1.0.10 or newer**.
|
|
6
6
|
|
|
7
7
|
## Before the room: put this on every machine
|
|
8
8
|
|
|
9
9
|
| What | Why | How |
|
|
10
10
|
| --- | --- | --- |
|
|
11
|
-
|
|
|
12
|
-
|
|
|
13
|
-
|
|
|
14
|
-
|
|
|
15
|
-
|
|
|
16
|
-
| A
|
|
17
|
-
| A device with `git` and a text editor | the edits in steps 2, 4 and 8 are small but real | `git --version` |
|
|
11
|
+
| The preflight passing | it checks Node, npm, git, an agent with its login or key, a free port, and on Windows PowerShell and long paths | `npx acrylblends@latest preflight` ends with `Ready for the workshop.` |
|
|
12
|
+
| Node.js 22.19 or newer (24 and 26 tested) | the app runs TypeScript directly | `node -v`; the app's own `scripts/check-node.cjs` refuses an older Node with a clear line |
|
|
13
|
+
| git, and a GitHub account with `gh auth login` | the last block forks the workshop registry and opens a pull request | `git --version`, `gh auth status` |
|
|
14
|
+
| One coding agent, logged in | the panel drives it; `codex`, `claude` and `pi` all worked | `codex login` once (and a model the account supports), or run `claude` once, or pi with `DEEPSEEK_API_KEY` set in the terminal that starts the app |
|
|
15
|
+
| A prepared app with Electron already downloaded | the desktop block is 15 minutes and the download is the slowest part | run the handout's blocks 1 and 4 once per machine, then keep the folder as `~/acryl-workshop/prepared/` |
|
|
16
|
+
| A warm npm cache | the first `npm create` and the Electron download dominate the first ten minutes | the prepared app does it |
|
|
18
17
|
|
|
19
|
-
|
|
18
|
+
**The agent config that decides the day.** The panel's agent is configured to act rather than describe. Check on every machine that a plain request
|
|
19
|
+
produces files, not a plan: ask the prepared app's panel "say hello in a card on the page" and watch the panel's `Working...` line and the first file
|
|
20
|
+
appear. If it only describes, the model is waiting for permission; the handout's sentence is "do it now".
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
npx acrylblends add desktop && npm install
|
|
26
|
-
cd ~/acryl-workshop && cp -R warmup prepared-notes && rm -rf warmup
|
|
27
|
-
```
|
|
22
|
+
**Agent-specific checks.** Codex answering `model_not_found` means the account does not have the default model: pick one it supports (`/model` in codex,
|
|
23
|
+
or `model = "..."` in `~/.codex/config.toml`). pi with DeepSeek needs `DEEPSEEK_API_KEY` in the environment of the terminal that runs `npm run dev`
|
|
24
|
+
(the panel starts pi from the app); the preflight reports `PASS agent pi (DeepSeek key found)` when it is there. The package is
|
|
25
|
+
`@earendil-works/pi-coding-agent` (1.4.0 on npm on 2026-10-30), installed with `npm i -g @earendil-works/pi-coding-agent`.
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
## Timings, from the 1.0.10 walks (macOS and Windows, pi on DeepSeek)
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
The handout's own timings, as measured on the published 1.0.2 (macOS, cold npm cache in a throwaway home):
|
|
34
|
-
|
|
35
|
-
| Minutes | Step | Measured | If late |
|
|
29
|
+
| Minutes | Block | Measured | If late |
|
|
36
30
|
| --- | --- | --- | --- |
|
|
37
|
-
| 0-10 |
|
|
38
|
-
| 10-
|
|
39
|
-
|
|
|
40
|
-
|
|
|
41
|
-
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
- **
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
- **
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
31
|
+
| 0-10 | preflight, setup and `/hello` | preflight 12 s; create, install, dev, the route edit, `npm test` (14 tests) and `npm run check` 14 s of commands | never cut |
|
|
32
|
+
| 10-40 | the agent builds the interface | 5:51 for pi to build, install and check the board (an earlier codex run: about 2.5 minutes) | if late, keep the board minimal (one column) |
|
|
33
|
+
| 40-60 | the agent drives the app | 1:41 for the tick-and-filter prompt (six door calls, most of the time the model thinking), 2:07 for the New-card prompt | the drive is the point; cut the second "check its own work" prompt |
|
|
34
|
+
| 60-75 | the same app in a window | add + install 5 s; first `npm run desktop` 10 s including the Electron download on a fast line; the drive in the window 22 s; the windows, menu and settings prompt 1:11 | pre-warm Electron or demo it |
|
|
35
|
+
| 75-90 | deploy and publish | production start in seconds; the registry check merges in about 2 minutes | keep the publish; the deploy talk can be 3 minutes |
|
|
36
|
+
|
|
37
|
+
The Windows walk on 1.0.10 (2026-10-30, Windows 10, Node 22, pi on DeepSeek) matched: preflight 13 s; `npm create` 8 s and install 4 s; pi built the
|
|
38
|
+
board from the panel in 5:56; the agent opened Settings through `File > Settings...`, set the appearance and saw `Saved: Dark`, and window 1 showed it
|
|
39
|
+
after a reload; with two windows open during a live run, `look` answered in 317-353 ms in each and the panel's Stop ended the run in 3 s; production served
|
|
40
|
+
the board read-only with the agent routes gone.
|
|
41
|
+
|
|
42
|
+
Checkpoints in the handout: 10 minutes a route answers; 40 minutes the agent's board is on screen; 60 minutes the agent has clicked through it; 75 minutes
|
|
43
|
+
the window is open. Walk the room at those minutes and help the machine that is behind, rather than the one that is ahead.
|
|
44
|
+
|
|
45
|
+
## What to say in the room
|
|
46
|
+
|
|
47
|
+
- **Close the browser tab before block 4.** While a browser tab of the app is open, a door action without `--window` can go to that tab: in the 1.0.10
|
|
48
|
+
walk the agent, asked from the window's panel, moved the hidden browser tab and reported success while the window stayed on `/`. With the tab closed
|
|
49
|
+
the same prompt drove the window in 22 s. The handout says so at the top of block 4; it stays until the door aims at the window the agent was asked
|
|
50
|
+
from (reported to Blends).
|
|
51
|
+
- **The Settings item.** It is in the application menu on macOS (`my-app > Settings...`, `Cmd+,`) and the first item of the File menu on Windows and Linux
|
|
52
|
+
(`Ctrl+,`). An app gets it because it serves `/settings`; the template does. In the walk, pi found it in the app menu by itself.
|
|
53
|
+
- **Appearance.** The template's `/settings` saves light, dark or "match the system" for the app's own pages. A window that is already open shows the
|
|
54
|
+
change after a reload, and a page the agent built follows the system theme unless asked otherwise. On a dark-mode machine, demo with Light.
|
|
55
|
+
- **The driving bar.** `Agent is driving: clicking` with a Stop button shows at the bottom of the page only while each action runs, a moment each; the
|
|
56
|
+
panel's `Working... m:ss` line and its Stop button are what people see during a run.
|
|
57
|
+
- **Every agent builds a different board.** pi's board needed a title typed before "New card" added a card, and kept its sidebar always open when the
|
|
58
|
+
prompt did not ask for a toggle. The handout's block 2 prompt now asks for a button that opens and closes the sidebar, so block 3 has something to open.
|
|
59
|
+
- **Production listens where it is told.** The app reads `ACRYLBLENDS_HOST` and `ACRYLBLENDS_PORT`, not `PORT`; without them it listens on `127.0.0.1` at a
|
|
60
|
+
port chosen from its folder. A server needs `ACRYLBLENDS_HOST=0.0.0.0 ACRYLBLENDS_PORT=8080 NODE_ENV=production npm start` (verified: it answered on the
|
|
61
|
+
LAN). If Blends ships `PORT`, the handout switches to it.
|
|
62
|
+
- **Windows.** Windows PowerShell 5.1 has no `&&` (two lines, or `;`); PowerShell sets variables with `$env:NAME="value"`; cmd.exe's `Ctrl-C` asks
|
|
63
|
+
`Terminate batch job (Y/N)?` (answer `Y`); cmd.exe does not expand `~` (use `%USERPROFILE%`). Node 22 prints only `Restarting 'src/main.ts'` on a save;
|
|
64
|
+
Node 24 and 26 print `Change detected …` before it.
|
|
65
|
+
- **F (the door through a DeepSeek model with no login).** pi with a DeepSeek key works today; do not promise more than that.
|
|
66
|
+
|
|
67
|
+
## What the 1.0.10 walk found, block by block
|
|
68
|
+
|
|
69
|
+
The final macOS walk on 1.0.10 (2026-10-30), verbatim from the handout as it stood before this revision, with pi on DeepSeek. Every block passed; these
|
|
70
|
+
are the places where the handout text differed from what the walk saw, and each one is now handled in the handout.
|
|
71
|
+
|
|
72
|
+
1. Block 1: npm test now has 14 tests (the guide gives no number). "Change detected … Restarting" matches on Node 24; on Node 22 only "Restarting"
|
|
73
|
+
prints (seen on z370n).
|
|
74
|
+
2. Block 2: "keep the app's own page (/) open in a second tab, because the panel lives there" is outdated: the panel is on every page now and followed the
|
|
75
|
+
agent to /board. The page is dark on a dark-mode Mac (screenshots s1-first-page/s3-board look different); the panel stays light on the dark page.
|
|
76
|
+
3. Block 3: the guide's block 2 prompt asks for no sidebar toggle, so "open the sidebar" has nothing to open (pi says so and goes on). "an indicator in
|
|
77
|
+
the corner says the agent is driving, with a stop button": it shows only while each single door call runs (a fraction of a second), so an attendee
|
|
78
|
+
will hardly see it; it never showed in 33 frames taken every 3 s. "Click New card twice" added no cards: pi's board needs a title first; the prompt
|
|
79
|
+
only asks whether the counts agree. "seven door calls in about twenty seconds" was 6 calls in 1:41 with pi.
|
|
80
|
+
4. Block 4: the guide says "use the File menu". On macOS Settings is in the app menu (my-app>Settings..., Cmd+,); pi found it there itself. Elsewhere it
|
|
81
|
+
is the first File item. "switch the appearance to dark" shows no change on a dark-mode Mac, and the agent-built /board ignores the app theme (its CSS
|
|
82
|
+
follows the system); the change shows on the template's / and /settings, and in other open windows only after a reload (switching to Light in window
|
|
83
|
+
3, window 1 on / changed only after act reload). The TODO(1.0.4-C) paragraph is outdated: the window, menu and settings control has shipped.
|
|
84
|
+
Important: if the browser tab from blocks 2-3 is still open, the agent's door calls from the window's panel go to that browser tab, not the window. My
|
|
85
|
+
first in-window drive moved the hidden tab and the window stayed on /. With the tab closed it worked.
|
|
86
|
+
5. Block 5: "That is the same app on any Node host … one port" names no port: the app binds 127.0.0.1 on a port derived from its folder path, ignores PORT
|
|
87
|
+
(PORT=3299 still gave 3991), and needs ACRYLBLENDS_PORT and ACRYLBLENDS_HOST (only the app's README names them; production.md does not).
|
|
74
88
|
|
|
75
89
|
## The no-network fallback
|
|
76
90
|
|
|
77
|
-
|
|
91
|
+
1. Prepared apps on every machine cover blocks 1-3; the agent's model still needs the network, so block 2 and 3 need a connection or a demo.
|
|
92
|
+
2. Block 5's registry needs GitHub; if the venue is offline, publish from your machine on a hotspot at the end, or show the recording.
|
|
93
|
+
3. Keep one phone hotspot for the room.
|
|
78
94
|
|
|
79
|
-
|
|
80
|
-
2. Step 8 uses the cloned registry and the installed `blends-core`; no network needed.
|
|
81
|
-
3. Step 7 needs the agent's own model, so it cannot run offline. Demo it from your machine on a tethered connection, or record it (a 4-minute
|
|
82
|
-
screen recording of the codex run is enough).
|
|
83
|
-
4. Keep one machine on a phone hotspot for `npm create` failures.
|
|
95
|
+
## Demo script (five minutes, if the room is behind)
|
|
84
96
|
|
|
85
|
-
|
|
97
|
+
1. Prepared app, panel open: ask for a card with a count. Narrate the panel's `Working...` line and the page as it reloads.
|
|
98
|
+
2. Ask: "open the sidebar, tick one card, change the filter to done, tell me the counts." Point at the page changing and at the driving bar as each action
|
|
99
|
+
runs.
|
|
100
|
+
3. Show `.acryl/audit/` afterwards: every action is a line.
|
|
101
|
+
4. Close the browser tab, switch to the desktop window and repeat one click there; then open Settings from the menu.
|
|
102
|
+
5. Show the registry listing with an app already published, and the four commands that put it there.
|
|
86
103
|
|
|
87
|
-
|
|
88
|
-
2. Ask: "Add a route GET /agent-built to src/routes.ts that returns {\"built\": true}, then run the tests and tell me what happened."
|
|
89
|
-
3. Narrate while it runs: the agent reads `AGENTS.md`, reads `docs/framework`, edits `src/routes.ts`, runs the tests; the terminal prints
|
|
90
|
-
`Change detected … Restarting`; reload `/agent-built` and show `{"built":true}`.
|
|
91
|
-
4. Point at the panel's stop button and the audit line the panel writes under `.acrylblends/audit/`.
|
|
104
|
+
## Screenshots
|
|
92
105
|
|
|
93
|
-
|
|
106
|
+
Taken on 1.0.10 on macOS in dark mode (the pages follow the system theme), 1280 wide, no personal data, tokens or real home paths:
|
|
94
107
|
|
|
95
|
-
|
|
108
|
+
| File | Shows |
|
|
109
|
+
| --- | --- |
|
|
110
|
+
| `s1-first-page.webp` | the first page with the panel open (block 1) |
|
|
111
|
+
| `s2-panel-building.webp` | the panel with the build request and `Working... 0:04` (block 2) |
|
|
112
|
+
| `s3-board.webp` | a board an agent built (block 2; from an earlier run, kept because it shows the result best) |
|
|
113
|
+
| `s4-agent-drives-window.webp` | the agent driving the board in the desktop window: the Done filter it just set (block 4) |
|
|
114
|
+
| `s5-two-windows.webp` | two desktop windows: the app's page in the dark appearance, and the Settings window showing `Saved: Dark` (block 4) |
|
|
115
|
+
| `s6-registry.webp` | the registry listing (block 5) |
|
|
96
116
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
S4 and S5 are page captures of the desktop windows (through the window's DevTools), without the window frame; a capture with the frame needs the
|
|
118
|
+
screen-recording permission on the machine that takes it.
|
|
119
|
+
|
|
120
|
+
## Resetting between sessions
|
|
101
121
|
|
|
102
|
-
|
|
122
|
+
Everything a person makes lives inside their app folder and `~/acryl-workshop`. To reset a machine, delete the app folders and copy the prepared one back;
|
|
123
|
+
nothing is installed globally except the agent, `gh` and Node.
|
|
103
124
|
|
|
104
125
|
## What is still open
|
|
105
126
|
|
|
106
|
-
-
|
|
107
|
-
|
|
108
|
-
-
|
|
127
|
+
- Close-the-tab advice in block 4 until the door aims at the window the agent was asked from.
|
|
128
|
+
- The appearance reaching open windows live, and an agent-built page following the app's appearance: reported to Blends; the handout says "reload".
|
|
129
|
+
- `PORT` for production: if Blends ships it, the handout's server line switches from `ACRYLBLENDS_PORT` to `PORT`.
|
|
130
|
+
- The handout's hosted-workspace section (browser-only attendees) stays TODO(M9) until that workspace is live; the one-click WebBoxes.ai deploy lives
|
|
131
|
+
there too.
|
|
@@ -4,6 +4,8 @@ import { _ as UiRequest, n as AuditEntry, r as ChannelToHost, v as UiResult } fr
|
|
|
4
4
|
/** The slice of a page's stream the channel needs, so tests can supply their own. */
|
|
5
5
|
interface PageStream {
|
|
6
6
|
send(data: string): void;
|
|
7
|
+
/** Tell the page something that is not a call (`run`: `1` while a run asked for from its panel goes, `0` when it ends). A stream that cannot (a test's) leaves it out. */
|
|
8
|
+
notify?(event: string, data: string): void;
|
|
7
9
|
close(): void;
|
|
8
10
|
}
|
|
9
11
|
interface ChannelOptions {
|
|
@@ -16,14 +18,16 @@ interface ChannelOptions {
|
|
|
16
18
|
readonly attachWaitMs?: number;
|
|
17
19
|
}
|
|
18
20
|
/**
|
|
19
|
-
* The pages and who drives which. One page answers a call, chosen the same way every time: the page
|
|
20
|
-
* one in front (it reports `focused`), else the most recently active; a page that did not acknowledge a call in time goes to the end of the line. An explicit desktop `window` picks its page.
|
|
21
|
+
* The pages and who drives which. One page answers a call, chosen the same way every time: the page whose panel asked for the run that is making the call (`driveFor`), else the page the
|
|
22
|
+
* Host just sent somewhere (it comes back as a new page, `prefer`), else the one in front (it reports `focused`), else the most recently active; a page that did not acknowledge a call in time goes to the end of the line. An explicit desktop `window` picks its page.
|
|
21
23
|
*/
|
|
22
24
|
declare class UiChannel {
|
|
23
25
|
private readonly ackMs;
|
|
24
26
|
private readonly attachWaitMs;
|
|
25
27
|
/** The page the Host sent to a new place and that came back: it keeps being driven until the person focuses another page. */
|
|
26
28
|
private preferred;
|
|
29
|
+
/** The pages whose panels have a run going, the latest last: a call with no `window` goes to the latest of them that is still connected. */
|
|
30
|
+
private readonly askers;
|
|
27
31
|
constructor(options?: ChannelOptions);
|
|
28
32
|
private readonly connections;
|
|
29
33
|
private readonly pending;
|
|
@@ -47,6 +51,14 @@ declare class UiChannel {
|
|
|
47
51
|
focused: boolean;
|
|
48
52
|
shellWindow?: number;
|
|
49
53
|
}[];
|
|
54
|
+
/**
|
|
55
|
+
* A run asked for from this page's panel is going: its calls (which name no window) are for this page, whatever else is open and whichever was driven last, until the run ends.
|
|
56
|
+
* An explicit desktop `window` still picks its own page.
|
|
57
|
+
* @returns the function to call when the run ends.
|
|
58
|
+
*/
|
|
59
|
+
driveFor(windowId: string): () => void;
|
|
60
|
+
private tellPage;
|
|
61
|
+
private tell;
|
|
50
62
|
/** Drive this page from now on (it is the one the Host just sent to a new place), until the person focuses another. */
|
|
51
63
|
prefer(windowId: string): void;
|
|
52
64
|
/**
|
|
@@ -78,7 +90,7 @@ declare class UiChannel {
|
|
|
78
90
|
reloadAll(timeoutMs?: number): Promise<number>;
|
|
79
91
|
/** Close every page's stream and settle every pending call as `unloaded`. */
|
|
80
92
|
close(): void;
|
|
81
|
-
/** The order pages are driven in: the one the Host sent somewhere, suspect ones last, the one in front, then the most recently active. */
|
|
93
|
+
/** The order pages are driven in: the one whose panel asked, the one the Host sent somewhere, suspect ones last, the one in front, then the most recently active. */
|
|
82
94
|
private ordered;
|
|
83
95
|
/** Forget a connection; its calls in flight settle as `disconnected` at once rather than waiting for their timeout. */
|
|
84
96
|
private drop;
|
package/lib/cordis/door.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { f as UiActionResult, y as UiSnapshot } from "../protocol-a2aqrp2X.js";
|
|
2
|
-
import { i as UiChannel, r as PageStream, t as AuditLog } from "../audit-
|
|
2
|
+
import { i as UiChannel, r as PageStream, t as AuditLog } from "../audit-BFpULBCj.js";
|
|
3
3
|
import { Context } from "@deepseek-ai/cordis";
|
|
4
4
|
import z from "@deepseek-ai/schemastery";
|
|
5
5
|
|
|
@@ -139,6 +139,8 @@ interface VerbAnswer {
|
|
|
139
139
|
declare class Door {
|
|
140
140
|
private readonly deps;
|
|
141
141
|
constructor(deps: DoorDeps);
|
|
142
|
+
/** A run asked for from the panel of this page is going: its verbs that name no window are for that page. @returns the function to call when the run ends. */
|
|
143
|
+
driveFor(windowId: string): () => void;
|
|
142
144
|
/** Run one verb. @throws DoorError or UiControlError. */
|
|
143
145
|
run(verb: string, args: unknown, signal: AbortSignal): Promise<VerbAnswer>;
|
|
144
146
|
brief(): VerbAnswer;
|
package/lib/cordis/door.js
CHANGED
|
@@ -4,7 +4,7 @@ import { r as loopbackAuthority } from "../loopback-only-BbasoF7R.js";
|
|
|
4
4
|
import "../helpers-BEjcdbgw.js";
|
|
5
5
|
import { n as clientModules } from "../client-modules-drj4mjhj.js";
|
|
6
6
|
import { a as MAX_WAIT_MS, d as parseChannelToHost, l as UiControlError, p as parseUiRequest, r as MAX_SNAPSHOT_NODES, u as WINDOW_ID } from "../protocol-CQ_if7Dg.js";
|
|
7
|
-
import { a as INVALID_JSON, c as operatorOnly, d as AuditLog, f as auditPath, i as DOOR_PREFIX, l as privateApi, o as error, p as UiChannel, r as pageChannelRoutes, s as jsonBody, t as renderSnapshot, u as readJson } from "../snapshot-text-
|
|
7
|
+
import { a as INVALID_JSON, c as operatorOnly, d as AuditLog, f as auditPath, i as DOOR_PREFIX, l as privateApi, o as error, p as UiChannel, r as pageChannelRoutes, s as jsonBody, t as renderSnapshot, u as readJson } from "../snapshot-text-BwM6T2nG.js";
|
|
8
8
|
import "../src-BTBm4OPD.js";
|
|
9
9
|
import "../middleware-BfG_fp8P.js";
|
|
10
10
|
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
@@ -620,6 +620,10 @@ var Door = class {
|
|
|
620
620
|
constructor(deps) {
|
|
621
621
|
this.deps = deps;
|
|
622
622
|
}
|
|
623
|
+
/** A run asked for from the panel of this page is going: its verbs that name no window are for that page. @returns the function to call when the run ends. */
|
|
624
|
+
driveFor(windowId) {
|
|
625
|
+
return this.deps.channel.driveFor(windowId);
|
|
626
|
+
}
|
|
623
627
|
/** Run one verb. @throws DoorError or UiControlError. */
|
|
624
628
|
async run(verb, args, signal) {
|
|
625
629
|
const input = typeof args === "object" && args !== null && !Array.isArray(args) ? args : {};
|
|
@@ -1186,6 +1190,12 @@ function pageSocketRoutes(channel, options) {
|
|
|
1186
1190
|
d: data
|
|
1187
1191
|
});
|
|
1188
1192
|
},
|
|
1193
|
+
notify: (event, data) => {
|
|
1194
|
+
write({
|
|
1195
|
+
e: event,
|
|
1196
|
+
d: data
|
|
1197
|
+
});
|
|
1198
|
+
},
|
|
1189
1199
|
close: () => {
|
|
1190
1200
|
ws.close(1e3, "replaced");
|
|
1191
1201
|
}
|
package/lib/cordis/state.d.ts
CHANGED
|
@@ -24,9 +24,10 @@ declare class State extends Service {
|
|
|
24
24
|
keys(): string[];
|
|
25
25
|
/**
|
|
26
26
|
* The current value of `key` as a server-sent event stream: the value now, then one event per change, until the client cancels or the router
|
|
27
|
-
* is disposed (both abort the stream). A comment line goes out every 15 seconds so proxies and browsers keep an idle stream open.
|
|
27
|
+
* is disposed (both abort the stream). A comment line goes out every 15 seconds so proxies and browsers keep an idle stream open. A string value travels as it is; with `json`
|
|
28
|
+
* (the `?json=1` of the browser client) every value is JSON, so `"12"` and `12` can be told apart.
|
|
28
29
|
*/
|
|
29
|
-
stream(key: string, c: Context$1): Response | undefined;
|
|
30
|
+
stream(key: string, c: Context$1, json?: boolean): Response | undefined;
|
|
30
31
|
}
|
|
31
32
|
declare function apply(ctx: Context): void;
|
|
32
33
|
//#endregion
|