@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 +4 -0
- package/dist/cjs/browser-upload.cjs +73 -0
- package/dist/cjs/main.cjs +19 -6
- package/dist/cjs/package.json +1 -1
- package/dist/mjs/browser-upload.mjs +42 -0
- package/dist/mjs/main.mjs +19 -6
- package/dist/mjs/package.json +1 -1
- package/dist/types/browser-upload.d.ts +7 -0
- package/dist/types/main.d.ts +14 -2
- package/package.json +2 -1
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
|
})
|
package/dist/cjs/package.json
CHANGED
|
@@ -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
|
})
|
package/dist/mjs/package.json
CHANGED
|
@@ -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>;
|
package/dist/types/main.d.ts
CHANGED
|
@@ -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.
|
|
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
|
},
|