@wrongstack/acp 0.286.0 → 0.289.0
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/README.md +27 -23
- package/dist/agent/wrongstack-acp-agent.d.ts +7 -0
- package/dist/agent/wrongstack-acp-agent.d.ts.map +1 -1
- package/dist/agent.js +62 -18
- package/dist/agent.js.map +2 -2
- package/dist/client/acp-session.d.ts +17 -0
- package/dist/client/acp-session.d.ts.map +1 -1
- package/dist/client/file-server.d.ts +27 -5
- package/dist/client/file-server.d.ts.map +1 -1
- package/dist/client/terminal-server.d.ts +15 -0
- package/dist/client/terminal-server.d.ts.map +1 -1
- package/dist/client.js +201 -32
- package/dist/client.js.map +3 -3
- package/dist/index.js +291 -51
- package/dist/index.js.map +3 -3
- package/dist/integration/acp-subagent-runner.d.ts.map +1 -1
- package/dist/registry/acp-registry-fetch.d.ts.map +1 -1
- package/dist/registry/agents.catalog.d.ts.map +1 -1
- package/dist/registry/ensemble-registry.d.ts +1 -1
- package/dist/registry/ensemble-registry.d.ts.map +1 -1
- package/dist/sdk.js +290 -51
- package/dist/sdk.js.map +3 -3
- package/dist/wrongstack-acp-agent.js +62 -18
- package/dist/wrongstack-acp-agent.js.map +2 -2
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acp-subagent-runner.d.ts","sourceRoot":"","sources":["../../src/integration/acp-subagent-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAKV,cAAc,EAEf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,UAAU,EAIV,KAAK,kBAAkB,EACxB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAEhE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAEpD,MAAM,WAAW,wBAAwB;IACvC,uCAAuC;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACzC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC;;;;OAIG;IACH,UAAU,CAAC,EAAE,kBAAkB,GAAG,SAAS,CAAC;IAC5C;;;;;OAKG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAC;IAChD;;;;OAIG;IACH,UAAU,CAAC,EAAE,SAAS,EAAE,GAAG,SAAS,CAAC;IACrC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAuBvE,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,cAAc,CAAC,CAazB;AAED;;;;;;GAMG;AACH,wBAAsB,6BAA6B,CACjD,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC;IAAE,MAAM,EAAE,cAAc,CAAC;IAAC,IAAI,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,CAAC,CAgGvE;AAoFD,gEAAgE;AAChE,YAAY,EAAE,UAAU,EAAE,CAAC;AAE3B,kDAAkD;AAClD,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,IAAI,CAQP;AASD;;;;;;GAMG;AACH,MAAM,MAAM,wBAAwB,GAAG,MAAM,CAC3C,MAAM,EACN;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CACnE,CAAC;AAEF,gFAAgF;AAChF,MAAM,MAAM,cAAc,GAAG,MAAM,CACjC,MAAM,EACN;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAC5E,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"acp-subagent-runner.d.ts","sourceRoot":"","sources":["../../src/integration/acp-subagent-runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"acp-registry-fetch.d.ts","sourceRoot":"","sources":["../../src/registry/acp-registry-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,wBAAwB,CAAC;AAEhC,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,yEAC2C,CAAC;AAEzE,yEAAyE;AACzE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE;QACb,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QAC3C,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QAC3C,MAAM,CAAC,EAAE,MAAM,CACb,MAAM,EACN;YAAE,OAAO,CAAC,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,CACjF,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,yEAAyE;AACzE,wBAAgB,kBAAkB,IAAI,MAAM,CAS3C;AASD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,kBAAkB,EACzB,WAAW,GAAE,MAA6B,GACzC,kBAAkB,GAAG,IAAI,CAmC3B;
|
|
1
|
+
{"version":3,"file":"acp-registry-fetch.d.ts","sourceRoot":"","sources":["../../src/registry/acp-registry-fetch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,wBAAwB,CAAC;AAEhC,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,yEAC2C,CAAC;AAEzE,yEAAyE;AACzE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE;QACb,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QAC3C,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;SAAE,CAAC;QAC3C,MAAM,CAAC,EAAE,MAAM,CACb,MAAM,EACN;YAAE,OAAO,CAAC,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAC;YAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;SAAE,CACjF,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,sBAAsB;IACrC,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,MAAM,EAAE,kBAAkB,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,uBAAuB;IACtC,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B,yEAAyE;IACzE,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAClC;AAED,yEAAyE;AACzE,wBAAgB,kBAAkB,IAAI,MAAM,CAS3C;AASD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,kBAAkB,EACzB,WAAW,GAAE,MAA6B,GACzC,kBAAkB,GAAG,IAAI,CAmC3B;AAYD;;;;GAIG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,GAAE,uBAA4B,GACjC,OAAO,CAAC,sBAAsB,CAAC,CA+BjC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.catalog.d.ts","sourceRoot":"","sources":["../../src/registry/agents.catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,kBAAkB,
|
|
1
|
+
{"version":3,"file":"agents.catalog.d.ts","sourceRoot":"","sources":["../../src/registry/agents.catalog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAEjE;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,SAAS,kBAAkB,EA2O9C,CAAC;AAEX,8DAA8D;AAC9D,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,MAAM,GACT,kBAAkB,GAAG,SAAS,CAEhC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Vendor classification — used to filter the catalog by family. */
|
|
2
|
-
export type ACPAgentVendor = 'anthropic' | 'google' | 'openai' | 'github' | 'community';
|
|
2
|
+
export type ACPAgentVendor = 'anthropic' | 'google' | 'openai' | 'github' | 'moonshot' | 'community';
|
|
3
3
|
/** How the agent is integrated into ACP. */
|
|
4
4
|
export type ACPIntegration =
|
|
5
5
|
/** Agent ships with a documented ACP entry flag. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ensemble-registry.d.ts","sourceRoot":"","sources":["../../src/registry/ensemble-registry.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ensemble-registry.d.ts","sourceRoot":"","sources":["../../src/registry/ensemble-registry.ts"],"names":[],"mappings":"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"}
|
package/dist/sdk.js
CHANGED
|
@@ -155,7 +155,7 @@ var ClientTransport = class {
|
|
|
155
155
|
}
|
|
156
156
|
async start() {
|
|
157
157
|
if (this.child) return;
|
|
158
|
-
const [{ spawn: spawn2 }, { buildChildEnv }, os] = await Promise.all([
|
|
158
|
+
const [{ spawn: spawn2 }, { buildChildEnv: buildChildEnv2 }, os] = await Promise.all([
|
|
159
159
|
import("node:child_process"),
|
|
160
160
|
import("@wrongstack/core"),
|
|
161
161
|
import("node:os")
|
|
@@ -172,7 +172,7 @@ var ClientTransport = class {
|
|
|
172
172
|
const childArgs = this.opts.args ?? [];
|
|
173
173
|
const shim = process.platform === "win32" ? buildWin32CmdShimInvocation(this.opts.command, childArgs) : null;
|
|
174
174
|
this.child = spawn2(shim?.command ?? this.opts.command, shim?.args ?? childArgs, {
|
|
175
|
-
env: { ...
|
|
175
|
+
env: { ...buildChildEnv2(), ...this.opts.env },
|
|
176
176
|
cwd: spawnCwd,
|
|
177
177
|
stdio: ["pipe", "pipe", "pipe"],
|
|
178
178
|
windowsHide: true,
|
|
@@ -414,8 +414,12 @@ var WebSocketClientTransport = class {
|
|
|
414
414
|
var ACP_PROTOCOL_VERSION = 1;
|
|
415
415
|
|
|
416
416
|
// src/client/file-server.ts
|
|
417
|
+
import { randomBytes } from "node:crypto";
|
|
418
|
+
import { realpathSync } from "node:fs";
|
|
417
419
|
import * as fsp from "node:fs/promises";
|
|
418
420
|
import * as path from "node:path";
|
|
421
|
+
var DEFAULT_MAX_READ_BYTES = 5 * 1024 * 1024;
|
|
422
|
+
var DEFAULT_MAX_WRITE_BYTES = 5 * 1024 * 1024;
|
|
419
423
|
var FsError = class extends Error {
|
|
420
424
|
code;
|
|
421
425
|
path;
|
|
@@ -428,23 +432,40 @@ var FsError = class extends Error {
|
|
|
428
432
|
};
|
|
429
433
|
var FileServer = class {
|
|
430
434
|
root;
|
|
435
|
+
realRoot;
|
|
431
436
|
timeoutMs;
|
|
437
|
+
maxReadBytes;
|
|
438
|
+
maxWriteBytes;
|
|
432
439
|
constructor(opts) {
|
|
433
440
|
this.root = path.resolve(opts.projectRoot);
|
|
441
|
+
this.realRoot = safeRealpathSync(this.root);
|
|
434
442
|
this.timeoutMs = opts.timeoutMs ?? 3e4;
|
|
443
|
+
this.maxReadBytes = opts.maxReadBytes ?? DEFAULT_MAX_READ_BYTES;
|
|
444
|
+
this.maxWriteBytes = opts.maxWriteBytes ?? DEFAULT_MAX_WRITE_BYTES;
|
|
435
445
|
}
|
|
436
446
|
/** Read a text file. Returns the content as a string. */
|
|
437
447
|
async readTextFile(params) {
|
|
438
|
-
const safe = this.resolveInside(params.path);
|
|
448
|
+
const safe = await this.resolveInside(params.path);
|
|
439
449
|
const controller = new AbortController();
|
|
440
450
|
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
441
451
|
try {
|
|
452
|
+
const stat2 = await fsp.stat(safe).catch((err) => {
|
|
453
|
+
throw mapFsError(err, safe);
|
|
454
|
+
});
|
|
455
|
+
if (stat2.size > this.maxReadBytes) {
|
|
456
|
+
throw new FsError(
|
|
457
|
+
"TOO_LARGE",
|
|
458
|
+
safe,
|
|
459
|
+
`file is ${stat2.size} bytes, max read is ${this.maxReadBytes} bytes`
|
|
460
|
+
);
|
|
461
|
+
}
|
|
442
462
|
const content = await fsp.readFile(safe, {
|
|
443
463
|
encoding: "utf8",
|
|
444
464
|
signal: controller.signal
|
|
445
465
|
});
|
|
446
466
|
return { content };
|
|
447
467
|
} catch (err) {
|
|
468
|
+
if (err instanceof FsError) throw err;
|
|
448
469
|
if (controller.signal.aborted) {
|
|
449
470
|
throw new FsError("TIMEOUT", safe, `readTextFile timed out after ${this.timeoutMs}ms`);
|
|
450
471
|
}
|
|
@@ -455,17 +476,31 @@ var FileServer = class {
|
|
|
455
476
|
}
|
|
456
477
|
/** Write a text file. Atomic via write-then-rename. */
|
|
457
478
|
async writeTextFile(params) {
|
|
458
|
-
const
|
|
479
|
+
const byteLength = Buffer.byteLength(params.content, "utf8");
|
|
480
|
+
if (byteLength > this.maxWriteBytes) {
|
|
481
|
+
throw new FsError(
|
|
482
|
+
"TOO_LARGE",
|
|
483
|
+
params.path,
|
|
484
|
+
`content is ${byteLength} bytes, max write is ${this.maxWriteBytes} bytes`
|
|
485
|
+
);
|
|
486
|
+
}
|
|
487
|
+
const safe = await this.resolveInside(params.path);
|
|
459
488
|
const controller = new AbortController();
|
|
460
489
|
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
461
|
-
const tmp = `${safe}.${
|
|
490
|
+
const tmp = `${safe}.${randomBytes(6).toString("hex")}.tmp`;
|
|
462
491
|
try {
|
|
463
492
|
await fsp.writeFile(tmp, params.content, {
|
|
464
493
|
encoding: "utf8",
|
|
465
494
|
signal: controller.signal
|
|
466
495
|
});
|
|
496
|
+
await this.assertRealInside(tmp);
|
|
497
|
+
await this.assertRealInside(path.dirname(safe));
|
|
467
498
|
await fsp.rename(tmp, safe);
|
|
468
499
|
} catch (err) {
|
|
500
|
+
if (err instanceof FsError) {
|
|
501
|
+
await fsp.unlink(tmp).catch(() => void 0);
|
|
502
|
+
throw err;
|
|
503
|
+
}
|
|
469
504
|
try {
|
|
470
505
|
await fsp.unlink(tmp);
|
|
471
506
|
} catch {
|
|
@@ -479,12 +514,14 @@ var FileServer = class {
|
|
|
479
514
|
}
|
|
480
515
|
}
|
|
481
516
|
/**
|
|
482
|
-
* Resolve a path
|
|
483
|
-
*
|
|
484
|
-
*
|
|
485
|
-
*
|
|
517
|
+
* Resolve a path and verify it is inside the project root by realpath.
|
|
518
|
+
* Rejects with `FsError` if the textual path, the resolved path, or the
|
|
519
|
+
* real (symlink-resolved) path escapes the project root.
|
|
520
|
+
*
|
|
521
|
+
* For files that don't exist yet (e.g. a write to a new file), the
|
|
522
|
+
* nearest existing ancestor directory is realpath-checked instead.
|
|
486
523
|
*/
|
|
487
|
-
resolveInside(p) {
|
|
524
|
+
async resolveInside(p) {
|
|
488
525
|
if (typeof p !== "string" || p.length === 0) {
|
|
489
526
|
throw new FsError("INVALID_PATH", p, "path is empty or not a string");
|
|
490
527
|
}
|
|
@@ -496,8 +533,38 @@ var FileServer = class {
|
|
|
496
533
|
if (resolved !== this.root && !resolved.startsWith(rootWithSep)) {
|
|
497
534
|
throw new FsError("OUTSIDE_ROOT", resolved, "path is outside the project root");
|
|
498
535
|
}
|
|
536
|
+
await this.assertRealInside(resolved);
|
|
499
537
|
return resolved;
|
|
500
538
|
}
|
|
539
|
+
/**
|
|
540
|
+
* Resolve `resolvedPath` through `fs.realpath` and verify the result is
|
|
541
|
+
* inside `realRoot`. For non-existent paths (new files), walk up to the
|
|
542
|
+
* nearest existing ancestor and check that instead.
|
|
543
|
+
*/
|
|
544
|
+
async assertRealInside(resolvedPath) {
|
|
545
|
+
let probe = resolvedPath;
|
|
546
|
+
for (; ; ) {
|
|
547
|
+
let real;
|
|
548
|
+
try {
|
|
549
|
+
real = await fsp.realpath(probe);
|
|
550
|
+
} catch (err) {
|
|
551
|
+
const code = err.code;
|
|
552
|
+
if (code === "ENOENT") {
|
|
553
|
+
const parent = path.dirname(probe);
|
|
554
|
+
if (parent === probe) return;
|
|
555
|
+
probe = parent;
|
|
556
|
+
continue;
|
|
557
|
+
}
|
|
558
|
+
throw mapFsError(err, resolvedPath);
|
|
559
|
+
}
|
|
560
|
+
if (real === this.realRoot || real.startsWith(this.realRoot + path.sep)) return;
|
|
561
|
+
throw new FsError(
|
|
562
|
+
"OUTSIDE_ROOT",
|
|
563
|
+
resolvedPath,
|
|
564
|
+
"path resolves through a symlink outside the project root"
|
|
565
|
+
);
|
|
566
|
+
}
|
|
567
|
+
}
|
|
501
568
|
};
|
|
502
569
|
function mapFsError(err, p) {
|
|
503
570
|
const code = err?.code;
|
|
@@ -508,12 +575,12 @@ function mapFsError(err, p) {
|
|
|
508
575
|
const msg = err instanceof Error ? err.message : String(err);
|
|
509
576
|
return new FsError("INVALID_PATH", p, msg);
|
|
510
577
|
}
|
|
511
|
-
function
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
578
|
+
function safeRealpathSync(p) {
|
|
579
|
+
try {
|
|
580
|
+
return realpathSync(p);
|
|
581
|
+
} catch {
|
|
582
|
+
return p;
|
|
515
583
|
}
|
|
516
|
-
return out;
|
|
517
584
|
}
|
|
518
585
|
|
|
519
586
|
// src/client/permission.ts
|
|
@@ -562,17 +629,21 @@ function makePermissionPolicy(decide) {
|
|
|
562
629
|
|
|
563
630
|
// src/client/terminal-server.ts
|
|
564
631
|
import { spawn } from "node:child_process";
|
|
632
|
+
import { realpathSync as realpathSync2 } from "node:fs";
|
|
565
633
|
import * as path2 from "node:path";
|
|
634
|
+
import { buildChildEnv } from "@wrongstack/core/utils";
|
|
566
635
|
var TerminalServer = class {
|
|
567
636
|
terminals = /* @__PURE__ */ new Map();
|
|
568
637
|
projectRoot;
|
|
569
638
|
commandTimeoutMs;
|
|
570
639
|
outputByteLimit;
|
|
640
|
+
maxOutputByteLimit;
|
|
571
641
|
nextId = 1;
|
|
572
642
|
constructor(opts) {
|
|
573
643
|
this.projectRoot = path2.resolve(opts.projectRoot);
|
|
574
644
|
this.commandTimeoutMs = opts.commandTimeoutMs ?? 5 * 6e4;
|
|
575
645
|
this.outputByteLimit = opts.outputByteLimit ?? 1024 * 1024;
|
|
646
|
+
this.maxOutputByteLimit = opts.maxOutputByteLimit ?? 16 * 1024 * 1024;
|
|
576
647
|
if (opts.signal) {
|
|
577
648
|
opts.signal.addEventListener("abort", () => this.releaseAll());
|
|
578
649
|
}
|
|
@@ -626,12 +697,15 @@ var TerminalServer = class {
|
|
|
626
697
|
state.exitStatus = exitStatus;
|
|
627
698
|
state.output += `[spawn error] ${err.message}
|
|
628
699
|
`;
|
|
629
|
-
state.retainedBytes
|
|
700
|
+
state.retainedBytes = Buffer.byteLength(state.output, "utf8");
|
|
630
701
|
resolve3(exitStatus);
|
|
631
702
|
});
|
|
632
703
|
})
|
|
633
704
|
};
|
|
634
|
-
const perCallByteLimit =
|
|
705
|
+
const perCallByteLimit = Math.min(
|
|
706
|
+
Math.max(1, this.clampFiniteInt(params.outputByteLimit, this.outputByteLimit)),
|
|
707
|
+
this.maxOutputByteLimit
|
|
708
|
+
);
|
|
635
709
|
proc.stdout?.setEncoding("utf8");
|
|
636
710
|
proc.stderr?.setEncoding("utf8");
|
|
637
711
|
const onData = (chunk) => {
|
|
@@ -711,24 +785,57 @@ var TerminalServer = class {
|
|
|
711
785
|
if (resolved !== this.projectRoot && !resolved.startsWith(rootWithSep)) {
|
|
712
786
|
return this.projectRoot;
|
|
713
787
|
}
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
if (env.PATHEXT !== void 0 && env.PATHEXT_CASE === void 0) {
|
|
721
|
-
env.PATHEXT_CASE = env.PATHEXT;
|
|
788
|
+
try {
|
|
789
|
+
const realRoot = realpathSync2(this.projectRoot);
|
|
790
|
+
const realCwd = realpathSync2(resolved);
|
|
791
|
+
const realRootWithSep = realRoot.endsWith(path2.sep) ? realRoot : realRoot + path2.sep;
|
|
792
|
+
if (realCwd !== realRoot && !realCwd.startsWith(realRootWithSep)) {
|
|
793
|
+
return realRoot;
|
|
722
794
|
}
|
|
795
|
+
return realCwd;
|
|
796
|
+
} catch {
|
|
797
|
+
return this.projectRoot;
|
|
723
798
|
}
|
|
799
|
+
}
|
|
800
|
+
buildEnv(agentEnv) {
|
|
801
|
+
const env = buildChildEnv();
|
|
724
802
|
if (agentEnv) {
|
|
725
803
|
for (const { name, value } of agentEnv) {
|
|
804
|
+
const upper = name.toUpperCase();
|
|
805
|
+
if (DENIED_AGENT_ENV_KEYS.has(upper)) continue;
|
|
726
806
|
env[name] = value;
|
|
727
807
|
}
|
|
728
808
|
}
|
|
729
809
|
return env;
|
|
730
810
|
}
|
|
811
|
+
/**
|
|
812
|
+
* Clamp an agent-supplied numeric to a finite positive safe integer, falling
|
|
813
|
+
* back to `defaultValue` for undefined/NaN/non-finite values. Prevents
|
|
814
|
+
* negative, NaN, or Infinity values from disabling output caps or causing
|
|
815
|
+
* unbounded memory growth.
|
|
816
|
+
*/
|
|
817
|
+
clampFiniteInt(value, defaultValue) {
|
|
818
|
+
if (value === void 0 || !Number.isFinite(value) || value < 1) {
|
|
819
|
+
return defaultValue;
|
|
820
|
+
}
|
|
821
|
+
return Math.trunc(value);
|
|
822
|
+
}
|
|
731
823
|
};
|
|
824
|
+
var DENIED_AGENT_ENV_KEYS = /* @__PURE__ */ new Set([
|
|
825
|
+
"NODE_OPTIONS",
|
|
826
|
+
"LD_PRELOAD",
|
|
827
|
+
"LD_LIBRARY_PATH",
|
|
828
|
+
"DYLD_INSERT_LIBRARIES",
|
|
829
|
+
"DYLD_LIBRARY_PATH",
|
|
830
|
+
"DYLD_FALLBACK_LIBRARY_PATH",
|
|
831
|
+
"PATH",
|
|
832
|
+
"PYTHONPATH",
|
|
833
|
+
"PYTHONSTARTUP",
|
|
834
|
+
"PERL5OPT",
|
|
835
|
+
"PERLLIB",
|
|
836
|
+
"RUBYOPT",
|
|
837
|
+
"RUBYLIB"
|
|
838
|
+
]);
|
|
732
839
|
|
|
733
840
|
// src/client/acp-session.ts
|
|
734
841
|
var ACPSessionError = class extends Error {
|
|
@@ -880,7 +987,7 @@ var ACPSession = class _ACPSession {
|
|
|
880
987
|
fs: { readTextFile: true, writeTextFile: true },
|
|
881
988
|
terminal: true
|
|
882
989
|
},
|
|
883
|
-
clientInfo: { name: "wrongstack", title: "WrongStack", version: "0.
|
|
990
|
+
clientInfo: { name: "wrongstack", title: "WrongStack", version: "0.287.0" }
|
|
884
991
|
});
|
|
885
992
|
if (isJsonRpcError(result)) {
|
|
886
993
|
throw new ACPSessionError("init_failed", `initialize failed: ${result.message}`, result);
|
|
@@ -1578,12 +1685,54 @@ var ACPSession = class _ACPSession {
|
|
|
1578
1685
|
return;
|
|
1579
1686
|
}
|
|
1580
1687
|
const policyAbort = new AbortController();
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1688
|
+
try {
|
|
1689
|
+
const outcome = await this.permissionPolicy({
|
|
1690
|
+
toolCall,
|
|
1691
|
+
options,
|
|
1692
|
+
signal: policyAbort.signal
|
|
1693
|
+
});
|
|
1694
|
+
await this.sendResult(id, { outcome });
|
|
1695
|
+
} catch (err) {
|
|
1696
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1697
|
+
await this.sendErrorResponse(id, -32603, `permission policy failed: ${message}`);
|
|
1698
|
+
}
|
|
1699
|
+
}
|
|
1700
|
+
/**
|
|
1701
|
+
* Enforce authorization at privileged callback sinks (fs/write,
|
|
1702
|
+
* terminal/create). Unlike `handlePermissionRequest` which responds to
|
|
1703
|
+
* agent-initiated `session/request_permission` messages, this method is
|
|
1704
|
+
* called by the handler BEFORE dispatching to FileServer/TerminalServer,
|
|
1705
|
+
* closing the gap where the agent simply skips the voluntary permission
|
|
1706
|
+
* request and sends the privileged callback directly.
|
|
1707
|
+
*
|
|
1708
|
+
* Uses the session's permission policy. The default policy
|
|
1709
|
+
* (`defaultPermissionPolicy`) auto-approves everything — this is correct
|
|
1710
|
+
* for trusted local agents (CLI `acp spawn`, Director fan-out). For
|
|
1711
|
+
* untrusted/remote agents, the host should inject
|
|
1712
|
+
* `readOnlyPermissionPolicy` or an interactive policy.
|
|
1713
|
+
*
|
|
1714
|
+
* Returns true if the callback is authorized, false if denied.
|
|
1715
|
+
*/
|
|
1716
|
+
async authorizeCallback(partial) {
|
|
1717
|
+
try {
|
|
1718
|
+
const outcome = await this.permissionPolicy({
|
|
1719
|
+
toolCall: {
|
|
1720
|
+
sessionUpdate: "tool_call_update",
|
|
1721
|
+
toolCallId: partial.toolCallId,
|
|
1722
|
+
title: partial.title,
|
|
1723
|
+
kind: partial.kind,
|
|
1724
|
+
status: "pending"
|
|
1725
|
+
},
|
|
1726
|
+
options: [
|
|
1727
|
+
{ optionId: "allow", name: "Allow", kind: "allow_once" },
|
|
1728
|
+
{ optionId: "reject", name: "Reject", kind: "reject_once" }
|
|
1729
|
+
],
|
|
1730
|
+
signal: new AbortController().signal
|
|
1731
|
+
});
|
|
1732
|
+
return outcome.outcome === "selected" && outcome.optionId !== "reject" && outcome.optionId !== "reject_once" && outcome.optionId !== "reject_always";
|
|
1733
|
+
} catch {
|
|
1734
|
+
return false;
|
|
1735
|
+
}
|
|
1587
1736
|
}
|
|
1588
1737
|
async handleFsRequest(msg) {
|
|
1589
1738
|
const id = msg.id;
|
|
@@ -1593,6 +1742,17 @@ var ACPSession = class _ACPSession {
|
|
|
1593
1742
|
await this.sendErrorResponse(id, -32602, "path is required");
|
|
1594
1743
|
return;
|
|
1595
1744
|
}
|
|
1745
|
+
if (msg.method === "fs/write_text_file") {
|
|
1746
|
+
const allowed = await this.authorizeCallback({
|
|
1747
|
+
toolCallId: `acp-fs-write-${id}`,
|
|
1748
|
+
title: `Write file: ${params.path}`,
|
|
1749
|
+
kind: "edit"
|
|
1750
|
+
});
|
|
1751
|
+
if (!allowed) {
|
|
1752
|
+
await this.sendErrorResponse(id, -32602, "filesystem write denied by permission policy");
|
|
1753
|
+
return;
|
|
1754
|
+
}
|
|
1755
|
+
}
|
|
1596
1756
|
try {
|
|
1597
1757
|
if (msg.method === "fs/read_text_file") {
|
|
1598
1758
|
const result = await this.fileServer.readTextFile({
|
|
@@ -1621,6 +1781,15 @@ var ACPSession = class _ACPSession {
|
|
|
1621
1781
|
try {
|
|
1622
1782
|
switch (msg.method) {
|
|
1623
1783
|
case "terminal/create": {
|
|
1784
|
+
const allowed = await this.authorizeCallback({
|
|
1785
|
+
toolCallId: `acp-terminal-create-${id}`,
|
|
1786
|
+
title: `Run command: ${String(params.command ?? "")} ${(Array.isArray(params.args) ? params.args : []).join(" ")}`.trim(),
|
|
1787
|
+
kind: "execute"
|
|
1788
|
+
});
|
|
1789
|
+
if (!allowed) {
|
|
1790
|
+
await this.sendErrorResponse(id, -32602, "terminal create denied by permission policy");
|
|
1791
|
+
return;
|
|
1792
|
+
}
|
|
1624
1793
|
const createOpts = {
|
|
1625
1794
|
sessionId: String(params.sessionId ?? ""),
|
|
1626
1795
|
command: String(params.command ?? ""),
|
|
@@ -2443,7 +2612,21 @@ var WrongStackACPServer = class {
|
|
|
2443
2612
|
async startHttp(port) {
|
|
2444
2613
|
const host = this.options.host ?? "127.0.0.1";
|
|
2445
2614
|
const handler = this.handler;
|
|
2615
|
+
const authToken = this.options.authToken;
|
|
2616
|
+
let httpChain = Promise.resolve();
|
|
2446
2617
|
this.httpServer = createServer(async (req, res) => {
|
|
2618
|
+
if (authToken) {
|
|
2619
|
+
const url = new URL(req.url ?? "/", `http://${host}:${port}`);
|
|
2620
|
+
const queryToken = url.searchParams.get("token");
|
|
2621
|
+
const authHeader = req.headers["authorization"];
|
|
2622
|
+
const bearerToken = Array.isArray(authHeader) ? authHeader[0]?.replace(/^Bearer\s+/i, "") : authHeader?.replace(/^Bearer\s+/i, "");
|
|
2623
|
+
const supplied = queryToken ?? bearerToken ?? "";
|
|
2624
|
+
if (supplied !== authToken) {
|
|
2625
|
+
res.writeHead(401, { "Content-Type": "application/json" });
|
|
2626
|
+
res.end(JSON.stringify({ error: { code: -32001, message: "Unauthorized" } }));
|
|
2627
|
+
return;
|
|
2628
|
+
}
|
|
2629
|
+
}
|
|
2447
2630
|
const selfOrigin = `http://${host}:${port}`;
|
|
2448
2631
|
const reqOrigin = Array.isArray(req.headers.origin) ? req.headers.origin[0] : req.headers.origin;
|
|
2449
2632
|
if (reqOrigin && reqOrigin !== selfOrigin) {
|
|
@@ -2453,7 +2636,7 @@ var WrongStackACPServer = class {
|
|
|
2453
2636
|
}
|
|
2454
2637
|
if (reqOrigin) res.setHeader("Access-Control-Allow-Origin", reqOrigin);
|
|
2455
2638
|
res.setHeader("Access-Control-Allow-Methods", "POST, OPTIONS");
|
|
2456
|
-
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Mcp-Session-Id");
|
|
2639
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Mcp-Session-Id, Authorization");
|
|
2457
2640
|
if (req.method === "OPTIONS") {
|
|
2458
2641
|
res.writeHead(204);
|
|
2459
2642
|
res.end();
|
|
@@ -2464,10 +2647,23 @@ var WrongStackACPServer = class {
|
|
|
2464
2647
|
res.end(JSON.stringify({ error: "method not allowed" }));
|
|
2465
2648
|
return;
|
|
2466
2649
|
}
|
|
2650
|
+
const MAX_HTTP_BODY = 10 * 1024 * 1024;
|
|
2467
2651
|
let body = "";
|
|
2652
|
+
let bodyBytes = 0;
|
|
2653
|
+
let tooLarge = false;
|
|
2468
2654
|
for await (const chunk of req) {
|
|
2655
|
+
bodyBytes += chunk.length;
|
|
2656
|
+
if (bodyBytes > MAX_HTTP_BODY) {
|
|
2657
|
+
tooLarge = true;
|
|
2658
|
+
break;
|
|
2659
|
+
}
|
|
2469
2660
|
body += chunk;
|
|
2470
2661
|
}
|
|
2662
|
+
if (tooLarge) {
|
|
2663
|
+
res.writeHead(413, { "Content-Type": "application/json" });
|
|
2664
|
+
res.end(JSON.stringify({ error: { code: -32700, message: "Request body too large" } }));
|
|
2665
|
+
return;
|
|
2666
|
+
}
|
|
2471
2667
|
let msg;
|
|
2472
2668
|
try {
|
|
2473
2669
|
msg = JSON.parse(body);
|
|
@@ -2476,26 +2672,43 @@ var WrongStackACPServer = class {
|
|
|
2476
2672
|
res.end(JSON.stringify({ error: { code: -32700, message: "Parse error" } }));
|
|
2477
2673
|
return;
|
|
2478
2674
|
}
|
|
2479
|
-
const
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
response = m;
|
|
2485
|
-
} else if (m.method === "session/update") {
|
|
2486
|
-
notifications.push(m.params);
|
|
2487
|
-
} else {
|
|
2488
|
-
notifications.push(m);
|
|
2675
|
+
const isNotification = typeof msg === "object" && msg !== null && msg.id === void 0 && typeof msg.method === "string";
|
|
2676
|
+
if (isNotification) {
|
|
2677
|
+
try {
|
|
2678
|
+
await handler.handleMessage(msg);
|
|
2679
|
+
} catch {
|
|
2489
2680
|
}
|
|
2490
|
-
|
|
2681
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2682
|
+
res.end(JSON.stringify({ notifications: [] }));
|
|
2683
|
+
return;
|
|
2684
|
+
}
|
|
2685
|
+
const requestPromise = httpChain.then(async () => {
|
|
2686
|
+
const notifications = [];
|
|
2687
|
+
let response = null;
|
|
2688
|
+
const originalSend = this.transport.send.bind(this.transport);
|
|
2689
|
+
this.transport.send = async (m) => {
|
|
2690
|
+
if (m.id !== void 0 && (m.result !== void 0 || m.error !== void 0)) {
|
|
2691
|
+
response = m;
|
|
2692
|
+
} else if (m.method === "session/update") {
|
|
2693
|
+
notifications.push(m.params);
|
|
2694
|
+
} else {
|
|
2695
|
+
notifications.push(m);
|
|
2696
|
+
}
|
|
2697
|
+
};
|
|
2698
|
+
try {
|
|
2699
|
+
await handler.handleMessage(msg);
|
|
2700
|
+
} finally {
|
|
2701
|
+
this.transport.send = originalSend;
|
|
2702
|
+
}
|
|
2703
|
+
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2704
|
+
const responseBody = response !== null ? { ...response, notifications } : { notifications };
|
|
2705
|
+
res.end(JSON.stringify(responseBody));
|
|
2706
|
+
});
|
|
2707
|
+
httpChain = requestPromise.catch(() => void 0);
|
|
2491
2708
|
try {
|
|
2492
|
-
await
|
|
2493
|
-
}
|
|
2494
|
-
this.transport.send = originalSend;
|
|
2709
|
+
await requestPromise;
|
|
2710
|
+
} catch {
|
|
2495
2711
|
}
|
|
2496
|
-
res.writeHead(200, { "Content-Type": "application/json" });
|
|
2497
|
-
const responseBody = response !== null ? { ...response, notifications } : { notifications };
|
|
2498
|
-
res.end(JSON.stringify(responseBody));
|
|
2499
2712
|
});
|
|
2500
2713
|
return new Promise((resolve3) => {
|
|
2501
2714
|
this.httpServer.listen(port, host, () => {
|
|
@@ -3146,6 +3359,28 @@ var AGENTS_CATALOG = [
|
|
|
3146
3359
|
},
|
|
3147
3360
|
integration: "experimental",
|
|
3148
3361
|
docs: "https://cursor.com"
|
|
3362
|
+
},
|
|
3363
|
+
// ── Moonshot AI (Kimi) ─────────────────────────────────────────────
|
|
3364
|
+
{
|
|
3365
|
+
id: "kimi",
|
|
3366
|
+
displayName: "Kimi Code CLI",
|
|
3367
|
+
vendor: "moonshot",
|
|
3368
|
+
probe: { command: "kimi", args: ["--version"] },
|
|
3369
|
+
// Kimi Code CLI speaks ACP behind `kimi acp`. The user must complete
|
|
3370
|
+
// terminal login (`kimi` → `/login`) before launching `kimi acp`;
|
|
3371
|
+
// otherwise session creation fails with `Authentication required`.
|
|
3372
|
+
// The adapter reuses the CLI's existing auth state — WrongStack does
|
|
3373
|
+
// NOT capture or replay the Kimi OAuth tokens.
|
|
3374
|
+
// Docs: https://www.kimi.com/code/docs/en/kimi-code-cli/reference/kimi-acp.html
|
|
3375
|
+
acp: { command: "kimi", args: ["acp"] },
|
|
3376
|
+
supports: {
|
|
3377
|
+
loadSession: true,
|
|
3378
|
+
promptImages: true,
|
|
3379
|
+
terminal: true,
|
|
3380
|
+
fs: true
|
|
3381
|
+
},
|
|
3382
|
+
integration: "native",
|
|
3383
|
+
docs: "https://www.kimi.com/code/docs/en/kimi-code-cli/guides/ides.html"
|
|
3149
3384
|
}
|
|
3150
3385
|
];
|
|
3151
3386
|
function findAgentDescriptor(id) {
|
|
@@ -3362,7 +3597,11 @@ var REGISTRY_ID_ALIASES = {
|
|
|
3362
3597
|
"claude-code": "claude-acp",
|
|
3363
3598
|
"gemini-cli": "gemini",
|
|
3364
3599
|
"codex-cli": "codex-acp",
|
|
3365
|
-
copilot: "github-copilot-cli"
|
|
3600
|
+
copilot: "github-copilot-cli",
|
|
3601
|
+
// Kimi's live registry id is `kimi` — same as our catalog id, so the
|
|
3602
|
+
// alias is identity. Listed explicitly so `resolveAcpAgentCommand`
|
|
3603
|
+
// finds the live entry when the registry is synced.
|
|
3604
|
+
kimi: "kimi"
|
|
3366
3605
|
};
|
|
3367
3606
|
function resolveAcpAgentCommand(id, overrides, live) {
|
|
3368
3607
|
const ov = overrides?.[id];
|