@ricsam/r5d-worker 0.0.152 → 0.0.154

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/mjs/main.mjs CHANGED
@@ -7,7 +7,7 @@ import { startManagerRpc } from "./runtime/releases/rpc-main.mjs";
7
7
  import { ManagerRpcConfig } from "./runtime/releases/rpc-protocol.mjs";
8
8
  const args = process.argv.slice(2);
9
9
  if (args.includes("--version")) {
10
- console.log(`r5d-worker ${true ? "0.0.152" : "development"}`);
10
+ console.log(`r5d-worker ${true ? "0.0.154" : "development"}`);
11
11
  } else if (!args.length || args.includes("--help")) {
12
12
  console.log(
13
13
  "Usage: r5d-worker start --label <label> [--root <dir>] [--base-url <url>] [--token <worker-token>]\n r5d-worker executor /absolute/private/config.json\n r5d-worker manager /absolute/private/config.json\n\nRun independently supervised durable runtime services. Provision configuration with r5dinfra."
@@ -15,7 +15,7 @@ if (args.includes("--version")) {
15
15
  } else if (args[0] === "start") {
16
16
  const runtime = await startPersonalWorker(
17
17
  parsePersonalWorkerOptions(args.slice(1)),
18
- true ? "0.0.152" : "development"
18
+ true ? "0.0.154" : "development"
19
19
  );
20
20
  console.log(`Worker connected: ${runtime.resourceId}`);
21
21
  let closing = false;
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/r5d-worker",
3
- "version": "0.0.152",
3
+ "version": "0.0.154",
4
4
  "type": "module"
5
5
  }
@@ -6,6 +6,16 @@ function packageMain(moduleUrl) {
6
6
  const module = fileURLToPath(moduleUrl);
7
7
  return path.join(path.dirname(module), path.extname(module) === ".cjs" ? "main.cjs" : "main.mjs");
8
8
  }
9
+ function internalMain(moduleUrl) {
10
+ return path.join(path.dirname(fileURLToPath(moduleUrl)), "..", "internal-r5dctl.cjs");
11
+ }
12
+ async function inspectInternal(candidate) {
13
+ const entrypoint = await fs.realpath(candidate);
14
+ const stat = await fs.lstat(entrypoint);
15
+ if (!stat.isFile() || stat.nlink !== 1 || stat.mode & 2 || ![0, process.getuid?.()].includes(stat.uid))
16
+ throw new Error("Untrusted internal r5dctl entrypoint");
17
+ return entrypoint;
18
+ }
9
19
  async function inspectPackage(candidate) {
10
20
  const entrypoint = await fs.realpath(candidate);
11
21
  const entrypointStat = await fs.lstat(entrypoint);
@@ -39,13 +49,19 @@ async function resolvePersonalCliEntrypoint(explicit, workerVersion, dependencie
39
49
  source = "explicit";
40
50
  candidate = explicit;
41
51
  } else {
52
+ const bundled = dependencies.bundled ?? internalMain(import.meta.url);
42
53
  try {
43
- const resolvePackage = dependencies.resolvePackage ?? ((specifier) => import.meta.resolve(specifier));
44
- candidate = packageMain(resolvePackage(`${PACKAGE_NAME}/cli`));
45
- source = "bundled";
46
- } catch {
47
- source = "path";
48
- candidate = (dependencies.which ?? Bun.which)("r5dctl");
54
+ return { entrypoint: await inspectInternal(bundled), version: workerVersion, source: "bundled" };
55
+ } catch (error) {
56
+ if (error.code !== "ENOENT" || workerVersion !== "development") throw error;
57
+ try {
58
+ const resolvePackage = dependencies.resolvePackage ?? ((specifier) => import.meta.resolve(specifier));
59
+ candidate = packageMain(resolvePackage(`${PACKAGE_NAME}/cli`));
60
+ source = "bundled";
61
+ } catch {
62
+ source = "path";
63
+ candidate = (dependencies.which ?? Bun.which)("r5dctl");
64
+ }
49
65
  }
50
66
  }
51
67
  if (!candidate) throw new Error("Install @ricsam/r5dctl before starting this worker");
@@ -12,7 +12,7 @@ import { privateDirectory, readPrivateJson } from "../runtime/storage.mjs";
12
12
  import { WorkspaceAuthority } from "../runtime/workspace/authority.mjs";
13
13
  import { ApprovedWorkbench, WorkspaceError } from "../runtime/workspace/contracts.mjs";
14
14
  import { WorkspaceStorageClient } from "../runtime/workspace/storage-client.mjs";
15
- import { BranchName, StorageId } from "../runtime/workspace/storage-wire.mjs";
15
+ import { BranchName, GitOid, StorageId } from "../runtime/workspace/storage-wire.mjs";
16
16
  const PersonalWorkerGrant = z.object({
17
17
  installationId: RuntimeId,
18
18
  userId: RuntimeId,
@@ -30,7 +30,8 @@ const Workbench = z.object({
30
30
  sessionId: RuntimeId,
31
31
  rootProfile: z.enum(["account", "project"]).default("project"),
32
32
  namespace: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/).optional(),
33
- projectName: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/).optional()
33
+ projectName: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/).optional(),
34
+ baseCommitHash: GitOid.optional()
34
35
  }).strict();
35
36
  const PersonalWorkspaceRequest = z.object({
36
37
  protocol: z.literal(1),
@@ -105,12 +106,13 @@ async function openPersonalWorkerRuntime(options) {
105
106
  let cliDirectory;
106
107
  if (options.cliEntrypoint) {
107
108
  const cli = await fs.realpath(options.cliEntrypoint), executable = await fs.realpath(process.execPath), stat = await fs.lstat(cli);
108
- if (!stat.isFile() || stat.mode & 18 || ![0, process.getuid?.()].includes(stat.uid))
109
+ if (!stat.isFile() || stat.nlink !== 1 || stat.mode & 2 || ![0, process.getuid?.()].includes(stat.uid))
109
110
  throw new Error("Untrusted installed r5dctl entrypoint");
110
111
  cliDirectory = path.join(root, "bin");
111
112
  privateDirectory(cliDirectory);
112
113
  const quote = (value) => "'" + value.replace(/'/g, "'\\''") + "'";
113
114
  const wrapper = `#!/bin/sh
115
+ export BUN_RUNTIME_TRANSPILER_CACHE_PATH=0
114
116
  exec ${quote(executable)} ${quote(cli)} "$@"
115
117
  `;
116
118
  const file = path.join(cliDirectory, "r5dctl"), temporary = `${file}.${randomBytes(8).toString("hex")}.next`;
@@ -212,7 +214,7 @@ exec ${quote(executable)} ${quote(cli)} "$@"
212
214
  });
213
215
  const previous = manifests.get(input.id);
214
216
  const stable = (value) => {
215
- const { sessionId: _sessionId, sharedSessionId: _sharedSessionId, ...binding } = value;
217
+ const { sessionId: _sessionId, sharedSessionId: _sharedSessionId, baseCommitHash: _baseCommitHash, ...binding } = value;
216
218
  return binding;
217
219
  };
218
220
  if (previous && canonicalJson(stable(previous)) !== canonicalJson(stable(row))) throw new Error("Personal workbench identity changed");
@@ -30,6 +30,7 @@ import {
30
30
  sourceBytes,
31
31
  verifyIgnore
32
32
  } from "./files.mjs";
33
+ const GITHUB_CREDENTIAL_HELPER = '!f() { if [ "$1" = get ] && [ -n "$R5D_GIT_CREDENTIAL" ]; then git credential-store --file="$R5D_GIT_CREDENTIAL" get; else return 0; fi; }; f';
33
34
  class WorkspaceAuthority {
34
35
  constructor(options) {
35
36
  this.options = options;
@@ -54,7 +55,7 @@ class WorkspaceAuthority {
54
55
  return path.join(workspaceRoot, "workbenches", config.id);
55
56
  }
56
57
  stableBinding(config) {
57
- const { sessionId: _sessionId, sharedSessionId: _sharedSessionId, ...binding } = config;
58
+ const { sessionId: _sessionId, sharedSessionId: _sharedSessionId, baseCommitHash: _baseCommitHash, ...binding } = config;
58
59
  return binding;
59
60
  }
60
61
  repositoryPath(config, directory) {
@@ -99,6 +100,9 @@ class WorkspaceAuthority {
99
100
  throw new WorkspaceError("invalid_config", "Project checkout is missing its GitHub repository identity");
100
101
  return `https://github.com/${b.config.namespace}/${b.config.projectName}.git`;
101
102
  }
103
+ canonicalRef(b) {
104
+ return `refs/r5d/canonical/${b.config.branch}`;
105
+ }
102
106
  resolveHostPath(value) {
103
107
  const expanded = value === "~" ? os.homedir() : value.startsWith("~/") ? path.join(os.homedir(), value.slice(2)) : value;
104
108
  if (!path.isAbsolute(expanded) || expanded.includes("\0")) throw new WorkspaceError("unsafe_path", "Host path must be absolute or home-relative");
@@ -443,8 +447,9 @@ class WorkspaceAuthority {
443
447
  throw new WorkspaceError("dirty_workbench", "Source differs from its canonical base; preserve and publish or reconcile edits first");
444
448
  if (this.linkedWorkbench(b)) {
445
449
  const localHead2 = (await git(b.config.cwd, ["rev-parse", "HEAD"])).toString().trim();
446
- if (localHead2 !== expectedBase || (await git(b.config.cwd, ["write-tree"])).toString().trim() !== expectedTree)
447
- throw new WorkspaceError("dirty_workbench", "Local branch or index changed; preserve and reconcile it before refreshing");
450
+ const localTree = (await git(b.repo, ["rev-parse", `${localHead2}^{tree}`])).toString().trim();
451
+ if ((await git(b.config.cwd, ["write-tree"])).toString().trim() !== localTree)
452
+ throw new WorkspaceError("dirty_workbench", "Staged Git changes are retained; preserve or reconcile them before refreshing");
448
453
  return;
449
454
  }
450
455
  const metadata = path.join(b.config.cwd, ".git");
@@ -565,8 +570,9 @@ class WorkspaceAuthority {
565
570
  await this.installGitPolicy(b, head);
566
571
  } else if (this.linkedWorkbench(b)) {
567
572
  await this.cleanRefreshBase(b, expectedBase);
568
- await git(b.repo, ["update-ref", `refs/heads/${b.config.branch}`, head, expectedBase]);
573
+ const visibleHead = (await git(b.config.cwd, ["rev-parse", "HEAD"])).toString().trim();
569
574
  await git(b.config.cwd, ["reset", "--hard", head]);
575
+ await git(b.config.cwd, ["reset", "--mixed", visibleHead]);
570
576
  await fs.rm(staged, { recursive: true });
571
577
  } else {
572
578
  await this.cleanRefreshBase(b, expectedBase);
@@ -775,7 +781,7 @@ class WorkspaceAuthority {
775
781
  return result;
776
782
  });
777
783
  }
778
- async installGitPolicy(b, head) {
784
+ async installGitPolicy(b, head, initialVisibleHead = b.config.baseCommitHash ?? head) {
779
785
  delete b.state.publishedMetadata;
780
786
  if (this.linkedWorkbench(b)) {
781
787
  const destination2 = path.join(b.config.cwd, ".git");
@@ -783,10 +789,17 @@ class WorkspaceAuthority {
783
789
  if (error.code === "ENOENT") return false;
784
790
  throw error;
785
791
  });
786
- await git(b.repo, ["update-ref", `refs/heads/${b.config.branch}`, head]);
792
+ await git(b.repo, ["update-ref", this.canonicalRef(b), head]);
787
793
  if (!exists) {
788
794
  if ((await fs.readdir(b.config.cwd)).length) throw new WorkspaceError("nonempty_workbench", "Linked worktree destination must be empty");
795
+ const visibleHead = initialVisibleHead;
796
+ await git(b.repo, ["cat-file", "-e", `${visibleHead}^{commit}`]);
797
+ await git(b.repo, ["update-ref", `refs/heads/${b.config.branch}`, visibleHead]);
789
798
  await git(b.repo, ["worktree", "add", "--force", b.config.cwd, b.config.branch]);
799
+ if (visibleHead !== head) {
800
+ await git(b.config.cwd, ["reset", "--hard", head]);
801
+ await git(b.config.cwd, ["reset", "--mixed", visibleHead]);
802
+ }
790
803
  }
791
804
  const origin = this.githubOrigin(b);
792
805
  await git(b.repo, ["config", "--local", "--replace-all", "remote.origin.url", origin]);
@@ -798,6 +811,7 @@ class WorkspaceAuthority {
798
811
  await git(b.repo, ["config", "--local", "--replace-all", `branch.${b.config.branch}.merge`, `refs/heads/${b.config.branch}`]);
799
812
  await git(b.repo, ["config", "--local", "--replace-all", "push.default", "upstream"]);
800
813
  await git(b.repo, ["config", "--local", "--replace-all", "credential.helper", ""]);
814
+ await git(b.repo, ["config", "--local", "--add", "credential.helper", GITHUB_CREDENTIAL_HELPER]);
801
815
  await git(b.repo, ["config", "--local", "--replace-all", "credential.useHttpPath", "false"]);
802
816
  await git(b.repo, ["config", "protocol.allow", "never"]);
803
817
  await git(b.repo, ["config", "protocol.https.allow", "always"]);
@@ -1013,6 +1027,7 @@ class WorkspaceAuthority {
1013
1027
  }));
1014
1028
  }
1015
1029
  async importCommit(b, head, id, identity) {
1030
+ const visibleHead = b.config.baseCommitHash ?? head;
1016
1031
  const entries = await selectedTree(b.repo, head);
1017
1032
  const staged = path.join(b.directory, `import-${randomUUID()}`);
1018
1033
  await fs.mkdir(staged, { mode: 448 });
@@ -1042,9 +1057,9 @@ ${DEFAULT_WORKSPACE_IGNORE}`, { mode: 384 });
1042
1057
  existing = { head: null };
1043
1058
  }
1044
1059
  if (existing.head) throw new WorkspaceError("conflict", "Branch already exists in canonical storage");
1045
- await git(b.repo, ["update-ref", `refs/heads/${b.config.branch}`, head]);
1060
+ await git(b.repo, ["update-ref", this.canonicalRef(b), head]);
1046
1061
  const file = path.join(b.directory, `publish-${randomUUID()}.bundle`);
1047
- await git(b.repo, ["bundle", "create", file, `refs/heads/${b.config.branch}`]);
1062
+ await git(b.repo, ["bundle", "create", file, this.canonicalRef(b)]);
1048
1063
  const bytes = await readRegular(file, STORAGE_LIMITS.blobBytes), blobId = operationId;
1049
1064
  b.state.blocked = { code: "publication_unknown", operationId, commit: head, message: "Inspect the original import publication receipt" };
1050
1065
  await this.save(b);
@@ -1056,7 +1071,7 @@ ${DEFAULT_WORKSPACE_IGNORE}`, { mode: 384 });
1056
1071
  if (result.head !== head) throw new WorkspaceError("invalid_receipt", "Import receipt does not match selected commit");
1057
1072
  if (this.linkedWorkbench(b)) await fs.rm(staged, { recursive: true });
1058
1073
  else for (const name of await fs.readdir(staged)) await fs.rename(path.join(staged, name), path.join(b.config.cwd, name));
1059
- await this.installGitPolicy(b, head);
1074
+ await this.installGitPolicy(b, head, visibleHead);
1060
1075
  b.state.initialized = true;
1061
1076
  b.state.head = head;
1062
1077
  b.state.blocked = null;
@@ -1069,7 +1084,6 @@ ${DEFAULT_WORKSPACE_IGNORE}`, { mode: 384 });
1069
1084
  return this.serial(b, () => this.productAction(b, input.id, { method: "commit", expectedHead: input.expectedHead, message: input.message }, async () => {
1070
1085
  const result = await this.publishIdle(b, identity, input.message);
1071
1086
  if (this.linkedWorkbench(b)) {
1072
- await git(b.config.cwd, ["reset", "--mixed", result.head]);
1073
1087
  return { ...result, treeHash: (await git(b.repo, ["rev-parse", `${result.head}^{tree}`])).toString().trim() };
1074
1088
  }
1075
1089
  const metadata = path.join(b.config.cwd, ".git");
@@ -1180,9 +1194,9 @@ ${DEFAULT_WORKSPACE_IGNORE}`, { mode: 384 });
1180
1194
  return { head: b.state.head, unchanged: true };
1181
1195
  const commit = (await git(b.repo, ["commit-tree", tree, ...b.state.head ? ["-p", b.state.head] : []], `${message}
1182
1196
  `)).toString().trim();
1183
- await git(b.repo, ["update-ref", `refs/heads/${b.config.branch}`, commit]);
1197
+ await git(b.repo, ["update-ref", this.canonicalRef(b), commit]);
1184
1198
  const bundleFile = path.join(b.directory, `${randomUUID()}.bundle`);
1185
- await git(b.repo, ["bundle", "create", bundleFile, `refs/heads/${b.config.branch}`]);
1199
+ await git(b.repo, ["bundle", "create", bundleFile, this.canonicalRef(b)]);
1186
1200
  const bytes = await readRegular(bundleFile, STORAGE_LIMITS.blobBytes);
1187
1201
  const operationId = `ws-${randomUUID()}`, blobId = `ws-${randomUUID()}`;
1188
1202
  try {
@@ -1236,10 +1250,6 @@ ${DEFAULT_WORKSPACE_IGNORE}`, { mode: 384 });
1236
1250
  });
1237
1251
  if (result.head !== commit)
1238
1252
  throw new WorkspaceError("invalid_response", "Publication receipt head mismatch; inspect original operation");
1239
- if (this.linkedWorkbench(b) && await fs.lstat(path.join(b.config.cwd, ".git")).then(() => true, (error) => {
1240
- if (error.code === "ENOENT") return false;
1241
- throw error;
1242
- })) await git(b.config.cwd, ["reset", "--mixed", commit]);
1243
1253
  b.state.head = commit;
1244
1254
  b.state.blocked = null;
1245
1255
  await this.save(b);
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { z } from "zod";
3
3
  import { RuntimeId } from "@ricsam/r5d-api/runtime-protocol";
4
- import { BranchName, StorageId } from "./storage-wire.mjs";
4
+ import { BranchName, GitOid, StorageId } from "./storage-wire.mjs";
5
5
  const ApprovedWorkbench = z.object({
6
6
  id: StorageId,
7
7
  userId: RuntimeId,
@@ -13,6 +13,8 @@ const ApprovedWorkbench = z.object({
13
13
  rootProfile: z.enum(["account", "project"]).default("project"),
14
14
  namespace: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/).optional(),
15
15
  projectName: z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._-]{0,99}$/).optional(),
16
+ /** GitHub/local branch tip; canonical workspace snapshots never replace it. */
17
+ baseCommitHash: GitOid.optional(),
16
18
  // Supervisor-owned exact argv approvals, NOT an agent-supplied read-only flag.
17
19
  // Approved servers must keep generated/cache files ignored and never write source.
18
20
  nonmutatingArgv: z.array(z.array(z.string()).min(1)).max(20).default([])
@@ -50,6 +52,7 @@ dist/
50
52
  build/
51
53
  coverage/
52
54
  .cache/
55
+ .bun/
53
56
  *.pem
54
57
  *.key
55
58
  `;
@@ -1,4 +1,5 @@
1
1
  type ResolutionDependencies = {
2
+ bundled?: string;
2
3
  resolvePackage?: (specifier: string) => string;
3
4
  which?: (command: string) => string | null;
4
5
  };
@@ -52,6 +52,7 @@ export declare const PersonalWorkspaceRequest: z.ZodObject<{
52
52
  }>>;
53
53
  namespace: z.ZodOptional<z.ZodString>;
54
54
  projectName: z.ZodOptional<z.ZodString>;
55
+ baseCommitHash: z.ZodOptional<z.ZodString>;
55
56
  }, z.core.$strict>;
56
57
  sourceWorkbench: z.ZodOptional<z.ZodObject<{
57
58
  id: z.ZodString;
@@ -64,6 +65,7 @@ export declare const PersonalWorkspaceRequest: z.ZodObject<{
64
65
  }>>;
65
66
  namespace: z.ZodOptional<z.ZodString>;
66
67
  projectName: z.ZodOptional<z.ZodString>;
68
+ baseCommitHash: z.ZodOptional<z.ZodString>;
67
69
  }, z.core.$strict>>;
68
70
  sharedWorkbenches: z.ZodOptional<z.ZodArray<z.ZodObject<{
69
71
  id: z.ZodString;
@@ -76,6 +78,7 @@ export declare const PersonalWorkspaceRequest: z.ZodObject<{
76
78
  }>>;
77
79
  namespace: z.ZodOptional<z.ZodString>;
78
80
  projectName: z.ZodOptional<z.ZodString>;
81
+ baseCommitHash: z.ZodOptional<z.ZodString>;
79
82
  }, z.core.$strict>>>;
80
83
  kind: z.ZodEnum<{
81
84
  inspect: "inspect";
@@ -34,6 +34,7 @@ export declare class WorkspaceAuthority {
34
34
  private assertNonOverlappingCheckout;
35
35
  private linkedWorkbench;
36
36
  private githubOrigin;
37
+ private canonicalRef;
37
38
  private resolveHostPath;
38
39
  static open(options: WorkspaceAuthorityOptions): Promise<WorkspaceAuthority>;
39
40
  private readonly registrations;
@@ -223,6 +224,7 @@ export declare class WorkspaceAuthority {
223
224
  sharedSessionId?: string | undefined;
224
225
  namespace?: string | undefined;
225
226
  projectName?: string | undefined;
227
+ baseCommitHash?: string | undefined;
226
228
  };
227
229
  }>;
228
230
  private cleanRefreshBase;
@@ -15,6 +15,7 @@ export declare const ApprovedWorkbench: z.ZodObject<{
15
15
  }>>;
16
16
  namespace: z.ZodOptional<z.ZodString>;
17
17
  projectName: z.ZodOptional<z.ZodString>;
18
+ baseCommitHash: z.ZodOptional<z.ZodString>;
18
19
  nonmutatingArgv: z.ZodDefault<z.ZodArray<z.ZodArray<z.ZodString>>>;
19
20
  }, z.core.$strict>;
20
21
  export type ApprovedWorkbench = z.input<typeof ApprovedWorkbench>;
@@ -36,6 +37,7 @@ export declare const WorkspaceConfig: z.ZodObject<{
36
37
  }>>;
37
38
  namespace: z.ZodOptional<z.ZodString>;
38
39
  projectName: z.ZodOptional<z.ZodString>;
40
+ baseCommitHash: z.ZodOptional<z.ZodString>;
39
41
  nonmutatingArgv: z.ZodDefault<z.ZodArray<z.ZodArray<z.ZodString>>>;
40
42
  }, z.core.$strict>>;
41
43
  dynamicWorkbenches: z.ZodOptional<z.ZodBoolean>;
@@ -85,4 +87,4 @@ export type WorkspaceState = {
85
87
  completedAt?: string;
86
88
  }>;
87
89
  };
88
- export declare const DEFAULT_WORKSPACE_IGNORE = "# Required destination workbench exclusions; keep these rules effective.\n.env\n.env.*\n!.env.example\nnode_modules/\n.r5d/\n.r5d-next/\n.ssh/\n.kube/\nsecrets/\ncredentials/\n.next/\ndist/\nbuild/\ncoverage/\n.cache/\n*.pem\n*.key\n";
90
+ export declare const DEFAULT_WORKSPACE_IGNORE = "# Required destination workbench exclusions; keep these rules effective.\n.env\n.env.*\n!.env.example\nnode_modules/\n.r5d/\n.r5d-next/\n.ssh/\n.kube/\nsecrets/\ncredentials/\n.next/\ndist/\nbuild/\ncoverage/\n.cache/\n.bun/\n*.pem\n*.key\n";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ricsam/r5d-worker",
3
- "version": "0.0.152",
3
+ "version": "0.0.154",
4
4
  "type": "module",
5
5
  "main": "./dist/mjs/main.mjs",
6
6
  "module": "./dist/mjs/main.mjs",
@@ -21,8 +21,7 @@
21
21
  "r5d-worker": "dist/mjs/main.mjs"
22
22
  },
23
23
  "dependencies": {
24
- "@ricsam/r5d-api": "^0.0.152",
25
- "@ricsam/r5dctl": "0.0.152",
24
+ "@ricsam/r5d-api": "^0.0.154",
26
25
  "node-pty": "1.1.0",
27
26
  "zod": "^4.1.13",
28
27
  "picomatch": "^4.0.3"