opencara 0.108.0 → 0.108.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.
- package/dist/bin.js +32 -13
- package/dist/claude-acp.js +59 -5
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -1153,6 +1153,7 @@ function runAcpJob(opts) {
|
|
|
1153
1153
|
const mcpServers = [host.acpServerEntry()];
|
|
1154
1154
|
const shimSupportsLoad = initResult.agentCapabilities?.loadSession === true;
|
|
1155
1155
|
let sessionId;
|
|
1156
|
+
let resumed = false;
|
|
1156
1157
|
if (acpSpec.priorSessionId && shimSupportsLoad) {
|
|
1157
1158
|
await client.loadSession({
|
|
1158
1159
|
sessionId: acpSpec.priorSessionId,
|
|
@@ -1160,6 +1161,7 @@ function runAcpJob(opts) {
|
|
|
1160
1161
|
mcpServers
|
|
1161
1162
|
});
|
|
1162
1163
|
sessionId = acpSpec.priorSessionId;
|
|
1164
|
+
resumed = true;
|
|
1163
1165
|
} else {
|
|
1164
1166
|
const session = await client.newSession({ cwd, mcpServers });
|
|
1165
1167
|
sessionId = session.sessionId;
|
|
@@ -1173,7 +1175,10 @@ function runAcpJob(opts) {
|
|
|
1173
1175
|
result = { exitCode: 1, stopReason: "cancelled", sessionId };
|
|
1174
1176
|
return result;
|
|
1175
1177
|
}
|
|
1176
|
-
const prompt = buildPromptContent(
|
|
1178
|
+
const prompt = buildPromptContent({
|
|
1179
|
+
...acpSpec,
|
|
1180
|
+
history: resumed ? [] : acpSpec.history
|
|
1181
|
+
});
|
|
1177
1182
|
const promptResult = await client.prompt({
|
|
1178
1183
|
sessionId,
|
|
1179
1184
|
prompt,
|
|
@@ -1307,7 +1312,7 @@ function resolveLocalAcpAdapter(command, args) {
|
|
|
1307
1312
|
}
|
|
1308
1313
|
|
|
1309
1314
|
// src/commands/run.ts
|
|
1310
|
-
var PKG_VERSION = "0.108.
|
|
1315
|
+
var PKG_VERSION = "0.108.2";
|
|
1311
1316
|
var LOG_FLUSH_MS = 800;
|
|
1312
1317
|
var MAX_CHUNK_SIZE = 4 * 1024;
|
|
1313
1318
|
async function run(opts = {}) {
|
|
@@ -1683,20 +1688,34 @@ function worktreeCreate(args) {
|
|
|
1683
1688
|
mkdirSync2(join2(cacheDir, ".git", "lfs", "objects"), { recursive: true });
|
|
1684
1689
|
}
|
|
1685
1690
|
}
|
|
1691
|
+
let reused = false;
|
|
1686
1692
|
if (existsSync4(join2(checkoutDir, ".git"))) {
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
git(checkoutDir, ["
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1693
|
+
try {
|
|
1694
|
+
git(checkoutDir, ["reset", "--hard", "HEAD"], gitEnv);
|
|
1695
|
+
git(checkoutDir, ["clean", "-fdx"], gitEnv);
|
|
1696
|
+
git(checkoutDir, ["fetch", "origin"], gitEnv);
|
|
1697
|
+
if (refExists(checkoutDir, `refs/remotes/origin/${branch}`)) {
|
|
1698
|
+
git(checkoutDir, ["checkout", "-B", branch, `origin/${branch}`], gitEnv);
|
|
1699
|
+
} else if (refExists(checkoutDir, `refs/heads/${branch}`)) {
|
|
1700
|
+
git(checkoutDir, ["checkout", branch], gitEnv);
|
|
1701
|
+
} else if (fromBranch) {
|
|
1702
|
+
git(checkoutDir, ["checkout", "-B", branch, `origin/${fromBranch}`], gitEnv);
|
|
1703
|
+
} else {
|
|
1704
|
+
fail(
|
|
1705
|
+
`worktree create: '${branch}' missing locally and on origin/, no --from-branch to fall back to`
|
|
1706
|
+
);
|
|
1707
|
+
}
|
|
1708
|
+
reused = true;
|
|
1709
|
+
} catch (err) {
|
|
1710
|
+
console.warn(
|
|
1711
|
+
`[worktree] reuse of ${checkoutDir} failed (${err.message}); re-cloning`
|
|
1697
1712
|
);
|
|
1713
|
+
rmSync(checkoutDir, { recursive: true, force: true });
|
|
1698
1714
|
}
|
|
1699
|
-
} else {
|
|
1715
|
+
} else if (existsSync4(checkoutDir)) {
|
|
1716
|
+
rmSync(checkoutDir, { recursive: true, force: true });
|
|
1717
|
+
}
|
|
1718
|
+
if (!reused) {
|
|
1700
1719
|
mkdirSync2(checkoutDir, { recursive: true });
|
|
1701
1720
|
const cloneArgs = ["-c", `credential.helper=${HELPER_SNIPPET}`, "clone"];
|
|
1702
1721
|
if (cacheDir) {
|
package/dist/claude-acp.js
CHANGED
|
@@ -61,6 +61,43 @@ function replyError(id, code, message) {
|
|
|
61
61
|
function notify(method, params) {
|
|
62
62
|
send({ jsonrpc: "2.0", method, params });
|
|
63
63
|
}
|
|
64
|
+
function normalizeMcpServers(raw) {
|
|
65
|
+
if (!Array.isArray(raw)) return [];
|
|
66
|
+
const out = [];
|
|
67
|
+
for (const entry of raw) {
|
|
68
|
+
if (!entry || typeof entry !== "object") continue;
|
|
69
|
+
const e = entry;
|
|
70
|
+
if (e["type"] !== "stdio") continue;
|
|
71
|
+
if (typeof e["name"] !== "string" || typeof e["command"] !== "string") continue;
|
|
72
|
+
const args = Array.isArray(e["args"]) ? e["args"].map(String) : [];
|
|
73
|
+
const env = [];
|
|
74
|
+
if (Array.isArray(e["env"])) {
|
|
75
|
+
for (const kv of e["env"]) {
|
|
76
|
+
if (!kv || typeof kv !== "object") continue;
|
|
77
|
+
const r = kv;
|
|
78
|
+
if (typeof r["name"] !== "string" || typeof r["value"] !== "string") continue;
|
|
79
|
+
env.push({ name: r["name"], value: r["value"] });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
out.push({
|
|
83
|
+
type: "stdio",
|
|
84
|
+
name: e["name"],
|
|
85
|
+
command: e["command"],
|
|
86
|
+
args,
|
|
87
|
+
env
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
function buildClaudeMcpConfig(servers) {
|
|
93
|
+
const mcpServers = {};
|
|
94
|
+
for (const s of servers) {
|
|
95
|
+
const env = {};
|
|
96
|
+
for (const kv of s.env) env[kv.name] = kv.value;
|
|
97
|
+
mcpServers[s.name] = { command: s.command, args: s.args, env };
|
|
98
|
+
}
|
|
99
|
+
return JSON.stringify({ mcpServers });
|
|
100
|
+
}
|
|
64
101
|
var sessions = /* @__PURE__ */ new Map();
|
|
65
102
|
async function runClaudeTurn(sessionId, state, promptText, permissionMode) {
|
|
66
103
|
return new Promise((resolve, reject) => {
|
|
@@ -82,6 +119,13 @@ async function runClaudeTurn(sessionId, state, promptText, permissionMode) {
|
|
|
82
119
|
} else {
|
|
83
120
|
args.push("--dangerously-skip-permissions");
|
|
84
121
|
}
|
|
122
|
+
if (state.mcpServers && state.mcpServers.length > 0) {
|
|
123
|
+
args.push(
|
|
124
|
+
"--mcp-config",
|
|
125
|
+
buildClaudeMcpConfig(state.mcpServers),
|
|
126
|
+
"--strict-mcp-config"
|
|
127
|
+
);
|
|
128
|
+
}
|
|
85
129
|
const child = spawn("claude", args, {
|
|
86
130
|
cwd: state.cwd,
|
|
87
131
|
env: process.env,
|
|
@@ -202,9 +246,9 @@ function handleInitialize(_params) {
|
|
|
202
246
|
agentCapabilities: {
|
|
203
247
|
// Session resume works by passing the ACP sessionId back as
|
|
204
248
|
// `claude --session-id <uuid>` on the next prompt — Claude CLI
|
|
205
|
-
// replays its own JSONL internally.
|
|
206
|
-
//
|
|
207
|
-
//
|
|
249
|
+
// replays its own JSONL internally. ACP's mcpServers are bridged
|
|
250
|
+
// to Claude via `--mcp-config <inline-json> --strict-mcp-config`
|
|
251
|
+
// on each turn (see SessionState.mcpServers / runClaudeTurn).
|
|
208
252
|
loadSession: true,
|
|
209
253
|
mcpCapabilities: {},
|
|
210
254
|
promptCapabilities: { embeddedContext: false, image: false, audio: false }
|
|
@@ -214,14 +258,24 @@ function handleInitialize(_params) {
|
|
|
214
258
|
}
|
|
215
259
|
function handleNewSession(params) {
|
|
216
260
|
const sessionId = randomUUID();
|
|
217
|
-
|
|
261
|
+
const mcpServers = normalizeMcpServers(params.mcpServers);
|
|
262
|
+
sessions.set(sessionId, {
|
|
263
|
+
cwd: params.cwd ?? process.cwd(),
|
|
264
|
+
resume: false,
|
|
265
|
+
...mcpServers.length > 0 ? { mcpServers } : {}
|
|
266
|
+
});
|
|
218
267
|
return { sessionId };
|
|
219
268
|
}
|
|
220
269
|
function handleLoadSession(params) {
|
|
221
270
|
if (typeof params.sessionId !== "string" || params.sessionId.length === 0) {
|
|
222
271
|
throw new Error("session/load: sessionId required");
|
|
223
272
|
}
|
|
224
|
-
|
|
273
|
+
const mcpServers = normalizeMcpServers(params.mcpServers);
|
|
274
|
+
sessions.set(params.sessionId, {
|
|
275
|
+
cwd: params.cwd ?? process.cwd(),
|
|
276
|
+
resume: true,
|
|
277
|
+
...mcpServers.length > 0 ? { mcpServers } : {}
|
|
278
|
+
});
|
|
225
279
|
return {};
|
|
226
280
|
}
|
|
227
281
|
async function handlePrompt(params) {
|