@agentorg/cli 0.0.5 → 0.0.7
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 +23 -104
- package/dist/node_modules/@agentorg/computer/LICENSE +201 -0
- package/dist/node_modules/@agentorg/computer/NOTICE +2 -0
- package/dist/node_modules/@agentorg/computer/dist/THIRD_PARTY_LICENSES.txt +1321 -0
- package/dist/node_modules/@agentorg/computer/dist/sdk.js +24909 -0
- package/dist/node_modules/@agentorg/computer/dist/types/generated/schema.d.ts +860 -0
- package/dist/node_modules/@agentorg/computer/dist/types/sdk.d.ts +242 -0
- package/dist/node_modules/@agentorg/computer/package.json +12 -0
- package/dist/node_modules/@agentorg/computer-connector/dist/src/index.d.ts +1 -0
- package/dist/node_modules/@agentorg/computer-connector/dist/src/index.js +1 -0
- package/dist/node_modules/@agentorg/computer-connector/dist/src/provider.d.ts +24 -0
- package/dist/node_modules/@agentorg/computer-connector/dist/src/provider.js +482 -0
- package/dist/node_modules/@agentorg/computer-connector/dist/src/unit.d.ts +19 -0
- package/dist/node_modules/@agentorg/computer-connector/dist/src/unit.js +149 -0
- package/dist/node_modules/@agentorg/computer-connector/package.json +33 -0
- package/dist/node_modules/@agentorg/computer-connector/skills/browser/SKILL.md +31 -0
- package/dist/node_modules/@agentorg/computer-connector/skills/computer/SKILL.md +30 -0
- package/dist/node_modules/@agentorg/computer-connector/skills/files/SKILL.md +28 -0
- package/dist/node_modules/@agentorg/computer-connector/skills/terminal/SKILL.md +39 -0
- package/dist/node_modules/@agentorg/computer-connector/skills/web-research/SKILL.md +29 -0
- package/dist/node_modules/@agentorg/hub/dist/src/hub-actor.d.ts +2 -7
- package/dist/node_modules/@agentorg/hub/dist/src/hub-actor.js +4 -144
- package/dist/node_modules/@agentorg/hub/dist/src/index.d.ts +1 -3
- package/dist/node_modules/@agentorg/hub/dist/src/index.js +1 -3
- package/dist/node_modules/@agentorg/hub/dist/src/router.d.ts +9 -58
- package/dist/node_modules/@agentorg/hub/dist/src/router.js +41 -414
- package/dist/node_modules/@agentorg/hub/dist/src/state.d.ts +17 -317
- package/dist/node_modules/@agentorg/hub/dist/src/state.js +42 -536
- package/dist/node_modules/@agentorg/hub/dist/src/validate.d.ts +1 -3
- package/dist/node_modules/@agentorg/hub/dist/src/validate.js +19 -17
- package/dist/node_modules/@agentorg/hub/package.json +0 -3
- package/dist/node_modules/@agentorg/interfaces/dist/src/agent-provider.d.ts +119 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/agent-provider.js +96 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/agent-settings.d.ts +42 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/agent-settings.js +53 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/chat.d.ts +93 -38
- package/dist/node_modules/@agentorg/interfaces/dist/src/chat.js +71 -22
- package/dist/node_modules/@agentorg/interfaces/dist/src/connection.d.ts +36 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/connection.js +31 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/folders.d.ts +19 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/folders.js +25 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/hub.d.ts +16 -286
- package/dist/node_modules/@agentorg/interfaces/dist/src/hub.js +17 -159
- package/dist/node_modules/@agentorg/interfaces/dist/src/index.d.ts +9 -9
- package/dist/node_modules/@agentorg/interfaces/dist/src/index.js +9 -9
- package/dist/node_modules/@agentorg/interfaces/dist/src/kv.d.ts +2 -2
- package/dist/node_modules/@agentorg/interfaces/dist/src/kv.js +2 -2
- package/dist/node_modules/@agentorg/interfaces/dist/src/llm-session.d.ts +2 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/llm-session.js +2 -1
- package/dist/node_modules/@agentorg/interfaces/dist/src/manager.d.ts +626 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/manager.js +349 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/tools.d.ts +39 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/tools.js +43 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/units.d.ts +460 -0
- package/dist/node_modules/@agentorg/interfaces/dist/src/units.js +204 -0
- package/dist/node_modules/@agentorg/looper/dist/src/index.d.ts +5 -0
- package/dist/node_modules/@agentorg/looper/dist/src/index.js +5 -0
- package/dist/node_modules/@agentorg/looper/dist/src/loop.d.ts +75 -0
- package/dist/node_modules/@agentorg/looper/dist/src/loop.js +332 -0
- package/dist/node_modules/@agentorg/looper/dist/src/looper.d.ts +71 -0
- package/dist/node_modules/@agentorg/looper/dist/src/looper.js +282 -0
- package/dist/node_modules/@agentorg/looper/dist/src/record.d.ts +99 -0
- package/dist/node_modules/@agentorg/looper/dist/src/record.js +278 -0
- package/dist/node_modules/@agentorg/looper/dist/src/tools.d.ts +11 -0
- package/dist/node_modules/@agentorg/looper/dist/src/tools.js +42 -0
- package/dist/node_modules/@agentorg/looper/dist/src/types.d.ts +147 -0
- package/dist/node_modules/@agentorg/looper/dist/src/types.js +32 -0
- package/dist/node_modules/@agentorg/looper/package.json +24 -0
- package/dist/node_modules/@agentorg/manager/dist/src/activity.d.ts +18 -0
- package/dist/node_modules/@agentorg/manager/dist/src/activity.js +65 -0
- package/dist/node_modules/@agentorg/manager/dist/src/control.d.ts +134 -0
- package/dist/node_modules/@agentorg/manager/dist/src/control.js +1115 -0
- package/dist/node_modules/@agentorg/manager/dist/src/form.d.ts +40 -0
- package/dist/node_modules/@agentorg/manager/dist/src/form.js +191 -0
- package/dist/node_modules/@agentorg/manager/dist/src/index.d.ts +1 -0
- package/dist/node_modules/@agentorg/manager/dist/src/index.js +1 -0
- package/dist/node_modules/@agentorg/manager/dist/src/manager.d.ts +25 -0
- package/dist/node_modules/@agentorg/manager/dist/src/manager.js +680 -0
- package/dist/node_modules/@agentorg/manager/dist/src/skills.d.ts +27 -0
- package/dist/node_modules/@agentorg/manager/dist/src/skills.js +152 -0
- package/dist/node_modules/@agentorg/manager/dist/src/stack.d.ts +454 -0
- package/dist/node_modules/@agentorg/manager/dist/src/stack.js +917 -0
- package/dist/node_modules/@agentorg/manager/package.json +30 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/connection.d.ts +34 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/connection.js +296 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/index.d.ts +4 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/index.js +4 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/kinds.d.ts +158 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/kinds.js +164 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/provider.d.ts +22 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/provider.js +197 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/public.d.ts +6 -0
- package/dist/node_modules/@agentorg/mcp/dist/src/public.js +72 -0
- package/dist/node_modules/@agentorg/mcp/package.json +31 -0
- package/dist/node_modules/@agentorg/sdk/dist/src/cli.js +3 -23
- package/dist/node_modules/@agentorg/sdk/dist/src/client.d.ts +4 -25
- package/dist/node_modules/@agentorg/sdk/dist/src/client.js +5 -55
- package/dist/node_modules/@agentorg/sdk/dist/src/errors.d.ts +1 -1
- package/dist/node_modules/@agentorg/sdk/dist/src/errors.js +3 -3
- package/dist/node_modules/@agentorg/sdk/dist/src/filled.d.ts +21 -0
- package/dist/node_modules/@agentorg/sdk/dist/src/filled.js +24 -0
- package/dist/node_modules/@agentorg/sdk/dist/src/index.d.ts +3 -2
- package/dist/node_modules/@agentorg/sdk/dist/src/index.js +2 -1
- package/dist/node_modules/@agentorg/sdk/dist/src/interface.d.ts +6 -34
- package/dist/node_modules/@agentorg/sdk/dist/src/interface.js +3 -24
- package/dist/node_modules/@agentorg/sdk/dist/src/module-host.d.ts +8 -17
- package/dist/node_modules/@agentorg/sdk/dist/src/module-host.js +15 -87
- package/dist/node_modules/@agentorg/sdk/dist/src/module.d.ts +10 -76
- package/dist/node_modules/@agentorg/sdk/dist/src/module.js +3 -23
- package/dist/node_modules/@agentorg/sdk/dist/src/person-commands.js +0 -5
- package/dist/node_modules/@agentorg/sdk/dist/src/runtime.d.ts +3 -27
- package/dist/node_modules/@agentorg/sdk/dist/src/runtime.js +5 -100
- package/dist/node_modules/@agentorg/sdk/dist/src/testing.d.ts +7 -8
- package/dist/node_modules/@agentorg/sdk/dist/src/testing.js +12 -24
- package/dist/node_modules/@agentorg/sdk/package.json +4 -37
- package/dist/node_modules/@agentorg/shell/dist/app.css +4624 -739
- package/dist/node_modules/@agentorg/shell/dist/app.js +245 -202
- package/dist/node_modules/@agentorg/shell/package.json +23 -10
- package/dist/node_modules/@agentorg/wire/dist/src/frames.d.ts +2 -3
- package/dist/node_modules/@agentorg/wire/dist/src/frames.js +2 -3
- package/dist/node_modules/@agentorg/wire/dist/src/ops.d.ts +5 -34
- package/dist/node_modules/@agentorg/wire/dist/src/ops.js +2 -17
- package/dist/node_modules/assistant/dist/src/chats.d.ts +92 -0
- package/dist/node_modules/assistant/dist/src/chats.js +357 -0
- package/dist/node_modules/assistant/dist/src/engine.d.ts +42 -0
- package/dist/node_modules/assistant/dist/src/engine.js +160 -0
- package/dist/node_modules/assistant/dist/src/local-store.d.ts +3 -0
- package/dist/node_modules/assistant/dist/src/local-store.js +58 -0
- package/dist/node_modules/assistant/dist/src/provider.d.ts +21 -0
- package/dist/node_modules/assistant/dist/src/provider.js +259 -0
- package/dist/node_modules/assistant/dist/src/settings.d.ts +17 -0
- package/dist/node_modules/assistant/dist/src/settings.js +43 -0
- package/dist/node_modules/assistant/dist/src/tools.d.ts +57 -0
- package/dist/node_modules/assistant/dist/src/tools.js +102 -0
- package/dist/node_modules/assistant/package.json +30 -0
- package/dist/node_modules/chatgpt/dist/src/account.d.ts +52 -0
- package/dist/node_modules/chatgpt/dist/src/account.js +270 -0
- package/dist/node_modules/chatgpt/dist/src/encoding.d.ts +7 -0
- package/dist/node_modules/chatgpt/dist/src/encoding.js +20 -0
- package/dist/node_modules/chatgpt/dist/src/file-store.d.ts +9 -0
- package/dist/node_modules/chatgpt/dist/src/file-store.js +68 -0
- package/dist/node_modules/chatgpt/dist/src/index.d.ts +1 -0
- package/dist/node_modules/chatgpt/dist/src/index.js +1 -0
- package/dist/node_modules/chatgpt/dist/src/jwt.d.ts +15 -0
- package/dist/node_modules/chatgpt/dist/src/jwt.js +37 -0
- package/dist/node_modules/chatgpt/dist/src/oauth.d.ts +43 -0
- package/dist/node_modules/chatgpt/dist/src/oauth.js +104 -0
- package/dist/node_modules/chatgpt/dist/src/program.d.ts +23 -0
- package/dist/node_modules/chatgpt/dist/src/program.js +41 -0
- package/dist/node_modules/chatgpt/dist/src/responses.d.ts +54 -0
- package/dist/node_modules/chatgpt/dist/src/responses.js +300 -0
- package/dist/node_modules/chatgpt/dist/src/serve.d.ts +65 -0
- package/dist/node_modules/chatgpt/dist/src/serve.js +46 -0
- package/dist/node_modules/chatgpt/package.json +33 -0
- package/dist/src/api.d.ts +5 -34
- package/dist/src/api.js +10 -68
- package/dist/src/cli.js +3 -7
- package/dist/src/folders.d.ts +2 -0
- package/dist/src/folders.js +45 -0
- package/dist/src/gateway.d.ts +13 -8
- package/dist/src/gateway.js +119 -296
- package/dist/src/index.d.ts +4 -5
- package/dist/src/index.js +3 -4
- package/dist/src/live.d.ts +17 -0
- package/dist/src/live.js +109 -0
- package/dist/src/notes.d.ts +11 -0
- package/dist/src/notes.js +64 -0
- package/dist/src/oauth.d.ts +16 -0
- package/dist/src/oauth.js +46 -0
- package/dist/src/programs.d.ts +36 -0
- package/dist/src/programs.js +198 -0
- package/dist/src/signin.d.ts +12 -3
- package/dist/src/signin.js +30 -6
- package/package.json +4 -11
- package/dist/bundled/index.json +0 -6
- package/dist/bundled/sha256-0e91cc3d0e9762b81abc2427b5496b20f383abcd6fb97d928a8d50e956b54d1f.agentorg +0 -0
- package/dist/bundled/sha256-1f64ca62a0209d767d6aa6c4feb50b0653d60f10bebbc301f79bd3a37e0153c1.agentorg +0 -0
- package/dist/bundled/sha256-4055f8fddf6b90f3d356543f554b2a9e9a2c4a8827a8774f8f87952dc1692331.agentorg +0 -0
- package/dist/bundled/sha256-e356ea3c1899138a8494baf521556831006f38534fa9e92ae873e7e6956c3a46.agentorg +0 -0
- package/dist/node_modules/@agentorg/hub/dist/src/build.d.ts +0 -17
- package/dist/node_modules/@agentorg/hub/dist/src/build.js +0 -120
- package/dist/node_modules/@agentorg/hub/dist/src/logs.d.ts +0 -33
- package/dist/node_modules/@agentorg/hub/dist/src/logs.js +0 -162
- package/dist/node_modules/@agentorg/hub/dist/src/net.d.ts +0 -41
- package/dist/node_modules/@agentorg/hub/dist/src/net.js +0 -265
- package/dist/node_modules/@agentorg/hub/dist/src/processes.d.ts +0 -78
- package/dist/node_modules/@agentorg/hub/dist/src/processes.js +0 -485
- package/dist/node_modules/@agentorg/hub/dist/src/storage.d.ts +0 -38
- package/dist/node_modules/@agentorg/hub/dist/src/storage.js +0 -194
- package/dist/node_modules/@agentorg/interfaces/dist/src/http-egress.d.ts +0 -6
- package/dist/node_modules/@agentorg/interfaces/dist/src/http-egress.js +0 -7
- package/dist/node_modules/@agentorg/interfaces/dist/src/installer.d.ts +0 -191
- package/dist/node_modules/@agentorg/interfaces/dist/src/installer.js +0 -136
- package/dist/node_modules/@agentorg/interfaces/dist/src/layout.d.ts +0 -47
- package/dist/node_modules/@agentorg/interfaces/dist/src/layout.js +0 -52
- package/dist/node_modules/@agentorg/interfaces/dist/src/rules.d.ts +0 -35
- package/dist/node_modules/@agentorg/interfaces/dist/src/rules.js +0 -37
- package/dist/node_modules/@agentorg/interfaces/dist/src/storage-admin.d.ts +0 -23
- package/dist/node_modules/@agentorg/interfaces/dist/src/storage-admin.js +0 -31
- package/dist/node_modules/@agentorg/interfaces/dist/src/ui-shell.d.ts +0 -14
- package/dist/node_modules/@agentorg/interfaces/dist/src/ui-shell.js +0 -26
- package/dist/node_modules/@agentorg/interfaces/dist/src/ui-view.d.ts +0 -27
- package/dist/node_modules/@agentorg/interfaces/dist/src/ui-view.js +0 -26
- package/dist/node_modules/@agentorg/kit/dist/src/chat.d.ts +0 -37
- package/dist/node_modules/@agentorg/kit/dist/src/chat.js +0 -131
- package/dist/node_modules/@agentorg/kit/dist/src/components.d.ts +0 -94
- package/dist/node_modules/@agentorg/kit/dist/src/components.js +0 -66
- package/dist/node_modules/@agentorg/kit/dist/src/icons.d.ts +0 -17
- package/dist/node_modules/@agentorg/kit/dist/src/icons.js +0 -30
- package/dist/node_modules/@agentorg/kit/dist/src/index.d.ts +0 -6
- package/dist/node_modules/@agentorg/kit/dist/src/index.js +0 -10
- package/dist/node_modules/@agentorg/kit/dist/src/markdown.d.ts +0 -9
- package/dist/node_modules/@agentorg/kit/dist/src/markdown.js +0 -14
- package/dist/node_modules/@agentorg/kit/dist/src/resizable.d.ts +0 -5
- package/dist/node_modules/@agentorg/kit/dist/src/resizable.js +0 -8
- package/dist/node_modules/@agentorg/kit/dist/src/styles.d.ts +0 -11
- package/dist/node_modules/@agentorg/kit/dist/src/styles.js +0 -166
- package/dist/node_modules/@agentorg/kit/package.json +0 -44
- package/dist/node_modules/@agentorg/sdk/dist/frame/runtime.js +0 -753
- package/dist/node_modules/@agentorg/sdk/dist/host/runner.js +0 -21963
- package/dist/node_modules/@agentorg/sdk/dist/src/build.d.ts +0 -2
- package/dist/node_modules/@agentorg/sdk/dist/src/build.js +0 -2
- package/dist/node_modules/@agentorg/sdk/dist/src/client-http.d.ts +0 -24
- package/dist/node_modules/@agentorg/sdk/dist/src/client-http.js +0 -247
- package/dist/node_modules/@agentorg/sdk/dist/src/describe.d.ts +0 -13
- package/dist/node_modules/@agentorg/sdk/dist/src/describe.js +0 -16
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-base.d.ts +0 -8
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-base.js +0 -64
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-entry.d.ts +0 -1
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-entry.js +0 -35
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-host.d.ts +0 -57
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-host.js +0 -293
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-protocol.d.ts +0 -124
- package/dist/node_modules/@agentorg/sdk/dist/src/frame-protocol.js +0 -16
- package/dist/node_modules/@agentorg/sdk/dist/src/frame.d.ts +0 -25
- package/dist/node_modules/@agentorg/sdk/dist/src/frame.js +0 -248
- package/dist/node_modules/@agentorg/sdk/dist/src/host-main.d.ts +0 -1
- package/dist/node_modules/@agentorg/sdk/dist/src/host-main.js +0 -60
- package/dist/node_modules/@agentorg/sdk/dist/src/host.d.ts +0 -25
- package/dist/node_modules/@agentorg/sdk/dist/src/host.js +0 -92
- package/dist/node_modules/@agentorg/sdk/dist/src/manifest-api.d.ts +0 -2
- package/dist/node_modules/@agentorg/sdk/dist/src/manifest-api.js +0 -2
- package/dist/node_modules/@agentorg/sdk/dist/src/manifest.d.ts +0 -56
- package/dist/node_modules/@agentorg/sdk/dist/src/manifest.js +0 -165
- package/dist/node_modules/@agentorg/sdk/dist/src/package.d.ts +0 -60
- package/dist/node_modules/@agentorg/sdk/dist/src/package.js +0 -538
- package/dist/node_modules/@agentorg/sdk/dist/src/tar.d.ts +0 -7
- package/dist/node_modules/@agentorg/sdk/dist/src/tar.js +0 -71
- package/dist/node_modules/@agentorg/shell/dist/agent-bindings.js +0 -59
- package/dist/node_modules/@agentorg/shell/src/agent-bindings.ts +0 -107
- package/dist/src/frames.d.ts +0 -23
- package/dist/src/frames.js +0 -78
- package/dist/src/layout.d.ts +0 -44
- package/dist/src/layout.js +0 -90
- package/dist/src/model.d.ts +0 -54
- package/dist/src/model.js +0 -299
- package/dist/src/rules.d.ts +0 -71
- package/dist/src/rules.js +0 -157
- package/dist/src/transfer.d.ts +0 -30
- package/dist/src/transfer.js +0 -110
package/dist/src/gateway.js
CHANGED
|
@@ -3,33 +3,32 @@ import { createServer } from "node:http";
|
|
|
3
3
|
import { createRequire } from "node:module";
|
|
4
4
|
import { dirname, join, normalize, resolve, sep } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
-
import { Hub, listen, PERSON
|
|
7
|
-
import { accountLogin,
|
|
8
|
-
import { Refused } from "@agentorg/sdk";
|
|
6
|
+
import { Hub, listen, PERSON } from "@agentorg/hub";
|
|
7
|
+
import { accountLogin, agents, connections, hubActors, hubAudit, hubBindings, hubExports, hubGrants, llmSession, skills, } from "@agentorg/interfaces";
|
|
8
|
+
import { describeInterface, Refused } from "@agentorg/sdk";
|
|
9
9
|
import { connect } from "@agentorg/sdk/client";
|
|
10
10
|
import { WebSocketServer } from "ws";
|
|
11
11
|
import { serveSocket } from "./api.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
12
|
+
import { callFolders } from "./folders.js";
|
|
13
|
+
import { LIVE_MAX, pipeLive } from "./live.js";
|
|
14
|
+
import { Notes } from "./notes.js";
|
|
15
|
+
import { oauthRoute } from "./oauth.js";
|
|
16
|
+
import { closePackageActors, startPrograms, } from "./programs.js";
|
|
16
17
|
import { SignIn } from "./signin.js";
|
|
17
|
-
import { MAX_TRANSFER, packageArchive, pinnedHashes, readSystem, withTemporaryFile, writeSystem, } from "./transfer.js";
|
|
18
18
|
/**
|
|
19
|
-
* The person's slots the gateway declares: every `hub.*` it holds,
|
|
20
|
-
*
|
|
19
|
+
* The person's slots the gateway declares: every `hub.*` it holds, and what the first run binds
|
|
20
|
+
* (any may be unbound): `login`, the model's account sign-in, and management's three.
|
|
21
21
|
*/
|
|
22
22
|
const SLOTS = {
|
|
23
|
-
packages: hubPackages,
|
|
24
23
|
actors: hubActors,
|
|
25
24
|
bindings: hubBindings,
|
|
26
25
|
grants: hubGrants,
|
|
27
26
|
exports: hubExports,
|
|
28
27
|
audit: hubAudit,
|
|
29
|
-
store: kv,
|
|
30
28
|
login: accountLogin,
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
agents,
|
|
30
|
+
connections,
|
|
31
|
+
skills,
|
|
33
32
|
};
|
|
34
33
|
const STATIC = join(dirname(fileURLToPath(import.meta.url)), "..", "..", "static");
|
|
35
34
|
/** The shell's built files, `@agentorg/shell`'s `dist`. */
|
|
@@ -42,6 +41,21 @@ const MAX_MESSAGE = 1024 * 1024;
|
|
|
42
41
|
const HELLO_TIMEOUT_MS = 10_000;
|
|
43
42
|
/** The close code for a socket with no live session: the tab signs in again. */
|
|
44
43
|
const SIGN_IN_AGAIN = 4401;
|
|
44
|
+
/** A model's reply can take minutes; every other interface keeps the Hub's own limit. */
|
|
45
|
+
export const HUB_OPTIONS = {
|
|
46
|
+
answerTimeoutsMs: { [describeInterface(llmSession).id]: 10 * 60_000 },
|
|
47
|
+
};
|
|
48
|
+
/** The port the kept sessions were given at, if any are kept. */
|
|
49
|
+
function keptPort(sessions) {
|
|
50
|
+
try {
|
|
51
|
+
const { at } = JSON.parse(readFileSync(sessions, "utf8"));
|
|
52
|
+
const port = /^http:\/\/127\.0\.0\.1:(\d+)$/.exec(String(at))?.[1];
|
|
53
|
+
return port === undefined ? undefined : Number(port);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
45
59
|
/** Write a file only its owner reads, all at once. */
|
|
46
60
|
function writePrivate(file, text) {
|
|
47
61
|
writeFileSync(`${file}.tmp`, text, { mode: 0o600 });
|
|
@@ -52,146 +66,79 @@ function writePrivate(file, text) {
|
|
|
52
66
|
* The app: a Hub in this process, and the person's gateway, its single running instance. The
|
|
53
67
|
* gateway holds the person's one channel to the Hub. Browser tabs and the CLI are the person's UIs,
|
|
54
68
|
* not channels: they reach the gateway at `/api`, and their calls run through the person's slots,
|
|
55
|
-
*
|
|
69
|
+
* and the person's notes are the app's own file.
|
|
56
70
|
*/
|
|
57
71
|
export async function startApp(options) {
|
|
58
72
|
const home = resolve(options.home);
|
|
59
73
|
mkdirSync(home, { recursive: true, mode: 0o700 });
|
|
60
|
-
|
|
74
|
+
closePackageActors(home);
|
|
75
|
+
const hub = Hub.open(home, HUB_OPTIONS);
|
|
61
76
|
const listener = await listen(hub, {}).catch((error) => {
|
|
62
77
|
hub.close();
|
|
63
78
|
throw error;
|
|
64
79
|
});
|
|
65
80
|
writePrivate(join(home, "url"), `${listener.url}\n`);
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
// A tab signed in before the app last stopped is still signed in, if the app is at the address
|
|
82
|
+
// it was then: what is kept is each session's hash, in a file only its owner reads. At another
|
|
83
|
+
// address they are dropped. A tab keeps its session by address, so it couldn't say one here, and
|
|
84
|
+
// a tab left open on the old address goes on saying its session to whatever answers there.
|
|
85
|
+
const sessions = join(home, "sessions.json");
|
|
86
|
+
const signIn = new SignIn({
|
|
87
|
+
kept: {
|
|
88
|
+
read() {
|
|
89
|
+
try {
|
|
90
|
+
return JSON.parse(readFileSync(sessions, "utf8")).hashes;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
// None kept, or none that reads back.
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
write(hashes) {
|
|
98
|
+
try {
|
|
99
|
+
writePrivate(sessions, `${JSON.stringify({ at: origin, hashes })}\n`);
|
|
100
|
+
}
|
|
101
|
+
catch {
|
|
102
|
+
// A home that can't be written still signs the tab in: only the next start forgets it.
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
});
|
|
83
107
|
const credential = readFileSync(join(home, "person-credential"), "utf8").trim();
|
|
84
|
-
|
|
108
|
+
/** The app's own notes: what the shell remembers. */
|
|
109
|
+
const notes = new Notes(join(home, "app-notes.json"));
|
|
85
110
|
const person = await connect({
|
|
86
111
|
hubUrl: listener.url,
|
|
87
112
|
actorId: PERSON,
|
|
88
113
|
credential,
|
|
89
114
|
slots: SLOTS,
|
|
90
|
-
exports: { layout },
|
|
91
|
-
start(ctx) {
|
|
92
|
-
logic = new Layout({
|
|
93
|
-
store: () => ({
|
|
94
|
-
get: (key) => ctx.slots.store.call.get({ key }),
|
|
95
|
-
set: (key, value) => ctx.slots.store.call.set({ key, value: value }),
|
|
96
|
-
}),
|
|
97
|
-
isView,
|
|
98
|
-
changed: () => emitChanged(),
|
|
99
|
-
});
|
|
100
|
-
const served = logic;
|
|
101
|
-
ctx.exports.layout.implement({
|
|
102
|
-
get: () => served.get(),
|
|
103
|
-
// Who placed it is the caller the Hub names, never the input.
|
|
104
|
-
place: (input, { caller }) => served.place(input, caller),
|
|
105
|
-
remove: (input) => served.remove(input),
|
|
106
|
-
move: (input) => served.move(input),
|
|
107
|
-
});
|
|
108
|
-
emitChanged = () => {
|
|
109
|
-
ctx.exports.layout.emit("changed", {});
|
|
110
|
-
for (const tell of [...changes])
|
|
111
|
-
tell();
|
|
112
|
-
};
|
|
113
|
-
},
|
|
114
115
|
}).catch((error) => {
|
|
115
116
|
void listener.close();
|
|
116
117
|
hub.close();
|
|
117
118
|
throw error;
|
|
118
119
|
});
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
// explicitly, as the Hub binds nothing by default.
|
|
122
|
-
if (!hub.state.binding(PERSON, "store"))
|
|
123
|
-
await person.slots.grants.call
|
|
124
|
-
.bind({ consumer: PERSON, slot: "store", provider: STORAGE, export: "kv" })
|
|
125
|
-
.catch((error) => {
|
|
126
|
-
person.close();
|
|
127
|
-
void listener.close();
|
|
128
|
-
hub.close();
|
|
129
|
-
throw error;
|
|
130
|
-
});
|
|
131
|
-
/** The person's side of `/api`: its slots, and `layout`, its own export, served here. */
|
|
120
|
+
/** A slot exposed to the person at run time: here exactly while it is bound. */
|
|
121
|
+
const exposedSlot = (slot) => person.exposed().find((one) => one.slot === slot);
|
|
132
122
|
const personSide = {
|
|
133
123
|
async call(slot, method, input) {
|
|
134
|
-
if (slot === "
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
throw new Refused("invalid", `rules has no method ${method}.`);
|
|
141
|
-
const parsed = spec.input.safeParse(input);
|
|
142
|
-
if (!parsed.success)
|
|
143
|
-
throw new Refused("invalid", `rules.${method}: ${parsed.error.message}`);
|
|
144
|
-
const result = method === "set"
|
|
145
|
-
? await rules.set(parsed.data)
|
|
146
|
-
: await rules.list();
|
|
147
|
-
const checked = spec.output.safeParse(result);
|
|
148
|
-
if (!checked.success)
|
|
149
|
-
throw new Refused("bad_output", `rules.${method}: ${checked.error.message}`);
|
|
150
|
-
return checked.data;
|
|
151
|
-
}
|
|
152
|
-
if (slot === "layout") {
|
|
153
|
-
const spec = Object.hasOwn(layout.methods, method)
|
|
154
|
-
? layout.methods[method]
|
|
155
|
-
: undefined;
|
|
156
|
-
if (!spec)
|
|
157
|
-
throw new Refused("invalid", `layout has no method ${method}.`);
|
|
158
|
-
const parsed = spec.input.safeParse(input);
|
|
159
|
-
if (!parsed.success)
|
|
160
|
-
throw new Refused("invalid", `layout.${method}: ${parsed.error.message}`);
|
|
161
|
-
// Through /api, the caller is the person.
|
|
162
|
-
const result = await layoutLogic[method](parsed.data, PERSON);
|
|
163
|
-
// Checked as a call through the Hub would be: what's stored may not fit.
|
|
164
|
-
const checked = spec.output.safeParse(result);
|
|
165
|
-
if (!checked.success)
|
|
166
|
-
throw new Refused("bad_output", `layout.${method}: ${checked.error.message}`);
|
|
167
|
-
return checked.data;
|
|
168
|
-
}
|
|
169
|
-
if (!Object.hasOwn(SLOTS, slot))
|
|
124
|
+
if (slot === "store")
|
|
125
|
+
return notes.call(method, input);
|
|
126
|
+
if (slot === "folders")
|
|
127
|
+
return callFolders(method, input);
|
|
128
|
+
const exposed = Object.hasOwn(SLOTS, slot) ? undefined : exposedSlot(slot);
|
|
129
|
+
if (!exposed && !Object.hasOwn(SLOTS, slot))
|
|
170
130
|
throw new Refused("invalid", `The person has no slot ${slot}.`);
|
|
171
|
-
const calls = person.slots[slot].call;
|
|
131
|
+
const calls = (exposed?.call ?? person.slots[slot].call);
|
|
172
132
|
const call = Object.hasOwn(calls, method) ? calls[method] : undefined;
|
|
173
133
|
if (!call)
|
|
174
134
|
throw new Refused("invalid", `${slot} has no method ${method}.`);
|
|
175
135
|
return call(input);
|
|
176
136
|
},
|
|
177
137
|
subscribe(slot, event, send) {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
throw new Refused("invalid", "rules has one event, changed.");
|
|
181
|
-
const tell = () => send({});
|
|
182
|
-
ruleChanges.add(tell);
|
|
183
|
-
return () => void ruleChanges.delete(tell);
|
|
184
|
-
}
|
|
185
|
-
if (slot === "layout") {
|
|
186
|
-
if (event !== "changed")
|
|
187
|
-
throw new Refused("invalid", "layout has one event, changed.");
|
|
188
|
-
const tell = () => send({});
|
|
189
|
-
changes.add(tell);
|
|
190
|
-
return () => void changes.delete(tell);
|
|
191
|
-
}
|
|
192
|
-
if (!Object.hasOwn(SLOTS, slot))
|
|
138
|
+
const exposed = Object.hasOwn(SLOTS, slot) ? undefined : exposedSlot(slot);
|
|
139
|
+
if (!exposed && !Object.hasOwn(SLOTS, slot))
|
|
193
140
|
throw new Refused("invalid", `The person has no slot ${slot}.`);
|
|
194
|
-
const handle = person.slots[slot];
|
|
141
|
+
const handle = (exposed ?? person.slots[slot]);
|
|
195
142
|
try {
|
|
196
143
|
return handle.on(event, send);
|
|
197
144
|
}
|
|
@@ -200,40 +147,17 @@ export async function startApp(options) {
|
|
|
200
147
|
}
|
|
201
148
|
},
|
|
202
149
|
};
|
|
203
|
-
const views = {
|
|
204
|
-
call: (view, slot, method, input) => hub.viewCall(view.actor, view.module, slot, method, input),
|
|
205
|
-
subscribe: (view, slot, event, send, end) => hub.viewSubscribe(view.actor, view.module, slot, event, send, () => end()),
|
|
206
|
-
slots: (view, onSlot) => hub.viewSlots(view.actor, view.module, onSlot),
|
|
207
|
-
log: (view, level, message, fields) => hub.viewLog(view.actor, view.module, {
|
|
208
|
-
level,
|
|
209
|
-
message,
|
|
210
|
-
...(fields ? { data: fields } : {}),
|
|
211
|
-
}),
|
|
212
|
-
};
|
|
213
150
|
// The first run, beside serving: the shell follows the person's bindings as they're made, so it
|
|
214
151
|
// needn't wait. What it can't do is logged and tried at the next start.
|
|
215
|
-
const ran =
|
|
216
|
-
|
|
217
|
-
:
|
|
218
|
-
log: (message) => process.stderr.write(`${message}\n`),
|
|
219
|
-
connected: (actorId) => hub.connected(actorId),
|
|
220
|
-
...options.firstRun,
|
|
221
|
-
}).catch((error) => {
|
|
222
|
-
process.stderr.write(`First run didn't work: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
223
|
-
return undefined;
|
|
224
|
-
});
|
|
225
|
-
// The person's named rules: off until turned on; their engine starts once the first run is done.
|
|
226
|
-
const rules = new Rules({
|
|
227
|
-
person: personSide,
|
|
152
|
+
const ran = startPrograms(personSide, {
|
|
153
|
+
home,
|
|
154
|
+
hubUrl: listener.url,
|
|
228
155
|
log: (message) => process.stderr.write(`${message}\n`),
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
156
|
+
...options.firstRun,
|
|
157
|
+
}).catch((error) => {
|
|
158
|
+
process.stderr.write(`First run didn't work: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
159
|
+
return undefined;
|
|
233
160
|
});
|
|
234
|
-
void Promise.resolve(ran)
|
|
235
|
-
.then(() => rules.start())
|
|
236
|
-
.catch((error) => process.stderr.write(`The rules didn't start: ${error instanceof Error ? error.message : String(error)}\n`));
|
|
237
161
|
/** The app's own pages: scripts and styles from here only, framed by nothing. */
|
|
238
162
|
const appCsp = [
|
|
239
163
|
"default-src 'self'",
|
|
@@ -241,7 +165,7 @@ export async function startApp(options) {
|
|
|
241
165
|
"style-src 'self' 'unsafe-inline'",
|
|
242
166
|
"img-src 'self' data:",
|
|
243
167
|
"connect-src 'self'",
|
|
244
|
-
"frame-src '
|
|
168
|
+
"frame-src 'none'",
|
|
245
169
|
"object-src 'none'",
|
|
246
170
|
"base-uri 'none'",
|
|
247
171
|
"form-action 'self'",
|
|
@@ -266,15 +190,6 @@ export async function startApp(options) {
|
|
|
266
190
|
const route = routes.get(url.pathname);
|
|
267
191
|
if (route)
|
|
268
192
|
return route(request, response, url);
|
|
269
|
-
if (url.pathname.startsWith("/frames/")) {
|
|
270
|
-
const served = request.method === "GET"
|
|
271
|
-
? serveFrame(url.pathname, origin, bundleOf, request.headers.origin)
|
|
272
|
-
: undefined;
|
|
273
|
-
if (!served)
|
|
274
|
-
return void response.writeHead(404).end();
|
|
275
|
-
response.writeHead(served.status, served.headers).end(served.body);
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
193
|
if (url.pathname === "/api/session" && request.method === "POST") {
|
|
279
194
|
// Same-origin only: a cross-site form can't trade a code it saw.
|
|
280
195
|
if (request.headers.origin !== origin)
|
|
@@ -294,14 +209,6 @@ export async function startApp(options) {
|
|
|
294
209
|
response.writeHead(200, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
295
210
|
return void response.end(JSON.stringify({ session }));
|
|
296
211
|
}
|
|
297
|
-
// A package's archive, and a system's file, both ways: for the person's UIs only, a tab by its
|
|
298
|
-
// session and the CLI by its token, as a bearer, which no other page can send.
|
|
299
|
-
if (url.pathname.startsWith("/packages") || url.pathname === "/system") {
|
|
300
|
-
const bearer = /^Bearer (\S+)$/.exec(request.headers.authorization ?? "")?.[1];
|
|
301
|
-
if (!signIn.isCli(request.headers.authorization) && !signIn.isSession(bearer))
|
|
302
|
-
return void response.writeHead(401).end();
|
|
303
|
-
return transfer(request, response, url);
|
|
304
|
-
}
|
|
305
212
|
if (url.pathname === "/api/code" && request.method === "POST") {
|
|
306
213
|
// The CLI's way to sign a browser in again: a fresh code, for its token only.
|
|
307
214
|
if (!signIn.isCli(request.headers.authorization))
|
|
@@ -333,115 +240,37 @@ export async function startApp(options) {
|
|
|
333
240
|
});
|
|
334
241
|
response.end(request.method === "HEAD" ? undefined : body);
|
|
335
242
|
};
|
|
336
|
-
/** Answer a transfer's failure as `/api` answers a call's: `{error}`, with a fitting status. */
|
|
337
|
-
const failure = (response, error) => {
|
|
338
|
-
const body = error instanceof Refused
|
|
339
|
-
? { name: "Refused", message: error.message, code: error.code }
|
|
340
|
-
: error instanceof Error &&
|
|
341
|
-
(error.name === "NotConnected" || error.name === "OutcomeUnknown")
|
|
342
|
-
? { name: error.name, message: error.message }
|
|
343
|
-
: { name: "Refused", message: "The gateway couldn't handle this.", code: "internal" };
|
|
344
|
-
const status = body.code === "too_large"
|
|
345
|
-
? 413
|
|
346
|
-
: body.code === "invalid" || body.code === "unknown"
|
|
347
|
-
? 400
|
|
348
|
-
: 409;
|
|
349
|
-
response.writeHead(status, { "Content-Type": "application/json", "Cache-Control": "no-store" });
|
|
350
|
-
response.end(JSON.stringify({ error: body }));
|
|
351
|
-
};
|
|
352
|
-
const sendFile = (response, name, bytes) => {
|
|
353
|
-
response.writeHead(200, {
|
|
354
|
-
"Content-Type": "application/octet-stream",
|
|
355
|
-
"Content-Disposition": `attachment; filename="${name.replace(/[^\w.@-]/g, "_")}"`,
|
|
356
|
-
"Cache-Control": "no-store",
|
|
357
|
-
"X-Content-Type-Options": "nosniff",
|
|
358
|
-
});
|
|
359
|
-
response.end(bytes);
|
|
360
|
-
};
|
|
361
|
-
/**
|
|
362
|
-
* `GET /packages/<hash>.agentorg`: a stored package's archive. `POST /packages`: an archive to
|
|
363
|
-
* add, verified by the Hub. `GET /system`: the system's file, its composition and every package
|
|
364
|
-
* it pins. `POST /system`: a system file, its packages added (each one's hash checked against
|
|
365
|
-
* its name), then imported with the person's authority.
|
|
366
|
-
*/
|
|
367
|
-
const transfer = async (request, response, url) => {
|
|
368
|
-
try {
|
|
369
|
-
const archive = /^\/packages\/(sha256-[0-9a-f]{64})\.agentorg$/.exec(url.pathname);
|
|
370
|
-
if (archive && request.method === "GET") {
|
|
371
|
-
const hash = archive[1];
|
|
372
|
-
const bytes = packageArchive(home, hash);
|
|
373
|
-
if (!bytes)
|
|
374
|
-
throw new Refused("unknown", `No package ${hash}.`);
|
|
375
|
-
const { manifest } = hub.state.package(hash);
|
|
376
|
-
return sendFile(response, `${manifest.name}-${manifest.version}.agentorg`, bytes);
|
|
377
|
-
}
|
|
378
|
-
if (url.pathname === "/packages" && request.method === "POST") {
|
|
379
|
-
const bytes = await readBytes(request, MAX_TRANSFER);
|
|
380
|
-
const added = await withTemporaryFile(home, "upload.agentorg", bytes, (path) => person.slots.packages.call.add({ path }));
|
|
381
|
-
response.writeHead(200, {
|
|
382
|
-
"Content-Type": "application/json",
|
|
383
|
-
"Cache-Control": "no-store",
|
|
384
|
-
});
|
|
385
|
-
return void response.end(JSON.stringify(added));
|
|
386
|
-
}
|
|
387
|
-
if (url.pathname === "/system" && request.method === "GET") {
|
|
388
|
-
const { composition } = await person.slots.installer.call.exportSystem({});
|
|
389
|
-
const archives = new Map();
|
|
390
|
-
for (const hash of pinnedHashes(composition)) {
|
|
391
|
-
const bytes = packageArchive(home, hash);
|
|
392
|
-
if (bytes)
|
|
393
|
-
archives.set(hash, bytes);
|
|
394
|
-
}
|
|
395
|
-
return sendFile(response, "system.agentorg-system", writeSystem(composition, archives));
|
|
396
|
-
}
|
|
397
|
-
if (url.pathname === "/system" && request.method === "POST") {
|
|
398
|
-
const { composition, packages } = readSystem(await readBytes(request, MAX_TRANSFER));
|
|
399
|
-
// Named by its hash, so the Hub refuses an archive whose hash isn't its name.
|
|
400
|
-
for (const [hash, bytes] of packages)
|
|
401
|
-
await withTemporaryFile(home, `${hash}.agentorg`, bytes, (path) => person.slots.packages.call.add({ path }));
|
|
402
|
-
const imported = await person.slots.installer.call.importSystem({ composition });
|
|
403
|
-
response.writeHead(200, {
|
|
404
|
-
"Content-Type": "application/json",
|
|
405
|
-
"Cache-Control": "no-store",
|
|
406
|
-
});
|
|
407
|
-
return void response.end(JSON.stringify(imported));
|
|
408
|
-
}
|
|
409
|
-
response.writeHead(405).end();
|
|
410
|
-
}
|
|
411
|
-
catch (error) {
|
|
412
|
-
failure(response, error);
|
|
413
|
-
}
|
|
414
|
-
};
|
|
415
|
-
const bundleOf = (hash, module) => {
|
|
416
|
-
try {
|
|
417
|
-
const entry = hub.state.package(hash).manifest.modules[module];
|
|
418
|
-
if (entry?.placement !== "view")
|
|
419
|
-
return undefined;
|
|
420
|
-
const dir = join(home, "packages", hash);
|
|
421
|
-
const file = resolve(dir, entry.entry);
|
|
422
|
-
return file.startsWith(dir + sep) ? file : undefined;
|
|
423
|
-
}
|
|
424
|
-
catch {
|
|
425
|
-
return undefined;
|
|
426
|
-
}
|
|
427
|
-
};
|
|
428
243
|
const sockets = new WebSocketServer({ noServer: true, maxPayload: MAX_MESSAGE });
|
|
244
|
+
const lives = new WebSocketServer({ noServer: true, maxPayload: LIVE_MAX });
|
|
429
245
|
server.on("upgrade", (request, socket, head) => {
|
|
430
246
|
// An upgraded socket has no error handler of its own: a client that resets would crash the app.
|
|
431
247
|
socket.on("error", () => socket.destroy());
|
|
432
248
|
const url = new URL(request.url ?? "/", origin);
|
|
433
249
|
const cli = signIn.isCli(request.headers.authorization);
|
|
434
250
|
const allowed = request.headers.host === host() &&
|
|
435
|
-
url.pathname === "/api" &&
|
|
251
|
+
(url.pathname === "/api" || url.pathname === "/live") &&
|
|
436
252
|
(cli || request.headers.origin === origin);
|
|
437
253
|
if (!allowed) {
|
|
438
254
|
socket.end("HTTP/1.1 401 Unauthorized\r\nConnection: close\r\n\r\n");
|
|
439
255
|
return;
|
|
440
256
|
}
|
|
257
|
+
if (url.pathname === "/live") {
|
|
258
|
+
const query = url.searchParams;
|
|
259
|
+
return lives.handleUpgrade(request, socket, head, (ws) => pipeLive(ws, {
|
|
260
|
+
cli,
|
|
261
|
+
isSession: (session) => signIn.isSession(session),
|
|
262
|
+
ticket: async () => (await personSide.call("agents", "live", {
|
|
263
|
+
agent: query.get("agent"),
|
|
264
|
+
instance: query.get("instance"),
|
|
265
|
+
surface: query.get("surface"),
|
|
266
|
+
mode: query.get("mode") ?? "watch",
|
|
267
|
+
})),
|
|
268
|
+
}));
|
|
269
|
+
}
|
|
441
270
|
sockets.handleUpgrade(request, socket, head, (ws) => {
|
|
442
271
|
let served;
|
|
443
272
|
const serve = () => {
|
|
444
|
-
served = serveSocket({ send: (text) => ws.send(text), close: (code, reason) => ws.close(code, reason) }, { person: personSide
|
|
273
|
+
served = serveSocket({ send: (text) => ws.send(text), close: (code, reason) => ws.close(code, reason) }, { person: personSide });
|
|
445
274
|
};
|
|
446
275
|
// The CLI is in by its token; a tab says its session first, or is closed.
|
|
447
276
|
if (cli)
|
|
@@ -473,35 +302,44 @@ export async function startApp(options) {
|
|
|
473
302
|
});
|
|
474
303
|
});
|
|
475
304
|
});
|
|
476
|
-
|
|
305
|
+
const listenOn = (port) => new Promise((done, failed) => {
|
|
477
306
|
server.once("error", failed);
|
|
478
|
-
server.listen(
|
|
479
|
-
})
|
|
307
|
+
server.listen(port, "127.0.0.1", () => done());
|
|
308
|
+
});
|
|
309
|
+
// With no port asked for, the one the kept sessions were given at, so a tab left open is still
|
|
310
|
+
// signed in. If that one can't be had, any free one, as on a first start.
|
|
311
|
+
await (options.port === undefined
|
|
312
|
+
? listenOn(keptPort(sessions) ?? 0).catch(() => listenOn(0))
|
|
313
|
+
: listenOn(options.port)).catch(async (error) => {
|
|
480
314
|
person.close();
|
|
481
315
|
await listener.close();
|
|
482
316
|
hub.close();
|
|
483
317
|
throw error;
|
|
484
318
|
});
|
|
485
|
-
|
|
319
|
+
const { port } = server.address();
|
|
320
|
+
// At another address the kept sessions are dropped, before anything is answered.
|
|
321
|
+
if (keptPort(sessions) !== port)
|
|
322
|
+
rmSync(sessions, { force: true });
|
|
323
|
+
origin = `http://127.0.0.1:${port}`;
|
|
486
324
|
writePrivate(join(home, "cli-token"), `${signIn.cliToken}\n`);
|
|
487
325
|
writePrivate(join(home, "app.json"), `${JSON.stringify({ url: origin, pid: process.pid })}\n`);
|
|
488
326
|
let closing;
|
|
489
327
|
let stopped = () => { };
|
|
328
|
+
let lost = false;
|
|
490
329
|
const closed = new Promise((done) => {
|
|
491
|
-
stopped = () => done({ lost
|
|
330
|
+
stopped = () => done({ lost });
|
|
492
331
|
// The person's channel gone (taken over, or the Hub gone): the gateway can't serve, so it stops.
|
|
493
332
|
void person.closed.then(() => {
|
|
494
333
|
if (!closing) {
|
|
334
|
+
lost = true;
|
|
495
335
|
void close();
|
|
496
|
-
done({ lost: true });
|
|
497
336
|
}
|
|
498
337
|
});
|
|
499
338
|
});
|
|
500
339
|
const close = () => {
|
|
501
340
|
closing ??= (async () => {
|
|
502
341
|
// A first run still going finishes first, so it isn't cut off half way.
|
|
503
|
-
await ran;
|
|
504
|
-
rules.close();
|
|
342
|
+
const programs = await ran;
|
|
505
343
|
const ours = (file, text) => {
|
|
506
344
|
if (file === "cli-token")
|
|
507
345
|
return text.trim() === signIn.cliToken;
|
|
@@ -523,14 +361,17 @@ export async function startApp(options) {
|
|
|
523
361
|
catch {
|
|
524
362
|
// Already gone.
|
|
525
363
|
}
|
|
526
|
-
for (const
|
|
527
|
-
client.
|
|
528
|
-
|
|
364
|
+
for (const server of [sockets, lives]) {
|
|
365
|
+
for (const client of server.clients)
|
|
366
|
+
client.terminate();
|
|
367
|
+
server.close();
|
|
368
|
+
}
|
|
529
369
|
// server.close waits for every open connection; a tab still connected (a keep-alive request,
|
|
530
370
|
// a socket reconnecting) would hold the app open, so they are all closed now.
|
|
531
371
|
const serverClosed = new Promise((done) => server.close(() => done()));
|
|
532
372
|
server.closeAllConnections();
|
|
533
373
|
await serverClosed;
|
|
374
|
+
await programs?.close();
|
|
534
375
|
person.close();
|
|
535
376
|
await person.closed;
|
|
536
377
|
await listener.close();
|
|
@@ -543,7 +384,7 @@ export async function startApp(options) {
|
|
|
543
384
|
url: origin,
|
|
544
385
|
hubUrl: listener.url,
|
|
545
386
|
hub,
|
|
546
|
-
|
|
387
|
+
firstRun: ran,
|
|
547
388
|
signInUrl: () => `${origin}/signin#${signIn.code()}`,
|
|
548
389
|
route: (path, route) => void routes.set(path, route),
|
|
549
390
|
close,
|
|
@@ -574,24 +415,6 @@ function contentType(file) {
|
|
|
574
415
|
return "image/svg+xml";
|
|
575
416
|
return "application/octet-stream";
|
|
576
417
|
}
|
|
577
|
-
/** A request's body as bytes, up to `max`: past it, `Refused("too_large")`. */
|
|
578
|
-
function readBytes(request, max) {
|
|
579
|
-
return new Promise((done, failed) => {
|
|
580
|
-
const chunks = [];
|
|
581
|
-
let size = 0;
|
|
582
|
-
request.on("data", (chunk) => {
|
|
583
|
-
size += chunk.length;
|
|
584
|
-
if (size > max) {
|
|
585
|
-
request.destroy();
|
|
586
|
-
failed(new Refused("too_large", `A file here is ${max / 1024 / 1024} MiB at most.`));
|
|
587
|
-
}
|
|
588
|
-
else
|
|
589
|
-
chunks.push(chunk);
|
|
590
|
-
});
|
|
591
|
-
request.on("end", () => done(new Uint8Array(Buffer.concat(chunks))));
|
|
592
|
-
request.on("error", failed);
|
|
593
|
-
});
|
|
594
|
-
}
|
|
595
418
|
function readBody(request) {
|
|
596
419
|
return new Promise((done, failed) => {
|
|
597
420
|
let body = "";
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
export { type PersonSide, type Socket, serveSocket
|
|
2
|
-
export { frameCsp, serveFrame, type ViewBundle } from "./frames.js";
|
|
1
|
+
export { type PersonSide, type Socket, serveSocket } from "./api.js";
|
|
3
2
|
export { type App, type AppOptions, type Route, startApp } from "./gateway.js";
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
3
|
+
export { Notes } from "./notes.js";
|
|
4
|
+
export { oauthRoute, type PersonCalls } from "./oauth.js";
|
|
5
|
+
export { type Programs, type ProgramsOptions, startPrograms } from "./programs.js";
|
|
6
6
|
export { SignIn } from "./signin.js";
|
|
7
|
-
export { MAX_TRANSFER, packageArchive, pinnedHashes, readSystem, type SystemComposition, withTemporaryFile, writeSystem, } from "./transfer.js";
|
package/dist/src/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export { serveSocket } from "./api.js";
|
|
2
|
-
export { frameCsp, serveFrame } from "./frames.js";
|
|
3
2
|
export { startApp } from "./gateway.js";
|
|
4
|
-
export {
|
|
5
|
-
export {
|
|
3
|
+
export { Notes } from "./notes.js";
|
|
4
|
+
export { oauthRoute } from "./oauth.js";
|
|
5
|
+
export { startPrograms } from "./programs.js";
|
|
6
6
|
export { SignIn } from "./signin.js";
|
|
7
|
-
export { MAX_TRANSFER, packageArchive, pinnedHashes, readSystem, withTemporaryFile, writeSystem, } from "./transfer.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import WebSocket from "ws";
|
|
2
|
+
/** What one live frame can be, either way. */
|
|
3
|
+
export declare const LIVE_MAX: number;
|
|
4
|
+
export interface Ticket {
|
|
5
|
+
url: string;
|
|
6
|
+
protocol: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Pipe a page's socket to a surface. A tab says its session first, as on `/api`, and is then
|
|
10
|
+
* answered `{"op":"live","protocol"}`; after that every frame is the surface's own. The CLI is in
|
|
11
|
+
* by its token.
|
|
12
|
+
*/
|
|
13
|
+
export declare function pipeLive(page: WebSocket, options: {
|
|
14
|
+
cli: boolean;
|
|
15
|
+
isSession(session: unknown): boolean;
|
|
16
|
+
ticket(): Promise<Ticket>;
|
|
17
|
+
}): void;
|