@immediately-run/sdk 0.2.4 → 0.2.6

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/index.cjs CHANGED
@@ -28,6 +28,9 @@ __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);
33
+ __reExport(index_exports, require("./runtime"), module.exports);
31
34
  __reExport(index_exports, require("./protocolStream"), module.exports);
32
35
  __reExport(index_exports, require("./sandboxTypes"), module.exports);
33
36
  // Annotate the CommonJS export names for ESM import in node:
@@ -45,6 +48,9 @@ __reExport(index_exports, require("./sandboxTypes"), module.exports);
45
48
  ...require("./mounts"),
46
49
  ...require("./contribute"),
47
50
  ...require("./catalog"),
51
+ ...require("./ipc"),
52
+ ...require("./tasks"),
53
+ ...require("./runtime"),
48
54
  ...require("./protocolStream"),
49
55
  ...require("./sandboxTypes")
50
56
  });
@@ -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,6BAbd;AAcA,0BAAc,2BAdd;","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 './runtime';\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,sBAfd;AAgBA,0BAAc,6BAhBd;AAiBA,0BAAc,2BAjBd;","names":[]}
package/dist/index.d.cts CHANGED
@@ -11,6 +11,9 @@ 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';
16
+ export { ImmediatelyRunGlobal, SDK_PROTOCOL_VERSION, SDK_VERSION, SdkHandshake, announceHandshake, getHostRuntime, sdkHandshake } from './runtime.cjs';
14
17
  export { StreamError, StreamFrame, StreamTransport, consumeStream, protocolStream } from './protocolStream.cjs';
15
18
  export { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryFunction, MetadataQueryResult, ModuleExports } from './sandboxTypes.cjs';
16
19
  import 'react';
package/dist/index.d.ts CHANGED
@@ -11,6 +11,9 @@ 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';
16
+ export { ImmediatelyRunGlobal, SDK_PROTOCOL_VERSION, SDK_VERSION, SdkHandshake, announceHandshake, getHostRuntime, sdkHandshake } from './runtime.js';
14
17
  export { StreamError, StreamFrame, StreamTransport, consumeStream, protocolStream } from './protocolStream.js';
15
18
  export { EvaluationContext, FileQueryResult, FilesMetadata, Metadata, MetadataQueryFunction, MetadataQueryResult, ModuleExports } from './sandboxTypes.js';
16
19
  import 'react';
package/dist/index.js CHANGED
@@ -11,6 +11,9 @@ 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";
16
+ export * from "./runtime";
14
17
  export * from "./protocolStream";
15
18
  export * from "./sandboxTypes";
16
19
  //# 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 './runtime';\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;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
@@ -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
@@ -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":[]}
@@ -0,0 +1,60 @@
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 runtime_exports = {};
20
+ __export(runtime_exports, {
21
+ SDK_PROTOCOL_VERSION: () => SDK_PROTOCOL_VERSION,
22
+ SDK_VERSION: () => SDK_VERSION,
23
+ announceHandshake: () => announceHandshake,
24
+ getHostRuntime: () => getHostRuntime,
25
+ sdkHandshake: () => sdkHandshake
26
+ });
27
+ module.exports = __toCommonJS(runtime_exports);
28
+ var import_sandboxUtils = require("./sandboxUtils");
29
+ const SDK_PROTOCOL_VERSION = "1.0.0";
30
+ const SDK_VERSION = "0.2.6";
31
+ function getHostRuntime() {
32
+ try {
33
+ return globalThis.__immediatelyRun__ ?? null;
34
+ } catch {
35
+ return null;
36
+ }
37
+ }
38
+ const sdkHandshake = () => ({
39
+ sdkVersion: SDK_VERSION,
40
+ protocolVersion: SDK_PROTOCOL_VERSION
41
+ });
42
+ function announceHandshake() {
43
+ const send = () => {
44
+ try {
45
+ (0, import_sandboxUtils.sendMessage)("sdk-handshake", sdkHandshake());
46
+ } catch {
47
+ }
48
+ };
49
+ send();
50
+ return (0, import_sandboxUtils.addListener)("request-handshake", send);
51
+ }
52
+ // Annotate the CommonJS export names for ESM import in node:
53
+ 0 && (module.exports = {
54
+ SDK_PROTOCOL_VERSION,
55
+ SDK_VERSION,
56
+ announceHandshake,
57
+ getHostRuntime,
58
+ sdkHandshake
59
+ });
60
+ //# sourceMappingURL=runtime.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["// Runtime discovery + version handshake (SDK_PACKAGING_SPEC §4/§6).\n//\n// Today the SDK reaches the host through the INJECTED sandbox services\n// (`module.evaluation.module.bundler.*`, see sandboxUtils). The packaging migration\n// makes the SDK an app-pinnable npm dependency that finds the runtime through a\n// stable, versioned global the sandbox publishes BEFORE evaluating app code:\n//\n// globalThis.__immediatelyRun__ = { runtimeVersion, protocolVersion, transport }\n//\n// Phase 1 (behind a flag, injection still active): the SDK can READ that global\n// when present (else fall back to injection), and ANNOUNCE its own version +\n// protocol so the host can record + version-check it (§6/T45). The transport itself\n// is unchanged here — this only wires the discovery + handshake fields so the check\n// exists when app-pinned versions become real.\nimport { sendMessage, addListener } from './sandboxUtils';\n\n/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.\n * Additive-only (§9); bump only for a backwards-compatible extension. */\nexport const SDK_PROTOCOL_VERSION = '1.0.0';\n\n/** This SDK's package version. Kept in step with package.json (a build step can\n * inject it later; a constant is fine while versions are still effectively fixed). */\nexport const SDK_VERSION = '0.2.6';\n\n/** The sandbox runtime's pre-evaluation discovery global (§4). */\nexport interface ImmediatelyRunGlobal {\n /** Sandbox-runtime protocol version (semver). */\n runtimeVersion?: string;\n /** postMessage envelope/protocol version. */\n protocolVersion?: string;\n /** The host channel the SDK talks over (MessagePort | message bus). */\n transport?: unknown;\n /** Resolves when ports arrive, if they arrive async after register-frame. */\n ready?: Promise<void>;\n}\n\n/**\n * Read the sandbox runtime's discovery global (§4), or null when absent — in which\n * case the SDK uses the current INJECTED path (`module.evaluation.*`). Lets the SDK\n * detect a host too old/new and fail closed (§6) once the global ships.\n */\nexport function getHostRuntime(): ImmediatelyRunGlobal | null {\n try {\n return (globalThis as { __immediatelyRun__?: ImmediatelyRunGlobal }).__immediatelyRun__ ?? null;\n } catch {\n return null;\n }\n}\n\n/** This SDK's handshake payload — the version + protocol the host records + checks\n * against `HOST_PROTOCOL_VERSION` (§6/T45). */\nexport interface SdkHandshake {\n sdkVersion: string;\n protocolVersion: string;\n}\nexport const sdkHandshake = (): SdkHandshake => ({\n sdkVersion: SDK_VERSION,\n protocolVersion: SDK_PROTOCOL_VERSION,\n});\n\n/**\n * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly\n * (best-effort — the host may already be listening) AND replies to a host\n * `request-handshake` (the robust path, mirroring the other `request-*` pulls).\n * Idempotent; safe to call more than once. Returns an unsubscribe fn.\n */\nexport function announceHandshake(): () => void {\n const send = () => {\n try {\n sendMessage('sdk-handshake', sdkHandshake() as unknown as Record<string, unknown>);\n } catch {\n /* transport not ready yet — the request-handshake reply covers it */\n }\n };\n send();\n return addListener('request-handshake', send);\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAcA,0BAAyC;AAIlC,MAAM,uBAAuB;AAI7B,MAAM,cAAc;AAmBpB,SAAS,iBAA8C;AAC5D,MAAI;AACF,WAAQ,WAA6D,sBAAsB;AAAA,EAC7F,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQO,MAAM,eAAe,OAAqB;AAAA,EAC/C,YAAY;AAAA,EACZ,iBAAiB;AACnB;AAQO,SAAS,oBAAgC;AAC9C,QAAM,OAAO,MAAM;AACjB,QAAI;AACF,2CAAY,iBAAiB,aAAa,CAAuC;AAAA,IACnF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,OAAK;AACL,aAAO,iCAAY,qBAAqB,IAAI;AAC9C;","names":[]}
@@ -0,0 +1,39 @@
1
+ /** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.
2
+ * Additive-only (§9); bump only for a backwards-compatible extension. */
3
+ declare const SDK_PROTOCOL_VERSION = "1.0.0";
4
+ /** This SDK's package version. Kept in step with package.json (a build step can
5
+ * inject it later; a constant is fine while versions are still effectively fixed). */
6
+ declare const SDK_VERSION = "0.2.6";
7
+ /** The sandbox runtime's pre-evaluation discovery global (§4). */
8
+ interface ImmediatelyRunGlobal {
9
+ /** Sandbox-runtime protocol version (semver). */
10
+ runtimeVersion?: string;
11
+ /** postMessage envelope/protocol version. */
12
+ protocolVersion?: string;
13
+ /** The host channel the SDK talks over (MessagePort | message bus). */
14
+ transport?: unknown;
15
+ /** Resolves when ports arrive, if they arrive async after register-frame. */
16
+ ready?: Promise<void>;
17
+ }
18
+ /**
19
+ * Read the sandbox runtime's discovery global (§4), or null when absent — in which
20
+ * case the SDK uses the current INJECTED path (`module.evaluation.*`). Lets the SDK
21
+ * detect a host too old/new and fail closed (§6) once the global ships.
22
+ */
23
+ declare function getHostRuntime(): ImmediatelyRunGlobal | null;
24
+ /** This SDK's handshake payload — the version + protocol the host records + checks
25
+ * against `HOST_PROTOCOL_VERSION` (§6/T45). */
26
+ interface SdkHandshake {
27
+ sdkVersion: string;
28
+ protocolVersion: string;
29
+ }
30
+ declare const sdkHandshake: () => SdkHandshake;
31
+ /**
32
+ * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly
33
+ * (best-effort — the host may already be listening) AND replies to a host
34
+ * `request-handshake` (the robust path, mirroring the other `request-*` pulls).
35
+ * Idempotent; safe to call more than once. Returns an unsubscribe fn.
36
+ */
37
+ declare function announceHandshake(): () => void;
38
+
39
+ export { type ImmediatelyRunGlobal, SDK_PROTOCOL_VERSION, SDK_VERSION, type SdkHandshake, announceHandshake, getHostRuntime, sdkHandshake };
@@ -0,0 +1,39 @@
1
+ /** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.
2
+ * Additive-only (§9); bump only for a backwards-compatible extension. */
3
+ declare const SDK_PROTOCOL_VERSION = "1.0.0";
4
+ /** This SDK's package version. Kept in step with package.json (a build step can
5
+ * inject it later; a constant is fine while versions are still effectively fixed). */
6
+ declare const SDK_VERSION = "0.2.6";
7
+ /** The sandbox runtime's pre-evaluation discovery global (§4). */
8
+ interface ImmediatelyRunGlobal {
9
+ /** Sandbox-runtime protocol version (semver). */
10
+ runtimeVersion?: string;
11
+ /** postMessage envelope/protocol version. */
12
+ protocolVersion?: string;
13
+ /** The host channel the SDK talks over (MessagePort | message bus). */
14
+ transport?: unknown;
15
+ /** Resolves when ports arrive, if they arrive async after register-frame. */
16
+ ready?: Promise<void>;
17
+ }
18
+ /**
19
+ * Read the sandbox runtime's discovery global (§4), or null when absent — in which
20
+ * case the SDK uses the current INJECTED path (`module.evaluation.*`). Lets the SDK
21
+ * detect a host too old/new and fail closed (§6) once the global ships.
22
+ */
23
+ declare function getHostRuntime(): ImmediatelyRunGlobal | null;
24
+ /** This SDK's handshake payload — the version + protocol the host records + checks
25
+ * against `HOST_PROTOCOL_VERSION` (§6/T45). */
26
+ interface SdkHandshake {
27
+ sdkVersion: string;
28
+ protocolVersion: string;
29
+ }
30
+ declare const sdkHandshake: () => SdkHandshake;
31
+ /**
32
+ * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly
33
+ * (best-effort — the host may already be listening) AND replies to a host
34
+ * `request-handshake` (the robust path, mirroring the other `request-*` pulls).
35
+ * Idempotent; safe to call more than once. Returns an unsubscribe fn.
36
+ */
37
+ declare function announceHandshake(): () => void;
38
+
39
+ export { type ImmediatelyRunGlobal, SDK_PROTOCOL_VERSION, SDK_VERSION, type SdkHandshake, announceHandshake, getHostRuntime, sdkHandshake };
@@ -0,0 +1,32 @@
1
+ import { sendMessage, addListener } from "./sandboxUtils";
2
+ const SDK_PROTOCOL_VERSION = "1.0.0";
3
+ const SDK_VERSION = "0.2.6";
4
+ function getHostRuntime() {
5
+ try {
6
+ return globalThis.__immediatelyRun__ ?? null;
7
+ } catch {
8
+ return null;
9
+ }
10
+ }
11
+ const sdkHandshake = () => ({
12
+ sdkVersion: SDK_VERSION,
13
+ protocolVersion: SDK_PROTOCOL_VERSION
14
+ });
15
+ function announceHandshake() {
16
+ const send = () => {
17
+ try {
18
+ sendMessage("sdk-handshake", sdkHandshake());
19
+ } catch {
20
+ }
21
+ };
22
+ send();
23
+ return addListener("request-handshake", send);
24
+ }
25
+ export {
26
+ SDK_PROTOCOL_VERSION,
27
+ SDK_VERSION,
28
+ announceHandshake,
29
+ getHostRuntime,
30
+ sdkHandshake
31
+ };
32
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/runtime.ts"],"sourcesContent":["// Runtime discovery + version handshake (SDK_PACKAGING_SPEC §4/§6).\n//\n// Today the SDK reaches the host through the INJECTED sandbox services\n// (`module.evaluation.module.bundler.*`, see sandboxUtils). The packaging migration\n// makes the SDK an app-pinnable npm dependency that finds the runtime through a\n// stable, versioned global the sandbox publishes BEFORE evaluating app code:\n//\n// globalThis.__immediatelyRun__ = { runtimeVersion, protocolVersion, transport }\n//\n// Phase 1 (behind a flag, injection still active): the SDK can READ that global\n// when present (else fall back to injection), and ANNOUNCE its own version +\n// protocol so the host can record + version-check it (§6/T45). The transport itself\n// is unchanged here — this only wires the discovery + handshake fields so the check\n// exists when app-pinned versions become real.\nimport { sendMessage, addListener } from './sandboxUtils';\n\n/** The wire protocol (postMessage envelope / channels / methods) THIS SDK speaks.\n * Additive-only (§9); bump only for a backwards-compatible extension. */\nexport const SDK_PROTOCOL_VERSION = '1.0.0';\n\n/** This SDK's package version. Kept in step with package.json (a build step can\n * inject it later; a constant is fine while versions are still effectively fixed). */\nexport const SDK_VERSION = '0.2.6';\n\n/** The sandbox runtime's pre-evaluation discovery global (§4). */\nexport interface ImmediatelyRunGlobal {\n /** Sandbox-runtime protocol version (semver). */\n runtimeVersion?: string;\n /** postMessage envelope/protocol version. */\n protocolVersion?: string;\n /** The host channel the SDK talks over (MessagePort | message bus). */\n transport?: unknown;\n /** Resolves when ports arrive, if they arrive async after register-frame. */\n ready?: Promise<void>;\n}\n\n/**\n * Read the sandbox runtime's discovery global (§4), or null when absent — in which\n * case the SDK uses the current INJECTED path (`module.evaluation.*`). Lets the SDK\n * detect a host too old/new and fail closed (§6) once the global ships.\n */\nexport function getHostRuntime(): ImmediatelyRunGlobal | null {\n try {\n return (globalThis as { __immediatelyRun__?: ImmediatelyRunGlobal }).__immediatelyRun__ ?? null;\n } catch {\n return null;\n }\n}\n\n/** This SDK's handshake payload — the version + protocol the host records + checks\n * against `HOST_PROTOCOL_VERSION` (§6/T45). */\nexport interface SdkHandshake {\n sdkVersion: string;\n protocolVersion: string;\n}\nexport const sdkHandshake = (): SdkHandshake => ({\n sdkVersion: SDK_VERSION,\n protocolVersion: SDK_PROTOCOL_VERSION,\n});\n\n/**\n * Announce this SDK's version to the host (§6). Sends `sdk-handshake` eagerly\n * (best-effort — the host may already be listening) AND replies to a host\n * `request-handshake` (the robust path, mirroring the other `request-*` pulls).\n * Idempotent; safe to call more than once. Returns an unsubscribe fn.\n */\nexport function announceHandshake(): () => void {\n const send = () => {\n try {\n sendMessage('sdk-handshake', sdkHandshake() as unknown as Record<string, unknown>);\n } catch {\n /* transport not ready yet — the request-handshake reply covers it */\n }\n };\n send();\n return addListener('request-handshake', send);\n}\n"],"mappings":"AAcA,SAAS,aAAa,mBAAmB;AAIlC,MAAM,uBAAuB;AAI7B,MAAM,cAAc;AAmBpB,SAAS,iBAA8C;AAC5D,MAAI;AACF,WAAQ,WAA6D,sBAAsB;AAAA,EAC7F,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQO,MAAM,eAAe,OAAqB;AAAA,EAC/C,YAAY;AAAA,EACZ,iBAAiB;AACnB;AAQO,SAAS,oBAAgC;AAC9C,QAAM,OAAO,MAAM;AACjB,QAAI;AACF,kBAAY,iBAAiB,aAAa,CAAuC;AAAA,IACnF,QAAQ;AAAA,IAER;AAAA,EACF;AACA,OAAK;AACL,SAAO,YAAY,qBAAqB,IAAI;AAC9C;","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":[]}
@@ -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 };
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@immediately-run/sdk",
3
- "version": "0.2.4",
3
+ "version": "0.2.6",
4
4
  "description": "Runtime SDK for code executing inside an immediately.run sandbox.",
5
5
  "license": "MIT",
6
6
  "repository": "github:immediately-run/immediately-run-sdk",