mindwire 0.1.42 → 0.1.44

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/run.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import type { Http } from "./http.js";
2
- import type { Event, ResultInfo, RespondInput, RunSnapshot, Run as RunData } from "./types.js";
2
+ import type { Attachment, Event, ResultInfo, RespondInput, RunSnapshot, Run as RunData } from "./types.js";
3
3
  export interface StreamOptions {
4
4
  signal?: AbortSignal;
5
5
  /** Resume after a snapshot/event cursor without replaying earlier output. */
@@ -64,7 +64,10 @@ export declare class Run {
64
64
  * Steer a follow-up message into the running turn without cancelling it. Requires the agent's
65
65
  * `input` capability.
66
66
  */
67
- sendInput(text: string): Promise<void>;
67
+ sendInput(text: string, options?: {
68
+ requestId?: string;
69
+ attachments?: Attachment[];
70
+ }): Promise<void>;
68
71
  /**
69
72
  * Soft-stop the running turn (ask the agent to halt current work) without the hard process kill
70
73
  * {@link Run.cancel} does — the turn stays open for a follow-up via {@link Run.sendInput}.
@@ -4,6 +4,15 @@ export interface SurfaceGeometry {
4
4
  height: number;
5
5
  revision: number;
6
6
  }
7
+ /** Actual remote cursor. The base64 PNG changes only with its shape, not its position. */
8
+ export interface SurfaceCursor {
9
+ id: string;
10
+ width: number;
11
+ height: number;
12
+ hotspotX: number;
13
+ hotspotY: number;
14
+ png: string;
15
+ }
7
16
  export interface SurfaceProblem {
8
17
  code: string;
9
18
  message: string;
@@ -33,6 +42,7 @@ export interface SurfaceSnapshot {
33
42
  workspaceId: string;
34
43
  kind: "desktop";
35
44
  provider: "oblien" | "macos";
45
+ desktopId?: string;
36
46
  version: number;
37
47
  revision: number;
38
48
  instanceId: string;
@@ -45,6 +55,7 @@ export interface SurfaceSnapshot {
45
55
  os?: string;
46
56
  capabilities: SurfaceCapabilities;
47
57
  geometry?: SurfaceGeometry;
58
+ cursor?: SurfaceCursor;
48
59
  controller?: SurfaceController;
49
60
  authorizationExpiresAt?: string;
50
61
  error?: SurfaceProblem;
@@ -70,8 +81,10 @@ export interface SurfaceBinding {
70
81
  registryId: string;
71
82
  workspaceId: string;
72
83
  gatewayToken?: string;
84
+ desktopId?: string;
73
85
  connection: {
74
86
  expires_at: string;
87
+ session_id?: string;
75
88
  ssh: {
76
89
  host: string;
77
90
  port: number;
@@ -91,6 +104,7 @@ export interface SurfaceSession {
91
104
  surfaceId: string;
92
105
  actor: "user" | "agent";
93
106
  name: string;
107
+ desktopId?: string;
94
108
  chatId?: string;
95
109
  runId?: string;
96
110
  mode: "view" | "control";
@@ -101,6 +115,7 @@ export interface SurfaceOpenRequest {
101
115
  requestId: string;
102
116
  name?: string;
103
117
  mode: "view" | "control";
118
+ desktopId?: string;
104
119
  }
105
120
  export interface SurfaceControlRequest {
106
121
  action: "acquire" | "takeover" | "release" | "renew";
@@ -136,7 +151,7 @@ export interface SurfaceReceipt {
136
151
  sessionId: string;
137
152
  surfaceId: string;
138
153
  kind: string;
139
- status: "dispatching" | "dispatched" | "outcome_unknown";
154
+ status: "dispatching" | "dispatched" | "outcome_unknown" | "cancelled";
140
155
  createdAt: string;
141
156
  error?: SurfaceProblem;
142
157
  /** Transient clipboard output, not stored in the receipt. */
@@ -167,6 +182,7 @@ export interface SurfaceToolAction {
167
182
  sessionId?: string;
168
183
  receiptId?: string;
169
184
  status?: string;
185
+ desktopId?: string;
170
186
  capture?: {
171
187
  id: string;
172
188
  artifactId: string;
@@ -174,10 +190,86 @@ export interface SurfaceToolAction {
174
190
  height: number;
175
191
  };
176
192
  }
177
- /** Workspace-scoped API. One controller is shared by every harness and app client. */
193
+ /** Private workspace runtime authorization, never an account/session credential. */
194
+ export interface DesktopRuntimeBinding {
195
+ registryId: string;
196
+ workspaceId: string;
197
+ gatewayToken: string;
198
+ expiresAt?: string;
199
+ }
200
+ export interface DesktopResolution {
201
+ width: number;
202
+ height: number;
203
+ }
204
+ export interface SavedDesktop {
205
+ id: string;
206
+ name: string;
207
+ state: string;
208
+ managed: boolean;
209
+ available: boolean;
210
+ resolution?: DesktopResolution;
211
+ mode?: string;
212
+ can_resize?: boolean;
213
+ can_delete?: boolean;
214
+ deletion_pending?: boolean;
215
+ created_at?: string;
216
+ updated_at?: string;
217
+ error?: string;
218
+ }
219
+ export interface DesktopCatalog {
220
+ success: boolean;
221
+ projectId?: string;
222
+ sessions: SavedDesktop[];
223
+ capabilities: {
224
+ mode: "virtual" | "console";
225
+ max_sessions: number;
226
+ can_create: boolean;
227
+ resolution?: {
228
+ min: DesktopResolution;
229
+ max: DesktopResolution;
230
+ default: DesktopResolution;
231
+ };
232
+ };
233
+ }
234
+ export interface SavedDesktopResult {
235
+ success: boolean;
236
+ session: SavedDesktop;
237
+ }
238
+ export interface CreateSavedDesktop {
239
+ /** Reuse the same ID and body after an interrupted response. */
240
+ requestId: string;
241
+ projectId?: string;
242
+ name: string;
243
+ resolution?: DesktopResolution;
244
+ }
245
+ export interface UpdateSavedDesktop {
246
+ name?: string;
247
+ resolution?: DesktopResolution;
248
+ }
249
+ /** One controller per saved desktop, shared by every harness and app client. */
178
250
  export declare class SurfacesApi {
179
251
  private readonly mw;
180
- constructor(mw: Mindwire);
252
+ private readonly desktopId?;
253
+ constructor(mw: Mindwire, desktopId?: string | undefined);
254
+ /** Select a saved display for status, events, captures and input receipts. */
255
+ desktop(id: string): SurfacesApi;
256
+ private scoped;
257
+ bindRuntime(binding: DesktopRuntimeBinding): Promise<{
258
+ configured: boolean;
259
+ }>;
260
+ listDesktops(projectId?: string): Promise<DesktopCatalog>;
261
+ createDesktop(request: CreateSavedDesktop): Promise<SavedDesktopResult>;
262
+ ensureProjectDesktop(projectId: string): Promise<SavedDesktopResult>;
263
+ getDesktop(id: string): Promise<SavedDesktopResult>;
264
+ updateDesktop(id: string, request: UpdateSavedDesktop): Promise<SavedDesktopResult>;
265
+ startDesktop(id: string): Promise<SavedDesktopResult>;
266
+ /** Stops this desktop's apps; keeps its profile and files. */
267
+ stopDesktop(id: string): Promise<SavedDesktopResult>;
268
+ /** Deletes the desktop's private profile. Closing a viewer uses close(), never this method. */
269
+ deleteDesktop(id: string): Promise<{
270
+ success: boolean;
271
+ session?: SavedDesktop;
272
+ }>;
181
273
  list(): Promise<SurfaceSnapshot[]>;
182
274
  status(refresh?: boolean): Promise<SurfaceSnapshot>;
183
275
  bind(binding: SurfaceBinding): Promise<SurfaceSnapshot>;
package/dist/types.d.ts CHANGED
@@ -9,7 +9,7 @@
9
9
  * escape hatch so a newer daemon adding a variant does not break older SDK builds.
10
10
  */
11
11
  /** One kind of unified streaming event. Every adapter normalizes native output into these. */
12
- export type EventType = "session" | "text" | "thinking" | "tool_use" | "tool_result" | "result" | "error" | "status" | "interaction" | "compaction" | "continuation";
12
+ export type EventType = "session" | "text" | "thinking" | "tool_use" | "tool_result" | "result" | "error" | "status" | "input" | "interaction" | "compaction" | "continuation";
13
13
  export interface ToolEvent {
14
14
  id?: string;
15
15
  name?: string;
@@ -152,6 +152,7 @@ export interface Event {
152
152
  compaction?: CompactionInfo;
153
153
  /** Populated on a `continuation` event (resolve mode). */
154
154
  continuation?: ContinuationInfo;
155
+ input?: UserInput;
155
156
  error?: string;
156
157
  meta?: Record<string, unknown>;
157
158
  /** RFC3339 timestamp. */
@@ -286,6 +287,7 @@ export interface Capabilities {
286
287
  /** User-in-loop ingress — each gates its route: answer an interaction, inject a follow-up, soft-stop. */
287
288
  respond: boolean;
288
289
  input: boolean;
290
+ queuedInput?: boolean;
289
291
  interrupt: boolean;
290
292
  /** Runtime control — switch the model / permission mode of a live turn (persistent transport only). */
291
293
  setModel: boolean;
@@ -667,8 +669,18 @@ export interface Part {
667
669
  interaction?: Interaction;
668
670
  /** Set on a `compaction` part — a conversation boundary in the reloaded transcript. */
669
671
  compaction?: CompactionInfo;
672
+ input?: UserInput;
670
673
  at?: string;
671
674
  }
675
+ /** Durable follow-up; queued messages belong to the daemon, including while a client is disconnected. */
676
+ export interface UserInput {
677
+ id: string;
678
+ text: string;
679
+ attachments?: Attachment[];
680
+ createdAt: string;
681
+ status: "queued" | "accepted" | "failed" | "cancelled" | (string & {});
682
+ error?: string;
683
+ }
672
684
  export interface Message {
673
685
  id: string;
674
686
  chatId: string;
@@ -760,6 +772,9 @@ export interface ResolveOptions {
760
772
  * Inline image content blocks require the persistent transport and are a follow-on.
761
773
  */
762
774
  export interface Attachment {
775
+ /** Completed upload belonging to this conversation. No inline bytes are needed. */
776
+ artifactId?: string;
777
+ bytes?: number;
763
778
  /** Display/file name shown to the agent when the file is referenced. */
764
779
  name?: string;
765
780
  /** Absolute path to a file already on disk (preferred). */
@@ -793,6 +808,8 @@ export interface Run {
793
808
  stopReason?: "done" | "capped" | "error" | "cancelled" | (string & {});
794
809
  /** Parent-only: how many child turns the resolve loop ran. */
795
810
  iterations?: number;
811
+ inputs?: UserInput[];
812
+ messageIds?: string[];
796
813
  }
797
814
  /** The daemon's view of a chat, for a sessions list. */
798
815
  export interface ChatSummary {
@@ -851,10 +868,12 @@ export interface HarnessSoftware {
851
868
  installedVersion: string;
852
869
  recommendedVersion?: string;
853
870
  latestVersion?: string;
854
- compatibility: "supported" | "untested" | "incompatible" | "not_installed" | (string & {});
871
+ compatibility: "supported" | "untested" | "incompatible" | "unavailable" | "not_installed" | (string & {});
855
872
  managed: boolean;
856
873
  updateAvailable: boolean;
857
874
  requiresDaemonUpdate: boolean;
875
+ /** An explicitly requested update can repair this damaged managed installation. */
876
+ repairAvailable?: boolean;
858
877
  requiredDaemonVersion?: string;
859
878
  message?: string;
860
879
  catalogRevision: number;
@@ -1006,6 +1025,8 @@ export interface Health {
1006
1025
  localDesktopVersion?: number;
1007
1026
  /** Workspace registry protocol version; absent on daemons predating workspace metadata. */
1008
1027
  workspaceMetadataVersion?: number;
1028
+ /** Durable project folders, membership and ordering, with conditional edits. */
1029
+ projectLibraryVersion?: number;
1009
1030
  /** Durable project creation/clone operations; absent on older daemons. */
1010
1031
  projectOperationsVersion?: number;
1011
1032
  /** Project-relative icons and authenticated image previews. */
@@ -1032,9 +1053,11 @@ export interface Health {
1032
1053
  workspaceExecutionVersion?: number;
1033
1054
  terminalProtocolVersion?: number;
1034
1055
  turnRequestVersion?: number;
1056
+ queuedInputVersion?: number;
1035
1057
  chatForkVersion?: number;
1036
1058
  /** Image-only input and image attachments retained in message history. */
1037
1059
  imageAttachmentsVersion?: number;
1060
+ attachmentUploadVersion?: number;
1038
1061
  computerConnectionVersion?: number;
1039
1062
  workspaceIsolation?: "direct" | "container";
1040
1063
  }
@@ -1106,3 +1129,22 @@ export interface ProcessFrame {
1106
1129
  export interface ApiErrorBody {
1107
1130
  error: string;
1108
1131
  }
1132
+ /** One resumable 384 KiB chunk. The SHA-256 covers the complete file. */
1133
+ export interface AttachmentUploadChunk {
1134
+ name: string;
1135
+ mime: string;
1136
+ bytes: number;
1137
+ sha256: string;
1138
+ offset: number;
1139
+ data: string;
1140
+ }
1141
+ export interface AttachmentUploadState {
1142
+ id: string;
1143
+ chatId: string;
1144
+ name: string;
1145
+ mime: string;
1146
+ bytes: number;
1147
+ sha256: string;
1148
+ offset: number;
1149
+ complete: boolean;
1150
+ }
@@ -211,6 +211,32 @@ export interface WorkspaceImport {
211
211
  id: string;
212
212
  })[];
213
213
  }
214
+ export interface ProjectFolder {
215
+ id: string;
216
+ name: string;
217
+ }
218
+ /** Daemon-owned grouping and manual order; all IDs refer to this workspace. */
219
+ export interface ProjectLibrary {
220
+ version: number;
221
+ revision: number;
222
+ folders: ProjectFolder[];
223
+ membership: Record<string, string>;
224
+ order: string[];
225
+ }
226
+ /** Partial atomic edit. On 409, read the current library before deciding how to rebase. */
227
+ export interface ProjectLibraryEdit {
228
+ expectedRevision: number;
229
+ folders?: ProjectFolder[];
230
+ deleteFolders?: string[];
231
+ placements?: {
232
+ projectId: string;
233
+ folderId: string | null;
234
+ }[];
235
+ order?: string[];
236
+ folderOrder?: string[];
237
+ /** Migration only: existing daemon organization always wins. */
238
+ importIfEmpty?: boolean;
239
+ }
214
240
  export interface WorkspaceSnapshot {
215
241
  version: number;
216
242
  workspaceId: string;
@@ -231,6 +257,8 @@ export interface WorkspaceSnapshot {
231
257
  agent: string;
232
258
  message: string;
233
259
  }[];
260
+ /** Present on full snapshots, or when organization changed in a delta. */
261
+ projectLibrary?: ProjectLibrary;
234
262
  }
235
263
  export declare class WorkspaceCollection<T extends WorkspaceRecord> {
236
264
  private readonly mw;
@@ -257,6 +285,8 @@ export declare class WorkspaceApi {
257
285
  snapshot(options?: {
258
286
  refresh?: boolean;
259
287
  }): Promise<WorkspaceSnapshot>;
288
+ library(): Promise<ProjectLibrary>;
289
+ editLibrary(edit: ProjectLibraryEdit): Promise<ProjectLibrary>;
260
290
  /** Read the saved icon, or preview a candidate relative path within the project. Requires projectIconsVersion >= 1. */
261
291
  projectIcon(projectId: string, path?: string): Promise<ProjectIcon>;
262
292
  /** Start an operation owned by the daemon. The same ID/payload returns the existing operation. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mindwire",
3
- "version": "0.1.42",
3
+ "version": "0.1.44",
4
4
  "main": "./dist/index.cjs",
5
5
  "module": "./dist/index.js",
6
6
  "bin": {
@@ -1,51 +0,0 @@
1
- import { MindwireError } from './chunk-T6TD76UA.js';
2
-
3
- // src/binary-cache.ts
4
- async function binaryCacheDirectory(platform = process.platform) {
5
- const path = await import('path');
6
- const { homedir } = await import('os');
7
- const homeDirectory = homedir();
8
- return platform === "darwin" ? path.join(homeDirectory, "Library", "Caches", "mindwire") : platform === "win32" ? path.join(process.env.LOCALAPPDATA ?? homeDirectory, "mindwire", "Cache") : path.join(process.env.XDG_CACHE_HOME ?? path.join(homeDirectory, ".cache"), "mindwire");
9
- }
10
- async function executableChecksum(bytes) {
11
- const { createHash } = await import('crypto');
12
- return createHash("sha256").update(bytes).digest("hex");
13
- }
14
- async function verifyReleaseBytes(bytes, expected, name) {
15
- if (!/^[a-f0-9]{64}$/i.test(expected) || await executableChecksum(bytes) !== expected.toLowerCase()) {
16
- throw new MindwireError(`mindwire: checksum verification failed for ${name}`);
17
- }
18
- }
19
- async function cachedExecutable(bin) {
20
- const fs = await import('fs/promises');
21
- try {
22
- const [bytes, checksum] = await Promise.all([fs.readFile(bin), fs.readFile(`${bin}.sha256`, "utf8")]);
23
- await verifyReleaseBytes(bytes, checksum.trim(), bin);
24
- return bin;
25
- } catch {
26
- return void 0;
27
- }
28
- }
29
- async function cacheExecutable(bin, bytes, expected) {
30
- await verifyReleaseBytes(bytes, expected, bin);
31
- const fs = await import('fs/promises');
32
- const { dirname } = await import('path');
33
- const { randomUUID } = await import('crypto');
34
- await fs.mkdir(dirname(bin), { recursive: true, mode: 448 });
35
- const temp = `${bin}.${randomUUID()}.tmp`;
36
- try {
37
- await fs.writeFile(temp, bytes, { mode: 493, flag: "wx" });
38
- await fs.writeFile(`${temp}.sha256`, `${expected.toLowerCase()}
39
- `, { mode: 384, flag: "wx" });
40
- await fs.rename(temp, bin);
41
- await fs.rename(`${temp}.sha256`, `${bin}.sha256`);
42
- return bin;
43
- } finally {
44
- await fs.rm(temp, { force: true });
45
- await fs.rm(`${temp}.sha256`, { force: true });
46
- }
47
- }
48
-
49
- export { binaryCacheDirectory, cacheExecutable, cachedExecutable, executableChecksum, verifyReleaseBytes };
50
- //# sourceMappingURL=binary-cache-ZTEYICUF.js.map
51
- //# sourceMappingURL=binary-cache-ZTEYICUF.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/binary-cache.ts"],"names":[],"mappings":";;;AAIA,eAAsB,oBAAA,CAAqB,QAAA,GAAW,OAAA,CAAQ,QAAA,EAA2B;AACvF,EAAA,MAAM,IAAA,GAAO,MAAM,OAAO,MAAW,CAAA;AACrC,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,MAAM,OAAO,IAAS,CAAA;AAC1C,EAAA,MAAM,gBAAgB,OAAA,EAAQ;AAC9B,EAAA,OAAO,QAAA,KAAa,QAAA,GAAW,IAAA,CAAK,IAAA,CAAK,aAAA,EAAe,SAAA,EAAW,QAAA,EAAU,UAAU,CAAA,GACnF,QAAA,KAAa,OAAA,GAAU,IAAA,CAAK,KAAK,OAAA,CAAQ,GAAA,CAAI,YAAA,IAAgB,aAAA,EAAe,UAAA,EAAY,OAAO,CAAA,GAC/F,IAAA,CAAK,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,cAAA,IAAkB,IAAA,CAAK,IAAA,CAAK,aAAA,EAAe,QAAQ,GAAG,UAAU,CAAA;AAC5F;AAEA,eAAsB,mBAAmB,KAAA,EAAoC;AAC3E,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,MAAM,OAAO,QAAa,CAAA;AACjD,EAAA,OAAO,WAAW,QAAQ,CAAA,CAAE,OAAO,KAAK,CAAA,CAAE,OAAO,KAAK,CAAA;AACxD;AAEA,eAAsB,kBAAA,CAAmB,KAAA,EAAmB,QAAA,EAAkB,IAAA,EAA6B;AACzG,EAAA,IAAI,CAAC,iBAAA,CAAkB,IAAA,CAAK,QAAQ,CAAA,IAAK,MAAM,kBAAA,CAAmB,KAAK,CAAA,KAAM,QAAA,CAAS,WAAA,EAAY,EAAG;AACnG,IAAA,MAAM,IAAI,aAAA,CAAc,CAAA,2CAAA,EAA8C,IAAI,CAAA,CAAE,CAAA;AAAA,EAC9E;AACF;AAEA,eAAsB,iBAAiB,GAAA,EAA0C;AAC/E,EAAA,MAAM,EAAA,GAAK,MAAM,OAAO,aAAkB,CAAA;AAC1C,EAAA,IAAI;AACF,IAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,IAAI,MAAM,OAAA,CAAQ,IAAI,CAAC,EAAA,CAAG,SAAS,GAAG,CAAA,EAAG,GAAG,QAAA,CAAS,CAAA,EAAG,GAAG,CAAA,OAAA,CAAA,EAAW,MAAM,CAAC,CAAC,CAAA;AACpG,IAAA,MAAM,kBAAA,CAAmB,KAAA,EAAO,QAAA,CAAS,IAAA,IAAQ,GAAG,CAAA;AACpD,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAAE,IAAA,OAAO,MAAA;AAAA,EAAW;AAC9B;AAEA,eAAsB,eAAA,CAAgB,GAAA,EAAa,KAAA,EAAmB,QAAA,EAAmC;AACvG,EAAA,MAAM,kBAAA,CAAmB,KAAA,EAAO,QAAA,EAAU,GAAG,CAAA;AAC7C,EAAA,MAAM,EAAA,GAAK,MAAM,OAAO,aAAkB,CAAA;AAC1C,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,MAAM,OAAO,MAAW,CAAA;AAC5C,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,MAAM,OAAO,QAAa,CAAA;AACjD,EAAA,MAAM,EAAA,CAAG,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,EAAG,EAAE,SAAA,EAAW,IAAA,EAAM,IAAA,EAAM,GAAA,EAAO,CAAA;AAE7D,EAAA,MAAM,IAAA,GAAO,CAAA,EAAG,GAAG,CAAA,CAAA,EAAI,YAAY,CAAA,IAAA,CAAA;AACnC,EAAA,IAAI;AACF,IAAA,MAAM,EAAA,CAAG,UAAU,IAAA,EAAM,KAAA,EAAO,EAAE,IAAA,EAAM,GAAA,EAAO,IAAA,EAAM,IAAA,EAAM,CAAA;AAC3D,IAAA,MAAM,EAAA,CAAG,UAAU,CAAA,EAAG,IAAI,WAAW,CAAA,EAAG,QAAA,CAAS,aAAa;AAAA,CAAA,EAAM,EAAE,IAAA,EAAM,GAAA,EAAO,IAAA,EAAM,MAAM,CAAA;AAC/F,IAAA,MAAM,EAAA,CAAG,MAAA,CAAO,IAAA,EAAM,GAAG,CAAA;AACzB,IAAA,MAAM,GAAG,MAAA,CAAO,CAAA,EAAG,IAAI,CAAA,OAAA,CAAA,EAAW,CAAA,EAAG,GAAG,CAAA,OAAA,CAAS,CAAA;AACjD,IAAA,OAAO,GAAA;AAAA,EACT,CAAA,SAAE;AACA,IAAA,MAAM,GAAG,EAAA,CAAG,IAAA,EAAM,EAAE,KAAA,EAAO,MAAM,CAAA;AACjC,IAAA,MAAM,EAAA,CAAG,GAAG,CAAA,EAAG,IAAI,WAAW,EAAE,KAAA,EAAO,MAAM,CAAA;AAAA,EAC/C;AACF","file":"binary-cache-ZTEYICUF.js","sourcesContent":["// Shared verified executable cache for the daemon and optional connection helpers.\n// Node modules stay lazy so importing the SDK in a browser remains supported.\nimport { MindwireError } from \"./errors.js\";\n\nexport async function binaryCacheDirectory(platform = process.platform): Promise<string> {\n const path = await import(\"node:path\");\n const { homedir } = await import(\"node:os\");\n const homeDirectory = homedir();\n return platform === \"darwin\" ? path.join(homeDirectory, \"Library\", \"Caches\", \"mindwire\")\n : platform === \"win32\" ? path.join(process.env.LOCALAPPDATA ?? homeDirectory, \"mindwire\", \"Cache\")\n : path.join(process.env.XDG_CACHE_HOME ?? path.join(homeDirectory, \".cache\"), \"mindwire\");\n}\n\nexport async function executableChecksum(bytes: Uint8Array): Promise<string> {\n const { createHash } = await import(\"node:crypto\");\n return createHash(\"sha256\").update(bytes).digest(\"hex\");\n}\n\nexport async function verifyReleaseBytes(bytes: Uint8Array, expected: string, name: string): Promise<void> {\n if (!/^[a-f0-9]{64}$/i.test(expected) || await executableChecksum(bytes) !== expected.toLowerCase()) {\n throw new MindwireError(`mindwire: checksum verification failed for ${name}`);\n }\n}\n\nexport async function cachedExecutable(bin: string): Promise<string | undefined> {\n const fs = await import(\"node:fs/promises\");\n try {\n const [bytes, checksum] = await Promise.all([fs.readFile(bin), fs.readFile(`${bin}.sha256`, \"utf8\")]);\n await verifyReleaseBytes(bytes, checksum.trim(), bin);\n return bin;\n } catch { return undefined; }\n}\n\nexport async function cacheExecutable(bin: string, bytes: Uint8Array, expected: string): Promise<string> {\n await verifyReleaseBytes(bytes, expected, bin);\n const fs = await import(\"node:fs/promises\");\n const { dirname } = await import(\"node:path\");\n const { randomUUID } = await import(\"node:crypto\");\n await fs.mkdir(dirname(bin), { recursive: true, mode: 0o700 });\n // Unique temporary names also cover concurrent acquisitions in the same process.\n const temp = `${bin}.${randomUUID()}.tmp`;\n try {\n await fs.writeFile(temp, bytes, { mode: 0o755, flag: \"wx\" });\n await fs.writeFile(`${temp}.sha256`, `${expected.toLowerCase()}\\n`, { mode: 0o600, flag: \"wx\" });\n await fs.rename(temp, bin);\n await fs.rename(`${temp}.sha256`, `${bin}.sha256`);\n return bin;\n } finally {\n await fs.rm(temp, { force: true });\n await fs.rm(`${temp}.sha256`, { force: true });\n }\n}\n"]}
@@ -1,57 +0,0 @@
1
- // src/errors.ts
2
- var MindwireError = class extends Error {
3
- constructor(message, options) {
4
- super(message, options);
5
- this.name = "MindwireError";
6
- }
7
- };
8
- var ApiError = class _ApiError extends MindwireError {
9
- status;
10
- url;
11
- method;
12
- body;
13
- constructor(args) {
14
- super(_ApiError.messageFor(args));
15
- this.name = "ApiError";
16
- this.status = args.status;
17
- this.url = args.url;
18
- this.method = args.method;
19
- this.body = args.body;
20
- }
21
- static messageFor({
22
- status,
23
- method,
24
- url,
25
- body
26
- }) {
27
- const detail = body && typeof body === "object" && "error" in body && typeof body.error === "string" ? body.error : typeof body === "string" && body.trim() !== "" ? body.trim() : "";
28
- const base = `${method} ${url} failed with ${status}`;
29
- return detail ? `${base}: ${detail}` : base;
30
- }
31
- };
32
- var RunFailedError = class extends MindwireError {
33
- status;
34
- runId;
35
- constructor(runId, status, detail) {
36
- super(detail ? `run ${runId} ${status}: ${detail}` : `run ${runId} ${status}`);
37
- this.name = "RunFailedError";
38
- this.runId = runId;
39
- this.status = status;
40
- }
41
- };
42
- var TimeoutError = class extends MindwireError {
43
- method;
44
- path;
45
- timeoutMs;
46
- constructor(method, path, timeoutMs) {
47
- super(`mindwire: ${method} ${path} timed out after ${timeoutMs}ms`);
48
- this.name = "TimeoutError";
49
- this.method = method;
50
- this.path = path;
51
- this.timeoutMs = timeoutMs;
52
- }
53
- };
54
-
55
- export { ApiError, MindwireError, RunFailedError, TimeoutError };
56
- //# sourceMappingURL=chunk-T6TD76UA.js.map
57
- //# sourceMappingURL=chunk-T6TD76UA.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/errors.ts"],"names":[],"mappings":";AACO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EACvC,WAAA,CAAY,SAAiB,OAAA,EAA+B;AAC1D,IAAA,KAAA,CAAM,SAAS,OAAO,CAAA;AACtB,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AAAA,EACd;AACF;AAMO,IAAM,QAAA,GAAN,MAAM,SAAA,SAAiB,aAAA,CAAc;AAAA,EACjC,MAAA;AAAA,EACA,GAAA;AAAA,EACA,MAAA;AAAA,EACA,IAAA;AAAA,EAET,YAAY,IAAA,EAAsE;AAChF,IAAA,KAAA,CAAM,SAAA,CAAS,UAAA,CAAW,IAAI,CAAC,CAAA;AAC/B,IAAA,IAAA,CAAK,IAAA,GAAO,UAAA;AACZ,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,MAAM,IAAA,CAAK,GAAA;AAChB,IAAA,IAAA,CAAK,SAAS,IAAA,CAAK,MAAA;AACnB,IAAA,IAAA,CAAK,OAAO,IAAA,CAAK,IAAA;AAAA,EACnB;AAAA,EAEA,OAAe,UAAA,CAAW;AAAA,IACxB,MAAA;AAAA,IACA,MAAA;AAAA,IACA,GAAA;AAAA,IACA;AAAA,GACF,EAKW;AACT,IAAA,MAAM,MAAA,GACJ,QAAQ,OAAO,IAAA,KAAS,YAAY,OAAA,IAAW,IAAA,IAAQ,OAAO,IAAA,CAAK,KAAA,KAAU,QAAA,GACzE,KAAK,KAAA,GACL,OAAO,SAAS,QAAA,IAAY,IAAA,CAAK,MAAK,KAAM,EAAA,GAC1C,IAAA,CAAK,IAAA,EAAK,GACV,EAAA;AACR,IAAA,MAAM,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,GAAG,gBAAgB,MAAM,CAAA,CAAA;AACnD,IAAA,OAAO,MAAA,GAAS,CAAA,EAAG,IAAI,CAAA,EAAA,EAAK,MAAM,CAAA,CAAA,GAAK,IAAA;AAAA,EACzC;AACF;AASO,IAAM,cAAA,GAAN,cAA6B,aAAA,CAAc;AAAA,EACvC,MAAA;AAAA,EACA,KAAA;AAAA,EAET,WAAA,CAAY,KAAA,EAAe,MAAA,EAAgB,MAAA,EAAiB;AAC1D,IAAA,KAAA,CAAM,MAAA,GAAS,CAAA,IAAA,EAAO,KAAK,CAAA,CAAA,EAAI,MAAM,CAAA,EAAA,EAAK,MAAM,CAAA,CAAA,GAAK,CAAA,IAAA,EAAO,KAAK,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE,CAAA;AAC7E,IAAA,IAAA,CAAK,IAAA,GAAO,gBAAA;AACZ,IAAA,IAAA,CAAK,KAAA,GAAQ,KAAA;AACb,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AACF;AAOO,IAAM,YAAA,GAAN,cAA2B,aAAA,CAAc;AAAA,EACrC,MAAA;AAAA,EACA,IAAA;AAAA,EACA,SAAA;AAAA,EAET,WAAA,CAAY,MAAA,EAAgB,IAAA,EAAc,SAAA,EAAmB;AAC3D,IAAA,KAAA,CAAM,aAAa,MAAM,CAAA,CAAA,EAAI,IAAI,CAAA,iBAAA,EAAoB,SAAS,CAAA,EAAA,CAAI,CAAA;AAClE,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA;AACZ,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AAAA,EACnB;AACF","file":"chunk-T6TD76UA.js","sourcesContent":["/** Base class for every error thrown by the SDK. */\nexport class MindwireError extends Error {\n constructor(message: string, options?: { cause?: unknown }) {\n super(message, options);\n this.name = \"MindwireError\";\n }\n}\n\n/**\n * A non-2xx HTTP response from the daemon. `body` is the parsed JSON error payload when the\n * daemon returned one (it uses `{ \"error\": \"...\" }`), otherwise the raw text.\n */\nexport class ApiError extends MindwireError {\n readonly status: number;\n readonly url: string;\n readonly method: string;\n readonly body: unknown;\n\n constructor(args: { status: number; url: string; method: string; body: unknown }) {\n super(ApiError.messageFor(args));\n this.name = \"ApiError\";\n this.status = args.status;\n this.url = args.url;\n this.method = args.method;\n this.body = args.body;\n }\n\n private static messageFor({\n status,\n method,\n url,\n body,\n }: {\n status: number;\n method: string;\n url: string;\n body: unknown;\n }): string {\n const detail =\n body && typeof body === \"object\" && \"error\" in body && typeof body.error === \"string\"\n ? body.error\n : typeof body === \"string\" && body.trim() !== \"\"\n ? body.trim()\n : \"\";\n const base = `${method} ${url} failed with ${status}`;\n return detail ? `${base}: ${detail}` : base;\n }\n}\n\n/**\n * Thrown by {@link import(\"./run.js\").Run.wait} when a run ends in a non-success terminal state\n * (`error`/`cancelled`), or when the event stream ends before the run reaches any terminal state —\n * a dropped/truncated stream. The `status` is whatever the run was in when `wait()` gave up, so a\n * truncated stream surfaces as e.g. `run <id> running: event stream ended …` rather than silently\n * returning a success-shaped result.\n */\nexport class RunFailedError extends MindwireError {\n readonly status: string;\n readonly runId: string;\n\n constructor(runId: string, status: string, detail?: string) {\n super(detail ? `run ${runId} ${status}: ${detail}` : `run ${runId} ${status}`);\n this.name = \"RunFailedError\";\n this.runId = runId;\n this.status = status;\n }\n}\n\n/**\n * Thrown when a unary request exceeds the client's `requestTimeoutMs` deadline. A hung daemon or a\n * dead tunnel would otherwise block the caller forever; this bounds every non-streaming call. SSE\n * streams are long-lived and are never subject to this timeout.\n */\nexport class TimeoutError extends MindwireError {\n readonly method: string;\n readonly path: string;\n readonly timeoutMs: number;\n\n constructor(method: string, path: string, timeoutMs: number) {\n super(`mindwire: ${method} ${path} timed out after ${timeoutMs}ms`);\n this.name = \"TimeoutError\";\n this.method = method;\n this.path = path;\n this.timeoutMs = timeoutMs;\n }\n}\n"]}