Initial commit
Supervised action bridge between Claude Code and the host system. Server accepts structured action requests, applies per-action policies (auto-accept/auto-deny/queue), and executes approved actions via typed handlers. Client provides CLI and module interfaces for calling the API. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
22
client/conduit.js
Normal file
22
client/conduit.js
Normal file
@@ -0,0 +1,22 @@
|
||||
// Conduit client module — import this when using conduit programmatically.
|
||||
// Designed for use by Claude or other tools that want to call conduit actions.
|
||||
|
||||
const BASE_URL = process.env.CONDUIT_URL || "http://localhost:3333";
|
||||
|
||||
export async function callAction(action, params = {}) {
|
||||
const res = await fetch(`${BASE_URL}/action`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ action, ...params }),
|
||||
});
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export async function listActions() {
|
||||
return callAction("list-actions");
|
||||
}
|
||||
|
||||
export async function getQueue() {
|
||||
const res = await fetch(`${BASE_URL}/queue`);
|
||||
return res.json();
|
||||
}
|
||||
51
client/index.js
Normal file
51
client/index.js
Normal file
@@ -0,0 +1,51 @@
|
||||
#!/usr/bin/env node
|
||||
// Conduit client — thin CLI wrapper for Claude to call the conduit server.
|
||||
// Usage:
|
||||
// node client/index.js <action> [key=value ...]
|
||||
// node client/index.js list-actions
|
||||
// node client/index.js edit-file filename=/workspace/foo.js
|
||||
|
||||
const BASE_URL = process.env.CONDUIT_URL || "http://localhost:3333";
|
||||
|
||||
async function callAction(action, params = {}) {
|
||||
const res = await fetch(`${BASE_URL}/action`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ action, ...params }),
|
||||
});
|
||||
|
||||
const body = await res.json();
|
||||
return { status: res.status, body };
|
||||
}
|
||||
|
||||
function parseArgs(argv) {
|
||||
const [, , action, ...rest] = argv;
|
||||
const params = {};
|
||||
for (const arg of rest) {
|
||||
const eq = arg.indexOf("=");
|
||||
if (eq === -1) {
|
||||
console.error(`Bad argument (expected key=value): ${arg}`);
|
||||
process.exit(1);
|
||||
}
|
||||
params[arg.slice(0, eq)] = arg.slice(eq + 1);
|
||||
}
|
||||
return { action, params };
|
||||
}
|
||||
|
||||
async function main() {
|
||||
if (process.argv.length < 3) {
|
||||
console.error("Usage: conduit <action> [key=value ...]");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const { action, params } = parseArgs(process.argv);
|
||||
const { status, body } = await callAction(action, params);
|
||||
|
||||
console.log(JSON.stringify(body, null, 2));
|
||||
process.exit(status >= 400 ? 1 : 0);
|
||||
}
|
||||
|
||||
main().catch((err) => {
|
||||
console.error("Conduit error:", err.message);
|
||||
process.exit(1);
|
||||
});
|
||||
Reference in New Issue
Block a user