@immediately-run/sdk 0.57.1 → 0.57.4
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/agentChatClient.cjs +112 -0
- package/dist/agentChatClient.cjs.map +1 -0
- package/dist/agentChatClient.d.cts +9 -0
- package/dist/agentChatClient.d.ts +9 -0
- package/dist/agentChatClient.js +89 -0
- package/dist/agentChatClient.js.map +1 -0
- package/dist/agentContext.cjs +69 -0
- package/dist/agentContext.cjs.map +1 -0
- package/dist/agentContext.d.cts +45 -0
- package/dist/agentContext.d.ts +45 -0
- package/dist/agentContext.js +45 -0
- package/dist/agentContext.js.map +1 -0
- package/dist/agentLoop.cjs +301 -0
- package/dist/agentLoop.cjs.map +1 -0
- package/dist/agentLoop.d.cts +267 -0
- package/dist/agentLoop.d.ts +267 -0
- package/dist/agentLoop.js +271 -0
- package/dist/agentLoop.js.map +1 -0
- package/dist/agentSteering.cjs +127 -0
- package/dist/agentSteering.cjs.map +1 -0
- package/dist/agentSteering.d.cts +80 -0
- package/dist/agentSteering.d.ts +80 -0
- package/dist/agentSteering.js +98 -0
- package/dist/agentSteering.js.map +1 -0
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +33 -2
- package/dist/auth.d.ts +33 -2
- package/dist/auth.js.map +1 -1
- package/dist/bundle.cjs +91 -0
- package/dist/bundle.cjs.map +1 -0
- package/dist/bundle.d.cts +63 -0
- package/dist/bundle.d.ts +63 -0
- package/dist/bundle.js +62 -0
- package/dist/bundle.js.map +1 -0
- package/dist/collectHeadings.cjs +59 -0
- package/dist/collectHeadings.cjs.map +1 -0
- package/dist/collectHeadings.d.cts +16 -0
- package/dist/collectHeadings.d.ts +16 -0
- package/dist/collectHeadings.js +36 -0
- package/dist/collectHeadings.js.map +1 -0
- package/dist/corpus.cjs +9 -58
- package/dist/corpus.cjs.map +1 -1
- package/dist/corpus.d.cts +3 -63
- package/dist/corpus.d.ts +3 -63
- package/dist/corpus.js +15 -57
- package/dist/corpus.js.map +1 -1
- package/dist/debug.cjs +115 -0
- package/dist/debug.cjs.map +1 -1
- package/dist/debug.js +115 -0
- package/dist/debug.js.map +1 -1
- package/dist/fence.cjs +49 -0
- package/dist/fence.cjs.map +1 -0
- package/dist/fence.d.cts +4 -0
- package/dist/fence.d.ts +4 -0
- package/dist/fence.js +26 -0
- package/dist/fence.js.map +1 -0
- package/dist/formFactor.cjs.map +1 -1
- package/dist/formFactor.d.cts +11 -2
- package/dist/formFactor.d.ts +11 -2
- package/dist/formFactor.js.map +1 -1
- package/dist/fs.cjs.map +1 -1
- package/dist/fs.d.cts +16 -6
- package/dist/fs.d.ts +16 -6
- package/dist/fs.js.map +1 -1
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +7 -0
- package/dist/hooks.d.ts +7 -0
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +19 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -3
- package/dist/index.d.ts +11 -3
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -1
- package/dist/launch.cjs +45 -6
- package/dist/launch.cjs.map +1 -1
- package/dist/launch.d.cts +3 -0
- package/dist/launch.d.ts +3 -0
- package/dist/launch.js +45 -6
- package/dist/launch.js.map +1 -1
- package/dist/llm.cjs.map +1 -1
- package/dist/llm.d.cts +20 -3
- package/dist/llm.d.ts +20 -3
- package/dist/llm.js.map +1 -1
- package/dist/metadataQueryTool.cjs +271 -0
- package/dist/metadataQueryTool.cjs.map +1 -0
- package/dist/metadataQueryTool.d.cts +159 -0
- package/dist/metadataQueryTool.d.ts +159 -0
- package/dist/metadataQueryTool.js +241 -0
- package/dist/metadataQueryTool.js.map +1 -0
- package/dist/mounts.cjs.map +1 -1
- package/dist/mounts.d.cts +22 -3
- package/dist/mounts.d.ts +22 -3
- package/dist/mounts.js.map +1 -1
- package/dist/onFsChange.cjs +13 -1
- package/dist/onFsChange.cjs.map +1 -1
- package/dist/onFsChange.d.cts +21 -1
- package/dist/onFsChange.d.ts +21 -1
- package/dist/onFsChange.js +13 -1
- package/dist/onFsChange.js.map +1 -1
- package/dist/protocolSchemes.cjs +1 -0
- package/dist/protocolSchemes.cjs.map +1 -1
- package/dist/protocolSchemes.d.cts +1 -0
- package/dist/protocolSchemes.d.ts +1 -0
- package/dist/protocolSchemes.js +2 -0
- package/dist/protocolSchemes.js.map +1 -1
- package/dist/recents.cjs +41 -0
- package/dist/recents.cjs.map +1 -0
- package/dist/recents.d.cts +23 -0
- package/dist/recents.d.ts +23 -0
- package/dist/recents.js +17 -0
- package/dist/recents.js.map +1 -0
- package/dist/tasks.cjs +41 -7
- package/dist/tasks.cjs.map +1 -1
- package/dist/tasks.d.cts +136 -7
- package/dist/tasks.d.ts +136 -7
- package/dist/tasks.js +39 -7
- package/dist/tasks.js.map +1 -1
- package/dist/version.cjs +1 -1
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +6 -5
package/dist/tasks.d.ts
CHANGED
|
@@ -44,27 +44,156 @@ declare const capDir: (ref: {
|
|
|
44
44
|
/**
|
|
45
45
|
* Invoke another app via a task contract and await its typed result (Recipe B).
|
|
46
46
|
* Rejects with a machine `.code` on refusal: `cancelled` (user dismissed the
|
|
47
|
-
* overlay), `timeout` (§5.7.1 liveness), `forbidden` (
|
|
48
|
-
* delegation you don't hold), `
|
|
49
|
-
* `
|
|
47
|
+
* overlay), `timeout` (§5.7.1 liveness), `forbidden` (missing `task:invoke`, or a
|
|
48
|
+
* file delegation you don't hold), `not-declared` (the task is missing from your
|
|
49
|
+
* `immediately.run.invokes`), `no-such-task` (no app is bound to that contract),
|
|
50
|
+
* `task-cycle`/`task-depth-exceeded`/`task-version-mismatch`, or `invalid-params`
|
|
51
|
+
* (result failed the contract schema). **Read `err.message`** — since R3-418 the host
|
|
52
|
+
* says which capability, which declaration or which param was at fault; the code alone
|
|
53
|
+
* does not distinguish them.
|
|
54
|
+
*
|
|
55
|
+
* Two things must BOTH be true before any invoke is admitted, and they are separate:
|
|
56
|
+
* 1. your `package.json` `immediately.run.invokes` lists the task (else `not-declared`);
|
|
57
|
+
* 2. your app holds the `task:invoke` capability — declare it in
|
|
58
|
+
* `immediately.run.capabilities` so the user can grant it (else `forbidden`).
|
|
59
|
+
* Declaring the invoke does not imply the capability.
|
|
60
|
+
*
|
|
61
|
+
* ── `pick-file`: `roots` is required (SPACES_UI_SPEC §4.1) ───────────────────
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { invokeTask, capDir, requestMount } from '@immediately-run/sdk';
|
|
64
|
+
*
|
|
65
|
+
* const mount = await requestMount(); // the user picks a space
|
|
66
|
+
* // `invokeTask` returns `unknown` — name the result type, or the destructuring
|
|
67
|
+
* // below does not compile.
|
|
68
|
+
* const { root, path } = await invokeTask<{ root: number; path: string }>('pick-file', {
|
|
69
|
+
* // `SandboxMount.id` is optional (absent on the primary repo mount) — fall back to
|
|
70
|
+
* // `path`, which is always present and is what the host resolves against.
|
|
71
|
+
* roots: [capDir({ mountId: mount.id ?? mount.path, relPath: 'boards' }, { mode: 'ro' })],
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
* - `roots` is a NON-EMPTY `DirCap[]` of directories you **already hold**. The result
|
|
75
|
+
* names its target as `{ root, path }` where `root` INDEXES `params.roots`, so
|
|
76
|
+
* `invokeTask('pick-file', {})` can never produce a valid result and is rejected.
|
|
77
|
+
* There is no rootless "pick from any of my spaces" mode by design: enumerating the
|
|
78
|
+
* user's spaces is the host's powerbox (`requestMount()`), and composing the two —
|
|
79
|
+
* as above — is that flow. See SPACES_UI_SPEC R-SPACES-5/R-SPACES-12.
|
|
80
|
+
* - Each `capDir` is attenuated against your own grant. **`{ mode: 'rw' }` over a space
|
|
81
|
+
* the user granted `ro` is refused `forbidden`** — the commonest failure, because the
|
|
82
|
+
* mount *was* granted and the path *is* inside it. Pass the mode you actually hold;
|
|
83
|
+
* `ro` is right for a plain pick.
|
|
84
|
+
* - The `requestMount()` grant is DURABLE and survives a cancelled pick: the user
|
|
85
|
+
* consented to the mount in host chrome, separately from the pick (SPACES_UI_SPEC §4.1).
|
|
86
|
+
* Reuse it for later picks rather than re-requesting.
|
|
87
|
+
*
|
|
88
|
+
* Off-host (plain `vite dev` — no host transport) it rejects with a plain
|
|
89
|
+
* "no host transport" error: there is no host to resolve the task binding.
|
|
50
90
|
*/
|
|
51
91
|
declare const invokeTask: <R = unknown>(task: string, params?: Record<string, unknown>) => Promise<R>;
|
|
92
|
+
/** Bytes captured by the host, as `capturePhoto()` / `captureAudio()` return them.
|
|
93
|
+
* `bytes` is a transferable `ArrayBuffer` — write it to a space, decode it, upload
|
|
94
|
+
* it. You never receive a `MediaStream` or a `MediaStreamTrack`, and that is not an
|
|
95
|
+
* omission: a track cannot be transferred into an app frame at all
|
|
96
|
+
* (`DataCloneError`), and the frame's opaque origin cannot open a device itself
|
|
97
|
+
* (`getUserMedia` throws `SecurityError: Invalid security origin`). */
|
|
98
|
+
interface CaptureResult {
|
|
99
|
+
bytes: ArrayBuffer;
|
|
100
|
+
/** e.g. `image/jpeg`, `audio/webm`. Chosen by the HOST, not by you. */
|
|
101
|
+
mimeType: string;
|
|
102
|
+
/** How long the device was open, in ms. */
|
|
103
|
+
durationMs: number;
|
|
104
|
+
}
|
|
105
|
+
/** Optional hints for a capture. They deliberately name NOTHING — no device id, no
|
|
106
|
+
* camera index — because the host chooses everything about how the capture is
|
|
107
|
+
* performed. That is what lets the grant be a plain on/off instead of a per-call
|
|
108
|
+
* target list the way `net:fetch` needs. */
|
|
109
|
+
interface CaptureOptions {
|
|
110
|
+
/** Which way the camera should face, if the device has a choice. A HINT: the host
|
|
111
|
+
* may ignore it. Ignored for audio. */
|
|
112
|
+
facing?: 'user' | 'environment';
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Take one photo, or record one audio clip, through the HOST's capture UI
|
|
116
|
+
* (`BROWSER_CAPABILITIES_SPEC` §3 grade 1).
|
|
117
|
+
*
|
|
118
|
+
* The host opens the device at its own origin, draws the viewfinder, and hands you
|
|
119
|
+
* the bytes when the user presses Done. **You are never in the loop while the device
|
|
120
|
+
* is live** — that is the point of the design, not a limitation of it:
|
|
121
|
+
*
|
|
122
|
+
* - The capture UI is drawn by the host, so a user can trust it the way they trust
|
|
123
|
+
* the sign-in dialog. Do not build a lookalike; imitating host chrome is spoofing.
|
|
124
|
+
* - While the device is open the host shows a persistent "camera on" / "microphone
|
|
125
|
+
* on" indicator in its own chrome, for the whole session. You cannot hide it and
|
|
126
|
+
* should not try to.
|
|
127
|
+
* - If the user cancels, this rejects `cancelled` and **nothing was recorded**. There
|
|
128
|
+
* is no partial result — do not write error handling that hopes for one.
|
|
129
|
+
*
|
|
130
|
+
* ```ts
|
|
131
|
+
* import { capturePhoto, requestMount, openFs } from '@immediately-run/sdk';
|
|
132
|
+
*
|
|
133
|
+
* try {
|
|
134
|
+
* const { bytes, mimeType } = await capturePhoto({ facing: 'environment' });
|
|
135
|
+
* const mount = await requestMount(); // the user picks a space to save into
|
|
136
|
+
* const fs = openFs(mount); // writeFile is a METHOD on the MountFs
|
|
137
|
+
* await fs.mkdir('photos', { recursive: true }); // writeFile does not create parents
|
|
138
|
+
* await fs.writeFile(`photos/latest.${mimeType === 'image/png' ? 'png' : 'jpg'}`, new Uint8Array(bytes));
|
|
139
|
+
* } catch (e) {
|
|
140
|
+
* if ((e as { code?: string }).code === 'cancelled') return; // the user said no
|
|
141
|
+
* throw e;
|
|
142
|
+
* }
|
|
143
|
+
* ```
|
|
144
|
+
* (The extension follows `mimeType` because the HOST chooses the format — do not assume
|
|
145
|
+
* JPEG. `openAppFs()` is the variant that writes to your own app space with no pick.)
|
|
146
|
+
*
|
|
147
|
+
* Two things must BOTH be true, exactly as for any other task:
|
|
148
|
+
* 1. `immediately.run.invokes` lists `capture-photo` (or `capture-audio`);
|
|
149
|
+
* 2. your app holds `task:invoke` **and** `device:camera` (or `device:microphone`)
|
|
150
|
+
* — declare them in `immediately.run.capabilities` so the user can grant them.
|
|
151
|
+
*
|
|
152
|
+
* Rejects with `.code`: `cancelled` (the user dismissed the capture — nothing was
|
|
153
|
+
* recorded), `forbidden` (you lack the capability; `message: 'browser-denied'` means
|
|
154
|
+
* the BROWSER refused immediately.run itself, which your consent cannot fix),
|
|
155
|
+
* `unavailable` (no such device on this machine, or it would not start),
|
|
156
|
+
* `unsupported` (this host cannot capture), `not-declared`, `timeout`.
|
|
157
|
+
*
|
|
158
|
+
* *Zero-platform alternative, still worth knowing:* `<input type="file"
|
|
159
|
+
* accept="image/*" capture="environment">` opens the OS camera from inside the
|
|
160
|
+
* sandbox (file choosers are not permission-gated). It needs no capability and no
|
|
161
|
+
* host support; it also gives you no indicator and no host-drawn surface.
|
|
162
|
+
*/
|
|
163
|
+
declare const capturePhoto: (options?: CaptureOptions) => Promise<CaptureResult>;
|
|
164
|
+
/** Record one audio clip through the host's capture UI. See {@link capturePhoto} —
|
|
165
|
+
* every rule there applies verbatim, with `device:microphone` and `capture-audio`. */
|
|
166
|
+
declare const captureAudio: (options?: CaptureOptions) => Promise<CaptureResult>;
|
|
52
167
|
/** The params this app was invoked with as a task callee. */
|
|
53
168
|
interface TaskInput {
|
|
54
169
|
task: string;
|
|
55
170
|
params: Record<string, unknown>;
|
|
56
171
|
}
|
|
57
|
-
/** The task params this app was invoked with, or null if it isn't a task callee.
|
|
172
|
+
/** The task params this app was invoked with, or null if it isn't a task callee.
|
|
173
|
+
* Off-host (plain `vite dev`) this is always `null` — there is no host to invoke
|
|
174
|
+
* this app as a callee. */
|
|
58
175
|
declare const getTaskInput: () => TaskInput | null;
|
|
59
176
|
/**
|
|
60
177
|
* Finish the task, returning a result to the caller. The host validates it against
|
|
61
178
|
* the contract's result schema before resolving the caller (`invalid-params` on
|
|
62
179
|
* violation), then tears down this overlay.
|
|
180
|
+
*
|
|
181
|
+
* `result` must be STRUCTURED-CLONEABLE — it crosses a frame boundary. A DOM node, a
|
|
182
|
+
* function, a class instance with methods, a `MediaStreamTrack`: all `DataCloneError`.
|
|
183
|
+
* **That throws**, deliberately and loudly: the alternative is a caller left hanging to
|
|
184
|
+
* its `invokeTask` deadline while this app believes it answered.
|
|
185
|
+
*
|
|
186
|
+
* Off-host (plain `vite dev` — no host transport) this is a no-op: there is no caller
|
|
187
|
+
* to answer. That case, and only that case, is silent.
|
|
63
188
|
*/
|
|
64
189
|
declare const completeTask: (result: unknown) => void;
|
|
65
|
-
/** Abort the task; the caller's `invokeTask` rejects with `cancelled`.
|
|
190
|
+
/** Abort the task; the caller's `invokeTask` rejects with `cancelled`.
|
|
191
|
+
* Off-host (plain `vite dev` — no host transport) this is a no-op; on-host a failed
|
|
192
|
+
* send throws rather than leaving the caller waiting, exactly as {@link completeTask}. */
|
|
66
193
|
declare const cancelTask: () => void;
|
|
67
|
-
/** React hook: the task input for this callee, re-rendering when it arrives.
|
|
194
|
+
/** React hook: the task input for this callee, re-rendering when it arrives.
|
|
195
|
+
* Off-host (plain `vite dev`) it stays `null` forever — render the non-callee
|
|
196
|
+
* state rather than waiting on it. */
|
|
68
197
|
declare const useTaskInput: () => TaskInput | null;
|
|
69
198
|
|
|
70
|
-
export { type DirCap, type FileCap, type TaskInput, cancelTask, capDir, capFile, completeTask, getTaskInput, invokeTask, useTaskInput };
|
|
199
|
+
export { type CaptureOptions, type CaptureResult, type DirCap, type FileCap, type TaskInput, cancelTask, capDir, capFile, captureAudio, capturePhoto, completeTask, getTaskInput, invokeTask, useTaskInput };
|
package/dist/tasks.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import "./chunk-VHAA22YE.js";
|
|
2
2
|
import { useEffect, useState } from "react";
|
|
3
3
|
import { protocolRequest, sendMessage, addListener } from "./sandboxUtils";
|
|
4
|
+
import { transport } from "./hostTransport";
|
|
4
5
|
import { PROTOCOL_TASK, TASK_CANCEL, TASK_COMPLETE, TASK_INPUT } from "./generated/protocol";
|
|
5
6
|
import { SCHEMES } from "./protocolSchemes";
|
|
6
7
|
const capFile = (ref, opts) => ({
|
|
@@ -24,15 +25,44 @@ const invokeTask = async (task, params = {}) => {
|
|
|
24
25
|
}
|
|
25
26
|
return res.data;
|
|
26
27
|
};
|
|
28
|
+
const capturePhoto = (options = {}) => invokeTask("capture-photo", { ...options });
|
|
29
|
+
const captureAudio = (options = {}) => invokeTask("capture-audio", { ...options });
|
|
27
30
|
let latestInput = null;
|
|
28
31
|
const inputListeners = /* @__PURE__ */ new Set();
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
let inputListenerRegistered = false;
|
|
33
|
+
const ensureInputListener = () => {
|
|
34
|
+
if (inputListenerRegistered) return;
|
|
35
|
+
try {
|
|
36
|
+
addListener(TASK_INPUT, (m) => {
|
|
37
|
+
latestInput = { task: m.task, params: m.params ?? {} };
|
|
38
|
+
inputListeners.forEach((l) => l(latestInput));
|
|
39
|
+
});
|
|
40
|
+
} catch {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
inputListenerRegistered = true;
|
|
44
|
+
};
|
|
45
|
+
ensureInputListener();
|
|
46
|
+
const getTaskInput = () => {
|
|
47
|
+
ensureInputListener();
|
|
48
|
+
return latestInput;
|
|
49
|
+
};
|
|
50
|
+
const hostReachable = () => {
|
|
51
|
+
try {
|
|
52
|
+
transport();
|
|
53
|
+
return true;
|
|
54
|
+
} catch {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const completeTask = (result) => {
|
|
59
|
+
if (!hostReachable()) return;
|
|
60
|
+
sendMessage(TASK_COMPLETE, { result });
|
|
61
|
+
};
|
|
62
|
+
const cancelTask = () => {
|
|
63
|
+
if (!hostReachable()) return;
|
|
64
|
+
sendMessage(TASK_CANCEL, {});
|
|
65
|
+
};
|
|
36
66
|
const useTaskInput = () => {
|
|
37
67
|
const [input, setInput] = useState(getTaskInput);
|
|
38
68
|
useEffect(() => {
|
|
@@ -49,6 +79,8 @@ export {
|
|
|
49
79
|
cancelTask,
|
|
50
80
|
capDir,
|
|
51
81
|
capFile,
|
|
82
|
+
captureAudio,
|
|
83
|
+
capturePhoto,
|
|
52
84
|
completeTask,
|
|
53
85
|
getTaskInput,
|
|
54
86
|
invokeTask,
|
package/dist/tasks.js.map
CHANGED
|
@@ -1 +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';\nimport { PROTOCOL_TASK, TASK_CANCEL, TASK_COMPLETE, TASK_INPUT } from './generated/protocol';\nimport { SCHEMES } from './protocolSchemes';\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 = (ref: { mountId: string; relPath: string }, opts: { mode: 'ro' | 'rw' }): FileCap => ({\n $cap: 'file',\n mountId: ref.mountId,\n relPath: ref.relPath,\n mode: opts.mode,\n});\n\n/** A delegated DIRECTORY capability marker for a task param (D2). Like {@link FileCap}\n * but `relPath` names a DIRECTORY: the host chroots the callee AT that directory\n * (the whole subtree). Used for the `pick-file` `roots` — one chroot per root. */\nexport interface DirCap {\n $cap: 'dir';\n mountId: string;\n relPath: string;\n mode: 'ro' | 'rw';\n}\n\n/**\n * Build a delegated DIRECTORY reference for a task param (the directory analogue of\n * {@link capFile}). The host resolves it against YOUR OWN grants and mints an\n * attenuated, task-scoped chroot of that directory for the callee — you can only\n * delegate a directory you already hold (attenuation only, never escalation):\n *\n * roots: [capDir({ mountId: 'space:abc', relPath: 'boards' }, { mode: 'rw' })]\n */\nexport const capDir = (ref: { mountId: string; relPath: string }, opts: { mode: 'ro' | 'rw' }): DirCap => ({\n $cap: 'dir',\n mountId: ref.mountId,\n relPath: ref.relPath,\n mode: opts.mode,\n});\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>(task: string, params: Record<string, unknown> = {}): Promise<R> => {\n const res = (await protocolRequest(SCHEMES[PROTOCOL_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;AAC1D,SAAS,eAAe,aAAa,eAAe,kBAAkB;AACtE,SAAS,eAAe;AAmBjB,MAAM,UAAU,CAAC,KAA2C,UAA0C;AAAA,EAC3G,MAAM;AAAA,EACN,SAAS,IAAI;AAAA,EACb,SAAS,IAAI;AAAA,EACb,MAAM,KAAK;AACb;AAoBO,MAAM,SAAS,CAAC,KAA2C,UAAyC;AAAA,EACzG,MAAM;AAAA,EACN,SAAS,IAAI;AAAA,EACb,SAAS,IAAI;AAAA,EACb,MAAM,KAAK;AACb;AASO,MAAM,aAAa,OAAoB,MAAc,SAAkC,CAAC,MAAkB;AAC/G,QAAM,MAAO,MAAM,gBAAgB,QAAQ,aAAa,GAAG,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,CAAC;AAIvF,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,YAAY,CAAC,MAA0D;AACjF,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,eAAe,EAAE,OAAO,CAAC;AAGrF,MAAM,aAAa,MAAY,YAAY,aAAa,CAAC,CAAC;AAG1D,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":[]}
|
|
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()`.\n//\n// OFF-HOST (plain `vite dev`, node/jsdom tests — no sandbox, no host transport):\n// importing this module is always safe (R3-421 — no subpath may throw at import\n// time), and the surface degrades instead of crashing: `getTaskInput()` /\n// `useTaskInput()` stay `null` forever (you are never a task callee without a\n// host), `completeTask` / `cancelTask` are no-ops, and `invokeTask` rejects with\n// a \"no host transport\" error. Under the @immediately-run/dev-fs substrate the\n// transport resolves but no task ever arrives — same observable behaviour.\n// The no-op is scoped to the ABSENCE of a host: when there IS one, a failed send\n// throws instead of leaving the caller to hang out its deadline.\nimport { useEffect, useState } from 'react';\nimport { protocolRequest, sendMessage, addListener } from './sandboxUtils';\nimport { transport } from './hostTransport';\nimport { PROTOCOL_TASK, TASK_CANCEL, TASK_COMPLETE, TASK_INPUT } from './generated/protocol';\nimport { SCHEMES } from './protocolSchemes';\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 = (ref: { mountId: string; relPath: string }, opts: { mode: 'ro' | 'rw' }): FileCap => ({\n $cap: 'file',\n mountId: ref.mountId,\n relPath: ref.relPath,\n mode: opts.mode,\n});\n\n/** A delegated DIRECTORY capability marker for a task param (D2). Like {@link FileCap}\n * but `relPath` names a DIRECTORY: the host chroots the callee AT that directory\n * (the whole subtree). Used for the `pick-file` `roots` — one chroot per root. */\nexport interface DirCap {\n $cap: 'dir';\n mountId: string;\n relPath: string;\n mode: 'ro' | 'rw';\n}\n\n/**\n * Build a delegated DIRECTORY reference for a task param (the directory analogue of\n * {@link capFile}). The host resolves it against YOUR OWN grants and mints an\n * attenuated, task-scoped chroot of that directory for the callee — you can only\n * delegate a directory you already hold (attenuation only, never escalation):\n *\n * roots: [capDir({ mountId: 'space:abc', relPath: 'boards' }, { mode: 'rw' })]\n */\nexport const capDir = (ref: { mountId: string; relPath: string }, opts: { mode: 'ro' | 'rw' }): DirCap => ({\n $cap: 'dir',\n mountId: ref.mountId,\n relPath: ref.relPath,\n mode: opts.mode,\n});\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` (missing `task:invoke`, or a\n * file delegation you don't hold), `not-declared` (the task is missing from your\n * `immediately.run.invokes`), `no-such-task` (no app is bound to that contract),\n * `task-cycle`/`task-depth-exceeded`/`task-version-mismatch`, or `invalid-params`\n * (result failed the contract schema). **Read `err.message`** — since R3-418 the host\n * says which capability, which declaration or which param was at fault; the code alone\n * does not distinguish them.\n *\n * Two things must BOTH be true before any invoke is admitted, and they are separate:\n * 1. your `package.json` `immediately.run.invokes` lists the task (else `not-declared`);\n * 2. your app holds the `task:invoke` capability — declare it in\n * `immediately.run.capabilities` so the user can grant it (else `forbidden`).\n * Declaring the invoke does not imply the capability.\n *\n * ── `pick-file`: `roots` is required (SPACES_UI_SPEC §4.1) ───────────────────\n * ```ts\n * import { invokeTask, capDir, requestMount } from '@immediately-run/sdk';\n *\n * const mount = await requestMount(); // the user picks a space\n * // `invokeTask` returns `unknown` — name the result type, or the destructuring\n * // below does not compile.\n * const { root, path } = await invokeTask<{ root: number; path: string }>('pick-file', {\n * // `SandboxMount.id` is optional (absent on the primary repo mount) — fall back to\n * // `path`, which is always present and is what the host resolves against.\n * roots: [capDir({ mountId: mount.id ?? mount.path, relPath: 'boards' }, { mode: 'ro' })],\n * });\n * ```\n * - `roots` is a NON-EMPTY `DirCap[]` of directories you **already hold**. The result\n * names its target as `{ root, path }` where `root` INDEXES `params.roots`, so\n * `invokeTask('pick-file', {})` can never produce a valid result and is rejected.\n * There is no rootless \"pick from any of my spaces\" mode by design: enumerating the\n * user's spaces is the host's powerbox (`requestMount()`), and composing the two —\n * as above — is that flow. See SPACES_UI_SPEC R-SPACES-5/R-SPACES-12.\n * - Each `capDir` is attenuated against your own grant. **`{ mode: 'rw' }` over a space\n * the user granted `ro` is refused `forbidden`** — the commonest failure, because the\n * mount *was* granted and the path *is* inside it. Pass the mode you actually hold;\n * `ro` is right for a plain pick.\n * - The `requestMount()` grant is DURABLE and survives a cancelled pick: the user\n * consented to the mount in host chrome, separately from the pick (SPACES_UI_SPEC §4.1).\n * Reuse it for later picks rather than re-requesting.\n *\n * Off-host (plain `vite dev` — no host transport) it rejects with a plain\n * \"no host transport\" error: there is no host to resolve the task binding.\n */\nexport const invokeTask = async <R = unknown>(task: string, params: Record<string, unknown> = {}): Promise<R> => {\n const res = (await protocolRequest(SCHEMES[PROTOCOL_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// ── the host-provided CAPTURE contracts (R3-425) ────────────────────────────\n\n/** Bytes captured by the host, as `capturePhoto()` / `captureAudio()` return them.\n * `bytes` is a transferable `ArrayBuffer` — write it to a space, decode it, upload\n * it. You never receive a `MediaStream` or a `MediaStreamTrack`, and that is not an\n * omission: a track cannot be transferred into an app frame at all\n * (`DataCloneError`), and the frame's opaque origin cannot open a device itself\n * (`getUserMedia` throws `SecurityError: Invalid security origin`). */\nexport interface CaptureResult {\n bytes: ArrayBuffer;\n /** e.g. `image/jpeg`, `audio/webm`. Chosen by the HOST, not by you. */\n mimeType: string;\n /** How long the device was open, in ms. */\n durationMs: number;\n}\n\n/** Optional hints for a capture. They deliberately name NOTHING — no device id, no\n * camera index — because the host chooses everything about how the capture is\n * performed. That is what lets the grant be a plain on/off instead of a per-call\n * target list the way `net:fetch` needs. */\nexport interface CaptureOptions {\n /** Which way the camera should face, if the device has a choice. A HINT: the host\n * may ignore it. Ignored for audio. */\n facing?: 'user' | 'environment';\n}\n\n/**\n * Take one photo, or record one audio clip, through the HOST's capture UI\n * (`BROWSER_CAPABILITIES_SPEC` §3 grade 1).\n *\n * The host opens the device at its own origin, draws the viewfinder, and hands you\n * the bytes when the user presses Done. **You are never in the loop while the device\n * is live** — that is the point of the design, not a limitation of it:\n *\n * - The capture UI is drawn by the host, so a user can trust it the way they trust\n * the sign-in dialog. Do not build a lookalike; imitating host chrome is spoofing.\n * - While the device is open the host shows a persistent \"camera on\" / \"microphone\n * on\" indicator in its own chrome, for the whole session. You cannot hide it and\n * should not try to.\n * - If the user cancels, this rejects `cancelled` and **nothing was recorded**. There\n * is no partial result — do not write error handling that hopes for one.\n *\n * ```ts\n * import { capturePhoto, requestMount, openFs } from '@immediately-run/sdk';\n *\n * try {\n * const { bytes, mimeType } = await capturePhoto({ facing: 'environment' });\n * const mount = await requestMount(); // the user picks a space to save into\n * const fs = openFs(mount); // writeFile is a METHOD on the MountFs\n * await fs.mkdir('photos', { recursive: true }); // writeFile does not create parents\n * await fs.writeFile(`photos/latest.${mimeType === 'image/png' ? 'png' : 'jpg'}`, new Uint8Array(bytes));\n * } catch (e) {\n * if ((e as { code?: string }).code === 'cancelled') return; // the user said no\n * throw e;\n * }\n * ```\n * (The extension follows `mimeType` because the HOST chooses the format — do not assume\n * JPEG. `openAppFs()` is the variant that writes to your own app space with no pick.)\n *\n * Two things must BOTH be true, exactly as for any other task:\n * 1. `immediately.run.invokes` lists `capture-photo` (or `capture-audio`);\n * 2. your app holds `task:invoke` **and** `device:camera` (or `device:microphone`)\n * — declare them in `immediately.run.capabilities` so the user can grant them.\n *\n * Rejects with `.code`: `cancelled` (the user dismissed the capture — nothing was\n * recorded), `forbidden` (you lack the capability; `message: 'browser-denied'` means\n * the BROWSER refused immediately.run itself, which your consent cannot fix),\n * `unavailable` (no such device on this machine, or it would not start),\n * `unsupported` (this host cannot capture), `not-declared`, `timeout`.\n *\n * *Zero-platform alternative, still worth knowing:* `<input type=\"file\"\n * accept=\"image/*\" capture=\"environment\">` opens the OS camera from inside the\n * sandbox (file choosers are not permission-gated). It needs no capability and no\n * host support; it also gives you no indicator and no host-drawn surface.\n */\nexport const capturePhoto = (options: CaptureOptions = {}): Promise<CaptureResult> =>\n invokeTask<CaptureResult>('capture-photo', { ...options });\n\n/** Record one audio clip through the host's capture UI. See {@link capturePhoto} —\n * every rule there applies verbatim, with `device:microphone` and `capture-audio`. */\nexport const captureAudio = (options: CaptureOptions = {}): Promise<CaptureResult> =>\n invokeTask<CaptureResult>('capture-audio', { ...options });\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>();\nlet inputListenerRegistered = false;\n\n// Register the `task-input` listener IF a host transport is reachable; otherwise do\n// nothing (and let the next call retry — the same pattern as pushChannel's `start`).\n// Split out so both the module-eval attempt below and the first-use call sites share\n// one idempotent path.\nconst ensureInputListener = (): void => {\n if (inputListenerRegistered) return;\n try {\n addListener(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 } catch {\n return; // off-host: the transport resolver threw — no host to listen on\n }\n inputListenerRegistered = true;\n};\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\"). That wire\n// message is a plain one-shot host→app message with NO replay/poll counterpart —\n// the contract (`@immediately-run/sandbox-protocol/sdk`) marks replayable state as\n// \"push … polled with request-*\" (mounts, theme, auth-state, …) and `task-input`\n// is not one of them — so a listener registered only on first use could miss an\n// input delivered between module evaluation and the app's first render. Hence:\n// register EAGERLY when a host transport is already present at module eval\n// (on-host, byte-for-byte the pre-R3-421 behaviour), and lazily-on-first-use\n// otherwise, so importing this module off-host (plain `vite dev`) never throws.\nensureInputListener();\n\n/** The task params this app was invoked with, or null if it isn't a task callee.\n * Off-host (plain `vite dev`) this is always `null` — there is no host to invoke\n * this app as a callee. */\nexport const getTaskInput = (): TaskInput | null => {\n ensureInputListener();\n return latestInput;\n};\n\n/**\n * Is a host transport reachable from this realm at all?\n *\n * The R3-421 off-host no-op below must mean EXACTLY \"there is nobody to answer\" —\n * plain `vite dev`, node, jsdom. A blanket try/catch around the send meant it also\n * swallowed a genuine failure against a REAL host (`DataCloneError` because the\n * result holds a DOM node, a function or a live class instance, being the usual\n * one): the host was then never told the task finished, and the caller's\n * `invokeTask` hung to its deadline with no diagnostic anywhere. Absence is\n * therefore decided BEFORE the send, and the send itself is left to throw.\n */\nconst hostReachable = (): boolean => {\n try {\n transport();\n return true;\n } catch {\n return false; // no injected bundler bus and no §4 discovery global — off-host\n }\n};\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 *\n * `result` must be STRUCTURED-CLONEABLE — it crosses a frame boundary. A DOM node, a\n * function, a class instance with methods, a `MediaStreamTrack`: all `DataCloneError`.\n * **That throws**, deliberately and loudly: the alternative is a caller left hanging to\n * its `invokeTask` deadline while this app believes it answered.\n *\n * Off-host (plain `vite dev` — no host transport) this is a no-op: there is no caller\n * to answer. That case, and only that case, is silent.\n */\nexport const completeTask = (result: unknown): void => {\n if (!hostReachable()) return; // off-host: no caller to answer — documented no-op\n // On-host, a failure here is REAL and the caller is waiting on this exact message.\n sendMessage(TASK_COMPLETE, { result });\n};\n\n/** Abort the task; the caller's `invokeTask` rejects with `cancelled`.\n * Off-host (plain `vite dev` — no host transport) this is a no-op; on-host a failed\n * send throws rather than leaving the caller waiting, exactly as {@link completeTask}. */\nexport const cancelTask = (): void => {\n if (!hostReachable()) return; // off-host: no caller to answer — documented no-op\n sendMessage(TASK_CANCEL, {});\n};\n\n/** React hook: the task input for this callee, re-rendering when it arrives.\n * Off-host (plain `vite dev`) it stays `null` forever — render the non-callee\n * state rather than waiting on it. */\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":";AAqBA,SAAS,WAAW,gBAAgB;AACpC,SAAS,iBAAiB,aAAa,mBAAmB;AAC1D,SAAS,iBAAiB;AAC1B,SAAS,eAAe,aAAa,eAAe,kBAAkB;AACtE,SAAS,eAAe;AAmBjB,MAAM,UAAU,CAAC,KAA2C,UAA0C;AAAA,EAC3G,MAAM;AAAA,EACN,SAAS,IAAI;AAAA,EACb,SAAS,IAAI;AAAA,EACb,MAAM,KAAK;AACb;AAoBO,MAAM,SAAS,CAAC,KAA2C,UAAyC;AAAA,EACzG,MAAM;AAAA,EACN,SAAS,IAAI;AAAA,EACb,SAAS,IAAI;AAAA,EACb,MAAM,KAAK;AACb;AAiDO,MAAM,aAAa,OAAoB,MAAc,SAAkC,CAAC,MAAkB;AAC/G,QAAM,MAAO,MAAM,gBAAgB,QAAQ,aAAa,GAAG,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC,CAAC;AAIvF,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;AA6EO,MAAM,eAAe,CAAC,UAA0B,CAAC,MACtD,WAA0B,iBAAiB,EAAE,GAAG,QAAQ,CAAC;AAIpD,MAAM,eAAe,CAAC,UAA0B,CAAC,MACtD,WAA0B,iBAAiB,EAAE,GAAG,QAAQ,CAAC;AAU3D,IAAI,cAAgC;AACpC,MAAM,iBAAiB,oBAAI,IAA4B;AACvD,IAAI,0BAA0B;AAM9B,MAAM,sBAAsB,MAAY;AACtC,MAAI,wBAAyB;AAC7B,MAAI;AACF,gBAAY,YAAY,CAAC,MAA0D;AACjF,oBAAc,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,UAAU,CAAC,EAAE;AACrD,qBAAe,QAAQ,CAAC,MAAM,EAAE,WAAY,CAAC;AAAA,IAC/C,CAAC;AAAA,EACH,QAAQ;AACN;AAAA,EACF;AACA,4BAA0B;AAC5B;AAYA,oBAAoB;AAKb,MAAM,eAAe,MAAwB;AAClD,sBAAoB;AACpB,SAAO;AACT;AAaA,MAAM,gBAAgB,MAAe;AACnC,MAAI;AACF,cAAU;AACV,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAeO,MAAM,eAAe,CAAC,WAA0B;AACrD,MAAI,CAAC,cAAc,EAAG;AAEtB,cAAY,eAAe,EAAE,OAAO,CAAC;AACvC;AAKO,MAAM,aAAa,MAAY;AACpC,MAAI,CAAC,cAAc,EAAG;AACtB,cAAY,aAAa,CAAC,CAAC;AAC7B;AAKO,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/dist/version.cjs
CHANGED
|
@@ -21,7 +21,7 @@ __export(version_exports, {
|
|
|
21
21
|
SDK_VERSION: () => SDK_VERSION
|
|
22
22
|
});
|
|
23
23
|
module.exports = __toCommonJS(version_exports);
|
|
24
|
-
const SDK_VERSION = "0.57.
|
|
24
|
+
const SDK_VERSION = "0.57.4";
|
|
25
25
|
// Annotate the CommonJS export names for ESM import in node:
|
|
26
26
|
0 && (module.exports = {
|
|
27
27
|
SDK_VERSION
|
package/dist/version.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.57.
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.57.4';\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAIO,MAAM,cAAc;","names":[]}
|
package/dist/version.d.cts
CHANGED
package/dist/version.d.ts
CHANGED
package/dist/version.js
CHANGED
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.57.
|
|
1
|
+
{"version":3,"sources":["../src/version.ts"],"sourcesContent":["// GENERATED by scripts/gen-version.mjs from package.json — do not edit by hand.\n// Regenerated on every build (prebuild); kept honest by version.test.ts.\n\n/** This SDK's package version, baked from package.json at build (SP2-6). */\nexport const SDK_VERSION = '0.57.4';\n"],"mappings":";AAIO,MAAM,cAAc;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@immediately-run/sdk",
|
|
3
|
-
"version": "0.57.
|
|
3
|
+
"version": "0.57.4",
|
|
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",
|
|
@@ -39,11 +39,12 @@
|
|
|
39
39
|
"api:update": "node scripts/check-api-stability.mjs --update",
|
|
40
40
|
"check:pins": "node scripts/check-dependency-pins.mjs --self-test && node scripts/check-dependency-pins.mjs",
|
|
41
41
|
"check:publish-version": "node scripts/check-publish-version.mjs --self-test && node scripts/check-publish-version.mjs",
|
|
42
|
-
"verify": "npm run check:pins && npm run check:publish-version && npm run format:check && npm run check:circular && npm run check:bundler:selftest && npm run check:bundler && npm run build && npm test && npm run test:safe-content && npm run test:metadata-e2e && npm run api:selftest && npm run api:check && npm run compat:selftest && npm run compat:previous && npm run protocol:check && npm run protocol:selftest && npm run check:ambient:selftest && npm run check:ambient && npm run check:selfhost:selftest && npm run check:selfhost && npm run verify:codegen-parity",
|
|
42
|
+
"verify": "npm run check:pins && npm run check:publish-version && npm run format:check && npm run check:circular && npm run check:bundler:selftest && npm run check:bundler && npm run build && npm test && npm run test:safe-content && npm run test:metadata-e2e && npm run test:subpath-imports && npm run api:selftest && npm run api:check && npm run compat:selftest && npm run compat:previous && npm run protocol:check && npm run protocol:selftest && npm run check:ambient:selftest && npm run check:ambient && npm run check:selfhost:selftest && npm run check:selfhost && npm run verify:codegen-parity",
|
|
43
43
|
"docs": "typedoc --json docs/api.json && node scripts/gen-llms.mjs",
|
|
44
44
|
"prepublishOnly": "npm run check:circular && npm run build && npm run api:selftest && npm run api:check",
|
|
45
45
|
"test:safe-content": "node scripts/build-safecontent-e2e.mjs && node --test test/safeContent.e2e.mjs",
|
|
46
46
|
"test:metadata-e2e": "node --test test/metadataHooks.e2e.mjs",
|
|
47
|
+
"test:subpath-imports": "node --test test/subpathImports.e2e.mjs",
|
|
47
48
|
"protocol:selftest": "node scripts/check-protocol-snapshot.mjs --self-test",
|
|
48
49
|
"compat:previous": "node scripts/check-previous-sdk-compat.mjs",
|
|
49
50
|
"compat:selftest": "node scripts/check-previous-sdk-compat.mjs --self-test",
|
|
@@ -60,11 +61,11 @@
|
|
|
60
61
|
"react-dom": "^19.0.0"
|
|
61
62
|
},
|
|
62
63
|
"dependencies": {
|
|
64
|
+
"@immediately-run/mdx-plugins": "0.5.0",
|
|
63
65
|
"@immediately-run/platform-constants": "0.2.0",
|
|
64
|
-
"@immediately-run/sandbox-protocol": "0.7.1",
|
|
65
|
-
"react-error-boundary": "^6.0.0",
|
|
66
66
|
"@immediately-run/safe-content": "0.1.0",
|
|
67
|
-
"@immediately-run/
|
|
67
|
+
"@immediately-run/sandbox-protocol": "0.7.6",
|
|
68
|
+
"react-error-boundary": "^6.0.0"
|
|
68
69
|
},
|
|
69
70
|
"devDependencies": {
|
|
70
71
|
"@immediately-run/prettier-config": "0.1.0",
|