@ricsam/r5d-worker 0.0.54 → 0.0.56

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
@@ -17,11 +17,11 @@ Web shells and agent shell commands receive a server-issued `r5dctl` credential
17
17
 
18
18
  When the user has signed in with GitHub, web shells and agent commands also receive that OAuth credential through `GH_TOKEN`. GitHub CLI commands such as `gh pr`, `gh issue`, and `gh workflow` therefore use the signed-in user's permissions without a separate `gh auth login` on the worker host. Signing in again refreshes the granted OAuth scopes for subsequently started commands and shells.
19
19
 
20
- Visible branch checkouts are the user/agent workbench. Their `origin` remains the connected GitHub repository for manual Git work. r5d internal sync git metadata lives separately under `~/.r5d/sync`; when a worker connects, every idle registered branch is force-synchronized from that internal remote. The same destructive sync can be requested for a live worker from User Settings.
20
+ Visible branch checkouts are the user/agent workbench. Their `origin` remains the connected GitHub repository for manual Git work. r5d internal sync git metadata lives separately under `~/.r5d/sync`; each worker periodically snapshots eligible working-tree changes and reconciles them with the canonical workspace like an independent Git client. Ordinary commands and shells may remain active while this happens. Compatible inbound changes are hydrated into the visible checkout, while paths changed locally since the snapshot are preserved for a later sync or conflict-remediation pass. Canonical remediation shells are the exception: they edit the hidden synchronization checkout directly and remain serialized with synchronization.
21
21
 
22
22
  Branch names managed by r5d use lowercase letters, numbers, internal hyphens, and slash-separated segments, for example `ft/esm-support`. They may contain at most 45 characters. On the first start after upgrading to the nested checkout layout, the worker atomically moves each unambiguous legacy `<namespace>-<project>` directory to `<namespace>/<project>`. If both paths exist, it preserves both and stops with recovery instructions.
23
23
 
24
- Worker protocol releases are breaking server/worker cutovers. Run any release-specific preflight and backfill against the production database, stop and upgrade workers to the required version, deploy the matching server, and then reconnect workers. Older workers are rejected before WebSocket upgrade rather than receiving incompatible target or manifest messages.
24
+ Releases that change the worker protocol are explicitly documented as breaking server/worker cutovers. For those releases, run the release-specific preflight and backfill against the production database, stop and upgrade workers to the required version, deploy the matching server, and then reconnect workers. Older workers are rejected before WebSocket upgrade rather than receiving incompatible target or manifest messages. Protocol-compatible releases use the ordinary worker update flow.
25
25
 
26
26
  Worker labels are mandatory and unique per user. Choose labels that describe host capabilities, such as `macos`, `linux`, `ios`, or `ec2-build`.
27
27
 
package/dist/cjs/main.cjs CHANGED
@@ -64,6 +64,7 @@ var import_heartbeat = require("./heartbeat.cjs");
64
64
  var import_process_tree = require("./process-tree.cjs");
65
65
  var import_port_forward_client = require("./port-forward-client.cjs");
66
66
  var import_workspace_incident_state = require("./workspace-incident-state.cjs");
67
+ var import_workspace_command_sync_policy = require("./workspace-command-sync-policy.cjs");
67
68
  var import_supervisor = require("./supervisor.cjs");
68
69
  var import_managed_paths = require("./managed-paths.cjs");
69
70
  var import_workspace_sync = require("./workspace-sync.cjs");
@@ -2295,7 +2296,7 @@ async function openPty(input) {
2295
2296
  });
2296
2297
  },
2297
2298
  onExit: (event) => {
2298
- input.releaseWorkspaceMutation();
2299
+ input.releaseWorkspaceMutation?.();
2299
2300
  activePtys.delete(input.message.ptyId);
2300
2301
  sendWorkerMessage(input.ws, {
2301
2302
  type: "pty_exit",
@@ -2305,7 +2306,7 @@ async function openPty(input) {
2305
2306
  });
2306
2307
  },
2307
2308
  onError: (error) => {
2308
- input.releaseWorkspaceMutation();
2309
+ input.releaseWorkspaceMutation?.();
2309
2310
  activePtys.delete(input.message.ptyId);
2310
2311
  sendWorkerMessage(input.ws, {
2311
2312
  type: "pty_error",
@@ -2318,7 +2319,7 @@ async function openPty(input) {
2318
2319
  activePtys.set(input.message.ptyId, {
2319
2320
  ...ptyProcess,
2320
2321
  target: input.resolvedTarget.target,
2321
- releaseWorkspaceMutation: input.releaseWorkspaceMutation
2322
+ ...input.releaseWorkspaceMutation ? { releaseWorkspaceMutation: input.releaseWorkspaceMutation } : {}
2322
2323
  });
2323
2324
  }
2324
2325
  function writePty(ws, message) {
@@ -2864,14 +2865,20 @@ async function startWorker(options) {
2864
2865
  });
2865
2866
  return;
2866
2867
  }
2867
- const releaseWorkspaceMutation = await workspaceSyncSingleFlight.acquireMutation();
2868
+ const releaseWorkspaceMutation = await (0, import_workspace_command_sync_policy.acquireWorkspaceCommandMutation)(message.target, workspaceSyncSingleFlight);
2868
2869
  let leaseTransferred = false;
2869
2870
  try {
2870
2871
  const resolvedTarget = resolveMessageTarget(message.target);
2871
2872
  process.stdout.write(`[r5d-worker] pty ${message.ptyId}: ${describeWorkerSessionTarget(message.target)}
2872
2873
  `);
2873
- await openPty({ ws, message, resolvedTarget, planRoot, releaseWorkspaceMutation });
2874
- leaseTransferred = true;
2874
+ await openPty({
2875
+ ws,
2876
+ message,
2877
+ resolvedTarget,
2878
+ planRoot,
2879
+ ...releaseWorkspaceMutation ? { releaseWorkspaceMutation } : {}
2880
+ });
2881
+ leaseTransferred = releaseWorkspaceMutation !== void 0;
2875
2882
  } catch (error) {
2876
2883
  sendWorkerMessage(ws, {
2877
2884
  type: "pty_error",
@@ -2880,7 +2887,7 @@ async function startWorker(options) {
2880
2887
  error: error instanceof Error ? error.message : String(error)
2881
2888
  });
2882
2889
  } finally {
2883
- if (!leaseTransferred) releaseWorkspaceMutation();
2890
+ if (!leaseTransferred) releaseWorkspaceMutation?.();
2884
2891
  }
2885
2892
  return;
2886
2893
  }
@@ -2909,12 +2916,13 @@ async function startWorker(options) {
2909
2916
  }
2910
2917
  let result;
2911
2918
  try {
2912
- result = await workspaceSyncSingleFlight.runMutation(async () => {
2919
+ const runCommand = async () => {
2913
2920
  const resolvedTarget = resolveMessageTarget(message.target);
2914
2921
  process.stdout.write(`[r5d-worker] exec ${message.runId}: ${message.argv.join(" ")}
2915
2922
  `);
2916
2923
  return await executeCommand({ message, resolvedTarget, baseUrl, token, artifactRoot, planRoot });
2917
- });
2924
+ };
2925
+ result = await (0, import_workspace_command_sync_policy.runWorkspaceCommand)(message.target, workspaceSyncSingleFlight, runCommand);
2918
2926
  } catch (error) {
2919
2927
  result = {
2920
2928
  type: "exec_result",
@@ -2943,7 +2951,7 @@ async function startWorker(options) {
2943
2951
  requestId: message.requestId,
2944
2952
  runId: message.runId
2945
2953
  });
2946
- void workspaceSyncSingleFlight.runMutation(async () => {
2954
+ const runCommand = async () => {
2947
2955
  const resolvedTarget = resolveMessageTarget(message.target);
2948
2956
  process.stdout.write(`[r5d-worker] exec_start ${message.runId}: ${message.argv.join(" ")}
2949
2957
  `);
@@ -2956,7 +2964,9 @@ async function startWorker(options) {
2956
2964
  artifactRoot,
2957
2965
  planRoot
2958
2966
  });
2959
- }).catch((error) => {
2967
+ };
2968
+ const execution = (0, import_workspace_command_sync_policy.runWorkspaceCommand)(message.target, workspaceSyncSingleFlight, runCommand);
2969
+ void execution.catch((error) => {
2960
2970
  sendWorkerMessage(ws, {
2961
2971
  type: "exec_start_error",
2962
2972
  requestId: message.requestId,
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@ricsam/r5d-worker",
3
- "version": "0.0.54",
3
+ "version": "0.0.56",
4
4
  "type": "commonjs"
5
5
  }
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var workspace_command_sync_policy_exports = {};
20
+ __export(workspace_command_sync_policy_exports, {
21
+ acquireWorkspaceCommandMutation: () => acquireWorkspaceCommandMutation,
22
+ runWorkspaceCommand: () => runWorkspaceCommand,
23
+ shouldSerializeWorkspaceCommand: () => shouldSerializeWorkspaceCommand
24
+ });
25
+ module.exports = __toCommonJS(workspace_command_sync_policy_exports);
26
+ function shouldSerializeWorkspaceCommand(target) {
27
+ return target.type === "workspace" && target.rootProfile === "canonical_sync";
28
+ }
29
+ function runWorkspaceCommand(target, coordinator, operation) {
30
+ return shouldSerializeWorkspaceCommand(target) ? coordinator.runMutation(operation) : Promise.resolve().then(operation);
31
+ }
32
+ function acquireWorkspaceCommandMutation(target, coordinator) {
33
+ return shouldSerializeWorkspaceCommand(target) ? coordinator.acquireMutation() : Promise.resolve(void 0);
34
+ }
35
+ // Annotate the CommonJS export names for ESM import in node:
36
+ 0 && (module.exports = {
37
+ acquireWorkspaceCommandMutation,
38
+ runWorkspaceCommand,
39
+ shouldSerializeWorkspaceCommand
40
+ });