acp-devtools 0.4.0 → 0.6.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/dist/index.js
CHANGED
|
@@ -3755,21 +3755,21 @@ var require_fast_uri = __commonJS({
|
|
|
3755
3755
|
normalizeString(uri, options);
|
|
3756
3756
|
} else if (typeof uri === "object") {
|
|
3757
3757
|
uri = /** @type {T} */
|
|
3758
|
-
|
|
3758
|
+
parse2(serialize(uri, options), options);
|
|
3759
3759
|
}
|
|
3760
3760
|
return uri;
|
|
3761
3761
|
}
|
|
3762
3762
|
function resolve2(baseURI, relativeURI, options) {
|
|
3763
3763
|
const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
|
|
3764
|
-
const resolved = resolveComponent(
|
|
3764
|
+
const resolved = resolveComponent(parse2(baseURI, schemelessOptions), parse2(relativeURI, schemelessOptions), schemelessOptions, true);
|
|
3765
3765
|
schemelessOptions.skipEscape = true;
|
|
3766
3766
|
return serialize(resolved, schemelessOptions);
|
|
3767
3767
|
}
|
|
3768
3768
|
function resolveComponent(base, relative, options, skipNormalization) {
|
|
3769
3769
|
const target = {};
|
|
3770
3770
|
if (!skipNormalization) {
|
|
3771
|
-
base =
|
|
3772
|
-
relative =
|
|
3771
|
+
base = parse2(serialize(base, options), options);
|
|
3772
|
+
relative = parse2(serialize(relative, options), options);
|
|
3773
3773
|
}
|
|
3774
3774
|
options = options || {};
|
|
3775
3775
|
if (!options.tolerant && relative.scheme) {
|
|
@@ -3992,7 +3992,7 @@ var require_fast_uri = __commonJS({
|
|
|
3992
3992
|
}
|
|
3993
3993
|
return { parsed, malformedAuthorityOrPort };
|
|
3994
3994
|
}
|
|
3995
|
-
function
|
|
3995
|
+
function parse2(uri, opts) {
|
|
3996
3996
|
return parseWithStatus(uri, opts).parsed;
|
|
3997
3997
|
}
|
|
3998
3998
|
function normalizeString(uri, opts) {
|
|
@@ -4021,7 +4021,7 @@ var require_fast_uri = __commonJS({
|
|
|
4021
4021
|
resolveComponent,
|
|
4022
4022
|
equal,
|
|
4023
4023
|
serialize,
|
|
4024
|
-
parse
|
|
4024
|
+
parse: parse2
|
|
4025
4025
|
};
|
|
4026
4026
|
module.exports = fastUri;
|
|
4027
4027
|
module.exports.default = fastUri;
|
|
@@ -7278,8 +7278,12 @@ function createAcpValidator(schema3) {
|
|
|
7278
7278
|
const ajv = new Ajv2020({ strict: false, allErrors: true, validateFormats: false });
|
|
7279
7279
|
ajv.addSchema(schema3, SCHEMA_ID);
|
|
7280
7280
|
const methodIndex = /* @__PURE__ */ new Map();
|
|
7281
|
+
const softRequired = /* @__PURE__ */ new Map();
|
|
7281
7282
|
const defs = schema3.$defs ?? {};
|
|
7282
7283
|
for (const [name, def] of Object.entries(defs)) {
|
|
7284
|
+
const soon = Object.entries(def.properties ?? {}).filter(([, prop]) => SOON_REQUIRED_RE.test(prop.description ?? "")).map(([field]) => field);
|
|
7285
|
+
if (soon.length > 0)
|
|
7286
|
+
softRequired.set(name, soon);
|
|
7283
7287
|
const method = def["x-method"];
|
|
7284
7288
|
if (typeof method !== "string")
|
|
7285
7289
|
continue;
|
|
@@ -7332,22 +7336,41 @@ function createAcpValidator(schema3) {
|
|
|
7332
7336
|
}
|
|
7333
7337
|
if (!defName)
|
|
7334
7338
|
return { valid: true, errors: [], skipped: "no-schema-for-kind" };
|
|
7339
|
+
const advisories = collectAdvisories(defName, target);
|
|
7335
7340
|
const validator2 = getValidator(defName);
|
|
7336
7341
|
const ok = validator2(target);
|
|
7337
|
-
|
|
7338
|
-
return { valid: true, errors: [], schemaName: defName };
|
|
7339
|
-
return {
|
|
7342
|
+
const base = ok ? { valid: true, errors: [], schemaName: defName } : {
|
|
7340
7343
|
valid: false,
|
|
7341
7344
|
errors: (validator2.errors ?? []).map(toError),
|
|
7342
7345
|
schemaName: defName
|
|
7343
7346
|
};
|
|
7347
|
+
if (advisories.length > 0)
|
|
7348
|
+
base.advisories = advisories;
|
|
7349
|
+
return base;
|
|
7350
|
+
}
|
|
7351
|
+
function collectAdvisories(defName, target) {
|
|
7352
|
+
const fields = softRequired.get(defName);
|
|
7353
|
+
if (!fields || typeof target !== "object" || target === null)
|
|
7354
|
+
return [];
|
|
7355
|
+
const obj = target;
|
|
7356
|
+
const out = [];
|
|
7357
|
+
for (const field of fields) {
|
|
7358
|
+
if (obj[field] === void 0 || obj[field] === null) {
|
|
7359
|
+
out.push({
|
|
7360
|
+
path: field,
|
|
7361
|
+
message: `missing ${field} \u2014 will be required in a future ACP version`,
|
|
7362
|
+
kind: "soon-required"
|
|
7363
|
+
});
|
|
7364
|
+
}
|
|
7365
|
+
}
|
|
7366
|
+
return out;
|
|
7344
7367
|
}
|
|
7345
7368
|
function knownAcpMethods2() {
|
|
7346
7369
|
return [...methodIndex.keys()].sort();
|
|
7347
7370
|
}
|
|
7348
7371
|
return { validateAcpMessage: validateAcpMessage2, knownAcpMethods: knownAcpMethods2 };
|
|
7349
7372
|
}
|
|
7350
|
-
var import__, ajvModule, Ajv2020, SCHEMA_ID;
|
|
7373
|
+
var import__, ajvModule, Ajv2020, SCHEMA_ID, SOON_REQUIRED_RE;
|
|
7351
7374
|
var init_validate_factory = __esm({
|
|
7352
7375
|
"../core/dist/acp/validate-factory.js"() {
|
|
7353
7376
|
"use strict";
|
|
@@ -7355,6 +7378,7 @@ var init_validate_factory = __esm({
|
|
|
7355
7378
|
ajvModule = import__.default;
|
|
7356
7379
|
Ajv2020 = ajvModule.default ?? ajvModule;
|
|
7357
7380
|
SCHEMA_ID = "acp";
|
|
7381
|
+
SOON_REQUIRED_RE = /will be required/i;
|
|
7358
7382
|
}
|
|
7359
7383
|
});
|
|
7360
7384
|
|
|
@@ -8430,6 +8454,7 @@ function detectAgentShortcut(agentCommand) {
|
|
|
8430
8454
|
const trimmed = agentCommand.trim();
|
|
8431
8455
|
if (trimmed.length === 0)
|
|
8432
8456
|
return null;
|
|
8457
|
+
const candidates = [trimmed, basenameFirstToken(trimmed)];
|
|
8433
8458
|
for (const def of Object.values(AGENT_REGISTRY)) {
|
|
8434
8459
|
const variants = [
|
|
8435
8460
|
[def.command, ...def.args],
|
|
@@ -8437,14 +8462,23 @@ function detectAgentShortcut(agentCommand) {
|
|
|
8437
8462
|
];
|
|
8438
8463
|
for (const variant of variants) {
|
|
8439
8464
|
const exact = variant.join(" ");
|
|
8440
|
-
|
|
8441
|
-
|
|
8442
|
-
|
|
8443
|
-
|
|
8465
|
+
for (const candidate of candidates) {
|
|
8466
|
+
if (candidate === exact)
|
|
8467
|
+
return def;
|
|
8468
|
+
if (candidate.startsWith(exact + " "))
|
|
8469
|
+
return def;
|
|
8470
|
+
}
|
|
8444
8471
|
}
|
|
8445
8472
|
}
|
|
8446
8473
|
return null;
|
|
8447
8474
|
}
|
|
8475
|
+
function basenameFirstToken(command) {
|
|
8476
|
+
const spaceAt = command.indexOf(" ");
|
|
8477
|
+
const head = spaceAt === -1 ? command : command.slice(0, spaceAt);
|
|
8478
|
+
const rest = spaceAt === -1 ? "" : command.slice(spaceAt);
|
|
8479
|
+
const base = head.split(/[/\\]/).pop() ?? head;
|
|
8480
|
+
return base + rest;
|
|
8481
|
+
}
|
|
8448
8482
|
var AGENT_REGISTRY, DEFAULT_AGENT;
|
|
8449
8483
|
var init_registry = __esm({
|
|
8450
8484
|
"../core/dist/agents/registry.js"() {
|
|
@@ -8484,6 +8518,14 @@ var init_registry = __esm({
|
|
|
8484
8518
|
command: "opencode",
|
|
8485
8519
|
args: ["acp"],
|
|
8486
8520
|
requiresExternalInstall: true
|
|
8521
|
+
},
|
|
8522
|
+
junie: {
|
|
8523
|
+
shortName: "junie",
|
|
8524
|
+
displayName: "Junie",
|
|
8525
|
+
description: "JetBrains Junie CLI \u2014 install separately, then this runs `junie --acp=true`",
|
|
8526
|
+
command: "junie",
|
|
8527
|
+
args: ["--acp=true"],
|
|
8528
|
+
requiresExternalInstall: true
|
|
8487
8529
|
}
|
|
8488
8530
|
};
|
|
8489
8531
|
DEFAULT_AGENT = "claude-code";
|
|
@@ -10039,6 +10081,142 @@ var init_dist = __esm({
|
|
|
10039
10081
|
}
|
|
10040
10082
|
});
|
|
10041
10083
|
|
|
10084
|
+
// src/lib/style.ts
|
|
10085
|
+
function colorEnabled(stream = process.stdout, env = process.env) {
|
|
10086
|
+
if (env.FORCE_COLOR === "0" || env.FORCE_COLOR === "false") return false;
|
|
10087
|
+
if (env.FORCE_COLOR !== void 0) return true;
|
|
10088
|
+
if (env.NO_COLOR !== void 0) return false;
|
|
10089
|
+
return Boolean(stream.isTTY);
|
|
10090
|
+
}
|
|
10091
|
+
function paint(enabled, code, s) {
|
|
10092
|
+
if (!enabled) return s;
|
|
10093
|
+
return `${ESC}[${CODES[code]}m${s}${ESC}[${CODES.reset}m`;
|
|
10094
|
+
}
|
|
10095
|
+
function createStyler(enabled = colorEnabled()) {
|
|
10096
|
+
const wrap = (code) => (s) => paint(enabled, code, s);
|
|
10097
|
+
return {
|
|
10098
|
+
enabled,
|
|
10099
|
+
bold: wrap("bold"),
|
|
10100
|
+
dim: wrap("dim"),
|
|
10101
|
+
italic: wrap("italic"),
|
|
10102
|
+
underline: wrap("underline"),
|
|
10103
|
+
red: wrap("red"),
|
|
10104
|
+
green: wrap("green"),
|
|
10105
|
+
yellow: wrap("yellow"),
|
|
10106
|
+
blue: wrap("blue"),
|
|
10107
|
+
magenta: wrap("magenta"),
|
|
10108
|
+
cyan: wrap("cyan"),
|
|
10109
|
+
gray: wrap("gray")
|
|
10110
|
+
};
|
|
10111
|
+
}
|
|
10112
|
+
function stripAnsi(s) {
|
|
10113
|
+
return s.replace(ANSI_PATTERN, "");
|
|
10114
|
+
}
|
|
10115
|
+
function visibleWidth(s) {
|
|
10116
|
+
return stripAnsi(s).length;
|
|
10117
|
+
}
|
|
10118
|
+
var ESC, CODES, ANSI_PATTERN;
|
|
10119
|
+
var init_style = __esm({
|
|
10120
|
+
"src/lib/style.ts"() {
|
|
10121
|
+
"use strict";
|
|
10122
|
+
ESC = String.fromCharCode(27);
|
|
10123
|
+
CODES = {
|
|
10124
|
+
reset: 0,
|
|
10125
|
+
bold: 1,
|
|
10126
|
+
dim: 2,
|
|
10127
|
+
italic: 3,
|
|
10128
|
+
underline: 4,
|
|
10129
|
+
red: 31,
|
|
10130
|
+
green: 32,
|
|
10131
|
+
yellow: 33,
|
|
10132
|
+
blue: 34,
|
|
10133
|
+
magenta: 35,
|
|
10134
|
+
cyan: 36,
|
|
10135
|
+
gray: 90
|
|
10136
|
+
};
|
|
10137
|
+
ANSI_PATTERN = new RegExp(`${ESC}\\[[0-9;]*m`, "g");
|
|
10138
|
+
}
|
|
10139
|
+
});
|
|
10140
|
+
|
|
10141
|
+
// src/lib/table.ts
|
|
10142
|
+
function renderTable(s, columns, rows, opts = {}) {
|
|
10143
|
+
const indent = opts.indent ?? "";
|
|
10144
|
+
const gap = opts.gap ?? " ";
|
|
10145
|
+
const widths = columns.map(
|
|
10146
|
+
(col, c) => Math.max(visibleWidth(col.title), ...rows.map((r) => visibleWidth(r[c] ?? "")))
|
|
10147
|
+
);
|
|
10148
|
+
const pad2 = (text, width, align) => {
|
|
10149
|
+
const fill = " ".repeat(Math.max(0, width - visibleWidth(text)));
|
|
10150
|
+
return align === "right" ? fill + text : text + fill;
|
|
10151
|
+
};
|
|
10152
|
+
const lineFor = (cells, color) => {
|
|
10153
|
+
const rendered = columns.map((col, c) => {
|
|
10154
|
+
const align = col.align ?? "left";
|
|
10155
|
+
const text = cells[c] ?? "";
|
|
10156
|
+
const isLast = c === columns.length - 1;
|
|
10157
|
+
const cell = isLast && align === "left" ? text : pad2(text, widths[c], align);
|
|
10158
|
+
return color(cell);
|
|
10159
|
+
});
|
|
10160
|
+
return indent + rendered.join(gap);
|
|
10161
|
+
};
|
|
10162
|
+
const out = [];
|
|
10163
|
+
out.push(
|
|
10164
|
+
lineFor(
|
|
10165
|
+
columns.map((col) => col.title),
|
|
10166
|
+
(t) => s.dim(t)
|
|
10167
|
+
)
|
|
10168
|
+
);
|
|
10169
|
+
for (const row2 of rows) {
|
|
10170
|
+
out.push(lineFor(row2, (t) => t));
|
|
10171
|
+
}
|
|
10172
|
+
return out.map((l) => l + "\n").join("");
|
|
10173
|
+
}
|
|
10174
|
+
var init_table = __esm({
|
|
10175
|
+
"src/lib/table.ts"() {
|
|
10176
|
+
"use strict";
|
|
10177
|
+
init_style();
|
|
10178
|
+
}
|
|
10179
|
+
});
|
|
10180
|
+
|
|
10181
|
+
// src/commands/agents.ts
|
|
10182
|
+
function registerAgentsCommand(program) {
|
|
10183
|
+
program.command("agents").description("List the built-in agent shortcuts (use with proxy / setup / --agent)").option("--json", "emit machine-readable JSON instead of a table").action((opts) => {
|
|
10184
|
+
const agents = listAgents();
|
|
10185
|
+
if (opts.json) {
|
|
10186
|
+
process.stdout.write(JSON.stringify(agents, null, 2) + "\n");
|
|
10187
|
+
return;
|
|
10188
|
+
}
|
|
10189
|
+
const s = createStyler(colorEnabled(process.stdout));
|
|
10190
|
+
const rows = agents.map((a) => [
|
|
10191
|
+
s.green(a.shortName),
|
|
10192
|
+
a.displayName,
|
|
10193
|
+
[a.command, ...a.args].join(" "),
|
|
10194
|
+
a.requiresExternalInstall ? "install separately" : "auto via npx"
|
|
10195
|
+
]);
|
|
10196
|
+
process.stdout.write(renderTable(s, COLUMNS, rows));
|
|
10197
|
+
process.stdout.write(
|
|
10198
|
+
s.dim(
|
|
10199
|
+
"\nUse a shortcut: acp-devtools <name> \xB7 proxy --agent <name> \xB7 setup <name> --editor <zed|jetbrains>\nAny other ACP agent: acp-devtools setup --editor <ed> -- <command\u2026>\n"
|
|
10200
|
+
)
|
|
10201
|
+
);
|
|
10202
|
+
});
|
|
10203
|
+
}
|
|
10204
|
+
var COLUMNS;
|
|
10205
|
+
var init_agents2 = __esm({
|
|
10206
|
+
"src/commands/agents.ts"() {
|
|
10207
|
+
"use strict";
|
|
10208
|
+
init_dist();
|
|
10209
|
+
init_style();
|
|
10210
|
+
init_table();
|
|
10211
|
+
COLUMNS = [
|
|
10212
|
+
{ title: "SHORTCUT" },
|
|
10213
|
+
{ title: "NAME" },
|
|
10214
|
+
{ title: "RUNS" },
|
|
10215
|
+
{ title: "INSTALL" }
|
|
10216
|
+
];
|
|
10217
|
+
}
|
|
10218
|
+
});
|
|
10219
|
+
|
|
10042
10220
|
// src/commands/backfill-metadata.ts
|
|
10043
10221
|
function backfillSession(db, id) {
|
|
10044
10222
|
let session;
|
|
@@ -10187,63 +10365,6 @@ var init_delete = __esm({
|
|
|
10187
10365
|
}
|
|
10188
10366
|
});
|
|
10189
10367
|
|
|
10190
|
-
// src/lib/style.ts
|
|
10191
|
-
function colorEnabled(stream = process.stdout, env = process.env) {
|
|
10192
|
-
if (env.FORCE_COLOR === "0" || env.FORCE_COLOR === "false") return false;
|
|
10193
|
-
if (env.FORCE_COLOR !== void 0) return true;
|
|
10194
|
-
if (env.NO_COLOR !== void 0) return false;
|
|
10195
|
-
return Boolean(stream.isTTY);
|
|
10196
|
-
}
|
|
10197
|
-
function paint(enabled, code, s) {
|
|
10198
|
-
if (!enabled) return s;
|
|
10199
|
-
return `${ESC}[${CODES[code]}m${s}${ESC}[${CODES.reset}m`;
|
|
10200
|
-
}
|
|
10201
|
-
function createStyler(enabled = colorEnabled()) {
|
|
10202
|
-
const wrap = (code) => (s) => paint(enabled, code, s);
|
|
10203
|
-
return {
|
|
10204
|
-
enabled,
|
|
10205
|
-
bold: wrap("bold"),
|
|
10206
|
-
dim: wrap("dim"),
|
|
10207
|
-
italic: wrap("italic"),
|
|
10208
|
-
underline: wrap("underline"),
|
|
10209
|
-
red: wrap("red"),
|
|
10210
|
-
green: wrap("green"),
|
|
10211
|
-
yellow: wrap("yellow"),
|
|
10212
|
-
blue: wrap("blue"),
|
|
10213
|
-
magenta: wrap("magenta"),
|
|
10214
|
-
cyan: wrap("cyan"),
|
|
10215
|
-
gray: wrap("gray")
|
|
10216
|
-
};
|
|
10217
|
-
}
|
|
10218
|
-
function stripAnsi(s) {
|
|
10219
|
-
return s.replace(ANSI_PATTERN, "");
|
|
10220
|
-
}
|
|
10221
|
-
function visibleWidth(s) {
|
|
10222
|
-
return stripAnsi(s).length;
|
|
10223
|
-
}
|
|
10224
|
-
var ESC, CODES, ANSI_PATTERN;
|
|
10225
|
-
var init_style = __esm({
|
|
10226
|
-
"src/lib/style.ts"() {
|
|
10227
|
-
"use strict";
|
|
10228
|
-
ESC = String.fromCharCode(27);
|
|
10229
|
-
CODES = {
|
|
10230
|
-
reset: 0,
|
|
10231
|
-
bold: 1,
|
|
10232
|
-
dim: 2,
|
|
10233
|
-
italic: 3,
|
|
10234
|
-
underline: 4,
|
|
10235
|
-
red: 31,
|
|
10236
|
-
green: 32,
|
|
10237
|
-
yellow: 33,
|
|
10238
|
-
blue: 34,
|
|
10239
|
-
magenta: 35,
|
|
10240
|
-
cyan: 36,
|
|
10241
|
-
gray: 90
|
|
10242
|
-
};
|
|
10243
|
-
ANSI_PATTERN = new RegExp(`${ESC}\\[[0-9;]*m`, "g");
|
|
10244
|
-
}
|
|
10245
|
-
});
|
|
10246
|
-
|
|
10247
10368
|
// src/lib/palette.ts
|
|
10248
10369
|
function colorKind(s, kind, text) {
|
|
10249
10370
|
switch (kind) {
|
|
@@ -10277,46 +10398,6 @@ var init_palette = __esm({
|
|
|
10277
10398
|
}
|
|
10278
10399
|
});
|
|
10279
10400
|
|
|
10280
|
-
// src/lib/table.ts
|
|
10281
|
-
function renderTable(s, columns, rows, opts = {}) {
|
|
10282
|
-
const indent = opts.indent ?? "";
|
|
10283
|
-
const gap = opts.gap ?? " ";
|
|
10284
|
-
const widths = columns.map(
|
|
10285
|
-
(col, c) => Math.max(visibleWidth(col.title), ...rows.map((r) => visibleWidth(r[c] ?? "")))
|
|
10286
|
-
);
|
|
10287
|
-
const pad2 = (text, width, align) => {
|
|
10288
|
-
const fill = " ".repeat(Math.max(0, width - visibleWidth(text)));
|
|
10289
|
-
return align === "right" ? fill + text : text + fill;
|
|
10290
|
-
};
|
|
10291
|
-
const lineFor = (cells, color) => {
|
|
10292
|
-
const rendered = columns.map((col, c) => {
|
|
10293
|
-
const align = col.align ?? "left";
|
|
10294
|
-
const text = cells[c] ?? "";
|
|
10295
|
-
const isLast = c === columns.length - 1;
|
|
10296
|
-
const cell = isLast && align === "left" ? text : pad2(text, widths[c], align);
|
|
10297
|
-
return color(cell);
|
|
10298
|
-
});
|
|
10299
|
-
return indent + rendered.join(gap);
|
|
10300
|
-
};
|
|
10301
|
-
const out = [];
|
|
10302
|
-
out.push(
|
|
10303
|
-
lineFor(
|
|
10304
|
-
columns.map((col) => col.title),
|
|
10305
|
-
(t) => s.dim(t)
|
|
10306
|
-
)
|
|
10307
|
-
);
|
|
10308
|
-
for (const row2 of rows) {
|
|
10309
|
-
out.push(lineFor(row2, (t) => t));
|
|
10310
|
-
}
|
|
10311
|
-
return out.map((l) => l + "\n").join("");
|
|
10312
|
-
}
|
|
10313
|
-
var init_table = __esm({
|
|
10314
|
-
"src/lib/table.ts"() {
|
|
10315
|
-
"use strict";
|
|
10316
|
-
init_style();
|
|
10317
|
-
}
|
|
10318
|
-
});
|
|
10319
|
-
|
|
10320
10401
|
// src/commands/diff.ts
|
|
10321
10402
|
function registerDiffCommand(program) {
|
|
10322
10403
|
program.command("diff").description(
|
|
@@ -10600,10 +10681,130 @@ var init_diff = __esm({
|
|
|
10600
10681
|
}
|
|
10601
10682
|
});
|
|
10602
10683
|
|
|
10684
|
+
// src/lib/setup-config.ts
|
|
10685
|
+
import { homedir as homedir3, platform } from "os";
|
|
10686
|
+
import { join as join3 } from "path";
|
|
10687
|
+
import { applyEdits, modify, parse } from "jsonc-parser";
|
|
10688
|
+
function isEditor(value) {
|
|
10689
|
+
return EDITORS.includes(value);
|
|
10690
|
+
}
|
|
10691
|
+
function zedSettingsPath() {
|
|
10692
|
+
if (platform() === "win32") {
|
|
10693
|
+
return join3(process.env.APPDATA ?? "", "Zed", "settings.json");
|
|
10694
|
+
}
|
|
10695
|
+
if (platform() === "darwin") {
|
|
10696
|
+
return join3(homedir3(), ".config", "zed", "settings.json");
|
|
10697
|
+
}
|
|
10698
|
+
return join3(process.env.XDG_CONFIG_HOME ?? join3(homedir3(), ".config"), "zed", "settings.json");
|
|
10699
|
+
}
|
|
10700
|
+
function jetbrainsConfigPath() {
|
|
10701
|
+
return join3(homedir3(), ".jetbrains", "acp.json");
|
|
10702
|
+
}
|
|
10703
|
+
function editorInfo(editor) {
|
|
10704
|
+
if (editor === "zed") {
|
|
10705
|
+
return {
|
|
10706
|
+
id: "zed",
|
|
10707
|
+
label: "Zed",
|
|
10708
|
+
configPath: zedSettingsPath(),
|
|
10709
|
+
placement: "add the agent_servers block to Zed\u2019s settings.json (create the file or the key if missing)",
|
|
10710
|
+
restart: "reopen the agent panel so Zed re-reads the config",
|
|
10711
|
+
dedicatedFile: false
|
|
10712
|
+
};
|
|
10713
|
+
}
|
|
10714
|
+
return {
|
|
10715
|
+
id: "jetbrains",
|
|
10716
|
+
label: "JetBrains",
|
|
10717
|
+
configPath: jetbrainsConfigPath(),
|
|
10718
|
+
placement: "write this to the global JetBrains ACP config (create it if missing \u2014 every JetBrains IDE shares this one file)",
|
|
10719
|
+
restart: "restart the AI chat tool window (close and reopen it)",
|
|
10720
|
+
dedicatedFile: true
|
|
10721
|
+
};
|
|
10722
|
+
}
|
|
10723
|
+
function deriveCustomName(target) {
|
|
10724
|
+
const first = target[0] ?? "agent";
|
|
10725
|
+
if (first === "npx") {
|
|
10726
|
+
for (let i = 1; i < target.length; i++) {
|
|
10727
|
+
const token = target[i];
|
|
10728
|
+
if (!token.startsWith("-")) return token;
|
|
10729
|
+
}
|
|
10730
|
+
}
|
|
10731
|
+
return first.split(/[/\\]/).pop() || first;
|
|
10732
|
+
}
|
|
10733
|
+
function buildSetupPlan(input) {
|
|
10734
|
+
const target = input.target.length > 0 ? [...input.target] : [DEFAULT_AGENT];
|
|
10735
|
+
const single = target.length === 1 ? target[0] : null;
|
|
10736
|
+
let args;
|
|
10737
|
+
let displayName;
|
|
10738
|
+
let isCustom;
|
|
10739
|
+
let agentDescription;
|
|
10740
|
+
let requiresExternalInstall = false;
|
|
10741
|
+
if (single !== null && isAgentShortcut(single)) {
|
|
10742
|
+
const def = resolveAgent(single);
|
|
10743
|
+
args = [def.shortName];
|
|
10744
|
+
displayName = input.name ?? `${def.displayName} (via ACP Devtools)`;
|
|
10745
|
+
isCustom = false;
|
|
10746
|
+
agentDescription = def.description;
|
|
10747
|
+
requiresExternalInstall = def.requiresExternalInstall ?? false;
|
|
10748
|
+
} else {
|
|
10749
|
+
args = ["proxy", ...target];
|
|
10750
|
+
displayName = input.name ?? `${deriveCustomName(target)} (via ACP Devtools)`;
|
|
10751
|
+
isCustom = true;
|
|
10752
|
+
}
|
|
10753
|
+
return {
|
|
10754
|
+
editor: editorInfo(input.editor),
|
|
10755
|
+
displayName,
|
|
10756
|
+
entry: { type: "custom", command: input.selfPath, args },
|
|
10757
|
+
isCustom,
|
|
10758
|
+
agentDescription,
|
|
10759
|
+
requiresExternalInstall
|
|
10760
|
+
};
|
|
10761
|
+
}
|
|
10762
|
+
function renderConfigBlock(plan) {
|
|
10763
|
+
const entries = { [plan.displayName]: plan.entry };
|
|
10764
|
+
if (plan.editor.dedicatedFile) {
|
|
10765
|
+
return JSON.stringify({ agent_servers: entries }, null, 4);
|
|
10766
|
+
}
|
|
10767
|
+
return `"agent_servers": ${JSON.stringify(entries, null, 4)}`;
|
|
10768
|
+
}
|
|
10769
|
+
function detectFormatting(text) {
|
|
10770
|
+
const match = text.match(/\n([ \t]+)\S/);
|
|
10771
|
+
if (!match) return { insertSpaces: true, tabSize: 4 };
|
|
10772
|
+
const ws = match[1];
|
|
10773
|
+
if (ws.startsWith(" ")) return { insertSpaces: false, tabSize: 1 };
|
|
10774
|
+
return { insertSpaces: true, tabSize: ws.length };
|
|
10775
|
+
}
|
|
10776
|
+
function mergeIntoConfig(existing, name, entry) {
|
|
10777
|
+
const base = existing !== null && existing.trim().length > 0 ? existing : "{}";
|
|
10778
|
+
const errors = [];
|
|
10779
|
+
const root = parse(base, errors, { allowTrailingComma: true });
|
|
10780
|
+
if (errors.length > 0) {
|
|
10781
|
+
throw new Error("config is not valid JSON");
|
|
10782
|
+
}
|
|
10783
|
+
if (typeof root !== "object" || root === null || Array.isArray(root)) {
|
|
10784
|
+
throw new Error("config root is not a JSON object");
|
|
10785
|
+
}
|
|
10786
|
+
const servers = root.agent_servers;
|
|
10787
|
+
const replaced = typeof servers === "object" && servers !== null && !Array.isArray(servers) ? Object.prototype.hasOwnProperty.call(servers, name) : false;
|
|
10788
|
+
const edits = modify(base, ["agent_servers", name], entry, {
|
|
10789
|
+
formattingOptions: detectFormatting(base)
|
|
10790
|
+
});
|
|
10791
|
+
let text = applyEdits(base, edits);
|
|
10792
|
+
if (!text.endsWith("\n")) text += "\n";
|
|
10793
|
+
return { text, replaced };
|
|
10794
|
+
}
|
|
10795
|
+
var EDITORS;
|
|
10796
|
+
var init_setup_config = __esm({
|
|
10797
|
+
"src/lib/setup-config.ts"() {
|
|
10798
|
+
"use strict";
|
|
10799
|
+
init_dist();
|
|
10800
|
+
EDITORS = ["zed", "jetbrains"];
|
|
10801
|
+
}
|
|
10802
|
+
});
|
|
10803
|
+
|
|
10603
10804
|
// src/commands/doctor.ts
|
|
10604
10805
|
import { existsSync as existsSync6, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
10605
|
-
import { homedir as
|
|
10606
|
-
import { join as
|
|
10806
|
+
import { homedir as homedir4, platform as platform2, release } from "os";
|
|
10807
|
+
import { join as join4 } from "path";
|
|
10607
10808
|
function colorStatus(s, status, text) {
|
|
10608
10809
|
switch (status) {
|
|
10609
10810
|
case "ok":
|
|
@@ -10626,7 +10827,7 @@ function checkEnvironment() {
|
|
|
10626
10827
|
});
|
|
10627
10828
|
results.push({
|
|
10628
10829
|
status: "info",
|
|
10629
|
-
label: `Platform: ${
|
|
10830
|
+
label: `Platform: ${platform2()} ${process.arch} (${release()})`
|
|
10630
10831
|
});
|
|
10631
10832
|
const binary = process.argv[1] ?? "(unknown)";
|
|
10632
10833
|
results.push({
|
|
@@ -10710,21 +10911,17 @@ function checkState() {
|
|
|
10710
10911
|
return results;
|
|
10711
10912
|
}
|
|
10712
10913
|
function probeZed() {
|
|
10713
|
-
const path =
|
|
10714
|
-
process.env.XDG_CONFIG_HOME ?? join3(homedir3(), ".config"),
|
|
10715
|
-
"zed",
|
|
10716
|
-
"settings.json"
|
|
10717
|
-
);
|
|
10914
|
+
const path = zedSettingsPath();
|
|
10718
10915
|
return { name: "Zed", path, exists: existsSync6(path) };
|
|
10719
10916
|
}
|
|
10720
10917
|
function probeJetBrains() {
|
|
10721
10918
|
const baseDirs = [];
|
|
10722
|
-
if (
|
|
10723
|
-
baseDirs.push(
|
|
10724
|
-
} else if (
|
|
10725
|
-
baseDirs.push(
|
|
10919
|
+
if (platform2() === "darwin") {
|
|
10920
|
+
baseDirs.push(join4(homedir4(), "Library", "Application Support", "JetBrains"));
|
|
10921
|
+
} else if (platform2() === "win32") {
|
|
10922
|
+
baseDirs.push(join4(process.env.APPDATA ?? "", "JetBrains"));
|
|
10726
10923
|
} else {
|
|
10727
|
-
baseDirs.push(
|
|
10924
|
+
baseDirs.push(join4(homedir4(), ".config", "JetBrains"));
|
|
10728
10925
|
}
|
|
10729
10926
|
const probes = [];
|
|
10730
10927
|
for (const base of baseDirs) {
|
|
@@ -10738,7 +10935,7 @@ function probeJetBrains() {
|
|
|
10738
10935
|
for (const entry of entries) {
|
|
10739
10936
|
if (entry.startsWith(".")) continue;
|
|
10740
10937
|
if (!JETBRAINS_VERSIONED.test(entry) && !JETBRAINS_UNVERSIONED.has(entry)) continue;
|
|
10741
|
-
const full =
|
|
10938
|
+
const full = join4(base, entry);
|
|
10742
10939
|
try {
|
|
10743
10940
|
if (!statSync2(full).isDirectory()) continue;
|
|
10744
10941
|
} catch {
|
|
@@ -10837,6 +11034,7 @@ var init_doctor = __esm({
|
|
|
10837
11034
|
"use strict";
|
|
10838
11035
|
init_dist();
|
|
10839
11036
|
init_style();
|
|
11037
|
+
init_setup_config();
|
|
10840
11038
|
STATUS_MARK = {
|
|
10841
11039
|
ok: "\u2713",
|
|
10842
11040
|
warn: "!",
|
|
@@ -10853,7 +11051,7 @@ var CLI_VERSION;
|
|
|
10853
11051
|
var init_version = __esm({
|
|
10854
11052
|
"src/version.ts"() {
|
|
10855
11053
|
"use strict";
|
|
10856
|
-
CLI_VERSION = "0.
|
|
11054
|
+
CLI_VERSION = "0.6.0";
|
|
10857
11055
|
}
|
|
10858
11056
|
});
|
|
10859
11057
|
|
|
@@ -11322,9 +11520,9 @@ function formatTable(rows) {
|
|
|
11322
11520
|
labelOf(r)
|
|
11323
11521
|
];
|
|
11324
11522
|
});
|
|
11325
|
-
return renderTable(s,
|
|
11523
|
+
return renderTable(s, COLUMNS2, body);
|
|
11326
11524
|
}
|
|
11327
|
-
var
|
|
11525
|
+
var COLUMNS2;
|
|
11328
11526
|
var init_list = __esm({
|
|
11329
11527
|
"src/commands/list.ts"() {
|
|
11330
11528
|
"use strict";
|
|
@@ -11332,7 +11530,7 @@ var init_list = __esm({
|
|
|
11332
11530
|
init_style();
|
|
11333
11531
|
init_palette();
|
|
11334
11532
|
init_table();
|
|
11335
|
-
|
|
11533
|
+
COLUMNS2 = [
|
|
11336
11534
|
{ title: "ID", align: "left" },
|
|
11337
11535
|
{ title: "AGE", align: "right" },
|
|
11338
11536
|
{ title: "KIND", align: "left" },
|
|
@@ -11589,7 +11787,9 @@ function buildMcpServer(opts) {
|
|
|
11589
11787
|
description: "Fetch a single captured frame by (session_id, seq). Returns the full record: raw JSON bytes, parsed payload, parseError (if any), direction, kind, method, rpcId, timestamp. Use this after find_spec_violations / get_session_messages narrows you down to a specific seq.",
|
|
11590
11788
|
inputSchema: {
|
|
11591
11789
|
session_id: z.number().int().positive().describe("session id from list_sessions"),
|
|
11592
|
-
seq: z.number().int().positive().describe(
|
|
11790
|
+
seq: z.number().int().positive().describe(
|
|
11791
|
+
"per-session sequence number from list_session_messages or find_spec_violations"
|
|
11792
|
+
)
|
|
11593
11793
|
},
|
|
11594
11794
|
outputSchema: {
|
|
11595
11795
|
session_id: z.number(),
|
|
@@ -11668,7 +11868,7 @@ function buildMcpServer(opts) {
|
|
|
11668
11868
|
server.registerTool(
|
|
11669
11869
|
"find_spec_violations",
|
|
11670
11870
|
{
|
|
11671
|
-
description: "Validate every captured frame in a session against the ACP JSON schema (Draft 2020-12, ajv-compiled). Returns every offender with its seq, method, and per-error path + keyword + message. Schema-skipped frames (unknown methods, parse errors, generic envelopes) are not counted. Use the returned seq with get_message to inspect the offending raw payload. Start here when an agent is misbehaving but you don't yet know how.",
|
|
11871
|
+
description: "Validate every captured frame in a session against the ACP JSON schema (Draft 2020-12, ajv-compiled). Returns every offender with its seq, method, and per-error path + keyword + message. Schema-skipped frames (unknown methods, parse errors, generic envelopes) are not counted. Also returns `advisories`: frames valid under today's schema that omit a field the spec says will become mandatory (e.g. `agentInfo` on an initialize response, `clientInfo` on the request) \u2014 these never count as violations. Use the returned seq with get_message to inspect the offending raw payload. Start here when an agent is misbehaving but you don't yet know how.",
|
|
11672
11872
|
inputSchema: {
|
|
11673
11873
|
session_id: z.number().int().positive().describe("session id from list_sessions")
|
|
11674
11874
|
},
|
|
@@ -11683,13 +11883,23 @@ function buildMcpServer(opts) {
|
|
|
11683
11883
|
z.object({
|
|
11684
11884
|
seq: z.number(),
|
|
11685
11885
|
method: z.string().nullable(),
|
|
11686
|
-
errors: z.array(
|
|
11687
|
-
|
|
11688
|
-
|
|
11689
|
-
|
|
11690
|
-
|
|
11691
|
-
|
|
11886
|
+
errors: z.array(
|
|
11887
|
+
z.looseObject({
|
|
11888
|
+
keyword: z.string(),
|
|
11889
|
+
instancePath: z.string().optional(),
|
|
11890
|
+
schemaPath: z.string().optional(),
|
|
11891
|
+
message: z.string().optional()
|
|
11892
|
+
})
|
|
11893
|
+
)
|
|
11692
11894
|
}).loose()
|
|
11895
|
+
),
|
|
11896
|
+
advisories: z.array(
|
|
11897
|
+
z.object({
|
|
11898
|
+
seq: z.number(),
|
|
11899
|
+
method: z.string().nullable(),
|
|
11900
|
+
path: z.string(),
|
|
11901
|
+
message: z.string()
|
|
11902
|
+
})
|
|
11693
11903
|
)
|
|
11694
11904
|
},
|
|
11695
11905
|
annotations: annotations({ title: "Validate session against ACP schema" })
|
|
@@ -11700,6 +11910,7 @@ function buildMcpServer(opts) {
|
|
|
11700
11910
|
const seqToMethod = /* @__PURE__ */ new Map();
|
|
11701
11911
|
for (const m of messages) if (m.method) seqToMethod.set(m.seq, m.method);
|
|
11702
11912
|
const violations = [];
|
|
11913
|
+
const advisories = [];
|
|
11703
11914
|
let checked = 0;
|
|
11704
11915
|
for (const m of messages) {
|
|
11705
11916
|
const pair = pairs.get(m.seq);
|
|
@@ -11709,15 +11920,15 @@ function buildMcpServer(opts) {
|
|
|
11709
11920
|
const result = validateAcpMessage(m, validationOpts);
|
|
11710
11921
|
if (result.skipped) continue;
|
|
11711
11922
|
checked += 1;
|
|
11923
|
+
const method = m.method ?? pairedMethod ?? null;
|
|
11712
11924
|
if (!result.valid) {
|
|
11713
|
-
violations.push({
|
|
11714
|
-
|
|
11715
|
-
|
|
11716
|
-
|
|
11717
|
-
});
|
|
11925
|
+
violations.push({ seq: m.seq, method, errors: result.errors });
|
|
11926
|
+
}
|
|
11927
|
+
for (const a of result.advisories ?? []) {
|
|
11928
|
+
advisories.push({ seq: m.seq, method, path: a.path, message: a.message });
|
|
11718
11929
|
}
|
|
11719
11930
|
}
|
|
11720
|
-
return structuredResult({ session_id, checked, violations });
|
|
11931
|
+
return structuredResult({ session_id, checked, violations, advisories });
|
|
11721
11932
|
}
|
|
11722
11933
|
);
|
|
11723
11934
|
server.registerTool(
|
|
@@ -11808,6 +12019,88 @@ function buildMcpServer(opts) {
|
|
|
11808
12019
|
});
|
|
11809
12020
|
}
|
|
11810
12021
|
);
|
|
12022
|
+
server.registerTool(
|
|
12023
|
+
"list_agent_shortcuts",
|
|
12024
|
+
{
|
|
12025
|
+
description: "List the built-in agent shortcuts you can pass to generate_editor_config as `agent` (or that the CLI accepts as `acp-devtools <name>` / `proxy --agent <name>`). Each is a known ACP agent wired into the registry; anything else is still supported via generate_editor_config's `command` argument. Same data as the CLI `acp-devtools agents`.",
|
|
12026
|
+
inputSchema: {},
|
|
12027
|
+
outputSchema: {
|
|
12028
|
+
agents: z.array(
|
|
12029
|
+
z.object({
|
|
12030
|
+
shortName: z.string(),
|
|
12031
|
+
displayName: z.string(),
|
|
12032
|
+
command: z.string(),
|
|
12033
|
+
args: z.array(z.string()),
|
|
12034
|
+
requiresExternalInstall: z.boolean()
|
|
12035
|
+
})
|
|
12036
|
+
)
|
|
12037
|
+
},
|
|
12038
|
+
annotations: annotations({ title: "List agent shortcuts" })
|
|
12039
|
+
},
|
|
12040
|
+
async () => {
|
|
12041
|
+
const agents = listAgents().map((a) => ({
|
|
12042
|
+
shortName: a.shortName,
|
|
12043
|
+
displayName: a.displayName,
|
|
12044
|
+
command: a.command,
|
|
12045
|
+
args: [...a.args],
|
|
12046
|
+
requiresExternalInstall: a.requiresExternalInstall ?? false
|
|
12047
|
+
}));
|
|
12048
|
+
return structuredResult({ agents });
|
|
12049
|
+
}
|
|
12050
|
+
);
|
|
12051
|
+
server.registerTool(
|
|
12052
|
+
"generate_editor_config",
|
|
12053
|
+
{
|
|
12054
|
+
description: 'Generate the editor config (Zed or JetBrains) that runs an ACP agent through ACP Devtools, with the absolute acp-devtools binary path already filled in. Use this when the user asks to wire up / add an agent \u2014 e.g. "add junie for zed". Returns `block` (the JSON to add to the editor config), `configPath` (where it goes), and `writeCommand` (the equivalent `acp-devtools setup --write` to run instead). This tool only COMPUTES the config \u2014 it does not write any file; add `block` to `configPath` with your own file tools, or tell the user to run `writeCommand`. Pass `agent` for a registry shortcut (see list_agent_shortcuts) or `command` for any other agent (wrapped via `proxy`). Mirrors the CLI `acp-devtools setup`.',
|
|
12055
|
+
inputSchema: {
|
|
12056
|
+
editor: z.enum(["zed", "jetbrains"]).describe("target editor: zed or jetbrains"),
|
|
12057
|
+
agent: z.string().optional().describe(
|
|
12058
|
+
"registry shortcut: junie, goose, codex, opencode, or claude-code (the default when neither agent nor command is given)"
|
|
12059
|
+
),
|
|
12060
|
+
command: z.array(z.string()).optional().describe(
|
|
12061
|
+
'custom agent command tokens (e.g. ["npx","-y","@scope/acp"]), wrapped via proxy; ignored when `agent` is set'
|
|
12062
|
+
),
|
|
12063
|
+
name: z.string().optional().describe("display name override for the agent entry")
|
|
12064
|
+
},
|
|
12065
|
+
outputSchema: {
|
|
12066
|
+
displayName: z.string(),
|
|
12067
|
+
editor: z.enum(["zed", "jetbrains"]),
|
|
12068
|
+
configPath: z.string(),
|
|
12069
|
+
dedicatedFile: z.boolean(),
|
|
12070
|
+
entry: z.object({
|
|
12071
|
+
type: z.literal("custom"),
|
|
12072
|
+
command: z.string(),
|
|
12073
|
+
args: z.array(z.string())
|
|
12074
|
+
}),
|
|
12075
|
+
block: z.string(),
|
|
12076
|
+
writeCommand: z.string(),
|
|
12077
|
+
requiresExternalInstall: z.boolean(),
|
|
12078
|
+
installHint: z.string().optional()
|
|
12079
|
+
},
|
|
12080
|
+
annotations: annotations({ title: "Generate editor config" })
|
|
12081
|
+
},
|
|
12082
|
+
async ({ editor, agent, command, name }) => {
|
|
12083
|
+
const target = command && command.length > 0 ? command : agent ? [agent] : [];
|
|
12084
|
+
const selfPath = process.argv[1] ?? "acp-devtools";
|
|
12085
|
+
const plan = buildSetupPlan({ target, editor, selfPath, name });
|
|
12086
|
+
const writeParts = ["acp-devtools setup", `--editor ${editor}`, "--write"];
|
|
12087
|
+
if (name) writeParts.push(`--name ${JSON.stringify(name)}`);
|
|
12088
|
+
if (target.length === 1) writeParts.push(target[0]);
|
|
12089
|
+
else if (target.length > 1) writeParts.push("--", ...target);
|
|
12090
|
+
const installHint = plan.isCustom ? void 0 : plan.requiresExternalInstall ? plan.agentDescription : "Installs automatically via npx on first run.";
|
|
12091
|
+
return structuredResult({
|
|
12092
|
+
displayName: plan.displayName,
|
|
12093
|
+
editor,
|
|
12094
|
+
configPath: plan.editor.configPath,
|
|
12095
|
+
dedicatedFile: plan.editor.dedicatedFile,
|
|
12096
|
+
entry: plan.entry,
|
|
12097
|
+
block: renderConfigBlock(plan),
|
|
12098
|
+
writeCommand: writeParts.join(" "),
|
|
12099
|
+
requiresExternalInstall: plan.requiresExternalInstall,
|
|
12100
|
+
...installHint !== void 0 ? { installHint } : {}
|
|
12101
|
+
});
|
|
12102
|
+
}
|
|
12103
|
+
);
|
|
11811
12104
|
registerPrompts(server);
|
|
11812
12105
|
return server;
|
|
11813
12106
|
}
|
|
@@ -11931,12 +12224,14 @@ var init_mcp = __esm({
|
|
|
11931
12224
|
"use strict";
|
|
11932
12225
|
init_dist();
|
|
11933
12226
|
init_version();
|
|
12227
|
+
init_setup_config();
|
|
11934
12228
|
SERVER_INSTRUCTIONS = `acp-devtools exposes a local SQLite store of captured
|
|
11935
12229
|
Agent Client Protocol (ACP) sessions. ACP is the editor\u2194agent JSON-RPC
|
|
11936
12230
|
protocol used by Claude Code, Goose, Codex, and other IDE agents.
|
|
11937
12231
|
|
|
11938
12232
|
Every tool here is **read-only** \u2014 nothing in this server writes to the
|
|
11939
|
-
database
|
|
12233
|
+
database or to any file (\`generate_editor_config\` only returns the config
|
|
12234
|
+
text to write; you apply it). Use it to investigate:
|
|
11940
12235
|
|
|
11941
12236
|
- a slow session (\`get_latency_stats\` returns per-method p50/p99/max
|
|
11942
12237
|
plus auto-detected insights: hotspot, long-tail, outlier, busiest,
|
|
@@ -11953,6 +12248,12 @@ database. Use it to investigate:
|
|
|
11953
12248
|
(\`diff_sessions\` aligns two captures and reports added / removed
|
|
11954
12249
|
frames and field-level payload changes)
|
|
11955
12250
|
|
|
12251
|
+
It also helps wire agents up: \`list_agent_shortcuts\` enumerates the known
|
|
12252
|
+
agents, and \`generate_editor_config({editor, agent})\` returns the
|
|
12253
|
+
Zed/JetBrains config block to run one through the proxy (e.g. "add junie for
|
|
12254
|
+
zed") \u2014 apply \`block\` to \`configPath\` with your own file tools, or run the
|
|
12255
|
+
returned \`writeCommand\`.
|
|
12256
|
+
|
|
11956
12257
|
A typical investigation:
|
|
11957
12258
|
1. \`list_sessions\` to see what is captured
|
|
11958
12259
|
2. \`get_session_summary({session_id})\` for the headline numbers and
|
|
@@ -12888,7 +13189,7 @@ function renderHits(s, hits, needle) {
|
|
|
12888
13189
|
truncate2(h.method ?? "\u2014", METHOD_MAX2),
|
|
12889
13190
|
highlight(s, h.snippet, needle)
|
|
12890
13191
|
]);
|
|
12891
|
-
return renderTable(s,
|
|
13192
|
+
return renderTable(s, COLUMNS3, body);
|
|
12892
13193
|
}
|
|
12893
13194
|
function highlight(s, snippet, needle) {
|
|
12894
13195
|
if (!s.enabled || needle.length === 0) return snippet;
|
|
@@ -12910,7 +13211,7 @@ function truncate2(s, max) {
|
|
|
12910
13211
|
if (s.length <= max) return s;
|
|
12911
13212
|
return s.slice(0, Math.max(1, max - 1)) + "\u2026";
|
|
12912
13213
|
}
|
|
12913
|
-
var SNIPPET_LEN, METHOD_MAX2,
|
|
13214
|
+
var SNIPPET_LEN, METHOD_MAX2, COLUMNS3;
|
|
12914
13215
|
var init_search = __esm({
|
|
12915
13216
|
"src/commands/search.ts"() {
|
|
12916
13217
|
"use strict";
|
|
@@ -12919,7 +13220,7 @@ var init_search = __esm({
|
|
|
12919
13220
|
init_table();
|
|
12920
13221
|
SNIPPET_LEN = 80;
|
|
12921
13222
|
METHOD_MAX2 = 32;
|
|
12922
|
-
|
|
13223
|
+
COLUMNS3 = [
|
|
12923
13224
|
{ title: "LOC", align: "left" },
|
|
12924
13225
|
{ title: "METHOD", align: "left" },
|
|
12925
13226
|
{ title: "MATCH", align: "left" }
|
|
@@ -13107,6 +13408,139 @@ var init_session_info = __esm({
|
|
|
13107
13408
|
}
|
|
13108
13409
|
});
|
|
13109
13410
|
|
|
13411
|
+
// src/commands/setup.ts
|
|
13412
|
+
import { mkdirSync as mkdirSync6, readFileSync as readFileSync5, writeFileSync as writeFileSync3 } from "fs";
|
|
13413
|
+
import { dirname as dirname5 } from "path";
|
|
13414
|
+
function fail(message, code) {
|
|
13415
|
+
process.stderr.write(`acp-devtools: ${message}
|
|
13416
|
+
`);
|
|
13417
|
+
process.exit(code);
|
|
13418
|
+
}
|
|
13419
|
+
function rerunCommand(editor, target, opts) {
|
|
13420
|
+
const parts = ["acp-devtools setup", `--editor ${editor}`, "--write"];
|
|
13421
|
+
if (opts.name) parts.push(`--name ${JSON.stringify(opts.name)}`);
|
|
13422
|
+
if (opts.configPath) parts.push(`--config-path ${opts.configPath}`);
|
|
13423
|
+
if (target.length === 1) {
|
|
13424
|
+
parts.push(target[0]);
|
|
13425
|
+
} else if (target.length > 1) {
|
|
13426
|
+
parts.push("--", ...target);
|
|
13427
|
+
}
|
|
13428
|
+
return parts.join(" ");
|
|
13429
|
+
}
|
|
13430
|
+
function printInstallHint(plan, s) {
|
|
13431
|
+
if (plan.isCustom) return;
|
|
13432
|
+
if (plan.requiresExternalInstall) {
|
|
13433
|
+
process.stdout.write(`
|
|
13434
|
+
${s.yellow("!")} ${plan.agentDescription}
|
|
13435
|
+
`);
|
|
13436
|
+
} else {
|
|
13437
|
+
process.stdout.write(`
|
|
13438
|
+
${s.dim("Installs automatically via npx on first run.")}
|
|
13439
|
+
`);
|
|
13440
|
+
}
|
|
13441
|
+
}
|
|
13442
|
+
function printGuidance(plan, target, opts, configPath, s) {
|
|
13443
|
+
const block = renderConfigBlock(plan);
|
|
13444
|
+
process.stdout.write(
|
|
13445
|
+
`
|
|
13446
|
+
${s.bold(plan.displayName)} ${s.dim("\u2192")} ${s.bold(plan.editor.label)}
|
|
13447
|
+
|
|
13448
|
+
`
|
|
13449
|
+
);
|
|
13450
|
+
process.stdout.write(` ${plan.editor.placement}:
|
|
13451
|
+
`);
|
|
13452
|
+
process.stdout.write(` ${s.cyan(configPath)}
|
|
13453
|
+
|
|
13454
|
+
`);
|
|
13455
|
+
process.stdout.write(`${block}
|
|
13456
|
+
`);
|
|
13457
|
+
printInstallHint(plan, s);
|
|
13458
|
+
process.stdout.write(`
|
|
13459
|
+
Then ${plan.editor.restart}.
|
|
13460
|
+
`);
|
|
13461
|
+
process.stdout.write(
|
|
13462
|
+
`
|
|
13463
|
+
${s.dim("Or let ACP Devtools edit the file for you:")}
|
|
13464
|
+
${rerunCommand(opts.editor, target, opts)}
|
|
13465
|
+
|
|
13466
|
+
`
|
|
13467
|
+
);
|
|
13468
|
+
}
|
|
13469
|
+
function doWrite(plan, target, opts, configPath, s) {
|
|
13470
|
+
let existing = null;
|
|
13471
|
+
try {
|
|
13472
|
+
existing = readFileSync5(configPath, "utf8");
|
|
13473
|
+
} catch (err) {
|
|
13474
|
+
if (err.code !== "ENOENT") {
|
|
13475
|
+
fail(`cannot read ${configPath}: ${err.message}`, 1);
|
|
13476
|
+
}
|
|
13477
|
+
}
|
|
13478
|
+
let merged;
|
|
13479
|
+
try {
|
|
13480
|
+
merged = mergeIntoConfig(existing, plan.displayName, plan.entry);
|
|
13481
|
+
} catch {
|
|
13482
|
+
process.stderr.write(
|
|
13483
|
+
`${s.red("\u2717")} ${configPath} isn't valid JSON \u2014 leaving it untouched.
|
|
13484
|
+
Paste this block in by hand:
|
|
13485
|
+
`
|
|
13486
|
+
);
|
|
13487
|
+
process.stdout.write(`
|
|
13488
|
+
${renderConfigBlock(plan)}
|
|
13489
|
+
|
|
13490
|
+
`);
|
|
13491
|
+
process.exit(1);
|
|
13492
|
+
}
|
|
13493
|
+
try {
|
|
13494
|
+
mkdirSync6(dirname5(configPath), { recursive: true });
|
|
13495
|
+
writeFileSync3(configPath, merged.text);
|
|
13496
|
+
} catch (err) {
|
|
13497
|
+
fail(`cannot write ${configPath}: ${err.message}`, 1);
|
|
13498
|
+
}
|
|
13499
|
+
const verb = merged.replaced ? "updated" : "wrote";
|
|
13500
|
+
process.stdout.write(
|
|
13501
|
+
`
|
|
13502
|
+
${s.green("\u2713")} ${verb} ${s.bold(JSON.stringify(plan.displayName))} in ${s.cyan(configPath)}
|
|
13503
|
+
`
|
|
13504
|
+
);
|
|
13505
|
+
printInstallHint(plan, s);
|
|
13506
|
+
process.stdout.write(`
|
|
13507
|
+
Then ${plan.editor.restart}.
|
|
13508
|
+
|
|
13509
|
+
`);
|
|
13510
|
+
process.exit(0);
|
|
13511
|
+
}
|
|
13512
|
+
function registerSetupCommand(program) {
|
|
13513
|
+
program.command("setup [target...]").description("Generate an editor config that runs an agent through ACP Devtools").option("--editor <name>", `target editor (${EDITORS.join(" | ")})`).option("--name <label>", "display name for the agent entry").option("--config-path <path>", "override the editor config file location").option("--write", "merge the entry into the editor config instead of printing it", false).option("--no-color", "disable ANSI colour output").action((target, opts) => {
|
|
13514
|
+
if (!opts.editor) {
|
|
13515
|
+
fail(`--editor is required (${EDITORS.join(" | ")})`, 2);
|
|
13516
|
+
}
|
|
13517
|
+
if (!isEditor(opts.editor)) {
|
|
13518
|
+
fail(`unknown editor "${opts.editor}" (expected ${EDITORS.join(" | ")})`, 2);
|
|
13519
|
+
}
|
|
13520
|
+
const selfPath = process.argv[1] ?? "acp-devtools";
|
|
13521
|
+
const plan = buildSetupPlan({
|
|
13522
|
+
target,
|
|
13523
|
+
editor: opts.editor,
|
|
13524
|
+
selfPath,
|
|
13525
|
+
name: opts.name
|
|
13526
|
+
});
|
|
13527
|
+
const configPath = opts.configPath ?? editorInfo(opts.editor).configPath;
|
|
13528
|
+
const s = createStyler(opts.color && colorEnabled(process.stdout));
|
|
13529
|
+
if (opts.write) {
|
|
13530
|
+
doWrite(plan, target, opts, configPath, s);
|
|
13531
|
+
}
|
|
13532
|
+
printGuidance(plan, target, opts, configPath, s);
|
|
13533
|
+
process.exit(0);
|
|
13534
|
+
});
|
|
13535
|
+
}
|
|
13536
|
+
var init_setup = __esm({
|
|
13537
|
+
"src/commands/setup.ts"() {
|
|
13538
|
+
"use strict";
|
|
13539
|
+
init_style();
|
|
13540
|
+
init_setup_config();
|
|
13541
|
+
}
|
|
13542
|
+
});
|
|
13543
|
+
|
|
13110
13544
|
// src/commands/stats.ts
|
|
13111
13545
|
function registerStatsCommand(program) {
|
|
13112
13546
|
program.command("stats").description(
|
|
@@ -13401,11 +13835,11 @@ var init_stats = __esm({
|
|
|
13401
13835
|
// src/commands/ui.ts
|
|
13402
13836
|
import { createReadStream, existsSync as existsSync7, statSync as statSync3 } from "fs";
|
|
13403
13837
|
import { createServer } from "http";
|
|
13404
|
-
import { dirname as
|
|
13838
|
+
import { dirname as dirname6, extname, join as join5, normalize, resolve, sep } from "path";
|
|
13405
13839
|
import { fileURLToPath } from "url";
|
|
13406
13840
|
import { spawn as spawn2 } from "child_process";
|
|
13407
13841
|
function uiDistDir() {
|
|
13408
|
-
const here =
|
|
13842
|
+
const here = dirname6(fileURLToPath(import.meta.url));
|
|
13409
13843
|
return resolve(here, "ui");
|
|
13410
13844
|
}
|
|
13411
13845
|
function contentTypeFor(path) {
|
|
@@ -13419,7 +13853,7 @@ function serveStatic(req, res, rootDir) {
|
|
|
13419
13853
|
}
|
|
13420
13854
|
const urlPath = decodeURIComponent((req.url ?? "/").split("?")[0] ?? "/");
|
|
13421
13855
|
const relative = urlPath === "/" || urlPath === "" ? "/index.html" : urlPath;
|
|
13422
|
-
const candidate = normalize(
|
|
13856
|
+
const candidate = normalize(join5(rootDir, relative));
|
|
13423
13857
|
if (!candidate.startsWith(rootDir + sep) && candidate !== rootDir) {
|
|
13424
13858
|
res.statusCode = 403;
|
|
13425
13859
|
res.end();
|
|
@@ -13427,7 +13861,7 @@ function serveStatic(req, res, rootDir) {
|
|
|
13427
13861
|
}
|
|
13428
13862
|
let filePath = candidate;
|
|
13429
13863
|
if (!existsSync7(filePath) || !statSync3(filePath).isFile()) {
|
|
13430
|
-
filePath =
|
|
13864
|
+
filePath = join5(rootDir, "index.html");
|
|
13431
13865
|
if (!existsSync7(filePath)) {
|
|
13432
13866
|
res.statusCode = 404;
|
|
13433
13867
|
res.setHeader("content-type", "text/plain; charset=utf-8");
|
|
@@ -13470,7 +13904,7 @@ function registerUiCommand(program) {
|
|
|
13470
13904
|
process.exit(2);
|
|
13471
13905
|
}
|
|
13472
13906
|
const rootDir = uiDistDir();
|
|
13473
|
-
if (!existsSync7(
|
|
13907
|
+
if (!existsSync7(join5(rootDir, "index.html"))) {
|
|
13474
13908
|
process.stderr.write(
|
|
13475
13909
|
`acp-devtools: UI bundle missing at ${rootDir}
|
|
13476
13910
|
Run \`npm run build:full\` in the monorepo, or reinstall the published package.
|
|
@@ -13597,6 +14031,7 @@ function registerValidateCommand(program) {
|
|
|
13597
14031
|
}
|
|
13598
14032
|
const methodNeedle = opts.method ? opts.method.toLowerCase() : null;
|
|
13599
14033
|
const violations = [];
|
|
14034
|
+
const advisories = [];
|
|
13600
14035
|
let checked = 0;
|
|
13601
14036
|
let skipped = 0;
|
|
13602
14037
|
for (const m of messages) {
|
|
@@ -13610,11 +14045,20 @@ function registerValidateCommand(program) {
|
|
|
13610
14045
|
continue;
|
|
13611
14046
|
}
|
|
13612
14047
|
checked += 1;
|
|
13613
|
-
if (result.valid) continue;
|
|
13614
14048
|
const method = m.method ?? pairedMethod ?? null;
|
|
13615
|
-
|
|
13616
|
-
|
|
14049
|
+
const methodMatch = !methodNeedle || !!method && method.toLowerCase().includes(methodNeedle);
|
|
14050
|
+
if (methodMatch && result.advisories) {
|
|
14051
|
+
for (const a of result.advisories) {
|
|
14052
|
+
advisories.push({
|
|
14053
|
+
seq: m.seq,
|
|
14054
|
+
method,
|
|
14055
|
+
schemaName: result.schemaName ?? "?",
|
|
14056
|
+
path: a.path,
|
|
14057
|
+
message: a.message
|
|
14058
|
+
});
|
|
14059
|
+
}
|
|
13617
14060
|
}
|
|
14061
|
+
if (result.valid || !methodMatch) continue;
|
|
13618
14062
|
for (const e of result.errors) {
|
|
13619
14063
|
if (violations.length >= limit) break;
|
|
13620
14064
|
const v = {
|
|
@@ -13633,7 +14077,7 @@ function registerValidateCommand(program) {
|
|
|
13633
14077
|
if (opts.json) {
|
|
13634
14078
|
process.stdout.write(
|
|
13635
14079
|
JSON.stringify(
|
|
13636
|
-
{ sessionId: id, checked, skipped, violations },
|
|
14080
|
+
{ sessionId: id, checked, skipped, violations, advisories },
|
|
13637
14081
|
null,
|
|
13638
14082
|
2
|
|
13639
14083
|
) + "\n"
|
|
@@ -13644,18 +14088,25 @@ function registerValidateCommand(program) {
|
|
|
13644
14088
|
const errStyler = createStyler(colorEnabled(process.stderr));
|
|
13645
14089
|
const affected = new Set(violations.map((v) => v.method ?? "?"));
|
|
13646
14090
|
const vCount = violations.length === 0 ? errStyler.green("0 violations") : errStyler.red(`${violations.length} violations`);
|
|
14091
|
+
const aCount = advisories.length === 0 ? "" : ` \xB7 ${errStyler.yellow(`${advisories.length} advisor${advisories.length === 1 ? "y" : "ies"}`)}`;
|
|
13647
14092
|
process.stderr.write(
|
|
13648
|
-
`${errStyler.bold(errStyler.cyan(`session #${id}`))} \xB7 ${checked} checked \xB7 ${skipped} skipped (no schema) \xB7 ${vCount} in ${affected.size} method${affected.size === 1 ? "" : "s"}
|
|
14093
|
+
`${errStyler.bold(errStyler.cyan(`session #${id}`))} \xB7 ${checked} checked \xB7 ${skipped} skipped (no schema) \xB7 ${vCount} in ${affected.size} method${affected.size === 1 ? "" : "s"}${aCount}
|
|
13649
14094
|
|
|
13650
14095
|
`
|
|
13651
14096
|
);
|
|
13652
|
-
|
|
14097
|
+
const s = createStyler(colorEnabled(process.stdout));
|
|
14098
|
+
if (violations.length > 0) {
|
|
14099
|
+
process.stdout.write(renderViolations(s, violations));
|
|
14100
|
+
}
|
|
14101
|
+
if (advisories.length > 0) {
|
|
14102
|
+
if (violations.length > 0) process.stdout.write("\n");
|
|
14103
|
+
process.stdout.write(renderAdvisories(s, advisories));
|
|
14104
|
+
}
|
|
14105
|
+
if (violations.length === 0 && advisories.length === 0) {
|
|
13653
14106
|
process.stdout.write(errStyler.green("no violations") + "\n");
|
|
13654
14107
|
return;
|
|
13655
14108
|
}
|
|
13656
|
-
|
|
13657
|
-
process.stdout.write(renderViolations(s, violations));
|
|
13658
|
-
process.exit(1);
|
|
14109
|
+
if (violations.length > 0) process.exit(1);
|
|
13659
14110
|
});
|
|
13660
14111
|
}
|
|
13661
14112
|
function renderViolations(s, violations) {
|
|
@@ -13666,13 +14117,24 @@ function renderViolations(s, violations) {
|
|
|
13666
14117
|
s.cyan(truncate3(v.path, PATH_MAX)),
|
|
13667
14118
|
s.red(v.message)
|
|
13668
14119
|
]);
|
|
13669
|
-
return renderTable(s,
|
|
14120
|
+
return renderTable(s, COLUMNS4, body);
|
|
14121
|
+
}
|
|
14122
|
+
function renderAdvisories(s, advisories) {
|
|
14123
|
+
const heading5 = s.yellow(`${advisories.length} advisor${advisories.length === 1 ? "y" : "ies"}`) + s.dim(" \u2014 valid today, but a future ACP version will require these fields") + "\n";
|
|
14124
|
+
const body = advisories.map((a) => [
|
|
14125
|
+
s.dim(`#${a.seq}`),
|
|
14126
|
+
truncate3(a.method ?? "\u2014", METHOD_MAX4),
|
|
14127
|
+
s.dim(truncate3(a.schemaName, SCHEMA_MAX)),
|
|
14128
|
+
s.yellow(truncate3(a.path, PATH_MAX)),
|
|
14129
|
+
s.yellow(a.message)
|
|
14130
|
+
]);
|
|
14131
|
+
return heading5 + renderTable(s, ADVISORY_COLUMNS, body);
|
|
13670
14132
|
}
|
|
13671
14133
|
function truncate3(s, max) {
|
|
13672
14134
|
if (s.length <= max) return s;
|
|
13673
14135
|
return s.slice(0, Math.max(1, max - 1)) + "\u2026";
|
|
13674
14136
|
}
|
|
13675
|
-
var METHOD_MAX4, SCHEMA_MAX, PATH_MAX,
|
|
14137
|
+
var METHOD_MAX4, SCHEMA_MAX, PATH_MAX, COLUMNS4, ADVISORY_COLUMNS;
|
|
13676
14138
|
var init_validate2 = __esm({
|
|
13677
14139
|
"src/commands/validate.ts"() {
|
|
13678
14140
|
"use strict";
|
|
@@ -13683,19 +14145,26 @@ var init_validate2 = __esm({
|
|
|
13683
14145
|
METHOD_MAX4 = 28;
|
|
13684
14146
|
SCHEMA_MAX = 28;
|
|
13685
14147
|
PATH_MAX = 38;
|
|
13686
|
-
|
|
14148
|
+
COLUMNS4 = [
|
|
13687
14149
|
{ title: "SEQ", align: "right" },
|
|
13688
14150
|
{ title: "METHOD", align: "left" },
|
|
13689
14151
|
{ title: "SCHEMA", align: "left" },
|
|
13690
14152
|
{ title: "PATH", align: "left" },
|
|
13691
14153
|
{ title: "ERROR", align: "left" }
|
|
13692
14154
|
];
|
|
14155
|
+
ADVISORY_COLUMNS = [
|
|
14156
|
+
{ title: "SEQ", align: "right" },
|
|
14157
|
+
{ title: "METHOD", align: "left" },
|
|
14158
|
+
{ title: "SCHEMA", align: "left" },
|
|
14159
|
+
{ title: "FIELD", align: "left" },
|
|
14160
|
+
{ title: "ADVISORY", align: "left" }
|
|
14161
|
+
];
|
|
13693
14162
|
}
|
|
13694
14163
|
});
|
|
13695
14164
|
|
|
13696
14165
|
// src/lib/help.ts
|
|
13697
|
-
import { homedir as
|
|
13698
|
-
function tidyHome(text, home =
|
|
14166
|
+
import { homedir as homedir5 } from "os";
|
|
14167
|
+
function tidyHome(text, home = homedir5()) {
|
|
13699
14168
|
if (!home) return text;
|
|
13700
14169
|
const escapedHome = home.replace(/\\/g, "\\\\");
|
|
13701
14170
|
const collapsed = text.split(escapedHome).join("~").split(home).join("~");
|
|
@@ -13857,7 +14326,7 @@ var init_help = __esm({
|
|
|
13857
14326
|
},
|
|
13858
14327
|
{ title: "View", commands: ["ui", "replay"] },
|
|
13859
14328
|
{ title: "Manage", commands: ["export", "import", "delete", "backfill-metadata"] },
|
|
13860
|
-
{ title: "Setup", commands: ["doctor", "mcp"] }
|
|
14329
|
+
{ title: "Setup", commands: ["setup", "agents", "doctor", "mcp"] }
|
|
13861
14330
|
];
|
|
13862
14331
|
SUMMARIES = {
|
|
13863
14332
|
proxy: "Capture an agent's traffic through a proxy",
|
|
@@ -13876,6 +14345,8 @@ var init_help = __esm({
|
|
|
13876
14345
|
import: "Import a JSON export into the store",
|
|
13877
14346
|
delete: "Delete saved sessions permanently",
|
|
13878
14347
|
"backfill-metadata": "Recompute session metadata columns",
|
|
14348
|
+
setup: "Generate an editor config for an agent",
|
|
14349
|
+
agents: "List the built-in agent shortcuts",
|
|
13879
14350
|
doctor: "Diagnose setup and report issues",
|
|
13880
14351
|
mcp: "Expose captures to Claude over MCP"
|
|
13881
14352
|
};
|
|
@@ -13934,6 +14405,17 @@ var init_help = __esm({
|
|
|
13934
14405
|
replay: ["acp-devtools replay 12", "acp-devtools replay --file session-12.json"],
|
|
13935
14406
|
validate: ["acp-devtools validate 12"],
|
|
13936
14407
|
"session-info": ["acp-devtools session-info 12"],
|
|
14408
|
+
setup: [
|
|
14409
|
+
"# See which agent shortcuts exist",
|
|
14410
|
+
"acp-devtools agents",
|
|
14411
|
+
"",
|
|
14412
|
+
"# Print a Zed config block for a registry agent",
|
|
14413
|
+
"acp-devtools setup junie --editor zed",
|
|
14414
|
+
"",
|
|
14415
|
+
"# Wrap a custom agent and write it straight into the JetBrains config",
|
|
14416
|
+
"acp-devtools setup --editor jetbrains --write -- npx -y @your-scope/your-acp"
|
|
14417
|
+
],
|
|
14418
|
+
agents: ["acp-devtools agents", "", "# Machine-readable", "acp-devtools agents --json"],
|
|
13937
14419
|
doctor: ["acp-devtools doctor"],
|
|
13938
14420
|
mcp: ["# Read-only MCP server over stdio (wire into .claude/mcp_servers.json)", "acp-devtools mcp"],
|
|
13939
14421
|
"backfill-metadata": [
|
|
@@ -13970,6 +14452,8 @@ function buildProgram() {
|
|
|
13970
14452
|
registerInspectCommand(program);
|
|
13971
14453
|
registerSearchCommand(program);
|
|
13972
14454
|
registerSessionInfoCommand(program);
|
|
14455
|
+
registerSetupCommand(program);
|
|
14456
|
+
registerAgentsCommand(program);
|
|
13973
14457
|
registerStatsCommand(program);
|
|
13974
14458
|
registerBackfillMetadataCommand(program);
|
|
13975
14459
|
registerMcpCommand(program);
|
|
@@ -13981,6 +14465,7 @@ function buildProgram() {
|
|
|
13981
14465
|
var init_program = __esm({
|
|
13982
14466
|
"src/program.ts"() {
|
|
13983
14467
|
"use strict";
|
|
14468
|
+
init_agents2();
|
|
13984
14469
|
init_backfill_metadata();
|
|
13985
14470
|
init_delete();
|
|
13986
14471
|
init_diff();
|
|
@@ -13996,6 +14481,7 @@ var init_program = __esm({
|
|
|
13996
14481
|
init_replay2();
|
|
13997
14482
|
init_search();
|
|
13998
14483
|
init_session_info();
|
|
14484
|
+
init_setup();
|
|
13999
14485
|
init_stats();
|
|
14000
14486
|
init_ui();
|
|
14001
14487
|
init_validate2();
|
|
@@ -14100,6 +14586,8 @@ var KNOWN_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
|
14100
14586
|
"inspect",
|
|
14101
14587
|
"search",
|
|
14102
14588
|
"session-info",
|
|
14589
|
+
"setup",
|
|
14590
|
+
"agents",
|
|
14103
14591
|
"stats",
|
|
14104
14592
|
"validate",
|
|
14105
14593
|
"backfill-metadata",
|