@ken-jo/agent-connector 0.4.79 → 0.4.91
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 +3 -3
- package/dist/{action-OHGFVKMC.js → action-L44DXFHT.js} +9 -9
- package/dist/antigravity-cli-JO6GUTV7.js +436 -0
- package/dist/antigravity-cli-JO6GUTV7.js.map +1 -0
- package/dist/{chunk-X457NOFE.js → chunk-25CPWJA7.js} +91 -11
- package/dist/chunk-25CPWJA7.js.map +1 -0
- package/dist/{chunk-VKRGQLY4.js → chunk-7HUUINPB.js} +18 -18
- package/dist/{chunk-LKAVD4HP.js → chunk-BLTVZACS.js} +8 -8
- package/dist/{chunk-PZHB5TVA.js → chunk-G4CEELKO.js} +2 -2
- package/dist/{chunk-VD4EG6SG.js → chunk-KIRCPLM4.js} +5 -5
- package/dist/{chunk-ZXX5DVSE.js → chunk-LAIITCMW.js} +6 -6
- package/dist/{chunk-UYZ53KWS.js → chunk-LF76VPGQ.js} +5 -5
- package/dist/{chunk-IRUYJD23.js → chunk-NLE2J5P4.js} +1 -1
- package/dist/{chunk-7NXEHZAK.js → chunk-NWLRJNXM.js} +2 -2
- package/dist/{chunk-YJP3KGLM.js → chunk-QARPXSIV.js} +4 -4
- package/dist/{chunk-AMK2K6XZ.js → chunk-R6LML2YS.js} +2 -2
- package/dist/{chunk-S4E6QQEM.js → chunk-ZMLVR4J7.js} +7 -2
- package/dist/chunk-ZMLVR4J7.js.map +1 -0
- package/dist/{claude-code-T6ZRCMA7.js → claude-code-WS4NAGZT.js} +4 -4
- package/dist/cli/sdk.js +4 -4
- package/dist/cli.js +1 -1
- package/dist/codebuddy-RBEZGXBG.js +643 -0
- package/dist/codebuddy-RBEZGXBG.js.map +1 -0
- package/dist/{codex-RHKQKNNG.js → codex-ZZ434GYR.js} +4 -4
- package/dist/{detect-ALAKE54S.js → detect-3S46RUMK.js} +4 -4
- package/dist/devin-PRJY2TTD.js +510 -0
- package/dist/devin-PRJY2TTD.js.map +1 -0
- package/dist/{doctor-UNF7FCF4.js → doctor-3CUBPQKU.js} +14 -14
- package/dist/grok-cli-5QD235UB.js +482 -0
- package/dist/grok-cli-5QD235UB.js.map +1 -0
- package/dist/{hook-GM2IDA3C.js → hook-P6EKDINW.js} +9 -9
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/{install-7O4XWH7T.js → install-7DMK53SB.js} +10 -10
- package/dist/{introspect-5o5ick0_.d.ts → introspect-DYOIX8Ov.d.ts} +1 -1
- package/dist/{jetbrains-copilot-4IOT3I2Y.js → jetbrains-copilot-T2EPKROP.js} +9 -3
- package/dist/jetbrains-copilot-T2EPKROP.js.map +1 -0
- package/dist/junie-SQ4SDLGK.js +227 -0
- package/dist/junie-SQ4SDLGK.js.map +1 -0
- package/dist/{kilo-TAHOPT2Q.js → kilo-OU2ZLZKB.js} +4 -4
- package/dist/{kilo-cli-X4NPJWGX.js → kilo-cli-NMWGYF4F.js} +4 -4
- package/dist/{kiro-YZ4TTZGD.js → kiro-4IN5IH46.js} +77 -2
- package/dist/kiro-4IN5IH46.js.map +1 -0
- package/dist/{leaderboard-DVW4WYJ6.js → leaderboard-LF5SP6X2.js} +4 -4
- package/dist/mistral-vibe-TRQDHAWV.js +300 -0
- package/dist/mistral-vibe-TRQDHAWV.js.map +1 -0
- package/dist/open-interpreter-4PKL56AA.js +264 -0
- package/dist/open-interpreter-4PKL56AA.js.map +1 -0
- package/dist/openhands-5LNH3BKB.js +384 -0
- package/dist/openhands-5LNH3BKB.js.map +1 -0
- package/dist/{package-H5V3AZHR.js → package-2EAIYSJ4.js} +7 -7
- package/dist/{pi-I7BLL4EI.js → pi-BUADR5MJ.js} +139 -2
- package/dist/pi-BUADR5MJ.js.map +1 -0
- package/dist/{qwen-code-JG7AF442.js → qwen-code-TUJNHKNI.js} +4 -4
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +7 -7
- package/dist/sdk/index.d.ts +3 -3
- package/dist/sdk/index.js +3 -3
- package/dist/sdk/test.d.ts +2 -2
- package/dist/sdk/test.js +7 -7
- package/dist/{serve-WMO2TUW3.js → serve-K62FW3V7.js} +9 -9
- package/dist/{status-WRLBTBRE.js → status-E5MCFZM6.js} +7 -7
- package/dist/{statusline-EUD4DMIP.js → statusline-LIPF2KVP.js} +8 -8
- package/dist/{telemetry-U3LGMR3D.js → telemetry-4OC56NTM.js} +5 -5
- package/dist/{types-D6RWGXm1.d.ts → types-C4qMgbJn.d.ts} +10 -9
- package/dist/{uninstall-TWPUEJEC.js → uninstall-2YYKN5DX.js} +10 -10
- package/dist/{upgrade-EM6Y7QLH.js → upgrade-55AFPJEF.js} +10 -10
- package/dist/{usage-3HQDTXGY.js → usage-3PB3WZSL.js} +3 -3
- package/dist/{usage-event-DWIGKO7V.js → usage-event-KD5FW6W4.js} +8 -8
- package/dist/{zed-LLOAUXSA.js → zed-ZF2OQ75O.js} +119 -3
- package/dist/zed-ZF2OQ75O.js.map +1 -0
- package/package.json +1 -1
- package/dist/antigravity-cli-KODEKUTM.js +0 -87
- package/dist/antigravity-cli-KODEKUTM.js.map +0 -1
- package/dist/chunk-S4E6QQEM.js.map +0 -1
- package/dist/chunk-X457NOFE.js.map +0 -1
- package/dist/jetbrains-copilot-4IOT3I2Y.js.map +0 -1
- package/dist/kiro-YZ4TTZGD.js.map +0 -1
- package/dist/pi-I7BLL4EI.js.map +0 -1
- package/dist/zed-LLOAUXSA.js.map +0 -1
- /package/dist/{action-OHGFVKMC.js.map → action-L44DXFHT.js.map} +0 -0
- /package/dist/{chunk-VKRGQLY4.js.map → chunk-7HUUINPB.js.map} +0 -0
- /package/dist/{chunk-LKAVD4HP.js.map → chunk-BLTVZACS.js.map} +0 -0
- /package/dist/{chunk-PZHB5TVA.js.map → chunk-G4CEELKO.js.map} +0 -0
- /package/dist/{chunk-VD4EG6SG.js.map → chunk-KIRCPLM4.js.map} +0 -0
- /package/dist/{chunk-ZXX5DVSE.js.map → chunk-LAIITCMW.js.map} +0 -0
- /package/dist/{chunk-UYZ53KWS.js.map → chunk-LF76VPGQ.js.map} +0 -0
- /package/dist/{chunk-IRUYJD23.js.map → chunk-NLE2J5P4.js.map} +0 -0
- /package/dist/{chunk-7NXEHZAK.js.map → chunk-NWLRJNXM.js.map} +0 -0
- /package/dist/{chunk-YJP3KGLM.js.map → chunk-QARPXSIV.js.map} +0 -0
- /package/dist/{chunk-AMK2K6XZ.js.map → chunk-R6LML2YS.js.map} +0 -0
- /package/dist/{claude-code-T6ZRCMA7.js.map → claude-code-WS4NAGZT.js.map} +0 -0
- /package/dist/{codex-RHKQKNNG.js.map → codex-ZZ434GYR.js.map} +0 -0
- /package/dist/{detect-ALAKE54S.js.map → detect-3S46RUMK.js.map} +0 -0
- /package/dist/{doctor-UNF7FCF4.js.map → doctor-3CUBPQKU.js.map} +0 -0
- /package/dist/{hook-GM2IDA3C.js.map → hook-P6EKDINW.js.map} +0 -0
- /package/dist/{install-7O4XWH7T.js.map → install-7DMK53SB.js.map} +0 -0
- /package/dist/{kilo-TAHOPT2Q.js.map → kilo-OU2ZLZKB.js.map} +0 -0
- /package/dist/{kilo-cli-X4NPJWGX.js.map → kilo-cli-NMWGYF4F.js.map} +0 -0
- /package/dist/{leaderboard-DVW4WYJ6.js.map → leaderboard-LF5SP6X2.js.map} +0 -0
- /package/dist/{package-H5V3AZHR.js.map → package-2EAIYSJ4.js.map} +0 -0
- /package/dist/{qwen-code-JG7AF442.js.map → qwen-code-TUJNHKNI.js.map} +0 -0
- /package/dist/{serve-WMO2TUW3.js.map → serve-K62FW3V7.js.map} +0 -0
- /package/dist/{status-WRLBTBRE.js.map → status-E5MCFZM6.js.map} +0 -0
- /package/dist/{statusline-EUD4DMIP.js.map → statusline-LIPF2KVP.js.map} +0 -0
- /package/dist/{telemetry-U3LGMR3D.js.map → telemetry-4OC56NTM.js.map} +0 -0
- /package/dist/{uninstall-TWPUEJEC.js.map → uninstall-2YYKN5DX.js.map} +0 -0
- /package/dist/{upgrade-EM6Y7QLH.js.map → upgrade-55AFPJEF.js.map} +0 -0
- /package/dist/{usage-3HQDTXGY.js.map → usage-3PB3WZSL.js.map} +0 -0
- /package/dist/{usage-event-DWIGKO7V.js.map → usage-event-KD5FW6W4.js.map} +0 -0
|
@@ -0,0 +1,643 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
extractSessionId,
|
|
4
|
+
normalizeSessionSource,
|
|
5
|
+
toolResponseToString
|
|
6
|
+
} from "./chunk-H53QZQJI.js";
|
|
7
|
+
import {
|
|
8
|
+
resolveEnvRefsDeep,
|
|
9
|
+
rewriteEnvRefs
|
|
10
|
+
} from "./chunk-BEFVJ2OE.js";
|
|
11
|
+
import {
|
|
12
|
+
BaseAdapter,
|
|
13
|
+
renderCommandMd,
|
|
14
|
+
renderSkillMd,
|
|
15
|
+
renderSubagentMd
|
|
16
|
+
} from "./chunk-VVFDU4IX.js";
|
|
17
|
+
import {
|
|
18
|
+
buildWrappedStdio,
|
|
19
|
+
isHomeBinHookCommand
|
|
20
|
+
} from "./chunk-HORHRHNG.js";
|
|
21
|
+
import "./chunk-YYNXIUR2.js";
|
|
22
|
+
import "./chunk-IXOQDZWC.js";
|
|
23
|
+
|
|
24
|
+
// src/adapters/codebuddy/index.ts
|
|
25
|
+
import { existsSync } from "fs";
|
|
26
|
+
import { homedir } from "os";
|
|
27
|
+
import { join } from "path";
|
|
28
|
+
var HOST = "codebuddy";
|
|
29
|
+
var MCP_ROOT_KEY = "mcpServers";
|
|
30
|
+
var CONFIG_DIR_ENV = "CODEBUDDY_CONFIG_DIR";
|
|
31
|
+
var CodeBuddyAdapter = class extends BaseAdapter {
|
|
32
|
+
id = HOST;
|
|
33
|
+
name = "CodeBuddy";
|
|
34
|
+
paradigm = "json-stdio";
|
|
35
|
+
capabilities = {
|
|
36
|
+
// CodeBuddy ships the full Claude hook set (bundle-confirmed event names).
|
|
37
|
+
preToolUse: true,
|
|
38
|
+
postToolUse: true,
|
|
39
|
+
preCompact: true,
|
|
40
|
+
sessionStart: true,
|
|
41
|
+
sessionEnd: true,
|
|
42
|
+
userPromptSubmit: true,
|
|
43
|
+
stop: true,
|
|
44
|
+
notification: true,
|
|
45
|
+
permissionRequest: true,
|
|
46
|
+
postToolUseFailure: true,
|
|
47
|
+
subagentStart: true,
|
|
48
|
+
subagentStop: true,
|
|
49
|
+
// Claude-fork reply envelope: PreToolUse can rewrite input (updatedInput);
|
|
50
|
+
// a PostToolUse hook cannot rewrite already-emitted output.
|
|
51
|
+
canModifyArgs: true,
|
|
52
|
+
canModifyOutput: false,
|
|
53
|
+
canInjectSessionContext: true,
|
|
54
|
+
// settings.json hook keys are free-form event names, so any host event
|
|
55
|
+
// declared under platforms["codebuddy"].nativeHooks installs verbatim.
|
|
56
|
+
supportsNativeHooks: true,
|
|
57
|
+
transports: ["stdio", "http"],
|
|
58
|
+
// CodeBuddy preserves Claude's native ${VAR} interpolation in mcpServers
|
|
59
|
+
// env/url, so secret-bearing fields survive into the config (never baked).
|
|
60
|
+
nativeServerEnvInterpolation: true,
|
|
61
|
+
// Content surfaces under <configDir>/{commands,skills,agents}.
|
|
62
|
+
supportsCommands: true,
|
|
63
|
+
supportsSkills: true,
|
|
64
|
+
supportsSubagents: true,
|
|
65
|
+
// Memory surface — EXCEPTION host: CodeBuddy reads CODEBUDDY.md (the fork's
|
|
66
|
+
// CLAUDE.md rename), NOT AGENTS.md, so memoryTargets below overrides the base
|
|
67
|
+
// AGENTS.md-first default.
|
|
68
|
+
supportsMemory: true
|
|
69
|
+
};
|
|
70
|
+
// ── Detection ────────────────────────────────────────────────────────────
|
|
71
|
+
detectInstalled(projectDir) {
|
|
72
|
+
const userDir = this.userConfigDir();
|
|
73
|
+
const userSettings = join(userDir, "settings.json");
|
|
74
|
+
const userServers = join(homedir(), ".codebuddy.json");
|
|
75
|
+
const projectServers = join(projectDir, ".mcp.json");
|
|
76
|
+
const userInstalled = existsSync(userDir) || existsSync(userSettings) || existsSync(userServers);
|
|
77
|
+
const projInstalled = existsSync(projectServers);
|
|
78
|
+
const installed = userInstalled || projInstalled;
|
|
79
|
+
const scope = projInstalled && !userInstalled ? "project" : "user";
|
|
80
|
+
const configPath = scope === "project" ? projectServers : userSettings;
|
|
81
|
+
return {
|
|
82
|
+
id: this.id,
|
|
83
|
+
name: this.name,
|
|
84
|
+
installed,
|
|
85
|
+
paradigm: this.paradigm,
|
|
86
|
+
capabilities: this.capabilities,
|
|
87
|
+
configPath,
|
|
88
|
+
scope,
|
|
89
|
+
reason: installed ? scope === "project" ? `found project CodeBuddy config at ${projectServers}` : `found CodeBuddy config under ${userDir}` : `no CodeBuddy config at ${userDir}`,
|
|
90
|
+
confidence: installed ? "high" : "low"
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// ── Native paths ─────────────────────────────────────────────────────────
|
|
94
|
+
/** User config dir: `$CODEBUDDY_CONFIG_DIR` || `~/.codebuddy`. */
|
|
95
|
+
userConfigDir() {
|
|
96
|
+
const override = process.env[CONFIG_DIR_ENV];
|
|
97
|
+
return override && override.trim() !== "" ? override : join(homedir(), ".codebuddy");
|
|
98
|
+
}
|
|
99
|
+
getConfigDir(ctx) {
|
|
100
|
+
return ctx.scope === "project" ? join(ctx.projectDir, ".codebuddy") : this.userConfigDir();
|
|
101
|
+
}
|
|
102
|
+
getServerConfigPath(ctx) {
|
|
103
|
+
return ctx.scope === "project" ? join(ctx.projectDir, ".mcp.json") : join(homedir(), ".codebuddy.json");
|
|
104
|
+
}
|
|
105
|
+
getHookConfigPath(ctx) {
|
|
106
|
+
return join(this.getConfigDir(ctx), "settings.json");
|
|
107
|
+
}
|
|
108
|
+
// ── MCP server install / uninstall ───────────────────────────────────────
|
|
109
|
+
installServer(ctx) {
|
|
110
|
+
const { connector } = ctx;
|
|
111
|
+
const override = connector.platforms[HOST]?.server;
|
|
112
|
+
if (!connector.server || override === false) {
|
|
113
|
+
return [
|
|
114
|
+
{
|
|
115
|
+
platform: this.id,
|
|
116
|
+
action: "skip",
|
|
117
|
+
detail: connector.server ? "server registration disabled for codebuddy" : "connector declares no MCP server"
|
|
118
|
+
}
|
|
119
|
+
];
|
|
120
|
+
}
|
|
121
|
+
const server = override && typeof override === "object" ? { ...connector.server, ...override } : connector.server;
|
|
122
|
+
const serverPath = this.getServerConfigPath(ctx);
|
|
123
|
+
const entry = this.renderServerEntry(ctx, server);
|
|
124
|
+
return [
|
|
125
|
+
this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun)
|
|
126
|
+
];
|
|
127
|
+
}
|
|
128
|
+
uninstallServer(ctx) {
|
|
129
|
+
const serverPath = this.getServerConfigPath(ctx);
|
|
130
|
+
return [
|
|
131
|
+
this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun)
|
|
132
|
+
];
|
|
133
|
+
}
|
|
134
|
+
/** Render a normalized ServerDef into CodeBuddy's native mcpServers entry. */
|
|
135
|
+
renderServerEntry(ctx, server) {
|
|
136
|
+
const transport = server.transport;
|
|
137
|
+
if (transport === "stdio") {
|
|
138
|
+
let command = server.command ?? "";
|
|
139
|
+
let args = [...server.args ?? []];
|
|
140
|
+
({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));
|
|
141
|
+
const entry2 = { type: "stdio", command, args };
|
|
142
|
+
const env = this.renderEnv(server.env);
|
|
143
|
+
if (env) entry2.env = env;
|
|
144
|
+
if (server.cwd) entry2.cwd = resolveEnvRefsDeep(server.cwd);
|
|
145
|
+
return entry2;
|
|
146
|
+
}
|
|
147
|
+
const entry = {
|
|
148
|
+
type: "http",
|
|
149
|
+
url: rewriteEnvRefs(server.url ?? "", codebuddyEnvToken)
|
|
150
|
+
};
|
|
151
|
+
if (server.headers) {
|
|
152
|
+
entry.headers = this.renderEnv(server.headers) ?? {};
|
|
153
|
+
}
|
|
154
|
+
return entry;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Render env/header values using CodeBuddy's native `${VAR}` interpolation
|
|
158
|
+
* (inherited from Claude Code), so `${env:VAR}` refs survive into the config
|
|
159
|
+
* rather than baking a secret. Literals pass through unchanged.
|
|
160
|
+
*/
|
|
161
|
+
renderEnv(env) {
|
|
162
|
+
if (!env || Object.keys(env).length === 0) return void 0;
|
|
163
|
+
const out = {};
|
|
164
|
+
for (const [k, v] of Object.entries(env)) {
|
|
165
|
+
out[k] = rewriteEnvRefs(v, codebuddyEnvToken);
|
|
166
|
+
}
|
|
167
|
+
return out;
|
|
168
|
+
}
|
|
169
|
+
// ── Hook install / uninstall ─────────────────────────────────────────────
|
|
170
|
+
installHooks(ctx) {
|
|
171
|
+
const { connector } = ctx;
|
|
172
|
+
const override = connector.platforms[HOST];
|
|
173
|
+
const normalizedEvents = override?.hooks === false ? [] : connector.hookEvents;
|
|
174
|
+
const nativeHooks = override?.nativeHooks ?? {};
|
|
175
|
+
const nativeEvents = Object.keys(nativeHooks);
|
|
176
|
+
if (normalizedEvents.length === 0 && nativeEvents.length === 0) {
|
|
177
|
+
return [
|
|
178
|
+
{
|
|
179
|
+
platform: this.id,
|
|
180
|
+
action: "skip",
|
|
181
|
+
detail: override?.hooks === false ? "hooks disabled for codebuddy" : "connector declares no hooks"
|
|
182
|
+
}
|
|
183
|
+
];
|
|
184
|
+
}
|
|
185
|
+
const settingsPath = this.getHookConfigPath(ctx);
|
|
186
|
+
const pending = [
|
|
187
|
+
...normalizedEvents.map((event) => ({
|
|
188
|
+
event,
|
|
189
|
+
matcher: connector.hooks[event]?.matcher ?? ""
|
|
190
|
+
})),
|
|
191
|
+
...nativeEvents.map((event) => ({
|
|
192
|
+
event,
|
|
193
|
+
matcher: nativeHooks[event]?.matcher ?? ""
|
|
194
|
+
}))
|
|
195
|
+
];
|
|
196
|
+
return this.upsertHookEntries(ctx, settingsPath, pending, this.hookDescriptor());
|
|
197
|
+
}
|
|
198
|
+
uninstallHooks(ctx) {
|
|
199
|
+
return this.removeHookEntries(ctx, this.getHookConfigPath(ctx), this.hookDescriptor());
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* CodeBuddy's hook-merge descriptor — the Claude NESTED shape
|
|
203
|
+
* `{ matcher, hooks: [...] }`: install find = THIS command present in the
|
|
204
|
+
* entry's inner `hooks`; uninstall is inner-strip only (drop entries left
|
|
205
|
+
* empty); never remove a whole entry by ownership.
|
|
206
|
+
*/
|
|
207
|
+
hookDescriptor() {
|
|
208
|
+
return {
|
|
209
|
+
renderEntry: (_event, matcher, command) => ({
|
|
210
|
+
matcher,
|
|
211
|
+
hooks: [{ type: "command", command }]
|
|
212
|
+
}),
|
|
213
|
+
entryOwnsCommand: (entry, command) => (entry.hooks ?? []).some((h) => h.command === command),
|
|
214
|
+
ownsEntryForRemove: () => () => false,
|
|
215
|
+
stripInner: (ctx) => (entry) => {
|
|
216
|
+
const innerBefore = entry.hooks?.length ?? 0;
|
|
217
|
+
const inner = (entry.hooks ?? []).filter((h) => !this.isOurCommand(h.command, ctx));
|
|
218
|
+
return {
|
|
219
|
+
next: inner.length > 0 ? { matcher: entry.matcher ?? "", hooks: inner } : null,
|
|
220
|
+
removed: innerBefore - inner.length
|
|
221
|
+
};
|
|
222
|
+
},
|
|
223
|
+
skipDetail: (event) => `hooks.${event} already registered`,
|
|
224
|
+
removeDetail: (event, removed) => `hooks.${event} (${removed})`,
|
|
225
|
+
absentDetail: "no hooks section present",
|
|
226
|
+
noMatchDetail: "no matching hook entries"
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
/** True when a hook command references our home binary AND this connector id. */
|
|
230
|
+
isOurCommand(command, ctx) {
|
|
231
|
+
return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);
|
|
232
|
+
}
|
|
233
|
+
// ── Content surfaces: commands / skills / subagents ──────────────────────
|
|
234
|
+
// Pure native-file writers under <configDir>/{commands,skills,agents}, the
|
|
235
|
+
// fork's confirmed surface dirs. Idempotent (byte-identical → skip) and
|
|
236
|
+
// reversible. Honors platforms["codebuddy"] per-surface `false` to skip.
|
|
237
|
+
commandsDir(ctx) {
|
|
238
|
+
return join(this.getConfigDir(ctx), "commands");
|
|
239
|
+
}
|
|
240
|
+
skillsDir(ctx) {
|
|
241
|
+
return join(this.getConfigDir(ctx), "skills");
|
|
242
|
+
}
|
|
243
|
+
agentsDir(ctx) {
|
|
244
|
+
return join(this.getConfigDir(ctx), "agents");
|
|
245
|
+
}
|
|
246
|
+
commandPath(ctx, name) {
|
|
247
|
+
return join(this.commandsDir(ctx), `${name}.md`);
|
|
248
|
+
}
|
|
249
|
+
skillDir(ctx, name) {
|
|
250
|
+
return join(this.skillsDir(ctx), name);
|
|
251
|
+
}
|
|
252
|
+
subagentPath(ctx, name) {
|
|
253
|
+
return join(this.agentsDir(ctx), `${name}.md`);
|
|
254
|
+
}
|
|
255
|
+
installCommands(ctx) {
|
|
256
|
+
const { connector } = ctx;
|
|
257
|
+
if (connector.platforms[HOST]?.commands === false) {
|
|
258
|
+
return [{ platform: this.id, action: "skip", detail: "commands disabled for codebuddy" }];
|
|
259
|
+
}
|
|
260
|
+
if (connector.commands.length === 0) {
|
|
261
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no commands" }];
|
|
262
|
+
}
|
|
263
|
+
return connector.commands.map(
|
|
264
|
+
(cmd) => this.writeContentFile(this.commandPath(ctx, cmd.name), this.renderCommand(cmd), ctx.dryRun)
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
uninstallCommands(ctx) {
|
|
268
|
+
const { connector } = ctx;
|
|
269
|
+
if (connector.commands.length === 0) {
|
|
270
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no commands" }];
|
|
271
|
+
}
|
|
272
|
+
return connector.commands.map(
|
|
273
|
+
(cmd) => this.removeContentFile(this.commandPath(ctx, cmd.name), ctx.dryRun)
|
|
274
|
+
);
|
|
275
|
+
}
|
|
276
|
+
renderCommand(cmd) {
|
|
277
|
+
return renderCommandMd(cmd);
|
|
278
|
+
}
|
|
279
|
+
installSkills(ctx) {
|
|
280
|
+
const { connector } = ctx;
|
|
281
|
+
if (connector.platforms[HOST]?.skills === false) {
|
|
282
|
+
return [{ platform: this.id, action: "skip", detail: "skills disabled for codebuddy" }];
|
|
283
|
+
}
|
|
284
|
+
if (connector.skills.length === 0) {
|
|
285
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no skills" }];
|
|
286
|
+
}
|
|
287
|
+
const changes = [];
|
|
288
|
+
for (const skill of connector.skills) {
|
|
289
|
+
const dir = this.skillDir(ctx, skill.name);
|
|
290
|
+
changes.push(
|
|
291
|
+
this.writeContentFile(join(dir, "SKILL.md"), this.renderSkill(skill), ctx.dryRun)
|
|
292
|
+
);
|
|
293
|
+
for (const [rel, contents] of Object.entries(skill.resources ?? {})) {
|
|
294
|
+
const target = this.resolveWithin(dir, rel);
|
|
295
|
+
if (target === null) {
|
|
296
|
+
changes.push({
|
|
297
|
+
platform: this.id,
|
|
298
|
+
action: "warn",
|
|
299
|
+
detail: `skill resource "${rel}" escapes the skill dir; skipped`
|
|
300
|
+
});
|
|
301
|
+
continue;
|
|
302
|
+
}
|
|
303
|
+
changes.push(this.writeContentFile(target, contents, ctx.dryRun));
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return changes;
|
|
307
|
+
}
|
|
308
|
+
uninstallSkills(ctx) {
|
|
309
|
+
const { connector } = ctx;
|
|
310
|
+
if (connector.skills.length === 0) {
|
|
311
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no skills" }];
|
|
312
|
+
}
|
|
313
|
+
const changes = [];
|
|
314
|
+
for (const skill of connector.skills) {
|
|
315
|
+
const dir = this.skillDir(ctx, skill.name);
|
|
316
|
+
changes.push(this.removeContentFile(join(dir, "SKILL.md"), ctx.dryRun));
|
|
317
|
+
for (const rel of Object.keys(skill.resources ?? {})) {
|
|
318
|
+
const target = this.resolveWithin(dir, rel);
|
|
319
|
+
if (target === null) continue;
|
|
320
|
+
changes.push(this.removeContentFile(target, ctx.dryRun));
|
|
321
|
+
}
|
|
322
|
+
changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));
|
|
323
|
+
}
|
|
324
|
+
return changes;
|
|
325
|
+
}
|
|
326
|
+
renderSkill(skill) {
|
|
327
|
+
return renderSkillMd(skill);
|
|
328
|
+
}
|
|
329
|
+
installSubagents(ctx) {
|
|
330
|
+
const { connector } = ctx;
|
|
331
|
+
if (connector.platforms[HOST]?.subagents === false) {
|
|
332
|
+
return [{ platform: this.id, action: "skip", detail: "subagents disabled for codebuddy" }];
|
|
333
|
+
}
|
|
334
|
+
if (connector.subagents.length === 0) {
|
|
335
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no subagents" }];
|
|
336
|
+
}
|
|
337
|
+
return connector.subagents.map(
|
|
338
|
+
(agent) => this.writeContentFile(this.subagentPath(ctx, agent.name), this.renderSubagent(agent), ctx.dryRun)
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
uninstallSubagents(ctx) {
|
|
342
|
+
const { connector } = ctx;
|
|
343
|
+
if (connector.subagents.length === 0) {
|
|
344
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no subagents" }];
|
|
345
|
+
}
|
|
346
|
+
return connector.subagents.map(
|
|
347
|
+
(agent) => this.removeContentFile(this.subagentPath(ctx, agent.name), ctx.dryRun)
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
renderSubagent(agent) {
|
|
351
|
+
return renderSubagentMd(agent);
|
|
352
|
+
}
|
|
353
|
+
// ── Memory surface: CODEBUDDY.md managed block ────────────────────────────
|
|
354
|
+
// EXCEPTION host. CodeBuddy reads CODEBUDDY.md (the fork's CLAUDE.md rename),
|
|
355
|
+
// NOT AGENTS.md (bundle-confirmed path list), so the base AGENTS.md-first
|
|
356
|
+
// default is overridden. HTML-comment markers are correct here for the same
|
|
357
|
+
// reason as Claude Code (comment-stripped before context injection). Unlike
|
|
358
|
+
// claude-code this adapter does NOT ship the opt-in agents-import bridge —
|
|
359
|
+
// only the canonical block in the host's own memory file.
|
|
360
|
+
memoryFilePath(ctx) {
|
|
361
|
+
return ctx.scope === "project" ? join(ctx.projectDir, "CODEBUDDY.md") : join(this.userConfigDir(), "CODEBUDDY.md");
|
|
362
|
+
}
|
|
363
|
+
memoryTargets(ctx) {
|
|
364
|
+
if (this.memoryOverride(ctx)?.path) return super.memoryTargets(ctx);
|
|
365
|
+
if (ctx.scope !== "project" && ctx.scope !== "user") return [];
|
|
366
|
+
return [
|
|
367
|
+
{
|
|
368
|
+
path: this.memoryFilePath(ctx),
|
|
369
|
+
reason: "CODEBUDDY.md (CodeBuddy reads CODEBUDDY.md, not AGENTS.md; HTML-comment markers are stripped from the model's context)"
|
|
370
|
+
}
|
|
371
|
+
];
|
|
372
|
+
}
|
|
373
|
+
// ── Diagnostics ──────────────────────────────────────────────────────────
|
|
374
|
+
getHealthChecks(ctx) {
|
|
375
|
+
const settingsPath = this.getHookConfigPath(ctx);
|
|
376
|
+
const connectorId = ctx.connector.id;
|
|
377
|
+
const homeBin = ctx.homeBinPath;
|
|
378
|
+
const declaredHookCount = ctx.connector.hookEvents.length + Object.keys(ctx.connector.platforms[HOST]?.nativeHooks ?? {}).length;
|
|
379
|
+
const checks = [
|
|
380
|
+
{
|
|
381
|
+
name: `${this.name}: settings.json present`,
|
|
382
|
+
check: () => {
|
|
383
|
+
if (declaredHookCount === 0) {
|
|
384
|
+
return { status: "OK", detail: "no hooks declared" };
|
|
385
|
+
}
|
|
386
|
+
return existsSync(settingsPath) ? { status: "OK", detail: settingsPath } : { status: "FAIL", detail: `not found: ${settingsPath}` };
|
|
387
|
+
}
|
|
388
|
+
},
|
|
389
|
+
{
|
|
390
|
+
name: `${this.name}: hook command registered`,
|
|
391
|
+
check: () => {
|
|
392
|
+
if (declaredHookCount === 0) {
|
|
393
|
+
return { status: "OK", detail: "no hooks declared" };
|
|
394
|
+
}
|
|
395
|
+
const settings = this.readJson(
|
|
396
|
+
settingsPath
|
|
397
|
+
);
|
|
398
|
+
if (!settings) return { status: "FAIL", detail: `cannot read ${settingsPath}` };
|
|
399
|
+
const hooks = settings.hooks ?? {};
|
|
400
|
+
const registered = Object.values(hooks).some(
|
|
401
|
+
(entries) => (entries ?? []).some(
|
|
402
|
+
(e) => (e.hooks ?? []).some((h) => isHomeBinHookCommand(h.command, homeBin, connectorId))
|
|
403
|
+
)
|
|
404
|
+
);
|
|
405
|
+
return registered ? { status: "OK", detail: "hook command present" } : { status: "FAIL", detail: `no hook for ${connectorId} in ${settingsPath}` };
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
];
|
|
409
|
+
for (const cmd of ctx.connector.commands) {
|
|
410
|
+
const p = this.commandPath(ctx, cmd.name);
|
|
411
|
+
checks.push({
|
|
412
|
+
name: `${this.name}: command ${cmd.name} present`,
|
|
413
|
+
check: () => existsSync(p) ? { status: "OK", detail: p } : { status: "FAIL", detail: `not found: ${p}` }
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
for (const skill of ctx.connector.skills) {
|
|
417
|
+
const p = join(this.skillDir(ctx, skill.name), "SKILL.md");
|
|
418
|
+
checks.push({
|
|
419
|
+
name: `${this.name}: skill ${skill.name} present`,
|
|
420
|
+
check: () => existsSync(p) ? { status: "OK", detail: p } : { status: "FAIL", detail: `not found: ${p}` }
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
for (const agent of ctx.connector.subagents) {
|
|
424
|
+
const p = this.subagentPath(ctx, agent.name);
|
|
425
|
+
checks.push({
|
|
426
|
+
name: `${this.name}: subagent ${agent.name} present`,
|
|
427
|
+
check: () => existsSync(p) ? { status: "OK", detail: p } : { status: "FAIL", detail: `not found: ${p}` }
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
return checks;
|
|
431
|
+
}
|
|
432
|
+
// ── Runtime: parse CodeBuddy stdin JSON → normalized event ────────────────
|
|
433
|
+
// CodeBuddy's wire is the Claude shape (snake_case fields, PascalCase events),
|
|
434
|
+
// so the claude-code/wire helpers (extractSessionId, toolResponseToString,
|
|
435
|
+
// normalizeSessionSource) apply 1:1.
|
|
436
|
+
parseEvent(event, raw) {
|
|
437
|
+
const input = raw ?? {};
|
|
438
|
+
const connectorId = typeof input.connector === "string" ? input.connector : "";
|
|
439
|
+
const sessionId = extractSessionId(input);
|
|
440
|
+
const projectDir = typeof input.cwd === "string" ? input.cwd : void 0;
|
|
441
|
+
const base = {
|
|
442
|
+
hostPlatform: HOST,
|
|
443
|
+
connectorId,
|
|
444
|
+
sessionId,
|
|
445
|
+
raw,
|
|
446
|
+
...projectDir !== void 0 ? { projectDir } : {}
|
|
447
|
+
};
|
|
448
|
+
switch (event) {
|
|
449
|
+
case "PreToolUse": {
|
|
450
|
+
const ev = {
|
|
451
|
+
...base,
|
|
452
|
+
toolName: input.tool_name ?? "",
|
|
453
|
+
toolInput: input.tool_input ?? {}
|
|
454
|
+
};
|
|
455
|
+
return ev;
|
|
456
|
+
}
|
|
457
|
+
case "PostToolUse": {
|
|
458
|
+
const ev = {
|
|
459
|
+
...base,
|
|
460
|
+
toolName: input.tool_name ?? "",
|
|
461
|
+
toolInput: input.tool_input ?? {},
|
|
462
|
+
...toolResponseToString(input.tool_response) !== void 0 ? { toolOutput: toolResponseToString(input.tool_response) } : {}
|
|
463
|
+
};
|
|
464
|
+
return ev;
|
|
465
|
+
}
|
|
466
|
+
case "SessionStart": {
|
|
467
|
+
const ev = { ...base, source: normalizeSessionSource(input.source) };
|
|
468
|
+
return ev;
|
|
469
|
+
}
|
|
470
|
+
case "SessionEnd": {
|
|
471
|
+
const ev = {
|
|
472
|
+
...base,
|
|
473
|
+
...typeof input.reason === "string" ? { reason: input.reason } : {}
|
|
474
|
+
};
|
|
475
|
+
return ev;
|
|
476
|
+
}
|
|
477
|
+
case "UserPromptSubmit": {
|
|
478
|
+
const ev = {
|
|
479
|
+
...base,
|
|
480
|
+
prompt: typeof input.prompt === "string" ? input.prompt : ""
|
|
481
|
+
};
|
|
482
|
+
return ev;
|
|
483
|
+
}
|
|
484
|
+
case "PreCompact": {
|
|
485
|
+
const ev = {
|
|
486
|
+
...base,
|
|
487
|
+
...input.trigger === "auto" || input.trigger === "manual" ? { trigger: input.trigger } : {}
|
|
488
|
+
};
|
|
489
|
+
return ev;
|
|
490
|
+
}
|
|
491
|
+
case "Stop": {
|
|
492
|
+
const ev = {
|
|
493
|
+
...base,
|
|
494
|
+
...typeof input.stop_hook_active === "boolean" ? { stopHookActive: input.stop_hook_active } : {}
|
|
495
|
+
};
|
|
496
|
+
return ev;
|
|
497
|
+
}
|
|
498
|
+
case "Notification": {
|
|
499
|
+
const ev = {
|
|
500
|
+
...base,
|
|
501
|
+
message: typeof input.message === "string" ? input.message : ""
|
|
502
|
+
};
|
|
503
|
+
return ev;
|
|
504
|
+
}
|
|
505
|
+
case "PermissionRequest": {
|
|
506
|
+
const ev = {
|
|
507
|
+
...base,
|
|
508
|
+
toolName: input.tool_name ?? "",
|
|
509
|
+
toolInput: input.tool_input ?? {},
|
|
510
|
+
...Array.isArray(input.permission_suggestions) ? { permissionSuggestions: input.permission_suggestions } : {}
|
|
511
|
+
};
|
|
512
|
+
return ev;
|
|
513
|
+
}
|
|
514
|
+
case "PostToolUseFailure": {
|
|
515
|
+
const ev = {
|
|
516
|
+
...base,
|
|
517
|
+
toolName: input.tool_name ?? "",
|
|
518
|
+
toolInput: input.tool_input ?? {},
|
|
519
|
+
error: typeof input.error === "string" ? input.error : "",
|
|
520
|
+
...typeof input.tool_use_id === "string" ? { toolUseId: input.tool_use_id } : {},
|
|
521
|
+
...typeof input.is_interrupt === "boolean" ? { isInterrupt: input.is_interrupt } : {},
|
|
522
|
+
...typeof input.duration_ms === "number" ? { durationMs: input.duration_ms } : {}
|
|
523
|
+
};
|
|
524
|
+
return ev;
|
|
525
|
+
}
|
|
526
|
+
case "SubagentStart": {
|
|
527
|
+
const ev = {
|
|
528
|
+
...base,
|
|
529
|
+
...typeof input.agent_id === "string" ? { agentId: input.agent_id } : {},
|
|
530
|
+
...typeof input.agent_type === "string" ? { agentType: input.agent_type } : {}
|
|
531
|
+
};
|
|
532
|
+
return ev;
|
|
533
|
+
}
|
|
534
|
+
case "SubagentStop": {
|
|
535
|
+
const ev = {
|
|
536
|
+
...base,
|
|
537
|
+
...typeof input.agent_id === "string" ? { agentId: input.agent_id } : {},
|
|
538
|
+
...typeof input.agent_type === "string" ? { agentType: input.agent_type } : {},
|
|
539
|
+
...typeof input.agent_transcript_path === "string" ? { agentTranscriptPath: input.agent_transcript_path } : {},
|
|
540
|
+
...typeof input.last_assistant_message === "string" ? { lastAssistantMessage: input.last_assistant_message } : {},
|
|
541
|
+
...typeof input.stop_hook_active === "boolean" ? { stopHookActive: input.stop_hook_active } : {}
|
|
542
|
+
};
|
|
543
|
+
return ev;
|
|
544
|
+
}
|
|
545
|
+
case "PostCompact": {
|
|
546
|
+
const ev = {
|
|
547
|
+
...base,
|
|
548
|
+
...input.trigger === "auto" || input.trigger === "manual" ? { trigger: input.trigger } : {}
|
|
549
|
+
};
|
|
550
|
+
return ev;
|
|
551
|
+
}
|
|
552
|
+
default: {
|
|
553
|
+
const _never = event;
|
|
554
|
+
throw new Error(`unsupported codebuddy hook event: ${String(_never)}`);
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
// ── Runtime: normalized response → CodeBuddy native hook reply ────────────
|
|
559
|
+
// Identical envelope to Claude Code (bundle-confirmed: hookSpecificOutput,
|
|
560
|
+
// permissionDecision/permissionDecisionReason, additionalContext,
|
|
561
|
+
// updatedInput; Stop-class blocks use the top-level decision:"block").
|
|
562
|
+
formatReply(event, response) {
|
|
563
|
+
const hookEventName = event;
|
|
564
|
+
const decision = response.decision ?? "allow";
|
|
565
|
+
if (event === "PermissionRequest") {
|
|
566
|
+
if (response.decision === "deny") {
|
|
567
|
+
return this.stdout({
|
|
568
|
+
hookSpecificOutput: {
|
|
569
|
+
hookEventName,
|
|
570
|
+
decision: { behavior: "deny", message: response.reason ?? "Blocked by hook" }
|
|
571
|
+
}
|
|
572
|
+
});
|
|
573
|
+
}
|
|
574
|
+
if (response.decision === "allow" || response.decision === "modify" && response.updatedInput) {
|
|
575
|
+
return this.stdout({
|
|
576
|
+
hookSpecificOutput: {
|
|
577
|
+
hookEventName,
|
|
578
|
+
decision: {
|
|
579
|
+
behavior: "allow",
|
|
580
|
+
...response.updatedInput ? { updatedInput: response.updatedInput } : {}
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
});
|
|
584
|
+
}
|
|
585
|
+
return { exitCode: 0 };
|
|
586
|
+
}
|
|
587
|
+
if (event === "PostToolUseFailure" || event === "SubagentStart") {
|
|
588
|
+
const context = decision === "context" ? response.additionalContext : decision === "deny" ? response.reason ?? response.additionalContext : void 0;
|
|
589
|
+
if (context) {
|
|
590
|
+
return this.stdout({ hookSpecificOutput: { hookEventName, additionalContext: context } });
|
|
591
|
+
}
|
|
592
|
+
return { exitCode: 0 };
|
|
593
|
+
}
|
|
594
|
+
if (decision === "deny") {
|
|
595
|
+
if (event === "Stop" || event === "SubagentStop" || event === "UserPromptSubmit" || event === "PostToolUse") {
|
|
596
|
+
return this.stdout({ decision: "block", reason: response.reason ?? "Blocked by hook" });
|
|
597
|
+
}
|
|
598
|
+
return this.stdout({
|
|
599
|
+
hookSpecificOutput: {
|
|
600
|
+
hookEventName,
|
|
601
|
+
permissionDecision: "deny",
|
|
602
|
+
permissionDecisionReason: response.reason ?? "Blocked by hook"
|
|
603
|
+
}
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
if (decision === "ask") {
|
|
607
|
+
return this.stdout({
|
|
608
|
+
hookSpecificOutput: {
|
|
609
|
+
hookEventName,
|
|
610
|
+
permissionDecision: "ask",
|
|
611
|
+
permissionDecisionReason: response.reason ?? "Confirmation required by hook"
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
if (decision === "modify") {
|
|
616
|
+
if (event === "PreToolUse" && response.updatedInput) {
|
|
617
|
+
return this.stdout({
|
|
618
|
+
hookSpecificOutput: { hookEventName, updatedInput: response.updatedInput }
|
|
619
|
+
});
|
|
620
|
+
}
|
|
621
|
+
}
|
|
622
|
+
if (decision === "context" && response.additionalContext) {
|
|
623
|
+
return this.stdout({
|
|
624
|
+
hookSpecificOutput: { hookEventName, additionalContext: response.additionalContext }
|
|
625
|
+
});
|
|
626
|
+
}
|
|
627
|
+
return { exitCode: 0 };
|
|
628
|
+
}
|
|
629
|
+
stdout(payload) {
|
|
630
|
+
return { exitCode: 0, stdout: JSON.stringify(payload) };
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
function codebuddyEnvToken(name) {
|
|
634
|
+
return `\${${name}}`;
|
|
635
|
+
}
|
|
636
|
+
var adapter = new CodeBuddyAdapter();
|
|
637
|
+
var codebuddy_default = adapter;
|
|
638
|
+
export {
|
|
639
|
+
CodeBuddyAdapter,
|
|
640
|
+
adapter,
|
|
641
|
+
codebuddy_default as default
|
|
642
|
+
};
|
|
643
|
+
//# sourceMappingURL=codebuddy-RBEZGXBG.js.map
|