@ricsam/r5d-worker 0.0.125 → 0.0.126

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/README.md CHANGED
@@ -94,3 +94,7 @@ Cancellation is checked again immediately before spawn. A `cancel` carrying `sco
94
94
  When the connected `r5d-browser` requests a port forward, the worker opens each relayed connection only to `127.0.0.1` on the requested worker port. Browser-side and worker-side ports may differ. The worker never opens a public listener, and a disconnected worker leaves the browser's long-lived mapping unavailable until the same worker label reconnects.
95
95
 
96
96
  Control execution requires an initialized launcher that explicitly declares its control capacity (or direct execution without an external launcher), an updated worker, and r5dctl installed on the worker's own PATH. Missing control support is an update error; a control request never falls back to a general shell. Deploy the app and worker support assets, update the CLI/worker, and reconnect before resuming paused work.
97
+
98
+ ## Uploading files to the signed-in browser
99
+
100
+ `browser_upload_files` transfers regular files from this worker to the connected r5d-browser and attaches them to the selected file input in one agent operation. Source paths may be anywhere this worker can read, including outside the project; relative paths resolve from the session working directory. `$R5D_ROOT`, `$R5D_SESSION_ID`, and `~/` are expanded without executing a shell. File reads are bounded to 1 MiB per RPC, and source metadata is checked throughout the transfer. These transient reads and binary responses bypass recovery journals. Uploads interrupted by a disconnect must be retried as a new operation.
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+ var browser_upload_exports = {};
30
+ __export(browser_upload_exports, {
31
+ readBrowserUploadChunk: () => readBrowserUploadChunk
32
+ });
33
+ module.exports = __toCommonJS(browser_upload_exports);
34
+ var import_promises = __toESM(require("node:fs/promises"), 1);
35
+ var import_node_fs = require("node:fs");
36
+ var import_node_os = __toESM(require("node:os"), 1);
37
+ var import_node_path = __toESM(require("node:path"), 1);
38
+ var import_browser_upload = require("@ricsam/r5d-api/browser-upload");
39
+ async function readBrowserUploadChunk(input, context) {
40
+ if (typeof input.filePath !== "string" || !input.filePath.trim() || input.filePath.includes("\0"))
41
+ throw new Error("Upload requires a file path.");
42
+ if (!Number.isSafeInteger(input.offset) || input.offset < 0) throw new Error("Invalid upload read offset.");
43
+ if (input.offset > 0 && !input.version) throw new Error("Upload continuation requires a file version.");
44
+ const expanded = input.filePath.replace(/\$\{R5D_ROOT\}|\$R5D_ROOT\b/g, () => context.rootDir).replace(/\$\{R5D_SESSION_ID\}|\$R5D_SESSION_ID\b/g, () => context.sessionId).replace(/^~\//, () => `${import_node_os.default.homedir()}/`);
45
+ const filePath = import_node_path.default.resolve(context.cwd, expanded);
46
+ const handle = await import_promises.default.open(filePath, import_node_fs.constants.O_RDONLY | import_node_fs.constants.O_NONBLOCK);
47
+ try {
48
+ const stat = await handle.stat({ bigint: true });
49
+ if (!stat.isFile()) throw new Error(`Upload source is not a regular file: ${input.filePath}`);
50
+ const metadata = (0, import_browser_upload.validateUploadFile)({ filename: import_node_path.default.basename(filePath), size: Number(stat.size) });
51
+ const versionOf = (s) => `${s.dev}:${s.ino}:${s.size}:${s.mtimeNs}:${s.ctimeNs}`;
52
+ const version = versionOf(stat);
53
+ if (input.version !== void 0 && input.version !== version)
54
+ throw new Error(`Upload source changed while being transferred: ${input.filePath}`);
55
+ if (input.offset > metadata.size) throw new Error("Upload offset is past the end of the file.");
56
+ const bytes = Buffer.alloc(input.metadataOnly === true ? 0 : Math.min(import_browser_upload.BROWSER_UPLOAD_CHUNK_BYTES, metadata.size - input.offset));
57
+ let read = 0;
58
+ while (read < bytes.length) {
59
+ const { bytesRead } = await handle.read(bytes, read, bytes.length - read, input.offset + read);
60
+ if (!bytesRead) throw new Error(`Upload source was truncated: ${input.filePath}`);
61
+ read += bytesRead;
62
+ }
63
+ if (versionOf(await handle.stat({ bigint: true })) !== version)
64
+ throw new Error(`Upload source changed while being read: ${input.filePath}`);
65
+ return { type: "browser_upload_read", ...metadata, version, offset: input.offset, base64: bytes.toString("base64") };
66
+ } finally {
67
+ await handle.close();
68
+ }
69
+ }
70
+ // Annotate the CommonJS export names for ESM import in node:
71
+ 0 && (module.exports = {
72
+ readBrowserUploadChunk
73
+ });
package/dist/cjs/main.cjs CHANGED
@@ -56,6 +56,7 @@ __export(main_exports, {
56
56
  writeWorkerTextFile: () => writeWorkerTextFile
57
57
  });
58
58
  module.exports = __toCommonJS(main_exports);
59
+ var import_browser_upload = require("./browser-upload.cjs");
59
60
  var import_runtime_version = require("./runtime-version.cjs");
60
61
  var import_plan_paths = require("./plan-paths.cjs");
61
62
  var import_plan_parser = require("./plan-parser.cjs");
@@ -2819,6 +2820,13 @@ async function executeOperation(input) {
2819
2820
  return executeViewFileBytesOperation({ ...input, message: input.message });
2820
2821
  case "code_list":
2821
2822
  return executeCodeListOperation({ ...input, message: input.message });
2823
+ case "browser_upload_read":
2824
+ input.assertAdmission();
2825
+ return (0, import_browser_upload.readBrowserUploadChunk)(input.message.input, {
2826
+ cwd: input.resolvedTarget.rootPath,
2827
+ rootDir: input.rootDir,
2828
+ sessionId: input.message.sessionId
2829
+ });
2822
2830
  case "code_read":
2823
2831
  return executeCodeReadOperation({ ...input, message: input.message });
2824
2832
  }
@@ -3250,6 +3258,10 @@ function sendReplayWorkerMessage(ws, message) {
3250
3258
  }
3251
3259
  function sendWorkerMessage(ws, message) {
3252
3260
  if (launcherFailureInProgress) return;
3261
+ if (message.type === "browser_upload_read_result") {
3262
+ if (currentWorkerSocket === ws && ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify(message));
3263
+ return;
3264
+ }
3253
3265
  const transportError = "error" in message && typeof message.error === "string" ? message.error : message.type === "workspace_sync_result" && message.result.outcome === "failed" ? message.result.error : void 0;
3254
3266
  if (recoveryJournal && transportError && isWorkerCommunicationFailure(transportError) && "requestId" in message && typeof message.requestId === "string") {
3255
3267
  recoveryJournal.unknown(message.requestId);
@@ -6036,6 +6048,7 @@ async function startWorker(options, projectRuntime = {
6036
6048
  capabilities: {
6037
6049
  updateClis: true,
6038
6050
  browserPortForwarding: true,
6051
+ browserFileUploads: true,
6039
6052
  execStdinV1: true,
6040
6053
  ptyEnvFilesV1: true,
6041
6054
  workspaceRemediationAncestorGuardV1: true,
@@ -6172,7 +6185,7 @@ async function startWorker(options, projectRuntime = {
6172
6185
  if (!startupRecoveryComplete && message.type !== "ping") await startupRecoveryPromise;
6173
6186
  if (!startupRecoveryComplete && message.type !== "ping") return;
6174
6187
  if (currentWorkerSocket !== ws) return;
6175
- const operationRequestId = "requestId" in message && typeof message.requestId === "string" && message.type !== "workspace_config" ? message.requestId : void 0;
6188
+ const operationRequestId = "requestId" in message && typeof message.requestId === "string" && message.type !== "workspace_config" && message.type !== "browser_upload_read" ? message.requestId : void 0;
6176
6189
  if (message.type === "cancel") {
6177
6190
  const admission = recoveryJournal.admit({ ...message, requestId: message.requestId });
6178
6191
  const cancelled = await cancelProcessRun(message.runId, message.scope);
@@ -7078,10 +7091,10 @@ async function startWorker(options, projectRuntime = {
7078
7091
  });
7079
7092
  return;
7080
7093
  }
7081
- if (message.type === "read_plan" || message.type === "lint_plans" || message.type === "update_task_status" || message.type === "read" || message.type === "write" || message.type === "edit" || message.type === "grep" || message.type === "find" || message.type === "ls" || message.type === "view_file_bytes" || message.type === "code_list" || message.type === "code_read") {
7094
+ if (message.type === "read_plan" || message.type === "lint_plans" || message.type === "update_task_status" || message.type === "read" || message.type === "write" || message.type === "edit" || message.type === "grep" || message.type === "find" || message.type === "ls" || message.type === "view_file_bytes" || message.type === "code_list" || message.type === "code_read" || message.type === "browser_upload_read") {
7082
7095
  if (workspaceOperationsAreFenced(deferredWorkspaceConfiguration, activeWorkspaceIncidentId)) {
7083
7096
  sendWorkerMessage(ws, {
7084
- type: "operation_result",
7097
+ type: message.type === "browser_upload_read" ? "browser_upload_read_result" : "operation_result",
7085
7098
  requestId: message.requestId,
7086
7099
  error: `Workspace operations are deferred for incident ${deferredWorkspaceConfiguration?.incidentId ?? activeWorkspaceIncidentId}; use a canonical remediation shell`
7087
7100
  });
@@ -7109,7 +7122,7 @@ async function startWorker(options, projectRuntime = {
7109
7122
  sendSerializedWorkerMessage(
7110
7123
  ws,
7111
7124
  JSON.stringify({
7112
- type: "operation_result",
7125
+ type: message.type === "browser_upload_read" ? "browser_upload_read_result" : "operation_result",
7113
7126
  requestId: message.requestId,
7114
7127
  error: error instanceof Error ? error.message : String(error)
7115
7128
  })
@@ -7137,7 +7150,7 @@ async function startWorker(options, projectRuntime = {
7137
7150
  sendSerializedWorkerMessage(
7138
7151
  ws,
7139
7152
  JSON.stringify({
7140
- type: "operation_result",
7153
+ type: message.type === "browser_upload_read" ? "browser_upload_read_result" : "operation_result",
7141
7154
  requestId: message.requestId,
7142
7155
  result
7143
7156
  })
@@ -7155,7 +7168,7 @@ async function startWorker(options, projectRuntime = {
7155
7168
  sendSerializedWorkerMessage(
7156
7169
  ws,
7157
7170
  JSON.stringify({
7158
- type: "operation_result",
7171
+ type: message.type === "browser_upload_read" ? "browser_upload_read_result" : "operation_result",
7159
7172
  requestId: message.requestId,
7160
7173
  error: error instanceof Error ? error.message : String(error)
7161
7174
  })
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/r5d-worker",
3
- "version": "0.0.125",
3
+ "version": "0.0.126",
4
4
  "type": "commonjs"
5
5
  }
@@ -0,0 +1,42 @@
1
+ import fs from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ import {
6
+ BROWSER_UPLOAD_CHUNK_BYTES,
7
+ validateUploadFile
8
+ } from "@ricsam/r5d-api/browser-upload";
9
+ async function readBrowserUploadChunk(input, context) {
10
+ if (typeof input.filePath !== "string" || !input.filePath.trim() || input.filePath.includes("\0"))
11
+ throw new Error("Upload requires a file path.");
12
+ if (!Number.isSafeInteger(input.offset) || input.offset < 0) throw new Error("Invalid upload read offset.");
13
+ if (input.offset > 0 && !input.version) throw new Error("Upload continuation requires a file version.");
14
+ const expanded = input.filePath.replace(/\$\{R5D_ROOT\}|\$R5D_ROOT\b/g, () => context.rootDir).replace(/\$\{R5D_SESSION_ID\}|\$R5D_SESSION_ID\b/g, () => context.sessionId).replace(/^~\//, () => `${os.homedir()}/`);
15
+ const filePath = path.resolve(context.cwd, expanded);
16
+ const handle = await fs.open(filePath, constants.O_RDONLY | constants.O_NONBLOCK);
17
+ try {
18
+ const stat = await handle.stat({ bigint: true });
19
+ if (!stat.isFile()) throw new Error(`Upload source is not a regular file: ${input.filePath}`);
20
+ const metadata = validateUploadFile({ filename: path.basename(filePath), size: Number(stat.size) });
21
+ const versionOf = (s) => `${s.dev}:${s.ino}:${s.size}:${s.mtimeNs}:${s.ctimeNs}`;
22
+ const version = versionOf(stat);
23
+ if (input.version !== void 0 && input.version !== version)
24
+ throw new Error(`Upload source changed while being transferred: ${input.filePath}`);
25
+ if (input.offset > metadata.size) throw new Error("Upload offset is past the end of the file.");
26
+ const bytes = Buffer.alloc(input.metadataOnly === true ? 0 : Math.min(BROWSER_UPLOAD_CHUNK_BYTES, metadata.size - input.offset));
27
+ let read = 0;
28
+ while (read < bytes.length) {
29
+ const { bytesRead } = await handle.read(bytes, read, bytes.length - read, input.offset + read);
30
+ if (!bytesRead) throw new Error(`Upload source was truncated: ${input.filePath}`);
31
+ read += bytesRead;
32
+ }
33
+ if (versionOf(await handle.stat({ bigint: true })) !== version)
34
+ throw new Error(`Upload source changed while being read: ${input.filePath}`);
35
+ return { type: "browser_upload_read", ...metadata, version, offset: input.offset, base64: bytes.toString("base64") };
36
+ } finally {
37
+ await handle.close();
38
+ }
39
+ }
40
+ export {
41
+ readBrowserUploadChunk
42
+ };
package/dist/mjs/main.mjs CHANGED
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bun
2
+ import { readBrowserUploadChunk } from "./browser-upload.mjs";
2
3
  import { WORKER_RUNTIME_VERSION } from "./runtime-version.mjs";
3
4
  import { getWorkerPlanPath, getWorkerPlansPath, validatePlanId } from "./plan-paths.mjs";
4
5
  import { createPlanMarkdown, updateTaskCheckbox } from "./plan-parser.mjs";
@@ -2840,6 +2841,13 @@ async function executeOperation(input) {
2840
2841
  return executeViewFileBytesOperation({ ...input, message: input.message });
2841
2842
  case "code_list":
2842
2843
  return executeCodeListOperation({ ...input, message: input.message });
2844
+ case "browser_upload_read":
2845
+ input.assertAdmission();
2846
+ return readBrowserUploadChunk(input.message.input, {
2847
+ cwd: input.resolvedTarget.rootPath,
2848
+ rootDir: input.rootDir,
2849
+ sessionId: input.message.sessionId
2850
+ });
2843
2851
  case "code_read":
2844
2852
  return executeCodeReadOperation({ ...input, message: input.message });
2845
2853
  }
@@ -3271,6 +3279,10 @@ function sendReplayWorkerMessage(ws, message) {
3271
3279
  }
3272
3280
  function sendWorkerMessage(ws, message) {
3273
3281
  if (launcherFailureInProgress) return;
3282
+ if (message.type === "browser_upload_read_result") {
3283
+ if (currentWorkerSocket === ws && ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify(message));
3284
+ return;
3285
+ }
3274
3286
  const transportError = "error" in message && typeof message.error === "string" ? message.error : message.type === "workspace_sync_result" && message.result.outcome === "failed" ? message.result.error : void 0;
3275
3287
  if (recoveryJournal && transportError && isWorkerCommunicationFailure(transportError) && "requestId" in message && typeof message.requestId === "string") {
3276
3288
  recoveryJournal.unknown(message.requestId);
@@ -6057,6 +6069,7 @@ async function startWorker(options, projectRuntime = {
6057
6069
  capabilities: {
6058
6070
  updateClis: true,
6059
6071
  browserPortForwarding: true,
6072
+ browserFileUploads: true,
6060
6073
  execStdinV1: true,
6061
6074
  ptyEnvFilesV1: true,
6062
6075
  workspaceRemediationAncestorGuardV1: true,
@@ -6193,7 +6206,7 @@ async function startWorker(options, projectRuntime = {
6193
6206
  if (!startupRecoveryComplete && message.type !== "ping") await startupRecoveryPromise;
6194
6207
  if (!startupRecoveryComplete && message.type !== "ping") return;
6195
6208
  if (currentWorkerSocket !== ws) return;
6196
- const operationRequestId = "requestId" in message && typeof message.requestId === "string" && message.type !== "workspace_config" ? message.requestId : void 0;
6209
+ const operationRequestId = "requestId" in message && typeof message.requestId === "string" && message.type !== "workspace_config" && message.type !== "browser_upload_read" ? message.requestId : void 0;
6197
6210
  if (message.type === "cancel") {
6198
6211
  const admission = recoveryJournal.admit({ ...message, requestId: message.requestId });
6199
6212
  const cancelled = await cancelProcessRun(message.runId, message.scope);
@@ -7099,10 +7112,10 @@ async function startWorker(options, projectRuntime = {
7099
7112
  });
7100
7113
  return;
7101
7114
  }
7102
- if (message.type === "read_plan" || message.type === "lint_plans" || message.type === "update_task_status" || message.type === "read" || message.type === "write" || message.type === "edit" || message.type === "grep" || message.type === "find" || message.type === "ls" || message.type === "view_file_bytes" || message.type === "code_list" || message.type === "code_read") {
7115
+ if (message.type === "read_plan" || message.type === "lint_plans" || message.type === "update_task_status" || message.type === "read" || message.type === "write" || message.type === "edit" || message.type === "grep" || message.type === "find" || message.type === "ls" || message.type === "view_file_bytes" || message.type === "code_list" || message.type === "code_read" || message.type === "browser_upload_read") {
7103
7116
  if (workspaceOperationsAreFenced(deferredWorkspaceConfiguration, activeWorkspaceIncidentId)) {
7104
7117
  sendWorkerMessage(ws, {
7105
- type: "operation_result",
7118
+ type: message.type === "browser_upload_read" ? "browser_upload_read_result" : "operation_result",
7106
7119
  requestId: message.requestId,
7107
7120
  error: `Workspace operations are deferred for incident ${deferredWorkspaceConfiguration?.incidentId ?? activeWorkspaceIncidentId}; use a canonical remediation shell`
7108
7121
  });
@@ -7130,7 +7143,7 @@ async function startWorker(options, projectRuntime = {
7130
7143
  sendSerializedWorkerMessage(
7131
7144
  ws,
7132
7145
  JSON.stringify({
7133
- type: "operation_result",
7146
+ type: message.type === "browser_upload_read" ? "browser_upload_read_result" : "operation_result",
7134
7147
  requestId: message.requestId,
7135
7148
  error: error instanceof Error ? error.message : String(error)
7136
7149
  })
@@ -7158,7 +7171,7 @@ async function startWorker(options, projectRuntime = {
7158
7171
  sendSerializedWorkerMessage(
7159
7172
  ws,
7160
7173
  JSON.stringify({
7161
- type: "operation_result",
7174
+ type: message.type === "browser_upload_read" ? "browser_upload_read_result" : "operation_result",
7162
7175
  requestId: message.requestId,
7163
7176
  result
7164
7177
  })
@@ -7176,7 +7189,7 @@ async function startWorker(options, projectRuntime = {
7176
7189
  sendSerializedWorkerMessage(
7177
7190
  ws,
7178
7191
  JSON.stringify({
7179
- type: "operation_result",
7192
+ type: message.type === "browser_upload_read" ? "browser_upload_read_result" : "operation_result",
7180
7193
  requestId: message.requestId,
7181
7194
  error: error instanceof Error ? error.message : String(error)
7182
7195
  })
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/r5d-worker",
3
- "version": "0.0.125",
3
+ "version": "0.0.126",
4
4
  "type": "module"
5
5
  }
@@ -0,0 +1,7 @@
1
+ import { type BrowserUploadChunk, type BrowserUploadReadInput } from "@ricsam/r5d-api/browser-upload";
2
+ /** Unlike code-view paths, uploads may read any regular file accessible to this worker. */
3
+ export declare function readBrowserUploadChunk(input: BrowserUploadReadInput, context: {
4
+ cwd: string;
5
+ rootDir: string;
6
+ sessionId: string;
7
+ }): Promise<BrowserUploadChunk>;
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env bun
2
+ import type { BrowserUploadChunk, BrowserUploadReadInput } from "@ricsam/r5d-api/browser-upload";
2
3
  import type { WorkerLintPlansResult, WorkerUpdatePlanTaskResult } from "./plan-paths";
3
4
  import { WORKER_RESUMABLE_PROTOCOL, type WorkerRecoveryClientMessage, type WorkerRecoveryServerMessage } from "./recovery-protocol";
4
5
  import { Database } from "bun:sqlite";
@@ -204,6 +205,11 @@ type WorkerClientMessage = WorkerRecoveryClientMessage | {
204
205
  ptyId: string;
205
206
  requestId?: string;
206
207
  error: string;
208
+ } | {
209
+ type: "browser_upload_read_result";
210
+ requestId: string;
211
+ result?: WorkerOperationResult;
212
+ error?: string;
207
213
  } | {
208
214
  type: "operation_result";
209
215
  requestId: string;
@@ -355,6 +361,12 @@ type WorkerServerMessage = WorkerRecoveryServerMessage | {
355
361
  type: "project";
356
362
  }>;
357
363
  path: string;
364
+ } | {
365
+ type: "browser_upload_read";
366
+ requestId: string;
367
+ target: WorkerSessionTarget;
368
+ sessionId: string;
369
+ input: BrowserUploadReadInput;
358
370
  } | {
359
371
  type: "code_read";
360
372
  requestId: string;
@@ -639,9 +651,9 @@ type WorkerCodeReadResult = {
639
651
  mtime: string;
640
652
  base64: string;
641
653
  };
642
- type WorkerOperationResult = WorkerReadFileResult | WorkerReadPlanResult | WorkerLintPlansResult | WorkerUpdatePlanTaskResult | WorkerWriteFileResult | WorkerEditFileResult | WorkerGrepResult | WorkerFindResult | WorkerLsResult | WorkerViewFileBytesResult | WorkerExecStdinAck | WorkerCreateProjectBranchResult | WorkerDeleteProjectBranchResult | WorkerCodeListResult | WorkerCodeReadResult;
654
+ type WorkerOperationResult = WorkerReadFileResult | WorkerReadPlanResult | WorkerLintPlansResult | WorkerUpdatePlanTaskResult | WorkerWriteFileResult | WorkerEditFileResult | WorkerGrepResult | WorkerFindResult | WorkerLsResult | WorkerViewFileBytesResult | WorkerExecStdinAck | WorkerCreateProjectBranchResult | WorkerDeleteProjectBranchResult | WorkerCodeListResult | WorkerCodeReadResult | BrowserUploadChunk;
643
655
  type WorkerOperationServerMessage = Extract<WorkerServerMessage, {
644
- type: "read_plan" | "lint_plans" | "update_task_status" | "read" | "write" | "edit" | "grep" | "find" | "ls" | "view_file_bytes" | "code_list" | "code_read";
656
+ type: "read_plan" | "lint_plans" | "update_task_status" | "read" | "write" | "edit" | "grep" | "find" | "ls" | "view_file_bytes" | "code_list" | "code_read" | "browser_upload_read";
645
657
  }>;
646
658
  declare class WorkspaceSyncAdmissionChangedError extends Error {
647
659
  readonly name = "WorkspaceSyncAdmissionChangedError";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ricsam/r5d-worker",
3
- "version": "0.0.125",
3
+ "version": "0.0.126",
4
4
  "type": "module",
5
5
  "main": "./dist/cjs/main.cjs",
6
6
  "module": "./dist/mjs/main.mjs",
@@ -21,6 +21,7 @@
21
21
  "r5d-worker": "dist/cjs/main.cjs"
22
22
  },
23
23
  "dependencies": {
24
+ "@ricsam/r5d-api": "^0.0.126",
24
25
  "node-pty": "^1.1.0",
25
26
  "picomatch": "^4.0.3"
26
27
  },