@immediately-run/sdk 0.2.3 → 0.2.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/catalog.cjs +8 -2
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.js +8 -2
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +4 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/ipc.cjs +51 -0
- package/dist/ipc.cjs.map +1 -0
- package/dist/ipc.d.cts +18 -0
- package/dist/ipc.d.ts +18 -0
- package/dist/ipc.js +25 -0
- package/dist/ipc.js.map +1 -0
- package/dist/tasks.cjs +71 -0
- package/dist/tasks.cjs.map +1 -0
- package/dist/tasks.d.cts +47 -0
- package/dist/tasks.d.ts +47 -0
- package/dist/tasks.js +42 -0
- package/dist/tasks.js.map +1 -0
- package/package.json +1 -1
package/dist/catalog.cjs
CHANGED
|
@@ -33,9 +33,15 @@ const split = (name) => {
|
|
|
33
33
|
if (i <= 0) throw new Error(`invalid catalog method name: ${name}`);
|
|
34
34
|
return [name.slice(0, i), name.slice(i + 1)];
|
|
35
35
|
};
|
|
36
|
-
const invoke = (name, params = {}) => {
|
|
36
|
+
const invoke = async (name, params = {}) => {
|
|
37
37
|
const [scheme, method] = split(name);
|
|
38
|
-
|
|
38
|
+
const res = await (0, import_sandboxUtils.protocolRequest)(scheme, method, [params]);
|
|
39
|
+
if (!res || res.ok !== true) {
|
|
40
|
+
const err = new Error(res?.message ?? `${name} failed`);
|
|
41
|
+
err.code = res?.code ?? "unknown";
|
|
42
|
+
throw err;
|
|
43
|
+
}
|
|
44
|
+
return res.data;
|
|
39
45
|
};
|
|
40
46
|
const bundlerTransport = {
|
|
41
47
|
send: (msg) => (
|
package/dist/catalog.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/catalog.ts"],"sourcesContent":["// The method catalog (UI_AS_APPS_SPEC §5.5) — the app's own grant-filtered RPC\n// surface, and a generic way to call it. The host advertises exactly the methods\n// this app may invoke (MCP-tool-shaped); `invoke()` calls one by its catalog name.\n// Handing the catalog to an embedded agent as its tool list confines the agent to\n// the app's authority (agent sandboxing falls out of the capability model, §5.9).\nimport { useEffect, useState } from 'react';\nimport { protocolRequest } from './sandboxUtils';\nimport type { StreamFrame } from './protocolStream';\nimport { consumeStream } from './protocolStream';\n\n/** One advertised method, as the host generated it from its gate table. */\nexport interface ApiMethod {\n /** Catalog name, `protocol-` stripped — e.g. `spaces:share`, `contribute:run`. */\n name: string;\n /** The capability this method requires (already held — it's in your catalog). */\n capability: string;\n /** True when the method STREAMS (use {@link invokeStream}) vs. single-reply. */\n stream?: boolean;\n}\n\n// `scheme:method` → ['scheme', 'method'] (the wire protocol is `protocol-scheme`).\nconst split = (name: string): [string, string] => {\n const i = name.indexOf(':');\n if (i <= 0) throw new Error(`invalid catalog method name: ${name}`);\n return [name.slice(0, i), name.slice(i + 1)];\n};\n\n/**\n * Call a catalog method by name — `invoke('spaces:share', { spaceId, login, role })`.\n * A thin generic over the host protocol: the host validates params and gates the\n * call (an un-granted method → `forbidden`, even if you name it directly). For a\n * STREAMING method (`ApiMethod.stream`), use {@link invokeStream}.\n */\nexport const invoke = <T = unknown>(name: string
|
|
1
|
+
{"version":3,"sources":["../src/catalog.ts"],"sourcesContent":["// The method catalog (UI_AS_APPS_SPEC §5.5) — the app's own grant-filtered RPC\n// surface, and a generic way to call it. The host advertises exactly the methods\n// this app may invoke (MCP-tool-shaped); `invoke()` calls one by its catalog name.\n// Handing the catalog to an embedded agent as its tool list confines the agent to\n// the app's authority (agent sandboxing falls out of the capability model, §5.9).\nimport { useEffect, useState } from 'react';\nimport { protocolRequest } from './sandboxUtils';\nimport type { StreamFrame } from './protocolStream';\nimport { consumeStream } from './protocolStream';\n\n/** One advertised method, as the host generated it from its gate table. */\nexport interface ApiMethod {\n /** Catalog name, `protocol-` stripped — e.g. `spaces:share`, `contribute:run`. */\n name: string;\n /** The capability this method requires (already held — it's in your catalog). */\n capability: string;\n /** True when the method STREAMS (use {@link invokeStream}) vs. single-reply. */\n stream?: boolean;\n}\n\n// `scheme:method` → ['scheme', 'method'] (the wire protocol is `protocol-scheme`).\nconst split = (name: string): [string, string] => {\n const i = name.indexOf(':');\n if (i <= 0) throw new Error(`invalid catalog method name: ${name}`);\n return [name.slice(0, i), name.slice(i + 1)];\n};\n\n/**\n * Call a catalog method by name — `invoke('spaces:share', { spaceId, login, role })`.\n * A thin generic over the host protocol: the host validates params and gates the\n * call (an un-granted method → `forbidden`, even if you name it directly). For a\n * STREAMING method (`ApiMethod.stream`), use {@link invokeStream}.\n */\nexport const invoke = async <T = unknown>(\n name: string,\n params: Record<string, unknown> = {},\n): Promise<T> => {\n const [scheme, method] = split(name);\n // The host replies with an `{ ok, data } | { ok:false, code }` envelope; unwrap\n // it and THROW on refusal (a `.code` like `forbidden` for an off-catalog call)\n // so callers — and any agent driving `invoke` — see the gate's verdict.\n const res = (await protocolRequest(scheme, method, [params])) as\n | { ok: true; data: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? `${name} failed`) as Error & { code?: string };\n err.code = res?.code ?? 'unknown';\n throw err;\n }\n return res.data as T;\n};\n\nconst bundlerTransport = {\n send: (msg: { type: string; method: string; params: unknown[]; msgId: number; stream: true }) =>\n // @ts-ignore - injected by the sandbox runtime\n module.evaluation.module.bundler.messageBus.sendMessage(msg.type, msg),\n subscribe: (type: string, handler: (msg: { msgId?: number; stream?: StreamFrame }) => void) => {\n // @ts-ignore - injected by the sandbox runtime\n const d = module.evaluation.module.bundler.messageBus.onMessage((m: { type?: string }) => {\n if (m && m.type === type) handler(m as { msgId?: number; stream?: StreamFrame });\n });\n return () => d.dispose();\n },\n};\n\n/** Call a STREAMING catalog method by name, yielding its events. */\nexport function invokeStream<T = unknown, R = unknown>(\n name: string,\n params: Record<string, unknown> = {},\n): AsyncGenerator<T, R, void> {\n const [scheme, method] = split(name);\n return consumeStream<T, R>(bundlerTransport, `protocol-${scheme}`, method, [params]);\n}\n\ninterface CatalogService {\n getCatalog(): ApiMethod[];\n onChange(listener: (catalog: ApiMethod[]) => void): { dispose(): void };\n}\n\n// `module.evaluation.module.bundler.catalog` — injected by the sandbox runtime.\nconst catalogService = (): CatalogService => {\n // @ts-ignore - injected by the sandbox runtime\n return module.evaluation.module.bundler.catalog;\n};\n\n/** The methods this app may call (grant-filtered, §5.5). Poll for a one-off read;\n * use {@link onCatalogChange} / {@link useCatalog} to react. */\nexport const getCatalog = (): ApiMethod[] => catalogService().getCatalog();\n\n/** Subscribe to catalog changes (e.g. a grant added/revoked). Invoked immediately\n * with the current catalog, then on every change. Returns an unsubscribe fn. */\nexport const onCatalogChange = (listener: (catalog: ApiMethod[]) => void): (() => void) => {\n const disposable = catalogService().onChange(listener);\n return () => disposable.dispose();\n};\n\n/** React hook returning this app's method catalog, re-rendering on change. Hand\n * it to an embedded agent as its tool list to confine the agent to the app's\n * authority (§5.9). */\nexport const useCatalog = (): ApiMethod[] => {\n const [catalog, setCatalog] = useState<ApiMethod[]>(getCatalog);\n useEffect(() => onCatalogChange(setCatalog), []);\n return catalog;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAKA,mBAAoC;AACpC,0BAAgC;AAEhC,4BAA8B;AAa9B,MAAM,QAAQ,CAAC,SAAmC;AAChD,QAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,MAAI,KAAK,EAAG,OAAM,IAAI,MAAM,gCAAgC,IAAI,EAAE;AAClE,SAAO,CAAC,KAAK,MAAM,GAAG,CAAC,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;AAC7C;AAQO,MAAM,SAAS,OACpB,MACA,SAAkC,CAAC,MACpB;AACf,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AAInC,QAAM,MAAO,UAAM,qCAAgB,QAAQ,QAAQ,CAAC,MAAM,CAAC;AAI3D,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,GAAG,IAAI,SAAS;AACtD,QAAI,OAAO,KAAK,QAAQ;AACxB,UAAM;AAAA,EACR;AACA,SAAO,IAAI;AACb;AAEA,MAAM,mBAAmB;AAAA,EACvB,MAAM,CAAC;AAAA;AAAA,IAEL,OAAO,WAAW,OAAO,QAAQ,WAAW,YAAY,IAAI,MAAM,GAAG;AAAA;AAAA,EACvE,WAAW,CAAC,MAAc,YAAqE;AAE7F,UAAM,IAAI,OAAO,WAAW,OAAO,QAAQ,WAAW,UAAU,CAAC,MAAyB;AACxF,UAAI,KAAK,EAAE,SAAS,KAAM,SAAQ,CAA6C;AAAA,IACjF,CAAC;AACD,WAAO,MAAM,EAAE,QAAQ;AAAA,EACzB;AACF;AAGO,SAAS,aACd,MACA,SAAkC,CAAC,GACP;AAC5B,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AACnC,aAAO,qCAAoB,kBAAkB,YAAY,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC;AACrF;AAQA,MAAM,iBAAiB,MAAsB;AAE3C,SAAO,OAAO,WAAW,OAAO,QAAQ;AAC1C;AAIO,MAAM,aAAa,MAAmB,eAAe,EAAE,WAAW;AAIlE,MAAM,kBAAkB,CAAC,aAA2D;AACzF,QAAM,aAAa,eAAe,EAAE,SAAS,QAAQ;AACrD,SAAO,MAAM,WAAW,QAAQ;AAClC;AAKO,MAAM,aAAa,MAAmB;AAC3C,QAAM,CAAC,SAAS,UAAU,QAAI,uBAAsB,UAAU;AAC9D,8BAAU,MAAM,gBAAgB,UAAU,GAAG,CAAC,CAAC;AAC/C,SAAO;AACT;","names":[]}
|
package/dist/catalog.js
CHANGED
|
@@ -6,9 +6,15 @@ const split = (name) => {
|
|
|
6
6
|
if (i <= 0) throw new Error(`invalid catalog method name: ${name}`);
|
|
7
7
|
return [name.slice(0, i), name.slice(i + 1)];
|
|
8
8
|
};
|
|
9
|
-
const invoke = (name, params = {}) => {
|
|
9
|
+
const invoke = async (name, params = {}) => {
|
|
10
10
|
const [scheme, method] = split(name);
|
|
11
|
-
|
|
11
|
+
const res = await protocolRequest(scheme, method, [params]);
|
|
12
|
+
if (!res || res.ok !== true) {
|
|
13
|
+
const err = new Error(res?.message ?? `${name} failed`);
|
|
14
|
+
err.code = res?.code ?? "unknown";
|
|
15
|
+
throw err;
|
|
16
|
+
}
|
|
17
|
+
return res.data;
|
|
12
18
|
};
|
|
13
19
|
const bundlerTransport = {
|
|
14
20
|
send: (msg) => (
|
package/dist/catalog.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/catalog.ts"],"sourcesContent":["// The method catalog (UI_AS_APPS_SPEC §5.5) — the app's own grant-filtered RPC\n// surface, and a generic way to call it. The host advertises exactly the methods\n// this app may invoke (MCP-tool-shaped); `invoke()` calls one by its catalog name.\n// Handing the catalog to an embedded agent as its tool list confines the agent to\n// the app's authority (agent sandboxing falls out of the capability model, §5.9).\nimport { useEffect, useState } from 'react';\nimport { protocolRequest } from './sandboxUtils';\nimport type { StreamFrame } from './protocolStream';\nimport { consumeStream } from './protocolStream';\n\n/** One advertised method, as the host generated it from its gate table. */\nexport interface ApiMethod {\n /** Catalog name, `protocol-` stripped — e.g. `spaces:share`, `contribute:run`. */\n name: string;\n /** The capability this method requires (already held — it's in your catalog). */\n capability: string;\n /** True when the method STREAMS (use {@link invokeStream}) vs. single-reply. */\n stream?: boolean;\n}\n\n// `scheme:method` → ['scheme', 'method'] (the wire protocol is `protocol-scheme`).\nconst split = (name: string): [string, string] => {\n const i = name.indexOf(':');\n if (i <= 0) throw new Error(`invalid catalog method name: ${name}`);\n return [name.slice(0, i), name.slice(i + 1)];\n};\n\n/**\n * Call a catalog method by name — `invoke('spaces:share', { spaceId, login, role })`.\n * A thin generic over the host protocol: the host validates params and gates the\n * call (an un-granted method → `forbidden`, even if you name it directly). For a\n * STREAMING method (`ApiMethod.stream`), use {@link invokeStream}.\n */\nexport const invoke = <T = unknown>(name: string
|
|
1
|
+
{"version":3,"sources":["../src/catalog.ts"],"sourcesContent":["// The method catalog (UI_AS_APPS_SPEC §5.5) — the app's own grant-filtered RPC\n// surface, and a generic way to call it. The host advertises exactly the methods\n// this app may invoke (MCP-tool-shaped); `invoke()` calls one by its catalog name.\n// Handing the catalog to an embedded agent as its tool list confines the agent to\n// the app's authority (agent sandboxing falls out of the capability model, §5.9).\nimport { useEffect, useState } from 'react';\nimport { protocolRequest } from './sandboxUtils';\nimport type { StreamFrame } from './protocolStream';\nimport { consumeStream } from './protocolStream';\n\n/** One advertised method, as the host generated it from its gate table. */\nexport interface ApiMethod {\n /** Catalog name, `protocol-` stripped — e.g. `spaces:share`, `contribute:run`. */\n name: string;\n /** The capability this method requires (already held — it's in your catalog). */\n capability: string;\n /** True when the method STREAMS (use {@link invokeStream}) vs. single-reply. */\n stream?: boolean;\n}\n\n// `scheme:method` → ['scheme', 'method'] (the wire protocol is `protocol-scheme`).\nconst split = (name: string): [string, string] => {\n const i = name.indexOf(':');\n if (i <= 0) throw new Error(`invalid catalog method name: ${name}`);\n return [name.slice(0, i), name.slice(i + 1)];\n};\n\n/**\n * Call a catalog method by name — `invoke('spaces:share', { spaceId, login, role })`.\n * A thin generic over the host protocol: the host validates params and gates the\n * call (an un-granted method → `forbidden`, even if you name it directly). For a\n * STREAMING method (`ApiMethod.stream`), use {@link invokeStream}.\n */\nexport const invoke = async <T = unknown>(\n name: string,\n params: Record<string, unknown> = {},\n): Promise<T> => {\n const [scheme, method] = split(name);\n // The host replies with an `{ ok, data } | { ok:false, code }` envelope; unwrap\n // it and THROW on refusal (a `.code` like `forbidden` for an off-catalog call)\n // so callers — and any agent driving `invoke` — see the gate's verdict.\n const res = (await protocolRequest(scheme, method, [params])) as\n | { ok: true; data: unknown }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? `${name} failed`) as Error & { code?: string };\n err.code = res?.code ?? 'unknown';\n throw err;\n }\n return res.data as T;\n};\n\nconst bundlerTransport = {\n send: (msg: { type: string; method: string; params: unknown[]; msgId: number; stream: true }) =>\n // @ts-ignore - injected by the sandbox runtime\n module.evaluation.module.bundler.messageBus.sendMessage(msg.type, msg),\n subscribe: (type: string, handler: (msg: { msgId?: number; stream?: StreamFrame }) => void) => {\n // @ts-ignore - injected by the sandbox runtime\n const d = module.evaluation.module.bundler.messageBus.onMessage((m: { type?: string }) => {\n if (m && m.type === type) handler(m as { msgId?: number; stream?: StreamFrame });\n });\n return () => d.dispose();\n },\n};\n\n/** Call a STREAMING catalog method by name, yielding its events. */\nexport function invokeStream<T = unknown, R = unknown>(\n name: string,\n params: Record<string, unknown> = {},\n): AsyncGenerator<T, R, void> {\n const [scheme, method] = split(name);\n return consumeStream<T, R>(bundlerTransport, `protocol-${scheme}`, method, [params]);\n}\n\ninterface CatalogService {\n getCatalog(): ApiMethod[];\n onChange(listener: (catalog: ApiMethod[]) => void): { dispose(): void };\n}\n\n// `module.evaluation.module.bundler.catalog` — injected by the sandbox runtime.\nconst catalogService = (): CatalogService => {\n // @ts-ignore - injected by the sandbox runtime\n return module.evaluation.module.bundler.catalog;\n};\n\n/** The methods this app may call (grant-filtered, §5.5). Poll for a one-off read;\n * use {@link onCatalogChange} / {@link useCatalog} to react. */\nexport const getCatalog = (): ApiMethod[] => catalogService().getCatalog();\n\n/** Subscribe to catalog changes (e.g. a grant added/revoked). Invoked immediately\n * with the current catalog, then on every change. Returns an unsubscribe fn. */\nexport const onCatalogChange = (listener: (catalog: ApiMethod[]) => void): (() => void) => {\n const disposable = catalogService().onChange(listener);\n return () => disposable.dispose();\n};\n\n/** React hook returning this app's method catalog, re-rendering on change. Hand\n * it to an embedded agent as its tool list to confine the agent to the app's\n * authority (§5.9). */\nexport const useCatalog = (): ApiMethod[] => {\n const [catalog, setCatalog] = useState<ApiMethod[]>(getCatalog);\n useEffect(() => onCatalogChange(setCatalog), []);\n return catalog;\n};\n"],"mappings":"AAKA,SAAS,WAAW,gBAAgB;AACpC,SAAS,uBAAuB;AAEhC,SAAS,qBAAqB;AAa9B,MAAM,QAAQ,CAAC,SAAmC;AAChD,QAAM,IAAI,KAAK,QAAQ,GAAG;AAC1B,MAAI,KAAK,EAAG,OAAM,IAAI,MAAM,gCAAgC,IAAI,EAAE;AAClE,SAAO,CAAC,KAAK,MAAM,GAAG,CAAC,GAAG,KAAK,MAAM,IAAI,CAAC,CAAC;AAC7C;AAQO,MAAM,SAAS,OACpB,MACA,SAAkC,CAAC,MACpB;AACf,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AAInC,QAAM,MAAO,MAAM,gBAAgB,QAAQ,QAAQ,CAAC,MAAM,CAAC;AAI3D,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,GAAG,IAAI,SAAS;AACtD,QAAI,OAAO,KAAK,QAAQ;AACxB,UAAM;AAAA,EACR;AACA,SAAO,IAAI;AACb;AAEA,MAAM,mBAAmB;AAAA,EACvB,MAAM,CAAC;AAAA;AAAA,IAEL,OAAO,WAAW,OAAO,QAAQ,WAAW,YAAY,IAAI,MAAM,GAAG;AAAA;AAAA,EACvE,WAAW,CAAC,MAAc,YAAqE;AAE7F,UAAM,IAAI,OAAO,WAAW,OAAO,QAAQ,WAAW,UAAU,CAAC,MAAyB;AACxF,UAAI,KAAK,EAAE,SAAS,KAAM,SAAQ,CAA6C;AAAA,IACjF,CAAC;AACD,WAAO,MAAM,EAAE,QAAQ;AAAA,EACzB;AACF;AAGO,SAAS,aACd,MACA,SAAkC,CAAC,GACP;AAC5B,QAAM,CAAC,QAAQ,MAAM,IAAI,MAAM,IAAI;AACnC,SAAO,cAAoB,kBAAkB,YAAY,MAAM,IAAI,QAAQ,CAAC,MAAM,CAAC;AACrF;AAQA,MAAM,iBAAiB,MAAsB;AAE3C,SAAO,OAAO,WAAW,OAAO,QAAQ;AAC1C;AAIO,MAAM,aAAa,MAAmB,eAAe,EAAE,WAAW;AAIlE,MAAM,kBAAkB,CAAC,aAA2D;AACzF,QAAM,aAAa,eAAe,EAAE,SAAS,QAAQ;AACrD,SAAO,MAAM,WAAW,QAAQ;AAClC;AAKO,MAAM,aAAa,MAAmB;AAC3C,QAAM,CAAC,SAAS,UAAU,IAAI,SAAsB,UAAU;AAC9D,YAAU,MAAM,gBAAgB,UAAU,GAAG,CAAC,CAAC;AAC/C,SAAO;AACT;","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -28,6 +28,8 @@ __reExport(index_exports, require("./formFactor"), module.exports);
|
|
|
28
28
|
__reExport(index_exports, require("./mounts"), module.exports);
|
|
29
29
|
__reExport(index_exports, require("./contribute"), module.exports);
|
|
30
30
|
__reExport(index_exports, require("./catalog"), module.exports);
|
|
31
|
+
__reExport(index_exports, require("./ipc"), module.exports);
|
|
32
|
+
__reExport(index_exports, require("./tasks"), module.exports);
|
|
31
33
|
__reExport(index_exports, require("./protocolStream"), module.exports);
|
|
32
34
|
__reExport(index_exports, require("./sandboxTypes"), module.exports);
|
|
33
35
|
// Annotate the CommonJS export names for ESM import in node:
|
|
@@ -45,6 +47,8 @@ __reExport(index_exports, require("./sandboxTypes"), module.exports);
|
|
|
45
47
|
...require("./mounts"),
|
|
46
48
|
...require("./contribute"),
|
|
47
49
|
...require("./catalog"),
|
|
50
|
+
...require("./ipc"),
|
|
51
|
+
...require("./tasks"),
|
|
48
52
|
...require("./protocolStream"),
|
|
49
53
|
...require("./sandboxTypes")
|
|
50
54
|
});
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './formFactor';\nexport * from './mounts';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './protocolStream';\nexport * from './sandboxTypes';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,0BAAd;AACA,0BAAc,sBADd;AAEA,0BAAc,mBAFd;AAGA,0BAAc,iCAHd;AAIA,0BAAc,uCAJd;AAKA,0BAAc,oBALd;AAMA,0BAAc,mBANd;AAOA,0BAAc,oBAPd;AAQA,0BAAc,4BARd;AASA,0BAAc,yBATd;AAUA,0BAAc,qBAVd;AAWA,0BAAc,yBAXd;AAYA,0BAAc,sBAZd;AAaA,0BAAc,
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './formFactor';\nexport * from './mounts';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './ipc';\nexport * from './tasks';\nexport * from './protocolStream';\nexport * from './sandboxTypes';\n"],"mappings":";;;;;;;;;;;;;;;AAAA;AAAA;AAAA,0BAAc,0BAAd;AACA,0BAAc,sBADd;AAEA,0BAAc,mBAFd;AAGA,0BAAc,iCAHd;AAIA,0BAAc,uCAJd;AAKA,0BAAc,oBALd;AAMA,0BAAc,mBANd;AAOA,0BAAc,oBAPd;AAQA,0BAAc,4BARd;AASA,0BAAc,yBATd;AAUA,0BAAc,qBAVd;AAWA,0BAAc,yBAXd;AAYA,0BAAc,sBAZd;AAaA,0BAAc,kBAbd;AAcA,0BAAc,oBAdd;AAeA,0BAAc,6BAfd;AAgBA,0BAAc,2BAhBd;","names":[]}
|
package/dist/index.d.cts
CHANGED
|
@@ -11,6 +11,8 @@ export { FormFactor, FormFactorClass, Orientation, getFormFactor, onFormFactorCh
|
|
|
11
11
|
export { GrantRecord, Member, MountQuery, ResolvedUser, Role, SandboxMount, SpaceError, SpaceInfo, createSpace, findMount, getMounts, getSpaceMembers, listAllSpaces, listGrants, listSpaces, lookupUser, mount, mountSpace, onMountsChange, openAppSpace, requestMount, requestSpace, revokeGrant, setSpaceRole, shareSpace, unmountSpace, unshareSpace, useMounts, waitForMount } from './mounts.cjs';
|
|
12
12
|
export { ContributeMode, ContributeOptions, ContributionEvent, ContributionResult, contribute } from './contribute.cjs';
|
|
13
13
|
export { ApiMethod, getCatalog, invoke, invokeStream, onCatalogChange, useCatalog } from './catalog.cjs';
|
|
14
|
+
export { RegionMessage, onRegionMessage, postToRegion, useRegionMessage } from './ipc.cjs';
|
|
15
|
+
export { FileCap, TaskInput, cancelTask, capFile, completeTask, getTaskInput, invokeTask, useTaskInput } from './tasks.cjs';
|
|
14
16
|
export { StreamError, StreamFrame, StreamTransport, consumeStream, protocolStream } from './protocolStream.cjs';
|
|
15
17
|
export { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryFunction, MetadataQueryResult, ModuleExports } from './sandboxTypes.cjs';
|
|
16
18
|
import 'react';
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export { FormFactor, FormFactorClass, Orientation, getFormFactor, onFormFactorCh
|
|
|
11
11
|
export { GrantRecord, Member, MountQuery, ResolvedUser, Role, SandboxMount, SpaceError, SpaceInfo, createSpace, findMount, getMounts, getSpaceMembers, listAllSpaces, listGrants, listSpaces, lookupUser, mount, mountSpace, onMountsChange, openAppSpace, requestMount, requestSpace, revokeGrant, setSpaceRole, shareSpace, unmountSpace, unshareSpace, useMounts, waitForMount } from './mounts.js';
|
|
12
12
|
export { ContributeMode, ContributeOptions, ContributionEvent, ContributionResult, contribute } from './contribute.js';
|
|
13
13
|
export { ApiMethod, getCatalog, invoke, invokeStream, onCatalogChange, useCatalog } from './catalog.js';
|
|
14
|
+
export { RegionMessage, onRegionMessage, postToRegion, useRegionMessage } from './ipc.js';
|
|
15
|
+
export { FileCap, TaskInput, cancelTask, capFile, completeTask, getTaskInput, invokeTask, useTaskInput } from './tasks.js';
|
|
14
16
|
export { StreamError, StreamFrame, StreamTransport, consumeStream, protocolStream } from './protocolStream.js';
|
|
15
17
|
export { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryFunction, MetadataQueryResult, ModuleExports } from './sandboxTypes.js';
|
|
16
18
|
import 'react';
|
package/dist/index.js
CHANGED
|
@@ -11,6 +11,8 @@ export * from "./formFactor";
|
|
|
11
11
|
export * from "./mounts";
|
|
12
12
|
export * from "./contribute";
|
|
13
13
|
export * from "./catalog";
|
|
14
|
+
export * from "./ipc";
|
|
15
|
+
export * from "./tasks";
|
|
14
16
|
export * from "./protocolStream";
|
|
15
17
|
export * from "./sandboxTypes";
|
|
16
18
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './formFactor';\nexport * from './mounts';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './protocolStream';\nexport * from './sandboxTypes';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["export * from \"./MDXProvider\";\nexport * from \"./routing\";\nexport * from \"./boot\";\nexport * from './components/Include';\nexport * from './components/MDXComponents';\nexport * from './hooks'\nexport * from './auth';\nexport * from './theme';\nexport * from './editorContext';\nexport * from './formFactor';\nexport * from './mounts';\nexport * from './contribute';\nexport * from './catalog';\nexport * from './ipc';\nexport * from './tasks';\nexport * from './protocolStream';\nexport * from './sandboxTypes';\n"],"mappings":"AAAA,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;AACd,cAAc;","names":[]}
|
package/dist/ipc.cjs
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var ipc_exports = {};
|
|
20
|
+
__export(ipc_exports, {
|
|
21
|
+
onRegionMessage: () => onRegionMessage,
|
|
22
|
+
postToRegion: () => postToRegion,
|
|
23
|
+
useRegionMessage: () => useRegionMessage
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(ipc_exports);
|
|
26
|
+
var import_react = require("react");
|
|
27
|
+
var import_sandboxUtils = require("./sandboxUtils");
|
|
28
|
+
const postToRegion = async (region, data) => {
|
|
29
|
+
const res = await (0, import_sandboxUtils.protocolRequest)("ipc", "post", [{ to: region, msg: data }]);
|
|
30
|
+
if (!res || res.ok !== true) {
|
|
31
|
+
const err = new Error(res?.message ?? "ipc post failed");
|
|
32
|
+
err.code = res?.code ?? "unknown";
|
|
33
|
+
throw err;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const onRegionMessage = (listener) => (0, import_sandboxUtils.addListener)(
|
|
37
|
+
"region-message",
|
|
38
|
+
(m) => listener({ from: m.from, data: m.data })
|
|
39
|
+
);
|
|
40
|
+
const useRegionMessage = () => {
|
|
41
|
+
const [msg, setMsg] = (0, import_react.useState)(null);
|
|
42
|
+
(0, import_react.useEffect)(() => onRegionMessage(setMsg), []);
|
|
43
|
+
return msg;
|
|
44
|
+
};
|
|
45
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
46
|
+
0 && (module.exports = {
|
|
47
|
+
onRegionMessage,
|
|
48
|
+
postToRegion,
|
|
49
|
+
useRegionMessage
|
|
50
|
+
});
|
|
51
|
+
//# sourceMappingURL=ipc.cjs.map
|
package/dist/ipc.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ipc.ts"],"sourcesContent":["// Inter-app messaging (UI_AS_APPS_SPEC §5.6) — L2: chrome panels/regions talk to\n// each other across an edge BOTH sides declared in their bindings (sender `ipc.to`\n// + the `ipc` capability; receiver `ipc.accepts`). The host enforces both halves\n// and attaches an unspoofable `from`; you still treat the payload as untrusted.\nimport { useEffect, useState } from 'react';\nimport { protocolRequest, addListener } from './sandboxUtils';\n\n/** A message delivered to this region. `from` is the SENDER's region, attached by\n * the host (unspoofable, T19); `data` is the sender-provided payload. */\nexport interface RegionMessage {\n from: string;\n data: unknown;\n}\n\n/**\n * Send a message to another region. Resolves when delivered; rejects (`forbidden`)\n * if the edge isn't two-sided-consented, the target isn't mounted, or this app\n * lacks the `ipc` capability.\n */\nexport const postToRegion = async (region: string, data: unknown): Promise<void> => {\n const res = (await protocolRequest('ipc', 'post', [{ to: region, msg: data }])) as\n | { ok: true }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'ipc post failed') as Error & { code?: string };\n err.code = res?.code ?? 'unknown';\n throw err;\n }\n};\n\n/** Subscribe to inbound region messages. Returns an unsubscribe fn. */\nexport const onRegionMessage = (listener: (msg: RegionMessage) => void): (() => void) =>\n addListener('region-message', (m: { from: string; data: unknown }) =>\n listener({ from: m.from, data: m.data }),\n );\n\n/** React hook: the most recent inbound region message (or `null`). */\nexport const useRegionMessage = (): RegionMessage | null => {\n const [msg, setMsg] = useState<RegionMessage | null>(null);\n useEffect(() => onRegionMessage(setMsg), []);\n return msg;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAIA,mBAAoC;AACpC,0BAA6C;AActC,MAAM,eAAe,OAAO,QAAgB,SAAiC;AAClF,QAAM,MAAO,UAAM,qCAAgB,OAAO,QAAQ,CAAC,EAAE,IAAI,QAAQ,KAAK,KAAK,CAAC,CAAC;AAI7E,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,iBAAiB;AACvD,QAAI,OAAO,KAAK,QAAQ;AACxB,UAAM;AAAA,EACR;AACF;AAGO,MAAM,kBAAkB,CAAC,iBAC9B;AAAA,EAAY;AAAA,EAAkB,CAAC,MAC7B,SAAS,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,KAAK,CAAC;AACzC;AAGK,MAAM,mBAAmB,MAA4B;AAC1D,QAAM,CAAC,KAAK,MAAM,QAAI,uBAA+B,IAAI;AACzD,8BAAU,MAAM,gBAAgB,MAAM,GAAG,CAAC,CAAC;AAC3C,SAAO;AACT;","names":[]}
|
package/dist/ipc.d.cts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** A message delivered to this region. `from` is the SENDER's region, attached by
|
|
2
|
+
* the host (unspoofable, T19); `data` is the sender-provided payload. */
|
|
3
|
+
interface RegionMessage {
|
|
4
|
+
from: string;
|
|
5
|
+
data: unknown;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Send a message to another region. Resolves when delivered; rejects (`forbidden`)
|
|
9
|
+
* if the edge isn't two-sided-consented, the target isn't mounted, or this app
|
|
10
|
+
* lacks the `ipc` capability.
|
|
11
|
+
*/
|
|
12
|
+
declare const postToRegion: (region: string, data: unknown) => Promise<void>;
|
|
13
|
+
/** Subscribe to inbound region messages. Returns an unsubscribe fn. */
|
|
14
|
+
declare const onRegionMessage: (listener: (msg: RegionMessage) => void) => (() => void);
|
|
15
|
+
/** React hook: the most recent inbound region message (or `null`). */
|
|
16
|
+
declare const useRegionMessage: () => RegionMessage | null;
|
|
17
|
+
|
|
18
|
+
export { type RegionMessage, onRegionMessage, postToRegion, useRegionMessage };
|
package/dist/ipc.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** A message delivered to this region. `from` is the SENDER's region, attached by
|
|
2
|
+
* the host (unspoofable, T19); `data` is the sender-provided payload. */
|
|
3
|
+
interface RegionMessage {
|
|
4
|
+
from: string;
|
|
5
|
+
data: unknown;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Send a message to another region. Resolves when delivered; rejects (`forbidden`)
|
|
9
|
+
* if the edge isn't two-sided-consented, the target isn't mounted, or this app
|
|
10
|
+
* lacks the `ipc` capability.
|
|
11
|
+
*/
|
|
12
|
+
declare const postToRegion: (region: string, data: unknown) => Promise<void>;
|
|
13
|
+
/** Subscribe to inbound region messages. Returns an unsubscribe fn. */
|
|
14
|
+
declare const onRegionMessage: (listener: (msg: RegionMessage) => void) => (() => void);
|
|
15
|
+
/** React hook: the most recent inbound region message (or `null`). */
|
|
16
|
+
declare const useRegionMessage: () => RegionMessage | null;
|
|
17
|
+
|
|
18
|
+
export { type RegionMessage, onRegionMessage, postToRegion, useRegionMessage };
|
package/dist/ipc.js
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { protocolRequest, addListener } from "./sandboxUtils";
|
|
3
|
+
const postToRegion = async (region, data) => {
|
|
4
|
+
const res = await protocolRequest("ipc", "post", [{ to: region, msg: data }]);
|
|
5
|
+
if (!res || res.ok !== true) {
|
|
6
|
+
const err = new Error(res?.message ?? "ipc post failed");
|
|
7
|
+
err.code = res?.code ?? "unknown";
|
|
8
|
+
throw err;
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const onRegionMessage = (listener) => addListener(
|
|
12
|
+
"region-message",
|
|
13
|
+
(m) => listener({ from: m.from, data: m.data })
|
|
14
|
+
);
|
|
15
|
+
const useRegionMessage = () => {
|
|
16
|
+
const [msg, setMsg] = useState(null);
|
|
17
|
+
useEffect(() => onRegionMessage(setMsg), []);
|
|
18
|
+
return msg;
|
|
19
|
+
};
|
|
20
|
+
export {
|
|
21
|
+
onRegionMessage,
|
|
22
|
+
postToRegion,
|
|
23
|
+
useRegionMessage
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=ipc.js.map
|
package/dist/ipc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/ipc.ts"],"sourcesContent":["// Inter-app messaging (UI_AS_APPS_SPEC §5.6) — L2: chrome panels/regions talk to\n// each other across an edge BOTH sides declared in their bindings (sender `ipc.to`\n// + the `ipc` capability; receiver `ipc.accepts`). The host enforces both halves\n// and attaches an unspoofable `from`; you still treat the payload as untrusted.\nimport { useEffect, useState } from 'react';\nimport { protocolRequest, addListener } from './sandboxUtils';\n\n/** A message delivered to this region. `from` is the SENDER's region, attached by\n * the host (unspoofable, T19); `data` is the sender-provided payload. */\nexport interface RegionMessage {\n from: string;\n data: unknown;\n}\n\n/**\n * Send a message to another region. Resolves when delivered; rejects (`forbidden`)\n * if the edge isn't two-sided-consented, the target isn't mounted, or this app\n * lacks the `ipc` capability.\n */\nexport const postToRegion = async (region: string, data: unknown): Promise<void> => {\n const res = (await protocolRequest('ipc', 'post', [{ to: region, msg: data }])) as\n | { ok: true }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? 'ipc post failed') as Error & { code?: string };\n err.code = res?.code ?? 'unknown';\n throw err;\n }\n};\n\n/** Subscribe to inbound region messages. Returns an unsubscribe fn. */\nexport const onRegionMessage = (listener: (msg: RegionMessage) => void): (() => void) =>\n addListener('region-message', (m: { from: string; data: unknown }) =>\n listener({ from: m.from, data: m.data }),\n );\n\n/** React hook: the most recent inbound region message (or `null`). */\nexport const useRegionMessage = (): RegionMessage | null => {\n const [msg, setMsg] = useState<RegionMessage | null>(null);\n useEffect(() => onRegionMessage(setMsg), []);\n return msg;\n};\n"],"mappings":"AAIA,SAAS,WAAW,gBAAgB;AACpC,SAAS,iBAAiB,mBAAmB;AActC,MAAM,eAAe,OAAO,QAAgB,SAAiC;AAClF,QAAM,MAAO,MAAM,gBAAgB,OAAO,QAAQ,CAAC,EAAE,IAAI,QAAQ,KAAK,KAAK,CAAC,CAAC;AAI7E,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,iBAAiB;AACvD,QAAI,OAAO,KAAK,QAAQ;AACxB,UAAM;AAAA,EACR;AACF;AAGO,MAAM,kBAAkB,CAAC,aAC9B;AAAA,EAAY;AAAA,EAAkB,CAAC,MAC7B,SAAS,EAAE,MAAM,EAAE,MAAM,MAAM,EAAE,KAAK,CAAC;AACzC;AAGK,MAAM,mBAAmB,MAA4B;AAC1D,QAAM,CAAC,KAAK,MAAM,IAAI,SAA+B,IAAI;AACzD,YAAU,MAAM,gBAAgB,MAAM,GAAG,CAAC,CAAC;AAC3C,SAAO;AACT;","names":[]}
|
package/dist/tasks.cjs
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var tasks_exports = {};
|
|
20
|
+
__export(tasks_exports, {
|
|
21
|
+
cancelTask: () => cancelTask,
|
|
22
|
+
capFile: () => capFile,
|
|
23
|
+
completeTask: () => completeTask,
|
|
24
|
+
getTaskInput: () => getTaskInput,
|
|
25
|
+
invokeTask: () => invokeTask,
|
|
26
|
+
useTaskInput: () => useTaskInput
|
|
27
|
+
});
|
|
28
|
+
module.exports = __toCommonJS(tasks_exports);
|
|
29
|
+
var import_react = require("react");
|
|
30
|
+
var import_sandboxUtils = require("./sandboxUtils");
|
|
31
|
+
const capFile = (ref, opts) => ({ $cap: "file", mountId: ref.mountId, relPath: ref.relPath, mode: opts.mode });
|
|
32
|
+
const invokeTask = async (task, params = {}) => {
|
|
33
|
+
const res = await (0, import_sandboxUtils.protocolRequest)("task", "invoke", [{ task, params }]);
|
|
34
|
+
if (!res || res.ok !== true) {
|
|
35
|
+
const err = new Error(res?.message ?? `task '${task}' failed`);
|
|
36
|
+
err.code = res?.code ?? "unknown";
|
|
37
|
+
throw err;
|
|
38
|
+
}
|
|
39
|
+
return res.data;
|
|
40
|
+
};
|
|
41
|
+
let latestInput = null;
|
|
42
|
+
const inputListeners = /* @__PURE__ */ new Set();
|
|
43
|
+
(0, import_sandboxUtils.addListener)("task-input", (m) => {
|
|
44
|
+
latestInput = { task: m.task, params: m.params ?? {} };
|
|
45
|
+
inputListeners.forEach((l) => l(latestInput));
|
|
46
|
+
});
|
|
47
|
+
const getTaskInput = () => latestInput;
|
|
48
|
+
const completeTask = (result) => (0, import_sandboxUtils.sendMessage)("task-complete", { result });
|
|
49
|
+
const cancelTask = () => (0, import_sandboxUtils.sendMessage)("task-cancel", {});
|
|
50
|
+
const useTaskInput = () => {
|
|
51
|
+
const [input, setInput] = (0, import_react.useState)(getTaskInput);
|
|
52
|
+
(0, import_react.useEffect)(() => {
|
|
53
|
+
const l = (i) => setInput(i);
|
|
54
|
+
inputListeners.add(l);
|
|
55
|
+
if (latestInput) setInput(latestInput);
|
|
56
|
+
return () => {
|
|
57
|
+
inputListeners.delete(l);
|
|
58
|
+
};
|
|
59
|
+
}, []);
|
|
60
|
+
return input;
|
|
61
|
+
};
|
|
62
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
63
|
+
0 && (module.exports = {
|
|
64
|
+
cancelTask,
|
|
65
|
+
capFile,
|
|
66
|
+
completeTask,
|
|
67
|
+
getTaskInput,
|
|
68
|
+
invokeTask,
|
|
69
|
+
useTaskInput
|
|
70
|
+
});
|
|
71
|
+
//# sourceMappingURL=tasks.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tasks.ts"],"sourcesContent":["// Task invocation — apps invoking apps (UI_AS_APPS_SPEC §5.7). The\n// `startActivityForResult` pattern: one app invokes another by TASK CONTRACT\n// (never by app name — the user's override picks the bound app), passes typed\n// params, and awaits a typed result. The callee runs in a host-owned overlay\n// under ITS OWN grants — data crosses, your authority does not (§5.7).\n//\n// Two roles:\n// - CALLER: `invokeTask(task, params)` (Recipe B — a deferred reply the host\n// holds open until the callee finishes). Delegate a file with `capFile(...)`:\n// the host resolves it against YOUR grants and mints an attenuated chroot.\n// - CALLEE: read `useTaskInput()`, then `completeTask(result)` / `cancelTask()`.\nimport { useEffect, useState } from 'react';\nimport { protocolRequest, sendMessage, addListener } from './sandboxUtils';\n\n// ── caller side ─────────────────────────────────────────────────────────────\n\n/** A delegated FILE capability marker for a task param (§5.7). */\nexport interface FileCap {\n $cap: 'file';\n mountId: string;\n relPath: string;\n mode: 'ro' | 'rw';\n}\n\n/**\n * Build a delegated file reference for a task param. The host resolves it against\n * YOUR OWN grants and mints an attenuated, task-scoped chroot for the callee — you\n * can only delegate a path you already hold (attenuation only, never escalation).\n *\n * file: capFile({ mountId: 'space:abc', relPath: 'photos/cat.jpg' }, { mode: 'rw' })\n */\nexport const capFile = (\n ref: { mountId: string; relPath: string },\n opts: { mode: 'ro' | 'rw' },\n): FileCap => ({ $cap: 'file', mountId: ref.mountId, relPath: ref.relPath, mode: opts.mode });\n\n/**\n * Invoke another app via a task contract and await its typed result (Recipe B).\n * Rejects with a machine `.code` on refusal: `cancelled` (user dismissed the\n * overlay), `timeout` (§5.7.1 liveness), `forbidden` (undeclared task or a file\n * delegation you don't hold), `no-such-task`, `task-cycle`/`task-depth-exceeded`/\n * `task-version-mismatch`, or `invalid-params` (result failed the contract schema).\n */\nexport const invokeTask = async <R = unknown>(\n task: string,\n params: Record<string, unknown> = {},\n): Promise<R> => {\n const res = (await protocolRequest('task', 'invoke', [{ task, params }])) as\n | { ok: true; data: R }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? `task '${task}' failed`) as Error & { code?: string };\n err.code = res?.code ?? 'unknown';\n throw err;\n }\n return res.data;\n};\n\n// ── callee side ─────────────────────────────────────────────────────────────\n\n/** The params this app was invoked with as a task callee. */\nexport interface TaskInput {\n task: string;\n params: Record<string, unknown>;\n}\n\nlet latestInput: TaskInput | null = null;\nconst inputListeners = new Set<(i: TaskInput) => void>();\n\n// The host delivers a `task-input` message to the callee's iframe right after it\n// mounts the overlay (the §5.7 \"params via the region's mount event\").\naddListener('task-input', (m: { task: string; params?: Record<string, unknown> }) => {\n latestInput = { task: m.task, params: m.params ?? {} };\n inputListeners.forEach((l) => l(latestInput!));\n});\n\n/** The task params this app was invoked with, or null if it isn't a task callee. */\nexport const getTaskInput = (): TaskInput | null => latestInput;\n\n/**\n * Finish the task, returning a result to the caller. The host validates it against\n * the contract's result schema before resolving the caller (`invalid-params` on\n * violation), then tears down this overlay.\n */\nexport const completeTask = (result: unknown): void => sendMessage('task-complete', { result });\n\n/** Abort the task; the caller's `invokeTask` rejects with `cancelled`. */\nexport const cancelTask = (): void => sendMessage('task-cancel', {});\n\n/** React hook: the task input for this callee, re-rendering when it arrives. */\nexport const useTaskInput = (): TaskInput | null => {\n const [input, setInput] = useState<TaskInput | null>(getTaskInput);\n useEffect(() => {\n const l = (i: TaskInput) => setInput(i);\n inputListeners.add(l);\n if (latestInput) setInput(latestInput);\n return () => {\n inputListeners.delete(l);\n };\n }, []);\n return input;\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAWA,mBAAoC;AACpC,0BAA0D;AAmBnD,MAAM,UAAU,CACrB,KACA,UACa,EAAE,MAAM,QAAQ,SAAS,IAAI,SAAS,SAAS,IAAI,SAAS,MAAM,KAAK,KAAK;AASpF,MAAM,aAAa,OACxB,MACA,SAAkC,CAAC,MACpB;AACf,QAAM,MAAO,UAAM,qCAAgB,QAAQ,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,CAAC;AAIvE,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,SAAS,IAAI,UAAU;AAC7D,QAAI,OAAO,KAAK,QAAQ;AACxB,UAAM;AAAA,EACR;AACA,SAAO,IAAI;AACb;AAUA,IAAI,cAAgC;AACpC,MAAM,iBAAiB,oBAAI,IAA4B;AAAA,IAIvD,iCAAY,cAAc,CAAC,MAA0D;AACnF,gBAAc,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,UAAU,CAAC,EAAE;AACrD,iBAAe,QAAQ,CAAC,MAAM,EAAE,WAAY,CAAC;AAC/C,CAAC;AAGM,MAAM,eAAe,MAAwB;AAO7C,MAAM,eAAe,CAAC,eAA0B,iCAAY,iBAAiB,EAAE,OAAO,CAAC;AAGvF,MAAM,aAAa,UAAY,iCAAY,eAAe,CAAC,CAAC;AAG5D,MAAM,eAAe,MAAwB;AAClD,QAAM,CAAC,OAAO,QAAQ,QAAI,uBAA2B,YAAY;AACjE,8BAAU,MAAM;AACd,UAAM,IAAI,CAAC,MAAiB,SAAS,CAAC;AACtC,mBAAe,IAAI,CAAC;AACpB,QAAI,YAAa,UAAS,WAAW;AACrC,WAAO,MAAM;AACX,qBAAe,OAAO,CAAC;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,CAAC;AACL,SAAO;AACT;","names":[]}
|
package/dist/tasks.d.cts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** A delegated FILE capability marker for a task param (§5.7). */
|
|
2
|
+
interface FileCap {
|
|
3
|
+
$cap: 'file';
|
|
4
|
+
mountId: string;
|
|
5
|
+
relPath: string;
|
|
6
|
+
mode: 'ro' | 'rw';
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Build a delegated file reference for a task param. The host resolves it against
|
|
10
|
+
* YOUR OWN grants and mints an attenuated, task-scoped chroot for the callee — you
|
|
11
|
+
* can only delegate a path you already hold (attenuation only, never escalation).
|
|
12
|
+
*
|
|
13
|
+
* file: capFile({ mountId: 'space:abc', relPath: 'photos/cat.jpg' }, { mode: 'rw' })
|
|
14
|
+
*/
|
|
15
|
+
declare const capFile: (ref: {
|
|
16
|
+
mountId: string;
|
|
17
|
+
relPath: string;
|
|
18
|
+
}, opts: {
|
|
19
|
+
mode: "ro" | "rw";
|
|
20
|
+
}) => FileCap;
|
|
21
|
+
/**
|
|
22
|
+
* Invoke another app via a task contract and await its typed result (Recipe B).
|
|
23
|
+
* Rejects with a machine `.code` on refusal: `cancelled` (user dismissed the
|
|
24
|
+
* overlay), `timeout` (§5.7.1 liveness), `forbidden` (undeclared task or a file
|
|
25
|
+
* delegation you don't hold), `no-such-task`, `task-cycle`/`task-depth-exceeded`/
|
|
26
|
+
* `task-version-mismatch`, or `invalid-params` (result failed the contract schema).
|
|
27
|
+
*/
|
|
28
|
+
declare const invokeTask: <R = unknown>(task: string, params?: Record<string, unknown>) => Promise<R>;
|
|
29
|
+
/** The params this app was invoked with as a task callee. */
|
|
30
|
+
interface TaskInput {
|
|
31
|
+
task: string;
|
|
32
|
+
params: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
/** The task params this app was invoked with, or null if it isn't a task callee. */
|
|
35
|
+
declare const getTaskInput: () => TaskInput | null;
|
|
36
|
+
/**
|
|
37
|
+
* Finish the task, returning a result to the caller. The host validates it against
|
|
38
|
+
* the contract's result schema before resolving the caller (`invalid-params` on
|
|
39
|
+
* violation), then tears down this overlay.
|
|
40
|
+
*/
|
|
41
|
+
declare const completeTask: (result: unknown) => void;
|
|
42
|
+
/** Abort the task; the caller's `invokeTask` rejects with `cancelled`. */
|
|
43
|
+
declare const cancelTask: () => void;
|
|
44
|
+
/** React hook: the task input for this callee, re-rendering when it arrives. */
|
|
45
|
+
declare const useTaskInput: () => TaskInput | null;
|
|
46
|
+
|
|
47
|
+
export { type FileCap, type TaskInput, cancelTask, capFile, completeTask, getTaskInput, invokeTask, useTaskInput };
|
package/dist/tasks.d.ts
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/** A delegated FILE capability marker for a task param (§5.7). */
|
|
2
|
+
interface FileCap {
|
|
3
|
+
$cap: 'file';
|
|
4
|
+
mountId: string;
|
|
5
|
+
relPath: string;
|
|
6
|
+
mode: 'ro' | 'rw';
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Build a delegated file reference for a task param. The host resolves it against
|
|
10
|
+
* YOUR OWN grants and mints an attenuated, task-scoped chroot for the callee — you
|
|
11
|
+
* can only delegate a path you already hold (attenuation only, never escalation).
|
|
12
|
+
*
|
|
13
|
+
* file: capFile({ mountId: 'space:abc', relPath: 'photos/cat.jpg' }, { mode: 'rw' })
|
|
14
|
+
*/
|
|
15
|
+
declare const capFile: (ref: {
|
|
16
|
+
mountId: string;
|
|
17
|
+
relPath: string;
|
|
18
|
+
}, opts: {
|
|
19
|
+
mode: "ro" | "rw";
|
|
20
|
+
}) => FileCap;
|
|
21
|
+
/**
|
|
22
|
+
* Invoke another app via a task contract and await its typed result (Recipe B).
|
|
23
|
+
* Rejects with a machine `.code` on refusal: `cancelled` (user dismissed the
|
|
24
|
+
* overlay), `timeout` (§5.7.1 liveness), `forbidden` (undeclared task or a file
|
|
25
|
+
* delegation you don't hold), `no-such-task`, `task-cycle`/`task-depth-exceeded`/
|
|
26
|
+
* `task-version-mismatch`, or `invalid-params` (result failed the contract schema).
|
|
27
|
+
*/
|
|
28
|
+
declare const invokeTask: <R = unknown>(task: string, params?: Record<string, unknown>) => Promise<R>;
|
|
29
|
+
/** The params this app was invoked with as a task callee. */
|
|
30
|
+
interface TaskInput {
|
|
31
|
+
task: string;
|
|
32
|
+
params: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
/** The task params this app was invoked with, or null if it isn't a task callee. */
|
|
35
|
+
declare const getTaskInput: () => TaskInput | null;
|
|
36
|
+
/**
|
|
37
|
+
* Finish the task, returning a result to the caller. The host validates it against
|
|
38
|
+
* the contract's result schema before resolving the caller (`invalid-params` on
|
|
39
|
+
* violation), then tears down this overlay.
|
|
40
|
+
*/
|
|
41
|
+
declare const completeTask: (result: unknown) => void;
|
|
42
|
+
/** Abort the task; the caller's `invokeTask` rejects with `cancelled`. */
|
|
43
|
+
declare const cancelTask: () => void;
|
|
44
|
+
/** React hook: the task input for this callee, re-rendering when it arrives. */
|
|
45
|
+
declare const useTaskInput: () => TaskInput | null;
|
|
46
|
+
|
|
47
|
+
export { type FileCap, type TaskInput, cancelTask, capFile, completeTask, getTaskInput, invokeTask, useTaskInput };
|
package/dist/tasks.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { useEffect, useState } from "react";
|
|
2
|
+
import { protocolRequest, sendMessage, addListener } from "./sandboxUtils";
|
|
3
|
+
const capFile = (ref, opts) => ({ $cap: "file", mountId: ref.mountId, relPath: ref.relPath, mode: opts.mode });
|
|
4
|
+
const invokeTask = async (task, params = {}) => {
|
|
5
|
+
const res = await protocolRequest("task", "invoke", [{ task, params }]);
|
|
6
|
+
if (!res || res.ok !== true) {
|
|
7
|
+
const err = new Error(res?.message ?? `task '${task}' failed`);
|
|
8
|
+
err.code = res?.code ?? "unknown";
|
|
9
|
+
throw err;
|
|
10
|
+
}
|
|
11
|
+
return res.data;
|
|
12
|
+
};
|
|
13
|
+
let latestInput = null;
|
|
14
|
+
const inputListeners = /* @__PURE__ */ new Set();
|
|
15
|
+
addListener("task-input", (m) => {
|
|
16
|
+
latestInput = { task: m.task, params: m.params ?? {} };
|
|
17
|
+
inputListeners.forEach((l) => l(latestInput));
|
|
18
|
+
});
|
|
19
|
+
const getTaskInput = () => latestInput;
|
|
20
|
+
const completeTask = (result) => sendMessage("task-complete", { result });
|
|
21
|
+
const cancelTask = () => sendMessage("task-cancel", {});
|
|
22
|
+
const useTaskInput = () => {
|
|
23
|
+
const [input, setInput] = useState(getTaskInput);
|
|
24
|
+
useEffect(() => {
|
|
25
|
+
const l = (i) => setInput(i);
|
|
26
|
+
inputListeners.add(l);
|
|
27
|
+
if (latestInput) setInput(latestInput);
|
|
28
|
+
return () => {
|
|
29
|
+
inputListeners.delete(l);
|
|
30
|
+
};
|
|
31
|
+
}, []);
|
|
32
|
+
return input;
|
|
33
|
+
};
|
|
34
|
+
export {
|
|
35
|
+
cancelTask,
|
|
36
|
+
capFile,
|
|
37
|
+
completeTask,
|
|
38
|
+
getTaskInput,
|
|
39
|
+
invokeTask,
|
|
40
|
+
useTaskInput
|
|
41
|
+
};
|
|
42
|
+
//# sourceMappingURL=tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/tasks.ts"],"sourcesContent":["// Task invocation — apps invoking apps (UI_AS_APPS_SPEC §5.7). The\n// `startActivityForResult` pattern: one app invokes another by TASK CONTRACT\n// (never by app name — the user's override picks the bound app), passes typed\n// params, and awaits a typed result. The callee runs in a host-owned overlay\n// under ITS OWN grants — data crosses, your authority does not (§5.7).\n//\n// Two roles:\n// - CALLER: `invokeTask(task, params)` (Recipe B — a deferred reply the host\n// holds open until the callee finishes). Delegate a file with `capFile(...)`:\n// the host resolves it against YOUR grants and mints an attenuated chroot.\n// - CALLEE: read `useTaskInput()`, then `completeTask(result)` / `cancelTask()`.\nimport { useEffect, useState } from 'react';\nimport { protocolRequest, sendMessage, addListener } from './sandboxUtils';\n\n// ── caller side ─────────────────────────────────────────────────────────────\n\n/** A delegated FILE capability marker for a task param (§5.7). */\nexport interface FileCap {\n $cap: 'file';\n mountId: string;\n relPath: string;\n mode: 'ro' | 'rw';\n}\n\n/**\n * Build a delegated file reference for a task param. The host resolves it against\n * YOUR OWN grants and mints an attenuated, task-scoped chroot for the callee — you\n * can only delegate a path you already hold (attenuation only, never escalation).\n *\n * file: capFile({ mountId: 'space:abc', relPath: 'photos/cat.jpg' }, { mode: 'rw' })\n */\nexport const capFile = (\n ref: { mountId: string; relPath: string },\n opts: { mode: 'ro' | 'rw' },\n): FileCap => ({ $cap: 'file', mountId: ref.mountId, relPath: ref.relPath, mode: opts.mode });\n\n/**\n * Invoke another app via a task contract and await its typed result (Recipe B).\n * Rejects with a machine `.code` on refusal: `cancelled` (user dismissed the\n * overlay), `timeout` (§5.7.1 liveness), `forbidden` (undeclared task or a file\n * delegation you don't hold), `no-such-task`, `task-cycle`/`task-depth-exceeded`/\n * `task-version-mismatch`, or `invalid-params` (result failed the contract schema).\n */\nexport const invokeTask = async <R = unknown>(\n task: string,\n params: Record<string, unknown> = {},\n): Promise<R> => {\n const res = (await protocolRequest('task', 'invoke', [{ task, params }])) as\n | { ok: true; data: R }\n | { ok: false; code?: string; message?: string }\n | undefined;\n if (!res || res.ok !== true) {\n const err = new Error(res?.message ?? `task '${task}' failed`) as Error & { code?: string };\n err.code = res?.code ?? 'unknown';\n throw err;\n }\n return res.data;\n};\n\n// ── callee side ─────────────────────────────────────────────────────────────\n\n/** The params this app was invoked with as a task callee. */\nexport interface TaskInput {\n task: string;\n params: Record<string, unknown>;\n}\n\nlet latestInput: TaskInput | null = null;\nconst inputListeners = new Set<(i: TaskInput) => void>();\n\n// The host delivers a `task-input` message to the callee's iframe right after it\n// mounts the overlay (the §5.7 \"params via the region's mount event\").\naddListener('task-input', (m: { task: string; params?: Record<string, unknown> }) => {\n latestInput = { task: m.task, params: m.params ?? {} };\n inputListeners.forEach((l) => l(latestInput!));\n});\n\n/** The task params this app was invoked with, or null if it isn't a task callee. */\nexport const getTaskInput = (): TaskInput | null => latestInput;\n\n/**\n * Finish the task, returning a result to the caller. The host validates it against\n * the contract's result schema before resolving the caller (`invalid-params` on\n * violation), then tears down this overlay.\n */\nexport const completeTask = (result: unknown): void => sendMessage('task-complete', { result });\n\n/** Abort the task; the caller's `invokeTask` rejects with `cancelled`. */\nexport const cancelTask = (): void => sendMessage('task-cancel', {});\n\n/** React hook: the task input for this callee, re-rendering when it arrives. */\nexport const useTaskInput = (): TaskInput | null => {\n const [input, setInput] = useState<TaskInput | null>(getTaskInput);\n useEffect(() => {\n const l = (i: TaskInput) => setInput(i);\n inputListeners.add(l);\n if (latestInput) setInput(latestInput);\n return () => {\n inputListeners.delete(l);\n };\n }, []);\n return input;\n};\n"],"mappings":"AAWA,SAAS,WAAW,gBAAgB;AACpC,SAAS,iBAAiB,aAAa,mBAAmB;AAmBnD,MAAM,UAAU,CACrB,KACA,UACa,EAAE,MAAM,QAAQ,SAAS,IAAI,SAAS,SAAS,IAAI,SAAS,MAAM,KAAK,KAAK;AASpF,MAAM,aAAa,OACxB,MACA,SAAkC,CAAC,MACpB;AACf,QAAM,MAAO,MAAM,gBAAgB,QAAQ,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,CAAC;AAIvE,MAAI,CAAC,OAAO,IAAI,OAAO,MAAM;AAC3B,UAAM,MAAM,IAAI,MAAM,KAAK,WAAW,SAAS,IAAI,UAAU;AAC7D,QAAI,OAAO,KAAK,QAAQ;AACxB,UAAM;AAAA,EACR;AACA,SAAO,IAAI;AACb;AAUA,IAAI,cAAgC;AACpC,MAAM,iBAAiB,oBAAI,IAA4B;AAIvD,YAAY,cAAc,CAAC,MAA0D;AACnF,gBAAc,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,UAAU,CAAC,EAAE;AACrD,iBAAe,QAAQ,CAAC,MAAM,EAAE,WAAY,CAAC;AAC/C,CAAC;AAGM,MAAM,eAAe,MAAwB;AAO7C,MAAM,eAAe,CAAC,WAA0B,YAAY,iBAAiB,EAAE,OAAO,CAAC;AAGvF,MAAM,aAAa,MAAY,YAAY,eAAe,CAAC,CAAC;AAG5D,MAAM,eAAe,MAAwB;AAClD,QAAM,CAAC,OAAO,QAAQ,IAAI,SAA2B,YAAY;AACjE,YAAU,MAAM;AACd,UAAM,IAAI,CAAC,MAAiB,SAAS,CAAC;AACtC,mBAAe,IAAI,CAAC;AACpB,QAAI,YAAa,UAAS,WAAW;AACrC,WAAO,MAAM;AACX,qBAAe,OAAO,CAAC;AAAA,IACzB;AAAA,EACF,GAAG,CAAC,CAAC;AACL,SAAO;AACT;","names":[]}
|
package/package.json
CHANGED