@ken-jo/agent-connector 0.1.0 → 0.2.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 +176 -24
- package/dist/{amp-QSFH2V7Y.js → amp-YGV66GJT.js} +9 -2
- package/dist/amp-YGV66GJT.js.map +1 -0
- package/dist/{antigravity-CX2YLSY7.js → antigravity-7IBYFO6P.js} +4 -3
- package/dist/{antigravity-cli-YQDFVV4U.js → antigravity-cli-JEOUP2VN.js} +4 -3
- package/dist/{antigravity-cli-YQDFVV4U.js.map → antigravity-cli-JEOUP2VN.js.map} +1 -1
- package/dist/{chunk-LTT56GI3.js → chunk-3JCRUROU.js} +18 -5
- package/dist/chunk-3JCRUROU.js.map +1 -0
- package/dist/{chunk-YNZU6PAV.js → chunk-4ML7SZ7R.js} +69 -16
- package/dist/chunk-4ML7SZ7R.js.map +1 -0
- package/dist/{chunk-54EMKTTX.js → chunk-AKJGNTU3.js} +17 -17
- package/dist/chunk-AKJGNTU3.js.map +1 -0
- package/dist/chunk-GSGDG2BV.js +568 -0
- package/dist/chunk-GSGDG2BV.js.map +1 -0
- package/dist/{chunk-TRKWUNO4.js → chunk-KQSNDFBN.js} +13 -2
- package/dist/chunk-KQSNDFBN.js.map +1 -0
- package/dist/chunk-N6HH7K6P.js +494 -0
- package/dist/chunk-N6HH7K6P.js.map +1 -0
- package/dist/{chunk-XUCWLJY5.js → chunk-O2SBA5KR.js} +30 -30
- package/dist/{chunk-TIIP3RG2.js → chunk-PD4VFEBY.js} +342 -2
- package/dist/chunk-PD4VFEBY.js.map +1 -0
- package/dist/{chunk-WV63X7IK.js → chunk-SCVBYSF7.js} +2 -2
- package/dist/chunk-SCVBYSF7.js.map +1 -0
- package/dist/{chunk-7MSDGHJW.js → chunk-Z2BVYKZL.js} +60 -7
- package/dist/chunk-Z2BVYKZL.js.map +1 -0
- package/dist/claude-code-4275HQU4.js +1432 -0
- package/dist/claude-code-4275HQU4.js.map +1 -0
- package/dist/cli/sdk.js +4 -3
- package/dist/cli/sdk.js.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/{codebuff-QX57FJDN.js → codebuff-LE3KBZGM.js} +9 -2
- package/dist/codebuff-LE3KBZGM.js.map +1 -0
- package/dist/{codex-JFQTS6LU.js → codex-4BY2ZJIW.js} +148 -7
- package/dist/codex-4BY2ZJIW.js.map +1 -0
- package/dist/{copilot-cli-MTCGHZ2T.js → copilot-cli-IPISKO3V.js} +109 -2
- package/dist/copilot-cli-IPISKO3V.js.map +1 -0
- package/dist/{crush-I7PK3FGI.js → crush-X3E25EQG.js} +31 -3
- package/dist/crush-X3E25EQG.js.map +1 -0
- package/dist/{cursor-4TMXKJOZ.js → cursor-UH3W622V.js} +66 -5
- package/dist/cursor-UH3W622V.js.map +1 -0
- package/dist/{detect-WIAGVYS4.js → detect-JK7T46N6.js} +7 -3
- package/dist/detect-JK7T46N6.js.map +1 -0
- package/dist/{doctor-EZW2K4NI.js → doctor-62BHIXOR.js} +13 -5
- package/dist/doctor-62BHIXOR.js.map +1 -0
- package/dist/{droid-KN6VRMMT.js → droid-T5VBRXZF.js} +32 -3
- package/dist/droid-T5VBRXZF.js.map +1 -0
- package/dist/{gemini-cli-Y35FFK4M.js → gemini-cli-ZSUK55UA.js} +51 -3
- package/dist/gemini-cli-ZSUK55UA.js.map +1 -0
- package/dist/{goose-ZTGTSUFJ.js → goose-M3RR3CZG.js} +63 -4
- package/dist/goose-M3RR3CZG.js.map +1 -0
- package/dist/{hermes-H2KV44GK.js → hermes-CUNKIAR5.js} +76 -3
- package/dist/hermes-CUNKIAR5.js.map +1 -0
- package/dist/{hook-YVDILAMZ.js → hook-AC7APC66.js} +26 -11
- package/dist/hook-AC7APC66.js.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -1
- package/dist/{install-HQRYZOQ2.js → install-DMW2C7SV.js} +12 -7
- package/dist/install-DMW2C7SV.js.map +1 -0
- package/dist/{jetbrains-copilot-HWA3DMH7.js → jetbrains-copilot-C3HDGGML.js} +16 -2
- package/dist/jetbrains-copilot-C3HDGGML.js.map +1 -0
- package/dist/{kilo-QXJRCSLT.js → kilo-ISR5FBBJ.js} +26 -2
- package/dist/kilo-ISR5FBBJ.js.map +1 -0
- package/dist/{kilo-cli-EAQTHXUW.js → kilo-cli-2RNODHWY.js} +30 -2
- package/dist/kilo-cli-2RNODHWY.js.map +1 -0
- package/dist/{kimi-GQ7VXNYT.js → kimi-Q5RG7CYT.js} +89 -6
- package/dist/kimi-Q5RG7CYT.js.map +1 -0
- package/dist/{kiro-VQTT6LO2.js → kiro-EKTRW424.js} +31 -2
- package/dist/kiro-EKTRW424.js.map +1 -0
- package/dist/{leaderboard-K6ON3SWW.js → leaderboard-R5HRJHNU.js} +3 -3
- package/dist/{mux-T2TV4CIQ.js → mux-5CI5FP2W.js} +9 -2
- package/dist/mux-5CI5FP2W.js.map +1 -0
- package/dist/{omp-PB4VDKS6.js → omp-AXA7XY22.js} +13 -2
- package/dist/omp-AXA7XY22.js.map +1 -0
- package/dist/{openclaw-ETN2M63O.js → openclaw-UZ5BMCGQ.js} +101 -4
- package/dist/openclaw-UZ5BMCGQ.js.map +1 -0
- package/dist/{opencode-FZ33JKUZ.js → opencode-NZBRLJN3.js} +53 -7
- package/dist/opencode-NZBRLJN3.js.map +1 -0
- package/dist/{package-DLOVE2E4.js → package-O63K4S7T.js} +10 -5
- package/dist/package-O63K4S7T.js.map +1 -0
- package/dist/{pi-CIU2QHT4.js → pi-SJPIL4VE.js} +6 -2
- package/dist/pi-SJPIL4VE.js.map +1 -0
- package/dist/{qwen-code-5POCNU6P.js → qwen-code-IFCM6BJY.js} +110 -2
- package/dist/qwen-code-IFCM6BJY.js.map +1 -0
- package/dist/{roo-code-IOIUXRDE.js → roo-code-NI5UU6JB.js} +26 -2
- package/dist/roo-code-NI5UU6JB.js.map +1 -0
- package/dist/runtime/index.d.ts +38 -4
- package/dist/runtime/index.js +9 -4
- package/dist/{serve-HVWWY4B6.js → serve-LFOUSZAD.js} +7 -6
- package/dist/{serve-HVWWY4B6.js.map → serve-LFOUSZAD.js.map} +1 -1
- package/dist/{status-FE7TECZD.js → status-M7JLZVLC.js} +6 -5
- package/dist/{status-FE7TECZD.js.map → status-M7JLZVLC.js.map} +1 -1
- package/dist/{telemetry-36GESKQQ.js → telemetry-3NVEXPYX.js} +5 -4
- package/dist/{telemetry-36GESKQQ.js.map → telemetry-3NVEXPYX.js.map} +1 -1
- package/dist/{trae-JSNDZFKL.js → trae-CQC72RHH.js} +9 -2
- package/dist/trae-CQC72RHH.js.map +1 -0
- package/dist/types-CNigfEuR.d.ts +757 -0
- package/dist/{uninstall-IGCKNOSF.js → uninstall-H6FGMIHN.js} +7 -6
- package/dist/{uninstall-IGCKNOSF.js.map → uninstall-H6FGMIHN.js.map} +1 -1
- package/dist/{upgrade-JV2VK242.js → upgrade-76BQZBMA.js} +7 -6
- package/dist/{upgrade-JV2VK242.js.map → upgrade-76BQZBMA.js.map} +1 -1
- package/dist/{usage-6ER6EMEY.js → usage-G3GSCX23.js} +3 -3
- package/dist/{usage-event-JKBI6XCF.js → usage-event-QUTMNBS5.js} +6 -5
- package/dist/{usage-event-JKBI6XCF.js.map → usage-event-QUTMNBS5.js.map} +1 -1
- package/dist/{vscode-copilot-CK3NO54M.js → vscode-copilot-4RVRTCKV.js} +53 -4
- package/dist/vscode-copilot-4RVRTCKV.js.map +1 -0
- package/dist/{warp-QNVDXOG4.js → warp-LLOSXR7A.js} +30 -2
- package/dist/warp-LLOSXR7A.js.map +1 -0
- package/dist/{zed-VRJKWYUR.js → zed-HYOITK7F.js} +53 -3
- package/dist/zed-HYOITK7F.js.map +1 -0
- package/package.json +4 -3
- package/dist/amp-QSFH2V7Y.js.map +0 -1
- package/dist/chunk-54EMKTTX.js.map +0 -1
- package/dist/chunk-7MSDGHJW.js.map +0 -1
- package/dist/chunk-LTT56GI3.js.map +0 -1
- package/dist/chunk-TIIP3RG2.js.map +0 -1
- package/dist/chunk-TRKWUNO4.js.map +0 -1
- package/dist/chunk-WV63X7IK.js.map +0 -1
- package/dist/chunk-XNAM7F35.js +0 -276
- package/dist/chunk-XNAM7F35.js.map +0 -1
- package/dist/chunk-YNZU6PAV.js.map +0 -1
- package/dist/claude-code-HKDV7T32.js +0 -637
- package/dist/claude-code-HKDV7T32.js.map +0 -1
- package/dist/codebuff-QX57FJDN.js.map +0 -1
- package/dist/codex-JFQTS6LU.js.map +0 -1
- package/dist/copilot-cli-MTCGHZ2T.js.map +0 -1
- package/dist/crush-I7PK3FGI.js.map +0 -1
- package/dist/cursor-4TMXKJOZ.js.map +0 -1
- package/dist/detect-WIAGVYS4.js.map +0 -1
- package/dist/doctor-EZW2K4NI.js.map +0 -1
- package/dist/droid-KN6VRMMT.js.map +0 -1
- package/dist/gemini-cli-Y35FFK4M.js.map +0 -1
- package/dist/goose-ZTGTSUFJ.js.map +0 -1
- package/dist/hermes-H2KV44GK.js.map +0 -1
- package/dist/hook-YVDILAMZ.js.map +0 -1
- package/dist/install-HQRYZOQ2.js.map +0 -1
- package/dist/jetbrains-copilot-HWA3DMH7.js.map +0 -1
- package/dist/kilo-QXJRCSLT.js.map +0 -1
- package/dist/kilo-cli-EAQTHXUW.js.map +0 -1
- package/dist/kimi-GQ7VXNYT.js.map +0 -1
- package/dist/kiro-VQTT6LO2.js.map +0 -1
- package/dist/mux-T2TV4CIQ.js.map +0 -1
- package/dist/omp-PB4VDKS6.js.map +0 -1
- package/dist/openclaw-ETN2M63O.js.map +0 -1
- package/dist/opencode-FZ33JKUZ.js.map +0 -1
- package/dist/package-DLOVE2E4.js.map +0 -1
- package/dist/pi-CIU2QHT4.js.map +0 -1
- package/dist/qwen-code-5POCNU6P.js.map +0 -1
- package/dist/roo-code-IOIUXRDE.js.map +0 -1
- package/dist/trae-JSNDZFKL.js.map +0 -1
- package/dist/types-CYUB1OTr.d.ts +0 -427
- package/dist/vscode-copilot-CK3NO54M.js.map +0 -1
- package/dist/warp-QNVDXOG4.js.map +0 -1
- package/dist/zed-VRJKWYUR.js.map +0 -1
- /package/dist/{antigravity-CX2YLSY7.js.map → antigravity-7IBYFO6P.js.map} +0 -0
- /package/dist/{chunk-XUCWLJY5.js.map → chunk-O2SBA5KR.js.map} +0 -0
- /package/dist/{leaderboard-K6ON3SWW.js.map → leaderboard-R5HRJHNU.js.map} +0 -0
- /package/dist/{usage-6ER6EMEY.js.map → usage-G3GSCX23.js.map} +0 -0
|
@@ -0,0 +1,568 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
MANAGED_BLOCK_BEGIN_TOKEN,
|
|
4
|
+
MANAGED_BLOCK_END_TOKEN,
|
|
5
|
+
MEMORY_CONTENT_HARD_CAP_BYTES
|
|
6
|
+
} from "./chunk-N6HH7K6P.js";
|
|
7
|
+
import {
|
|
8
|
+
ensureDir
|
|
9
|
+
} from "./chunk-TRQKHP7D.js";
|
|
10
|
+
|
|
11
|
+
// src/core/config-patch-ledger.ts
|
|
12
|
+
import { createHash, randomBytes } from "crypto";
|
|
13
|
+
import {
|
|
14
|
+
existsSync,
|
|
15
|
+
readFileSync,
|
|
16
|
+
renameSync,
|
|
17
|
+
rmSync,
|
|
18
|
+
writeFileSync
|
|
19
|
+
} from "fs";
|
|
20
|
+
import { dirname, join } from "path";
|
|
21
|
+
var CONFIG_PATCH_SEGMENT_RE = /^[A-Za-z0-9_-]+$/;
|
|
22
|
+
function isValidConfigPatchKey(key) {
|
|
23
|
+
if (typeof key !== "string" || key.length === 0) return false;
|
|
24
|
+
return key.split(".").every((seg) => CONFIG_PATCH_SEGMENT_RE.test(seg));
|
|
25
|
+
}
|
|
26
|
+
function isJsonValue(value) {
|
|
27
|
+
if (value === null) return true;
|
|
28
|
+
switch (typeof value) {
|
|
29
|
+
case "string":
|
|
30
|
+
case "boolean":
|
|
31
|
+
return true;
|
|
32
|
+
case "number":
|
|
33
|
+
return Number.isFinite(value);
|
|
34
|
+
case "object":
|
|
35
|
+
break;
|
|
36
|
+
default:
|
|
37
|
+
return false;
|
|
38
|
+
}
|
|
39
|
+
if (Array.isArray(value)) return value.every((v) => isJsonValue(v));
|
|
40
|
+
const proto = Object.getPrototypeOf(value);
|
|
41
|
+
if (proto !== Object.prototype && proto !== null) return false;
|
|
42
|
+
return Object.values(value).every((v) => isJsonValue(v));
|
|
43
|
+
}
|
|
44
|
+
function configPatchNamespaceViolation(key) {
|
|
45
|
+
const head = key.split(".")[0] ?? "";
|
|
46
|
+
if (head === "hooks") {
|
|
47
|
+
return `"${key}" targets the hooks config agent-connector already models; declare it via \`hooks\` (normalized) or \`platforms.<id>.nativeHooks\` instead`;
|
|
48
|
+
}
|
|
49
|
+
if (head === "mcpServers" || head === "enableAllProjectMcpServers" || head === "enabledMcpjsonServers" || head === "disabledMcpjsonServers") {
|
|
50
|
+
return `"${key}" targets MCP server registration agent-connector already models; declare it via \`server\` / \`platforms.<id>.server\` / \`extra\` instead`;
|
|
51
|
+
}
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
function configPatchManualEdit(patch) {
|
|
55
|
+
const docs = patch.docsUrl ? ` \u2014 see ${patch.docsUrl}` : "";
|
|
56
|
+
return `manual edit if wanted: set ${patch.key} = ${describeJsonValue(patch.value)} (${patch.reason})${docs}`;
|
|
57
|
+
}
|
|
58
|
+
function describeJsonValue(value) {
|
|
59
|
+
if (value === void 0) return "<absent>";
|
|
60
|
+
try {
|
|
61
|
+
return JSON.stringify(value);
|
|
62
|
+
} catch {
|
|
63
|
+
return String(value);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function canonicalJson(value) {
|
|
67
|
+
if (value === void 0) return "undefined";
|
|
68
|
+
if (value === null || typeof value !== "object") return JSON.stringify(value);
|
|
69
|
+
if (Array.isArray(value)) {
|
|
70
|
+
return `[${value.map((v) => canonicalJson(v)).join(",")}]`;
|
|
71
|
+
}
|
|
72
|
+
const keys = Object.keys(value).sort();
|
|
73
|
+
const parts = keys.map((k) => `${JSON.stringify(k)}:${canonicalJson(value[k])}`);
|
|
74
|
+
return `{${parts.join(",")}}`;
|
|
75
|
+
}
|
|
76
|
+
function hashJsonValue(value) {
|
|
77
|
+
return createHash("sha256").update(canonicalJson(value)).digest("hex");
|
|
78
|
+
}
|
|
79
|
+
function jsonDeepEquals(a, b) {
|
|
80
|
+
return canonicalJson(a) === canonicalJson(b);
|
|
81
|
+
}
|
|
82
|
+
function configPatchLedgerPath(dataRoot) {
|
|
83
|
+
return join(dataRoot, "state", "config-patches.json");
|
|
84
|
+
}
|
|
85
|
+
function loadConfigPatchLedger(dataRoot) {
|
|
86
|
+
const path = configPatchLedgerPath(dataRoot);
|
|
87
|
+
if (!existsSync(path)) return { version: 1, entries: [] };
|
|
88
|
+
try {
|
|
89
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
90
|
+
if (!parsed || !Array.isArray(parsed.entries)) return { version: 1, entries: [] };
|
|
91
|
+
return { version: 1, entries: parsed.entries.filter(isPlausibleEntry) };
|
|
92
|
+
} catch {
|
|
93
|
+
return { version: 1, entries: [] };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function isPlausibleEntry(e) {
|
|
97
|
+
if (e == null || typeof e !== "object") return false;
|
|
98
|
+
const entry = e;
|
|
99
|
+
return typeof entry.platform === "string" && typeof entry.file === "string" && typeof entry.key === "string" && Array.isArray(entry.owners);
|
|
100
|
+
}
|
|
101
|
+
function saveConfigPatchLedger(dataRoot, ledger) {
|
|
102
|
+
const path = configPatchLedgerPath(dataRoot);
|
|
103
|
+
ensureDir(dirname(path));
|
|
104
|
+
const tmpFile = `${path}.${process.pid}-${randomBytes(4).toString("hex")}.tmp`;
|
|
105
|
+
try {
|
|
106
|
+
writeFileSync(tmpFile, `${JSON.stringify(ledger, null, 2)}
|
|
107
|
+
`, "utf8");
|
|
108
|
+
renameSync(tmpFile, path);
|
|
109
|
+
} catch (err) {
|
|
110
|
+
rmSync(tmpFile, { force: true });
|
|
111
|
+
throw err;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
function findLedgerEntry(ledger, platform, file, key) {
|
|
115
|
+
return ledger.entries.find(
|
|
116
|
+
(e) => e.platform === platform && e.file === file && e.key === key
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
function ledgerEntriesOwnedBy(ledger, platform, connectorId) {
|
|
120
|
+
return ledger.entries.filter(
|
|
121
|
+
(e) => e.platform === platform && e.owners.some((o) => o.connectorId === connectorId)
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
function createLedgerEntry(ledger, init) {
|
|
125
|
+
const entry = {
|
|
126
|
+
platform: init.platform,
|
|
127
|
+
file: init.file,
|
|
128
|
+
key: init.key,
|
|
129
|
+
writtenValue: init.value,
|
|
130
|
+
writtenValueHash: hashJsonValue(init.value),
|
|
131
|
+
prior: { present: false },
|
|
132
|
+
owners: [
|
|
133
|
+
{
|
|
134
|
+
connectorId: init.connectorId,
|
|
135
|
+
connectorVersion: init.connectorVersion,
|
|
136
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
137
|
+
}
|
|
138
|
+
]
|
|
139
|
+
};
|
|
140
|
+
ledger.entries.push(entry);
|
|
141
|
+
return entry;
|
|
142
|
+
}
|
|
143
|
+
function addLedgerOwner(entry, connectorId, connectorVersion) {
|
|
144
|
+
if (entry.owners.some((o) => o.connectorId === connectorId)) return false;
|
|
145
|
+
entry.owners.push({
|
|
146
|
+
connectorId,
|
|
147
|
+
connectorVersion,
|
|
148
|
+
installedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
149
|
+
});
|
|
150
|
+
return true;
|
|
151
|
+
}
|
|
152
|
+
function removeLedgerOwner(entry, connectorId) {
|
|
153
|
+
const before = entry.owners.length;
|
|
154
|
+
entry.owners = entry.owners.filter((o) => o.connectorId !== connectorId);
|
|
155
|
+
return { removed: entry.owners.length < before, lastOwner: entry.owners.length === 0 };
|
|
156
|
+
}
|
|
157
|
+
function dropLedgerEntry(ledger, entry) {
|
|
158
|
+
ledger.entries = ledger.entries.filter((e) => e !== entry);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// src/core/define-connector.ts
|
|
162
|
+
import { isAbsolute, normalize } from "path";
|
|
163
|
+
|
|
164
|
+
// src/core/mcp-standard.ts
|
|
165
|
+
var MCP_SERVER_SCHEMA_URL = "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json";
|
|
166
|
+
var MCPB_MANIFEST_VERSION = "0.3";
|
|
167
|
+
var MCP_PROTOCOL_VERSION = "2025-11-25";
|
|
168
|
+
var NPM_REGISTRY_BASE_URL = "https://registry.npmjs.org";
|
|
169
|
+
function registryTransportType(transport) {
|
|
170
|
+
switch (transport) {
|
|
171
|
+
case "stdio":
|
|
172
|
+
return "stdio";
|
|
173
|
+
case "http":
|
|
174
|
+
return "streamable-http";
|
|
175
|
+
case "sse":
|
|
176
|
+
return "sse";
|
|
177
|
+
case "ws":
|
|
178
|
+
return null;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
function isConcreteSemver(v) {
|
|
182
|
+
return /^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/.test(v);
|
|
183
|
+
}
|
|
184
|
+
function isPlaceholderVersion(v) {
|
|
185
|
+
return v === "0.0.0";
|
|
186
|
+
}
|
|
187
|
+
var REGISTRY_NAMESPACE_RE = /^[a-zA-Z0-9.-]+$/;
|
|
188
|
+
var REGISTRY_NAME_RE = /^[a-zA-Z0-9.-]+\/[a-zA-Z0-9._-]+$/;
|
|
189
|
+
|
|
190
|
+
// src/core/define-connector.ts
|
|
191
|
+
var ID_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
192
|
+
var SURFACE_NAME_RE = /^[a-z0-9][a-z0-9-]*$/;
|
|
193
|
+
var SKILL_DESCRIPTION_MAX = 1024;
|
|
194
|
+
var ALL_EVENTS = [
|
|
195
|
+
"SessionStart",
|
|
196
|
+
"SessionEnd",
|
|
197
|
+
"UserPromptSubmit",
|
|
198
|
+
"PreToolUse",
|
|
199
|
+
"PostToolUse",
|
|
200
|
+
"PreCompact",
|
|
201
|
+
"Stop",
|
|
202
|
+
"Notification",
|
|
203
|
+
"PermissionRequest",
|
|
204
|
+
"PostToolUseFailure",
|
|
205
|
+
"SubagentStart",
|
|
206
|
+
"SubagentStop"
|
|
207
|
+
];
|
|
208
|
+
var ConnectorConfigError = class extends Error {
|
|
209
|
+
constructor(message) {
|
|
210
|
+
super(`Invalid connector config: ${message}`);
|
|
211
|
+
this.name = "ConnectorConfigError";
|
|
212
|
+
}
|
|
213
|
+
};
|
|
214
|
+
function declaredEvents(hooks) {
|
|
215
|
+
if (!hooks) return [];
|
|
216
|
+
return ALL_EVENTS.filter((e) => typeof hooks[e]?.handler === "function");
|
|
217
|
+
}
|
|
218
|
+
function defineConnector(config) {
|
|
219
|
+
if (!config || typeof config !== "object") {
|
|
220
|
+
throw new ConnectorConfigError("config must be an object");
|
|
221
|
+
}
|
|
222
|
+
if (typeof config.id !== "string" || !ID_RE.test(config.id)) {
|
|
223
|
+
throw new ConnectorConfigError(
|
|
224
|
+
`id must be kebab-case matching ${ID_RE} (got ${JSON.stringify(config.id)})`
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
const hasCommands = Array.isArray(config.commands) && config.commands.length > 0;
|
|
228
|
+
const hasSkills = Array.isArray(config.skills) && config.skills.length > 0;
|
|
229
|
+
const hasSubagents = Array.isArray(config.subagents) && config.subagents.length > 0;
|
|
230
|
+
const hasMemory = Array.isArray(config.memory) && config.memory.length > 0;
|
|
231
|
+
const hasNativeHooks = Object.values(config.platforms ?? {}).some(
|
|
232
|
+
(override) => override?.nativeHooks != null && Object.keys(override.nativeHooks).length > 0
|
|
233
|
+
);
|
|
234
|
+
const hasConfigPatch = Object.values(config.platforms ?? {}).some(
|
|
235
|
+
(override) => Array.isArray(override?.configPatch) && override.configPatch.length > 0
|
|
236
|
+
);
|
|
237
|
+
if (!config.server && !config.hooks && !hasCommands && !hasSkills && !hasSubagents && !hasMemory && !hasNativeHooks && !hasConfigPatch) {
|
|
238
|
+
throw new ConnectorConfigError(
|
|
239
|
+
"a connector must declare at least one of `server`, `hooks`, `commands`, `skills`, `subagents`, `memory`, or a per-platform `nativeHooks` / `configPatch` declaration"
|
|
240
|
+
);
|
|
241
|
+
}
|
|
242
|
+
if (config.server) {
|
|
243
|
+
const s = config.server;
|
|
244
|
+
if (s.transport === "stdio") {
|
|
245
|
+
if (!s.command || typeof s.command !== "string") {
|
|
246
|
+
throw new ConnectorConfigError(
|
|
247
|
+
"server.command is required for stdio transport"
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
} else {
|
|
251
|
+
if (!s.url || typeof s.url !== "string") {
|
|
252
|
+
throw new ConnectorConfigError(
|
|
253
|
+
`server.url is required for ${s.transport} transport`
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (config.hooks) {
|
|
259
|
+
for (const ev of ALL_EVENTS) {
|
|
260
|
+
const def = config.hooks[ev];
|
|
261
|
+
if (def != null && typeof def.handler !== "function") {
|
|
262
|
+
throw new ConnectorConfigError(`hooks.${ev}.handler must be a function`);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
validateNativeHooks(config.platforms);
|
|
267
|
+
validateConfigPatches(config.platforms);
|
|
268
|
+
const commands = normalizeCommands(config.commands);
|
|
269
|
+
const skills = normalizeSkills(config.skills);
|
|
270
|
+
const subagents = normalizeSubagents(config.subagents);
|
|
271
|
+
const memory = normalizeMemory(config.memory);
|
|
272
|
+
const t = config.telemetry ?? {};
|
|
273
|
+
const resolved = {
|
|
274
|
+
id: config.id,
|
|
275
|
+
displayName: config.displayName ?? config.id,
|
|
276
|
+
version: config.version ?? "0.0.0",
|
|
277
|
+
...config.server ? { server: normalizeServer(config.server) } : {},
|
|
278
|
+
hooks: config.hooks ?? {},
|
|
279
|
+
hookEvents: declaredEvents(config.hooks),
|
|
280
|
+
telemetry: {
|
|
281
|
+
enabled: t.enabled ?? true,
|
|
282
|
+
modelFamilyHint: t.modelFamilyHint ?? "auto",
|
|
283
|
+
measureToolDefs: t.measureToolDefs ?? true,
|
|
284
|
+
// OPT-IN: host-native turn-usage capture is OFF unless explicitly enabled
|
|
285
|
+
// in config (or forced on at install via AGENT_CONNECTOR_HOST_NATIVE=1).
|
|
286
|
+
hostNativeUsage: t.hostNativeUsage ?? false,
|
|
287
|
+
store: t.store ?? "ndjson",
|
|
288
|
+
calibration: {
|
|
289
|
+
anthropicCountTokens: t.calibration?.anthropicCountTokens ?? false
|
|
290
|
+
}
|
|
291
|
+
},
|
|
292
|
+
commands,
|
|
293
|
+
skills,
|
|
294
|
+
subagents,
|
|
295
|
+
memory,
|
|
296
|
+
platforms: config.platforms ?? {},
|
|
297
|
+
targets: config.targets ?? "auto",
|
|
298
|
+
...config.publish ? { publish: normalizePublish(config.publish) } : {}
|
|
299
|
+
};
|
|
300
|
+
return resolved;
|
|
301
|
+
}
|
|
302
|
+
var NORMALIZED_EVENT_SET = new Set(ALL_EVENTS);
|
|
303
|
+
function validateNativeHooks(platforms) {
|
|
304
|
+
if (platforms == null) return;
|
|
305
|
+
for (const [platformId, override] of Object.entries(platforms)) {
|
|
306
|
+
const native = override?.nativeHooks;
|
|
307
|
+
if (native == null) continue;
|
|
308
|
+
const where = `platforms.${platformId}.nativeHooks`;
|
|
309
|
+
if (typeof native !== "object" || Array.isArray(native)) {
|
|
310
|
+
throw new ConnectorConfigError(
|
|
311
|
+
`${where} must be an object keyed by host-native event name`
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
for (const [event, def] of Object.entries(native)) {
|
|
315
|
+
if (NORMALIZED_EVENT_SET.has(event)) {
|
|
316
|
+
throw new ConnectorConfigError(
|
|
317
|
+
`${where}.${event} collides with the normalized hook event "${event}"; declare it under \`hooks.${event}\` (the normalized, cross-platform hooks API) instead`
|
|
318
|
+
);
|
|
319
|
+
}
|
|
320
|
+
if (def == null || typeof def !== "object" || typeof def.handler !== "function") {
|
|
321
|
+
throw new ConnectorConfigError(`${where}.${event}.handler must be a function`);
|
|
322
|
+
}
|
|
323
|
+
if (def.matcher !== void 0 && typeof def.matcher !== "string") {
|
|
324
|
+
throw new ConnectorConfigError(`${where}.${event}.matcher must be a string`);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
function validateConfigPatches(platforms) {
|
|
330
|
+
if (platforms == null) return;
|
|
331
|
+
for (const [platformId, override] of Object.entries(platforms)) {
|
|
332
|
+
const patches = override?.configPatch;
|
|
333
|
+
if (patches == null) continue;
|
|
334
|
+
const where = `platforms.${platformId}.configPatch`;
|
|
335
|
+
if (!Array.isArray(patches)) {
|
|
336
|
+
throw new ConnectorConfigError(`${where} must be an array of patch objects`);
|
|
337
|
+
}
|
|
338
|
+
const seen = /* @__PURE__ */ new Set();
|
|
339
|
+
patches.forEach((patch, i) => {
|
|
340
|
+
if (patch == null || typeof patch !== "object" || Array.isArray(patch)) {
|
|
341
|
+
throw new ConnectorConfigError(`${where}[${i}] must be an object`);
|
|
342
|
+
}
|
|
343
|
+
if (!isValidConfigPatchKey(patch.key)) {
|
|
344
|
+
throw new ConnectorConfigError(
|
|
345
|
+
`${where}[${i}].key must be a dotted LEAF path whose segments match ${CONFIG_PATCH_SEGMENT_RE} (no dots-in-key, no array indices); got ${JSON.stringify(patch.key)}`
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
const violation = configPatchNamespaceViolation(patch.key);
|
|
349
|
+
if (violation) {
|
|
350
|
+
throw new ConnectorConfigError(`${where}[${i}].key ${violation}`);
|
|
351
|
+
}
|
|
352
|
+
if (seen.has(patch.key)) {
|
|
353
|
+
throw new ConnectorConfigError(
|
|
354
|
+
`${where}[${i}] duplicate key "${patch.key}"`
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
seen.add(patch.key);
|
|
358
|
+
if (!isJsonValue(patch.value)) {
|
|
359
|
+
throw new ConnectorConfigError(
|
|
360
|
+
`${where}[${i}].value must be JSON-serializable data (string/finite number/boolean/null/array/plain object)`
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
if (typeof patch.reason !== "string" || patch.reason.trim() === "") {
|
|
364
|
+
throw new ConnectorConfigError(
|
|
365
|
+
`${where}[${i}].reason is required (a human-readable why, printed in the install diff and every skip-warn)`
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
if (patch.docsUrl !== void 0 && typeof patch.docsUrl !== "string") {
|
|
369
|
+
throw new ConnectorConfigError(`${where}[${i}].docsUrl must be a string`);
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function normalizePublish(publish) {
|
|
375
|
+
if (typeof publish !== "object" || Array.isArray(publish)) {
|
|
376
|
+
throw new ConnectorConfigError("publish must be an object");
|
|
377
|
+
}
|
|
378
|
+
if (publish.registryNamespace !== void 0) {
|
|
379
|
+
const ns = publish.registryNamespace;
|
|
380
|
+
if (typeof ns !== "string" || !REGISTRY_NAMESPACE_RE.test(ns)) {
|
|
381
|
+
throw new ConnectorConfigError(
|
|
382
|
+
`publish.registryNamespace must be a reverse-DNS namespace matching ${REGISTRY_NAMESPACE_RE} (e.g. "io.github.acme" or "com.acme"); got ${JSON.stringify(ns)}`
|
|
383
|
+
);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
if (publish.packageName !== void 0 && typeof publish.packageName !== "string") {
|
|
387
|
+
throw new ConnectorConfigError("publish.packageName must be a string");
|
|
388
|
+
}
|
|
389
|
+
if (publish.author !== void 0) {
|
|
390
|
+
const a = publish.author;
|
|
391
|
+
if (typeof a !== "object" || a == null || typeof a.name !== "string" || a.name === "") {
|
|
392
|
+
throw new ConnectorConfigError("publish.author.name must be a non-empty string");
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
return { ...publish };
|
|
396
|
+
}
|
|
397
|
+
function assertSurfaceName(surface, name, index) {
|
|
398
|
+
if (typeof name !== "string" || !SURFACE_NAME_RE.test(name)) {
|
|
399
|
+
throw new ConnectorConfigError(
|
|
400
|
+
`${surface}[${index}].name must be kebab-case matching ${SURFACE_NAME_RE} (got ${JSON.stringify(name)})`
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
return name;
|
|
404
|
+
}
|
|
405
|
+
function assertNonEmptyString(surface, index, field, value) {
|
|
406
|
+
if (typeof value !== "string" || value.length === 0) {
|
|
407
|
+
throw new ConnectorConfigError(`${surface}[${index}].${field} must be a non-empty string`);
|
|
408
|
+
}
|
|
409
|
+
return value;
|
|
410
|
+
}
|
|
411
|
+
function assertNoDuplicate(surface, seen, name, index) {
|
|
412
|
+
if (seen.has(name)) {
|
|
413
|
+
throw new ConnectorConfigError(`${surface}[${index}] duplicate name "${name}"`);
|
|
414
|
+
}
|
|
415
|
+
seen.add(name);
|
|
416
|
+
}
|
|
417
|
+
function normalizeCommands(input) {
|
|
418
|
+
if (input == null) return [];
|
|
419
|
+
if (!Array.isArray(input)) {
|
|
420
|
+
throw new ConnectorConfigError("commands must be an array");
|
|
421
|
+
}
|
|
422
|
+
const seen = /* @__PURE__ */ new Set();
|
|
423
|
+
return input.map((cmd, i) => {
|
|
424
|
+
if (!cmd || typeof cmd !== "object") {
|
|
425
|
+
throw new ConnectorConfigError(`commands[${i}] must be an object`);
|
|
426
|
+
}
|
|
427
|
+
const name = assertSurfaceName("commands", cmd.name, i);
|
|
428
|
+
assertNoDuplicate("commands", seen, name, i);
|
|
429
|
+
assertNonEmptyString("commands", i, "prompt", cmd.prompt);
|
|
430
|
+
return { ...cmd, name };
|
|
431
|
+
});
|
|
432
|
+
}
|
|
433
|
+
function normalizeSkills(input) {
|
|
434
|
+
if (input == null) return [];
|
|
435
|
+
if (!Array.isArray(input)) {
|
|
436
|
+
throw new ConnectorConfigError("skills must be an array");
|
|
437
|
+
}
|
|
438
|
+
const seen = /* @__PURE__ */ new Set();
|
|
439
|
+
return input.map((skill, i) => {
|
|
440
|
+
if (!skill || typeof skill !== "object") {
|
|
441
|
+
throw new ConnectorConfigError(`skills[${i}] must be an object`);
|
|
442
|
+
}
|
|
443
|
+
const name = assertSurfaceName("skills", skill.name, i);
|
|
444
|
+
assertNoDuplicate("skills", seen, name, i);
|
|
445
|
+
const description = assertNonEmptyString("skills", i, "description", skill.description);
|
|
446
|
+
if (description.length > SKILL_DESCRIPTION_MAX) {
|
|
447
|
+
throw new ConnectorConfigError(
|
|
448
|
+
`skills[${i}].description exceeds ${SKILL_DESCRIPTION_MAX} chars (got ${description.length})`
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
assertNonEmptyString("skills", i, "body", skill.body);
|
|
452
|
+
assertSafeResourceKeys("skills", i, skill.resources);
|
|
453
|
+
return { ...skill, name };
|
|
454
|
+
});
|
|
455
|
+
}
|
|
456
|
+
function assertSafeResourceKeys(surface, index, resources) {
|
|
457
|
+
if (resources == null) return;
|
|
458
|
+
if (typeof resources !== "object" || Array.isArray(resources)) {
|
|
459
|
+
throw new ConnectorConfigError(`${surface}[${index}].resources must be an object`);
|
|
460
|
+
}
|
|
461
|
+
for (const rel of Object.keys(resources)) {
|
|
462
|
+
if (rel === "" || rel === "." || rel.trim() === "") {
|
|
463
|
+
throw new ConnectorConfigError(
|
|
464
|
+
`${surface}[${index}].resources key must be a non-empty relative path (got ${JSON.stringify(rel)})`
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
if (isAbsolute(rel)) {
|
|
468
|
+
throw new ConnectorConfigError(
|
|
469
|
+
`${surface}[${index}].resources key must be a relative path inside the skill dir, not absolute (got ${JSON.stringify(rel)})`
|
|
470
|
+
);
|
|
471
|
+
}
|
|
472
|
+
const norm = normalize(rel.replace(/\\/g, "/"));
|
|
473
|
+
const segs = norm.split(/[/\\]/);
|
|
474
|
+
if (norm === ".." || norm.startsWith("../") || norm.startsWith("..\\") || segs.includes("..")) {
|
|
475
|
+
throw new ConnectorConfigError(
|
|
476
|
+
`${surface}[${index}].resources key must not escape the skill dir via ".." (got ${JSON.stringify(rel)})`
|
|
477
|
+
);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
var MEMORY_DEFAULT_NAME = "memory";
|
|
482
|
+
function normalizeMemory(input) {
|
|
483
|
+
if (input == null) return [];
|
|
484
|
+
if (!Array.isArray(input)) {
|
|
485
|
+
throw new ConnectorConfigError("memory must be an array");
|
|
486
|
+
}
|
|
487
|
+
const seen = /* @__PURE__ */ new Set();
|
|
488
|
+
return input.map((entry, i) => {
|
|
489
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
490
|
+
throw new ConnectorConfigError(`memory[${i}] must be an object`);
|
|
491
|
+
}
|
|
492
|
+
const name = entry.name === void 0 ? MEMORY_DEFAULT_NAME : assertSurfaceName("memory", entry.name, i);
|
|
493
|
+
assertNoDuplicate("memory", seen, name, i);
|
|
494
|
+
const content = assertNonEmptyString("memory", i, "content", entry.content);
|
|
495
|
+
const bytes = Buffer.byteLength(content, "utf8");
|
|
496
|
+
if (bytes > MEMORY_CONTENT_HARD_CAP_BYTES) {
|
|
497
|
+
throw new ConnectorConfigError(
|
|
498
|
+
`memory[${i}].content exceeds the ${MEMORY_CONTENT_HARD_CAP_BYTES}-byte hard cap (got ${bytes} bytes); memory is inlined into every prompt of every targeted host \u2014 keep it terse`
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
for (const token of [MANAGED_BLOCK_BEGIN_TOKEN, MANAGED_BLOCK_END_TOKEN]) {
|
|
502
|
+
if (content.includes(token)) {
|
|
503
|
+
throw new ConnectorConfigError(
|
|
504
|
+
`memory[${i}].content must not contain the literal marker token "${token}" (it would corrupt managed-block scanning in the shared memory file); rephrase the guidance`
|
|
505
|
+
);
|
|
506
|
+
}
|
|
507
|
+
}
|
|
508
|
+
if (entry.description !== void 0 && typeof entry.description !== "string") {
|
|
509
|
+
throw new ConnectorConfigError(`memory[${i}].description must be a string`);
|
|
510
|
+
}
|
|
511
|
+
return { ...entry, name };
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
function normalizeSubagents(input) {
|
|
515
|
+
if (input == null) return [];
|
|
516
|
+
if (!Array.isArray(input)) {
|
|
517
|
+
throw new ConnectorConfigError("subagents must be an array");
|
|
518
|
+
}
|
|
519
|
+
const seen = /* @__PURE__ */ new Set();
|
|
520
|
+
return input.map((agent, i) => {
|
|
521
|
+
if (!agent || typeof agent !== "object") {
|
|
522
|
+
throw new ConnectorConfigError(`subagents[${i}] must be an object`);
|
|
523
|
+
}
|
|
524
|
+
const name = assertSurfaceName("subagents", agent.name, i);
|
|
525
|
+
assertNoDuplicate("subagents", seen, name, i);
|
|
526
|
+
assertNonEmptyString("subagents", i, "description", agent.description);
|
|
527
|
+
assertNonEmptyString("subagents", i, "prompt", agent.prompt);
|
|
528
|
+
return { ...agent, name };
|
|
529
|
+
});
|
|
530
|
+
}
|
|
531
|
+
function normalizeServer(server) {
|
|
532
|
+
if (!server) return void 0;
|
|
533
|
+
const wrapDefault = server.transport === "stdio";
|
|
534
|
+
return {
|
|
535
|
+
...server,
|
|
536
|
+
enabled: server.enabled ?? true,
|
|
537
|
+
tools: server.tools ?? { include: ["*"] },
|
|
538
|
+
wrapForTelemetry: server.wrapForTelemetry ?? wrapDefault
|
|
539
|
+
};
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
export {
|
|
543
|
+
MCP_SERVER_SCHEMA_URL,
|
|
544
|
+
MCPB_MANIFEST_VERSION,
|
|
545
|
+
MCP_PROTOCOL_VERSION,
|
|
546
|
+
NPM_REGISTRY_BASE_URL,
|
|
547
|
+
registryTransportType,
|
|
548
|
+
isConcreteSemver,
|
|
549
|
+
isPlaceholderVersion,
|
|
550
|
+
REGISTRY_NAME_RE,
|
|
551
|
+
isValidConfigPatchKey,
|
|
552
|
+
configPatchNamespaceViolation,
|
|
553
|
+
configPatchManualEdit,
|
|
554
|
+
describeJsonValue,
|
|
555
|
+
hashJsonValue,
|
|
556
|
+
jsonDeepEquals,
|
|
557
|
+
loadConfigPatchLedger,
|
|
558
|
+
saveConfigPatchLedger,
|
|
559
|
+
findLedgerEntry,
|
|
560
|
+
ledgerEntriesOwnedBy,
|
|
561
|
+
createLedgerEntry,
|
|
562
|
+
addLedgerOwner,
|
|
563
|
+
removeLedgerOwner,
|
|
564
|
+
dropLedgerEntry,
|
|
565
|
+
ConnectorConfigError,
|
|
566
|
+
defineConnector
|
|
567
|
+
};
|
|
568
|
+
//# sourceMappingURL=chunk-GSGDG2BV.js.map
|