@exponential_app/engine 0.0.0-stage → 0.1.1
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/LICENSE +201 -0
- package/NOTICE +54 -0
- package/README.md +35 -2
- package/dist/capabilities.js +29 -0
- package/dist/capabilities.js.map +9 -0
- package/dist/chunks/index-3nf9f7pv.js +315 -0
- package/dist/chunks/index-3nf9f7pv.js.map +10 -0
- package/dist/chunks/index-3rgr16n2.js +443 -0
- package/dist/chunks/index-3rgr16n2.js.map +9 -0
- package/dist/chunks/index-79swfbsm.js +366 -0
- package/dist/chunks/index-79swfbsm.js.map +10 -0
- package/dist/chunks/index-knntt4cb.js +259 -0
- package/dist/chunks/index-knntt4cb.js.map +10 -0
- package/dist/chunks/index-m2845dn6.js +72 -0
- package/dist/chunks/index-m2845dn6.js.map +10 -0
- package/dist/chunks/index-pqpnz4ns.js +2213 -0
- package/dist/chunks/index-pqpnz4ns.js.map +9 -0
- package/dist/chunks/index-q4zws02e.js +2301 -0
- package/dist/chunks/index-q4zws02e.js.map +10 -0
- package/dist/chunks/index-s3xjr701.js +170 -0
- package/dist/chunks/index-s3xjr701.js.map +10 -0
- package/dist/chunks/index-sk8b0dh4.js +126 -0
- package/dist/chunks/index-sk8b0dh4.js.map +10 -0
- package/dist/chunks/index-tvsykgcv.js +3015 -0
- package/dist/chunks/index-tvsykgcv.js.map +19 -0
- package/dist/chunks/index-v0m7r4y3.js +6869 -0
- package/dist/chunks/index-v0m7r4y3.js.map +13 -0
- package/dist/consent.js +24 -0
- package/dist/consent.js.map +9 -0
- package/dist/index.js +654 -0
- package/dist/index.js.map +12 -0
- package/dist/lifecycle.js +11 -0
- package/dist/lifecycle.js.map +9 -0
- package/dist/outbox.js +27 -0
- package/dist/outbox.js.map +9 -0
- package/dist/pdf.js +15 -0
- package/dist/pdf.js.map +9 -0
- package/dist/providers.js +26 -0
- package/dist/providers.js.map +9 -0
- package/dist/runner.js +24 -0
- package/dist/runner.js.map +9 -0
- package/dist/tools.js +38 -0
- package/dist/tools.js.map +9 -0
- package/dist/types/domain-contract/src/app-records.d.ts +3148 -0
- package/dist/types/domain-contract/src/app-share.d.ts +222 -0
- package/dist/types/domain-contract/src/apps.d.ts +612 -0
- package/dist/types/eengine/fixtures/providers.json +55 -0
- package/dist/types/eengine/src/broker.d.ts +80 -0
- package/dist/types/eengine/src/capabilities.d.ts +88 -0
- package/dist/types/eengine/src/consent.d.ts +50 -0
- package/dist/types/eengine/src/index.d.ts +12 -0
- package/dist/types/eengine/src/instance.d.ts +131 -0
- package/dist/types/eengine/src/lifecycle.d.ts +64 -0
- package/dist/types/eengine/src/outbox.d.ts +3 -0
- package/dist/types/eengine/src/pdf.d.ts +36 -0
- package/dist/types/eengine/src/providers.d.ts +38 -0
- package/dist/types/eengine/src/runner.d.ts +82 -0
- package/dist/types/eengine/src/stores.d.ts +125 -0
- package/dist/types/eengine/src/synced.d.ts +59 -0
- package/dist/types/eengine/src/tools.d.ts +79 -0
- package/dist/types/eengine/src/web/index.d.ts +20 -0
- package/dist/types/eengine/src/web/mcp.d.ts +27 -0
- package/dist/types/eengine/src/web/platform.d.ts +91 -0
- package/dist/types/eengine/src/web/stores.d.ts +125 -0
- package/dist/types/emcp/fixtures/automations.json +521 -0
- package/dist/types/emcp/fixtures/hub.json +498 -0
- package/dist/types/emcp/src/access.d.ts +55 -0
- package/dist/types/emcp/src/audit.d.ts +22 -0
- package/dist/types/emcp/src/automations.d.ts +111 -0
- package/dist/types/emcp/src/exposes.d.ts +242 -0
- package/dist/types/emcp/src/hub.d.ts +63 -0
- package/dist/types/emcp/src/index.d.ts +7 -0
- package/dist/types/emcp/src/pure.d.ts +11 -0
- package/dist/types/emcp/src/upstream.d.ts +288 -0
- package/dist/types/emcp/src/vault.d.ts +34 -0
- package/dist/web/index.js +791 -0
- package/dist/web/index.js.map +13 -0
- package/fixtures/bundle.json +1165 -0
- package/fixtures/capabilities.json +434 -0
- package/fixtures/consent.json +146 -0
- package/fixtures/lifecycle.json +125 -0
- package/fixtures/outbox.json +22 -0
- package/fixtures/providers.json +55 -0
- package/fixtures/runner.json +2167 -0
- package/package.json +92 -4
|
@@ -0,0 +1,612 @@
|
|
|
1
|
+
export declare const APPS_COPY: {
|
|
2
|
+
nav: string;
|
|
3
|
+
title: string;
|
|
4
|
+
newApp: string;
|
|
5
|
+
untitled: string;
|
|
6
|
+
import: string;
|
|
7
|
+
version: string;
|
|
8
|
+
noVersion: string;
|
|
9
|
+
versions: string;
|
|
10
|
+
head: string;
|
|
11
|
+
noNote: string;
|
|
12
|
+
byAgent: string;
|
|
13
|
+
viewing: string;
|
|
14
|
+
restore: string;
|
|
15
|
+
restored: string;
|
|
16
|
+
restoredNote: string;
|
|
17
|
+
publish: string;
|
|
18
|
+
published: string;
|
|
19
|
+
publishedToast: string;
|
|
20
|
+
publishNothing: string;
|
|
21
|
+
empty: string;
|
|
22
|
+
chatEmpty: string;
|
|
23
|
+
previewEmpty: string;
|
|
24
|
+
versionsEmpty: string;
|
|
25
|
+
composerPlaceholder: string;
|
|
26
|
+
draftPlaceholder: string;
|
|
27
|
+
starterTitle: string;
|
|
28
|
+
starters: string[];
|
|
29
|
+
noDevice: string;
|
|
30
|
+
namePlaceholder: string;
|
|
31
|
+
descriptionPlaceholder: string;
|
|
32
|
+
deleteTitle: string;
|
|
33
|
+
deleteBody: string;
|
|
34
|
+
delete: string;
|
|
35
|
+
menu: {
|
|
36
|
+
versions: string;
|
|
37
|
+
settings: string;
|
|
38
|
+
export: string;
|
|
39
|
+
delete: string;
|
|
40
|
+
edit: string;
|
|
41
|
+
};
|
|
42
|
+
tabs: {
|
|
43
|
+
chat: string;
|
|
44
|
+
preview: string;
|
|
45
|
+
data: string;
|
|
46
|
+
versions: string;
|
|
47
|
+
settings: string;
|
|
48
|
+
};
|
|
49
|
+
settingsTitle: string;
|
|
50
|
+
records: string;
|
|
51
|
+
recordsOne: string;
|
|
52
|
+
recordsOf: string;
|
|
53
|
+
recordsNone: string;
|
|
54
|
+
tools: {
|
|
55
|
+
title: string;
|
|
56
|
+
hint: string;
|
|
57
|
+
none: string;
|
|
58
|
+
granted: string;
|
|
59
|
+
always: string;
|
|
60
|
+
};
|
|
61
|
+
preview: string;
|
|
62
|
+
frame: {
|
|
63
|
+
desktop: string;
|
|
64
|
+
phone: string;
|
|
65
|
+
};
|
|
66
|
+
runAs: {
|
|
67
|
+
me: string;
|
|
68
|
+
writesOff: string;
|
|
69
|
+
};
|
|
70
|
+
automations: {
|
|
71
|
+
title: string;
|
|
72
|
+
schedule: string;
|
|
73
|
+
scheduleZone: string;
|
|
74
|
+
create: string;
|
|
75
|
+
update: string;
|
|
76
|
+
delete: string;
|
|
77
|
+
event: string;
|
|
78
|
+
webhook: string;
|
|
79
|
+
paused: string;
|
|
80
|
+
failed: string;
|
|
81
|
+
ok: string;
|
|
82
|
+
never: string;
|
|
83
|
+
runsAs: string;
|
|
84
|
+
dropped: string;
|
|
85
|
+
droppedOne: string;
|
|
86
|
+
pausedReasons: {
|
|
87
|
+
sponsorGone: string;
|
|
88
|
+
sponsorReadOnly: string;
|
|
89
|
+
sponsorNotAllowed: string;
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
migrating: string;
|
|
93
|
+
migratingOf: string;
|
|
94
|
+
migrationFailed: string;
|
|
95
|
+
rollbackTitle: string;
|
|
96
|
+
rollbackBody: string;
|
|
97
|
+
webhooks: {
|
|
98
|
+
title: string;
|
|
99
|
+
ready: string;
|
|
100
|
+
unsigned: string;
|
|
101
|
+
copyUrl: string;
|
|
102
|
+
copied: string;
|
|
103
|
+
mint: string;
|
|
104
|
+
rotate: string;
|
|
105
|
+
secret: string;
|
|
106
|
+
copySecret: string;
|
|
107
|
+
};
|
|
108
|
+
runEmpty: string;
|
|
109
|
+
needsUpdate: string;
|
|
110
|
+
accounts: {
|
|
111
|
+
title: string;
|
|
112
|
+
connect: string;
|
|
113
|
+
reconnect: string;
|
|
114
|
+
connected: string;
|
|
115
|
+
notSetUp: string;
|
|
116
|
+
addServer: string;
|
|
117
|
+
usesServer: string;
|
|
118
|
+
};
|
|
119
|
+
mcpTools: {
|
|
120
|
+
title: string;
|
|
121
|
+
read: string;
|
|
122
|
+
write: string;
|
|
123
|
+
};
|
|
124
|
+
policies: {
|
|
125
|
+
title: string;
|
|
126
|
+
ops: {
|
|
127
|
+
read: string;
|
|
128
|
+
create: string;
|
|
129
|
+
update: string;
|
|
130
|
+
delete: string;
|
|
131
|
+
};
|
|
132
|
+
levels: {
|
|
133
|
+
member: string;
|
|
134
|
+
author: string;
|
|
135
|
+
owners: string;
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
export declare const APPS_PANES: {
|
|
140
|
+
chat: number;
|
|
141
|
+
preview: number;
|
|
142
|
+
chatMinWidth: number;
|
|
143
|
+
breakpoint: number;
|
|
144
|
+
};
|
|
145
|
+
export declare const APPS_PREVIEW: {
|
|
146
|
+
radius: number;
|
|
147
|
+
padding: number;
|
|
148
|
+
surfaceId: string;
|
|
149
|
+
$comment: string;
|
|
150
|
+
frames: string[];
|
|
151
|
+
defaultFrame: string;
|
|
152
|
+
phoneWidth: number;
|
|
153
|
+
};
|
|
154
|
+
export declare const APPS_TEST_IDS: {
|
|
155
|
+
list: string;
|
|
156
|
+
row: string;
|
|
157
|
+
newApp: string;
|
|
158
|
+
editor: string;
|
|
159
|
+
chat: string;
|
|
160
|
+
preview: string;
|
|
161
|
+
versions: string;
|
|
162
|
+
versionRow: string;
|
|
163
|
+
tabs: string;
|
|
164
|
+
composer: string;
|
|
165
|
+
viewing: string;
|
|
166
|
+
importApp: string;
|
|
167
|
+
starter: string;
|
|
168
|
+
menu: string;
|
|
169
|
+
settings: string;
|
|
170
|
+
versionPreview: string;
|
|
171
|
+
versionRestore: string;
|
|
172
|
+
data: string;
|
|
173
|
+
previewToolbar: string;
|
|
174
|
+
previewFrame: string;
|
|
175
|
+
previewTemplate: string;
|
|
176
|
+
previewRunAs: string;
|
|
177
|
+
publish: string;
|
|
178
|
+
versionPublish: string;
|
|
179
|
+
automations: string;
|
|
180
|
+
automationRow: string;
|
|
181
|
+
webhooks: string;
|
|
182
|
+
webhookRow: string;
|
|
183
|
+
webhookSecret: string;
|
|
184
|
+
previewScreens: string;
|
|
185
|
+
run: string;
|
|
186
|
+
runMenu: string;
|
|
187
|
+
newMenu: string;
|
|
188
|
+
accounts: string;
|
|
189
|
+
accountRow: string;
|
|
190
|
+
importUpstreams: string;
|
|
191
|
+
importUpstream: string;
|
|
192
|
+
mcpTools: string;
|
|
193
|
+
mcpToolRow: string;
|
|
194
|
+
policies: string;
|
|
195
|
+
policyRow: string;
|
|
196
|
+
};
|
|
197
|
+
export declare const APPS_EDITOR_TABS: {
|
|
198
|
+
wide: string[];
|
|
199
|
+
phone: string[];
|
|
200
|
+
menu: string[];
|
|
201
|
+
default: string;
|
|
202
|
+
phoneDefault: string;
|
|
203
|
+
settingsMaxWidth: number;
|
|
204
|
+
search: string;
|
|
205
|
+
};
|
|
206
|
+
/** VAPP-242: THE RUN VIEW's `…` menu + THE NEW MENU, in order. */
|
|
207
|
+
export declare const APPS_RUN: {
|
|
208
|
+
$comment: string;
|
|
209
|
+
menu: string[];
|
|
210
|
+
newMenu: string[];
|
|
211
|
+
editorPath: string;
|
|
212
|
+
};
|
|
213
|
+
/** VAPP-177: the editor's tabs (web ≥ md and desktop: Preview | Versions |
|
|
214
|
+
* Settings; phones: Chat | Preview + the `…` menu's sheets). */
|
|
215
|
+
export type AppEditorTab = `chat` | `preview` | `data` | `versions` | `settings`;
|
|
216
|
+
/** The phone menu items that open a tab body as a sheet. */
|
|
217
|
+
export type AppEditorSheet = `versions` | `settings`;
|
|
218
|
+
/** A requested tab (web `?tab=`, the desktop settings nav) → the tab on
|
|
219
|
+
* screen and, on phones, the sheet over it (`editorTabCases`). */
|
|
220
|
+
export declare function editorTab(requested: string | null | undefined, phone: boolean): {
|
|
221
|
+
tab: AppEditorTab;
|
|
222
|
+
sheet: AppEditorSheet | null;
|
|
223
|
+
};
|
|
224
|
+
/** VAPP-176: a DRAFT = an app with no version yet (New app's "Untitled app"
|
|
225
|
+
* until the editor session publishes). */
|
|
226
|
+
export declare function isDraftApp(app: {
|
|
227
|
+
headVersion: number;
|
|
228
|
+
}): boolean;
|
|
229
|
+
export declare const APP_SLUG_MAX: number;
|
|
230
|
+
export declare const APP_NAME_MAX: number;
|
|
231
|
+
export declare const APP_DESCRIPTION_MAX: number;
|
|
232
|
+
export declare const APP_NOTE_MAX: number;
|
|
233
|
+
export declare const APP_PACKAGE_MAX_BYTES: number;
|
|
234
|
+
export declare const APP_TEMPLATE_MAX_COMPONENTS: number;
|
|
235
|
+
export declare const APP_SLUG_PATTERN: RegExp;
|
|
236
|
+
export declare const APP_RECORD_KIND_PATTERN: RegExp;
|
|
237
|
+
export declare const APP_RECORD_MAX_BYTES: number;
|
|
238
|
+
export declare const APP_RECORD_KINDS_MAX: number;
|
|
239
|
+
/** `v{n}`, or the "no version" copy while an app has no head. */
|
|
240
|
+
export declare function versionLabel(headVersion: number): string;
|
|
241
|
+
/** eApps V1 (#VAPP-210, fixture `publishCases`): an app's two pointers. */
|
|
242
|
+
export interface AppVersions {
|
|
243
|
+
headVersion: number;
|
|
244
|
+
publishedVersion: number;
|
|
245
|
+
}
|
|
246
|
+
/** The version the editor's preview shows: an explicitly viewed one, else
|
|
247
|
+
* nothing (no version), else the HEAD (the draft) while the viewer's own
|
|
248
|
+
* editor session is live or nothing is published, else the PUBLISHED one. */
|
|
249
|
+
export declare function shownVersion(app: AppVersions, editing: boolean, viewing: number | null): number;
|
|
250
|
+
/** Publish is offered while the head is not the published version. */
|
|
251
|
+
export declare function canPublish(app: AppVersions): boolean;
|
|
252
|
+
/** The list's and the header's version pill: the PUBLISHED version. */
|
|
253
|
+
export declare function listPill(app: AppVersions): string;
|
|
254
|
+
/** The version a grant is made on and checked against (`apps.update
|
|
255
|
+
* {headVersion}` carries it): the published one, else the head. */
|
|
256
|
+
export declare function grantVersion(app: AppVersions): number;
|
|
257
|
+
/** A Versions row's trailing: the published badge, the head badge + Publish,
|
|
258
|
+
* or Preview + Publish. */
|
|
259
|
+
export declare function versionRow(app: AppVersions, number: number): `published` | `head` | `version`;
|
|
260
|
+
/** eApps R8 (#VAPP-233, fixture `migrationCases`): a version row's sweep columns. */
|
|
261
|
+
export interface VersionMigration {
|
|
262
|
+
migrationState: string | null;
|
|
263
|
+
migrationTotal: number;
|
|
264
|
+
migrationDone: number;
|
|
265
|
+
migrationError: string | null;
|
|
266
|
+
}
|
|
267
|
+
/** A Versions row's sweep line (after its subtitle), or null. */
|
|
268
|
+
export declare function versionMigration(row: VersionMigration): string | null;
|
|
269
|
+
/** #VAPP-256 (`rollbackCases`): whether publishing `target` rolls back past a
|
|
270
|
+
* version whose sweep ran, so the Publish asks first. */
|
|
271
|
+
export declare function rollbackWarns(published: number, target: number, rows: readonly {
|
|
272
|
+
number: number;
|
|
273
|
+
migrationState?: string | null;
|
|
274
|
+
}[]): boolean;
|
|
275
|
+
export declare const rollbackTitle: (n: number) => string;
|
|
276
|
+
export declare const rollbackBody: (n: number) => string;
|
|
277
|
+
/** A name → its slug: lowercase ASCII letters, digits and single dashes,
|
|
278
|
+
* diacritics stripped, cut at the cap, `app` when nothing is left; a taken
|
|
279
|
+
* slug gets `-2`, `-3`, … */
|
|
280
|
+
export declare function slugify(name: string, taken?: readonly string[]): string;
|
|
281
|
+
export interface AppListLike {
|
|
282
|
+
slug: string;
|
|
283
|
+
name: string;
|
|
284
|
+
}
|
|
285
|
+
/** The list order: by name (case-insensitive). No built-in apps. */
|
|
286
|
+
export declare function sortApps<T extends AppListLike>(apps: readonly T[]): T[];
|
|
287
|
+
/** VAPP-213: the built-in skills every app editor session runs with
|
|
288
|
+
* (fixtures/skills.json `builtin.editorDelivery`), apps first. */
|
|
289
|
+
export declare const EDITOR_SKILLS: readonly string[];
|
|
290
|
+
/** The editor WORKFLOW: what an app is and the MCP calls that read, save
|
|
291
|
+
* and publish it. ONE source: the editor brief below and the built-in
|
|
292
|
+
* `exponential-apps` skill's SKILL.md (packages/exponential-ui/scripts/
|
|
293
|
+
* generate-skills.ts) both print it. */
|
|
294
|
+
export declare function editorWorkflow(slug: string): string;
|
|
295
|
+
/** The brief an app's EDITOR SESSION gets as the preface of its first
|
|
296
|
+
* message (every new or continued session): what the app is, the MCP
|
|
297
|
+
* calls that read and publish it, and the built-in skills it runs with. */
|
|
298
|
+
export declare function editorBrief(app: {
|
|
299
|
+
name: string;
|
|
300
|
+
slug: string;
|
|
301
|
+
headVersion: number;
|
|
302
|
+
description?: string | null;
|
|
303
|
+
}): string;
|
|
304
|
+
/** VAPP-157: the app hosts' media rule (fixture `mediaPolicy`), a plain
|
|
305
|
+
* string rule so the four hosts agree byte for byte: a `data:` image, audio
|
|
306
|
+
* or video (never svg), or the instance's own `/api/attachments/<uuid>`
|
|
307
|
+
* (relative or on `origin` exactly) with nothing after the id. */
|
|
308
|
+
export declare const APP_MEDIA_POLICY: {
|
|
309
|
+
$comment: string;
|
|
310
|
+
origin: string;
|
|
311
|
+
dataMimePrefixes: string[];
|
|
312
|
+
deniedDataMimes: string[];
|
|
313
|
+
attachmentPath: string;
|
|
314
|
+
cases: {
|
|
315
|
+
src: string;
|
|
316
|
+
expected: boolean;
|
|
317
|
+
$why: string;
|
|
318
|
+
}[];
|
|
319
|
+
};
|
|
320
|
+
export declare function appMediaAllowed(src: string, origin: string): boolean;
|
|
321
|
+
/** VAPP-179: the preview's templates, sorted by id (a JSON layer, Postgres
|
|
322
|
+
* JSONB included, does not keep the declared order). */
|
|
323
|
+
export declare function previewTemplates(pkg: {
|
|
324
|
+
templates?: Record<string, unknown>;
|
|
325
|
+
} | null | undefined): string[];
|
|
326
|
+
/** The template the preview shows: the picked one while the package has it,
|
|
327
|
+
* else the first (`templateCases`). */
|
|
328
|
+
export declare function previewTemplate(pkg: {
|
|
329
|
+
templates?: Record<string, unknown>;
|
|
330
|
+
} | null | undefined, picked: string | null): string | null;
|
|
331
|
+
/** #VAPP-251 (`surfaceStateCases`): what an app's pane shows: nothing to run,
|
|
332
|
+
* the surface, or once the host had its chance and holds no surface (it
|
|
333
|
+
* refused the package), `copy.needsUpdate`. */
|
|
334
|
+
export type AppSurfaceState = `empty` | `surface` | `needsUpdate`;
|
|
335
|
+
export declare function surfaceState(hasPackage: boolean, applied: boolean, hasSurface: boolean): AppSurfaceState;
|
|
336
|
+
/** VAPP-198: one Run as option (`value` "" = me). */
|
|
337
|
+
export interface RunAsOption {
|
|
338
|
+
value: string;
|
|
339
|
+
label: string;
|
|
340
|
+
}
|
|
341
|
+
/** VAPP-198: the preview toolbar's Run as options (`runAsCases`): null
|
|
342
|
+
* unless the viewer is a team owner with another member; else Me, then
|
|
343
|
+
* every other member by name (case-insensitive, then id; no name = id). */
|
|
344
|
+
export declare function runAsOptions(members: readonly {
|
|
345
|
+
userId: string;
|
|
346
|
+
name?: string | null;
|
|
347
|
+
role: string;
|
|
348
|
+
}[], me: string | null, role: string | null): RunAsOption[] | null;
|
|
349
|
+
/** #FEED-204 (`editorDeviceCases`, the fixture's EDITOR DEVICE): the device
|
|
350
|
+
* an app editor's composer shows and sends on. `candidates` = the member's
|
|
351
|
+
* online devices (with a root: the targets a move accepts), default flagged. */
|
|
352
|
+
export interface EditorDeviceChoice {
|
|
353
|
+
/** The device; null = none online and no root to fall back on. */
|
|
354
|
+
deviceId: string | null;
|
|
355
|
+
/** A live root: the row names its device and cannot change. */
|
|
356
|
+
locked: boolean;
|
|
357
|
+
/** An ended root's next send goes to another device. */
|
|
358
|
+
move: boolean;
|
|
359
|
+
}
|
|
360
|
+
export declare function editorDevice(root: {
|
|
361
|
+
status: string;
|
|
362
|
+
deviceId: string | null;
|
|
363
|
+
} | null, candidates: readonly {
|
|
364
|
+
deviceId: string;
|
|
365
|
+
isDefault?: boolean;
|
|
366
|
+
}[], remembered: string | null): EditorDeviceChoice;
|
|
367
|
+
/** #VAPP-220 (`automationRowCases`): one row of the Settings tab's
|
|
368
|
+
* Automations group, from tRPC `appAccess.appTools` `automations`. */
|
|
369
|
+
export interface AutomationRowInput {
|
|
370
|
+
name: string;
|
|
371
|
+
on: {
|
|
372
|
+
schedule: {
|
|
373
|
+
cron: string;
|
|
374
|
+
tz?: string;
|
|
375
|
+
};
|
|
376
|
+
} | {
|
|
377
|
+
record: {
|
|
378
|
+
kind: string;
|
|
379
|
+
op: `create` | `update` | `delete`;
|
|
380
|
+
};
|
|
381
|
+
} | {
|
|
382
|
+
event: string;
|
|
383
|
+
} | {
|
|
384
|
+
webhook: {
|
|
385
|
+
name: string;
|
|
386
|
+
};
|
|
387
|
+
};
|
|
388
|
+
paused: string | null;
|
|
389
|
+
lastStatus: string | null;
|
|
390
|
+
}
|
|
391
|
+
export type AutomationStatus = `paused` | `failed` | `ok` | `never`;
|
|
392
|
+
export declare function automationRow(row: AutomationRowInput): {
|
|
393
|
+
trigger: string;
|
|
394
|
+
status: AutomationStatus;
|
|
395
|
+
label: string;
|
|
396
|
+
};
|
|
397
|
+
/** #VAPP-243 (`automationSponsorCases`): who an automation runs as, or why
|
|
398
|
+
* it is paused (a pause wins); null = the second line is the trigger alone. */
|
|
399
|
+
export declare function automationSponsor(paused: string | null, sponsorName: string | null): string | null;
|
|
400
|
+
/** #VAPP-255 (`automationDroppedCases`): the runs the rate cap dropped in the
|
|
401
|
+
* last 24 h; null = nothing to say. */
|
|
402
|
+
export declare function automationDropped(n: number): string | null;
|
|
403
|
+
/** #VAPP-238 (`webhookRowCases`): one row of the Settings tab's Webhooks
|
|
404
|
+
* group, from tRPC `appAccess.appTools` `hooks`; `isOwner` = `canToggle`. */
|
|
405
|
+
export interface WebhookRowInput {
|
|
406
|
+
name: string;
|
|
407
|
+
hasSecret: boolean;
|
|
408
|
+
}
|
|
409
|
+
export type WebhookStatus = `ready` | `unsigned`;
|
|
410
|
+
export type WebhookAction = `mint` | `rotate`;
|
|
411
|
+
export declare function webhookRow(row: WebhookRowInput, isOwner: boolean): {
|
|
412
|
+
status: WebhookStatus;
|
|
413
|
+
label: string;
|
|
414
|
+
action: WebhookAction | null;
|
|
415
|
+
actionLabel: string | null;
|
|
416
|
+
};
|
|
417
|
+
/** #VAPP-243 (`accountRowCases`): one row of the Settings tab's Accounts
|
|
418
|
+
* group, from tRPC `appAccess.appTools` `upstreams` (the viewer's own
|
|
419
|
+
* connection to each upstream the app declares). */
|
|
420
|
+
export interface AccountRowInput {
|
|
421
|
+
name: string;
|
|
422
|
+
serverId: string | null;
|
|
423
|
+
state: string | null;
|
|
424
|
+
}
|
|
425
|
+
export type AccountStatus = `notSetUp` | `connected` | `disconnected` | `connecting` | `failed` | `reconnect` | `expired`;
|
|
426
|
+
export type AccountAction = `connect` | `reconnect`;
|
|
427
|
+
export declare function accountRow(row: AccountRowInput): {
|
|
428
|
+
status: AccountStatus;
|
|
429
|
+
label: string | null;
|
|
430
|
+
action: AccountAction | null;
|
|
431
|
+
actionLabel: string | null;
|
|
432
|
+
};
|
|
433
|
+
/** #VAPP-254 (`upstreamPickerCases`): an Accounts or import row's server
|
|
434
|
+
* picker, and the second line naming the real server. */
|
|
435
|
+
export interface UpstreamPickerRow {
|
|
436
|
+
name: string;
|
|
437
|
+
serverId: string | null;
|
|
438
|
+
serverName: string | null;
|
|
439
|
+
}
|
|
440
|
+
export declare const UPSTREAM_PICKER_NONE: string;
|
|
441
|
+
export declare function upstreamPicker(row: UpstreamPickerRow, servers: readonly {
|
|
442
|
+
id: string;
|
|
443
|
+
name: string;
|
|
444
|
+
}[]): {
|
|
445
|
+
value: string;
|
|
446
|
+
options: {
|
|
447
|
+
value: string;
|
|
448
|
+
label: string;
|
|
449
|
+
}[];
|
|
450
|
+
} | null;
|
|
451
|
+
export declare function accountCaption(row: UpstreamPickerRow): string | null;
|
|
452
|
+
/** #VAPP-243 (`policyRowCases`): a kind's EFFECTIVE record policy as the
|
|
453
|
+
* Record access row's caption, ops in record-policy.json order. */
|
|
454
|
+
export type PolicyOp = `read` | `create` | `update` | `delete`;
|
|
455
|
+
export type PolicyLevel = `member` | `author` | `owners`;
|
|
456
|
+
export declare const POLICY_OPS: readonly PolicyOp[];
|
|
457
|
+
export declare function policyCaption(policy: Record<PolicyOp, PolicyLevel>): string;
|
|
458
|
+
/** The declared kinds in code-point order (the group's rows). */
|
|
459
|
+
export declare function policyKinds(records: unknown): string[];
|
|
460
|
+
/** VAPP-221 (eApps R7): the app hosts' FileUpload uploads (fixture
|
|
461
|
+
* `appFiles`): every picked file POSTs to `uploadPath` as one part
|
|
462
|
+
* `partName`; the answer's `url` lands in the FileUpload's bound list. */
|
|
463
|
+
export declare const APP_FILES: {
|
|
464
|
+
$comment: string;
|
|
465
|
+
uploadPath: string;
|
|
466
|
+
partName: string;
|
|
467
|
+
failedVerb: string;
|
|
468
|
+
failedThing: string;
|
|
469
|
+
targetCases: ({
|
|
470
|
+
$why: string;
|
|
471
|
+
name: string;
|
|
472
|
+
components: ({
|
|
473
|
+
id: string;
|
|
474
|
+
component: string;
|
|
475
|
+
children: string[];
|
|
476
|
+
name?: undefined;
|
|
477
|
+
files?: undefined;
|
|
478
|
+
} | {
|
|
479
|
+
id: string;
|
|
480
|
+
component: string;
|
|
481
|
+
name: string;
|
|
482
|
+
files: {
|
|
483
|
+
path: string;
|
|
484
|
+
};
|
|
485
|
+
children?: undefined;
|
|
486
|
+
})[];
|
|
487
|
+
expected: string;
|
|
488
|
+
} | {
|
|
489
|
+
$why: string;
|
|
490
|
+
name: string;
|
|
491
|
+
components: {
|
|
492
|
+
id: string;
|
|
493
|
+
component: string;
|
|
494
|
+
files: {
|
|
495
|
+
path: string;
|
|
496
|
+
};
|
|
497
|
+
}[];
|
|
498
|
+
expected: string;
|
|
499
|
+
} | {
|
|
500
|
+
$why: string;
|
|
501
|
+
name: string;
|
|
502
|
+
components: ({
|
|
503
|
+
id: string;
|
|
504
|
+
component: string;
|
|
505
|
+
name: string;
|
|
506
|
+
files: never[];
|
|
507
|
+
} | {
|
|
508
|
+
id: string;
|
|
509
|
+
component: string;
|
|
510
|
+
name: string;
|
|
511
|
+
files: {
|
|
512
|
+
path: string;
|
|
513
|
+
};
|
|
514
|
+
})[];
|
|
515
|
+
expected: null;
|
|
516
|
+
} | {
|
|
517
|
+
$why: string;
|
|
518
|
+
name: string;
|
|
519
|
+
components: {
|
|
520
|
+
id: string;
|
|
521
|
+
component: string;
|
|
522
|
+
name: string;
|
|
523
|
+
value: {
|
|
524
|
+
path: string;
|
|
525
|
+
};
|
|
526
|
+
}[];
|
|
527
|
+
expected: null;
|
|
528
|
+
})[];
|
|
529
|
+
urlCases: ({
|
|
530
|
+
$why: string;
|
|
531
|
+
list: {
|
|
532
|
+
name: string;
|
|
533
|
+
size: number;
|
|
534
|
+
type: string;
|
|
535
|
+
}[];
|
|
536
|
+
fileName: string;
|
|
537
|
+
url: string;
|
|
538
|
+
expected: ({
|
|
539
|
+
name: string;
|
|
540
|
+
size: number;
|
|
541
|
+
type: string;
|
|
542
|
+
url?: undefined;
|
|
543
|
+
} | {
|
|
544
|
+
name: string;
|
|
545
|
+
size: number;
|
|
546
|
+
type: string;
|
|
547
|
+
url: string;
|
|
548
|
+
})[];
|
|
549
|
+
} | {
|
|
550
|
+
$why: string;
|
|
551
|
+
list: {
|
|
552
|
+
name: string;
|
|
553
|
+
url: string;
|
|
554
|
+
}[];
|
|
555
|
+
fileName: string;
|
|
556
|
+
url: string;
|
|
557
|
+
expected: {
|
|
558
|
+
name: string;
|
|
559
|
+
url: string;
|
|
560
|
+
}[];
|
|
561
|
+
} | {
|
|
562
|
+
$why: string;
|
|
563
|
+
list: (string | {
|
|
564
|
+
name: string;
|
|
565
|
+
})[];
|
|
566
|
+
fileName: string;
|
|
567
|
+
url: string;
|
|
568
|
+
expected: (string | {
|
|
569
|
+
name: string;
|
|
570
|
+
url: string;
|
|
571
|
+
})[];
|
|
572
|
+
} | {
|
|
573
|
+
$why: string;
|
|
574
|
+
list: {
|
|
575
|
+
name: string;
|
|
576
|
+
}[];
|
|
577
|
+
fileName: string;
|
|
578
|
+
url: string;
|
|
579
|
+
expected: null;
|
|
580
|
+
} | {
|
|
581
|
+
$why: string;
|
|
582
|
+
list: null;
|
|
583
|
+
fileName: string;
|
|
584
|
+
url: string;
|
|
585
|
+
expected: null;
|
|
586
|
+
})[];
|
|
587
|
+
};
|
|
588
|
+
/** The upload url of an app (`uploadPath` with its id). */
|
|
589
|
+
export declare function appUploadPath(appId: string): string;
|
|
590
|
+
/** The absolute `files` path of the FIRST FileUpload (component order)
|
|
591
|
+
* named `name` (its `name`, else its id); null when it has no absolute
|
|
592
|
+
* `{path}` binding (`targetCases`). */
|
|
593
|
+
export declare function appUploadTarget(components: readonly Record<string, unknown>[], name: string): string | null;
|
|
594
|
+
/** `list` with `url` on every object entry named `fileName`; null = nothing
|
|
595
|
+
* to write (no list, no such entry) (`urlCases`). */
|
|
596
|
+
export declare function withUploadedUrl(list: unknown, fileName: string, url: string): unknown[] | null;
|
|
597
|
+
/** VAPP-218 (U1): the screens contract (`screens.$comment`). */
|
|
598
|
+
export declare const APPS_SCREENS: {
|
|
599
|
+
$comment: string;
|
|
600
|
+
sidebarWidth: number;
|
|
601
|
+
reserved: string[];
|
|
602
|
+
};
|
|
603
|
+
/** Which navigation the preview frame paints for a package's screens:
|
|
604
|
+
* none without screens, the phone bottom bar on a phone (or the Phone
|
|
605
|
+
* frame), else the sidebar (`screenShellCases`). */
|
|
606
|
+
export declare function screenShell(screenCount: number, phone: boolean): `sidebar` | `bar` | null;
|
|
607
|
+
/** The web deep link to an app screen: `/t/<team>/apps/<app>/<screen>`,
|
|
608
|
+
* then the params sorted by key (`screenPathCases`). */
|
|
609
|
+
export declare function screenPath(teamSlug: string, appSlug: string, screen: string, params?: Record<string, string>): string;
|
|
610
|
+
/** A screen route's query → its params: every string key but the editor's
|
|
611
|
+
* own (`screens.reserved`), sorted (`screenQueryCases`). */
|
|
612
|
+
export declare function screenParamsFromQuery(query: Record<string, unknown>): Record<string, string>;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "VAPP-260 (Engine E0, epic VAPP-259, docs/spec/apps.md §13.1): WHAT A HOST HANDS THE ENGINE, the `HostConfig`. Each key of `providers` is `required` (the Engine refuses to start without it: `missing`) or optional (absent = its `default`); `list: true` = zero or more. There is NO telemetry and NO update provider: `forbidden` keys are refused by name (`forbidden`), so an exported runner can never grow an analytics, crash-report or over-the-air channel through its config (a new package version = a rebundle, decided 2026-11-05); any other unknown key is `unknown`. `network` is one of `networkPolicies`; `identity.kind` one of `identityKinds`. A capability is mounted under its name (capabilities.json), each name once (`duplicateCapability`); an agent provider (Agents' `AgentProvider`: `acp`, `localModel`, `remoteSession`) once per id (`duplicateAgent`). `validateHostConfig(config)` -> the issues `{key, code}` in `providers` order, then forbidden and unknown keys sorted. HOSTS (`hosts`): what each host kind provides, informative and checked against the validator (each must pass). IDENTITY (`identityCases`, `engineViewer`): `member` = the signed-in member with their team role and app access (Exponential); `local` = ONE person on one device and no account (the softcoded app, eDE Local desktops, exported apps): the viewer = `{id: the device uuid, role: owner, access: write}`, so genUI's `recordRefusal` allows every op of every kind policy (`member`, `author`, `owners` all collapse to \"me\"), and records the instance writes carry the device uuid as author; `peer` = a P2P key (Spezl), judged like `member` with the key as id and role `member`. NETWORK (`networkCases`, `networkAllows`): `off` = nothing leaves the device (upstreams, `http.fetch` and a sync transport are refused `offline`); `upstreamsOnly` = the package's declared `upstreams` and the sync transport, never `http.fetch`; `any` = all three (an `http.fetch` still needs its manifest origin and consent: capabilities.json). A refusal is `{allowed: false, reason}`.",
|
|
3
|
+
"providers": {
|
|
4
|
+
"host": { "required": true, "doc": "HostInfo: host kind, platform, form factor, locale, Engine version" },
|
|
5
|
+
"storage": { "required": true, "doc": "RecordStore: query, write (writeId), history, subscribe (MemoryRecordStore, SqliteRecordStore = elocal's app-records table, SyncedRecordStore)" },
|
|
6
|
+
"blobs": { "required": true, "doc": "BlobStore: put/get record files (FsBlobStore, the server's attachments)" },
|
|
7
|
+
"identity": { "required": true, "doc": "Identity: the viewer (member, local or peer)" },
|
|
8
|
+
"vault": { "required": true, "doc": "emcp Vault: grants, upstream tokens (Keychain, Keystore, libsecret, sealed server column)" },
|
|
9
|
+
"window": { "required": true, "doc": "WindowHost: open a screen (window, nav stack, sheet), report lifecycle events" },
|
|
10
|
+
"clock": { "required": false, "default": "system", "doc": "Clock: now (tests pin it)" },
|
|
11
|
+
"zone": { "required": false, "default": "device", "doc": "HostZone: the IANA zone of today/now/month (the team's in Exponential)" },
|
|
12
|
+
"network": { "required": false, "default": "upstreamsOnly", "doc": "NetworkPolicy" },
|
|
13
|
+
"sync": { "required": false, "default": null, "doc": "SyncTransport: pull deltas, push outbox entries (Exponential: Electric in, tRPC out; Spezl: P2P); absent = writes apply locally, no outbox" },
|
|
14
|
+
"agents": { "required": false, "default": [], "list": true, "doc": "AgentProvider (Agents): acp, localModel, remoteSession; each gets its tools only as a hub grant" },
|
|
15
|
+
"capabilities": { "required": false, "default": [], "list": true, "doc": "Capability: a native tool provider on the in-process hub (capabilities.json)" },
|
|
16
|
+
"consent": { "required": false, "default": "sheet", "doc": "ConsentUi: the Engine's own genUI sheet unless the host paints it (consent.json)" }
|
|
17
|
+
},
|
|
18
|
+
"forbidden": ["analytics", "crashReporter", "telemetry", "updateChannel", "updates"],
|
|
19
|
+
"networkPolicies": ["off", "upstreamsOnly", "any"],
|
|
20
|
+
"identityKinds": ["member", "local", "peer"],
|
|
21
|
+
"hosts": {
|
|
22
|
+
"exponential": { "host": {}, "storage": {}, "blobs": {}, "identity": { "kind": "member" }, "vault": {}, "window": {}, "zone": {}, "network": "any", "sync": {}, "agents": [{ "id": "acp" }, { "id": "remoteSession" }], "capabilities": [{ "name": "files" }, { "name": "share" }, { "name": "notifications" }] },
|
|
23
|
+
"softcoded": { "host": {}, "storage": {}, "blobs": {}, "identity": { "kind": "local" }, "vault": {}, "window": {}, "network": "upstreamsOnly", "agents": [{ "id": "localModel" }] },
|
|
24
|
+
"ede": { "host": {}, "storage": {}, "blobs": {}, "identity": { "kind": "local" }, "vault": {}, "window": {}, "network": "any", "agents": [{ "id": "acp" }], "capabilities": [{ "name": "files" }, { "name": "notifications" }, { "name": "shell" }, { "name": "windows" }, { "name": "focus" }, { "name": "launch" }] },
|
|
25
|
+
"spezl": { "host": {}, "storage": {}, "blobs": {}, "identity": { "kind": "peer" }, "vault": {}, "window": {}, "network": "any", "sync": {}, "agents": [{ "id": "acp" }] },
|
|
26
|
+
"exported": { "host": {}, "storage": {}, "blobs": {}, "identity": { "kind": "local" }, "vault": {}, "window": {}, "network": "off", "capabilities": [{ "name": "photos" }, { "name": "print" }, { "name": "share" }] }
|
|
27
|
+
},
|
|
28
|
+
"validateCases": [
|
|
29
|
+
{ "name": "the minimum", "config": { "host": {}, "storage": {}, "blobs": {}, "identity": { "kind": "local" }, "vault": {}, "window": {} }, "expected": [] },
|
|
30
|
+
{ "name": "every required key missing", "config": {}, "expected": [{ "key": "host", "code": "missing" }, { "key": "storage", "code": "missing" }, { "key": "blobs", "code": "missing" }, { "key": "identity", "code": "missing" }, { "key": "vault", "code": "missing" }, { "key": "window", "code": "missing" }] },
|
|
31
|
+
{ "name": "no telemetry, no update channel", "config": { "host": {}, "storage": {}, "blobs": {}, "identity": { "kind": "local" }, "vault": {}, "window": {}, "updates": {}, "telemetry": {}, "theme": {} }, "expected": [{ "key": "telemetry", "code": "forbidden" }, { "key": "theme", "code": "unknown" }, { "key": "updates", "code": "forbidden" }] },
|
|
32
|
+
{ "name": "a bad network policy and identity kind", "config": { "host": {}, "storage": {}, "blobs": {}, "identity": { "kind": "guest" }, "vault": {}, "window": {}, "network": "lan" }, "expected": [{ "key": "identity", "code": "invalid" }, { "key": "network", "code": "invalid" }] },
|
|
33
|
+
{ "name": "a capability or agent twice", "config": { "host": {}, "storage": {}, "blobs": {}, "identity": { "kind": "member" }, "vault": {}, "window": {}, "agents": [{ "id": "acp" }, { "id": "acp" }], "capabilities": [{ "name": "photos" }, { "name": "photos" }] }, "expected": [{ "key": "agents", "code": "duplicateAgent" }, { "key": "capabilities", "code": "duplicateCapability" }] },
|
|
34
|
+
{ "name": "a capability under a reserved or invalid name", "config": { "host": {}, "storage": {}, "blobs": {}, "identity": { "kind": "member" }, "vault": {}, "window": {}, "capabilities": [{ "name": "records" }, { "name": "Bad_Name" }] }, "expected": [{ "key": "capabilities", "code": "invalidCapability" }] },
|
|
35
|
+
{ "name": "an unknown agent provider", "config": { "host": {}, "storage": {}, "blobs": {}, "identity": { "kind": "member" }, "vault": {}, "window": {}, "agents": [{ "id": "openclaw" }] }, "expected": [{ "key": "agents", "code": "invalid" }] }
|
|
36
|
+
],
|
|
37
|
+
"agentProviders": ["acp", "localModel", "remoteSession"],
|
|
38
|
+
"identityCases": [
|
|
39
|
+
{ "name": "local: an author-only update of someone else's record", "identity": { "kind": "local", "deviceId": "d-1" }, "policy": { "read": "author", "create": "owners", "update": "author", "delete": "owners" }, "op": "update", "row": { "authorId": "u-imported" }, "expected": { "viewer": { "id": "d-1", "role": "owner", "access": "write" }, "refusal": null } },
|
|
40
|
+
{ "name": "local: an owners-only delete", "identity": { "kind": "local", "deviceId": "d-1" }, "policy": { "read": "member", "create": "member", "update": "author", "delete": "owners" }, "op": "delete", "row": { "authorId": "d-1" }, "expected": { "viewer": { "id": "d-1", "role": "owner", "access": "write" }, "refusal": null } },
|
|
41
|
+
{ "name": "member: the policy applies", "identity": { "kind": "member", "userId": "u-1", "role": "member", "access": "write" }, "policy": { "read": "member", "create": "member", "update": "author", "delete": "author" }, "op": "update", "row": { "authorId": "u-2" }, "expected": { "viewer": { "id": "u-1", "role": "member", "access": "write" }, "refusal": "Only the record's author or a team owner can change it" } },
|
|
42
|
+
{ "name": "peer: a key judged as a member", "identity": { "kind": "peer", "key": "pk-9" }, "policy": { "read": "member", "create": "member", "update": "author", "delete": "author" }, "op": "update", "row": { "authorId": "pk-9" }, "expected": { "viewer": { "id": "pk-9", "role": "member", "access": "write" }, "refusal": null } }
|
|
43
|
+
],
|
|
44
|
+
"networkCases": [
|
|
45
|
+
{ "policy": "off", "target": "upstream", "declared": true, "expected": { "allowed": false, "reason": "offline" } },
|
|
46
|
+
{ "policy": "off", "target": "sync", "declared": true, "expected": { "allowed": false, "reason": "offline" } },
|
|
47
|
+
{ "policy": "off", "target": "http", "declared": true, "expected": { "allowed": false, "reason": "offline" } },
|
|
48
|
+
{ "policy": "upstreamsOnly", "target": "upstream", "declared": true, "expected": { "allowed": true, "reason": null } },
|
|
49
|
+
{ "policy": "upstreamsOnly", "target": "upstream", "declared": false, "expected": { "allowed": false, "reason": "notDeclared" } },
|
|
50
|
+
{ "policy": "upstreamsOnly", "target": "sync", "declared": true, "expected": { "allowed": true, "reason": null } },
|
|
51
|
+
{ "policy": "upstreamsOnly", "target": "http", "declared": true, "expected": { "allowed": false, "reason": "network" } },
|
|
52
|
+
{ "policy": "any", "target": "http", "declared": true, "expected": { "allowed": true, "reason": null } },
|
|
53
|
+
{ "policy": "any", "target": "upstream", "declared": false, "expected": { "allowed": false, "reason": "notDeclared" } }
|
|
54
|
+
]
|
|
55
|
+
}
|