@miraland-labs/conduit-bridge 0.16.7 → 0.16.9

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 CHANGED
@@ -48,8 +48,8 @@ export function isSafeModelName(value) {
48
48
  return /^[A-Za-z0-9][A-Za-z0-9._/-]{0,99}$/.test(value);
49
49
  }
50
50
  /** Grants → Claude Code tool allow-list (mutate_repo mapping). Privileged grants are never mapped. */
51
- export function claudeToolsForGrants(grants, verificationCommands = []) {
52
- return projectClaude("mutate_repo", { grants, verificationCommands }).allowedTools;
51
+ export function claudeToolsForGrants(grants, verificationCommands = [], capabilities = []) {
52
+ return projectClaude("mutate_repo", { grants, verificationCommands, capabilities }).allowedTools;
53
53
  }
54
54
  export const claudeDeniedTools = deniedCommands.map((command) => `Bash(${command}:*)`);
55
55
  function resolveRunClass(input) {
@@ -475,6 +475,7 @@ export const claudeCodeDriver = {
475
475
  const projected = projectClaude(executionClass, {
476
476
  grants: input.grants,
477
477
  verificationCommands: input.verificationCommands,
478
+ capabilities: input.capabilities,
478
479
  diagnosis: input.workRole === "diagnose",
479
480
  });
480
481
  // Fail closed: omitting --allowedTools would leave only the deny-list and
@@ -4,7 +4,7 @@
4
4
  * Cached under {sourceWorkspace}/.conduit/normative-cache/ so sibling-repo specs are
5
5
  * fetched once per machine checkout, not once per attempt.
6
6
  */
7
- import { access, cp, mkdir, readFile, writeFile } from "node:fs/promises";
7
+ import { access, cp, mkdir, readFile, readdir, writeFile } from "node:fs/promises";
8
8
  import { constants } from "node:fs";
9
9
  import { dirname, join, relative } from "node:path";
10
10
  import { execFile } from "node:child_process";
@@ -15,7 +15,7 @@ const execFileAsync = promisify(execFile);
15
15
  export const normativeRefSchema = z.object({
16
16
  label: z.string().trim().min(1).max(120),
17
17
  repository: z.string().trim().min(3).max(500),
18
- paths: z.array(z.string().trim().min(1).max(500)).min(1).max(20),
18
+ paths: z.array(z.string().trim().min(1).max(500)).max(20),
19
19
  revision: z.string().trim().min(1).max(120).optional(),
20
20
  markers: z.array(z.string().trim().min(1).max(500)).max(20).optional(),
21
21
  });
@@ -131,6 +131,32 @@ async function ensureRepoCache(sourceWorkspace, ref) {
131
131
  await writeFile(marker, `${revision}\n`, "utf8");
132
132
  return { dir, revision };
133
133
  }
134
+ const CONTRACT_SURFACE = [
135
+ "README.md", "README", "README.rst", "README.txt",
136
+ "docs", "openapi.yaml", "openapi.yml", "openapi.json",
137
+ "CONTRACT.md", "NORMATIVE.md", "SPEC.md",
138
+ ];
139
+ /** Bounded files/dirs Bridge copies when the pin names a repo but not paths. */
140
+ export async function discoverNormativePaths(cacheRepo) {
141
+ const found = [];
142
+ for (const name of CONTRACT_SURFACE) {
143
+ if (await pathExists(join(cacheRepo, name)))
144
+ found.push(name);
145
+ }
146
+ if (found.length)
147
+ return found.slice(0, 20);
148
+ const entries = await readdir(cacheRepo, { withFileTypes: true }).catch(() => []);
149
+ for (const entry of entries) {
150
+ if (!entry.isFile() || entry.name.startsWith("."))
151
+ continue;
152
+ if (!/\.(md|markdown)$/i.test(entry.name))
153
+ continue;
154
+ found.push(entry.name);
155
+ if (found.length >= 20)
156
+ break;
157
+ }
158
+ return found;
159
+ }
134
160
  async function copyNormativePath(cacheRepo, attemptWorkspace, label, path) {
135
161
  validateNormativePath(path);
136
162
  const src = join(cacheRepo, path);
@@ -148,8 +174,12 @@ export async function materializeNormativeRefs(input) {
148
174
  const materialized = [];
149
175
  for (const ref of input.refs) {
150
176
  const { dir, revision } = await ensureRepoCache(input.sourceWorkspace, ref);
177
+ const paths = ref.paths.length ? ref.paths : await discoverNormativePaths(dir);
178
+ if (!paths.length) {
179
+ throw new Error(`${NORMATIVE_REF_PREFIX}: no published-contract files found in ${fingerprint(ref.repository)}`);
180
+ }
151
181
  const workspace_paths = [];
152
- for (const path of ref.paths) {
182
+ for (const path of paths) {
153
183
  workspace_paths.push(await copyNormativePath(dir, input.attemptWorkspace, ref.label, path));
154
184
  }
155
185
  materialized.push({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@miraland-labs/conduit-bridge",
3
- "version": "0.16.7",
3
+ "version": "0.16.9",
4
4
  "description": "Conduit Bridge CLI — 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": {