esoul-sdk 0.16.0 → 0.18.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 +1227 -10
- package/bin/esoul-device-exec.mjs +99 -0
- package/dist/db/client-core.d.ts +10 -0
- package/dist/db/client-core.js +17 -0
- package/dist/db/compile-rules.d.ts +31 -0
- package/dist/db/compile-rules.js +67 -0
- package/dist/db/memory-client.d.ts +2 -0
- package/dist/db/memory-client.js +8 -6
- package/dist/db/schema-gen.d.ts +13 -3
- package/dist/db/schema-gen.js +59 -13
- package/dist/device.d.ts +136 -0
- package/dist/device.js +15 -0
- package/dist/failed-requests.d.ts +77 -0
- package/dist/failed-requests.js +127 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/machine/capabilities.d.ts +81 -0
- package/dist/machine/capabilities.js +211 -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 +136 -0
- package/dist/machine/commands.js +229 -0
- package/dist/machine/digest.d.ts +14 -0
- package/dist/machine/digest.js +42 -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 +19 -0
- package/dist/machine/index.js +19 -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 +30 -0
- package/dist/machine/service.js +189 -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 +54 -0
- package/dist/machine/supervisor.js +259 -0
- package/dist/machine/wake.d.ts +31 -0
- package/dist/machine/wake.js +105 -0
- package/dist/manifest.d.ts +444 -0
- package/dist/manifest.js +51 -0
- package/dist/react.d.ts +110 -0
- package/dist/react.js +42 -0
- package/dist/server.d.ts +28 -0
- package/dist/server.js +20 -0
- package/docs/03-events-and-state.md +9 -4
- package/docs/05-ui.md +65 -0
- package/docs/14-database.md +21 -3
- package/docs/18-your-computer.md +235 -0
- package/llms-full.txt +333 -6
- package/llms.txt +1 -0
- package/package.json +10 -4
- package/schemas/plugin.schema.json +242 -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.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"; }>>; 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, { 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"; }>; config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; redact?: string[]; onAppDeleted?: "kill" | "finish"; }, { 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"; }>; config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; redact?: string[]; onAppDeleted?: "kill" | "finish"; }>, { 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"; }>; config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; redact?: string[]; onAppDeleted?: "kill" | "finish"; }, { 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"; }>; config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; 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?: { 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"; }>; config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; 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?: { 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"; }>; config?: Record<string, { required?: boolean; describe?: string; secret?: boolean; }>; 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,17 @@ 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
|
+
config?: Record<string, ConfigKeySpec>;
|
|
1405
|
+
redact?: string[];
|
|
1406
|
+
onAppDeleted?: "kill" | "finish";
|
|
1407
|
+
}
|
|
1408
|
+
```
|
|
1409
|
+
|
|
1324
1410
|
#### `EventData` — interface · src/types.ts
|
|
1325
1411
|
|
|
1326
1412
|
```ts
|
|
@@ -1635,6 +1721,22 @@ interface OpToolConfig<S extends OpInput, R> {
|
|
|
1635
1721
|
}
|
|
1636
1722
|
```
|
|
1637
1723
|
|
|
1724
|
+
#### `ParamSpec` — type · src/machine/commands.ts
|
|
1725
|
+
|
|
1726
|
+
DECLARED COMMANDS — the wall between an app and the person's computer.
|
|
1727
|
+
|
|
1728
|
+
```ts
|
|
1729
|
+
type ParamSpec =
|
|
1730
|
+
| "int"
|
|
1731
|
+
| "number"
|
|
1732
|
+
| "bool"
|
|
1733
|
+
| "string"
|
|
1734
|
+
| { type: "int" | "number"; min?: number; max?: number; describe?: string }
|
|
1735
|
+
| { type: "string"; pattern?: string; maxLength?: number; allowDash?: boolean; describe?: string }
|
|
1736
|
+
| { type: "enum"; values: string[]; describe?: string }
|
|
1737
|
+
| { type: "bool"; describe?: string };
|
|
1738
|
+
```
|
|
1739
|
+
|
|
1638
1740
|
#### `ParsedSourceId` — type · src/files.ts
|
|
1639
1741
|
|
|
1640
1742
|
```ts
|
|
@@ -1733,6 +1835,20 @@ type ReconcileDecision =
|
|
|
1733
1835
|
| { kind: "adopt" };
|
|
1734
1836
|
```
|
|
1735
1837
|
|
|
1838
|
+
#### `RenderedCommand` — interface · src/machine/commands.ts
|
|
1839
|
+
|
|
1840
|
+
```ts
|
|
1841
|
+
interface RenderedCommand {
|
|
1842
|
+
name: string;
|
|
1843
|
+
argv: string[];
|
|
1844
|
+
cwd?: string;
|
|
1845
|
+
env: Record<string, string>;
|
|
1846
|
+
config: string[];
|
|
1847
|
+
timeoutSeconds: number;
|
|
1848
|
+
onRestart: "report" | "rerun";
|
|
1849
|
+
}
|
|
1850
|
+
```
|
|
1851
|
+
|
|
1736
1852
|
#### `RequiredStateShape` — interface · src/helpers.ts
|
|
1737
1853
|
|
|
1738
1854
|
Fields whose ABSENCE means "did not load" (they are seeded at genesis).
|
|
@@ -1810,11 +1926,11 @@ interface UsesDecl {
|
|
|
1810
1926
|
```
|
|
1811
1927
|
|
|
1812
1928
|
==============================================================================
|
|
1813
|
-
## `esoul-sdk/server` —
|
|
1929
|
+
## `esoul-sdk/server` — 77 exports
|
|
1814
1930
|
|
|
1815
1931
|
Server code only (server.ts, ops, routes, tasks): the viewer, the app's database, files, connections, machines, charts, route tokens.
|
|
1816
1932
|
|
|
1817
|
-
### Functions and values (
|
|
1933
|
+
### Functions and values (29)
|
|
1818
1934
|
|
|
1819
1935
|
#### `APPROVAL_WAIT` — const · src/computer.ts
|
|
1820
1936
|
|
|
@@ -1848,6 +1964,22 @@ COMPOSE A ROLE, as the owner: a name of its own, a base word from the vocabulary
|
|
|
1848
1964
|
function defineAppRole( _ctx: { pluginId: string; workspaceId: string; nodeId: string; viewer: PluginViewer }, _definition: CustomRoleDefinitionRaw, ): Promise<{ ok: boolean; name?: string; error?: string }>
|
|
1849
1965
|
```
|
|
1850
1966
|
|
|
1967
|
+
#### `DEVICE_RUN_TERMINAL` — const · src/device.ts
|
|
1968
|
+
|
|
1969
|
+
The statuses a run ends in: done, expired, cancelled, lost.
|
|
1970
|
+
|
|
1971
|
+
```ts
|
|
1972
|
+
const DEVICE_RUN_TERMINAL: readonly DeviceRunStatus[]
|
|
1973
|
+
```
|
|
1974
|
+
|
|
1975
|
+
#### `devices` — function · src/server.ts
|
|
1976
|
+
|
|
1977
|
+
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:
|
|
1978
|
+
|
|
1979
|
+
```ts
|
|
1980
|
+
function devices(_ctx: { pluginId: string; nodeId: string; viewer?: { canWrite: boolean; kind: string; userId: string | null } }): Devices
|
|
1981
|
+
```
|
|
1982
|
+
|
|
1851
1983
|
#### `emitPluginAppEvent` — function · src/server.ts
|
|
1852
1984
|
|
|
1853
1985
|
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 +2164,7 @@ WHO IS THIS, IN WORDS. The caller's own name and email, for an app with a reason
|
|
|
2032
2164
|
function viewerProfile(_viewer: PluginViewer): Promise<ViewerProfile | null>
|
|
2033
2165
|
```
|
|
2034
2166
|
|
|
2035
|
-
### Types (
|
|
2167
|
+
### Types (48)
|
|
2036
2168
|
|
|
2037
2169
|
#### `AppRolePerson` — interface · src/server.ts
|
|
2038
2170
|
|
|
@@ -2263,6 +2395,94 @@ interface CustomRolesEnvelope {
|
|
|
2263
2395
|
}
|
|
2264
2396
|
```
|
|
2265
2397
|
|
|
2398
|
+
#### `DeviceRunOptions` — interface · src/device.ts
|
|
2399
|
+
|
|
2400
|
+
```ts
|
|
2401
|
+
interface DeviceRunOptions {
|
|
2402
|
+
linkId?: string;
|
|
2403
|
+
expiresInSeconds?: number;
|
|
2404
|
+
}
|
|
2405
|
+
```
|
|
2406
|
+
|
|
2407
|
+
#### `DeviceRunStarted` — interface · src/device.ts
|
|
2408
|
+
|
|
2409
|
+
```ts
|
|
2410
|
+
interface DeviceRunStarted {
|
|
2411
|
+
commandId: string;
|
|
2412
|
+
status: DeviceRunStatus;
|
|
2413
|
+
machineOnline: boolean;
|
|
2414
|
+
expiresAt: number;
|
|
2415
|
+
}
|
|
2416
|
+
```
|
|
2417
|
+
|
|
2418
|
+
#### `DeviceRunStatus` — type · src/device.ts
|
|
2419
|
+
|
|
2420
|
+
Types for `devices(ctx)` — parts of an app that run on the person's own computer (plugin-device-arm.md §10–§11). The functions live in server.ts (host-only); the hooks and <ConnectComputer/> in react.ts.
|
|
2421
|
+
|
|
2422
|
+
```ts
|
|
2423
|
+
type DeviceRunStatus = "queued" | "claimed" | "running" | "done" | "expired" | "cancelled" | "lost";
|
|
2424
|
+
```
|
|
2425
|
+
|
|
2426
|
+
#### `DeviceRunView` — interface · src/device.ts
|
|
2427
|
+
|
|
2428
|
+
```ts
|
|
2429
|
+
interface DeviceRunView {
|
|
2430
|
+
commandId: string;
|
|
2431
|
+
linkId: string;
|
|
2432
|
+
machineId: string;
|
|
2433
|
+
capability?: string;
|
|
2434
|
+
agent?: string | null;
|
|
2435
|
+
name: string;
|
|
2436
|
+
params: Record<string, unknown>;
|
|
2437
|
+
argv: string[];
|
|
2438
|
+
status: DeviceRunStatus;
|
|
2439
|
+
exitCode: number | null;
|
|
2440
|
+
signal: string | null;
|
|
2441
|
+
reason: string | null;
|
|
2442
|
+
output?: string;
|
|
2443
|
+
tail?: string;
|
|
2444
|
+
result?: unknown;
|
|
2445
|
+
resultError?: string | null;
|
|
2446
|
+
outputMode?: "live" | "batched" | "final";
|
|
2447
|
+
outputBytes: number;
|
|
2448
|
+
outputSeq: number;
|
|
2449
|
+
truncated: boolean;
|
|
2450
|
+
createdAt: number;
|
|
2451
|
+
startedAt: number | null;
|
|
2452
|
+
endedAt: number | null;
|
|
2453
|
+
expiresAt: number;
|
|
2454
|
+
}
|
|
2455
|
+
```
|
|
2456
|
+
|
|
2457
|
+
#### `Devices` — interface · src/device.ts
|
|
2458
|
+
|
|
2459
|
+
```ts
|
|
2460
|
+
interface Devices {
|
|
2461
|
+
list(): Promise<DeviceSummary[]>;
|
|
2462
|
+
run(name: string, params?: Record<string, unknown>, opts?: DeviceRunOptions): Promise<DeviceRunStarted>;
|
|
2463
|
+
get(commandId: string): Promise<DeviceRunView>;
|
|
2464
|
+
wait(commandId: string, opts?: { timeoutSeconds?: number }): Promise<DeviceRunView>;
|
|
2465
|
+
cancel(commandId: string): Promise<{ status: string }>;
|
|
2466
|
+
sh(line: string, opts: { agent: string; stdin?: string; linkId?: string; waitSeconds?: number }): Promise<ShellResult & { commandId: string; status: DeviceRunStatus }>;
|
|
2467
|
+
}
|
|
2468
|
+
```
|
|
2469
|
+
|
|
2470
|
+
#### `DeviceSummary` — interface · src/device.ts
|
|
2471
|
+
|
|
2472
|
+
One computer connected to this app instance.
|
|
2473
|
+
|
|
2474
|
+
```ts
|
|
2475
|
+
interface DeviceSummary {
|
|
2476
|
+
linkId: string;
|
|
2477
|
+
status: "active" | "suspended";
|
|
2478
|
+
reason: string | null;
|
|
2479
|
+
commands: string[];
|
|
2480
|
+
pendingApproval: { added: string[]; changed: string[] };
|
|
2481
|
+
machine: { machineId: string; hostname: string; os: string; arch: string | null; runtimeVersion: string | null; lastSeenAt: number | null; online: boolean } | null;
|
|
2482
|
+
workspace?: WorkspaceGrant | null;
|
|
2483
|
+
}
|
|
2484
|
+
```
|
|
2485
|
+
|
|
2266
2486
|
#### `EmitPluginAppEventArgs` — interface · src/server.ts
|
|
2267
2487
|
|
|
2268
2488
|
```ts
|
|
@@ -2561,6 +2781,22 @@ interface RunOptions {
|
|
|
2561
2781
|
}
|
|
2562
2782
|
```
|
|
2563
2783
|
|
|
2784
|
+
#### `ShellResult` — interface · src/device.ts
|
|
2785
|
+
|
|
2786
|
+
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`.
|
|
2787
|
+
|
|
2788
|
+
```ts
|
|
2789
|
+
interface ShellResult {
|
|
2790
|
+
ok: boolean;
|
|
2791
|
+
text: string;
|
|
2792
|
+
data?: unknown;
|
|
2793
|
+
exitCode?: number | null;
|
|
2794
|
+
error?: string;
|
|
2795
|
+
opId?: string;
|
|
2796
|
+
cwd: string;
|
|
2797
|
+
}
|
|
2798
|
+
```
|
|
2799
|
+
|
|
2564
2800
|
#### `ToEndOptions` — interface · src/computer.ts
|
|
2565
2801
|
|
|
2566
2802
|
```ts
|
|
@@ -2582,12 +2818,44 @@ interface ViewerProfile {
|
|
|
2582
2818
|
}
|
|
2583
2819
|
```
|
|
2584
2820
|
|
|
2821
|
+
#### `WorkspaceGrant` — type · src/device.ts
|
|
2822
|
+
|
|
2823
|
+
What an app's agents may reach on a computer through the shared command line.
|
|
2824
|
+
|
|
2825
|
+
```ts
|
|
2826
|
+
type WorkspaceGrant = { scope: "folder"; root: string } | { scope: "computer" };
|
|
2827
|
+
```
|
|
2828
|
+
|
|
2585
2829
|
==============================================================================
|
|
2586
|
-
## `esoul-sdk/react` —
|
|
2830
|
+
## `esoul-sdk/react` — 64 exports
|
|
2587
2831
|
|
|
2588
2832
|
The app's UI: hooks for the viewer, the app's state, realtime, workspace files and tools.
|
|
2589
2833
|
|
|
2590
|
-
### Functions and values (
|
|
2834
|
+
### Functions and values (33)
|
|
2835
|
+
|
|
2836
|
+
#### `ConnectComputer` — function · src/react.ts
|
|
2837
|
+
|
|
2838
|
+
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+.
|
|
2839
|
+
|
|
2840
|
+
```ts
|
|
2841
|
+
function ConnectComputer(_props: { workspaceId: string; nodeId: string; title?: string; className?: string }): any
|
|
2842
|
+
```
|
|
2843
|
+
|
|
2844
|
+
#### `describeFailure` — function · src/failed-requests.ts
|
|
2845
|
+
|
|
2846
|
+
Words and retryability for a thrown request: `PluginCallError` carries status + code; a fetch that never reached the server throws a TypeError.
|
|
2847
|
+
|
|
2848
|
+
```ts
|
|
2849
|
+
function describeFailure(error: unknown): { why: string; retryable: boolean }
|
|
2850
|
+
```
|
|
2851
|
+
|
|
2852
|
+
#### `dismissFailedRequest` — function · src/failed-requests.ts
|
|
2853
|
+
|
|
2854
|
+
Take a request off the banner — it landed after all, or the person dismissed it.
|
|
2855
|
+
|
|
2856
|
+
```ts
|
|
2857
|
+
function dismissFailedRequest(key: string): void
|
|
2858
|
+
```
|
|
2591
2859
|
|
|
2592
2860
|
#### `FilesBrowseError` — class · src/react.ts
|
|
2593
2861
|
|
|
@@ -2605,6 +2873,14 @@ A polygon labeller for one image — the Explorer's mask editor as a component:
|
|
|
2605
2873
|
function ImageLabeler(_props: ImageLabelerProps): any
|
|
2606
2874
|
```
|
|
2607
2875
|
|
|
2876
|
+
#### `isRetryableFailure` — function · src/failed-requests.ts
|
|
2877
|
+
|
|
2878
|
+
Is this failure worth a Try again? A lost connection, a timeout, a server error or a rate limit — yes. A refusal (the server read the request and said no, with a reason) — retrying sends the same no; the app shows the reason instead.
|
|
2879
|
+
|
|
2880
|
+
```ts
|
|
2881
|
+
function isRetryableFailure(r: { reason?: string; status?: number }): boolean
|
|
2882
|
+
```
|
|
2883
|
+
|
|
2608
2884
|
#### `listFileEntries` — function · src/react.ts
|
|
2609
2885
|
|
|
2610
2886
|
One page of a folder, as a plain call (no hook).
|
|
@@ -2629,6 +2905,14 @@ Folders matching what is being typed: names that START with it, then names that
|
|
|
2629
2905
|
function rankFolderSuggestions(entries: FileEntry[], partial: string, limit = 50): FileEntry[]
|
|
2630
2906
|
```
|
|
2631
2907
|
|
|
2908
|
+
#### `reportFailedRequest` — function · src/failed-requests.ts
|
|
2909
|
+
|
|
2910
|
+
Report a request that failed after the screen already showed it; the banner names it (and offers Try again when `retry` is given). The same `key` replaces, never stacks.
|
|
2911
|
+
|
|
2912
|
+
```ts
|
|
2913
|
+
function reportFailedRequest(r: Omit<FailedRequest, "at" | "retrying"> & { at?: number }): void
|
|
2914
|
+
```
|
|
2915
|
+
|
|
2632
2916
|
#### `resolveFilePath` — function · src/react.ts
|
|
2633
2917
|
|
|
2634
2918
|
Walk "a/b/c" from the source's root by exact names, as a plain call.
|
|
@@ -2637,6 +2921,14 @@ Walk "a/b/c" from the source's root by exact names, as a plain call.
|
|
|
2637
2921
|
function resolveFilePath(_workspaceId: string, _sourceId: string, _path: string): Promise<ResolvedFilePath>
|
|
2638
2922
|
```
|
|
2639
2923
|
|
|
2924
|
+
#### `runOptimistic` — function · src/failed-requests.ts
|
|
2925
|
+
|
|
2926
|
+
The optimistic-UI rule in one call. `apply` puts the result on screen at once; `send` does the work; on success any earlier failure of the same `key` clears. On failure `revert` puts the screen back and the request is reported: a connection loss, timeout or server error gets Try again (which runs the whole thing again, apply included), a refusal shows its reason only — retrying would send the same no.
|
|
2927
|
+
|
|
2928
|
+
```ts
|
|
2929
|
+
async function runOptimistic<T>(r: { key: string; what: string; apply?: () => void; revert?: () => void; send: () => Promise<T>; }): Promise<{ ok: true; result: T } | { ok: false; error: unknown }>
|
|
2930
|
+
```
|
|
2931
|
+
|
|
2640
2932
|
#### `splitTypedPath` — function · src/react.ts
|
|
2641
2933
|
|
|
2642
2934
|
"sheets/quality/Ty" → `{ parentPath: "sheets/quality", partial: "Ty" }`; a trailing "/" means "inside it". Pure.
|
|
@@ -2653,6 +2945,30 @@ True when the current viewer may mutate this workspace.
|
|
|
2653
2945
|
function useAppCanEdit(): boolean
|
|
2654
2946
|
```
|
|
2655
2947
|
|
|
2948
|
+
#### `useDeviceActions` — function · src/react.ts
|
|
2949
|
+
|
|
2950
|
+
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.
|
|
2951
|
+
|
|
2952
|
+
```ts
|
|
2953
|
+
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 }>; }
|
|
2954
|
+
```
|
|
2955
|
+
|
|
2956
|
+
#### `useDeviceRun` — function · src/react.ts
|
|
2957
|
+
|
|
2958
|
+
One run, live: status as it changes, output as it streams. `finished` once it ended.
|
|
2959
|
+
|
|
2960
|
+
```ts
|
|
2961
|
+
function useDeviceRun(_where: { workspaceId: string; nodeId: string; commandId: string | null | undefined }): { run: DeviceRunView | null; error: string | null; refetch: () => Promise<void>; finished: boolean }
|
|
2962
|
+
```
|
|
2963
|
+
|
|
2964
|
+
#### `useDevices` — function · src/react.ts
|
|
2965
|
+
|
|
2966
|
+
The computers connected to this app instance, live (presence refreshes every 20 s).
|
|
2967
|
+
|
|
2968
|
+
```ts
|
|
2969
|
+
function useDevices(_where: { workspaceId: string; nodeId: string }): { devices: DeviceSummary[] | null; error: string | null; refresh: () => Promise<void> }
|
|
2970
|
+
```
|
|
2971
|
+
|
|
2656
2972
|
#### `useFileSourceEntries` — function · src/react.ts
|
|
2657
2973
|
|
|
2658
2974
|
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.
|
|
@@ -2685,6 +3001,14 @@ A folder box with autocomplete: give it the text being typed ("sheets/quality_da
|
|
|
2685
3001
|
function useFolderAutocomplete(_workspaceId: string | null, _sourceId: string | null, _text: string): FolderAutocompleteState
|
|
2686
3002
|
```
|
|
2687
3003
|
|
|
3004
|
+
#### `useMyComputers` — function · src/react.ts
|
|
3005
|
+
|
|
3006
|
+
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.
|
|
3007
|
+
|
|
3008
|
+
```ts
|
|
3009
|
+
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 }> }
|
|
3010
|
+
```
|
|
3011
|
+
|
|
2688
3012
|
#### `usePluginCurrentChatId` — function · src/react.ts
|
|
2689
3013
|
|
|
2690
3014
|
Current open chat id, for `chatIdSource` attribution.
|
|
@@ -2765,7 +3089,88 @@ Invoke tools of OTHER apps in the workspace (append a spreadsheet row, add a cal
|
|
|
2765
3089
|
function useWorkspaceTools(_identity: { workspaceId: string; nodeId: string }): WorkspaceTools
|
|
2766
3090
|
```
|
|
2767
3091
|
|
|
2768
|
-
|
|
3092
|
+
#### `YourComputers` — function · src/react.ts
|
|
3093
|
+
|
|
3094
|
+
The account's computers as a panel: online, the apps each serves, Disconnect.
|
|
3095
|
+
|
|
3096
|
+
```ts
|
|
3097
|
+
function YourComputers(_props: { className?: string }): any
|
|
3098
|
+
```
|
|
3099
|
+
|
|
3100
|
+
### Types (31)
|
|
3101
|
+
|
|
3102
|
+
#### `DeviceRunStarted` — interface · src/device.ts
|
|
3103
|
+
|
|
3104
|
+
```ts
|
|
3105
|
+
interface DeviceRunStarted {
|
|
3106
|
+
commandId: string;
|
|
3107
|
+
status: DeviceRunStatus;
|
|
3108
|
+
machineOnline: boolean;
|
|
3109
|
+
expiresAt: number;
|
|
3110
|
+
}
|
|
3111
|
+
```
|
|
3112
|
+
|
|
3113
|
+
#### `DeviceRunView` — interface · src/device.ts
|
|
3114
|
+
|
|
3115
|
+
```ts
|
|
3116
|
+
interface DeviceRunView {
|
|
3117
|
+
commandId: string;
|
|
3118
|
+
linkId: string;
|
|
3119
|
+
machineId: string;
|
|
3120
|
+
capability?: string;
|
|
3121
|
+
agent?: string | null;
|
|
3122
|
+
name: string;
|
|
3123
|
+
params: Record<string, unknown>;
|
|
3124
|
+
argv: string[];
|
|
3125
|
+
status: DeviceRunStatus;
|
|
3126
|
+
exitCode: number | null;
|
|
3127
|
+
signal: string | null;
|
|
3128
|
+
reason: string | null;
|
|
3129
|
+
output?: string;
|
|
3130
|
+
tail?: string;
|
|
3131
|
+
result?: unknown;
|
|
3132
|
+
resultError?: string | null;
|
|
3133
|
+
outputMode?: "live" | "batched" | "final";
|
|
3134
|
+
outputBytes: number;
|
|
3135
|
+
outputSeq: number;
|
|
3136
|
+
truncated: boolean;
|
|
3137
|
+
createdAt: number;
|
|
3138
|
+
startedAt: number | null;
|
|
3139
|
+
endedAt: number | null;
|
|
3140
|
+
expiresAt: number;
|
|
3141
|
+
}
|
|
3142
|
+
```
|
|
3143
|
+
|
|
3144
|
+
#### `DeviceSummary` — interface · src/device.ts
|
|
3145
|
+
|
|
3146
|
+
One computer connected to this app instance.
|
|
3147
|
+
|
|
3148
|
+
```ts
|
|
3149
|
+
interface DeviceSummary {
|
|
3150
|
+
linkId: string;
|
|
3151
|
+
status: "active" | "suspended";
|
|
3152
|
+
reason: string | null;
|
|
3153
|
+
commands: string[];
|
|
3154
|
+
pendingApproval: { added: string[]; changed: string[] };
|
|
3155
|
+
machine: { machineId: string; hostname: string; os: string; arch: string | null; runtimeVersion: string | null; lastSeenAt: number | null; online: boolean } | null;
|
|
3156
|
+
workspace?: WorkspaceGrant | null;
|
|
3157
|
+
}
|
|
3158
|
+
```
|
|
3159
|
+
|
|
3160
|
+
#### `FailedRequest` — interface · src/failed-requests.ts
|
|
3161
|
+
|
|
3162
|
+
The platform's list of requests that failed after the UI already showed their result (the optimistic-UI rule, app-style-guide.md "Interaction"): an app updates the screen at once, and when the request behind it fails the app puts the screen back and reports here — `<FailedRequestBanner/>` then names the request and offers Try again, in the same place and style as the "new version is available" pill. Pure and framework-free, so any app (built-in or Forge) and any test can use it. A Forge app imports it from `esoul-sdk/react`; the platform's `src/lib/failed-requests.ts` re-exports this very module, so both reach one list.
|
|
3163
|
+
|
|
3164
|
+
```ts
|
|
3165
|
+
interface FailedRequest {
|
|
3166
|
+
key: string;
|
|
3167
|
+
what: string;
|
|
3168
|
+
why?: string;
|
|
3169
|
+
retry?: () => Promise<boolean> | boolean;
|
|
3170
|
+
at: number;
|
|
3171
|
+
retrying?: boolean;
|
|
3172
|
+
}
|
|
3173
|
+
```
|
|
2769
3174
|
|
|
2770
3175
|
#### `FileEntriesState` — interface · src/react.ts
|
|
2771
3176
|
|
|
@@ -2868,6 +3273,23 @@ interface LabelClass {
|
|
|
2868
3273
|
}
|
|
2869
3274
|
```
|
|
2870
3275
|
|
|
3276
|
+
#### `MyComputer` — interface · src/react.ts
|
|
3277
|
+
|
|
3278
|
+
One computer connected to the signed-in account, and the apps it is assigned to.
|
|
3279
|
+
|
|
3280
|
+
```ts
|
|
3281
|
+
interface MyComputer {
|
|
3282
|
+
machineId: string;
|
|
3283
|
+
hostname: string;
|
|
3284
|
+
os: string;
|
|
3285
|
+
arch: string | null;
|
|
3286
|
+
runtimeVersion: string | null;
|
|
3287
|
+
lastSeenAt: number | null;
|
|
3288
|
+
online: boolean;
|
|
3289
|
+
apps: { linkId: string; nodeId: string; workspaceId: string; status: string; appName: string | null }[];
|
|
3290
|
+
}
|
|
3291
|
+
```
|
|
3292
|
+
|
|
2871
3293
|
#### `PluginRealtime` — interface · src/react.ts
|
|
2872
3294
|
|
|
2873
3295
|
```ts
|
|
@@ -3013,6 +3435,22 @@ interface ResolvedFilePath {
|
|
|
3013
3435
|
}
|
|
3014
3436
|
```
|
|
3015
3437
|
|
|
3438
|
+
#### `ShellResult` — interface · src/device.ts
|
|
3439
|
+
|
|
3440
|
+
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`.
|
|
3441
|
+
|
|
3442
|
+
```ts
|
|
3443
|
+
interface ShellResult {
|
|
3444
|
+
ok: boolean;
|
|
3445
|
+
text: string;
|
|
3446
|
+
data?: unknown;
|
|
3447
|
+
exitCode?: number | null;
|
|
3448
|
+
error?: string;
|
|
3449
|
+
opId?: string;
|
|
3450
|
+
cwd: string;
|
|
3451
|
+
}
|
|
3452
|
+
```
|
|
3453
|
+
|
|
3016
3454
|
#### `SignInWall` — interface · src/react.ts
|
|
3017
3455
|
|
|
3018
3456
|
```ts
|
|
@@ -3036,6 +3474,14 @@ interface WorkspaceAppSummary {
|
|
|
3036
3474
|
}
|
|
3037
3475
|
```
|
|
3038
3476
|
|
|
3477
|
+
#### `WorkspaceGrant` — type · src/device.ts
|
|
3478
|
+
|
|
3479
|
+
What an app's agents may reach on a computer through the shared command line.
|
|
3480
|
+
|
|
3481
|
+
```ts
|
|
3482
|
+
type WorkspaceGrant = { scope: "folder"; root: string } | { scope: "computer" };
|
|
3483
|
+
```
|
|
3484
|
+
|
|
3039
3485
|
#### `WorkspaceNav` — interface · src/react.ts
|
|
3040
3486
|
|
|
3041
3487
|
```ts
|
|
@@ -3289,3 +3735,774 @@ interface TestManifest {
|
|
|
3289
3735
|
```ts
|
|
3290
3736
|
type ViewerKind = RuleViewer["kind"];
|
|
3291
3737
|
```
|
|
3738
|
+
|
|
3739
|
+
==============================================================================
|
|
3740
|
+
## `esoul-sdk/machine` — 82 exports
|
|
3741
|
+
|
|
3742
|
+
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.
|
|
3743
|
+
|
|
3744
|
+
### Functions and values (51)
|
|
3745
|
+
|
|
3746
|
+
#### `AGENT_NAME_RE` — const · src/machine/shell.ts
|
|
3747
|
+
|
|
3748
|
+
What an agent may be called: lowercase letters, digits, - and _, up to 32, starting with a letter.
|
|
3749
|
+
|
|
3750
|
+
```ts
|
|
3751
|
+
const AGENT_NAME_RE: RegExp
|
|
3752
|
+
```
|
|
3753
|
+
|
|
3754
|
+
#### `announce` — function · src/machine/capabilities.ts
|
|
3755
|
+
|
|
3756
|
+
What the hello announces: ["commands@1", "workspace@1"].
|
|
3757
|
+
|
|
3758
|
+
```ts
|
|
3759
|
+
function announce(reg: Map<string, Capability>): string[]
|
|
3760
|
+
```
|
|
3761
|
+
|
|
3762
|
+
#### `applyEdits` — function · src/machine/files.ts
|
|
3763
|
+
|
|
3764
|
+
Find-and-replace edits, applied in order; each must match exactly once (unless `all`). All or nothing.
|
|
3765
|
+
|
|
3766
|
+
```ts
|
|
3767
|
+
function applyEdits(text: string, edits: Edit[]): { text: string; applied: number }
|
|
3768
|
+
```
|
|
3769
|
+
|
|
3770
|
+
#### `applyPatch` — function · src/machine/files.ts
|
|
3771
|
+
|
|
3772
|
+
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`.
|
|
3773
|
+
|
|
3774
|
+
```ts
|
|
3775
|
+
function applyPatch(text: string, diff: string, opts: { partial?: boolean } = {}): { text: string; results: HunkResult[] }
|
|
3776
|
+
```
|
|
3777
|
+
|
|
3778
|
+
#### `builtInCapabilities` — function · src/machine/capabilities.ts
|
|
3779
|
+
|
|
3780
|
+
The capabilities this runtime is built with, as one registry (the supervisor dispatches through it).
|
|
3781
|
+
|
|
3782
|
+
```ts
|
|
3783
|
+
function builtInCapabilities(startRun: (job: Job, redact: string[], env: Record<string, string>) => Promise<void>): Map<string, Capability>
|
|
3784
|
+
```
|
|
3785
|
+
|
|
3786
|
+
#### `canonical` — function · src/machine/protocol.ts
|
|
3787
|
+
|
|
3788
|
+
The exact bytes that are signed. Path INCLUDES the query string.
|
|
3789
|
+
|
|
3790
|
+
```ts
|
|
3791
|
+
function canonical(method: string, pathAndQuery: string, ts: number | string, body: string | Uint8Array): string
|
|
3792
|
+
```
|
|
3793
|
+
|
|
3794
|
+
#### `COMMAND_NAME_RE` — const · src/machine/commands.ts
|
|
3795
|
+
|
|
3796
|
+
What a command name may look like: lowercase, starts with a letter, up to 40 characters.
|
|
3797
|
+
|
|
3798
|
+
```ts
|
|
3799
|
+
const COMMAND_NAME_RE: RegExp
|
|
3800
|
+
```
|
|
3801
|
+
|
|
3802
|
+
#### `commandDigest` — function · src/machine/digest.ts
|
|
3803
|
+
|
|
3804
|
+
Stable digest of one command's spec — what the owner approved.
|
|
3805
|
+
|
|
3806
|
+
```ts
|
|
3807
|
+
function commandDigest(spec: CommandSpec): string
|
|
3808
|
+
```
|
|
3809
|
+
|
|
3810
|
+
#### `commandDigests` — function · src/machine/digest.ts
|
|
3811
|
+
|
|
3812
|
+
Every declared command's digest, by name — what an approval records.
|
|
3813
|
+
|
|
3814
|
+
```ts
|
|
3815
|
+
function commandDigests(block: DeviceBlock): Record<string, string>
|
|
3816
|
+
```
|
|
3817
|
+
|
|
3818
|
+
#### `commandsCapability` — function · src/machine/capabilities.ts
|
|
3819
|
+
|
|
3820
|
+
The app's declared commands; the detached runner owns and reports each run.
|
|
3821
|
+
|
|
3822
|
+
```ts
|
|
3823
|
+
function commandsCapability(deps: { startRun: (job: Job, redact: string[], env: Record<string, string>) => Promise<void> }): Capability
|
|
3824
|
+
```
|
|
3825
|
+
|
|
3826
|
+
#### `confinedArgv` — function · src/machine/shell.ts
|
|
3827
|
+
|
|
3828
|
+
argv that runs `line` in `cwd` under the scope's confinement.
|
|
3829
|
+
|
|
3830
|
+
```ts
|
|
3831
|
+
function confinedArgv(ws: Workspace, cwd: string, line: string): string[]
|
|
3832
|
+
```
|
|
3833
|
+
|
|
3834
|
+
#### `connect` — function · src/machine/supervisor.ts
|
|
3835
|
+
|
|
3836
|
+
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.
|
|
3837
|
+
|
|
3838
|
+
```ts
|
|
3839
|
+
async function connect(opts: ConnectOptions): Promise<ConnectResult>
|
|
3840
|
+
```
|
|
3841
|
+
|
|
3842
|
+
#### `connectCode` — function · src/machine/protocol.ts
|
|
3843
|
+
|
|
3844
|
+
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.
|
|
3845
|
+
|
|
3846
|
+
```ts
|
|
3847
|
+
function connectCode(publicKey: string, offerId: string): string
|
|
3848
|
+
```
|
|
3849
|
+
|
|
3850
|
+
#### `DEFAULT_TIMEOUT_SECONDS` — const · src/machine/commands.ts
|
|
3851
|
+
|
|
3852
|
+
A command's time limit when it declares none: one hour.
|
|
3853
|
+
|
|
3854
|
+
```ts
|
|
3855
|
+
const DEFAULT_TIMEOUT_SECONDS: 3600
|
|
3856
|
+
```
|
|
3857
|
+
|
|
3858
|
+
#### `describeGrant` — function · src/machine/grant.ts
|
|
3859
|
+
|
|
3860
|
+
A grant in words: "the folder /home/me/proj", "the whole computer", or "no workspace access".
|
|
3861
|
+
|
|
3862
|
+
```ts
|
|
3863
|
+
function describeGrant(g: WorkspaceGrant | null): string
|
|
3864
|
+
```
|
|
3865
|
+
|
|
3866
|
+
#### `deviceBlockProblems` — function · src/machine/commands.ts
|
|
3867
|
+
|
|
3868
|
+
Every problem with a `device` block, in words an author can act on. Empty = valid.
|
|
3869
|
+
|
|
3870
|
+
```ts
|
|
3871
|
+
function deviceBlockProblems(block: unknown): string[]
|
|
3872
|
+
```
|
|
3873
|
+
|
|
3874
|
+
#### `DeviceCommandError` — class · src/machine/commands.ts
|
|
3875
|
+
|
|
3876
|
+
Why a command was refused: `unknown_command` (not declared), `bad_param` (missing, extra or ill-typed), `bad_spec`. The message says which, in words.
|
|
3877
|
+
|
|
3878
|
+
```ts
|
|
3879
|
+
class DeviceCommandError extends Error { … }
|
|
3880
|
+
```
|
|
3881
|
+
|
|
3882
|
+
#### `deviceHome` — function · src/machine/state.ts
|
|
3883
|
+
|
|
3884
|
+
The runtime's folder on this computer: `explicit`, else ESOUL_DEVICE_HOME, else ~/.esoul-device.
|
|
3885
|
+
|
|
3886
|
+
```ts
|
|
3887
|
+
function deviceHome(explicit?: string): string
|
|
3888
|
+
```
|
|
3889
|
+
|
|
3890
|
+
#### `DoorError` — class · src/machine/client.ts
|
|
3891
|
+
|
|
3892
|
+
A door call that failed: `status` 0 means the door never answered (network); otherwise the door's own `code` and message.
|
|
3893
|
+
|
|
3894
|
+
```ts
|
|
3895
|
+
class DoorError extends Error { … }
|
|
3896
|
+
```
|
|
3897
|
+
|
|
3898
|
+
#### `effectiveGrant` — function · src/machine/grant.ts
|
|
3899
|
+
|
|
3900
|
+
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.
|
|
3901
|
+
|
|
3902
|
+
```ts
|
|
3903
|
+
function effectiveGrant(grant: WorkspaceGrant | null, ceiling: WorkspaceGrant | null): { ok: true; grant: WorkspaceGrant; why?: undefined } | { ok: false; why: string; grant?: undefined }
|
|
3904
|
+
```
|
|
3905
|
+
|
|
3906
|
+
#### `execute` — function · src/machine/shell.ts
|
|
3907
|
+
|
|
3908
|
+
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.
|
|
3909
|
+
|
|
3910
|
+
```ts
|
|
3911
|
+
async function execute(call: ShellCall): Promise<ShellResult>
|
|
3912
|
+
```
|
|
3913
|
+
|
|
3914
|
+
#### `FileError` — class · src/machine/files.ts
|
|
3915
|
+
|
|
3916
|
+
Why a file operation was refused: outside_scope, not_found, changed, hard_link, edit_failed, patch_failed, … — with a sentence and details.
|
|
3917
|
+
|
|
3918
|
+
```ts
|
|
3919
|
+
class FileError extends Error { … }
|
|
3920
|
+
```
|
|
3921
|
+
|
|
3922
|
+
#### `generateDeviceKey` — function · src/machine/protocol.ts
|
|
3923
|
+
|
|
3924
|
+
A new Ed25519 keypair for a computer: the public key in base64url, the private key as PKCS#8 PEM (it never leaves the computer).
|
|
3925
|
+
|
|
3926
|
+
```ts
|
|
3927
|
+
function generateDeviceKey(): DeviceKeyPair
|
|
3928
|
+
```
|
|
3929
|
+
|
|
3930
|
+
#### `grantFromChoice` — function · src/machine/grant.ts
|
|
3931
|
+
|
|
3932
|
+
The owner's choice turned into a grant under this computer's ceiling, or why it cannot be.
|
|
3933
|
+
|
|
3934
|
+
```ts
|
|
3935
|
+
function grantFromChoice(choice: WorkspaceChoice, ceiling: WorkspaceGrant | null): { ok: true; grant: WorkspaceGrant | null; why?: undefined } | { ok: false; why: string; grant?: undefined }
|
|
3936
|
+
```
|
|
3937
|
+
|
|
3938
|
+
#### `H` — const · src/machine/protocol.ts
|
|
3939
|
+
|
|
3940
|
+
Request headers. `key` names the signer: a machine id, or `connect:<id>` before approval.
|
|
3941
|
+
|
|
3942
|
+
```ts
|
|
3943
|
+
const H: { readonly key: "x-esoul-key"; readonly ts: "x-esoul-ts"; readonly sig: "x-esoul-sig"; readonly runtime: "x-esoul-runtime"; }
|
|
3944
|
+
```
|
|
3945
|
+
|
|
3946
|
+
#### `isPublicKey` — function · src/machine/protocol.ts
|
|
3947
|
+
|
|
3948
|
+
Whether `s` is a base64url Ed25519 public key (43 characters).
|
|
3949
|
+
|
|
3950
|
+
```ts
|
|
3951
|
+
function isPublicKey(s: unknown): s is string
|
|
3952
|
+
```
|
|
3953
|
+
|
|
3954
|
+
#### `isTransient` — function · src/machine/client.ts
|
|
3955
|
+
|
|
3956
|
+
Transient = worth retrying later without telling anyone.
|
|
3957
|
+
|
|
3958
|
+
```ts
|
|
3959
|
+
function isTransient(e: unknown): boolean
|
|
3960
|
+
```
|
|
3961
|
+
|
|
3962
|
+
#### `Journal` — class · src/machine/files.ts
|
|
3963
|
+
|
|
3964
|
+
The undo journal of one workspace: previous contents (content-addressed), directory snapshots, and the append-only log of operations.
|
|
3965
|
+
|
|
3966
|
+
```ts
|
|
3967
|
+
class Journal { … }
|
|
3968
|
+
```
|
|
3969
|
+
|
|
3970
|
+
#### `machineFingerprint` — function · src/machine/state.ts
|
|
3971
|
+
|
|
3972
|
+
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).
|
|
3973
|
+
|
|
3974
|
+
```ts
|
|
3975
|
+
function machineFingerprint(home: string): string
|
|
3976
|
+
```
|
|
3977
|
+
|
|
3978
|
+
#### `makeClient` — function · src/machine/client.ts
|
|
3979
|
+
|
|
3980
|
+
A signed door client for one key: every call carries the signature, retries only what the door never answered.
|
|
3981
|
+
|
|
3982
|
+
```ts
|
|
3983
|
+
function makeClient(args: { base: string; keyId: string; privateKeyPem: string; runtimeVersion: string; fetch?: FetchLike; onTiming?: (t: CallTiming) => void }): DoorClient
|
|
3984
|
+
```
|
|
3985
|
+
|
|
3986
|
+
#### `MAX_SKEW_MS` — const · src/machine/protocol.ts
|
|
3987
|
+
|
|
3988
|
+
How far a request's clock may be from the server's. Laptops drift; five minutes is generous and still bounds a replay.
|
|
3989
|
+
|
|
3990
|
+
```ts
|
|
3991
|
+
const MAX_SKEW_MS: number
|
|
3992
|
+
```
|
|
3993
|
+
|
|
3994
|
+
#### `MAX_TIMEOUT_SECONDS` — const · src/machine/commands.ts
|
|
3995
|
+
|
|
3996
|
+
The longest time limit a command may declare: seven days.
|
|
3997
|
+
|
|
3998
|
+
```ts
|
|
3999
|
+
const MAX_TIMEOUT_SECONDS: number
|
|
4000
|
+
```
|
|
4001
|
+
|
|
4002
|
+
#### `newAuthority` — function · src/machine/digest.ts
|
|
4003
|
+
|
|
4004
|
+
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.
|
|
4005
|
+
|
|
4006
|
+
```ts
|
|
4007
|
+
function newAuthority(approved: Record<string, string>, current: DeviceBlock): { added: string[]; changed: string[] }
|
|
4008
|
+
```
|
|
4009
|
+
|
|
4010
|
+
#### `openWorkspace` — function · src/machine/shell.ts
|
|
4011
|
+
|
|
4012
|
+
Open (or create) the workspace for a scope under the runtime's home.
|
|
4013
|
+
|
|
4014
|
+
```ts
|
|
4015
|
+
function openWorkspace(home: string, id: string, scope: Scope): Workspace
|
|
4016
|
+
```
|
|
4017
|
+
|
|
4018
|
+
#### `OUTPUT_LIMITS` — const · src/machine/commands.ts
|
|
4019
|
+
|
|
4020
|
+
The ceilings of the output options: chunk 3 MB, stored head 8 MB, gather 60 s, tail 64 KB.
|
|
4021
|
+
|
|
4022
|
+
```ts
|
|
4023
|
+
const OUTPUT_LIMITS: { readonly maxChunkKb: 3072; readonly maxKb: 8192; readonly flushMs: 60000; readonly tailChars: number; }
|
|
4024
|
+
```
|
|
4025
|
+
|
|
4026
|
+
#### `OutputUploader` — class · src/machine/capabilities.ts
|
|
4027
|
+
|
|
4028
|
+
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.
|
|
4029
|
+
|
|
4030
|
+
```ts
|
|
4031
|
+
class OutputUploader { … }
|
|
4032
|
+
```
|
|
4033
|
+
|
|
4034
|
+
#### `parseGrant` — function · src/machine/grant.ts
|
|
4035
|
+
|
|
4036
|
+
A grant from untrusted JSON, or null. Roots must be absolute and plain.
|
|
4037
|
+
|
|
4038
|
+
```ts
|
|
4039
|
+
function parseGrant(v: unknown): WorkspaceGrant | null
|
|
4040
|
+
```
|
|
4041
|
+
|
|
4042
|
+
#### `parseUnifiedDiff` — function · src/machine/files.ts
|
|
4043
|
+
|
|
4044
|
+
The hunks of a unified diff (`@@ -a,b +c,d
|
|
4045
|
+
|
|
4046
|
+
```ts
|
|
4047
|
+
function parseUnifiedDiff(diff: string): Hunk[]
|
|
4048
|
+
```
|
|
4049
|
+
|
|
4050
|
+
#### `PROTOCOL` — const · src/machine/protocol.ts
|
|
4051
|
+
|
|
4052
|
+
The protocol version, the first line of every signed request.
|
|
4053
|
+
|
|
4054
|
+
```ts
|
|
4055
|
+
const PROTOCOL: "esoul-device/1"
|
|
4056
|
+
```
|
|
4057
|
+
|
|
4058
|
+
#### `registry` — function · src/machine/capabilities.ts
|
|
4059
|
+
|
|
4060
|
+
The capability table the runtime dispatches jobs through, by name.
|
|
4061
|
+
|
|
4062
|
+
```ts
|
|
4063
|
+
function registry(caps: Capability[]): Map<string, Capability>
|
|
4064
|
+
```
|
|
4065
|
+
|
|
4066
|
+
#### `renderCommand` — function · src/machine/commands.ts
|
|
4067
|
+
|
|
4068
|
+
Render one declared command. Throws `DeviceCommandError` with a sentence for anything undeclared or ill-typed.
|
|
4069
|
+
|
|
4070
|
+
```ts
|
|
4071
|
+
function renderCommand(block: DeviceBlock, name: string, params: Record<string, unknown> = {}): RenderedCommand
|
|
4072
|
+
```
|
|
4073
|
+
|
|
4074
|
+
#### `resolveInScope` — function · src/machine/files.ts
|
|
4075
|
+
|
|
4076
|
+
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.
|
|
4077
|
+
|
|
4078
|
+
```ts
|
|
4079
|
+
function resolveInScope(scope: Scope, cwd: string, p: string): string
|
|
4080
|
+
```
|
|
4081
|
+
|
|
4082
|
+
#### `resolveOutput` — function · src/machine/commands.ts
|
|
4083
|
+
|
|
4084
|
+
The spec's output choice with its defaults filled in — what the runtime and the door both use.
|
|
4085
|
+
|
|
4086
|
+
```ts
|
|
4087
|
+
function resolveOutput(spec: OutputSpec | undefined): ResolvedOutput
|
|
4088
|
+
```
|
|
4089
|
+
|
|
4090
|
+
#### `RUNTIME_CAPABILITIES` — const · src/machine/capabilities.ts
|
|
4091
|
+
|
|
4092
|
+
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.
|
|
4093
|
+
|
|
4094
|
+
```ts
|
|
4095
|
+
const RUNTIME_CAPABILITIES: string[]
|
|
4096
|
+
```
|
|
4097
|
+
|
|
4098
|
+
#### `sandboxFor` — function · src/machine/shell.ts
|
|
4099
|
+
|
|
4100
|
+
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).
|
|
4101
|
+
|
|
4102
|
+
```ts
|
|
4103
|
+
function sandboxFor(scope: Scope): Sandbox
|
|
4104
|
+
```
|
|
4105
|
+
|
|
4106
|
+
#### `sha256Hex` — function · src/machine/protocol.ts
|
|
4107
|
+
|
|
4108
|
+
Hex SHA-256 of a request body, as signed.
|
|
4109
|
+
|
|
4110
|
+
```ts
|
|
4111
|
+
function sha256Hex(body: string | Uint8Array): string
|
|
4112
|
+
```
|
|
4113
|
+
|
|
4114
|
+
#### `signRequest` — function · src/machine/protocol.ts
|
|
4115
|
+
|
|
4116
|
+
Sign one request (method, path with query, body) now; returns the `x-esoul-ts` and `x-esoul-sig` header values.
|
|
4117
|
+
|
|
4118
|
+
```ts
|
|
4119
|
+
function signRequest( privateKeyPem: string, method: string, pathAndQuery: string, body: string | Uint8Array, now: number = Date.now(), ): { ts: string; sig: string }
|
|
4120
|
+
```
|
|
4121
|
+
|
|
4122
|
+
#### `startSupervisor` — function · src/machine/supervisor.ts
|
|
4123
|
+
|
|
4124
|
+
The runtime: one per computer, for every connected app — hello, wake, claim, re-render and run, report, and the app's lifecycle.
|
|
4125
|
+
|
|
4126
|
+
```ts
|
|
4127
|
+
function startSupervisor(opts: SupervisorOptions)
|
|
4128
|
+
```
|
|
4129
|
+
|
|
4130
|
+
#### `tokenize` — function · src/machine/shell.ts
|
|
4131
|
+
|
|
4132
|
+
Shell-like words: quotes ('…' literal, "…" with \" escapes), backslash escapes, whitespace separation.
|
|
4133
|
+
|
|
4134
|
+
```ts
|
|
4135
|
+
function tokenize(line: string): string[]
|
|
4136
|
+
```
|
|
4137
|
+
|
|
4138
|
+
#### `verifyRequest` — function · src/machine/protocol.ts
|
|
4139
|
+
|
|
4140
|
+
Pure verification. `publicKey` comes from the platform's row for `x-esoul-key`, never from the request.
|
|
4141
|
+
|
|
4142
|
+
```ts
|
|
4143
|
+
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 }
|
|
4144
|
+
```
|
|
4145
|
+
|
|
4146
|
+
#### `workspaceCapability` — function · src/machine/capabilities.ts
|
|
4147
|
+
|
|
4148
|
+
The shared command line, under grant ∩ ceiling, one working directory per named agent.
|
|
4149
|
+
|
|
4150
|
+
```ts
|
|
4151
|
+
function workspaceCapability(): Capability
|
|
4152
|
+
```
|
|
4153
|
+
|
|
4154
|
+
### Types (31)
|
|
4155
|
+
|
|
4156
|
+
#### `CallTiming` — interface · src/machine/client.ts
|
|
4157
|
+
|
|
4158
|
+
```ts
|
|
4159
|
+
interface CallTiming {
|
|
4160
|
+
method: string;
|
|
4161
|
+
path: string;
|
|
4162
|
+
status: number;
|
|
4163
|
+
ms: number;
|
|
4164
|
+
server: string | null;
|
|
4165
|
+
}
|
|
4166
|
+
```
|
|
4167
|
+
|
|
4168
|
+
#### `Capability` — interface · src/machine/capabilities.ts
|
|
4169
|
+
|
|
4170
|
+
```ts
|
|
4171
|
+
interface Capability {
|
|
4172
|
+
name: string;
|
|
4173
|
+
version: number;
|
|
4174
|
+
refuse(job: Job, ctx: JobContext): string | null;
|
|
4175
|
+
start(job: Job, ctx: JobContext): Promise<void>;
|
|
4176
|
+
}
|
|
4177
|
+
```
|
|
4178
|
+
|
|
4179
|
+
#### `CommandSpec` — interface · src/machine/commands.ts
|
|
4180
|
+
|
|
4181
|
+
```ts
|
|
4182
|
+
interface CommandSpec {
|
|
4183
|
+
argv: string[];
|
|
4184
|
+
params?: Record<string, ParamSpec>;
|
|
4185
|
+
cwd?: string;
|
|
4186
|
+
env?: Record<string, string>;
|
|
4187
|
+
config?: string[];
|
|
4188
|
+
timeoutSeconds?: number;
|
|
4189
|
+
onRestart?: "report" | "rerun";
|
|
4190
|
+
output?: OutputSpec;
|
|
4191
|
+
result?: "text" | "json";
|
|
4192
|
+
describe?: string;
|
|
4193
|
+
}
|
|
4194
|
+
```
|
|
4195
|
+
|
|
4196
|
+
#### `ConfigKeySpec` — interface · src/machine/commands.ts
|
|
4197
|
+
|
|
4198
|
+
```ts
|
|
4199
|
+
interface ConfigKeySpec {
|
|
4200
|
+
secret?: boolean;
|
|
4201
|
+
required?: boolean;
|
|
4202
|
+
describe?: string;
|
|
4203
|
+
}
|
|
4204
|
+
```
|
|
4205
|
+
|
|
4206
|
+
#### `ConnectOptions` — interface · src/machine/supervisor.ts
|
|
4207
|
+
|
|
4208
|
+
```ts
|
|
4209
|
+
interface ConnectOptions {
|
|
4210
|
+
url: string;
|
|
4211
|
+
home?: string;
|
|
4212
|
+
runtimeVersion: string;
|
|
4213
|
+
fetch?: FetchLike;
|
|
4214
|
+
pollMs?: number;
|
|
4215
|
+
print?: (line: string) => void;
|
|
4216
|
+
fingerprint?: string;
|
|
4217
|
+
ceiling?: WorkspaceGrant | null;
|
|
4218
|
+
}
|
|
4219
|
+
```
|
|
4220
|
+
|
|
4221
|
+
#### `ConnectResult` — interface · src/machine/supervisor.ts
|
|
4222
|
+
|
|
4223
|
+
```ts
|
|
4224
|
+
interface ConnectResult {
|
|
4225
|
+
machineId: string;
|
|
4226
|
+
linkId: string | null;
|
|
4227
|
+
base: string;
|
|
4228
|
+
appName: string | null;
|
|
4229
|
+
}
|
|
4230
|
+
```
|
|
4231
|
+
|
|
4232
|
+
#### `DeviceBlock` — interface · src/machine/commands.ts
|
|
4233
|
+
|
|
4234
|
+
```ts
|
|
4235
|
+
interface DeviceBlock {
|
|
4236
|
+
commands: Record<string, CommandSpec>;
|
|
4237
|
+
config?: Record<string, ConfigKeySpec>;
|
|
4238
|
+
redact?: string[];
|
|
4239
|
+
onAppDeleted?: "kill" | "finish";
|
|
4240
|
+
}
|
|
4241
|
+
```
|
|
4242
|
+
|
|
4243
|
+
#### `DeviceKeyPair` — interface · src/machine/protocol.ts
|
|
4244
|
+
|
|
4245
|
+
```ts
|
|
4246
|
+
interface DeviceKeyPair {
|
|
4247
|
+
publicKey: string;
|
|
4248
|
+
privateKeyPem: string;
|
|
4249
|
+
}
|
|
4250
|
+
```
|
|
4251
|
+
|
|
4252
|
+
#### `DoorClient` — interface · src/machine/client.ts
|
|
4253
|
+
|
|
4254
|
+
```ts
|
|
4255
|
+
interface DoorClient {
|
|
4256
|
+
call<T = Record<string, unknown>>(method: "GET" | "POST", path: string, body?: unknown, opts?: { timeoutMs?: number; tries?: number }): Promise<T>;
|
|
4257
|
+
base: string;
|
|
4258
|
+
}
|
|
4259
|
+
```
|
|
4260
|
+
|
|
4261
|
+
#### `Edit` — interface · src/machine/files.ts
|
|
4262
|
+
|
|
4263
|
+
```ts
|
|
4264
|
+
interface Edit {
|
|
4265
|
+
find: string;
|
|
4266
|
+
replace: string;
|
|
4267
|
+
all?: boolean;
|
|
4268
|
+
}
|
|
4269
|
+
```
|
|
4270
|
+
|
|
4271
|
+
#### `FetchLike` — type · src/machine/client.ts
|
|
4272
|
+
|
|
4273
|
+
```ts
|
|
4274
|
+
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 } }>;
|
|
4275
|
+
```
|
|
4276
|
+
|
|
4277
|
+
#### `HunkResult` — interface · src/machine/files.ts
|
|
4278
|
+
|
|
4279
|
+
```ts
|
|
4280
|
+
interface HunkResult {
|
|
4281
|
+
hunk: number;
|
|
4282
|
+
applied: boolean;
|
|
4283
|
+
at?: number;
|
|
4284
|
+
offset?: number;
|
|
4285
|
+
reason?: string;
|
|
4286
|
+
}
|
|
4287
|
+
```
|
|
4288
|
+
|
|
4289
|
+
#### `Job` — interface · src/machine/capabilities.ts
|
|
4290
|
+
|
|
4291
|
+
```ts
|
|
4292
|
+
interface Job extends ClaimedCommand {
|
|
4293
|
+
capability: string;
|
|
4294
|
+
agent: string | null;
|
|
4295
|
+
}
|
|
4296
|
+
```
|
|
4297
|
+
|
|
4298
|
+
#### `JobContext` — interface · src/machine/capabilities.ts
|
|
4299
|
+
|
|
4300
|
+
```ts
|
|
4301
|
+
interface JobContext {
|
|
4302
|
+
home: string;
|
|
4303
|
+
link: LocalLink;
|
|
4304
|
+
ceiling: WorkspaceGrant | null;
|
|
4305
|
+
client: DoorClient;
|
|
4306
|
+
signal: AbortSignal;
|
|
4307
|
+
log: (s: string) => void;
|
|
4308
|
+
}
|
|
4309
|
+
```
|
|
4310
|
+
|
|
4311
|
+
#### `JobOutcome` — interface · src/machine/capabilities.ts
|
|
4312
|
+
|
|
4313
|
+
```ts
|
|
4314
|
+
interface JobOutcome {
|
|
4315
|
+
exitCode: number | null;
|
|
4316
|
+
reason?: string | null;
|
|
4317
|
+
signal?: string | null;
|
|
4318
|
+
result?: unknown;
|
|
4319
|
+
}
|
|
4320
|
+
```
|
|
4321
|
+
|
|
4322
|
+
#### `JournalEntry` — interface · src/machine/files.ts
|
|
4323
|
+
|
|
4324
|
+
```ts
|
|
4325
|
+
interface JournalEntry {
|
|
4326
|
+
opId: string;
|
|
4327
|
+
at: number;
|
|
4328
|
+
agent: string;
|
|
4329
|
+
op: "write" | "edit" | "patch" | "rm" | "mv" | "mkdir" | "undo";
|
|
4330
|
+
path: string;
|
|
4331
|
+
to?: string;
|
|
4332
|
+
before: string | null;
|
|
4333
|
+
after: string | null;
|
|
4334
|
+
dirSnapshot?: string;
|
|
4335
|
+
}
|
|
4336
|
+
```
|
|
4337
|
+
|
|
4338
|
+
#### `LocalLink` — interface · src/machine/state.ts
|
|
4339
|
+
|
|
4340
|
+
```ts
|
|
4341
|
+
interface LocalLink {
|
|
4342
|
+
linkId: string;
|
|
4343
|
+
nodeId: string;
|
|
4344
|
+
workspaceId: string;
|
|
4345
|
+
pluginId: string;
|
|
4346
|
+
appName: string | null;
|
|
4347
|
+
status: "active" | "suspended" | "revoked";
|
|
4348
|
+
reason: string | null;
|
|
4349
|
+
commands: DeviceBlock | null;
|
|
4350
|
+
grants?: Record<string, unknown> | null;
|
|
4351
|
+
}
|
|
4352
|
+
```
|
|
4353
|
+
|
|
4354
|
+
#### `LocalState` — interface · src/machine/state.ts
|
|
4355
|
+
|
|
4356
|
+
```ts
|
|
4357
|
+
interface LocalState {
|
|
4358
|
+
base: string;
|
|
4359
|
+
machineId: string;
|
|
4360
|
+
links: Record<string, LocalLink>;
|
|
4361
|
+
ceiling?: { scope: "folder"; root: string } | { scope: "computer" } | null;
|
|
4362
|
+
}
|
|
4363
|
+
```
|
|
4364
|
+
|
|
4365
|
+
#### `MachineShellResult` — interface · src/machine/shell.ts
|
|
4366
|
+
|
|
4367
|
+
```ts
|
|
4368
|
+
interface ShellResult {
|
|
4369
|
+
ok: boolean;
|
|
4370
|
+
text: string;
|
|
4371
|
+
data?: unknown;
|
|
4372
|
+
exitCode?: number | null;
|
|
4373
|
+
error?: string;
|
|
4374
|
+
opId?: string;
|
|
4375
|
+
cwd: string;
|
|
4376
|
+
}
|
|
4377
|
+
```
|
|
4378
|
+
|
|
4379
|
+
#### `OutputSpec` — interface · src/machine/commands.ts
|
|
4380
|
+
|
|
4381
|
+
The delivery tradeoff, chosen per command (esoul-sdk docs/18 §4):
|
|
4382
|
+
|
|
4383
|
+
```ts
|
|
4384
|
+
interface OutputSpec {
|
|
4385
|
+
mode?: "live" | "batched" | "final";
|
|
4386
|
+
flushMs?: number;
|
|
4387
|
+
maxChunkKb?: number;
|
|
4388
|
+
keep?: "head" | "tail" | "both";
|
|
4389
|
+
maxKb?: number;
|
|
4390
|
+
}
|
|
4391
|
+
```
|
|
4392
|
+
|
|
4393
|
+
#### `ParamSpec` — type · src/machine/commands.ts
|
|
4394
|
+
|
|
4395
|
+
DECLARED COMMANDS — the wall between an app and the person's computer.
|
|
4396
|
+
|
|
4397
|
+
```ts
|
|
4398
|
+
type ParamSpec =
|
|
4399
|
+
| "int"
|
|
4400
|
+
| "number"
|
|
4401
|
+
| "bool"
|
|
4402
|
+
| "string"
|
|
4403
|
+
| { type: "int" | "number"; min?: number; max?: number; describe?: string }
|
|
4404
|
+
| { type: "string"; pattern?: string; maxLength?: number; allowDash?: boolean; describe?: string }
|
|
4405
|
+
| { type: "enum"; values: string[]; describe?: string }
|
|
4406
|
+
| { type: "bool"; describe?: string };
|
|
4407
|
+
```
|
|
4408
|
+
|
|
4409
|
+
#### `RenderedCommand` — interface · src/machine/commands.ts
|
|
4410
|
+
|
|
4411
|
+
```ts
|
|
4412
|
+
interface RenderedCommand {
|
|
4413
|
+
name: string;
|
|
4414
|
+
argv: string[];
|
|
4415
|
+
cwd?: string;
|
|
4416
|
+
env: Record<string, string>;
|
|
4417
|
+
config: string[];
|
|
4418
|
+
timeoutSeconds: number;
|
|
4419
|
+
onRestart: "report" | "rerun";
|
|
4420
|
+
}
|
|
4421
|
+
```
|
|
4422
|
+
|
|
4423
|
+
#### `ResolvedOutput` — interface · src/machine/commands.ts
|
|
4424
|
+
|
|
4425
|
+
```ts
|
|
4426
|
+
interface ResolvedOutput {
|
|
4427
|
+
mode: "live" | "batched" | "final";
|
|
4428
|
+
flushMs: number;
|
|
4429
|
+
maxChunkBytes: number;
|
|
4430
|
+
headMaxBytes: number;
|
|
4431
|
+
tailMaxChars: number;
|
|
4432
|
+
}
|
|
4433
|
+
```
|
|
4434
|
+
|
|
4435
|
+
#### `Sandbox` — type · src/machine/shell.ts
|
|
4436
|
+
|
|
4437
|
+
```ts
|
|
4438
|
+
type Sandbox = { kind: "none" } | { kind: "bwrap"; bin: string } | { kind: "seatbelt" } | { kind: "unavailable"; why: string };
|
|
4439
|
+
```
|
|
4440
|
+
|
|
4441
|
+
#### `Scope` — type · src/machine/files.ts
|
|
4442
|
+
|
|
4443
|
+
```ts
|
|
4444
|
+
type Scope = { kind: "folder"; root: string } | { kind: "computer" };
|
|
4445
|
+
```
|
|
4446
|
+
|
|
4447
|
+
#### `ShellCall` — interface · src/machine/shell.ts
|
|
4448
|
+
|
|
4449
|
+
```ts
|
|
4450
|
+
interface ShellCall {
|
|
4451
|
+
ws: Workspace;
|
|
4452
|
+
agent: string;
|
|
4453
|
+
line: string;
|
|
4454
|
+
stdin?: string;
|
|
4455
|
+
onOutput?: (chunk: string) => void;
|
|
4456
|
+
signal?: AbortSignal;
|
|
4457
|
+
}
|
|
4458
|
+
```
|
|
4459
|
+
|
|
4460
|
+
#### `SupervisorOptions` — interface · src/machine/supervisor.ts
|
|
4461
|
+
|
|
4462
|
+
```ts
|
|
4463
|
+
interface SupervisorOptions {
|
|
4464
|
+
home?: string;
|
|
4465
|
+
runtimeVersion: string;
|
|
4466
|
+
execScript: string;
|
|
4467
|
+
nodePath?: string;
|
|
4468
|
+
fetch?: FetchLike;
|
|
4469
|
+
wake?: boolean;
|
|
4470
|
+
pollSeconds?: number;
|
|
4471
|
+
flushMs?: number;
|
|
4472
|
+
helloEveryMs?: number;
|
|
4473
|
+
log?: (line: string) => void;
|
|
4474
|
+
onEmpty?: (why: string) => void | Promise<void>;
|
|
4475
|
+
}
|
|
4476
|
+
```
|
|
4477
|
+
|
|
4478
|
+
#### `VerifyFailure` — type · src/machine/protocol.ts
|
|
4479
|
+
|
|
4480
|
+
```ts
|
|
4481
|
+
type VerifyFailure = "missing" | "bad_key" | "skew" | "bad_signature";
|
|
4482
|
+
```
|
|
4483
|
+
|
|
4484
|
+
#### `Workspace` — interface · src/machine/shell.ts
|
|
4485
|
+
|
|
4486
|
+
```ts
|
|
4487
|
+
interface Workspace {
|
|
4488
|
+
id: string;
|
|
4489
|
+
scope: Scope;
|
|
4490
|
+
journal: Journal;
|
|
4491
|
+
stateDir: string;
|
|
4492
|
+
sandbox: Sandbox;
|
|
4493
|
+
}
|
|
4494
|
+
```
|
|
4495
|
+
|
|
4496
|
+
#### `WorkspaceChoice` — type · src/machine/grant.ts
|
|
4497
|
+
|
|
4498
|
+
```ts
|
|
4499
|
+
type WorkspaceChoice = "none" | "folder" | "computer";
|
|
4500
|
+
```
|
|
4501
|
+
|
|
4502
|
+
#### `WorkspaceGrant` — type · src/machine/grant.ts
|
|
4503
|
+
|
|
4504
|
+
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:
|
|
4505
|
+
|
|
4506
|
+
```ts
|
|
4507
|
+
type WorkspaceGrant = { scope: "folder"; root: string } | { scope: "computer" };
|
|
4508
|
+
```
|