@miraland-labs/conduit-bridge 0.16.127 → 0.16.130
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/driver.js +7 -4
- package/dist/ensure-test-evidence.js +1 -1
- package/dist/execution-class.js +4 -1
- package/dist/execution.js +5 -1
- package/dist/on-shift-apply.js +16 -0
- package/package.json +1 -1
package/dist/driver.js
CHANGED
|
@@ -696,7 +696,7 @@ export function claudeUsage(message) {
|
|
|
696
696
|
*/
|
|
697
697
|
export const CLAUDE_CODE_KNOWN_MODELS = [
|
|
698
698
|
"fable", "opus", "sonnet", "haiku",
|
|
699
|
-
"claude-fable-5-1", "claude-opus-5", "claude-sonnet-5", "claude-haiku-4-5",
|
|
699
|
+
"claude-fable-5-1", "claude-opus-5-5", "claude-opus-5", "claude-sonnet-5", "claude-haiku-4-5",
|
|
700
700
|
];
|
|
701
701
|
export const claudeCodeDriver = {
|
|
702
702
|
name: "claude-code",
|
|
@@ -960,7 +960,8 @@ export function cursorRunArgs(input) {
|
|
|
960
960
|
args.push(...modelArgs(cursorDriver, input.model));
|
|
961
961
|
if (input.resumeSessionId)
|
|
962
962
|
args.push("--resume", input.resumeSessionId);
|
|
963
|
-
|
|
963
|
+
// The prompt goes on stdin, as it does for codex: Linux caps one argument at 128 KiB
|
|
964
|
+
// (MAX_ARG_STRLEN) and an assignment contract exceeds that, which spawned `E2BIG`.
|
|
964
965
|
return args;
|
|
965
966
|
}
|
|
966
967
|
/** Parse `agent --list-models` output: one "id - Label" line per model. */
|
|
@@ -999,7 +1000,9 @@ export const cursorDriver = {
|
|
|
999
1000
|
vendor: "cursor",
|
|
1000
1001
|
// Cursor's own first-party families only. `--list-models` also lists other vendors' models
|
|
1001
1002
|
// Cursor proxies at a much higher price (the "Other Models" allowance) — those are not owned.
|
|
1002
|
-
|
|
1003
|
+
// Grok 4.7 dropped the `cursor-` prefix (`grok-4.7-high`, 2026-09-26) but Cursor still lists it
|
|
1004
|
+
// under "Cursor Models", beside Grok 4.6 and Composer.
|
|
1005
|
+
owns: (id) => id.startsWith("cursor-grok-") || id.startsWith("grok-") || id.startsWith("composer-"),
|
|
1003
1006
|
},
|
|
1004
1007
|
async run(input) {
|
|
1005
1008
|
const fuelSource = input.fuelSource === "local" ? "local" : "conduit";
|
|
@@ -1047,7 +1050,7 @@ export const cursorDriver = {
|
|
|
1047
1050
|
capabilities: input.capabilities ?? [],
|
|
1048
1051
|
diagnosis: input.workRole === "diagnose",
|
|
1049
1052
|
});
|
|
1050
|
-
const configured = await withCursorPermissions(input.workspace, { allow: projected.allow, deny: projected.deny }, () => execute(executable, cursorRunArgs({ ...input, trustWorkspace, executionClass, force: projected.force }), input.workspace, agentTurnTimeoutMs(input), undefined, "local",
|
|
1053
|
+
const configured = await withCursorPermissions(input.workspace, { allow: projected.allow, deny: projected.deny }, () => execute(executable, cursorRunArgs({ ...input, trustWorkspace, executionClass, force: projected.force }), input.workspace, agentTurnTimeoutMs(input), undefined, "local", input.prompt, input.signal));
|
|
1051
1054
|
const { code, stdout, stderr } = configured;
|
|
1052
1055
|
const parsed = parseCursorOutput(stdout);
|
|
1053
1056
|
// Cursor prints no token or cost figure, so the run reports the one fact it can prove: it ran.
|
|
@@ -101,7 +101,7 @@ export function verificationCommandsMentioned(text, offered = []) {
|
|
|
101
101
|
const source = text.slice(0, 20_000);
|
|
102
102
|
const verbatim = [...new Set(offered.map((command) => command.trim()))]
|
|
103
103
|
.filter((command) => isBoundedVerificationCommand(command) && textNamesCommand(source, command));
|
|
104
|
-
const pattern = /(?:^|[\s("'`])((?:npm run [A-Za-z0-9][A-Za-z0-9._:-]*|pnpm [A-Za-z0-9][A-Za-z0-9._:-]*|yarn [A-Za-z0-9][A-Za-z0-9._:-]*|cargo (?:test|check)|go test(?: \.\/\.\.\.)?|make [A-Za-z0-9][A-Za-z0-9._-]*|python3? -m [A-Za-z0-9_][\w.]*(?: [\w./=:-]*[./=-][\w./=:-]*)*|pytest(?: [\w./=-]*[./=-][\w./=-]*)?|python3? [\w./-]+\.py(?: [\w./=:-]*[./=-][\w./=:-]*)*|(?:\.\/gradlew|gradle|\.\/mvnw|mvn) test|Rscript tests\/testthat\.R|Rscript -e testthat::test_local\(\)))(?=$|[\s"'`),.;:])/g;
|
|
104
|
+
const pattern = /(?:^|[\s("'`])((?:npm run [A-Za-z0-9][A-Za-z0-9._:-]*|pnpm [A-Za-z0-9][A-Za-z0-9._:-]*|yarn [A-Za-z0-9][A-Za-z0-9._:-]*|cargo (?:test|check|clippy)|go test(?: \.\/\.\.\.)?|make [A-Za-z0-9][A-Za-z0-9._-]*|python3? -m [A-Za-z0-9_][\w.]*(?: [\w./=:-]*[./=-][\w./=:-]*)*|pytest(?: [\w./=-]*[./=-][\w./=-]*)?|python3? [\w./-]+\.py(?: [\w./=:-]*[./=-][\w./=:-]*)*|(?:\.\/gradlew|gradle|\.\/mvnw|mvn) test|Rscript tests\/testthat\.R|Rscript -e testthat::test_local\(\)))(?=$|[\s"'`),.;:])/g;
|
|
105
105
|
const mentions = [...new Set([...source.matchAll(pattern)].map((match) => match[1]))]
|
|
106
106
|
.filter((mention) => isBoundedVerificationCommand(mention)
|
|
107
107
|
&& !verbatim.some((command) => command === mention || command.startsWith(`${mention} `)));
|
package/dist/execution-class.js
CHANGED
|
@@ -13,7 +13,10 @@ export function isBoundedVerificationCommand(command) {
|
|
|
13
13
|
// A `*` is a legal character in a Python argument (`-p test_*.py` is how a repository spells its
|
|
14
14
|
// own gate). Bridge starts a gate with execFile and no shell, so the star stays literal and no
|
|
15
15
|
// expansion can happen. Refusing it only dropped the declaration, with no reason given.
|
|
16
|
-
|
|
16
|
+
// Cargo takes flags the same way: acme-sim registered `cargo clippy --all-targets -- -D warnings`
|
|
17
|
+
// on 2026-09-25, the rule admitted only a bare `cargo test|check`, and five deliveries shipped
|
|
18
|
+
// clippy failures because the gate was dropped before any attempt could run it.
|
|
19
|
+
return /^(npm run [A-Za-z0-9][A-Za-z0-9._:-]*|pnpm [A-Za-z0-9][A-Za-z0-9._:-]*|yarn [A-Za-z0-9][A-Za-z0-9._:-]*|cargo (test|check|clippy)(?: [\w./=:-]+)*|go test(?: \.\/\.\.\.)?|make [A-Za-z0-9][A-Za-z0-9._-]*|python3? -m [A-Za-z0-9_][\w.]*(?: [\w./=:*-]+)*|pytest(?: [\w./=*-]+)?|python3? [\w./-]+\.py(?: [\w./=:-]+)*|(?:\.\/gradlew|gradle|\.\/mvnw|mvn) test|Rscript tests\/testthat\.R|Rscript -e testthat::test_local\(\))$/.test(command);
|
|
17
20
|
}
|
|
18
21
|
/** Shell commands each grant authorizes — mapped per driver so they cannot drift. */
|
|
19
22
|
export const branchCreateCommands = [
|
package/dist/execution.js
CHANGED
|
@@ -1180,7 +1180,11 @@ async function runAttempt(client, config, driver, workspace, brief, taskId, watc
|
|
|
1180
1180
|
// diffing from the requested base would report commits that predate the agent as its work.
|
|
1181
1181
|
// T138: a rework carries the first revision's resolved start, because its worktree starts at the
|
|
1182
1182
|
// previous delivery's head. That lets a prose-only rework witness the original pack while still
|
|
1183
|
-
// including any new rework changes.
|
|
1183
|
+
// including any new rework changes. A conflict rework is different: it is pinned to the live base
|
|
1184
|
+
// tip and starts fresh there, so the control plane sends no carried base and the requested base --
|
|
1185
|
+
// the pinned tip -- is the delivery base. Diffing from the first revision's start would report
|
|
1186
|
+
// every commit the base gained in between as the agent's own work. Older contracts fall back to
|
|
1187
|
+
// the T136 rule.
|
|
1184
1188
|
const rework = task.delivery_state === "changes_requested" || Boolean(executionContract.prior_head_commit);
|
|
1185
1189
|
const deliveryBaseCommit = executionContract.delivery_base_commit
|
|
1186
1190
|
?? (rework
|
package/dist/on-shift-apply.js
CHANGED
|
@@ -8,6 +8,7 @@ import { expandOpsValue } from "./ops.js";
|
|
|
8
8
|
import { ensureCheckout } from "./checkout.js";
|
|
9
9
|
import { bootstrapManagedWorkspace } from "./workspace-bootstrap.js";
|
|
10
10
|
import { managedWorkspacePath } from "./managed-workspace-path.js";
|
|
11
|
+
import { refreshSourceWorkspace } from "./workspace-refresh.js";
|
|
11
12
|
export { managedWorkspacePath } from "./managed-workspace-path.js";
|
|
12
13
|
function pathsEqual(left, right) {
|
|
13
14
|
return resolve(expandOpsValue(left)) === resolve(expandOpsValue(right));
|
|
@@ -32,6 +33,21 @@ export async function switchManagedWorkspace(managedRoot, repositoryUrl, deps =
|
|
|
32
33
|
if (result === "cloned") {
|
|
33
34
|
console.log(`Cloned ${repositoryUrl} into ${target}`);
|
|
34
35
|
(deps.bootstrapWorkspace ?? bootstrapManagedWorkspace)(target);
|
|
36
|
+
return target;
|
|
37
|
+
}
|
|
38
|
+
// The runner's own refresh follows only the workspace it was started on. A managed checkout it
|
|
39
|
+
// switches into was never refreshed: acme-sim stayed shallow at a five-day-old main on
|
|
40
|
+
// 2026-09-25 while every claim read it. Follow origin here, before the claim reads the checkout.
|
|
41
|
+
// A dirty or diverged checkout is not moved; the attempt worktree refuses a dirty source.
|
|
42
|
+
const refresh = await refreshSourceWorkspace(target).catch(() => null);
|
|
43
|
+
if (refresh?.state === "fast_forwarded") {
|
|
44
|
+
console.log(`Managed workspace ${target} fast-forwarded to origin/${refresh.branch}.`);
|
|
45
|
+
}
|
|
46
|
+
else if (refresh?.state === "diverged") {
|
|
47
|
+
console.error(`Managed workspace ${target} cannot fast-forward: ${refresh.local_commits} local-only commit(s) on ${refresh.branch}. Park or push them.`);
|
|
48
|
+
}
|
|
49
|
+
else if (refresh?.state !== "up_to_date") {
|
|
50
|
+
console.error(`Managed workspace ${target} could not follow origin (dirty tree, detached HEAD, or fetch failed).`);
|
|
35
51
|
}
|
|
36
52
|
return target;
|
|
37
53
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miraland-labs/conduit-bridge",
|
|
3
|
-
"version": "0.16.
|
|
3
|
+
"version": "0.16.130",
|
|
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": {
|