acp-devtools 0.5.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/README.md +10 -3
- package/dist/index.js +553 -143
- package/dist/ui/assets/{index-C5YKMrXl.js → index-D6fYTnQ6.js} +4 -4
- package/dist/ui/index.html +1 -1
- package/package.json +3 -2
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;
|
|
@@ -8518,6 +8518,14 @@ var init_registry = __esm({
|
|
|
8518
8518
|
command: "opencode",
|
|
8519
8519
|
args: ["acp"],
|
|
8520
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
|
|
8521
8529
|
}
|
|
8522
8530
|
};
|
|
8523
8531
|
DEFAULT_AGENT = "claude-code";
|
|
@@ -10073,6 +10081,142 @@ var init_dist = __esm({
|
|
|
10073
10081
|
}
|
|
10074
10082
|
});
|
|
10075
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
|
+
|
|
10076
10220
|
// src/commands/backfill-metadata.ts
|
|
10077
10221
|
function backfillSession(db, id) {
|
|
10078
10222
|
let session;
|
|
@@ -10221,63 +10365,6 @@ var init_delete = __esm({
|
|
|
10221
10365
|
}
|
|
10222
10366
|
});
|
|
10223
10367
|
|
|
10224
|
-
// src/lib/style.ts
|
|
10225
|
-
function colorEnabled(stream = process.stdout, env = process.env) {
|
|
10226
|
-
if (env.FORCE_COLOR === "0" || env.FORCE_COLOR === "false") return false;
|
|
10227
|
-
if (env.FORCE_COLOR !== void 0) return true;
|
|
10228
|
-
if (env.NO_COLOR !== void 0) return false;
|
|
10229
|
-
return Boolean(stream.isTTY);
|
|
10230
|
-
}
|
|
10231
|
-
function paint(enabled, code, s) {
|
|
10232
|
-
if (!enabled) return s;
|
|
10233
|
-
return `${ESC}[${CODES[code]}m${s}${ESC}[${CODES.reset}m`;
|
|
10234
|
-
}
|
|
10235
|
-
function createStyler(enabled = colorEnabled()) {
|
|
10236
|
-
const wrap = (code) => (s) => paint(enabled, code, s);
|
|
10237
|
-
return {
|
|
10238
|
-
enabled,
|
|
10239
|
-
bold: wrap("bold"),
|
|
10240
|
-
dim: wrap("dim"),
|
|
10241
|
-
italic: wrap("italic"),
|
|
10242
|
-
underline: wrap("underline"),
|
|
10243
|
-
red: wrap("red"),
|
|
10244
|
-
green: wrap("green"),
|
|
10245
|
-
yellow: wrap("yellow"),
|
|
10246
|
-
blue: wrap("blue"),
|
|
10247
|
-
magenta: wrap("magenta"),
|
|
10248
|
-
cyan: wrap("cyan"),
|
|
10249
|
-
gray: wrap("gray")
|
|
10250
|
-
};
|
|
10251
|
-
}
|
|
10252
|
-
function stripAnsi(s) {
|
|
10253
|
-
return s.replace(ANSI_PATTERN, "");
|
|
10254
|
-
}
|
|
10255
|
-
function visibleWidth(s) {
|
|
10256
|
-
return stripAnsi(s).length;
|
|
10257
|
-
}
|
|
10258
|
-
var ESC, CODES, ANSI_PATTERN;
|
|
10259
|
-
var init_style = __esm({
|
|
10260
|
-
"src/lib/style.ts"() {
|
|
10261
|
-
"use strict";
|
|
10262
|
-
ESC = String.fromCharCode(27);
|
|
10263
|
-
CODES = {
|
|
10264
|
-
reset: 0,
|
|
10265
|
-
bold: 1,
|
|
10266
|
-
dim: 2,
|
|
10267
|
-
italic: 3,
|
|
10268
|
-
underline: 4,
|
|
10269
|
-
red: 31,
|
|
10270
|
-
green: 32,
|
|
10271
|
-
yellow: 33,
|
|
10272
|
-
blue: 34,
|
|
10273
|
-
magenta: 35,
|
|
10274
|
-
cyan: 36,
|
|
10275
|
-
gray: 90
|
|
10276
|
-
};
|
|
10277
|
-
ANSI_PATTERN = new RegExp(`${ESC}\\[[0-9;]*m`, "g");
|
|
10278
|
-
}
|
|
10279
|
-
});
|
|
10280
|
-
|
|
10281
10368
|
// src/lib/palette.ts
|
|
10282
10369
|
function colorKind(s, kind, text) {
|
|
10283
10370
|
switch (kind) {
|
|
@@ -10311,46 +10398,6 @@ var init_palette = __esm({
|
|
|
10311
10398
|
}
|
|
10312
10399
|
});
|
|
10313
10400
|
|
|
10314
|
-
// src/lib/table.ts
|
|
10315
|
-
function renderTable(s, columns, rows, opts = {}) {
|
|
10316
|
-
const indent = opts.indent ?? "";
|
|
10317
|
-
const gap = opts.gap ?? " ";
|
|
10318
|
-
const widths = columns.map(
|
|
10319
|
-
(col, c) => Math.max(visibleWidth(col.title), ...rows.map((r) => visibleWidth(r[c] ?? "")))
|
|
10320
|
-
);
|
|
10321
|
-
const pad2 = (text, width, align) => {
|
|
10322
|
-
const fill = " ".repeat(Math.max(0, width - visibleWidth(text)));
|
|
10323
|
-
return align === "right" ? fill + text : text + fill;
|
|
10324
|
-
};
|
|
10325
|
-
const lineFor = (cells, color) => {
|
|
10326
|
-
const rendered = columns.map((col, c) => {
|
|
10327
|
-
const align = col.align ?? "left";
|
|
10328
|
-
const text = cells[c] ?? "";
|
|
10329
|
-
const isLast = c === columns.length - 1;
|
|
10330
|
-
const cell = isLast && align === "left" ? text : pad2(text, widths[c], align);
|
|
10331
|
-
return color(cell);
|
|
10332
|
-
});
|
|
10333
|
-
return indent + rendered.join(gap);
|
|
10334
|
-
};
|
|
10335
|
-
const out = [];
|
|
10336
|
-
out.push(
|
|
10337
|
-
lineFor(
|
|
10338
|
-
columns.map((col) => col.title),
|
|
10339
|
-
(t) => s.dim(t)
|
|
10340
|
-
)
|
|
10341
|
-
);
|
|
10342
|
-
for (const row2 of rows) {
|
|
10343
|
-
out.push(lineFor(row2, (t) => t));
|
|
10344
|
-
}
|
|
10345
|
-
return out.map((l) => l + "\n").join("");
|
|
10346
|
-
}
|
|
10347
|
-
var init_table = __esm({
|
|
10348
|
-
"src/lib/table.ts"() {
|
|
10349
|
-
"use strict";
|
|
10350
|
-
init_style();
|
|
10351
|
-
}
|
|
10352
|
-
});
|
|
10353
|
-
|
|
10354
10401
|
// src/commands/diff.ts
|
|
10355
10402
|
function registerDiffCommand(program) {
|
|
10356
10403
|
program.command("diff").description(
|
|
@@ -10634,10 +10681,130 @@ var init_diff = __esm({
|
|
|
10634
10681
|
}
|
|
10635
10682
|
});
|
|
10636
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
|
+
|
|
10637
10804
|
// src/commands/doctor.ts
|
|
10638
10805
|
import { existsSync as existsSync6, readdirSync as readdirSync2, statSync as statSync2 } from "fs";
|
|
10639
|
-
import { homedir as
|
|
10640
|
-
import { join as
|
|
10806
|
+
import { homedir as homedir4, platform as platform2, release } from "os";
|
|
10807
|
+
import { join as join4 } from "path";
|
|
10641
10808
|
function colorStatus(s, status, text) {
|
|
10642
10809
|
switch (status) {
|
|
10643
10810
|
case "ok":
|
|
@@ -10660,7 +10827,7 @@ function checkEnvironment() {
|
|
|
10660
10827
|
});
|
|
10661
10828
|
results.push({
|
|
10662
10829
|
status: "info",
|
|
10663
|
-
label: `Platform: ${
|
|
10830
|
+
label: `Platform: ${platform2()} ${process.arch} (${release()})`
|
|
10664
10831
|
});
|
|
10665
10832
|
const binary = process.argv[1] ?? "(unknown)";
|
|
10666
10833
|
results.push({
|
|
@@ -10744,21 +10911,17 @@ function checkState() {
|
|
|
10744
10911
|
return results;
|
|
10745
10912
|
}
|
|
10746
10913
|
function probeZed() {
|
|
10747
|
-
const path =
|
|
10748
|
-
process.env.XDG_CONFIG_HOME ?? join3(homedir3(), ".config"),
|
|
10749
|
-
"zed",
|
|
10750
|
-
"settings.json"
|
|
10751
|
-
);
|
|
10914
|
+
const path = zedSettingsPath();
|
|
10752
10915
|
return { name: "Zed", path, exists: existsSync6(path) };
|
|
10753
10916
|
}
|
|
10754
10917
|
function probeJetBrains() {
|
|
10755
10918
|
const baseDirs = [];
|
|
10756
|
-
if (
|
|
10757
|
-
baseDirs.push(
|
|
10758
|
-
} else if (
|
|
10759
|
-
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"));
|
|
10760
10923
|
} else {
|
|
10761
|
-
baseDirs.push(
|
|
10924
|
+
baseDirs.push(join4(homedir4(), ".config", "JetBrains"));
|
|
10762
10925
|
}
|
|
10763
10926
|
const probes = [];
|
|
10764
10927
|
for (const base of baseDirs) {
|
|
@@ -10772,7 +10935,7 @@ function probeJetBrains() {
|
|
|
10772
10935
|
for (const entry of entries) {
|
|
10773
10936
|
if (entry.startsWith(".")) continue;
|
|
10774
10937
|
if (!JETBRAINS_VERSIONED.test(entry) && !JETBRAINS_UNVERSIONED.has(entry)) continue;
|
|
10775
|
-
const full =
|
|
10938
|
+
const full = join4(base, entry);
|
|
10776
10939
|
try {
|
|
10777
10940
|
if (!statSync2(full).isDirectory()) continue;
|
|
10778
10941
|
} catch {
|
|
@@ -10871,6 +11034,7 @@ var init_doctor = __esm({
|
|
|
10871
11034
|
"use strict";
|
|
10872
11035
|
init_dist();
|
|
10873
11036
|
init_style();
|
|
11037
|
+
init_setup_config();
|
|
10874
11038
|
STATUS_MARK = {
|
|
10875
11039
|
ok: "\u2713",
|
|
10876
11040
|
warn: "!",
|
|
@@ -10887,7 +11051,7 @@ var CLI_VERSION;
|
|
|
10887
11051
|
var init_version = __esm({
|
|
10888
11052
|
"src/version.ts"() {
|
|
10889
11053
|
"use strict";
|
|
10890
|
-
CLI_VERSION = "0.
|
|
11054
|
+
CLI_VERSION = "0.6.0";
|
|
10891
11055
|
}
|
|
10892
11056
|
});
|
|
10893
11057
|
|
|
@@ -11356,9 +11520,9 @@ function formatTable(rows) {
|
|
|
11356
11520
|
labelOf(r)
|
|
11357
11521
|
];
|
|
11358
11522
|
});
|
|
11359
|
-
return renderTable(s,
|
|
11523
|
+
return renderTable(s, COLUMNS2, body);
|
|
11360
11524
|
}
|
|
11361
|
-
var
|
|
11525
|
+
var COLUMNS2;
|
|
11362
11526
|
var init_list = __esm({
|
|
11363
11527
|
"src/commands/list.ts"() {
|
|
11364
11528
|
"use strict";
|
|
@@ -11366,7 +11530,7 @@ var init_list = __esm({
|
|
|
11366
11530
|
init_style();
|
|
11367
11531
|
init_palette();
|
|
11368
11532
|
init_table();
|
|
11369
|
-
|
|
11533
|
+
COLUMNS2 = [
|
|
11370
11534
|
{ title: "ID", align: "left" },
|
|
11371
11535
|
{ title: "AGE", align: "right" },
|
|
11372
11536
|
{ title: "KIND", align: "left" },
|
|
@@ -11623,7 +11787,9 @@ function buildMcpServer(opts) {
|
|
|
11623
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.",
|
|
11624
11788
|
inputSchema: {
|
|
11625
11789
|
session_id: z.number().int().positive().describe("session id from list_sessions"),
|
|
11626
|
-
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
|
+
)
|
|
11627
11793
|
},
|
|
11628
11794
|
outputSchema: {
|
|
11629
11795
|
session_id: z.number(),
|
|
@@ -11717,12 +11883,14 @@ function buildMcpServer(opts) {
|
|
|
11717
11883
|
z.object({
|
|
11718
11884
|
seq: z.number(),
|
|
11719
11885
|
method: z.string().nullable(),
|
|
11720
|
-
errors: z.array(
|
|
11721
|
-
|
|
11722
|
-
|
|
11723
|
-
|
|
11724
|
-
|
|
11725
|
-
|
|
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
|
+
)
|
|
11726
11894
|
}).loose()
|
|
11727
11895
|
),
|
|
11728
11896
|
advisories: z.array(
|
|
@@ -11851,6 +12019,88 @@ function buildMcpServer(opts) {
|
|
|
11851
12019
|
});
|
|
11852
12020
|
}
|
|
11853
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
|
+
);
|
|
11854
12104
|
registerPrompts(server);
|
|
11855
12105
|
return server;
|
|
11856
12106
|
}
|
|
@@ -11974,12 +12224,14 @@ var init_mcp = __esm({
|
|
|
11974
12224
|
"use strict";
|
|
11975
12225
|
init_dist();
|
|
11976
12226
|
init_version();
|
|
12227
|
+
init_setup_config();
|
|
11977
12228
|
SERVER_INSTRUCTIONS = `acp-devtools exposes a local SQLite store of captured
|
|
11978
12229
|
Agent Client Protocol (ACP) sessions. ACP is the editor\u2194agent JSON-RPC
|
|
11979
12230
|
protocol used by Claude Code, Goose, Codex, and other IDE agents.
|
|
11980
12231
|
|
|
11981
12232
|
Every tool here is **read-only** \u2014 nothing in this server writes to the
|
|
11982
|
-
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:
|
|
11983
12235
|
|
|
11984
12236
|
- a slow session (\`get_latency_stats\` returns per-method p50/p99/max
|
|
11985
12237
|
plus auto-detected insights: hotspot, long-tail, outlier, busiest,
|
|
@@ -11996,6 +12248,12 @@ database. Use it to investigate:
|
|
|
11996
12248
|
(\`diff_sessions\` aligns two captures and reports added / removed
|
|
11997
12249
|
frames and field-level payload changes)
|
|
11998
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
|
+
|
|
11999
12257
|
A typical investigation:
|
|
12000
12258
|
1. \`list_sessions\` to see what is captured
|
|
12001
12259
|
2. \`get_session_summary({session_id})\` for the headline numbers and
|
|
@@ -12931,7 +13189,7 @@ function renderHits(s, hits, needle) {
|
|
|
12931
13189
|
truncate2(h.method ?? "\u2014", METHOD_MAX2),
|
|
12932
13190
|
highlight(s, h.snippet, needle)
|
|
12933
13191
|
]);
|
|
12934
|
-
return renderTable(s,
|
|
13192
|
+
return renderTable(s, COLUMNS3, body);
|
|
12935
13193
|
}
|
|
12936
13194
|
function highlight(s, snippet, needle) {
|
|
12937
13195
|
if (!s.enabled || needle.length === 0) return snippet;
|
|
@@ -12953,7 +13211,7 @@ function truncate2(s, max) {
|
|
|
12953
13211
|
if (s.length <= max) return s;
|
|
12954
13212
|
return s.slice(0, Math.max(1, max - 1)) + "\u2026";
|
|
12955
13213
|
}
|
|
12956
|
-
var SNIPPET_LEN, METHOD_MAX2,
|
|
13214
|
+
var SNIPPET_LEN, METHOD_MAX2, COLUMNS3;
|
|
12957
13215
|
var init_search = __esm({
|
|
12958
13216
|
"src/commands/search.ts"() {
|
|
12959
13217
|
"use strict";
|
|
@@ -12962,7 +13220,7 @@ var init_search = __esm({
|
|
|
12962
13220
|
init_table();
|
|
12963
13221
|
SNIPPET_LEN = 80;
|
|
12964
13222
|
METHOD_MAX2 = 32;
|
|
12965
|
-
|
|
13223
|
+
COLUMNS3 = [
|
|
12966
13224
|
{ title: "LOC", align: "left" },
|
|
12967
13225
|
{ title: "METHOD", align: "left" },
|
|
12968
13226
|
{ title: "MATCH", align: "left" }
|
|
@@ -13150,6 +13408,139 @@ var init_session_info = __esm({
|
|
|
13150
13408
|
}
|
|
13151
13409
|
});
|
|
13152
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
|
+
|
|
13153
13544
|
// src/commands/stats.ts
|
|
13154
13545
|
function registerStatsCommand(program) {
|
|
13155
13546
|
program.command("stats").description(
|
|
@@ -13444,11 +13835,11 @@ var init_stats = __esm({
|
|
|
13444
13835
|
// src/commands/ui.ts
|
|
13445
13836
|
import { createReadStream, existsSync as existsSync7, statSync as statSync3 } from "fs";
|
|
13446
13837
|
import { createServer } from "http";
|
|
13447
|
-
import { dirname as
|
|
13838
|
+
import { dirname as dirname6, extname, join as join5, normalize, resolve, sep } from "path";
|
|
13448
13839
|
import { fileURLToPath } from "url";
|
|
13449
13840
|
import { spawn as spawn2 } from "child_process";
|
|
13450
13841
|
function uiDistDir() {
|
|
13451
|
-
const here =
|
|
13842
|
+
const here = dirname6(fileURLToPath(import.meta.url));
|
|
13452
13843
|
return resolve(here, "ui");
|
|
13453
13844
|
}
|
|
13454
13845
|
function contentTypeFor(path) {
|
|
@@ -13462,7 +13853,7 @@ function serveStatic(req, res, rootDir) {
|
|
|
13462
13853
|
}
|
|
13463
13854
|
const urlPath = decodeURIComponent((req.url ?? "/").split("?")[0] ?? "/");
|
|
13464
13855
|
const relative = urlPath === "/" || urlPath === "" ? "/index.html" : urlPath;
|
|
13465
|
-
const candidate = normalize(
|
|
13856
|
+
const candidate = normalize(join5(rootDir, relative));
|
|
13466
13857
|
if (!candidate.startsWith(rootDir + sep) && candidate !== rootDir) {
|
|
13467
13858
|
res.statusCode = 403;
|
|
13468
13859
|
res.end();
|
|
@@ -13470,7 +13861,7 @@ function serveStatic(req, res, rootDir) {
|
|
|
13470
13861
|
}
|
|
13471
13862
|
let filePath = candidate;
|
|
13472
13863
|
if (!existsSync7(filePath) || !statSync3(filePath).isFile()) {
|
|
13473
|
-
filePath =
|
|
13864
|
+
filePath = join5(rootDir, "index.html");
|
|
13474
13865
|
if (!existsSync7(filePath)) {
|
|
13475
13866
|
res.statusCode = 404;
|
|
13476
13867
|
res.setHeader("content-type", "text/plain; charset=utf-8");
|
|
@@ -13513,7 +13904,7 @@ function registerUiCommand(program) {
|
|
|
13513
13904
|
process.exit(2);
|
|
13514
13905
|
}
|
|
13515
13906
|
const rootDir = uiDistDir();
|
|
13516
|
-
if (!existsSync7(
|
|
13907
|
+
if (!existsSync7(join5(rootDir, "index.html"))) {
|
|
13517
13908
|
process.stderr.write(
|
|
13518
13909
|
`acp-devtools: UI bundle missing at ${rootDir}
|
|
13519
13910
|
Run \`npm run build:full\` in the monorepo, or reinstall the published package.
|
|
@@ -13726,7 +14117,7 @@ function renderViolations(s, violations) {
|
|
|
13726
14117
|
s.cyan(truncate3(v.path, PATH_MAX)),
|
|
13727
14118
|
s.red(v.message)
|
|
13728
14119
|
]);
|
|
13729
|
-
return renderTable(s,
|
|
14120
|
+
return renderTable(s, COLUMNS4, body);
|
|
13730
14121
|
}
|
|
13731
14122
|
function renderAdvisories(s, advisories) {
|
|
13732
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";
|
|
@@ -13743,7 +14134,7 @@ function truncate3(s, max) {
|
|
|
13743
14134
|
if (s.length <= max) return s;
|
|
13744
14135
|
return s.slice(0, Math.max(1, max - 1)) + "\u2026";
|
|
13745
14136
|
}
|
|
13746
|
-
var METHOD_MAX4, SCHEMA_MAX, PATH_MAX,
|
|
14137
|
+
var METHOD_MAX4, SCHEMA_MAX, PATH_MAX, COLUMNS4, ADVISORY_COLUMNS;
|
|
13747
14138
|
var init_validate2 = __esm({
|
|
13748
14139
|
"src/commands/validate.ts"() {
|
|
13749
14140
|
"use strict";
|
|
@@ -13754,7 +14145,7 @@ var init_validate2 = __esm({
|
|
|
13754
14145
|
METHOD_MAX4 = 28;
|
|
13755
14146
|
SCHEMA_MAX = 28;
|
|
13756
14147
|
PATH_MAX = 38;
|
|
13757
|
-
|
|
14148
|
+
COLUMNS4 = [
|
|
13758
14149
|
{ title: "SEQ", align: "right" },
|
|
13759
14150
|
{ title: "METHOD", align: "left" },
|
|
13760
14151
|
{ title: "SCHEMA", align: "left" },
|
|
@@ -13772,8 +14163,8 @@ var init_validate2 = __esm({
|
|
|
13772
14163
|
});
|
|
13773
14164
|
|
|
13774
14165
|
// src/lib/help.ts
|
|
13775
|
-
import { homedir as
|
|
13776
|
-
function tidyHome(text, home =
|
|
14166
|
+
import { homedir as homedir5 } from "os";
|
|
14167
|
+
function tidyHome(text, home = homedir5()) {
|
|
13777
14168
|
if (!home) return text;
|
|
13778
14169
|
const escapedHome = home.replace(/\\/g, "\\\\");
|
|
13779
14170
|
const collapsed = text.split(escapedHome).join("~").split(home).join("~");
|
|
@@ -13935,7 +14326,7 @@ var init_help = __esm({
|
|
|
13935
14326
|
},
|
|
13936
14327
|
{ title: "View", commands: ["ui", "replay"] },
|
|
13937
14328
|
{ title: "Manage", commands: ["export", "import", "delete", "backfill-metadata"] },
|
|
13938
|
-
{ title: "Setup", commands: ["doctor", "mcp"] }
|
|
14329
|
+
{ title: "Setup", commands: ["setup", "agents", "doctor", "mcp"] }
|
|
13939
14330
|
];
|
|
13940
14331
|
SUMMARIES = {
|
|
13941
14332
|
proxy: "Capture an agent's traffic through a proxy",
|
|
@@ -13954,6 +14345,8 @@ var init_help = __esm({
|
|
|
13954
14345
|
import: "Import a JSON export into the store",
|
|
13955
14346
|
delete: "Delete saved sessions permanently",
|
|
13956
14347
|
"backfill-metadata": "Recompute session metadata columns",
|
|
14348
|
+
setup: "Generate an editor config for an agent",
|
|
14349
|
+
agents: "List the built-in agent shortcuts",
|
|
13957
14350
|
doctor: "Diagnose setup and report issues",
|
|
13958
14351
|
mcp: "Expose captures to Claude over MCP"
|
|
13959
14352
|
};
|
|
@@ -14012,6 +14405,17 @@ var init_help = __esm({
|
|
|
14012
14405
|
replay: ["acp-devtools replay 12", "acp-devtools replay --file session-12.json"],
|
|
14013
14406
|
validate: ["acp-devtools validate 12"],
|
|
14014
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"],
|
|
14015
14419
|
doctor: ["acp-devtools doctor"],
|
|
14016
14420
|
mcp: ["# Read-only MCP server over stdio (wire into .claude/mcp_servers.json)", "acp-devtools mcp"],
|
|
14017
14421
|
"backfill-metadata": [
|
|
@@ -14048,6 +14452,8 @@ function buildProgram() {
|
|
|
14048
14452
|
registerInspectCommand(program);
|
|
14049
14453
|
registerSearchCommand(program);
|
|
14050
14454
|
registerSessionInfoCommand(program);
|
|
14455
|
+
registerSetupCommand(program);
|
|
14456
|
+
registerAgentsCommand(program);
|
|
14051
14457
|
registerStatsCommand(program);
|
|
14052
14458
|
registerBackfillMetadataCommand(program);
|
|
14053
14459
|
registerMcpCommand(program);
|
|
@@ -14059,6 +14465,7 @@ function buildProgram() {
|
|
|
14059
14465
|
var init_program = __esm({
|
|
14060
14466
|
"src/program.ts"() {
|
|
14061
14467
|
"use strict";
|
|
14468
|
+
init_agents2();
|
|
14062
14469
|
init_backfill_metadata();
|
|
14063
14470
|
init_delete();
|
|
14064
14471
|
init_diff();
|
|
@@ -14074,6 +14481,7 @@ var init_program = __esm({
|
|
|
14074
14481
|
init_replay2();
|
|
14075
14482
|
init_search();
|
|
14076
14483
|
init_session_info();
|
|
14484
|
+
init_setup();
|
|
14077
14485
|
init_stats();
|
|
14078
14486
|
init_ui();
|
|
14079
14487
|
init_validate2();
|
|
@@ -14178,6 +14586,8 @@ var KNOWN_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
|
14178
14586
|
"inspect",
|
|
14179
14587
|
"search",
|
|
14180
14588
|
"session-info",
|
|
14589
|
+
"setup",
|
|
14590
|
+
"agents",
|
|
14181
14591
|
"stats",
|
|
14182
14592
|
"validate",
|
|
14183
14593
|
"backfill-metadata",
|