@bivy/bivy 0.1.1 → 0.1.2

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.
@@ -117,6 +117,23 @@ export class ControlPlaneTaskPoller {
117
117
  poke() {
118
118
  void this.tick();
119
119
  }
120
+ /**
121
+ * Replace the routing labels this live poller serves.
122
+ *
123
+ * Node names are editable while the daemon is running, and targeted queue
124
+ * labels are derived from that name (`bivy/<name>`). Keeping the startup-time
125
+ * labels forever leaves work routed to a renamed node pending until the daemon
126
+ * restarts. Update in place so already-running queue jobs are not disturbed,
127
+ * then poll immediately for work addressed to the new name.
128
+ */
129
+ setLabels(labels) {
130
+ const next = Array.from(new Set(labels.map((label) => label.trim()).filter(Boolean)));
131
+ if (!next.length || (next.length === this.cfg.labels.length && next.every((label, i) => label === this.cfg.labels[i])))
132
+ return;
133
+ this.cfg.labels = next;
134
+ console.log(`[control-plane-tasks] now watching hosted queue for labels [${next.join(", ")}]`);
135
+ this.poke();
136
+ }
120
137
  stop() {
121
138
  if (this.timer)
122
139
  clearInterval(this.timer);
package/dist/git-auth.js CHANGED
@@ -88,7 +88,13 @@ function writeIfChanged(file, content, mode) {
88
88
  export function ensureCredentialHelper() {
89
89
  fs.mkdirSync(credDir(), { recursive: true, mode: 0o700 });
90
90
  writeIfChanged(workerPath(), WORKER_SOURCE, 0o700);
91
- const shim = `#!/usr/bin/env sh\nexec ${shDq(process.execPath)} ${shDq(workerPath())} "$@"\n`;
91
+ // Git can invoke a credential helper after its caller's checkout has been
92
+ // removed (for example while an old daemon drains across an npm update, or
93
+ // while a broken clone is being rebuilt). Node resolves its cwd before it
94
+ // evaluates the worker and aborts with uv_cwd when that inherited directory
95
+ // has been unlinked. Move to a stable directory in the shell first; the worker
96
+ // resolves endpoint.json from import.meta.url and never relies on cwd.
97
+ const shim = `#!/usr/bin/env sh\ncd / || exit 0\nexec ${shDq(process.execPath)} ${shDq(workerPath())} "$@"\n`;
92
98
  writeIfChanged(shimPath(), shim, 0o700);
93
99
  return shimPath();
94
100
  }
package/dist/server.js CHANGED
@@ -86,7 +86,7 @@ const repoRoot = path.resolve(__dirname, "..");
86
86
  // running from source. Packaged/release builds may override them (BIVY_ASSET_ROOT,
87
87
  // BIVY_DATA_DIR) so it can write outside the read-only app bundle.
88
88
  const assetRoot = process.env.BIVY_ASSET_ROOT ?? repoRoot;
89
- const appDir = process.env.BIVY_DATA_DIR ?? path.join(repoRoot, ".bivy");
89
+ const appDir = path.resolve(process.env.BIVY_DATA_DIR ?? path.join(repoRoot, ".bivy"));
90
90
  // Load persisted env from cli.json into process.env so config written there —
91
91
  // e.g. connecting a GitHub App (BIVY_GITHUB_APP_ID / BIVY_GITHUB_HOSTED_TASKS /
92
92
  // BIVY_NODE_LABEL) — takes effect on the NEXT restart even if the service
@@ -115,6 +115,13 @@ initSharedDepCache(appDir);
115
115
  // Materialize the git credential helper under the data dir so repo clones can
116
116
  // authenticate without ever writing a token into their remote URL / .git/config.
117
117
  configureGitAuth(appDir);
118
+ // Never leave the daemon parked in its installed package directory. A global
119
+ // npm update atomically replaces that directory while the old process drains;
120
+ // any later child process (notably git's remote/credential helpers) then aborts
121
+ // before running with "Unable to read current working directory". appDir is the
122
+ // durable state root and every workspace/asset path below is already absolute.
123
+ // Anchoring the process itself fixes all subprocess paths, not just `git clone`.
124
+ process.chdir(appDir);
118
125
  // Make `bivy update` and user-scoped npm globals available to agents/tools
119
126
  // launched by the daemon even when the node runs under systemd/launchd with a
120
127
  // minimal PATH. The installer also symlinks ~/.local/bin/bivy, but adding these
@@ -2377,6 +2384,9 @@ const RELAY_COMMANDS = {
2377
2384
  "node.rename"(msg, ctx) {
2378
2385
  const prev = identity.name;
2379
2386
  const name = identity.setName(String(msg.name ?? ""));
2387
+ // Queue routing follows the node name (`bivy/<name>`). Update the live
2388
+ // poller now instead of leaving it on its startup-time label until restart.
2389
+ refreshControlPlaneTaskLabels();
2380
2390
  void advertiseNodeName(name, prev);
2381
2391
  ctx.broadcast({ type: "node.updated", name });
2382
2392
  ctx.reply({ type: "node.updated", name });
@@ -3850,6 +3860,7 @@ async function advertiseNodeName(name, prevName) {
3850
3860
  const accepted = typeof data?.node?.name === "string" ? data.node.name : undefined;
3851
3861
  if (accepted && accepted !== identity.name) {
3852
3862
  identity.setName(accepted);
3863
+ refreshControlPlaneTaskLabels();
3853
3864
  broadcast({ type: "node.updated", name: accepted });
3854
3865
  relay?.sendEvent({ type: "node.updated", name: accepted });
3855
3866
  }
@@ -3859,6 +3870,7 @@ async function advertiseNodeName(name, prevName) {
3859
3870
  // optimistic local change so the node name stays consistent with the account.
3860
3871
  if (prevName && prevName !== identity.name) {
3861
3872
  identity.setName(prevName);
3873
+ refreshControlPlaneTaskLabels();
3862
3874
  broadcast({ type: "node.updated", name: prevName });
3863
3875
  relay?.sendEvent({ type: "node.updated", name: prevName });
3864
3876
  }
@@ -4524,6 +4536,14 @@ async function startGitHubTasksIfConfigured() {
4524
4536
  githubPoller.start();
4525
4537
  }
4526
4538
  let controlPlanePoller;
4539
+ /** Refresh a running queue poller's labels after the node is renamed. */
4540
+ function refreshControlPlaneTaskLabels() {
4541
+ if (!controlPlanePoller)
4542
+ return;
4543
+ const cfg = resolveControlPlaneTaskConfig(loadRelayConfig(appDir), process.env, identity.name);
4544
+ if (cfg)
4545
+ controlPlanePoller.setLabels(cfg.labels);
4546
+ }
4527
4547
  let githubApps;
4528
4548
  const installationIdByRepo = new Map();
4529
4549
  /** Resolve (once) the GitHub Apps configured on this node. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bivy/bivy",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "license": "FSL-1.1-ALv2",
6
6
  "description": "Run coding agents on machines you own. Source-available, self-hostable agent workspace.",