@miraland-labs/conduit-bridge 0.16.100 → 0.16.101

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/execution.js CHANGED
@@ -831,14 +831,18 @@ export async function claimNextAssignment(client, config, workspace, brief, driv
831
831
  for (const released of releasedWorktrees) {
832
832
  // T96: resolve the released attempt's own repository under the managed root, not the runner's
833
833
  // default workspace, so a retained tree in another managed checkout is actually swept.
834
- const releaseWorkspace = released.repository_fingerprint && options.managedRoot?.trim()
835
- ? managedWorkspacePath(options.managedRoot.trim(), released.repository_fingerprint)
836
- : workspace;
837
- const worktree = attemptWorktreePath(releaseWorkspace, released.attempt_id);
838
- await removeAttemptWorktree(releaseWorkspace, worktree)
839
- .then((removed) => { if (removed)
840
- console.log(`Released settled diagnostic worktree ${worktree}`); })
841
- .catch((error) => console.error(`Diagnostic worktree release failed: ${redactSecrets(error instanceof Error ? error.message : "unknown")}`));
834
+ try {
835
+ const releaseWorkspace = released.repository_fingerprint && options.managedRoot?.trim()
836
+ ? managedWorkspacePath(options.managedRoot.trim(), released.repository_fingerprint)
837
+ : workspace;
838
+ const worktree = attemptWorktreePath(releaseWorkspace, released.attempt_id);
839
+ await removeAttemptWorktree(releaseWorkspace, worktree)
840
+ .then((removed) => { if (removed)
841
+ console.log(`Released settled diagnostic worktree ${worktree}`); });
842
+ }
843
+ catch (error) {
844
+ console.error(`Diagnostic worktree release failed: ${redactSecrets(error instanceof Error ? error.message : "unknown")}`);
845
+ }
842
846
  }
843
847
  const assignment = assignments[0];
844
848
  if (!assignment)
@@ -1,7 +1,12 @@
1
1
  import { normalizeRepositoryUrl } from "./brief.js";
2
2
  /** Where a managed computer keeps `repositoryUrl` — `<root>/<owner>/<repo>`. */
3
3
  export function managedWorkspacePath(managedRoot, repositoryUrl) {
4
+ if (repositoryUrl.includes("\\"))
5
+ throw new Error("managed_workspace_repository_invalid");
4
6
  const parts = normalizeRepositoryUrl(repositoryUrl.trim()).split("/").filter(Boolean);
7
+ if (parts.length === 0 || parts.some((part) => part === "." || part === "..")) {
8
+ throw new Error("managed_workspace_repository_invalid");
9
+ }
5
10
  const name = parts[parts.length - 1] || "workspace";
6
11
  const owner = parts.length >= 2 ? parts[parts.length - 2] : null;
7
12
  const root = managedRoot.trim().replace(/[/]+$/, "");
@@ -3,7 +3,7 @@
3
3
  * machine-wide ops.env. The rebound runner's matching heartbeat clears the intent;
4
4
  * installation alone is not proof that the new process is actually bound.
5
5
  */
6
- import { resolve } from "node:path";
6
+ import { relative, resolve } from "node:path";
7
7
  import { expandOpsValue } from "./ops.js";
8
8
  import { ensureCheckout } from "./checkout.js";
9
9
  import { bootstrapManagedWorkspace } from "./workspace-bootstrap.js";
@@ -21,7 +21,12 @@ function pathsEqual(left, right) {
21
21
  * gives a managed checkout.
22
22
  */
23
23
  export async function switchManagedWorkspace(managedRoot, repositoryUrl, deps = {}) {
24
+ const root = resolve(expandOpsValue(managedRoot));
24
25
  const target = resolve(expandOpsValue(managedWorkspacePath(managedRoot, repositoryUrl)));
26
+ const fromRoot = relative(root, target);
27
+ if (!fromRoot || fromRoot === ".." || fromRoot.startsWith(`..${process.platform === "win32" ? "\\" : "/"}`) || resolve(root, fromRoot) !== target) {
28
+ throw new Error("managed_workspace_path_outside_root");
29
+ }
25
30
  const checkout = deps.ensureCheckout ?? ensureCheckout;
26
31
  const result = await checkout(target, repositoryUrl);
27
32
  if (result === "cloned") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miraland-labs/conduit-bridge",
3
- "version": "0.16.100",
3
+ "version": "0.16.101",
4
4
  "description": "Conduit Bridge CLI \u2014 join, connect, disconnect, multi-driver lanes, and run Claude Code / Codex / Cursor / OpenCode / Pi / Kiro / Antigravity / Grok Build agents for a Conduit organization",
5
5
  "type": "module",
6
6
  "bin": {