esoul-sdk 0.17.0 → 0.19.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/api-reference.md +1429 -11
- package/bin/esoul-device-exec.mjs +99 -0
- package/bin/esoul-device-program.mjs +146 -0
- package/dist/device.d.ts +161 -0
- package/dist/device.js +15 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/machine/capabilities.d.ts +92 -0
- package/dist/machine/capabilities.js +245 -0
- package/dist/machine/cli.d.ts +2 -0
- package/dist/machine/cli.js +232 -0
- package/dist/machine/client.d.ts +46 -0
- package/dist/machine/client.js +91 -0
- package/dist/machine/commands.d.ts +178 -0
- package/dist/machine/commands.js +281 -0
- package/dist/machine/digest.d.ts +26 -0
- package/dist/machine/digest.js +71 -0
- package/dist/machine/files.d.ts +188 -0
- package/dist/machine/files.js +511 -0
- package/dist/machine/grant.d.ts +49 -0
- package/dist/machine/grant.js +69 -0
- package/dist/machine/index.d.ts +21 -0
- package/dist/machine/index.js +21 -0
- package/dist/machine/program-api.d.ts +101 -0
- package/dist/machine/program-api.js +22 -0
- package/dist/machine/program-manager.d.ts +61 -0
- package/dist/machine/program-manager.js +600 -0
- package/dist/machine/protocol.d.ts +52 -0
- package/dist/machine/protocol.js +88 -0
- package/dist/machine/runner.d.ts +43 -0
- package/dist/machine/runner.js +255 -0
- package/dist/machine/service.d.ts +36 -0
- package/dist/machine/service.js +240 -0
- package/dist/machine/shell.d.ts +65 -0
- package/dist/machine/shell.js +474 -0
- package/dist/machine/state.d.ts +50 -0
- package/dist/machine/state.js +96 -0
- package/dist/machine/supervisor.d.ts +58 -0
- package/dist/machine/supervisor.js +275 -0
- package/dist/machine/wake.d.ts +31 -0
- package/dist/machine/wake.js +105 -0
- package/dist/manifest.d.ts +595 -0
- package/dist/manifest.js +72 -0
- package/dist/react.d.ts +104 -0
- package/dist/react.js +36 -0
- package/dist/server.d.ts +38 -0
- package/dist/server.js +20 -0
- package/docs/05-ui.md +37 -0
- package/docs/18-your-computer.md +350 -0
- package/llms-full.txt +391 -0
- package/llms.txt +1 -0
- package/package.json +10 -4
- package/schemas/plugin.schema.json +317 -0
- package/scripts/build-api-reference.mjs +1 -0
package/api-reference.md
CHANGED
|
@@ -7,11 +7,11 @@ the complete list it teaches from. In a Forge workbench the source itself is rea
|
|
|
7
7
|
Regenerate: `npm run docs:api`.
|
|
8
8
|
|
|
9
9
|
==============================================================================
|
|
10
|
-
## `esoul-sdk` —
|
|
10
|
+
## `esoul-sdk` — 196 exports
|
|
11
11
|
|
|
12
12
|
Manifest, events, tools, ops, bindings, contracts, charts, access words — what app.tsx and the shared modules import.
|
|
13
13
|
|
|
14
|
-
### Functions and values (
|
|
14
|
+
### Functions and values (115)
|
|
15
15
|
|
|
16
16
|
#### `ASSET_APP_MAX_BYTES` — const · src/assets.ts
|
|
17
17
|
|
|
@@ -189,6 +189,14 @@ Every declared attribute a grant carries, typed; an undeclared or ill-typed one
|
|
|
189
189
|
function coerceAttrs(types: Record<string, AttrType>, raw: Record<string, unknown> | undefined | null): Record<string, AttrValue>
|
|
190
190
|
```
|
|
191
191
|
|
|
192
|
+
#### `COMMAND_NAME_RE` — const · src/machine/commands.ts
|
|
193
|
+
|
|
194
|
+
What a command name may look like: lowercase, starts with a letter, up to 40 characters.
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
const COMMAND_NAME_RE: RegExp
|
|
198
|
+
```
|
|
199
|
+
|
|
192
200
|
#### `compareFileNames` — function · src/files.ts
|
|
193
201
|
|
|
194
202
|
Natural name order: "frame_2" before "frame_10".
|
|
@@ -245,6 +253,14 @@ What a mounted editor should do with the value the store now holds for the item
|
|
|
245
253
|
function decideReconcile<T>(args: { incoming: T; /** What the editor last knew the server to hold (its merge base). */ base: T | undefined; /** What the editor shows right now. */ current: T; equal: (a: T, b: T) => boolean; /** A local save is scheduled and not yet dispatched. */ pending: boolean; /** The user is in the middle of editing (focus, an open field). */ editing: boolean; /** isOlderOwnWrite(...) for the incoming state. */ olderOwn: boolean; /** The editor supplies a three-way merge. */ canMerge: boolean; /** May a merge be applied while the person is editing? Default true. An editor that can only apply by * replacing its whole surface (an input in progress would be lost) sets false: it merges once idle. */ mergeWhileEditing?: boolean; }): ReconcileDecision
|
|
246
254
|
```
|
|
247
255
|
|
|
256
|
+
#### `DEFAULT_TIMEOUT_SECONDS` — const · src/machine/commands.ts
|
|
257
|
+
|
|
258
|
+
A command's time limit when it declares none: one hour.
|
|
259
|
+
|
|
260
|
+
```ts
|
|
261
|
+
const DEFAULT_TIMEOUT_SECONDS: 3600
|
|
262
|
+
```
|
|
263
|
+
|
|
248
264
|
#### `defineBindingEvent` — function · src/bindings.ts
|
|
249
265
|
|
|
250
266
|
The event definition for one app's slots. `knownSlots` comes from the manifest, so an event naming a slot the app never declared is ignored rather than inventing one.
|
|
@@ -277,6 +293,22 @@ Refold-stable id from event payload — the ONLY way a processor may mint an id
|
|
|
277
293
|
function deterministicReducerId(prefix: string, seed: unknown): string
|
|
278
294
|
```
|
|
279
295
|
|
|
296
|
+
#### `deviceBlockProblems` — function · src/machine/commands.ts
|
|
297
|
+
|
|
298
|
+
Every problem with a `device` block, in words an author can act on. Empty = valid.
|
|
299
|
+
|
|
300
|
+
```ts
|
|
301
|
+
function deviceBlockProblems(block: unknown): string[]
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
#### `DeviceCommandError` — class · src/machine/commands.ts
|
|
305
|
+
|
|
306
|
+
Why a command was refused: `unknown_command` (not declared), `bad_param` (missing, extra or ill-typed), `bad_spec`. The message says which, in words.
|
|
307
|
+
|
|
308
|
+
```ts
|
|
309
|
+
class DeviceCommandError extends Error { … }
|
|
310
|
+
```
|
|
311
|
+
|
|
280
312
|
#### `fenceMetaOf` — function · src/editor-sync.ts
|
|
281
313
|
|
|
282
314
|
The fence record of `itemKey` in an app state (`__itemRevs`), if any.
|
|
@@ -509,6 +541,14 @@ Does an entry pass these listing options? The one rule every provider's listing
|
|
|
509
541
|
function matchesListOptions(entry: Pick<FileEntry, "name" | "kind">, opts?: FileListOptions | null): boolean
|
|
510
542
|
```
|
|
511
543
|
|
|
544
|
+
#### `MAX_TIMEOUT_SECONDS` — const · src/machine/commands.ts
|
|
545
|
+
|
|
546
|
+
The longest time limit a command may declare: seven days.
|
|
547
|
+
|
|
548
|
+
```ts
|
|
549
|
+
const MAX_TIMEOUT_SECONDS: number
|
|
550
|
+
```
|
|
551
|
+
|
|
512
552
|
#### `mergeFields` — function · src/editor-sync.ts
|
|
513
553
|
|
|
514
554
|
Three-way merge of a flat record of fields (a form: to/cc/subject/body; a node's config). A field changed differently on both sides is a conflict → `null`.
|
|
@@ -714,7 +754,7 @@ const PluginConnectionSchema: z.ZodEffects<z.ZodObject<{ key: z.ZodString; kind:
|
|
|
714
754
|
The zod schema `plugin.json` must satisfy — the sync and `check_app` refuse a manifest that fails it, with the path.
|
|
715
755
|
|
|
716
756
|
```ts
|
|
717
|
-
const PluginManifestSchema: z.ZodObject<{ manifestVersion: z.ZodLiteral<1>; id: z.ZodString; name: z.ZodString; version: z.ZodString; description: z.ZodString; applicationType: z.ZodString; entry: z.ZodString; icon: z.ZodOptional<z.ZodString>; author: z.ZodOptional<z.ZodObject<{ name: z.ZodString; email: z.ZodOptional<z.ZodString>; url: z.ZodOptional<z.ZodString>; }, "strip", z.ZodTypeAny, { name?: string; email?: string; url?: string; }, { name?: string; email?: string; url?: string; }>>; kickableTasks: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodRecord<z.ZodString, z.ZodObject<{ access: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodEnum<["write", "read", "public", "token"]>, z.ZodArray<z.ZodString, "many">]>>>; requires: z.ZodOptional<z.ZodLiteral<"account">>; }, "strict", z.ZodTypeAny, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>>]>>>; webhooks: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>; ops: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodRecord<z.ZodString, z.ZodObject<{ access: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodEnum<["write", "read", "public", "token"]>, z.ZodArray<z.ZodString, "many">]>>>; requires: z.ZodOptional<z.ZodLiteral<"account">>; }, "strict", z.ZodTypeAny, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>>]>>>; routes: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodRecord<z.ZodString, z.ZodObject<{ access: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodEnum<["write", "read", "public", "token"]>, z.ZodArray<z.ZodString, "many">]>>>; requires: z.ZodOptional<z.ZodLiteral<"account">>; }, "strict", z.ZodTypeAny, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>>]>>>; pollTasks: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{ task: z.ZodString; everyMinutes: z.ZodNumber; }, "strip", z.ZodTypeAny, { task?: string; everyMinutes?: number; }, { task?: string; everyMinutes?: number; }>, "many">>>; platformApi: z.ZodOptional<z.ZodObject<{ min: z.ZodString; max: z.ZodOptional<z.ZodString>; }, "strip", z.ZodTypeAny, { min?: string; max?: string; }, { min?: string; max?: string; }>>; scopes: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>; roles: z.ZodOptional<z.ZodEffects<z.ZodObject<{ vocabulary: z.ZodArray<z.ZodString, "many">; default: z.ZodDefault<z.ZodOptional<z.ZodObject<{ owner: z.ZodOptional<z.ZodString>; "member-edit": z.ZodOptional<z.ZodString>; "member-readonly": z.ZodOptional<z.ZodString>; visitor: z.ZodOptional<z.ZodString>; anonymous: z.ZodOptional<z.ZodString>; agent: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }, { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }>>>; describe: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>; attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<["string", "int", "boolean"]>>>; custom: z.ZodOptional<z.ZodObject<{ attributes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; models: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{ where: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; hide: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; update: z.ZodOptional<z.ZodObject<{ fields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; transitions: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { fields?: string[]; transitions?: string; }, { fields?: string[]; transitions?: string; }>>; }, "strict", z.ZodTypeAny, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>>>; ops: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; }, "strict", z.ZodTypeAny, { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }, { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }>>; }, "strict", z.ZodTypeAny, { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }, { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }>, { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }, { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }>>; workspaceTools: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>; connections: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodObject<{ key: z.ZodString; kind: z.ZodEnum<["oauth2", "apiKey"]>; label: z.ZodString; description: z.ZodOptional<z.ZodString>; authorizeUrl: z.ZodOptional<z.ZodString>; tokenUrl: z.ZodOptional<z.ZodString>; oauthScopes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; clientIdEnv: z.ZodOptional<z.ZodString>; clientSecretEnv: z.ZodOptional<z.ZodString>; headerNames: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; }, "strict", z.ZodTypeAny, { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }, { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }>, { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }, { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }>, "many">>>; fileSources: z.ZodOptional<z.ZodEffects<z.ZodObject<{ workspace: z.ZodOptional<z.ZodEnum<["read", "readwrite"]>>; providers: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>; write: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; }, "strict", z.ZodTypeAny, { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }, { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }>, { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }, { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }>>; fileProviders: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{ key: z.ZodString; connectionKey: z.ZodString; label: z.ZodString; }, "strict", z.ZodTypeAny, { key?: string; label?: string; connectionKey?: string; }, { key?: string; label?: string; connectionKey?: string; }>, "many">>>; uses: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{ contract: z.ZodString; label: z.ZodOptional<z.ZodString>; optional: z.ZodOptional<z.ZodBoolean>; }, "strict", z.ZodTypeAny, { label?: string; contract?: string; optional?: boolean; }, { label?: string; contract?: string; optional?: boolean; }>>>; provides: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{ tools: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; events: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; models: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; }, "strict", z.ZodTypeAny, { models?: string[]; tools?: string[]; events?: string[]; }, { models?: string[]; tools?: string[]; events?: string[]; }>>>; channel: z.ZodOptional<z.ZodObject<{ topics: z.ZodRecord<z.ZodString, z.ZodObject<{ audience: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"all">, z.ZodLiteral<"viewer">, z.ZodString]>>; mayAddress: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; description: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { description?: string; audience?: string; mayAddress?: string[]; }, { description?: string; audience?: string; mayAddress?: string[]; }>>; }, "strict", z.ZodTypeAny, { topics?: Record<string, { description?: string; audience?: string; mayAddress?: string[]; }>; }, { topics?: Record<string, { description?: string; audience?: string; mayAddress?: string[]; }>; }>>; db: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{ scope: z.ZodOptional<z.ZodEnum<["instance", "workspace", "user"]>>; owner: z.ZodOptional<z.ZodLiteral<"creator">>; fields: z.ZodRecord<z.ZodString, z.ZodString>; sealed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; unique: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">>; indexes: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodObject<{ fields: z.ZodArray<z.ZodString, "many">; kind: z.ZodOptional<z.ZodEnum<["btree", "contains", "text"]>>; }, "strict", z.ZodTypeAny, { kind?: "btree" | "contains" | "text"; fields?: string[]; }, { kind?: "btree" | "contains" | "text"; fields?: string[]; }>]>, "many">>; rules: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; }, "strict", z.ZodTypeAny, { owner?: "creator"; fields?: Record<string, string>; scope?: "workspace" | "instance" | "user"; sealed?: string[]; unique?: string[][]; indexes?: (string[] | { kind?: "btree" | "contains" | "text"; fields?: string[]; })[]; rules?: Record<string, unknown>; }, { owner?: "creator"; fields?: Record<string, string>; scope?: "workspace" | "instance" | "user"; sealed?: string[]; unique?: string[][]; indexes?: (string[] | { kind?: "btree" | "contains" | "text"; fields?: string[]; })[]; rules?: Record<string, unknown>; }>>>; }, "strict", z.ZodTypeAny, { roles?: { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }; description?: string; manifestVersion?: 1; id?: string; name?: string; version?: string; applicationType?: string; entry?: string; icon?: string; author?: { name?: string; email?: string; url?: string; }; kickableTasks?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; webhooks?: string[]; ops?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; routes?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; pollTasks?: { task?: string; everyMinutes?: number; }[]; platformApi?: { min?: string; max?: string; }; scopes?: string[]; workspaceTools?: string[]; connections?: { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }[]; fileSources?: { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }; fileProviders?: { key?: string; label?: string; connectionKey?: string; }[]; uses?: Record<string, { label?: string; contract?: string; optional?: boolean; }>; provides?: Record<string, { models?: string[]; tools?: string[]; events?: string[]; }>; channel?: { topics?: Record<string, { description?: string; audience?: string; mayAddress?: string[]; }>; }; db?: Record<string, { owner?: "creator"; fields?: Record<string, string>; scope?: "workspace" | "instance" | "user"; sealed?: string[]; unique?: string[][]; indexes?: (string[] | { kind?: "btree" | "contains" | "text"; fields?: string[]; })[]; rules?: Record<string, unknown>; }>; }, { roles?: { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }; description?: string; manifestVersion?: 1; id?: string; name?: string; version?: string; applicationType?: string; entry?: string; icon?: string; author?: { name?: string; email?: string; url?: string; }; kickableTasks?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; webhooks?: string[]; ops?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; routes?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; pollTasks?: { task?: string; everyMinutes?: number; }[]; platformApi?: { min?: string; max?: string; }; scopes?: string[]; workspaceTools?: string[]; connections?: { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }[]; fileSources?: { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }; fileProviders?: { key?: string; label?: string; connectionKey?: string; }[]; uses?: Record<string, { label?: string; contract?: string; optional?: boolean; }>; provides?: Record<string, { models?: string[]; tools?: string[]; events?: string[]; }>; channel?: { topics?: Record<string, { description?: string; audience?: string; mayAddress?: string[]; }>; }; db?: Record<string, { owner?: "creator"; fields?: Record<string, string>; scope?: "workspace" | "instance" | "user"; sealed?: string[]; unique?: string[][]; indexes?: (string[] | { kind?: "btree" | "contains" | "text"; fields?: string[]; })[]; rules?: Record<string, unknown>; }>; }>
|
|
757
|
+
const PluginManifestSchema: z.ZodObject<{ manifestVersion: z.ZodLiteral<1>; id: z.ZodString; name: z.ZodString; version: z.ZodString; description: z.ZodString; applicationType: z.ZodString; entry: z.ZodString; icon: z.ZodOptional<z.ZodString>; author: z.ZodOptional<z.ZodObject<{ name: z.ZodString; email: z.ZodOptional<z.ZodString>; url: z.ZodOptional<z.ZodString>; }, "strip", z.ZodTypeAny, { name?: string; email?: string; url?: string; }, { name?: string; email?: string; url?: string; }>>; kickableTasks: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodRecord<z.ZodString, z.ZodObject<{ access: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodEnum<["write", "read", "public", "token"]>, z.ZodArray<z.ZodString, "many">]>>>; requires: z.ZodOptional<z.ZodLiteral<"account">>; }, "strict", z.ZodTypeAny, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>>]>>>; webhooks: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>; ops: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodRecord<z.ZodString, z.ZodObject<{ access: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodEnum<["write", "read", "public", "token"]>, z.ZodArray<z.ZodString, "many">]>>>; requires: z.ZodOptional<z.ZodLiteral<"account">>; }, "strict", z.ZodTypeAny, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>>]>>>; routes: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodRecord<z.ZodString, z.ZodObject<{ access: z.ZodDefault<z.ZodOptional<z.ZodUnion<[z.ZodEnum<["write", "read", "public", "token"]>, z.ZodArray<z.ZodString, "many">]>>>; requires: z.ZodOptional<z.ZodLiteral<"account">>; }, "strict", z.ZodTypeAny, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>>]>>>; pollTasks: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{ task: z.ZodString; everyMinutes: z.ZodNumber; }, "strip", z.ZodTypeAny, { task?: string; everyMinutes?: number; }, { task?: string; everyMinutes?: number; }>, "many">>>; platformApi: z.ZodOptional<z.ZodObject<{ min: z.ZodString; max: z.ZodOptional<z.ZodString>; }, "strip", z.ZodTypeAny, { min?: string; max?: string; }, { min?: string; max?: string; }>>; scopes: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>; roles: z.ZodOptional<z.ZodEffects<z.ZodObject<{ vocabulary: z.ZodArray<z.ZodString, "many">; default: z.ZodDefault<z.ZodOptional<z.ZodObject<{ owner: z.ZodOptional<z.ZodString>; "member-edit": z.ZodOptional<z.ZodString>; "member-readonly": z.ZodOptional<z.ZodString>; visitor: z.ZodOptional<z.ZodString>; anonymous: z.ZodOptional<z.ZodString>; agent: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }, { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }>>>; describe: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>; attributes: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodEnum<["string", "int", "boolean"]>>>; custom: z.ZodOptional<z.ZodObject<{ attributes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; models: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{ where: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; hide: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; update: z.ZodOptional<z.ZodObject<{ fields: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; transitions: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { fields?: string[]; transitions?: string; }, { fields?: string[]; transitions?: string; }>>; }, "strict", z.ZodTypeAny, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>>>; ops: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; }, "strict", z.ZodTypeAny, { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }, { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }>>; }, "strict", z.ZodTypeAny, { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }, { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }>, { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }, { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }>>; workspaceTools: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>; device: z.ZodOptional<z.ZodEffects<z.ZodObject<{ commands: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{ argv: z.ZodArray<z.ZodString, "many">; params: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<[z.ZodEnum<["int", "number", "bool", "string"]>, z.ZodObject<{ type: z.ZodEnum<["int", "number"]>; min: z.ZodOptional<z.ZodNumber>; max: z.ZodOptional<z.ZodNumber>; describe: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { type?: "number" | "int"; min?: number; max?: number; describe?: string; }, { type?: "number" | "int"; min?: number; max?: number; describe?: string; }>, z.ZodObject<{ type: z.ZodLiteral<"string">; pattern: z.ZodOptional<z.ZodString>; maxLength: z.ZodOptional<z.ZodNumber>; allowDash: z.ZodOptional<z.ZodBoolean>; describe: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { type?: "string"; maxLength?: number; describe?: string; pattern?: string; allowDash?: boolean; }, { type?: "string"; maxLength?: number; describe?: string; pattern?: string; allowDash?: boolean; }>, z.ZodObject<{ type: z.ZodLiteral<"enum">; values: z.ZodArray<z.ZodString, "many">; describe: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { values?: string[]; type?: "enum"; describe?: string; }, { values?: string[]; type?: "enum"; describe?: string; }>, z.ZodObject<{ type: z.ZodLiteral<"bool">; describe: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { type?: "bool"; describe?: string; }, { type?: "bool"; describe?: string; }>]>>>; cwd: z.ZodOptional<z.ZodString>; env: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>; config: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; timeoutSeconds: z.ZodOptional<z.ZodNumber>; onRestart: z.ZodOptional<z.ZodEnum<["report", "rerun"]>>; output: z.ZodOptional<z.ZodObject<{ mode: z.ZodOptional<z.ZodEnum<["live", "batched", "final"]>>; flushMs: z.ZodOptional<z.ZodNumber>; maxChunkKb: z.ZodOptional<z.ZodNumber>; keep: z.ZodOptional<z.ZodEnum<["head", "tail", "both"]>>; maxKb: z.ZodOptional<z.ZodNumber>; }, "strict", z.ZodTypeAny, { mode?: "live" | "batched" | "final"; flushMs?: number; maxChunkKb?: number; keep?: "head" | "tail" | "both"; maxKb?: number; }, { mode?: "live" | "batched" | "final"; flushMs?: number; maxChunkKb?: number; keep?: "head" | "tail" | "both"; maxKb?: number; }>>; result: z.ZodOptional<z.ZodEnum<["text", "json"]>>; describe: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { params?: Record<string, "string" | "number" | "int" | "bool" | { type?: "number" | "int"; min?: number; max?: number; describe?: string; } | { type?: "string"; maxLength?: number; describe?: string; pattern?: string; allowDash?: boolean; } | { values?: string[]; type?: "enum"; describe?: string; } | { type?: "bool"; describe?: string; }>; describe?: string; argv?: string[]; cwd?: string; env?: Record<string, string>; config?: string[]; timeoutSeconds?: number; onRestart?: "report" | "rerun"; output?: { mode?: "live" | "batched" | "final"; flushMs?: number; maxChunkKb?: number; keep?: "head" | "tail" | "both"; maxKb?: number; }; result?: "text" | "json"; }, { params?: Record<string, "string" | "number" | "int" | "bool" | { type?: "number" | "int"; min?: number; max?: number; describe?: string; } | { type?: "string"; maxLength?: number; describe?: string; pattern?: string; allowDash?: boolean; } | { values?: string[]; type?: "enum"; describe?: string; } | { type?: "bool"; describe?: string; }>; describe?: string; argv?: string[]; cwd?: string; env?: Record<string, string>; config?: string[]; timeoutSeconds?: number; onRestart?: "report" | "rerun"; output?: { mode?: "live" | "batched" | "final"; flushMs?: number; maxChunkKb?: number; keep?: "head" | "tail" | "both"; maxKb?: number; }; result?: "text" | "json"; }>>>; program: z.ZodOptional<z.ZodObject<{ main: z.ZodString; resident: z.ZodOptional<z.ZodBoolean>; setup: z.ZodOptional<z.ZodArray<z.ZodObject<{ id: z.ZodString; describe: z.ZodString; run: z.ZodArray<z.ZodString, "many">; inputs: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; timeoutSeconds: z.ZodOptional<z.ZodNumber>; }, "strict", z.ZodTypeAny, { id?: string; describe?: string; timeoutSeconds?: number; run?: string[]; inputs?: string[]; }, { id?: string; describe?: string; timeoutSeconds?: number; run?: string[]; inputs?: string[]; }>, "many">>; selfTest: z.ZodOptional<z.ZodObject<{ run: z.ZodArray<z.ZodString, "many">; timeoutSeconds: z.ZodOptional<z.ZodNumber>; }, "strict", z.ZodTypeAny, { timeoutSeconds?: number; run?: string[]; }, { timeoutSeconds?: number; run?: string[]; }>>; }, "strict", z.ZodTypeAny, { main?: string; resident?: boolean; setup?: { id?: string; describe?: string; timeoutSeconds?: number; run?: string[]; inputs?: string[]; }[]; selfTest?: { timeoutSeconds?: number; run?: string[]; }; }, { main?: string; resident?: boolean; setup?: { id?: string; describe?: string; timeoutSeconds?: number; run?: string[]; inputs?: string[]; }[]; selfTest?: { timeoutSeconds?: number; run?: string[]; }; }>>; config: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{ secret: z.ZodOptional<z.ZodBoolean>; required: z.ZodOptional<z.ZodBoolean>; describe: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { required?: boolean; describe?: string; secret?: boolean; }, { required?: boolean; describe?: string; secret?: boolean; }>>>; redact: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; onAppDeleted: z.ZodOptional<z.ZodEnum<["kill", "finish"]>>; }, "strict", z.ZodTypeAny, { config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; commands?: Record<string, { params?: Record<string, "string" | "number" | "int" | "bool" | { type?: "number" | "int"; min?: number; max?: number; describe?: string; } | { type?: "string"; maxLength?: number; describe?: string; pattern?: string; allowDash?: boolean; } | { values?: string[]; type?: "enum"; describe?: string; } | { type?: "bool"; describe?: string; }>; describe?: string; argv?: string[]; cwd?: string; env?: Record<string, string>; config?: string[]; timeoutSeconds?: number; onRestart?: "report" | "rerun"; output?: { mode?: "live" | "batched" | "final"; flushMs?: number; maxChunkKb?: number; keep?: "head" | "tail" | "both"; maxKb?: number; }; result?: "text" | "json"; }>; program?: { main?: string; resident?: boolean; setup?: { id?: string; describe?: string; timeoutSeconds?: number; run?: string[]; inputs?: string[]; }[]; selfTest?: { timeoutSeconds?: number; run?: string[]; }; }; redact?: string[]; onAppDeleted?: "kill" | "finish"; }, { config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; commands?: Record<string, { params?: Record<string, "string" | "number" | "int" | "bool" | { type?: "number" | "int"; min?: number; max?: number; describe?: string; } | { type?: "string"; maxLength?: number; describe?: string; pattern?: string; allowDash?: boolean; } | { values?: string[]; type?: "enum"; describe?: string; } | { type?: "bool"; describe?: string; }>; describe?: string; argv?: string[]; cwd?: string; env?: Record<string, string>; config?: string[]; timeoutSeconds?: number; onRestart?: "report" | "rerun"; output?: { mode?: "live" | "batched" | "final"; flushMs?: number; maxChunkKb?: number; keep?: "head" | "tail" | "both"; maxKb?: number; }; result?: "text" | "json"; }>; program?: { main?: string; resident?: boolean; setup?: { id?: string; describe?: string; timeoutSeconds?: number; run?: string[]; inputs?: string[]; }[]; selfTest?: { timeoutSeconds?: number; run?: string[]; }; }; redact?: string[]; onAppDeleted?: "kill" | "finish"; }>, { config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; commands?: Record<string, { params?: Record<string, "string" | "number" | "int" | "bool" | { type?: "number" | "int"; min?: number; max?: number; describe?: string; } | { type?: "string"; maxLength?: number; describe?: string; pattern?: string; allowDash?: boolean; } | { values?: string[]; type?: "enum"; describe?: string; } | { type?: "bool"; describe?: string; }>; describe?: string; argv?: string[]; cwd?: string; env?: Record<string, string>; config?: string[]; timeoutSeconds?: number; onRestart?: "report" | "rerun"; output?: { mode?: "live" | "batched" | "final"; flushMs?: number; maxChunkKb?: number; keep?: "head" | "tail" | "both"; maxKb?: number; }; result?: "text" | "json"; }>; program?: { main?: string; resident?: boolean; setup?: { id?: string; describe?: string; timeoutSeconds?: number; run?: string[]; inputs?: string[]; }[]; selfTest?: { timeoutSeconds?: number; run?: string[]; }; }; redact?: string[]; onAppDeleted?: "kill" | "finish"; }, { config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; commands?: Record<string, { params?: Record<string, "string" | "number" | "int" | "bool" | { type?: "number" | "int"; min?: number; max?: number; describe?: string; } | { type?: "string"; maxLength?: number; describe?: string; pattern?: string; allowDash?: boolean; } | { values?: string[]; type?: "enum"; describe?: string; } | { type?: "bool"; describe?: string; }>; describe?: string; argv?: string[]; cwd?: string; env?: Record<string, string>; config?: string[]; timeoutSeconds?: number; onRestart?: "report" | "rerun"; output?: { mode?: "live" | "batched" | "final"; flushMs?: number; maxChunkKb?: number; keep?: "head" | "tail" | "both"; maxKb?: number; }; result?: "text" | "json"; }>; program?: { main?: string; resident?: boolean; setup?: { id?: string; describe?: string; timeoutSeconds?: number; run?: string[]; inputs?: string[]; }[]; selfTest?: { timeoutSeconds?: number; run?: string[]; }; }; redact?: string[]; onAppDeleted?: "kill" | "finish"; }>>; connections: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodEffects<z.ZodObject<{ key: z.ZodString; kind: z.ZodEnum<["oauth2", "apiKey"]>; label: z.ZodString; description: z.ZodOptional<z.ZodString>; authorizeUrl: z.ZodOptional<z.ZodString>; tokenUrl: z.ZodOptional<z.ZodString>; oauthScopes: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; clientIdEnv: z.ZodOptional<z.ZodString>; clientSecretEnv: z.ZodOptional<z.ZodString>; headerNames: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; }, "strict", z.ZodTypeAny, { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }, { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }>, { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }, { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }>, "many">>>; fileSources: z.ZodOptional<z.ZodEffects<z.ZodObject<{ workspace: z.ZodOptional<z.ZodEnum<["read", "readwrite"]>>; providers: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>; write: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; }, "strict", z.ZodTypeAny, { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }, { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }>, { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }, { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }>>; fileProviders: z.ZodDefault<z.ZodOptional<z.ZodArray<z.ZodObject<{ key: z.ZodString; connectionKey: z.ZodString; label: z.ZodString; }, "strict", z.ZodTypeAny, { key?: string; label?: string; connectionKey?: string; }, { key?: string; label?: string; connectionKey?: string; }>, "many">>>; uses: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{ contract: z.ZodString; label: z.ZodOptional<z.ZodString>; optional: z.ZodOptional<z.ZodBoolean>; }, "strict", z.ZodTypeAny, { label?: string; contract?: string; optional?: boolean; }, { label?: string; contract?: string; optional?: boolean; }>>>; provides: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{ tools: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; events: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; models: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; }, "strict", z.ZodTypeAny, { models?: string[]; tools?: string[]; events?: string[]; }, { models?: string[]; tools?: string[]; events?: string[]; }>>>; channel: z.ZodOptional<z.ZodObject<{ topics: z.ZodRecord<z.ZodString, z.ZodObject<{ audience: z.ZodOptional<z.ZodUnion<[z.ZodLiteral<"all">, z.ZodLiteral<"viewer">, z.ZodString]>>; mayAddress: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; description: z.ZodOptional<z.ZodString>; }, "strict", z.ZodTypeAny, { description?: string; audience?: string; mayAddress?: string[]; }, { description?: string; audience?: string; mayAddress?: string[]; }>>; }, "strict", z.ZodTypeAny, { topics?: Record<string, { description?: string; audience?: string; mayAddress?: string[]; }>; }, { topics?: Record<string, { description?: string; audience?: string; mayAddress?: string[]; }>; }>>; db: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{ scope: z.ZodOptional<z.ZodEnum<["instance", "workspace", "user"]>>; owner: z.ZodOptional<z.ZodLiteral<"creator">>; fields: z.ZodRecord<z.ZodString, z.ZodString>; sealed: z.ZodOptional<z.ZodArray<z.ZodString, "many">>; unique: z.ZodOptional<z.ZodArray<z.ZodArray<z.ZodString, "many">, "many">>; indexes: z.ZodOptional<z.ZodArray<z.ZodUnion<[z.ZodArray<z.ZodString, "many">, z.ZodObject<{ fields: z.ZodArray<z.ZodString, "many">; kind: z.ZodOptional<z.ZodEnum<["btree", "contains", "text"]>>; }, "strict", z.ZodTypeAny, { kind?: "text" | "btree" | "contains"; fields?: string[]; }, { kind?: "text" | "btree" | "contains"; fields?: string[]; }>]>, "many">>; rules: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>; }, "strict", z.ZodTypeAny, { owner?: "creator"; fields?: Record<string, string>; scope?: "workspace" | "instance" | "user"; sealed?: string[]; unique?: string[][]; indexes?: (string[] | { kind?: "text" | "btree" | "contains"; fields?: string[]; })[]; rules?: Record<string, unknown>; }, { owner?: "creator"; fields?: Record<string, string>; scope?: "workspace" | "instance" | "user"; sealed?: string[]; unique?: string[][]; indexes?: (string[] | { kind?: "text" | "btree" | "contains"; fields?: string[]; })[]; rules?: Record<string, unknown>; }>>>; }, "strict", z.ZodTypeAny, { roles?: { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }; description?: string; manifestVersion?: 1; id?: string; name?: string; version?: string; applicationType?: string; entry?: string; icon?: string; author?: { name?: string; email?: string; url?: string; }; kickableTasks?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; webhooks?: string[]; ops?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; routes?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; pollTasks?: { task?: string; everyMinutes?: number; }[]; platformApi?: { min?: string; max?: string; }; scopes?: string[]; workspaceTools?: string[]; device?: { config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; commands?: Record<string, { params?: Record<string, "string" | "number" | "int" | "bool" | { type?: "number" | "int"; min?: number; max?: number; describe?: string; } | { type?: "string"; maxLength?: number; describe?: string; pattern?: string; allowDash?: boolean; } | { values?: string[]; type?: "enum"; describe?: string; } | { type?: "bool"; describe?: string; }>; describe?: string; argv?: string[]; cwd?: string; env?: Record<string, string>; config?: string[]; timeoutSeconds?: number; onRestart?: "report" | "rerun"; output?: { mode?: "live" | "batched" | "final"; flushMs?: number; maxChunkKb?: number; keep?: "head" | "tail" | "both"; maxKb?: number; }; result?: "text" | "json"; }>; program?: { main?: string; resident?: boolean; setup?: { id?: string; describe?: string; timeoutSeconds?: number; run?: string[]; inputs?: string[]; }[]; selfTest?: { timeoutSeconds?: number; run?: string[]; }; }; redact?: string[]; onAppDeleted?: "kill" | "finish"; }; connections?: { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }[]; fileSources?: { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }; fileProviders?: { key?: string; label?: string; connectionKey?: string; }[]; uses?: Record<string, { label?: string; contract?: string; optional?: boolean; }>; provides?: Record<string, { models?: string[]; tools?: string[]; events?: string[]; }>; channel?: { topics?: Record<string, { description?: string; audience?: string; mayAddress?: string[]; }>; }; db?: Record<string, { owner?: "creator"; fields?: Record<string, string>; scope?: "workspace" | "instance" | "user"; sealed?: string[]; unique?: string[][]; indexes?: (string[] | { kind?: "text" | "btree" | "contains"; fields?: string[]; })[]; rules?: Record<string, unknown>; }>; }, { roles?: { default?: { owner?: string; "member-edit"?: string; "member-readonly"?: string; visitor?: string; anonymous?: string; agent?: string; }; custom?: { ops?: string[]; attributes?: string[]; models?: Record<string, { where?: string[]; hide?: string[]; update?: { fields?: string[]; transitions?: string; }; }>; }; vocabulary?: string[]; describe?: Record<string, string>; attributes?: Record<string, "string" | "boolean" | "int">; }; description?: string; manifestVersion?: 1; id?: string; name?: string; version?: string; applicationType?: string; entry?: string; icon?: string; author?: { name?: string; email?: string; url?: string; }; kickableTasks?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; webhooks?: string[]; ops?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; routes?: string[] | Record<string, { access?: "write" | "read" | "public" | "token" | string[]; requires?: "account"; }>; pollTasks?: { task?: string; everyMinutes?: number; }[]; platformApi?: { min?: string; max?: string; }; scopes?: string[]; workspaceTools?: string[]; device?: { config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; commands?: Record<string, { params?: Record<string, "string" | "number" | "int" | "bool" | { type?: "number" | "int"; min?: number; max?: number; describe?: string; } | { type?: "string"; maxLength?: number; describe?: string; pattern?: string; allowDash?: boolean; } | { values?: string[]; type?: "enum"; describe?: string; } | { type?: "bool"; describe?: string; }>; describe?: string; argv?: string[]; cwd?: string; env?: Record<string, string>; config?: string[]; timeoutSeconds?: number; onRestart?: "report" | "rerun"; output?: { mode?: "live" | "batched" | "final"; flushMs?: number; maxChunkKb?: number; keep?: "head" | "tail" | "both"; maxKb?: number; }; result?: "text" | "json"; }>; program?: { main?: string; resident?: boolean; setup?: { id?: string; describe?: string; timeoutSeconds?: number; run?: string[]; inputs?: string[]; }[]; selfTest?: { timeoutSeconds?: number; run?: string[]; }; }; redact?: string[]; onAppDeleted?: "kill" | "finish"; }; connections?: { key?: string; kind?: "oauth2" | "apiKey"; label?: string; description?: string; authorizeUrl?: string; tokenUrl?: string; oauthScopes?: string[]; clientIdEnv?: string; clientSecretEnv?: string; headerNames?: string[]; }[]; fileSources?: { write?: string[]; workspace?: "read" | "readwrite"; providers?: string[]; }; fileProviders?: { key?: string; label?: string; connectionKey?: string; }[]; uses?: Record<string, { label?: string; contract?: string; optional?: boolean; }>; provides?: Record<string, { models?: string[]; tools?: string[]; events?: string[]; }>; channel?: { topics?: Record<string, { description?: string; audience?: string; mayAddress?: string[]; }>; }; db?: Record<string, { owner?: "creator"; fields?: Record<string, string>; scope?: "workspace" | "instance" | "user"; sealed?: string[]; unique?: string[][]; indexes?: (string[] | { kind?: "text" | "btree" | "contains"; fields?: string[]; })[]; rules?: Record<string, unknown>; }>; }>
|
|
718
758
|
```
|
|
719
759
|
|
|
720
760
|
#### `PluginRolesSchema` — const · src/manifest.ts
|
|
@@ -765,6 +805,14 @@ The reducer behind `plugin/binding_set`. Deterministic: setting a slot replaces
|
|
|
765
805
|
function reduceBinding( current: BindingMap, event: { slot?: unknown; nodeId?: unknown; applicationType?: unknown; via?: unknown; at?: unknown }, knownSlots: readonly string[], ): BindingMap
|
|
766
806
|
```
|
|
767
807
|
|
|
808
|
+
#### `renderCommand` — function · src/machine/commands.ts
|
|
809
|
+
|
|
810
|
+
Render one declared command. Throws `DeviceCommandError` with a sentence for anything undeclared or ill-typed.
|
|
811
|
+
|
|
812
|
+
```ts
|
|
813
|
+
function renderCommand(block: DeviceBlock, name: string, params: Record<string, unknown> = {}): RenderedCommand
|
|
814
|
+
```
|
|
815
|
+
|
|
768
816
|
#### `resolveAppRole` — function · src/roles.ts
|
|
769
817
|
|
|
770
818
|
The app's word for this caller.
|
|
@@ -885,7 +933,7 @@ A manifest with one entry removed (the bytes stay; they may be shared). Pure.
|
|
|
885
933
|
function withoutAsset(assets: AssetsManifest | null | undefined, pluginId: string, name: string): AssetsManifest
|
|
886
934
|
```
|
|
887
935
|
|
|
888
|
-
### Types (
|
|
936
|
+
### Types (81)
|
|
889
937
|
|
|
890
938
|
#### `AgentRunToolContext` — interface · src/types.ts
|
|
891
939
|
|
|
@@ -1191,6 +1239,23 @@ interface CollapsibleConfig {
|
|
|
1191
1239
|
}
|
|
1192
1240
|
```
|
|
1193
1241
|
|
|
1242
|
+
#### `CommandSpec` — interface · src/machine/commands.ts
|
|
1243
|
+
|
|
1244
|
+
```ts
|
|
1245
|
+
interface CommandSpec {
|
|
1246
|
+
argv: string[];
|
|
1247
|
+
params?: Record<string, ParamSpec>;
|
|
1248
|
+
cwd?: string;
|
|
1249
|
+
env?: Record<string, string>;
|
|
1250
|
+
config?: string[];
|
|
1251
|
+
timeoutSeconds?: number;
|
|
1252
|
+
onRestart?: "report" | "rerun";
|
|
1253
|
+
output?: OutputSpec;
|
|
1254
|
+
result?: "text" | "json";
|
|
1255
|
+
describe?: string;
|
|
1256
|
+
}
|
|
1257
|
+
```
|
|
1258
|
+
|
|
1194
1259
|
#### `CompiledCustomRole` — interface · src/db/custom-roles.ts
|
|
1195
1260
|
|
|
1196
1261
|
```ts
|
|
@@ -1211,6 +1276,16 @@ interface CompiledCustomRole {
|
|
|
1211
1276
|
}
|
|
1212
1277
|
```
|
|
1213
1278
|
|
|
1279
|
+
#### `ConfigKeySpec` — interface · src/machine/commands.ts
|
|
1280
|
+
|
|
1281
|
+
```ts
|
|
1282
|
+
interface ConfigKeySpec {
|
|
1283
|
+
secret?: boolean;
|
|
1284
|
+
required?: boolean;
|
|
1285
|
+
describe?: string;
|
|
1286
|
+
}
|
|
1287
|
+
```
|
|
1288
|
+
|
|
1214
1289
|
#### `ContractDef` — interface · src/bindings.ts
|
|
1215
1290
|
|
|
1216
1291
|
What a contract REQUIRES of whoever claims it. The platform ships these; an app may publish its own.
|
|
@@ -1321,6 +1396,18 @@ interface DerivedTool extends ApplicationTools {
|
|
|
1321
1396
|
}
|
|
1322
1397
|
```
|
|
1323
1398
|
|
|
1399
|
+
#### `DeviceBlock` — interface · src/machine/commands.ts
|
|
1400
|
+
|
|
1401
|
+
```ts
|
|
1402
|
+
interface DeviceBlock {
|
|
1403
|
+
commands: Record<string, CommandSpec>;
|
|
1404
|
+
program?: ProgramSpec;
|
|
1405
|
+
config?: Record<string, ConfigKeySpec>;
|
|
1406
|
+
redact?: string[];
|
|
1407
|
+
onAppDeleted?: "kill" | "finish";
|
|
1408
|
+
}
|
|
1409
|
+
```
|
|
1410
|
+
|
|
1324
1411
|
#### `EventData` — interface · src/types.ts
|
|
1325
1412
|
|
|
1326
1413
|
```ts
|
|
@@ -1635,6 +1722,22 @@ interface OpToolConfig<S extends OpInput, R> {
|
|
|
1635
1722
|
}
|
|
1636
1723
|
```
|
|
1637
1724
|
|
|
1725
|
+
#### `ParamSpec` — type · src/machine/commands.ts
|
|
1726
|
+
|
|
1727
|
+
DECLARED COMMANDS — the wall between an app and the person's computer.
|
|
1728
|
+
|
|
1729
|
+
```ts
|
|
1730
|
+
type ParamSpec =
|
|
1731
|
+
| "int"
|
|
1732
|
+
| "number"
|
|
1733
|
+
| "bool"
|
|
1734
|
+
| "string"
|
|
1735
|
+
| { type: "int" | "number"; min?: number; max?: number; describe?: string }
|
|
1736
|
+
| { type: "string"; pattern?: string; maxLength?: number; allowDash?: boolean; describe?: string }
|
|
1737
|
+
| { type: "enum"; values: string[]; describe?: string }
|
|
1738
|
+
| { type: "bool"; describe?: string };
|
|
1739
|
+
```
|
|
1740
|
+
|
|
1638
1741
|
#### `ParsedSourceId` — type · src/files.ts
|
|
1639
1742
|
|
|
1640
1743
|
```ts
|
|
@@ -1733,6 +1836,20 @@ type ReconcileDecision =
|
|
|
1733
1836
|
| { kind: "adopt" };
|
|
1734
1837
|
```
|
|
1735
1838
|
|
|
1839
|
+
#### `RenderedCommand` — interface · src/machine/commands.ts
|
|
1840
|
+
|
|
1841
|
+
```ts
|
|
1842
|
+
interface RenderedCommand {
|
|
1843
|
+
name: string;
|
|
1844
|
+
argv: string[];
|
|
1845
|
+
cwd?: string;
|
|
1846
|
+
env: Record<string, string>;
|
|
1847
|
+
config: string[];
|
|
1848
|
+
timeoutSeconds: number;
|
|
1849
|
+
onRestart: "report" | "rerun";
|
|
1850
|
+
}
|
|
1851
|
+
```
|
|
1852
|
+
|
|
1736
1853
|
#### `RequiredStateShape` — interface · src/helpers.ts
|
|
1737
1854
|
|
|
1738
1855
|
Fields whose ABSENCE means "did not load" (they are seeded at genesis).
|
|
@@ -1810,11 +1927,11 @@ interface UsesDecl {
|
|
|
1810
1927
|
```
|
|
1811
1928
|
|
|
1812
1929
|
==============================================================================
|
|
1813
|
-
## `esoul-sdk/server` —
|
|
1930
|
+
## `esoul-sdk/server` — 79 exports
|
|
1814
1931
|
|
|
1815
1932
|
Server code only (server.ts, ops, routes, tasks): the viewer, the app's database, files, connections, machines, charts, route tokens.
|
|
1816
1933
|
|
|
1817
|
-
### Functions and values (
|
|
1934
|
+
### Functions and values (29)
|
|
1818
1935
|
|
|
1819
1936
|
#### `APPROVAL_WAIT` — const · src/computer.ts
|
|
1820
1937
|
|
|
@@ -1848,6 +1965,22 @@ COMPOSE A ROLE, as the owner: a name of its own, a base word from the vocabulary
|
|
|
1848
1965
|
function defineAppRole( _ctx: { pluginId: string; workspaceId: string; nodeId: string; viewer: PluginViewer }, _definition: CustomRoleDefinitionRaw, ): Promise<{ ok: boolean; name?: string; error?: string }>
|
|
1849
1966
|
```
|
|
1850
1967
|
|
|
1968
|
+
#### `DEVICE_RUN_TERMINAL` — const · src/device.ts
|
|
1969
|
+
|
|
1970
|
+
The statuses a run ends in: done, expired, cancelled, lost.
|
|
1971
|
+
|
|
1972
|
+
```ts
|
|
1973
|
+
const DEVICE_RUN_TERMINAL: readonly DeviceRunStatus[]
|
|
1974
|
+
```
|
|
1975
|
+
|
|
1976
|
+
#### `devices` — function · src/server.ts
|
|
1977
|
+
|
|
1978
|
+
PARTS OF THE APP THAT RUN ON THE PERSON'S COMPUTER (plugin-device-arm.md). The app declares its commands in plugin.json `device.commands`; the owner connects a computer with <ConnectComputer/> (esoul-sdk/react) and approves that list; then server code runs a declared command by name:
|
|
1979
|
+
|
|
1980
|
+
```ts
|
|
1981
|
+
function devices(_ctx: { pluginId: string; nodeId: string; viewer?: { canWrite: boolean; kind: string; userId: string | null } }): Devices
|
|
1982
|
+
```
|
|
1983
|
+
|
|
1851
1984
|
#### `emitPluginAppEvent` — function · src/server.ts
|
|
1852
1985
|
|
|
1853
1986
|
Cross-app events: dispatch the TARGET app's own events through the platform spine (target's dataCreator mints; triggers fire; every event is actor-stamped `{kind:"plugin", pluginId, sourceNodeId}`). Same-workspace only. HOST-ONLY.
|
|
@@ -2032,7 +2165,7 @@ WHO IS THIS, IN WORDS. The caller's own name and email, for an app with a reason
|
|
|
2032
2165
|
function viewerProfile(_viewer: PluginViewer): Promise<ViewerProfile | null>
|
|
2033
2166
|
```
|
|
2034
2167
|
|
|
2035
|
-
### Types (
|
|
2168
|
+
### Types (50)
|
|
2036
2169
|
|
|
2037
2170
|
#### `AppRolePerson` — interface · src/server.ts
|
|
2038
2171
|
|
|
@@ -2263,6 +2396,98 @@ interface CustomRolesEnvelope {
|
|
|
2263
2396
|
}
|
|
2264
2397
|
```
|
|
2265
2398
|
|
|
2399
|
+
#### `DeviceRunOptions` — interface · src/device.ts
|
|
2400
|
+
|
|
2401
|
+
```ts
|
|
2402
|
+
interface DeviceRunOptions {
|
|
2403
|
+
linkId?: string;
|
|
2404
|
+
expiresInSeconds?: number;
|
|
2405
|
+
}
|
|
2406
|
+
```
|
|
2407
|
+
|
|
2408
|
+
#### `DeviceRunStarted` — interface · src/device.ts
|
|
2409
|
+
|
|
2410
|
+
```ts
|
|
2411
|
+
interface DeviceRunStarted {
|
|
2412
|
+
commandId: string;
|
|
2413
|
+
status: DeviceRunStatus;
|
|
2414
|
+
machineOnline: boolean;
|
|
2415
|
+
expiresAt: number;
|
|
2416
|
+
}
|
|
2417
|
+
```
|
|
2418
|
+
|
|
2419
|
+
#### `DeviceRunStatus` — type · src/device.ts
|
|
2420
|
+
|
|
2421
|
+
```ts
|
|
2422
|
+
type DeviceRunStatus = "queued" | "claimed" | "running" | "done" | "expired" | "cancelled" | "lost";
|
|
2423
|
+
```
|
|
2424
|
+
|
|
2425
|
+
#### `DeviceRunView` — interface · src/device.ts
|
|
2426
|
+
|
|
2427
|
+
```ts
|
|
2428
|
+
interface DeviceRunView {
|
|
2429
|
+
commandId: string;
|
|
2430
|
+
linkId: string;
|
|
2431
|
+
machineId: string;
|
|
2432
|
+
capability?: string;
|
|
2433
|
+
agent?: string | null;
|
|
2434
|
+
name: string;
|
|
2435
|
+
params: Record<string, unknown>;
|
|
2436
|
+
argv: string[];
|
|
2437
|
+
status: DeviceRunStatus;
|
|
2438
|
+
exitCode: number | null;
|
|
2439
|
+
signal: string | null;
|
|
2440
|
+
reason: string | null;
|
|
2441
|
+
output?: string;
|
|
2442
|
+
tail?: string;
|
|
2443
|
+
result?: unknown;
|
|
2444
|
+
resultError?: string | null;
|
|
2445
|
+
outputMode?: "live" | "batched" | "final";
|
|
2446
|
+
outputBytes: number;
|
|
2447
|
+
outputSeq: number;
|
|
2448
|
+
truncated: boolean;
|
|
2449
|
+
createdAt: number;
|
|
2450
|
+
startedAt: number | null;
|
|
2451
|
+
endedAt: number | null;
|
|
2452
|
+
expiresAt: number;
|
|
2453
|
+
}
|
|
2454
|
+
```
|
|
2455
|
+
|
|
2456
|
+
#### `Devices` — interface · src/device.ts
|
|
2457
|
+
|
|
2458
|
+
```ts
|
|
2459
|
+
interface Devices {
|
|
2460
|
+
list(): Promise<DeviceSummary[]>;
|
|
2461
|
+
run(name: string, params?: Record<string, unknown>, opts?: DeviceRunOptions): Promise<DeviceRunStarted>;
|
|
2462
|
+
get(commandId: string): Promise<DeviceRunView>;
|
|
2463
|
+
wait(commandId: string, opts?: { timeoutSeconds?: number }): Promise<DeviceRunView>;
|
|
2464
|
+
cancel(commandId: string): Promise<{ status: string }>;
|
|
2465
|
+
sh(line: string, opts: { agent: string; stdin?: string; linkId?: string; waitSeconds?: number }): Promise<ShellResult & { commandId: string; status: DeviceRunStatus }>;
|
|
2466
|
+
program(linkId: string): {
|
|
2467
|
+
send(topic: string, data?: unknown, opts?: { waitSeconds?: number }): Promise<{ commandId: string; status: DeviceRunStatus; ok: boolean; result: unknown; error: string | null }>;
|
|
2468
|
+
state(): Promise<ProgramState | null>;
|
|
2469
|
+
};
|
|
2470
|
+
}
|
|
2471
|
+
```
|
|
2472
|
+
|
|
2473
|
+
#### `DeviceSummary` — interface · src/device.ts
|
|
2474
|
+
|
|
2475
|
+
One computer connected to this app instance.
|
|
2476
|
+
|
|
2477
|
+
```ts
|
|
2478
|
+
interface DeviceSummary {
|
|
2479
|
+
linkId: string;
|
|
2480
|
+
status: "active" | "suspended";
|
|
2481
|
+
reason: string | null;
|
|
2482
|
+
commands: string[];
|
|
2483
|
+
pendingApproval: { added: string[]; changed: string[] };
|
|
2484
|
+
machine: { machineId: string; hostname: string; os: string; arch: string | null; runtimeVersion: string | null; lastSeenAt: number | null; online: boolean } | null;
|
|
2485
|
+
workspace?: WorkspaceGrant | null;
|
|
2486
|
+
program?: boolean;
|
|
2487
|
+
programState?: ProgramState | null;
|
|
2488
|
+
}
|
|
2489
|
+
```
|
|
2490
|
+
|
|
2266
2491
|
#### `EmitPluginAppEventArgs` — interface · src/server.ts
|
|
2267
2492
|
|
|
2268
2493
|
```ts
|
|
@@ -2500,7 +2725,8 @@ interface PluginViewer {
|
|
|
2500
2725
|
attrs?: Record<string, AttrValue>;
|
|
2501
2726
|
canWrite: boolean;
|
|
2502
2727
|
shareId: string | null;
|
|
2503
|
-
agent?: { runId?: string; onBehalfOf: Omit<PluginViewer, "agent"> };
|
|
2728
|
+
agent?: { runId?: string; onBehalfOf: Omit<PluginViewer, "agent"> };
|
|
2729
|
+
device?: { machineId: string; linkId: string; hostname: string };
|
|
2504
2730
|
}
|
|
2505
2731
|
```
|
|
2506
2732
|
|
|
@@ -2541,6 +2767,38 @@ type PluginWebhookHandler = (
|
|
|
2541
2767
|
) => Promise<Response>;
|
|
2542
2768
|
```
|
|
2543
2769
|
|
|
2770
|
+
#### `ProgramState` — interface · src/machine/program-api.ts
|
|
2771
|
+
|
|
2772
|
+
Where an app's program stands on one computer — what the runtime reports and the app's Computers card renders. `phase` moves forward installing → setup → self-test → running (or ready, for a program started by its first message); `failed` and `refused` say why in `error`.
|
|
2773
|
+
|
|
2774
|
+
```ts
|
|
2775
|
+
interface ProgramState {
|
|
2776
|
+
digest: string;
|
|
2777
|
+
phase: "installing" | "setup" | "self-test" | "ready" | "starting" | "running" | "stopped" | "failed" | "refused";
|
|
2778
|
+
steps: ProgramStepState[];
|
|
2779
|
+
status?: { text: string; progress?: number; ready?: boolean; at: number } | null;
|
|
2780
|
+
error?: string | null;
|
|
2781
|
+
logTail?: string[];
|
|
2782
|
+
restarts: number;
|
|
2783
|
+
updatedAt: number;
|
|
2784
|
+
}
|
|
2785
|
+
```
|
|
2786
|
+
|
|
2787
|
+
#### `ProgramStepState` — interface · src/machine/program-api.ts
|
|
2788
|
+
|
|
2789
|
+
One setup step, as the Computers card shows it.
|
|
2790
|
+
|
|
2791
|
+
```ts
|
|
2792
|
+
interface ProgramStepState {
|
|
2793
|
+
id: string;
|
|
2794
|
+
describe: string;
|
|
2795
|
+
state: "pending" | "running" | "done" | "cached" | "failed";
|
|
2796
|
+
startedAt?: number;
|
|
2797
|
+
endedAt?: number;
|
|
2798
|
+
detail?: string;
|
|
2799
|
+
}
|
|
2800
|
+
```
|
|
2801
|
+
|
|
2544
2802
|
#### `RouteTokenGrant` — interface · src/server.ts
|
|
2545
2803
|
|
|
2546
2804
|
```ts
|
|
@@ -2561,6 +2819,22 @@ interface RunOptions {
|
|
|
2561
2819
|
}
|
|
2562
2820
|
```
|
|
2563
2821
|
|
|
2822
|
+
#### `ShellResult` — interface · src/device.ts
|
|
2823
|
+
|
|
2824
|
+
One line of the shared command line, answered (esoul-sdk/machine shell.ts): `text` is what a terminal would print (what an agent reads), `data` the same answer structured, `opId` the journal entry to `undo`.
|
|
2825
|
+
|
|
2826
|
+
```ts
|
|
2827
|
+
interface ShellResult {
|
|
2828
|
+
ok: boolean;
|
|
2829
|
+
text: string;
|
|
2830
|
+
data?: unknown;
|
|
2831
|
+
exitCode?: number | null;
|
|
2832
|
+
error?: string;
|
|
2833
|
+
opId?: string;
|
|
2834
|
+
cwd: string;
|
|
2835
|
+
}
|
|
2836
|
+
```
|
|
2837
|
+
|
|
2564
2838
|
#### `ToEndOptions` — interface · src/computer.ts
|
|
2565
2839
|
|
|
2566
2840
|
```ts
|
|
@@ -2582,12 +2856,28 @@ interface ViewerProfile {
|
|
|
2582
2856
|
}
|
|
2583
2857
|
```
|
|
2584
2858
|
|
|
2859
|
+
#### `WorkspaceGrant` — type · src/device.ts
|
|
2860
|
+
|
|
2861
|
+
What an app's agents may reach on a computer through the shared command line.
|
|
2862
|
+
|
|
2863
|
+
```ts
|
|
2864
|
+
type WorkspaceGrant = { scope: "folder"; root: string } | { scope: "computer" };
|
|
2865
|
+
```
|
|
2866
|
+
|
|
2585
2867
|
==============================================================================
|
|
2586
|
-
## `esoul-sdk/react` —
|
|
2868
|
+
## `esoul-sdk/react` — 64 exports
|
|
2587
2869
|
|
|
2588
2870
|
The app's UI: hooks for the viewer, the app's state, realtime, workspace files and tools.
|
|
2589
2871
|
|
|
2590
|
-
### Functions and values (
|
|
2872
|
+
### Functions and values (33)
|
|
2873
|
+
|
|
2874
|
+
#### `ConnectComputer` — function · src/react.ts
|
|
2875
|
+
|
|
2876
|
+
The connect panel for an app's config page: the computers already connected (online, last seen, Disconnect, Approve new commands) and "Connect a computer" — one command to paste in a terminal, the code the computer shows, Approve. Linux and macOS, Node 22+.
|
|
2877
|
+
|
|
2878
|
+
```ts
|
|
2879
|
+
function ConnectComputer(_props: { workspaceId: string; nodeId: string; title?: string; className?: string }): any
|
|
2880
|
+
```
|
|
2591
2881
|
|
|
2592
2882
|
#### `describeFailure` — function · src/failed-requests.ts
|
|
2593
2883
|
|
|
@@ -2693,6 +2983,30 @@ True when the current viewer may mutate this workspace.
|
|
|
2693
2983
|
function useAppCanEdit(): boolean
|
|
2694
2984
|
```
|
|
2695
2985
|
|
|
2986
|
+
#### `useDeviceActions` — function · src/react.ts
|
|
2987
|
+
|
|
2988
|
+
The owner's buttons from the UI: run a declared command, stop a run, disconnect a computer, approve an update's new commands. Needs edit access.
|
|
2989
|
+
|
|
2990
|
+
```ts
|
|
2991
|
+
function useDeviceActions(_where: { nodeId: string }): { run(name: string, params?: Record<string, unknown>, opts?: { linkId?: string; expiresInSeconds?: number }): Promise<DeviceRunStarted>; cancel(commandId: string): Promise<{ status: string }>; disconnect(linkId: string): Promise<{ ok: boolean }>; approveUpdate(linkId: string): Promise<unknown>; recent(limit?: number): Promise<{ commands: DeviceRunView[] }>; /** What the app's agents may reach on that computer: none, its folder, or the whole computer. */ setWorkspace(linkId: string, workspace: "none" | "folder" | "computer"): Promise<unknown>; /** One line of the shared command line as a named agent; `result` is the answer once it ends. */ sh(line: string, opts: { agent: string; stdin?: string; linkId?: string; waitSeconds?: number }): Promise<DeviceRunView & { result?: import("./device.js").ShellResult }>; }
|
|
2992
|
+
```
|
|
2993
|
+
|
|
2994
|
+
#### `useDeviceRun` — function · src/react.ts
|
|
2995
|
+
|
|
2996
|
+
One run, live: status as it changes, output as it streams. `finished` once it ended.
|
|
2997
|
+
|
|
2998
|
+
```ts
|
|
2999
|
+
function useDeviceRun(_where: { workspaceId: string; nodeId: string; commandId: string | null | undefined }): { run: DeviceRunView | null; error: string | null; refetch: () => Promise<void>; finished: boolean }
|
|
3000
|
+
```
|
|
3001
|
+
|
|
3002
|
+
#### `useDevices` — function · src/react.ts
|
|
3003
|
+
|
|
3004
|
+
The computers connected to this app instance, live (presence refreshes every 20 s).
|
|
3005
|
+
|
|
3006
|
+
```ts
|
|
3007
|
+
function useDevices(_where: { workspaceId: string; nodeId: string }): { devices: DeviceSummary[] | null; error: string | null; refresh: () => Promise<void> }
|
|
3008
|
+
```
|
|
3009
|
+
|
|
2696
3010
|
#### `useFileSourceEntries` — function · src/react.ts
|
|
2697
3011
|
|
|
2698
3012
|
One folder's listing; a failing source reports error/errorKind, never []. `opts` narrows AT THE SOURCE — `{ only: "folder" }`, `{ nameContains }`, `{ orderBy: "name", pageSize: 1000 }` — and `loadMore()` appends the next page.
|
|
@@ -2725,6 +3039,14 @@ A folder box with autocomplete: give it the text being typed ("sheets/quality_da
|
|
|
2725
3039
|
function useFolderAutocomplete(_workspaceId: string | null, _sourceId: string | null, _text: string): FolderAutocompleteState
|
|
2726
3040
|
```
|
|
2727
3041
|
|
|
3042
|
+
#### `useMyComputers` — function · src/react.ts
|
|
3043
|
+
|
|
3044
|
+
The account's computers (computers belong to the person, not to an app; an app gets one by assignment). `assign(machineId, nodeId)` gives a computer to an app (approving its declared commands); `disconnect(machineId)` removes a computer from the account entirely.
|
|
3045
|
+
|
|
3046
|
+
```ts
|
|
3047
|
+
function useMyComputers(): { computers: MyComputer[] | null; error: string | null; refresh: () => Promise<void>; assign(machineId: string, nodeId: string): Promise<{ linkId: string }>; disconnect(machineId: string): Promise<{ ok: boolean }> }
|
|
3048
|
+
```
|
|
3049
|
+
|
|
2728
3050
|
#### `usePluginCurrentChatId` — function · src/react.ts
|
|
2729
3051
|
|
|
2730
3052
|
Current open chat id, for `chatIdSource` attribution.
|
|
@@ -2805,7 +3127,75 @@ Invoke tools of OTHER apps in the workspace (append a spreadsheet row, add a cal
|
|
|
2805
3127
|
function useWorkspaceTools(_identity: { workspaceId: string; nodeId: string }): WorkspaceTools
|
|
2806
3128
|
```
|
|
2807
3129
|
|
|
2808
|
-
|
|
3130
|
+
#### `YourComputers` — function · src/react.ts
|
|
3131
|
+
|
|
3132
|
+
The account's computers as a panel: online, the apps each serves, Disconnect.
|
|
3133
|
+
|
|
3134
|
+
```ts
|
|
3135
|
+
function YourComputers(_props: { className?: string }): any
|
|
3136
|
+
```
|
|
3137
|
+
|
|
3138
|
+
### Types (31)
|
|
3139
|
+
|
|
3140
|
+
#### `DeviceRunStarted` — interface · src/device.ts
|
|
3141
|
+
|
|
3142
|
+
```ts
|
|
3143
|
+
interface DeviceRunStarted {
|
|
3144
|
+
commandId: string;
|
|
3145
|
+
status: DeviceRunStatus;
|
|
3146
|
+
machineOnline: boolean;
|
|
3147
|
+
expiresAt: number;
|
|
3148
|
+
}
|
|
3149
|
+
```
|
|
3150
|
+
|
|
3151
|
+
#### `DeviceRunView` — interface · src/device.ts
|
|
3152
|
+
|
|
3153
|
+
```ts
|
|
3154
|
+
interface DeviceRunView {
|
|
3155
|
+
commandId: string;
|
|
3156
|
+
linkId: string;
|
|
3157
|
+
machineId: string;
|
|
3158
|
+
capability?: string;
|
|
3159
|
+
agent?: string | null;
|
|
3160
|
+
name: string;
|
|
3161
|
+
params: Record<string, unknown>;
|
|
3162
|
+
argv: string[];
|
|
3163
|
+
status: DeviceRunStatus;
|
|
3164
|
+
exitCode: number | null;
|
|
3165
|
+
signal: string | null;
|
|
3166
|
+
reason: string | null;
|
|
3167
|
+
output?: string;
|
|
3168
|
+
tail?: string;
|
|
3169
|
+
result?: unknown;
|
|
3170
|
+
resultError?: string | null;
|
|
3171
|
+
outputMode?: "live" | "batched" | "final";
|
|
3172
|
+
outputBytes: number;
|
|
3173
|
+
outputSeq: number;
|
|
3174
|
+
truncated: boolean;
|
|
3175
|
+
createdAt: number;
|
|
3176
|
+
startedAt: number | null;
|
|
3177
|
+
endedAt: number | null;
|
|
3178
|
+
expiresAt: number;
|
|
3179
|
+
}
|
|
3180
|
+
```
|
|
3181
|
+
|
|
3182
|
+
#### `DeviceSummary` — interface · src/device.ts
|
|
3183
|
+
|
|
3184
|
+
One computer connected to this app instance.
|
|
3185
|
+
|
|
3186
|
+
```ts
|
|
3187
|
+
interface DeviceSummary {
|
|
3188
|
+
linkId: string;
|
|
3189
|
+
status: "active" | "suspended";
|
|
3190
|
+
reason: string | null;
|
|
3191
|
+
commands: string[];
|
|
3192
|
+
pendingApproval: { added: string[]; changed: string[] };
|
|
3193
|
+
machine: { machineId: string; hostname: string; os: string; arch: string | null; runtimeVersion: string | null; lastSeenAt: number | null; online: boolean } | null;
|
|
3194
|
+
workspace?: WorkspaceGrant | null;
|
|
3195
|
+
program?: boolean;
|
|
3196
|
+
programState?: ProgramState | null;
|
|
3197
|
+
}
|
|
3198
|
+
```
|
|
2809
3199
|
|
|
2810
3200
|
#### `FailedRequest` — interface · src/failed-requests.ts
|
|
2811
3201
|
|
|
@@ -2923,6 +3313,23 @@ interface LabelClass {
|
|
|
2923
3313
|
}
|
|
2924
3314
|
```
|
|
2925
3315
|
|
|
3316
|
+
#### `MyComputer` — interface · src/react.ts
|
|
3317
|
+
|
|
3318
|
+
One computer connected to the signed-in account, and the apps it is assigned to.
|
|
3319
|
+
|
|
3320
|
+
```ts
|
|
3321
|
+
interface MyComputer {
|
|
3322
|
+
machineId: string;
|
|
3323
|
+
hostname: string;
|
|
3324
|
+
os: string;
|
|
3325
|
+
arch: string | null;
|
|
3326
|
+
runtimeVersion: string | null;
|
|
3327
|
+
lastSeenAt: number | null;
|
|
3328
|
+
online: boolean;
|
|
3329
|
+
apps: { linkId: string; nodeId: string; workspaceId: string; status: string; appName: string | null }[];
|
|
3330
|
+
}
|
|
3331
|
+
```
|
|
3332
|
+
|
|
2926
3333
|
#### `PluginRealtime` — interface · src/react.ts
|
|
2927
3334
|
|
|
2928
3335
|
```ts
|
|
@@ -3068,6 +3475,22 @@ interface ResolvedFilePath {
|
|
|
3068
3475
|
}
|
|
3069
3476
|
```
|
|
3070
3477
|
|
|
3478
|
+
#### `ShellResult` — interface · src/device.ts
|
|
3479
|
+
|
|
3480
|
+
One line of the shared command line, answered (esoul-sdk/machine shell.ts): `text` is what a terminal would print (what an agent reads), `data` the same answer structured, `opId` the journal entry to `undo`.
|
|
3481
|
+
|
|
3482
|
+
```ts
|
|
3483
|
+
interface ShellResult {
|
|
3484
|
+
ok: boolean;
|
|
3485
|
+
text: string;
|
|
3486
|
+
data?: unknown;
|
|
3487
|
+
exitCode?: number | null;
|
|
3488
|
+
error?: string;
|
|
3489
|
+
opId?: string;
|
|
3490
|
+
cwd: string;
|
|
3491
|
+
}
|
|
3492
|
+
```
|
|
3493
|
+
|
|
3071
3494
|
#### `SignInWall` — interface · src/react.ts
|
|
3072
3495
|
|
|
3073
3496
|
```ts
|
|
@@ -3091,6 +3514,14 @@ interface WorkspaceAppSummary {
|
|
|
3091
3514
|
}
|
|
3092
3515
|
```
|
|
3093
3516
|
|
|
3517
|
+
#### `WorkspaceGrant` — type · src/device.ts
|
|
3518
|
+
|
|
3519
|
+
What an app's agents may reach on a computer through the shared command line.
|
|
3520
|
+
|
|
3521
|
+
```ts
|
|
3522
|
+
type WorkspaceGrant = { scope: "folder"; root: string } | { scope: "computer" };
|
|
3523
|
+
```
|
|
3524
|
+
|
|
3094
3525
|
#### `WorkspaceNav` — interface · src/react.ts
|
|
3095
3526
|
|
|
3096
3527
|
```ts
|
|
@@ -3344,3 +3775,990 @@ interface TestManifest {
|
|
|
3344
3775
|
```ts
|
|
3345
3776
|
type ViewerKind = RuleViewer["kind"];
|
|
3346
3777
|
```
|
|
3778
|
+
|
|
3779
|
+
==============================================================================
|
|
3780
|
+
## `esoul-sdk/machine` — 102 exports
|
|
3781
|
+
|
|
3782
|
+
The side of an app that runs on the person's computer: the signed door protocol, the declared-command rules, the runtime behind the `esoul-device` command. Node built-ins only.
|
|
3783
|
+
|
|
3784
|
+
### Functions and values (62)
|
|
3785
|
+
|
|
3786
|
+
#### `AGENT_NAME_RE` — const · src/machine/shell.ts
|
|
3787
|
+
|
|
3788
|
+
What an agent may be called: lowercase letters, digits, - and _, up to 32, starting with a letter.
|
|
3789
|
+
|
|
3790
|
+
```ts
|
|
3791
|
+
const AGENT_NAME_RE: RegExp
|
|
3792
|
+
```
|
|
3793
|
+
|
|
3794
|
+
#### `announce` — function · src/machine/capabilities.ts
|
|
3795
|
+
|
|
3796
|
+
What the hello announces: ["commands@1", "workspace@1"].
|
|
3797
|
+
|
|
3798
|
+
```ts
|
|
3799
|
+
function announce(reg: Map<string, Capability>): string[]
|
|
3800
|
+
```
|
|
3801
|
+
|
|
3802
|
+
#### `applyEdits` — function · src/machine/files.ts
|
|
3803
|
+
|
|
3804
|
+
Find-and-replace edits, applied in order; each must match exactly once (unless `all`). All or nothing.
|
|
3805
|
+
|
|
3806
|
+
```ts
|
|
3807
|
+
function applyEdits(text: string, edits: Edit[]): { text: string; applied: number }
|
|
3808
|
+
```
|
|
3809
|
+
|
|
3810
|
+
#### `applyPatch` — function · src/machine/files.ts
|
|
3811
|
+
|
|
3812
|
+
Apply a unified diff with context. Each hunk's old lines (context + removed) are located exactly, preferring the line the diff names and searching outward, so a file that moved on still takes a hunk whose context is intact. A hunk whose context is gone is reported, never forced. All-or-nothing unless `partial`.
|
|
3813
|
+
|
|
3814
|
+
```ts
|
|
3815
|
+
function applyPatch(text: string, diff: string, opts: { partial?: boolean } = {}): { text: string; results: HunkResult[] }
|
|
3816
|
+
```
|
|
3817
|
+
|
|
3818
|
+
#### `approvedCommandNames` — function · src/machine/digest.ts
|
|
3819
|
+
|
|
3820
|
+
The command names an approval covers (without the program's entry).
|
|
3821
|
+
|
|
3822
|
+
```ts
|
|
3823
|
+
function approvedCommandNames(approved: Record<string, string>): string[]
|
|
3824
|
+
```
|
|
3825
|
+
|
|
3826
|
+
#### `builtInCapabilities` — function · src/machine/capabilities.ts
|
|
3827
|
+
|
|
3828
|
+
The capabilities this runtime is built with, as one registry (the supervisor dispatches through it).
|
|
3829
|
+
|
|
3830
|
+
```ts
|
|
3831
|
+
function builtInCapabilities(startRun: (job: Job, redact: string[], env: Record<string, string>) => Promise<void>, programs: ProgramDelivery | null = null): Map<string, Capability>
|
|
3832
|
+
```
|
|
3833
|
+
|
|
3834
|
+
#### `canonical` — function · src/machine/protocol.ts
|
|
3835
|
+
|
|
3836
|
+
The exact bytes that are signed. Path INCLUDES the query string.
|
|
3837
|
+
|
|
3838
|
+
```ts
|
|
3839
|
+
function canonical(method: string, pathAndQuery: string, ts: number | string, body: string | Uint8Array): string
|
|
3840
|
+
```
|
|
3841
|
+
|
|
3842
|
+
#### `COMMAND_NAME_RE` — const · src/machine/commands.ts
|
|
3843
|
+
|
|
3844
|
+
What a command name may look like: lowercase, starts with a letter, up to 40 characters.
|
|
3845
|
+
|
|
3846
|
+
```ts
|
|
3847
|
+
const COMMAND_NAME_RE: RegExp
|
|
3848
|
+
```
|
|
3849
|
+
|
|
3850
|
+
#### `commandDigest` — function · src/machine/digest.ts
|
|
3851
|
+
|
|
3852
|
+
Stable digest of one command's spec — what the owner approved.
|
|
3853
|
+
|
|
3854
|
+
```ts
|
|
3855
|
+
function commandDigest(spec: CommandSpec): string
|
|
3856
|
+
```
|
|
3857
|
+
|
|
3858
|
+
#### `commandDigests` — function · src/machine/digest.ts
|
|
3859
|
+
|
|
3860
|
+
Every declared command's digest, by name, and the program's under `@program` — what an approval records.
|
|
3861
|
+
|
|
3862
|
+
```ts
|
|
3863
|
+
function commandDigests(block: DeviceBlock): Record<string, string>
|
|
3864
|
+
```
|
|
3865
|
+
|
|
3866
|
+
#### `commandsCapability` — function · src/machine/capabilities.ts
|
|
3867
|
+
|
|
3868
|
+
The app's declared commands; the detached runner owns and reports each run.
|
|
3869
|
+
|
|
3870
|
+
```ts
|
|
3871
|
+
function commandsCapability(deps: { startRun: (job: Job, redact: string[], env: Record<string, string>) => Promise<void> }): Capability
|
|
3872
|
+
```
|
|
3873
|
+
|
|
3874
|
+
#### `confinedArgv` — function · src/machine/shell.ts
|
|
3875
|
+
|
|
3876
|
+
argv that runs `line` in `cwd` under the scope's confinement.
|
|
3877
|
+
|
|
3878
|
+
```ts
|
|
3879
|
+
function confinedArgv(ws: Workspace, cwd: string, line: string): string[]
|
|
3880
|
+
```
|
|
3881
|
+
|
|
3882
|
+
#### `connect` — function · src/machine/supervisor.ts
|
|
3883
|
+
|
|
3884
|
+
Answer a connect link from the app's page with this computer's key: print the code and the commands, wait for the owner's approval.
|
|
3885
|
+
|
|
3886
|
+
```ts
|
|
3887
|
+
async function connect(opts: ConnectOptions): Promise<ConnectResult>
|
|
3888
|
+
```
|
|
3889
|
+
|
|
3890
|
+
#### `connectCode` — function · src/machine/protocol.ts
|
|
3891
|
+
|
|
3892
|
+
The short code both the machine and the connect page show, so the owner can see the request on screen is the one from the machine in front of them. Derived from the machine's public key + the offer, so neither side invents it.
|
|
3893
|
+
|
|
3894
|
+
```ts
|
|
3895
|
+
function connectCode(publicKey: string, offerId: string): string
|
|
3896
|
+
```
|
|
3897
|
+
|
|
3898
|
+
#### `createProgramManager` — function · src/machine/program-manager.ts
|
|
3899
|
+
|
|
3900
|
+
The runtime's keeper of app programs: `reconcile(links)` after each hello brings every approved program to its approved digest (download, verify, setup, self-test, start) and stops the rest; `deliver` hands a program the app's message and resolves with its answer.
|
|
3901
|
+
|
|
3902
|
+
```ts
|
|
3903
|
+
function createProgramManager(opts: ProgramManagerOptions)
|
|
3904
|
+
```
|
|
3905
|
+
|
|
3906
|
+
#### `DEFAULT_TIMEOUT_SECONDS` — const · src/machine/commands.ts
|
|
3907
|
+
|
|
3908
|
+
A command's time limit when it declares none: one hour.
|
|
3909
|
+
|
|
3910
|
+
```ts
|
|
3911
|
+
const DEFAULT_TIMEOUT_SECONDS: 3600
|
|
3912
|
+
```
|
|
3913
|
+
|
|
3914
|
+
#### `defineProgram` — function · src/machine/program-api.ts
|
|
3915
|
+
|
|
3916
|
+
Identity helper for a program written in plain JavaScript (TypeScript can use `satisfies Program`).
|
|
3917
|
+
|
|
3918
|
+
```ts
|
|
3919
|
+
function defineProgram(program: Program): Program
|
|
3920
|
+
```
|
|
3921
|
+
|
|
3922
|
+
#### `describeGrant` — function · src/machine/grant.ts
|
|
3923
|
+
|
|
3924
|
+
A grant in words: "the folder /home/me/proj", "the whole computer", or "no workspace access".
|
|
3925
|
+
|
|
3926
|
+
```ts
|
|
3927
|
+
function describeGrant(g: WorkspaceGrant | null): string
|
|
3928
|
+
```
|
|
3929
|
+
|
|
3930
|
+
#### `deviceBlockProblems` — function · src/machine/commands.ts
|
|
3931
|
+
|
|
3932
|
+
Every problem with a `device` block, in words an author can act on. Empty = valid.
|
|
3933
|
+
|
|
3934
|
+
```ts
|
|
3935
|
+
function deviceBlockProblems(block: unknown): string[]
|
|
3936
|
+
```
|
|
3937
|
+
|
|
3938
|
+
#### `DeviceCommandError` — class · src/machine/commands.ts
|
|
3939
|
+
|
|
3940
|
+
Why a command was refused: `unknown_command` (not declared), `bad_param` (missing, extra or ill-typed), `bad_spec`. The message says which, in words.
|
|
3941
|
+
|
|
3942
|
+
```ts
|
|
3943
|
+
class DeviceCommandError extends Error { … }
|
|
3944
|
+
```
|
|
3945
|
+
|
|
3946
|
+
#### `deviceHome` — function · src/machine/state.ts
|
|
3947
|
+
|
|
3948
|
+
The runtime's folder on this computer: `explicit`, else ESOUL_DEVICE_HOME, else ~/.esoul-device.
|
|
3949
|
+
|
|
3950
|
+
```ts
|
|
3951
|
+
function deviceHome(explicit?: string): string
|
|
3952
|
+
```
|
|
3953
|
+
|
|
3954
|
+
#### `DoorError` — class · src/machine/client.ts
|
|
3955
|
+
|
|
3956
|
+
A door call that failed: `status` 0 means the door never answered (network); otherwise the door's own `code` and message.
|
|
3957
|
+
|
|
3958
|
+
```ts
|
|
3959
|
+
class DoorError extends Error { … }
|
|
3960
|
+
```
|
|
3961
|
+
|
|
3962
|
+
#### `effectiveGrant` — function · src/machine/grant.ts
|
|
3963
|
+
|
|
3964
|
+
What the runtime actually allows: the grant, if it fits inside the ceiling. A folder grant inside a folder ceiling keeps the grant's (narrower) root; a computer grant needs a computer ceiling.
|
|
3965
|
+
|
|
3966
|
+
```ts
|
|
3967
|
+
function effectiveGrant(grant: WorkspaceGrant | null, ceiling: WorkspaceGrant | null): { ok: true; grant: WorkspaceGrant; why?: undefined } | { ok: false; why: string; grant?: undefined }
|
|
3968
|
+
```
|
|
3969
|
+
|
|
3970
|
+
#### `execute` — function · src/machine/shell.ts
|
|
3971
|
+
|
|
3972
|
+
Run one line of the shared command line as a named agent in a workspace; never throws — failures come back as `ok: false` with an `error` code.
|
|
3973
|
+
|
|
3974
|
+
```ts
|
|
3975
|
+
async function execute(call: ShellCall): Promise<ShellResult>
|
|
3976
|
+
```
|
|
3977
|
+
|
|
3978
|
+
#### `FileError` — class · src/machine/files.ts
|
|
3979
|
+
|
|
3980
|
+
Why a file operation was refused: outside_scope, not_found, changed, hard_link, edit_failed, patch_failed, … — with a sentence and details.
|
|
3981
|
+
|
|
3982
|
+
```ts
|
|
3983
|
+
class FileError extends Error { … }
|
|
3984
|
+
```
|
|
3985
|
+
|
|
3986
|
+
#### `generateDeviceKey` — function · src/machine/protocol.ts
|
|
3987
|
+
|
|
3988
|
+
A new Ed25519 keypair for a computer: the public key in base64url, the private key as PKCS#8 PEM (it never leaves the computer).
|
|
3989
|
+
|
|
3990
|
+
```ts
|
|
3991
|
+
function generateDeviceKey(): DeviceKeyPair
|
|
3992
|
+
```
|
|
3993
|
+
|
|
3994
|
+
#### `grantFromChoice` — function · src/machine/grant.ts
|
|
3995
|
+
|
|
3996
|
+
The owner's choice turned into a grant under this computer's ceiling, or why it cannot be.
|
|
3997
|
+
|
|
3998
|
+
```ts
|
|
3999
|
+
function grantFromChoice(choice: WorkspaceChoice, ceiling: WorkspaceGrant | null): { ok: true; grant: WorkspaceGrant | null; why?: undefined } | { ok: false; why: string; grant?: undefined }
|
|
4000
|
+
```
|
|
4001
|
+
|
|
4002
|
+
#### `H` — const · src/machine/protocol.ts
|
|
4003
|
+
|
|
4004
|
+
Request headers. `key` names the signer: a machine id, or `connect:<id>` before approval.
|
|
4005
|
+
|
|
4006
|
+
```ts
|
|
4007
|
+
const H: { readonly key: "x-esoul-key"; readonly ts: "x-esoul-ts"; readonly sig: "x-esoul-sig"; readonly runtime: "x-esoul-runtime"; }
|
|
4008
|
+
```
|
|
4009
|
+
|
|
4010
|
+
#### `isPublicKey` — function · src/machine/protocol.ts
|
|
4011
|
+
|
|
4012
|
+
Whether `s` is a base64url Ed25519 public key (43 characters).
|
|
4013
|
+
|
|
4014
|
+
```ts
|
|
4015
|
+
function isPublicKey(s: unknown): s is string
|
|
4016
|
+
```
|
|
4017
|
+
|
|
4018
|
+
#### `isTransient` — function · src/machine/client.ts
|
|
4019
|
+
|
|
4020
|
+
Transient = worth retrying later without telling anyone.
|
|
4021
|
+
|
|
4022
|
+
```ts
|
|
4023
|
+
function isTransient(e: unknown): boolean
|
|
4024
|
+
```
|
|
4025
|
+
|
|
4026
|
+
#### `Journal` — class · src/machine/files.ts
|
|
4027
|
+
|
|
4028
|
+
The undo journal of one workspace: previous contents (content-addressed), directory snapshots, and the append-only log of operations.
|
|
4029
|
+
|
|
4030
|
+
```ts
|
|
4031
|
+
class Journal { … }
|
|
4032
|
+
```
|
|
4033
|
+
|
|
4034
|
+
#### `machineFingerprint` — function · src/machine/state.ts
|
|
4035
|
+
|
|
4036
|
+
This computer, stably: the OS machine id (Linux /etc/machine-id, macOS the platform UUID), the user, and the runtime home. Sent when connecting, so the platform RECOGNISES a reconnect (a reinstall, a new key) instead of listing a second entry for the same computer. A different home is deliberately a different computer (a second runtime, a test run).
|
|
4037
|
+
|
|
4038
|
+
```ts
|
|
4039
|
+
function machineFingerprint(home: string): string
|
|
4040
|
+
```
|
|
4041
|
+
|
|
4042
|
+
#### `makeClient` — function · src/machine/client.ts
|
|
4043
|
+
|
|
4044
|
+
A signed door client for one key: every call carries the signature, retries only what the door never answered.
|
|
4045
|
+
|
|
4046
|
+
```ts
|
|
4047
|
+
function makeClient(args: { base: string; keyId: string; privateKeyPem: string; runtimeVersion: string; fetch?: FetchLike; onTiming?: (t: CallTiming) => void }): DoorClient
|
|
4048
|
+
```
|
|
4049
|
+
|
|
4050
|
+
#### `MAX_SKEW_MS` — const · src/machine/protocol.ts
|
|
4051
|
+
|
|
4052
|
+
How far a request's clock may be from the server's. Laptops drift; five minutes is generous and still bounds a replay.
|
|
4053
|
+
|
|
4054
|
+
```ts
|
|
4055
|
+
const MAX_SKEW_MS: number
|
|
4056
|
+
```
|
|
4057
|
+
|
|
4058
|
+
#### `MAX_TIMEOUT_SECONDS` — const · src/machine/commands.ts
|
|
4059
|
+
|
|
4060
|
+
The longest time limit a command may declare: seven days.
|
|
4061
|
+
|
|
4062
|
+
```ts
|
|
4063
|
+
const MAX_TIMEOUT_SECONDS: number
|
|
4064
|
+
```
|
|
4065
|
+
|
|
4066
|
+
#### `newAuthority` — function · src/machine/digest.ts
|
|
4067
|
+
|
|
4068
|
+
What an app update asks of the owner. Removing a command, or leaving one untouched, needs nothing; ADDING a command or CHANGING one is new authority and waits for a fresh approval.
|
|
4069
|
+
|
|
4070
|
+
```ts
|
|
4071
|
+
function newAuthority(approved: Record<string, string>, current: DeviceBlock): { added: string[]; changed: string[] }
|
|
4072
|
+
```
|
|
4073
|
+
|
|
4074
|
+
#### `openWorkspace` — function · src/machine/shell.ts
|
|
4075
|
+
|
|
4076
|
+
Open (or create) the workspace for a scope under the runtime's home.
|
|
4077
|
+
|
|
4078
|
+
```ts
|
|
4079
|
+
function openWorkspace(home: string, id: string, scope: Scope): Workspace
|
|
4080
|
+
```
|
|
4081
|
+
|
|
4082
|
+
#### `OUTPUT_LIMITS` — const · src/machine/commands.ts
|
|
4083
|
+
|
|
4084
|
+
The ceilings of the output options: chunk 3 MB, stored head 8 MB, gather 60 s, tail 64 KB.
|
|
4085
|
+
|
|
4086
|
+
```ts
|
|
4087
|
+
const OUTPUT_LIMITS: { readonly maxChunkKb: 3072; readonly maxKb: 8192; readonly flushMs: 60000; readonly tailChars: number; }
|
|
4088
|
+
```
|
|
4089
|
+
|
|
4090
|
+
#### `OutputUploader` — class · src/machine/capabilities.ts
|
|
4091
|
+
|
|
4092
|
+
Ordered, batched, retried upload of one job's output (the run directory is the outbox for detached runs; inline jobs hold theirs here). `finish` drains the output, then reports the end with the result.
|
|
4093
|
+
|
|
4094
|
+
```ts
|
|
4095
|
+
class OutputUploader { … }
|
|
4096
|
+
```
|
|
4097
|
+
|
|
4098
|
+
#### `parseGrant` — function · src/machine/grant.ts
|
|
4099
|
+
|
|
4100
|
+
A grant from untrusted JSON, or null. Roots must be absolute and plain.
|
|
4101
|
+
|
|
4102
|
+
```ts
|
|
4103
|
+
function parseGrant(v: unknown): WorkspaceGrant | null
|
|
4104
|
+
```
|
|
4105
|
+
|
|
4106
|
+
#### `parseUnifiedDiff` — function · src/machine/files.ts
|
|
4107
|
+
|
|
4108
|
+
The hunks of a unified diff (`@@ -a,b +c,d
|
|
4109
|
+
|
|
4110
|
+
```ts
|
|
4111
|
+
function parseUnifiedDiff(diff: string): Hunk[]
|
|
4112
|
+
```
|
|
4113
|
+
|
|
4114
|
+
#### `PROGRAM_KEY` — const · src/machine/digest.ts
|
|
4115
|
+
|
|
4116
|
+
Where an approval records the program's digest, beside the commands' (no command name can start with "@").
|
|
4117
|
+
|
|
4118
|
+
```ts
|
|
4119
|
+
const PROGRAM_KEY: "@program"
|
|
4120
|
+
```
|
|
4121
|
+
|
|
4122
|
+
#### `PROGRAM_MAX_BYTES` — const · src/machine/commands.ts
|
|
4123
|
+
|
|
4124
|
+
A program's files: at most this many bytes in all (setup steps download the heavy things).
|
|
4125
|
+
|
|
4126
|
+
```ts
|
|
4127
|
+
const PROGRAM_MAX_BYTES: number
|
|
4128
|
+
```
|
|
4129
|
+
|
|
4130
|
+
#### `PROGRAM_MAX_FILES` — const · src/machine/commands.ts
|
|
4131
|
+
|
|
4132
|
+
A program's files: at most this many.
|
|
4133
|
+
|
|
4134
|
+
```ts
|
|
4135
|
+
const PROGRAM_MAX_FILES: 200
|
|
4136
|
+
```
|
|
4137
|
+
|
|
4138
|
+
#### `programCapability` — function · src/machine/capabilities.ts
|
|
4139
|
+
|
|
4140
|
+
A message from the app to its program on this computer; the program's answer is the job's result.
|
|
4141
|
+
|
|
4142
|
+
```ts
|
|
4143
|
+
function programCapability(programs: ProgramDelivery | null): Capability
|
|
4144
|
+
```
|
|
4145
|
+
|
|
4146
|
+
#### `programDigest` — function · src/machine/digest.ts
|
|
4147
|
+
|
|
4148
|
+
The digest of a program: its spec (without the computed fields) and every file, sorted by path. Two builds of the same files give the same digest.
|
|
4149
|
+
|
|
4150
|
+
```ts
|
|
4151
|
+
function programDigest(spec: Omit<ProgramSpec, "digest" | "size">, files: { path: string; content: Buffer | Uint8Array | string }[]): string
|
|
4152
|
+
```
|
|
4153
|
+
|
|
4154
|
+
#### `programEnv` — function · src/machine/program-manager.ts
|
|
4155
|
+
|
|
4156
|
+
The environment an app's program and its setup steps get: scrubbed (the runtime's own settings never reach app code), the runtime's Node FIRST on PATH — on a computer whose only Node is the one the bootstrap brought (showrack), `node` in a setup step must be it — and HOME its own data folder, or the person's real home when the whole computer was granted (unconfined).
|
|
4157
|
+
|
|
4158
|
+
```ts
|
|
4159
|
+
function programEnv(env: Record<string, string | undefined>, nodePath: string, dataDir: string, opts: { unconfined?: boolean } = {}): Record<string, string>
|
|
4160
|
+
```
|
|
4161
|
+
|
|
4162
|
+
#### `programPaths` — function · src/machine/program-manager.ts
|
|
4163
|
+
|
|
4164
|
+
Where an app's program lives in the runtime's folder: its version folder, its own data folder, setup markers and logs.
|
|
4165
|
+
|
|
4166
|
+
```ts
|
|
4167
|
+
function programPaths(home: string, linkId: string, digest?: string)
|
|
4168
|
+
```
|
|
4169
|
+
|
|
4170
|
+
#### `programProblems` — function · src/machine/commands.ts
|
|
4171
|
+
|
|
4172
|
+
What is wrong with a program spec, in words (the platform's build adds `digest` and `size`).
|
|
4173
|
+
|
|
4174
|
+
```ts
|
|
4175
|
+
function programProblems(p: unknown): string[]
|
|
4176
|
+
```
|
|
4177
|
+
|
|
4178
|
+
#### `PROTOCOL` — const · src/machine/protocol.ts
|
|
4179
|
+
|
|
4180
|
+
The protocol version, the first line of every signed request.
|
|
4181
|
+
|
|
4182
|
+
```ts
|
|
4183
|
+
const PROTOCOL: "esoul-device/1"
|
|
4184
|
+
```
|
|
4185
|
+
|
|
4186
|
+
#### `registry` — function · src/machine/capabilities.ts
|
|
4187
|
+
|
|
4188
|
+
The capability table the runtime dispatches jobs through, by name.
|
|
4189
|
+
|
|
4190
|
+
```ts
|
|
4191
|
+
function registry(caps: Capability[]): Map<string, Capability>
|
|
4192
|
+
```
|
|
4193
|
+
|
|
4194
|
+
#### `renderCommand` — function · src/machine/commands.ts
|
|
4195
|
+
|
|
4196
|
+
Render one declared command. Throws `DeviceCommandError` with a sentence for anything undeclared or ill-typed.
|
|
4197
|
+
|
|
4198
|
+
```ts
|
|
4199
|
+
function renderCommand(block: DeviceBlock, name: string, params: Record<string, unknown> = {}): RenderedCommand
|
|
4200
|
+
```
|
|
4201
|
+
|
|
4202
|
+
#### `resolveInScope` — function · src/machine/files.ts
|
|
4203
|
+
|
|
4204
|
+
A path as the agent wrote it → an absolute path the scope allows. `cwd` is the agent's current directory (absolute, inside the scope). `~` means the home directory, and is allowed only when the scope contains it.
|
|
4205
|
+
|
|
4206
|
+
```ts
|
|
4207
|
+
function resolveInScope(scope: Scope, cwd: string, p: string): string
|
|
4208
|
+
```
|
|
4209
|
+
|
|
4210
|
+
#### `resolveOutput` — function · src/machine/commands.ts
|
|
4211
|
+
|
|
4212
|
+
The spec's output choice with its defaults filled in — what the runtime and the door both use.
|
|
4213
|
+
|
|
4214
|
+
```ts
|
|
4215
|
+
function resolveOutput(spec: OutputSpec | undefined): ResolvedOutput
|
|
4216
|
+
```
|
|
4217
|
+
|
|
4218
|
+
#### `RUNTIME_CAPABILITIES` — const · src/machine/capabilities.ts
|
|
4219
|
+
|
|
4220
|
+
What this runtime can do, said at CONNECT as well as in every hello, so the platform knows it from the approval on: work asked for before the runtime's first hello waits in the queue instead of being refused.
|
|
4221
|
+
|
|
4222
|
+
```ts
|
|
4223
|
+
const RUNTIME_CAPABILITIES: string[]
|
|
4224
|
+
```
|
|
4225
|
+
|
|
4226
|
+
#### `sandboxFor` — function · src/machine/shell.ts
|
|
4227
|
+
|
|
4228
|
+
How `run` and `term` are confined. The computer scope runs processes as they are. A folder scope needs an OS sandbox — bubblewrap on Linux, Seatbelt on macOS — or processes are REFUSED (a path check cannot keep a shell in a folder; `cd ..` would do).
|
|
4229
|
+
|
|
4230
|
+
```ts
|
|
4231
|
+
function sandboxFor(scope: Scope): Sandbox
|
|
4232
|
+
```
|
|
4233
|
+
|
|
4234
|
+
#### `sha256Hex` — function · src/machine/protocol.ts
|
|
4235
|
+
|
|
4236
|
+
Hex SHA-256 of a request body, as signed.
|
|
4237
|
+
|
|
4238
|
+
```ts
|
|
4239
|
+
function sha256Hex(body: string | Uint8Array): string
|
|
4240
|
+
```
|
|
4241
|
+
|
|
4242
|
+
#### `signRequest` — function · src/machine/protocol.ts
|
|
4243
|
+
|
|
4244
|
+
Sign one request (method, path with query, body) now; returns the `x-esoul-ts` and `x-esoul-sig` header values.
|
|
4245
|
+
|
|
4246
|
+
```ts
|
|
4247
|
+
function signRequest( privateKeyPem: string, method: string, pathAndQuery: string, body: string | Uint8Array, now: number = Date.now(), ): { ts: string; sig: string }
|
|
4248
|
+
```
|
|
4249
|
+
|
|
4250
|
+
#### `startSupervisor` — function · src/machine/supervisor.ts
|
|
4251
|
+
|
|
4252
|
+
The runtime: one per computer, for every connected app — hello, wake, claim, re-render and run, report, and the app's lifecycle.
|
|
4253
|
+
|
|
4254
|
+
```ts
|
|
4255
|
+
function startSupervisor(opts: SupervisorOptions)
|
|
4256
|
+
```
|
|
4257
|
+
|
|
4258
|
+
#### `tokenize` — function · src/machine/shell.ts
|
|
4259
|
+
|
|
4260
|
+
Shell-like words: quotes ('…' literal, "…" with \" escapes), backslash escapes, whitespace separation.
|
|
4261
|
+
|
|
4262
|
+
```ts
|
|
4263
|
+
function tokenize(line: string): string[]
|
|
4264
|
+
```
|
|
4265
|
+
|
|
4266
|
+
#### `verifyRequest` — function · src/machine/protocol.ts
|
|
4267
|
+
|
|
4268
|
+
Pure verification. `publicKey` comes from the platform's row for `x-esoul-key`, never from the request.
|
|
4269
|
+
|
|
4270
|
+
```ts
|
|
4271
|
+
function verifyRequest(args: { publicKey: string; method: string; pathAndQuery: string; body: string | Uint8Array; ts: string | null | undefined; sig: string | null | undefined; now?: number; }): { ok: true } | { ok: false; reason: VerifyFailure }
|
|
4272
|
+
```
|
|
4273
|
+
|
|
4274
|
+
#### `workspaceCapability` — function · src/machine/capabilities.ts
|
|
4275
|
+
|
|
4276
|
+
The shared command line, under grant ∩ ceiling, one working directory per named agent.
|
|
4277
|
+
|
|
4278
|
+
```ts
|
|
4279
|
+
function workspaceCapability(): Capability
|
|
4280
|
+
```
|
|
4281
|
+
|
|
4282
|
+
### Types (40)
|
|
4283
|
+
|
|
4284
|
+
#### `CallTiming` — interface · src/machine/client.ts
|
|
4285
|
+
|
|
4286
|
+
```ts
|
|
4287
|
+
interface CallTiming {
|
|
4288
|
+
method: string;
|
|
4289
|
+
path: string;
|
|
4290
|
+
status: number;
|
|
4291
|
+
ms: number;
|
|
4292
|
+
server: string | null;
|
|
4293
|
+
}
|
|
4294
|
+
```
|
|
4295
|
+
|
|
4296
|
+
#### `Capability` — interface · src/machine/capabilities.ts
|
|
4297
|
+
|
|
4298
|
+
```ts
|
|
4299
|
+
interface Capability {
|
|
4300
|
+
name: string;
|
|
4301
|
+
version: number;
|
|
4302
|
+
refuse(job: Job, ctx: JobContext): string | null;
|
|
4303
|
+
start(job: Job, ctx: JobContext): Promise<void>;
|
|
4304
|
+
}
|
|
4305
|
+
```
|
|
4306
|
+
|
|
4307
|
+
#### `CommandSpec` — interface · src/machine/commands.ts
|
|
4308
|
+
|
|
4309
|
+
```ts
|
|
4310
|
+
interface CommandSpec {
|
|
4311
|
+
argv: string[];
|
|
4312
|
+
params?: Record<string, ParamSpec>;
|
|
4313
|
+
cwd?: string;
|
|
4314
|
+
env?: Record<string, string>;
|
|
4315
|
+
config?: string[];
|
|
4316
|
+
timeoutSeconds?: number;
|
|
4317
|
+
onRestart?: "report" | "rerun";
|
|
4318
|
+
output?: OutputSpec;
|
|
4319
|
+
result?: "text" | "json";
|
|
4320
|
+
describe?: string;
|
|
4321
|
+
}
|
|
4322
|
+
```
|
|
4323
|
+
|
|
4324
|
+
#### `ConfigKeySpec` — interface · src/machine/commands.ts
|
|
4325
|
+
|
|
4326
|
+
```ts
|
|
4327
|
+
interface ConfigKeySpec {
|
|
4328
|
+
secret?: boolean;
|
|
4329
|
+
required?: boolean;
|
|
4330
|
+
describe?: string;
|
|
4331
|
+
}
|
|
4332
|
+
```
|
|
4333
|
+
|
|
4334
|
+
#### `ConnectOptions` — interface · src/machine/supervisor.ts
|
|
4335
|
+
|
|
4336
|
+
```ts
|
|
4337
|
+
interface ConnectOptions {
|
|
4338
|
+
url: string;
|
|
4339
|
+
home?: string;
|
|
4340
|
+
runtimeVersion: string;
|
|
4341
|
+
fetch?: FetchLike;
|
|
4342
|
+
pollMs?: number;
|
|
4343
|
+
print?: (line: string) => void;
|
|
4344
|
+
fingerprint?: string;
|
|
4345
|
+
ceiling?: WorkspaceGrant | null;
|
|
4346
|
+
}
|
|
4347
|
+
```
|
|
4348
|
+
|
|
4349
|
+
#### `ConnectResult` — interface · src/machine/supervisor.ts
|
|
4350
|
+
|
|
4351
|
+
```ts
|
|
4352
|
+
interface ConnectResult {
|
|
4353
|
+
machineId: string;
|
|
4354
|
+
linkId: string | null;
|
|
4355
|
+
base: string;
|
|
4356
|
+
appName: string | null;
|
|
4357
|
+
}
|
|
4358
|
+
```
|
|
4359
|
+
|
|
4360
|
+
#### `DeviceBlock` — interface · src/machine/commands.ts
|
|
4361
|
+
|
|
4362
|
+
```ts
|
|
4363
|
+
interface DeviceBlock {
|
|
4364
|
+
commands: Record<string, CommandSpec>;
|
|
4365
|
+
program?: ProgramSpec;
|
|
4366
|
+
config?: Record<string, ConfigKeySpec>;
|
|
4367
|
+
redact?: string[];
|
|
4368
|
+
onAppDeleted?: "kill" | "finish";
|
|
4369
|
+
}
|
|
4370
|
+
```
|
|
4371
|
+
|
|
4372
|
+
#### `DeviceKeyPair` — interface · src/machine/protocol.ts
|
|
4373
|
+
|
|
4374
|
+
```ts
|
|
4375
|
+
interface DeviceKeyPair {
|
|
4376
|
+
publicKey: string;
|
|
4377
|
+
privateKeyPem: string;
|
|
4378
|
+
}
|
|
4379
|
+
```
|
|
4380
|
+
|
|
4381
|
+
#### `DoorClient` — interface · src/machine/client.ts
|
|
4382
|
+
|
|
4383
|
+
```ts
|
|
4384
|
+
interface DoorClient {
|
|
4385
|
+
call<T = Record<string, unknown>>(method: "GET" | "POST", path: string, body?: unknown, opts?: { timeoutMs?: number; tries?: number }): Promise<T>;
|
|
4386
|
+
base: string;
|
|
4387
|
+
}
|
|
4388
|
+
```
|
|
4389
|
+
|
|
4390
|
+
#### `Edit` — interface · src/machine/files.ts
|
|
4391
|
+
|
|
4392
|
+
```ts
|
|
4393
|
+
interface Edit {
|
|
4394
|
+
find: string;
|
|
4395
|
+
replace: string;
|
|
4396
|
+
all?: boolean;
|
|
4397
|
+
}
|
|
4398
|
+
```
|
|
4399
|
+
|
|
4400
|
+
#### `FetchLike` — type · src/machine/client.ts
|
|
4401
|
+
|
|
4402
|
+
```ts
|
|
4403
|
+
type FetchLike = (input: string, init: { method: string; headers: Record<string, string>; body?: string; signal?: AbortSignal }) => Promise<{ status: number; text(): Promise<string>; headers?: { get(name: string): string | null } }>;
|
|
4404
|
+
```
|
|
4405
|
+
|
|
4406
|
+
#### `HunkResult` — interface · src/machine/files.ts
|
|
4407
|
+
|
|
4408
|
+
```ts
|
|
4409
|
+
interface HunkResult {
|
|
4410
|
+
hunk: number;
|
|
4411
|
+
applied: boolean;
|
|
4412
|
+
at?: number;
|
|
4413
|
+
offset?: number;
|
|
4414
|
+
reason?: string;
|
|
4415
|
+
}
|
|
4416
|
+
```
|
|
4417
|
+
|
|
4418
|
+
#### `Job` — interface · src/machine/capabilities.ts
|
|
4419
|
+
|
|
4420
|
+
```ts
|
|
4421
|
+
interface Job extends ClaimedCommand {
|
|
4422
|
+
capability: string;
|
|
4423
|
+
agent: string | null;
|
|
4424
|
+
}
|
|
4425
|
+
```
|
|
4426
|
+
|
|
4427
|
+
#### `JobContext` — interface · src/machine/capabilities.ts
|
|
4428
|
+
|
|
4429
|
+
```ts
|
|
4430
|
+
interface JobContext {
|
|
4431
|
+
home: string;
|
|
4432
|
+
link: LocalLink;
|
|
4433
|
+
ceiling: WorkspaceGrant | null;
|
|
4434
|
+
client: DoorClient;
|
|
4435
|
+
signal: AbortSignal;
|
|
4436
|
+
log: (s: string) => void;
|
|
4437
|
+
}
|
|
4438
|
+
```
|
|
4439
|
+
|
|
4440
|
+
#### `JobOutcome` — interface · src/machine/capabilities.ts
|
|
4441
|
+
|
|
4442
|
+
```ts
|
|
4443
|
+
interface JobOutcome {
|
|
4444
|
+
exitCode: number | null;
|
|
4445
|
+
reason?: string | null;
|
|
4446
|
+
signal?: string | null;
|
|
4447
|
+
result?: unknown;
|
|
4448
|
+
}
|
|
4449
|
+
```
|
|
4450
|
+
|
|
4451
|
+
#### `JournalEntry` — interface · src/machine/files.ts
|
|
4452
|
+
|
|
4453
|
+
```ts
|
|
4454
|
+
interface JournalEntry {
|
|
4455
|
+
opId: string;
|
|
4456
|
+
at: number;
|
|
4457
|
+
agent: string;
|
|
4458
|
+
op: "write" | "edit" | "patch" | "rm" | "mv" | "mkdir" | "undo";
|
|
4459
|
+
path: string;
|
|
4460
|
+
to?: string;
|
|
4461
|
+
before: string | null;
|
|
4462
|
+
after: string | null;
|
|
4463
|
+
dirSnapshot?: string;
|
|
4464
|
+
}
|
|
4465
|
+
```
|
|
4466
|
+
|
|
4467
|
+
#### `LocalLink` — interface · src/machine/state.ts
|
|
4468
|
+
|
|
4469
|
+
```ts
|
|
4470
|
+
interface LocalLink {
|
|
4471
|
+
linkId: string;
|
|
4472
|
+
nodeId: string;
|
|
4473
|
+
workspaceId: string;
|
|
4474
|
+
pluginId: string;
|
|
4475
|
+
appName: string | null;
|
|
4476
|
+
status: "active" | "suspended" | "revoked";
|
|
4477
|
+
reason: string | null;
|
|
4478
|
+
commands: DeviceBlock | null;
|
|
4479
|
+
grants?: Record<string, unknown> | null;
|
|
4480
|
+
}
|
|
4481
|
+
```
|
|
4482
|
+
|
|
4483
|
+
#### `LocalState` — interface · src/machine/state.ts
|
|
4484
|
+
|
|
4485
|
+
```ts
|
|
4486
|
+
interface LocalState {
|
|
4487
|
+
base: string;
|
|
4488
|
+
machineId: string;
|
|
4489
|
+
links: Record<string, LocalLink>;
|
|
4490
|
+
ceiling?: { scope: "folder"; root: string } | { scope: "computer" } | null;
|
|
4491
|
+
}
|
|
4492
|
+
```
|
|
4493
|
+
|
|
4494
|
+
#### `MachineShellResult` — interface · src/machine/shell.ts
|
|
4495
|
+
|
|
4496
|
+
```ts
|
|
4497
|
+
interface ShellResult {
|
|
4498
|
+
ok: boolean;
|
|
4499
|
+
text: string;
|
|
4500
|
+
data?: unknown;
|
|
4501
|
+
exitCode?: number | null;
|
|
4502
|
+
error?: string;
|
|
4503
|
+
opId?: string;
|
|
4504
|
+
cwd: string;
|
|
4505
|
+
}
|
|
4506
|
+
```
|
|
4507
|
+
|
|
4508
|
+
#### `OutputSpec` — interface · src/machine/commands.ts
|
|
4509
|
+
|
|
4510
|
+
The delivery tradeoff, chosen per command (esoul-sdk docs/18 §4):
|
|
4511
|
+
|
|
4512
|
+
```ts
|
|
4513
|
+
interface OutputSpec {
|
|
4514
|
+
mode?: "live" | "batched" | "final";
|
|
4515
|
+
flushMs?: number;
|
|
4516
|
+
maxChunkKb?: number;
|
|
4517
|
+
keep?: "head" | "tail" | "both";
|
|
4518
|
+
maxKb?: number;
|
|
4519
|
+
}
|
|
4520
|
+
```
|
|
4521
|
+
|
|
4522
|
+
#### `ParamSpec` — type · src/machine/commands.ts
|
|
4523
|
+
|
|
4524
|
+
DECLARED COMMANDS — the wall between an app and the person's computer.
|
|
4525
|
+
|
|
4526
|
+
```ts
|
|
4527
|
+
type ParamSpec =
|
|
4528
|
+
| "int"
|
|
4529
|
+
| "number"
|
|
4530
|
+
| "bool"
|
|
4531
|
+
| "string"
|
|
4532
|
+
| { type: "int" | "number"; min?: number; max?: number; describe?: string }
|
|
4533
|
+
| { type: "string"; pattern?: string; maxLength?: number; allowDash?: boolean; describe?: string }
|
|
4534
|
+
| { type: "enum"; values: string[]; describe?: string }
|
|
4535
|
+
| { type: "bool"; describe?: string };
|
|
4536
|
+
```
|
|
4537
|
+
|
|
4538
|
+
#### `Program` — interface · src/machine/program-api.ts
|
|
4539
|
+
|
|
4540
|
+
An app's program: `start` is called once per process; `stop` before the process ends, when it ends cleanly.
|
|
4541
|
+
|
|
4542
|
+
```ts
|
|
4543
|
+
interface Program {
|
|
4544
|
+
start(p: ProgramApi): void | Promise<void>;
|
|
4545
|
+
stop?(): void | Promise<void>;
|
|
4546
|
+
}
|
|
4547
|
+
```
|
|
4548
|
+
|
|
4549
|
+
#### `ProgramApi` — interface · src/machine/program-api.ts
|
|
4550
|
+
|
|
4551
|
+
The program's handle on the computer and on its app.
|
|
4552
|
+
|
|
4553
|
+
```ts
|
|
4554
|
+
interface ProgramApi {
|
|
4555
|
+
readonly computer: { readonly hostname: string; readonly platform: string; readonly arch: string; readonly cpus: number; readonly memoryGb: number };
|
|
4556
|
+
readonly appName: string | null;
|
|
4557
|
+
readonly programDir: string;
|
|
4558
|
+
readonly dataDir: string;
|
|
4559
|
+
readonly workspaceRoot: string | null;
|
|
4560
|
+
readonly config: Readonly<Record<string, string>>;
|
|
4561
|
+
status(text: string, extra?: { progress?: number; ready?: boolean }): void;
|
|
4562
|
+
op<T = unknown>(name: string, args?: unknown, opts?: { key?: string }): Promise<T>;
|
|
4563
|
+
on(topic: string, handler: (data: unknown) => unknown | Promise<unknown>): void;
|
|
4564
|
+
every(ms: number, fn: () => unknown | Promise<unknown>): () => void;
|
|
4565
|
+
log(...args: unknown[]): void;
|
|
4566
|
+
}
|
|
4567
|
+
```
|
|
4568
|
+
|
|
4569
|
+
#### `ProgramDelivery` — interface · src/machine/capabilities.ts
|
|
4570
|
+
|
|
4571
|
+
The part of the program manager a message job needs (program-manager.ts).
|
|
4572
|
+
|
|
4573
|
+
```ts
|
|
4574
|
+
interface ProgramDelivery {
|
|
4575
|
+
has(linkId: string): boolean;
|
|
4576
|
+
deliver(linkId: string, topic: string, data: unknown, signal?: AbortSignal): Promise<{ ok: boolean; result?: unknown; error?: string }>;
|
|
4577
|
+
}
|
|
4578
|
+
```
|
|
4579
|
+
|
|
4580
|
+
#### `ProgramManager` — type · src/machine/program-manager.ts
|
|
4581
|
+
|
|
4582
|
+
The program manager's handle (see createProgramManager).
|
|
4583
|
+
|
|
4584
|
+
```ts
|
|
4585
|
+
type ProgramManager = ReturnType<typeof createProgramManager>;
|
|
4586
|
+
```
|
|
4587
|
+
|
|
4588
|
+
#### `ProgramManagerOptions` — interface · src/machine/program-manager.ts
|
|
4589
|
+
|
|
4590
|
+
What the program manager needs from the runtime.
|
|
4591
|
+
|
|
4592
|
+
```ts
|
|
4593
|
+
interface ProgramManagerOptions {
|
|
4594
|
+
home: string;
|
|
4595
|
+
client: DoorClient;
|
|
4596
|
+
hostScript: string;
|
|
4597
|
+
nodePath?: string;
|
|
4598
|
+
log: (line: string) => void;
|
|
4599
|
+
ceiling: () => WorkspaceGrant | null;
|
|
4600
|
+
sandbox?: Sandbox;
|
|
4601
|
+
}
|
|
4602
|
+
```
|
|
4603
|
+
|
|
4604
|
+
#### `ProgramSpec` — interface · src/machine/commands.ts
|
|
4605
|
+
|
|
4606
|
+
The app's own program on the computer (`computer-apps.md` §4.1): the files of `device/` shipped per app version, set up once, then started — at approval when `resident`, or when the app first sends it a message.
|
|
4607
|
+
|
|
4608
|
+
```ts
|
|
4609
|
+
interface ProgramSpec {
|
|
4610
|
+
main: string;
|
|
4611
|
+
resident?: boolean;
|
|
4612
|
+
setup?: SetupStepSpec[];
|
|
4613
|
+
selfTest?: { run: string[]; timeoutSeconds?: number };
|
|
4614
|
+
digest?: string;
|
|
4615
|
+
size?: number;
|
|
4616
|
+
}
|
|
4617
|
+
```
|
|
4618
|
+
|
|
4619
|
+
#### `ProgramState` — interface · src/machine/program-api.ts
|
|
4620
|
+
|
|
4621
|
+
Where an app's program stands on one computer — what the runtime reports and the app's Computers card renders. `phase` moves forward installing → setup → self-test → running (or ready, for a program started by its first message); `failed` and `refused` say why in `error`.
|
|
4622
|
+
|
|
4623
|
+
```ts
|
|
4624
|
+
interface ProgramState {
|
|
4625
|
+
digest: string;
|
|
4626
|
+
phase: "installing" | "setup" | "self-test" | "ready" | "starting" | "running" | "stopped" | "failed" | "refused";
|
|
4627
|
+
steps: ProgramStepState[];
|
|
4628
|
+
status?: { text: string; progress?: number; ready?: boolean; at: number } | null;
|
|
4629
|
+
error?: string | null;
|
|
4630
|
+
logTail?: string[];
|
|
4631
|
+
restarts: number;
|
|
4632
|
+
updatedAt: number;
|
|
4633
|
+
}
|
|
4634
|
+
```
|
|
4635
|
+
|
|
4636
|
+
#### `ProgramStepState` — interface · src/machine/program-api.ts
|
|
4637
|
+
|
|
4638
|
+
One setup step, as the Computers card shows it.
|
|
4639
|
+
|
|
4640
|
+
```ts
|
|
4641
|
+
interface ProgramStepState {
|
|
4642
|
+
id: string;
|
|
4643
|
+
describe: string;
|
|
4644
|
+
state: "pending" | "running" | "done" | "cached" | "failed";
|
|
4645
|
+
startedAt?: number;
|
|
4646
|
+
endedAt?: number;
|
|
4647
|
+
detail?: string;
|
|
4648
|
+
}
|
|
4649
|
+
```
|
|
4650
|
+
|
|
4651
|
+
#### `RenderedCommand` — interface · src/machine/commands.ts
|
|
4652
|
+
|
|
4653
|
+
```ts
|
|
4654
|
+
interface RenderedCommand {
|
|
4655
|
+
name: string;
|
|
4656
|
+
argv: string[];
|
|
4657
|
+
cwd?: string;
|
|
4658
|
+
env: Record<string, string>;
|
|
4659
|
+
config: string[];
|
|
4660
|
+
timeoutSeconds: number;
|
|
4661
|
+
onRestart: "report" | "rerun";
|
|
4662
|
+
}
|
|
4663
|
+
```
|
|
4664
|
+
|
|
4665
|
+
#### `ResolvedOutput` — interface · src/machine/commands.ts
|
|
4666
|
+
|
|
4667
|
+
```ts
|
|
4668
|
+
interface ResolvedOutput {
|
|
4669
|
+
mode: "live" | "batched" | "final";
|
|
4670
|
+
flushMs: number;
|
|
4671
|
+
maxChunkBytes: number;
|
|
4672
|
+
headMaxBytes: number;
|
|
4673
|
+
tailMaxChars: number;
|
|
4674
|
+
}
|
|
4675
|
+
```
|
|
4676
|
+
|
|
4677
|
+
#### `Sandbox` — type · src/machine/shell.ts
|
|
4678
|
+
|
|
4679
|
+
```ts
|
|
4680
|
+
type Sandbox = { kind: "none" } | { kind: "bwrap"; bin: string } | { kind: "seatbelt" } | { kind: "unavailable"; why: string };
|
|
4681
|
+
```
|
|
4682
|
+
|
|
4683
|
+
#### `Scope` — type · src/machine/files.ts
|
|
4684
|
+
|
|
4685
|
+
```ts
|
|
4686
|
+
type Scope = { kind: "folder"; root: string } | { kind: "computer" };
|
|
4687
|
+
```
|
|
4688
|
+
|
|
4689
|
+
#### `SetupStepSpec` — interface · src/machine/commands.ts
|
|
4690
|
+
|
|
4691
|
+
One setup step of a program: argv (never a shell line), run once per program digest and declared inputs.
|
|
4692
|
+
|
|
4693
|
+
```ts
|
|
4694
|
+
interface SetupStepSpec {
|
|
4695
|
+
id: string;
|
|
4696
|
+
describe: string;
|
|
4697
|
+
run: string[];
|
|
4698
|
+
inputs?: string[];
|
|
4699
|
+
timeoutSeconds?: number;
|
|
4700
|
+
}
|
|
4701
|
+
```
|
|
4702
|
+
|
|
4703
|
+
#### `ShellCall` — interface · src/machine/shell.ts
|
|
4704
|
+
|
|
4705
|
+
```ts
|
|
4706
|
+
interface ShellCall {
|
|
4707
|
+
ws: Workspace;
|
|
4708
|
+
agent: string;
|
|
4709
|
+
line: string;
|
|
4710
|
+
stdin?: string;
|
|
4711
|
+
onOutput?: (chunk: string) => void;
|
|
4712
|
+
signal?: AbortSignal;
|
|
4713
|
+
}
|
|
4714
|
+
```
|
|
4715
|
+
|
|
4716
|
+
#### `SupervisorOptions` — interface · src/machine/supervisor.ts
|
|
4717
|
+
|
|
4718
|
+
```ts
|
|
4719
|
+
interface SupervisorOptions {
|
|
4720
|
+
home?: string;
|
|
4721
|
+
runtimeVersion: string;
|
|
4722
|
+
execScript: string;
|
|
4723
|
+
nodePath?: string;
|
|
4724
|
+
fetch?: FetchLike;
|
|
4725
|
+
wake?: boolean;
|
|
4726
|
+
pollSeconds?: number;
|
|
4727
|
+
flushMs?: number;
|
|
4728
|
+
helloEveryMs?: number;
|
|
4729
|
+
log?: (line: string) => void;
|
|
4730
|
+
onEmpty?: (why: string) => void | Promise<void>;
|
|
4731
|
+
}
|
|
4732
|
+
```
|
|
4733
|
+
|
|
4734
|
+
#### `VerifyFailure` — type · src/machine/protocol.ts
|
|
4735
|
+
|
|
4736
|
+
```ts
|
|
4737
|
+
type VerifyFailure = "missing" | "bad_key" | "skew" | "bad_signature";
|
|
4738
|
+
```
|
|
4739
|
+
|
|
4740
|
+
#### `Workspace` — interface · src/machine/shell.ts
|
|
4741
|
+
|
|
4742
|
+
```ts
|
|
4743
|
+
interface Workspace {
|
|
4744
|
+
id: string;
|
|
4745
|
+
scope: Scope;
|
|
4746
|
+
journal: Journal;
|
|
4747
|
+
stateDir: string;
|
|
4748
|
+
sandbox: Sandbox;
|
|
4749
|
+
}
|
|
4750
|
+
```
|
|
4751
|
+
|
|
4752
|
+
#### `WorkspaceChoice` — type · src/machine/grant.ts
|
|
4753
|
+
|
|
4754
|
+
```ts
|
|
4755
|
+
type WorkspaceChoice = "none" | "folder" | "computer";
|
|
4756
|
+
```
|
|
4757
|
+
|
|
4758
|
+
#### `WorkspaceGrant` — type · src/machine/grant.ts
|
|
4759
|
+
|
|
4760
|
+
WORKSPACE GRANTS (plugin-device-arm.md §15): what an app's agents may reach on a computer through the shared command line — one FOLDER, or the whole COMPUTER. Two parties must agree:
|
|
4761
|
+
|
|
4762
|
+
```ts
|
|
4763
|
+
type WorkspaceGrant = { scope: "folder"; root: string } | { scope: "computer" };
|
|
4764
|
+
```
|