@ken-jo/agent-connector 0.1.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/LICENSE +202 -0
- package/NOTICE +6 -0
- package/README.md +348 -0
- package/dist/amp-QSFH2V7Y.js +217 -0
- package/dist/amp-QSFH2V7Y.js.map +1 -0
- package/dist/amp-TULUPXXL.js +237 -0
- package/dist/amp-TULUPXXL.js.map +1 -0
- package/dist/antigravity-CX2YLSY7.js +17 -0
- package/dist/antigravity-CX2YLSY7.js.map +1 -0
- package/dist/antigravity-STHZWMP3.js +171 -0
- package/dist/antigravity-STHZWMP3.js.map +1 -0
- package/dist/antigravity-cli-P6HADOAO.js +121 -0
- package/dist/antigravity-cli-P6HADOAO.js.map +1 -0
- package/dist/antigravity-cli-YQDFVV4U.js +86 -0
- package/dist/antigravity-cli-YQDFVV4U.js.map +1 -0
- package/dist/chunk-54EMKTTX.js +191 -0
- package/dist/chunk-54EMKTTX.js.map +1 -0
- package/dist/chunk-7L6ITC4T.js +54 -0
- package/dist/chunk-7L6ITC4T.js.map +1 -0
- package/dist/chunk-7MSDGHJW.js +316 -0
- package/dist/chunk-7MSDGHJW.js.map +1 -0
- package/dist/chunk-BCHWFTV4.js +196 -0
- package/dist/chunk-BCHWFTV4.js.map +1 -0
- package/dist/chunk-DBQMX75U.js +36 -0
- package/dist/chunk-DBQMX75U.js.map +1 -0
- package/dist/chunk-EXLS7BSI.js +29 -0
- package/dist/chunk-EXLS7BSI.js.map +1 -0
- package/dist/chunk-JNM3TPLX.js +593 -0
- package/dist/chunk-JNM3TPLX.js.map +1 -0
- package/dist/chunk-JWNT5KW7.js +197 -0
- package/dist/chunk-JWNT5KW7.js.map +1 -0
- package/dist/chunk-KHO5WNTP.js +30 -0
- package/dist/chunk-KHO5WNTP.js.map +1 -0
- package/dist/chunk-LTT56GI3.js +155 -0
- package/dist/chunk-LTT56GI3.js.map +1 -0
- package/dist/chunk-MEH7GC7R.js +111 -0
- package/dist/chunk-MEH7GC7R.js.map +1 -0
- package/dist/chunk-MQPNU2CY.js +64 -0
- package/dist/chunk-MQPNU2CY.js.map +1 -0
- package/dist/chunk-OPXAP3AC.js +12 -0
- package/dist/chunk-OPXAP3AC.js.map +1 -0
- package/dist/chunk-RK6VBLXP.js +50 -0
- package/dist/chunk-RK6VBLXP.js.map +1 -0
- package/dist/chunk-TIIP3RG2.js +420 -0
- package/dist/chunk-TIIP3RG2.js.map +1 -0
- package/dist/chunk-TRKWUNO4.js +702 -0
- package/dist/chunk-TRKWUNO4.js.map +1 -0
- package/dist/chunk-TRQKHP7D.js +93 -0
- package/dist/chunk-TRQKHP7D.js.map +1 -0
- package/dist/chunk-WCETQWWK.js +59 -0
- package/dist/chunk-WCETQWWK.js.map +1 -0
- package/dist/chunk-WV63X7IK.js +357 -0
- package/dist/chunk-WV63X7IK.js.map +1 -0
- package/dist/chunk-XD7MY6HB.js +343 -0
- package/dist/chunk-XD7MY6HB.js.map +1 -0
- package/dist/chunk-XNAM7F35.js +276 -0
- package/dist/chunk-XNAM7F35.js.map +1 -0
- package/dist/chunk-XUCWLJY5.js +238 -0
- package/dist/chunk-XUCWLJY5.js.map +1 -0
- package/dist/chunk-YNZU6PAV.js +800 -0
- package/dist/chunk-YNZU6PAV.js.map +1 -0
- package/dist/chunk-YT43MUSJ.js +146 -0
- package/dist/chunk-YT43MUSJ.js.map +1 -0
- package/dist/claude-code-HKDV7T32.js +637 -0
- package/dist/claude-code-HKDV7T32.js.map +1 -0
- package/dist/claude-code-W74MNTAC.js +652 -0
- package/dist/claude-code-W74MNTAC.js.map +1 -0
- package/dist/cli/sdk.d.ts +54 -0
- package/dist/cli/sdk.js +82 -0
- package/dist/cli/sdk.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +15 -0
- package/dist/cli.js.map +1 -0
- package/dist/codebuff-3PMZJJHP.js +307 -0
- package/dist/codebuff-3PMZJJHP.js.map +1 -0
- package/dist/codebuff-QX57FJDN.js +220 -0
- package/dist/codebuff-QX57FJDN.js.map +1 -0
- package/dist/codex-JFQTS6LU.js +593 -0
- package/dist/codex-JFQTS6LU.js.map +1 -0
- package/dist/codex-Q3ATRRX3.js +364 -0
- package/dist/codex-Q3ATRRX3.js.map +1 -0
- package/dist/copilot-cli-MTCGHZ2T.js +622 -0
- package/dist/copilot-cli-MTCGHZ2T.js.map +1 -0
- package/dist/copilot-cli-SJGIXVSD.js +369 -0
- package/dist/copilot-cli-SJGIXVSD.js.map +1 -0
- package/dist/crush-I7PK3FGI.js +360 -0
- package/dist/crush-I7PK3FGI.js.map +1 -0
- package/dist/crush-LN5QFFR2.js +183 -0
- package/dist/crush-LN5QFFR2.js.map +1 -0
- package/dist/cursor-4TMXKJOZ.js +603 -0
- package/dist/cursor-4TMXKJOZ.js.map +1 -0
- package/dist/cursor-QZ6MTO74.js +194 -0
- package/dist/cursor-QZ6MTO74.js.map +1 -0
- package/dist/detect-WIAGVYS4.js +68 -0
- package/dist/detect-WIAGVYS4.js.map +1 -0
- package/dist/doctor-EZW2K4NI.js +372 -0
- package/dist/doctor-EZW2K4NI.js.map +1 -0
- package/dist/droid-KN6VRMMT.js +424 -0
- package/dist/droid-KN6VRMMT.js.map +1 -0
- package/dist/droid-W5WF5XEX.js +224 -0
- package/dist/droid-W5WF5XEX.js.map +1 -0
- package/dist/gemini-cli-CIRW37TU.js +369 -0
- package/dist/gemini-cli-CIRW37TU.js.map +1 -0
- package/dist/gemini-cli-Y35FFK4M.js +705 -0
- package/dist/gemini-cli-Y35FFK4M.js.map +1 -0
- package/dist/goose-A3M5GODH.js +212 -0
- package/dist/goose-A3M5GODH.js.map +1 -0
- package/dist/goose-ZTGTSUFJ.js +480 -0
- package/dist/goose-ZTGTSUFJ.js.map +1 -0
- package/dist/hermes-H2KV44GK.js +470 -0
- package/dist/hermes-H2KV44GK.js.map +1 -0
- package/dist/hermes-ZYLMOFLZ.js +196 -0
- package/dist/hermes-ZYLMOFLZ.js.map +1 -0
- package/dist/hook-YVDILAMZ.js +75 -0
- package/dist/hook-YVDILAMZ.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/install-HQRYZOQ2.js +60 -0
- package/dist/install-HQRYZOQ2.js.map +1 -0
- package/dist/jetbrains-copilot-HWA3DMH7.js +633 -0
- package/dist/jetbrains-copilot-HWA3DMH7.js.map +1 -0
- package/dist/kilo-NSWAVP6P.js +235 -0
- package/dist/kilo-NSWAVP6P.js.map +1 -0
- package/dist/kilo-QXJRCSLT.js +384 -0
- package/dist/kilo-QXJRCSLT.js.map +1 -0
- package/dist/kilo-cli-EAQTHXUW.js +587 -0
- package/dist/kilo-cli-EAQTHXUW.js.map +1 -0
- package/dist/kilo-cli-EVBKUODA.js +160 -0
- package/dist/kilo-cli-EVBKUODA.js.map +1 -0
- package/dist/kimi-EI3UM3ZV.js +155 -0
- package/dist/kimi-EI3UM3ZV.js.map +1 -0
- package/dist/kimi-GQ7VXNYT.js +423 -0
- package/dist/kimi-GQ7VXNYT.js.map +1 -0
- package/dist/kiro-UCLSLBW2.js +217 -0
- package/dist/kiro-UCLSLBW2.js.map +1 -0
- package/dist/kiro-VQTT6LO2.js +451 -0
- package/dist/kiro-VQTT6LO2.js.map +1 -0
- package/dist/leaderboard-K6ON3SWW.js +137 -0
- package/dist/leaderboard-K6ON3SWW.js.map +1 -0
- package/dist/mux-T2TV4CIQ.js +211 -0
- package/dist/mux-T2TV4CIQ.js.map +1 -0
- package/dist/mux-ZMLVAXOO.js +96 -0
- package/dist/mux-ZMLVAXOO.js.map +1 -0
- package/dist/omp-PB4VDKS6.js +586 -0
- package/dist/omp-PB4VDKS6.js.map +1 -0
- package/dist/openclaw-ETN2M63O.js +751 -0
- package/dist/openclaw-ETN2M63O.js.map +1 -0
- package/dist/openclaw-IYA7ASL6.js +150 -0
- package/dist/openclaw-IYA7ASL6.js.map +1 -0
- package/dist/opencode-FZ33JKUZ.js +734 -0
- package/dist/opencode-FZ33JKUZ.js.map +1 -0
- package/dist/opencode-HWT3RSMN.js +216 -0
- package/dist/opencode-HWT3RSMN.js.map +1 -0
- package/dist/package-DLOVE2E4.js +1132 -0
- package/dist/package-DLOVE2E4.js.map +1 -0
- package/dist/pi-CIU2QHT4.js +208 -0
- package/dist/pi-CIU2QHT4.js.map +1 -0
- package/dist/pi-UFX2OYFV.js +139 -0
- package/dist/pi-UFX2OYFV.js.map +1 -0
- package/dist/qwen-code-5POCNU6P.js +573 -0
- package/dist/qwen-code-5POCNU6P.js.map +1 -0
- package/dist/qwen-code-W7NUCDEN.js +134 -0
- package/dist/qwen-code-W7NUCDEN.js.map +1 -0
- package/dist/roo-code-IOIUXRDE.js +242 -0
- package/dist/roo-code-IOIUXRDE.js.map +1 -0
- package/dist/roo-code-ZLKH4A7N.js +229 -0
- package/dist/roo-code-ZLKH4A7N.js.map +1 -0
- package/dist/runtime/index.d.ts +157 -0
- package/dist/runtime/index.js +20 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/serve-HVWWY4B6.js +65 -0
- package/dist/serve-HVWWY4B6.js.map +1 -0
- package/dist/status-FE7TECZD.js +128 -0
- package/dist/status-FE7TECZD.js.map +1 -0
- package/dist/synthetic-UKR6SMGS.js +178 -0
- package/dist/synthetic-UKR6SMGS.js.map +1 -0
- package/dist/telemetry-36GESKQQ.js +349 -0
- package/dist/telemetry-36GESKQQ.js.map +1 -0
- package/dist/trae-JSNDZFKL.js +204 -0
- package/dist/trae-JSNDZFKL.js.map +1 -0
- package/dist/trae-PA26DPBW.js +157 -0
- package/dist/trae-PA26DPBW.js.map +1 -0
- package/dist/types-CYUB1OTr.d.ts +427 -0
- package/dist/uninstall-IGCKNOSF.js +72 -0
- package/dist/uninstall-IGCKNOSF.js.map +1 -0
- package/dist/upgrade-JV2VK242.js +104 -0
- package/dist/upgrade-JV2VK242.js.map +1 -0
- package/dist/usage-6ER6EMEY.js +324 -0
- package/dist/usage-6ER6EMEY.js.map +1 -0
- package/dist/usage-event-JKBI6XCF.js +48 -0
- package/dist/usage-event-JKBI6XCF.js.map +1 -0
- package/dist/vscode-copilot-CK3NO54M.js +715 -0
- package/dist/vscode-copilot-CK3NO54M.js.map +1 -0
- package/dist/warp-JNQA7PBU.js +126 -0
- package/dist/warp-JNQA7PBU.js.map +1 -0
- package/dist/warp-QNVDXOG4.js +199 -0
- package/dist/warp-QNVDXOG4.js.map +1 -0
- package/dist/zed-NNNX5MNT.js +272 -0
- package/dist/zed-NNNX5MNT.js.map +1 -0
- package/dist/zed-VRJKWYUR.js +209 -0
- package/dist/zed-VRJKWYUR.js.map +1 -0
- package/package.json +79 -0
|
@@ -0,0 +1,702 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
resolveEnvRefsDeep
|
|
4
|
+
} from "./chunk-DBQMX75U.js";
|
|
5
|
+
import {
|
|
6
|
+
BaseAdapter
|
|
7
|
+
} from "./chunk-TIIP3RG2.js";
|
|
8
|
+
import {
|
|
9
|
+
buildHomeBinHookCommand,
|
|
10
|
+
buildServeWrapperCommand,
|
|
11
|
+
buildUsageEventCommand,
|
|
12
|
+
isHomeBinHookCommand,
|
|
13
|
+
isHostNativeUsageEnabled,
|
|
14
|
+
isUsageEventCommand,
|
|
15
|
+
shouldWrapForTelemetry
|
|
16
|
+
} from "./chunk-MEH7GC7R.js";
|
|
17
|
+
|
|
18
|
+
// src/adapters/antigravity/index.ts
|
|
19
|
+
import { existsSync } from "fs";
|
|
20
|
+
import { homedir } from "os";
|
|
21
|
+
import { dirname, join } from "path";
|
|
22
|
+
var HOST = "antigravity";
|
|
23
|
+
var MCP_ROOT_KEY = "mcpServers";
|
|
24
|
+
var USER_CONFIG_CANDIDATES = [
|
|
25
|
+
[".gemini", "antigravity", "mcp_config.json"],
|
|
26
|
+
[".gemini", "config", "mcp_config.json"],
|
|
27
|
+
[".gemini", "antigravity-cli", "mcp_config.json"]
|
|
28
|
+
];
|
|
29
|
+
var SUPPORTED_EVENTS = /* @__PURE__ */ new Set([
|
|
30
|
+
"PreToolUse",
|
|
31
|
+
"PostToolUse",
|
|
32
|
+
"SessionStart",
|
|
33
|
+
"Stop"
|
|
34
|
+
]);
|
|
35
|
+
var USAGE_HOOK_EVENT = "AfterModel";
|
|
36
|
+
var AntigravityAdapter = class extends BaseAdapter {
|
|
37
|
+
id = HOST;
|
|
38
|
+
name = "Google Antigravity";
|
|
39
|
+
paradigm = "json-stdio";
|
|
40
|
+
capabilities = {
|
|
41
|
+
// Antigravity 2.0 fires PreToolUse / PostToolUse / SessionStart / Stop.
|
|
42
|
+
preToolUse: true,
|
|
43
|
+
postToolUse: true,
|
|
44
|
+
sessionStart: true,
|
|
45
|
+
stop: true,
|
|
46
|
+
// No documented equivalents — kept false; the corresponding normalized
|
|
47
|
+
// events warn-skip at install time.
|
|
48
|
+
preCompact: false,
|
|
49
|
+
sessionEnd: false,
|
|
50
|
+
userPromptSubmit: false,
|
|
51
|
+
notification: false,
|
|
52
|
+
// Transform-category hooks can rewrite tool input and tool output; the
|
|
53
|
+
// SessionStart hook can inject additional context.
|
|
54
|
+
canModifyArgs: true,
|
|
55
|
+
canModifyOutput: true,
|
|
56
|
+
canInjectSessionContext: true,
|
|
57
|
+
// Antigravity registers stdio, SSE, and Streamable HTTP MCP servers.
|
|
58
|
+
transports: ["stdio", "sse", "http"],
|
|
59
|
+
// Content surfaces: Workflows (markdown commands) + Agent Skills (SKILL.md).
|
|
60
|
+
// Declarative subagents exist only inside a plugin bundle (not emitted), so
|
|
61
|
+
// subagents are unsupported and inherit the BaseAdapter skip/warn default.
|
|
62
|
+
supportsCommands: true,
|
|
63
|
+
supportsSkills: true,
|
|
64
|
+
supportsSubagents: false
|
|
65
|
+
};
|
|
66
|
+
// ── Detection ────────────────────────────────────────────────────────────
|
|
67
|
+
detectInstalled(projectDir) {
|
|
68
|
+
const userConfig = this.resolveUserConfigPath();
|
|
69
|
+
const userDir = join(homedir(), ".gemini");
|
|
70
|
+
const projectConfig = join(projectDir, ".agents", "mcp_config.json");
|
|
71
|
+
const userInstalled = existsSync(userDir) || this.userConfigCandidates().some((parts) => existsSync(join(homedir(), ...parts)));
|
|
72
|
+
const projInstalled = existsSync(projectConfig);
|
|
73
|
+
const installed = userInstalled || projInstalled;
|
|
74
|
+
const scope = projInstalled && !userInstalled ? "project" : "user";
|
|
75
|
+
const configPath = scope === "project" ? projectConfig : userConfig;
|
|
76
|
+
return {
|
|
77
|
+
id: this.id,
|
|
78
|
+
name: this.name,
|
|
79
|
+
installed,
|
|
80
|
+
paradigm: this.paradigm,
|
|
81
|
+
capabilities: this.capabilities,
|
|
82
|
+
configPath,
|
|
83
|
+
scope,
|
|
84
|
+
reason: installed ? scope === "project" ? `found project Antigravity config at ${projectConfig}` : `found Antigravity config under ${userDir}` : `no Antigravity config at ${userDir} or ${projectConfig}`,
|
|
85
|
+
confidence: installed ? "high" : "low"
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
// ── Native paths ─────────────────────────────────────────────────────────
|
|
89
|
+
getConfigDir(ctx) {
|
|
90
|
+
if (ctx.scope === "project") return join(ctx.projectDir, ".agents");
|
|
91
|
+
return dirname(this.resolveUserConfigPath());
|
|
92
|
+
}
|
|
93
|
+
getServerConfigPath(ctx) {
|
|
94
|
+
return ctx.scope === "project" ? join(ctx.projectDir, ".agents", "mcp_config.json") : this.resolveUserConfigPath();
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Hooks live in a SEPARATE hooks.json in the customization dir — NOT the
|
|
98
|
+
* mcp_config.json. Project → <proj>/.agents/hooks.json; user →
|
|
99
|
+
* <resolvedUserConfigDir>/hooks.json (the dir holding the resolved user MCP
|
|
100
|
+
* config). Path is medium-confidence and surfaced by the doctor.
|
|
101
|
+
*/
|
|
102
|
+
getHookConfigPath(ctx) {
|
|
103
|
+
return join(this.getConfigDir(ctx), "hooks.json");
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* The user-scope MCP config candidates, in preference order. Overridable by
|
|
107
|
+
* forks (e.g. the Antigravity CLI) that resolve a different user-scope root
|
|
108
|
+
* while reusing resolveUserConfigPath's prefer-existing-else-candidate[0] logic.
|
|
109
|
+
*/
|
|
110
|
+
userConfigCandidates() {
|
|
111
|
+
return USER_CONFIG_CANDIDATES;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Pick the user-scope mcp_config.json: prefer a candidate that already exists,
|
|
115
|
+
* else default to candidate[0] (the CONFIRMED canonical ~/.gemini/antigravity path).
|
|
116
|
+
*/
|
|
117
|
+
resolveUserConfigPath() {
|
|
118
|
+
const home = homedir();
|
|
119
|
+
const candidates = this.userConfigCandidates();
|
|
120
|
+
for (const parts of candidates) {
|
|
121
|
+
const p = join(home, ...parts);
|
|
122
|
+
if (existsSync(p)) return p;
|
|
123
|
+
}
|
|
124
|
+
const fallback = candidates[0];
|
|
125
|
+
if (fallback === void 0) {
|
|
126
|
+
return join(home, ".gemini", "antigravity", "mcp_config.json");
|
|
127
|
+
}
|
|
128
|
+
return join(home, ...fallback);
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Resolve the Workflows (slash-command) dir, prefer-existing-else-canonical.
|
|
132
|
+
* project → prefer existing <proj>/.agent/workflows or <proj>/.agents/workflows;
|
|
133
|
+
* default .agent/workflows (launch-era singular `.agent`).
|
|
134
|
+
* user → ~/.gemini/antigravity/global_workflows.
|
|
135
|
+
*/
|
|
136
|
+
resolveWorkflowsDir(ctx) {
|
|
137
|
+
if (ctx.scope === "project") {
|
|
138
|
+
const singular = join(ctx.projectDir, ".agent", "workflows");
|
|
139
|
+
const plural = join(ctx.projectDir, ".agents", "workflows");
|
|
140
|
+
if (existsSync(singular)) return singular;
|
|
141
|
+
if (existsSync(plural)) return plural;
|
|
142
|
+
return singular;
|
|
143
|
+
}
|
|
144
|
+
return join(homedir(), ".gemini", "antigravity", "global_workflows");
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Resolve the Agent Skills dir, prefer-existing-else-canonical.
|
|
148
|
+
* project → <proj>/.agents/skills (plural — matches mcp/skills convention).
|
|
149
|
+
* user → prefer existing ~/.gemini/antigravity-cli/skills, else
|
|
150
|
+
* ~/.gemini/skills. NEVER ~/.gemini/antigravity/skills
|
|
151
|
+
* (reportedly broken), so it is not a candidate.
|
|
152
|
+
*/
|
|
153
|
+
resolveSkillsDir(ctx) {
|
|
154
|
+
if (ctx.scope === "project") {
|
|
155
|
+
return join(ctx.projectDir, ".agents", "skills");
|
|
156
|
+
}
|
|
157
|
+
const home = homedir();
|
|
158
|
+
const cliSkills = join(home, ".gemini", "antigravity-cli", "skills");
|
|
159
|
+
const sharedSkills = join(home, ".gemini", "skills");
|
|
160
|
+
if (existsSync(cliSkills)) return cliSkills;
|
|
161
|
+
if (existsSync(sharedSkills)) return sharedSkills;
|
|
162
|
+
return cliSkills;
|
|
163
|
+
}
|
|
164
|
+
// ── MCP server install / uninstall ───────────────────────────────────────
|
|
165
|
+
installServer(ctx) {
|
|
166
|
+
const { connector } = ctx;
|
|
167
|
+
const override = connector.platforms[this.id]?.server;
|
|
168
|
+
if (!connector.server || override === false) {
|
|
169
|
+
return [
|
|
170
|
+
{
|
|
171
|
+
platform: this.id,
|
|
172
|
+
action: "skip",
|
|
173
|
+
detail: connector.server ? `server registration disabled for ${this.id}` : "connector declares no MCP server"
|
|
174
|
+
}
|
|
175
|
+
];
|
|
176
|
+
}
|
|
177
|
+
const server = override && typeof override === "object" ? { ...connector.server, ...override } : connector.server;
|
|
178
|
+
const serverPath = this.getServerConfigPath(ctx);
|
|
179
|
+
const entry = this.renderServerEntry(ctx, server);
|
|
180
|
+
return [
|
|
181
|
+
this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun)
|
|
182
|
+
];
|
|
183
|
+
}
|
|
184
|
+
uninstallServer(ctx) {
|
|
185
|
+
const serverPath = this.getServerConfigPath(ctx);
|
|
186
|
+
return [
|
|
187
|
+
this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun)
|
|
188
|
+
];
|
|
189
|
+
}
|
|
190
|
+
/** Render a normalized ServerDef into Antigravity's native mcpServers entry. */
|
|
191
|
+
renderServerEntry(ctx, server) {
|
|
192
|
+
const transport = server.transport;
|
|
193
|
+
if (transport === "stdio") {
|
|
194
|
+
let command = server.command ?? "";
|
|
195
|
+
let args = [...server.args ?? []];
|
|
196
|
+
if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {
|
|
197
|
+
const wrapped = buildServeWrapperCommand(
|
|
198
|
+
ctx.homeBinPath,
|
|
199
|
+
ctx.connector.id,
|
|
200
|
+
command,
|
|
201
|
+
args,
|
|
202
|
+
ctx.scope,
|
|
203
|
+
this.id
|
|
204
|
+
);
|
|
205
|
+
command = wrapped.command;
|
|
206
|
+
args = wrapped.args;
|
|
207
|
+
}
|
|
208
|
+
const entry2 = { command: resolveEnvRefsDeep(command) };
|
|
209
|
+
if (args.length > 0) entry2.args = resolveEnvRefsDeep(args);
|
|
210
|
+
const env = this.renderEnv(server.env);
|
|
211
|
+
if (env) entry2.env = env;
|
|
212
|
+
return entry2;
|
|
213
|
+
}
|
|
214
|
+
const entry = { serverUrl: resolveEnvRefsDeep(server.url ?? "") };
|
|
215
|
+
const headers = this.renderEnv(server.headers);
|
|
216
|
+
if (headers) entry.headers = headers;
|
|
217
|
+
return entry;
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* Render env/header values. Antigravity documents no native interpolation
|
|
221
|
+
* token, so resolve `${env:VAR}` references to literals at install time.
|
|
222
|
+
*/
|
|
223
|
+
renderEnv(env) {
|
|
224
|
+
if (!env || Object.keys(env).length === 0) return void 0;
|
|
225
|
+
return resolveEnvRefsDeep({ ...env });
|
|
226
|
+
}
|
|
227
|
+
// ── Hook install / uninstall ─────────────────────────────────────────────
|
|
228
|
+
installHooks(ctx) {
|
|
229
|
+
const { connector } = ctx;
|
|
230
|
+
if (connector.platforms[this.id]?.hooks === false) {
|
|
231
|
+
return [{ platform: this.id, action: "skip", detail: `hooks disabled for ${this.id}` }];
|
|
232
|
+
}
|
|
233
|
+
const hostNative = isHostNativeUsageEnabled(connector.telemetry);
|
|
234
|
+
if (connector.hookEvents.length === 0 && !hostNative) {
|
|
235
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no hooks" }];
|
|
236
|
+
}
|
|
237
|
+
const hooksPath = this.getHookConfigPath(ctx);
|
|
238
|
+
if (this.isPresentButUnparseable(hooksPath)) {
|
|
239
|
+
return [
|
|
240
|
+
{
|
|
241
|
+
platform: this.id,
|
|
242
|
+
action: "warn",
|
|
243
|
+
path: hooksPath,
|
|
244
|
+
detail: `existing ${hooksPath} is not parseable; left untouched (back it up / fix it, then re-run)`
|
|
245
|
+
}
|
|
246
|
+
];
|
|
247
|
+
}
|
|
248
|
+
const file = this.readJson(hooksPath) ?? {};
|
|
249
|
+
const hooks = file.hooks ??= {};
|
|
250
|
+
const changes = [];
|
|
251
|
+
let mutated = false;
|
|
252
|
+
for (const event of connector.hookEvents) {
|
|
253
|
+
if (!SUPPORTED_EVENTS.has(event)) {
|
|
254
|
+
changes.push({
|
|
255
|
+
platform: this.id,
|
|
256
|
+
action: "warn",
|
|
257
|
+
path: hooksPath,
|
|
258
|
+
detail: `${event} has no Antigravity hook equivalent \u2014 skipped`
|
|
259
|
+
});
|
|
260
|
+
continue;
|
|
261
|
+
}
|
|
262
|
+
const command = buildHomeBinHookCommand(ctx.homeBinPath, this.id, event, connector.id);
|
|
263
|
+
const matcher = connector.hooks[event]?.matcher ?? "";
|
|
264
|
+
const entry = {
|
|
265
|
+
matcher,
|
|
266
|
+
hooks: [{ type: "command", command }]
|
|
267
|
+
};
|
|
268
|
+
const bucket = hooks[event] ??= [];
|
|
269
|
+
const existingIdx = bucket.findIndex((e) => this.entryHasOurCommand(e, ctx));
|
|
270
|
+
if (existingIdx >= 0) {
|
|
271
|
+
if (JSON.stringify(bucket[existingIdx]) === JSON.stringify(entry)) {
|
|
272
|
+
changes.push({
|
|
273
|
+
platform: this.id,
|
|
274
|
+
action: "skip",
|
|
275
|
+
path: hooksPath,
|
|
276
|
+
detail: `hooks.${event} already registered`
|
|
277
|
+
});
|
|
278
|
+
continue;
|
|
279
|
+
}
|
|
280
|
+
bucket[existingIdx] = entry;
|
|
281
|
+
changes.push({
|
|
282
|
+
platform: this.id,
|
|
283
|
+
action: "update",
|
|
284
|
+
path: hooksPath,
|
|
285
|
+
detail: `hooks.${event}`
|
|
286
|
+
});
|
|
287
|
+
} else {
|
|
288
|
+
bucket.push(entry);
|
|
289
|
+
changes.push({
|
|
290
|
+
platform: this.id,
|
|
291
|
+
action: "create",
|
|
292
|
+
path: hooksPath,
|
|
293
|
+
detail: `hooks.${event}`
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
mutated = true;
|
|
297
|
+
}
|
|
298
|
+
if (hostNative) {
|
|
299
|
+
if (this.installUsageHook(hooks, ctx, hooksPath, changes)) mutated = true;
|
|
300
|
+
}
|
|
301
|
+
if (mutated) this.writeJson(hooksPath, file, ctx.dryRun);
|
|
302
|
+
return changes;
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Register the opt-in AfterModel host-native usage hook (4a) into `hooks`.
|
|
306
|
+
* Idempotent (byte-identical → skip, drift → update); returns true on mutation.
|
|
307
|
+
* The command is the hidden `usage-event` entrypoint (NOT a connector hook), so
|
|
308
|
+
* it carries an empty matcher. Reads `this.id` so the CLI fork installs its own
|
|
309
|
+
* `usage-event antigravity-cli …` variant.
|
|
310
|
+
*/
|
|
311
|
+
installUsageHook(hooks, ctx, hooksPath, changes) {
|
|
312
|
+
const command = buildUsageEventCommand(ctx.homeBinPath, this.id, ctx.connector.id);
|
|
313
|
+
const entry = {
|
|
314
|
+
matcher: "",
|
|
315
|
+
hooks: [{ type: "command", command }]
|
|
316
|
+
};
|
|
317
|
+
const bucket = hooks[USAGE_HOOK_EVENT] ??= [];
|
|
318
|
+
const existingIdx = bucket.findIndex(
|
|
319
|
+
(e) => (e.hooks ?? []).some((h) => isUsageEventCommand(h.command, ctx.homeBinPath, ctx.connector.id))
|
|
320
|
+
);
|
|
321
|
+
if (existingIdx >= 0) {
|
|
322
|
+
if (JSON.stringify(bucket[existingIdx]) === JSON.stringify(entry)) {
|
|
323
|
+
changes.push({
|
|
324
|
+
platform: this.id,
|
|
325
|
+
action: "skip",
|
|
326
|
+
path: hooksPath,
|
|
327
|
+
detail: `hooks.${USAGE_HOOK_EVENT} (host-native usage) already registered`
|
|
328
|
+
});
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
331
|
+
bucket[existingIdx] = entry;
|
|
332
|
+
changes.push({
|
|
333
|
+
platform: this.id,
|
|
334
|
+
action: "update",
|
|
335
|
+
path: hooksPath,
|
|
336
|
+
detail: `hooks.${USAGE_HOOK_EVENT} (host-native usage)`
|
|
337
|
+
});
|
|
338
|
+
} else {
|
|
339
|
+
bucket.push(entry);
|
|
340
|
+
changes.push({
|
|
341
|
+
platform: this.id,
|
|
342
|
+
action: "create",
|
|
343
|
+
path: hooksPath,
|
|
344
|
+
detail: `hooks.${USAGE_HOOK_EVENT} (host-native usage)`
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
return true;
|
|
348
|
+
}
|
|
349
|
+
uninstallHooks(ctx) {
|
|
350
|
+
const hooksPath = this.getHookConfigPath(ctx);
|
|
351
|
+
const file = this.readJson(hooksPath);
|
|
352
|
+
const hooks = file?.hooks;
|
|
353
|
+
if (!file || !hooks) {
|
|
354
|
+
return [
|
|
355
|
+
{
|
|
356
|
+
platform: this.id,
|
|
357
|
+
action: "skip",
|
|
358
|
+
path: hooksPath,
|
|
359
|
+
detail: "no hooks section present"
|
|
360
|
+
}
|
|
361
|
+
];
|
|
362
|
+
}
|
|
363
|
+
const changes = [];
|
|
364
|
+
let mutated = false;
|
|
365
|
+
for (const event of Object.keys(hooks)) {
|
|
366
|
+
const bucket = hooks[event];
|
|
367
|
+
if (!Array.isArray(bucket)) continue;
|
|
368
|
+
const next = [];
|
|
369
|
+
let removed = 0;
|
|
370
|
+
for (const e of bucket) {
|
|
371
|
+
const innerBefore = e.hooks?.length ?? 0;
|
|
372
|
+
const inner = (e.hooks ?? []).filter((h) => !this.isOurCommand(h.command, ctx));
|
|
373
|
+
removed += innerBefore - inner.length;
|
|
374
|
+
if (inner.length > 0) next.push({ matcher: e.matcher ?? "", hooks: inner });
|
|
375
|
+
}
|
|
376
|
+
if (removed > 0) {
|
|
377
|
+
if (next.length > 0) hooks[event] = next;
|
|
378
|
+
else delete hooks[event];
|
|
379
|
+
changes.push({
|
|
380
|
+
platform: this.id,
|
|
381
|
+
action: "remove",
|
|
382
|
+
path: hooksPath,
|
|
383
|
+
detail: `hooks.${event} (${removed})`
|
|
384
|
+
});
|
|
385
|
+
mutated = true;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
if (mutated) this.writeJson(hooksPath, file, ctx.dryRun);
|
|
389
|
+
if (changes.length === 0) {
|
|
390
|
+
changes.push({
|
|
391
|
+
platform: this.id,
|
|
392
|
+
action: "skip",
|
|
393
|
+
path: hooksPath,
|
|
394
|
+
detail: "no matching hook entries"
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
return changes;
|
|
398
|
+
}
|
|
399
|
+
entryHasOurCommand(entry, ctx) {
|
|
400
|
+
return (entry.hooks ?? []).some((h) => this.isOurCommand(h.command, ctx));
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* True when a hook command is ONE OF OURS for this connector — the universal
|
|
404
|
+
* `hook` dispatcher OR the opt-in `usage-event` sink. Both are anchored on the
|
|
405
|
+
* connector id (see isHomeBinHookCommand) so a shared-prefix id can't collide,
|
|
406
|
+
* and so uninstall reverses the AfterModel usage hook too.
|
|
407
|
+
*/
|
|
408
|
+
isOurCommand(command, ctx) {
|
|
409
|
+
return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id) || isUsageEventCommand(command, ctx.homeBinPath, ctx.connector.id);
|
|
410
|
+
}
|
|
411
|
+
// ── Content surfaces: commands (Workflows) / skills ───────────────────────
|
|
412
|
+
// CONTENT-ONLY: pure native-file writers under the probed workflows / skills
|
|
413
|
+
// dirs. No runtime dispatch, no home-bin pointer, no telemetry wrap. Each
|
|
414
|
+
// method is idempotent (byte-identical → skip) via BaseAdapter.writeContentFile
|
|
415
|
+
// and reversible via removeContentFile. Honors platforms["antigravity"]
|
|
416
|
+
// per-surface false to skip. Commands are markdown Workflows (NOT TOML, unlike
|
|
417
|
+
// gemini-cli); skills are the uniform Claude-compatible SKILL.md. Subagents are
|
|
418
|
+
// unsupported (plugin-bundle-only) and inherit the BaseAdapter skip/warn.
|
|
419
|
+
/** Native Workflow file path: <workflowsDir>/<name>.md. */
|
|
420
|
+
commandPath(ctx, name) {
|
|
421
|
+
return join(this.resolveWorkflowsDir(ctx), `${name}.md`);
|
|
422
|
+
}
|
|
423
|
+
/** Native skill dir: <skillsDir>/<name>. */
|
|
424
|
+
skillDir(ctx, name) {
|
|
425
|
+
return join(this.resolveSkillsDir(ctx), name);
|
|
426
|
+
}
|
|
427
|
+
// ── Commands (Workflows) ──────────────────────────────────────────────────
|
|
428
|
+
installCommands(ctx) {
|
|
429
|
+
const { connector } = ctx;
|
|
430
|
+
if (connector.platforms[this.id]?.commands === false) {
|
|
431
|
+
return [{ platform: this.id, action: "skip", detail: `commands disabled for ${this.id}` }];
|
|
432
|
+
}
|
|
433
|
+
if (connector.commands.length === 0) {
|
|
434
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no commands" }];
|
|
435
|
+
}
|
|
436
|
+
return connector.commands.map(
|
|
437
|
+
(cmd) => this.writeContentFile(this.commandPath(ctx, cmd.name), this.renderCommand(cmd), ctx.dryRun)
|
|
438
|
+
);
|
|
439
|
+
}
|
|
440
|
+
uninstallCommands(ctx) {
|
|
441
|
+
const { connector } = ctx;
|
|
442
|
+
if (connector.commands.length === 0) {
|
|
443
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no commands" }];
|
|
444
|
+
}
|
|
445
|
+
return connector.commands.map(
|
|
446
|
+
(cmd) => this.removeContentFile(this.commandPath(ctx, cmd.name), ctx.dryRun)
|
|
447
|
+
);
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* Render a command to an Antigravity Workflow: a plain markdown `.md` whose
|
|
451
|
+
* body is the command prompt, optionally preceded by a leading description
|
|
452
|
+
* line. No frontmatter / TOML (unlike gemini-cli).
|
|
453
|
+
*/
|
|
454
|
+
renderCommand(cmd) {
|
|
455
|
+
const body = cmd.prompt.endsWith("\n") ? cmd.prompt : `${cmd.prompt}
|
|
456
|
+
`;
|
|
457
|
+
if (cmd.description !== void 0 && cmd.description !== "") {
|
|
458
|
+
return `${cmd.description}
|
|
459
|
+
|
|
460
|
+
${body}`;
|
|
461
|
+
}
|
|
462
|
+
return body;
|
|
463
|
+
}
|
|
464
|
+
// ── Skills ────────────────────────────────────────────────────────────────
|
|
465
|
+
installSkills(ctx) {
|
|
466
|
+
const { connector } = ctx;
|
|
467
|
+
if (connector.platforms[this.id]?.skills === false) {
|
|
468
|
+
return [{ platform: this.id, action: "skip", detail: `skills disabled for ${this.id}` }];
|
|
469
|
+
}
|
|
470
|
+
if (connector.skills.length === 0) {
|
|
471
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no skills" }];
|
|
472
|
+
}
|
|
473
|
+
const changes = [];
|
|
474
|
+
for (const skill of connector.skills) {
|
|
475
|
+
const dir = this.skillDir(ctx, skill.name);
|
|
476
|
+
changes.push(
|
|
477
|
+
this.writeContentFile(join(dir, "SKILL.md"), this.renderSkill(skill), ctx.dryRun)
|
|
478
|
+
);
|
|
479
|
+
for (const [rel, contents] of Object.entries(skill.resources ?? {})) {
|
|
480
|
+
const target = this.resolveWithin(dir, rel);
|
|
481
|
+
if (target === null) {
|
|
482
|
+
changes.push({
|
|
483
|
+
platform: this.id,
|
|
484
|
+
action: "warn",
|
|
485
|
+
detail: `skill resource "${rel}" escapes the skill dir; skipped`
|
|
486
|
+
});
|
|
487
|
+
continue;
|
|
488
|
+
}
|
|
489
|
+
changes.push(this.writeContentFile(target, contents, ctx.dryRun));
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
return changes;
|
|
493
|
+
}
|
|
494
|
+
uninstallSkills(ctx) {
|
|
495
|
+
const { connector } = ctx;
|
|
496
|
+
if (connector.skills.length === 0) {
|
|
497
|
+
return [{ platform: this.id, action: "skip", detail: "connector declares no skills" }];
|
|
498
|
+
}
|
|
499
|
+
const changes = [];
|
|
500
|
+
for (const skill of connector.skills) {
|
|
501
|
+
const dir = this.skillDir(ctx, skill.name);
|
|
502
|
+
changes.push(this.removeContentFile(join(dir, "SKILL.md"), ctx.dryRun));
|
|
503
|
+
for (const rel of Object.keys(skill.resources ?? {})) {
|
|
504
|
+
const target = this.resolveWithin(dir, rel);
|
|
505
|
+
if (target === null) continue;
|
|
506
|
+
changes.push(this.removeContentFile(target, ctx.dryRun));
|
|
507
|
+
}
|
|
508
|
+
changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));
|
|
509
|
+
}
|
|
510
|
+
return changes;
|
|
511
|
+
}
|
|
512
|
+
/**
|
|
513
|
+
* Render a skill's SKILL.md: frontmatter (name, description + optional model,
|
|
514
|
+
* allowed-tools, disable-model-invocation) + body. Uniform across platforms.
|
|
515
|
+
*/
|
|
516
|
+
renderSkill(skill) {
|
|
517
|
+
const frontmatter = {
|
|
518
|
+
name: skill.name,
|
|
519
|
+
description: skill.description
|
|
520
|
+
};
|
|
521
|
+
if (skill.model !== void 0) frontmatter.model = skill.model;
|
|
522
|
+
const allow = skill.tools?.allow;
|
|
523
|
+
if (allow && allow.length > 0) frontmatter["allowed-tools"] = allow.join(", ");
|
|
524
|
+
if (skill.disableModelInvocation !== void 0) {
|
|
525
|
+
frontmatter["disable-model-invocation"] = skill.disableModelInvocation;
|
|
526
|
+
}
|
|
527
|
+
if (skill.extra) Object.assign(frontmatter, skill.extra);
|
|
528
|
+
return this.renderFrontmatterMd(frontmatter, skill.body);
|
|
529
|
+
}
|
|
530
|
+
// ── Diagnostics ──────────────────────────────────────────────────────────
|
|
531
|
+
getHealthChecks(ctx) {
|
|
532
|
+
const mcpPath = this.getServerConfigPath(ctx);
|
|
533
|
+
const hooksPath = this.getHookConfigPath(ctx);
|
|
534
|
+
const connectorId = ctx.connector.id;
|
|
535
|
+
const homeBin = ctx.homeBinPath;
|
|
536
|
+
const hookEvents = ctx.connector.hookEvents;
|
|
537
|
+
const workflowsDir = this.resolveWorkflowsDir(ctx);
|
|
538
|
+
const skillsDir = this.resolveSkillsDir(ctx);
|
|
539
|
+
const checks = [
|
|
540
|
+
{
|
|
541
|
+
name: `${this.name}: mcp_config.json present`,
|
|
542
|
+
check: () => existsSync(mcpPath) ? { status: "OK", detail: `${mcpPath} (path probed; verify for your Antigravity version)` } : { status: "FAIL", detail: `not found: ${mcpPath} (path probed; verify for your Antigravity version)` }
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
name: `${this.name}: server entry registered`,
|
|
546
|
+
check: () => {
|
|
547
|
+
const cfg = this.readJson(mcpPath);
|
|
548
|
+
const bucket = cfg?.[MCP_ROOT_KEY];
|
|
549
|
+
if (!cfg || !bucket) {
|
|
550
|
+
return { status: "FAIL", detail: `no ${MCP_ROOT_KEY} in ${mcpPath}` };
|
|
551
|
+
}
|
|
552
|
+
return connectorId in bucket ? { status: "OK", detail: `${MCP_ROOT_KEY}.${connectorId} present` } : {
|
|
553
|
+
status: "FAIL",
|
|
554
|
+
detail: `no ${MCP_ROOT_KEY}.${connectorId} in ${mcpPath}`
|
|
555
|
+
};
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
{
|
|
559
|
+
name: `${this.name}: hooks.json hook command registered`,
|
|
560
|
+
check: () => {
|
|
561
|
+
if (hookEvents.length === 0) {
|
|
562
|
+
return { status: "OK", detail: "no hooks declared" };
|
|
563
|
+
}
|
|
564
|
+
const file = this.readJson(hooksPath);
|
|
565
|
+
if (!file) {
|
|
566
|
+
return {
|
|
567
|
+
status: "FAIL",
|
|
568
|
+
detail: `not found: ${hooksPath} (path probed; verify for your Antigravity version)`
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
const hooks = file.hooks ?? {};
|
|
572
|
+
const registered = Object.values(hooks).some(
|
|
573
|
+
(entries) => (entries ?? []).some(
|
|
574
|
+
(e) => (e.hooks ?? []).some(
|
|
575
|
+
(h) => isHomeBinHookCommand(h.command, homeBin, connectorId)
|
|
576
|
+
)
|
|
577
|
+
)
|
|
578
|
+
);
|
|
579
|
+
return registered ? { status: "OK", detail: `hook command present in ${hooksPath}` } : { status: "FAIL", detail: `no hook for ${connectorId} in ${hooksPath}` };
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
];
|
|
583
|
+
for (const cmd of ctx.connector.commands) {
|
|
584
|
+
const p = join(workflowsDir, `${cmd.name}.md`);
|
|
585
|
+
checks.push({
|
|
586
|
+
name: `${this.name}: workflow ${cmd.name} present`,
|
|
587
|
+
check: () => existsSync(p) ? { status: "OK", detail: `${p} (workflows dir probed; verify for your version)` } : { status: "FAIL", detail: `not found: ${p} (workflows dir probed; verify for your version)` }
|
|
588
|
+
});
|
|
589
|
+
}
|
|
590
|
+
for (const skill of ctx.connector.skills) {
|
|
591
|
+
const p = join(skillsDir, skill.name, "SKILL.md");
|
|
592
|
+
checks.push({
|
|
593
|
+
name: `${this.name}: skill ${skill.name} present`,
|
|
594
|
+
check: () => existsSync(p) ? { status: "OK", detail: `${p} (skills dir probed; verify for your version)` } : { status: "FAIL", detail: `not found: ${p} (skills dir probed; verify for your version)` }
|
|
595
|
+
});
|
|
596
|
+
}
|
|
597
|
+
return checks;
|
|
598
|
+
}
|
|
599
|
+
// ── Runtime: parse Antigravity stdin JSON → normalized event ──────────────
|
|
600
|
+
parseEvent(event, raw) {
|
|
601
|
+
const input = raw ?? {};
|
|
602
|
+
const connectorId = typeof input.connector === "string" ? input.connector : "";
|
|
603
|
+
const sessionId = typeof input.sessionId === "string" ? input.sessionId : "";
|
|
604
|
+
const projectDir = typeof input.cwd === "string" ? input.cwd : void 0;
|
|
605
|
+
const base = {
|
|
606
|
+
hostPlatform: this.id,
|
|
607
|
+
connectorId,
|
|
608
|
+
sessionId,
|
|
609
|
+
raw,
|
|
610
|
+
...projectDir !== void 0 ? { projectDir } : {}
|
|
611
|
+
};
|
|
612
|
+
switch (event) {
|
|
613
|
+
case "PreToolUse": {
|
|
614
|
+
const ev = {
|
|
615
|
+
...base,
|
|
616
|
+
toolName: input.toolName ?? "",
|
|
617
|
+
toolInput: input.toolInput ?? {}
|
|
618
|
+
};
|
|
619
|
+
return ev;
|
|
620
|
+
}
|
|
621
|
+
case "PostToolUse": {
|
|
622
|
+
const ev = {
|
|
623
|
+
...base,
|
|
624
|
+
toolName: input.toolName ?? "",
|
|
625
|
+
toolInput: input.toolInput ?? {},
|
|
626
|
+
...input.toolOutput !== void 0 ? { toolOutput: input.toolOutput } : {},
|
|
627
|
+
...input.isError === true ? { isError: true } : {}
|
|
628
|
+
};
|
|
629
|
+
return ev;
|
|
630
|
+
}
|
|
631
|
+
case "SessionStart": {
|
|
632
|
+
const ev = {
|
|
633
|
+
...base,
|
|
634
|
+
source: normalizeSessionSource(input.source)
|
|
635
|
+
};
|
|
636
|
+
return ev;
|
|
637
|
+
}
|
|
638
|
+
case "Stop": {
|
|
639
|
+
const ev = {
|
|
640
|
+
...base,
|
|
641
|
+
...typeof input.stopHookActive === "boolean" ? { stopHookActive: input.stopHookActive } : {}
|
|
642
|
+
};
|
|
643
|
+
return ev;
|
|
644
|
+
}
|
|
645
|
+
default: {
|
|
646
|
+
throw new Error(`unsupported ${this.id} hook event: ${String(event)}`);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
// ── Runtime: normalized response → Antigravity native hook reply ──────────
|
|
651
|
+
formatReply(event, response) {
|
|
652
|
+
const decision = response.decision ?? "allow";
|
|
653
|
+
if (decision === "deny") {
|
|
654
|
+
return this.stdout({
|
|
655
|
+
decision: "deny",
|
|
656
|
+
reason: response.reason ?? "Blocked by hook"
|
|
657
|
+
});
|
|
658
|
+
}
|
|
659
|
+
if (decision === "ask") {
|
|
660
|
+
return this.stdout({
|
|
661
|
+
decision: "deny",
|
|
662
|
+
reason: response.reason ?? "Action requires user confirmation (security policy)"
|
|
663
|
+
});
|
|
664
|
+
}
|
|
665
|
+
if (decision === "modify") {
|
|
666
|
+
if (event === "PreToolUse" && response.updatedInput) {
|
|
667
|
+
return this.stdout({ updatedInput: response.updatedInput });
|
|
668
|
+
}
|
|
669
|
+
if (event === "PostToolUse" && response.updatedOutput !== void 0) {
|
|
670
|
+
return this.stdout({ updatedOutput: response.updatedOutput });
|
|
671
|
+
}
|
|
672
|
+
}
|
|
673
|
+
if (decision === "context" && response.additionalContext) {
|
|
674
|
+
return this.stdout({ additionalContext: response.additionalContext });
|
|
675
|
+
}
|
|
676
|
+
return { exitCode: 0 };
|
|
677
|
+
}
|
|
678
|
+
stdout(payload) {
|
|
679
|
+
return { exitCode: 0, stdout: JSON.stringify(payload) };
|
|
680
|
+
}
|
|
681
|
+
};
|
|
682
|
+
function normalizeSessionSource(source) {
|
|
683
|
+
switch (source) {
|
|
684
|
+
case "compact":
|
|
685
|
+
return "compact";
|
|
686
|
+
case "resume":
|
|
687
|
+
return "resume";
|
|
688
|
+
case "clear":
|
|
689
|
+
return "clear";
|
|
690
|
+
default:
|
|
691
|
+
return "startup";
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
var adapter = new AntigravityAdapter();
|
|
695
|
+
var antigravity_default = adapter;
|
|
696
|
+
|
|
697
|
+
export {
|
|
698
|
+
AntigravityAdapter,
|
|
699
|
+
adapter,
|
|
700
|
+
antigravity_default
|
|
701
|
+
};
|
|
702
|
+
//# sourceMappingURL=chunk-TRKWUNO4.js.map
|