@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
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
import {
|
|
13
13
|
fail,
|
|
14
14
|
print
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-AKJGNTU3.js";
|
|
16
16
|
import {
|
|
17
17
|
openStore
|
|
18
18
|
} from "./chunk-BCHWFTV4.js";
|
|
@@ -21,8 +21,9 @@ import {
|
|
|
21
21
|
listRegisteredConnectors,
|
|
22
22
|
loadRegisteredConnector,
|
|
23
23
|
readRegisteredMeta
|
|
24
|
-
} from "./chunk-
|
|
25
|
-
import "./chunk-
|
|
24
|
+
} from "./chunk-3JCRUROU.js";
|
|
25
|
+
import "./chunk-GSGDG2BV.js";
|
|
26
|
+
import "./chunk-N6HH7K6P.js";
|
|
26
27
|
import "./chunk-TRQKHP7D.js";
|
|
27
28
|
|
|
28
29
|
// src/cli/commands/telemetry.ts
|
|
@@ -346,4 +347,4 @@ export {
|
|
|
346
347
|
parseSince,
|
|
347
348
|
run
|
|
348
349
|
};
|
|
349
|
-
//# sourceMappingURL=telemetry-
|
|
350
|
+
//# sourceMappingURL=telemetry-3NVEXPYX.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/commands/telemetry.ts","../src/telemetry/report.ts"],"sourcesContent":["/**\n * cli/commands/telemetry — inspect the local per-tool token telemetry store.\n *\n * Subcommands:\n * report --by tool|session|project (default tool) --since 7d|24h|… --connector <id> [--json]\n * → summarize(openStore({}), …) + formatReport (the aligned table).\n * export --format csv|json (default json) --out <file> [--since/--connector …]\n * → toCSV / toJSONExport of the raw records.\n *\n * Telemetry rows are aggregate counts only (never raw arguments/results).\n */\n\nimport { writeFileSync } from \"node:fs\";\nimport { parseArgs } from \"node:util\";\n\nimport type { QueryFilter } from \"../../telemetry/types.js\";\nimport type { RollupDimension } from \"../../telemetry/report.js\";\nimport { openStore } from \"../../telemetry/store.js\";\nimport { summarize, toCSV, toJSONExport } from \"../../telemetry/report.js\";\nimport {\n formatMcpLeaderboard,\n formatSurfaceLeaderboard,\n formatToolLeaderboard,\n isScopeFilter,\n mcpLeaderboard,\n SCOPE_FILTER_VALUES,\n surfaceLeaderboard,\n toolLeaderboard,\n type LeaderboardOptions,\n type ScopeFilter,\n type SurfaceLeaderboardOptions,\n} from \"../../telemetry/leaderboard.js\";\nimport {\n connectorFromMeta,\n listRegisteredConnectors,\n loadRegisteredConnector,\n readRegisteredMeta,\n} from \"../../core/load-connector.js\";\nimport type { ResolvedConnector } from \"../../core/types.js\";\nimport { fail, print } from \"../app.js\";\n\n/**\n * Parse a relative duration (`Ns`/`Nm`/`Nh`/`Nd`) to a lower-bound epoch ms.\n * Returns undefined for an empty input and null for a malformed one.\n */\nexport function parseSince(since: string | undefined): number | null | undefined {\n if (since == null || since.trim() === \"\") return undefined;\n const m = since.trim().match(/^(\\d+)\\s*([smhd])$/i);\n if (!m || !m[1] || !m[2]) return null;\n const n = Number(m[1]);\n const unitMs: Record<string, number> = {\n s: 1000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n };\n const factor = unitMs[m[2].toLowerCase()];\n if (factor == null) return null;\n return Date.now() - n * factor;\n}\n\n/** Build a QueryFilter from the shared --since / --connector flags. */\nfunction buildFilter(\n since: string | undefined,\n connectorId: string | undefined,\n): QueryFilter | null {\n const sinceMs = parseSince(since);\n if (sinceMs === null) return null;\n const filter: QueryFilter = {};\n if (sinceMs !== undefined) filter.sinceMs = sinceMs;\n if (connectorId && connectorId.trim() !== \"\") filter.connectorId = connectorId;\n return filter;\n}\n\nfunction runReport(argv: string[]): number {\n const { values } = parseArgs({\n args: argv,\n options: {\n by: { type: \"string\", default: \"tool\" },\n since: { type: \"string\" },\n connector: { type: \"string\" },\n json: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const by = values.by;\n if (by !== \"tool\" && by !== \"session\" && by !== \"project\") {\n return fail(`invalid --by \"${by}\" (use tool|session|project)`);\n }\n const dimension: RollupDimension = by;\n\n const filter = buildFilter(values.since, values.connector);\n if (filter === null) {\n return fail(`invalid --since \"${values.since}\" (use forms like 30s, 15m, 24h, 7d)`);\n }\n\n const store = openStore({});\n try {\n const { rows, text } = summarize(store, { by: dimension, filter });\n if (values.json) {\n print(JSON.stringify(rows, null, 2));\n } else {\n print(text);\n }\n } finally {\n store.close();\n }\n return 0;\n}\n\nfunction runExport(argv: string[]): number {\n const { values } = parseArgs({\n args: argv,\n options: {\n format: { type: \"string\", default: \"json\" },\n out: { type: \"string\" },\n since: { type: \"string\" },\n connector: { type: \"string\" },\n },\n allowPositionals: false,\n });\n\n const format = values.format;\n if (format !== \"csv\" && format !== \"json\") {\n return fail(`invalid --format \"${format}\" (use csv|json)`);\n }\n\n const filter = buildFilter(values.since, values.connector);\n if (filter === null) {\n return fail(`invalid --since \"${values.since}\" (use forms like 30s, 15m, 24h, 7d)`);\n }\n\n const store = openStore({});\n let serialized: string;\n try {\n const records = store.query(filter);\n serialized = format === \"csv\" ? toCSV(records) : toJSONExport(records);\n } finally {\n store.close();\n }\n\n if (values.out && values.out.trim() !== \"\") {\n writeFileSync(values.out, serialized, \"utf8\");\n print(`wrote ${format.toUpperCase()} export → ${values.out}`);\n } else {\n print(serialized);\n }\n return 0;\n}\n\n/**\n * `telemetry leaderboard` — rank the per-MCP telemetry by connector (--by mcp,\n * the default and signature \"which MCP server costs the most\" metric), by tool\n * (--by tool), or by developer-axis surface (--by surface — the FIVE surfaces:\n * server + hook runtime rows plus static command/skill/subagent footprints).\n * Honors --since / --connector and the scope slice (--scope).\n */\nasync function runLeaderboard(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n by: { type: \"string\", default: \"mcp\" },\n since: { type: \"string\" },\n connector: { type: \"string\" },\n scope: { type: \"string\" },\n json: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const by = values.by;\n if (by !== \"mcp\" && by !== \"tool\" && by !== \"surface\") {\n return fail(`invalid --by \"${by}\" (use mcp|tool|surface)`);\n }\n\n const sinceMs = parseSince(values.since);\n if (sinceMs === null) {\n return fail(`invalid --since \"${values.since}\" (use forms like 30s, 15m, 24h, 7d)`);\n }\n\n let scope: ScopeFilter | undefined;\n if (values.scope !== undefined && values.scope.trim() !== \"\") {\n const s = values.scope.trim();\n if (!isScopeFilter(s)) {\n return fail(`invalid --scope \"${s}\" (use ${SCOPE_FILTER_VALUES.join(\"|\")})`);\n }\n scope = s;\n }\n\n const opts: LeaderboardOptions = {};\n if (sinceMs !== undefined) opts.sinceMs = sinceMs;\n if (values.connector && values.connector.trim() !== \"\") {\n opts.connectorId = values.connector.trim();\n }\n if (scope !== undefined) opts.scope = scope;\n\n if (by === \"tool\") {\n const rows = toolLeaderboard(opts);\n print(values.json ? JSON.stringify(rows, null, 2) : formatToolLeaderboard(rows));\n } else if (by === \"surface\") {\n // The per-surface view folds the STATIC command/skill/subagent footprints of\n // the registered connector(s) into the runtime server/hook rows.\n const connectorId = values.connector?.trim();\n const surfaceOpts: SurfaceLeaderboardOptions = {\n ...opts,\n connectors: await gatherConnectors(connectorId),\n };\n const rows = surfaceLeaderboard(surfaceOpts);\n print(values.json ? JSON.stringify(rows, null, 2) : formatSurfaceLeaderboard(rows));\n } else {\n const rows = mcpLeaderboard(opts);\n print(values.json ? JSON.stringify(rows, null, 2) : formatMcpLeaderboard(rows));\n }\n return 0;\n}\n\n/**\n * Gather the registered connector(s) whose STATIC command/skill/subagent\n * footprints feed the per-surface view. When `connectorId` is given, prefer the\n * LIVE module (freshest content) and fall back to the persisted meta record;\n * otherwise enumerate every registered connector from its meta. Best-effort: a\n * connector that cannot be loaded is skipped (the surface view still renders the\n * runtime rows it can read from the store).\n */\nasync function gatherConnectors(\n connectorId: string | undefined,\n): Promise<ResolvedConnector[]> {\n if (connectorId !== undefined && connectorId !== \"\") {\n try {\n return [await loadRegisteredConnector(connectorId)];\n } catch {\n const meta = readRegisteredMetaSafe(connectorId);\n return meta ? [connectorFromMeta(meta)] : [];\n }\n }\n return listRegisteredConnectors();\n}\n\n/** readRegisteredMeta wrapped so a missing/corrupt record never throws here. */\nfunction readRegisteredMetaSafe(id: string): ReturnType<typeof readRegisteredMeta> {\n try {\n return readRegisteredMeta(id);\n } catch {\n return null;\n }\n}\n\nexport async function run(argv: string[]): Promise<number> {\n const sub = argv[0];\n const rest = argv.slice(1);\n\n switch (sub) {\n case \"report\":\n return runReport(rest);\n case \"export\":\n return runExport(rest);\n case \"leaderboard\":\n return await runLeaderboard(rest);\n case undefined:\n case \"--help\":\n case \"-h\":\n print(\"usage: agent-connector telemetry <report|export|leaderboard> [flags]\");\n print(\" report --by tool|session|project --since 7d --connector <id> --json\");\n print(\" export --format csv|json --out <file> --since 7d --connector <id>\");\n print(\" leaderboard --by mcp|tool|surface --since 7d --connector <id> --scope <slice> --json\");\n return sub === undefined ? 1 : 0;\n default:\n return fail(`unknown telemetry subcommand \"${sub}\" (use report|export|leaderboard)`);\n }\n}\n","/**\n * telemetry/report — CLI-facing formatting for telemetry rollups and exports.\n *\n * Pure functions: take store output (rollup rows / raw records) and render text,\n * CSV, or JSON. No IO except {@link summarize}, which reads through a passed-in\n * {@link TelemetryStore}. Confidence is surfaced verbatim so heuristic/approx\n * numbers are never mistaken for exact host-reported usage.\n */\n\nimport type { TelemetryStore } from \"./types.js\";\nimport type {\n ConfidenceSource,\n QueryFilter,\n RollupRow,\n ToolEventRecord,\n} from \"./types.js\";\n\n/** Grouping dimension, mirrored from {@link TelemetryStore.rollup}. */\nexport type RollupDimension = \"tool\" | \"session\" | \"project\";\n\n/** Human label for the leading KEY column, per grouping dimension. */\nconst KEY_HEADER: Record<RollupDimension, string> = {\n tool: \"TOOL\",\n session: \"SESSION\",\n project: \"PROJECT\",\n};\n\n/**\n * Sources whose counts are estimates (vs. real / host-reported numbers).\n * `tokenizer-calibrated` is still an estimate — an approximation nudged toward\n * truth by a sampled Anthropic count_tokens factor — so it belongs here too.\n */\nconst ESTIMATE_SOURCES: ReadonlySet<ConfidenceSource> = new Set<ConfidenceSource>([\n \"heuristic\",\n \"tokenizer-approx\",\n \"tokenizer-calibrated\",\n]);\n\n/** Compact, fixed-width integer formatting with thousands separators. */\nfunction fmtInt(n: number): string {\n return n.toLocaleString(\"en-US\");\n}\n\n/** Pad a cell to a column width (right-pad text, used for left-aligned cols). */\nfunction padRight(s: string, width: number): string {\n return s.length >= width ? s : s + \" \".repeat(width - s.length);\n}\n\n/** Pad a cell to a column width (left-pad, used for right-aligned numbers). */\nfunction padLeft(s: string, width: number): string {\n return s.length >= width ? s : \" \".repeat(width - s.length) + s;\n}\n\n/**\n * Render an aligned text table of rollup rows, sorted by total tokens desc, with\n * a TOTAL footer and a short legend noting which confidence labels are estimates.\n */\nexport function formatReport(rows: RollupRow[], by: RollupDimension): string {\n const keyHeader = KEY_HEADER[by];\n const headers = [keyHeader, \"CALLS\", \"IN\", \"OUT\", \"TOTAL\", \"CONFIDENCE\"];\n\n const sorted = [...rows].sort((a, b) => b.totalTokens - a.totalTokens);\n\n // Build the data matrix (string cells) first so we can measure widths.\n const dataRows = sorted.map((r) => [\n r.key,\n fmtInt(r.calls),\n fmtInt(r.inputTokens),\n fmtInt(r.outputTokens),\n fmtInt(r.totalTokens),\n r.confidence,\n ]);\n\n // Totals footer. Confidence is the worst (least-confident) across all rows.\n const totals = sorted.reduce(\n (acc, r) => {\n acc.calls += r.calls;\n acc.inputTokens += r.inputTokens;\n acc.outputTokens += r.outputTokens;\n acc.totalTokens += r.totalTokens;\n return acc;\n },\n { calls: 0, inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n );\n const totalRow = [\n \"TOTAL\",\n fmtInt(totals.calls),\n fmtInt(totals.inputTokens),\n fmtInt(totals.outputTokens),\n fmtInt(totals.totalTokens),\n \"\",\n ];\n\n // Column widths: max over header, every data cell, and the totals row.\n const widths = headers.map((h, col) => {\n let w = h.length;\n for (const row of dataRows) w = Math.max(w, (row[col] ?? \"\").length);\n w = Math.max(w, (totalRow[col] ?? \"\").length);\n return w;\n });\n\n // Column 0 (KEY) is left-aligned; numeric/label columns are right-aligned.\n const renderRow = (cells: string[]): string =>\n cells\n .map((c, col) =>\n col === 0\n ? padRight(c, widths[col] ?? 0)\n : padLeft(c, widths[col] ?? 0),\n )\n .join(\" \")\n .trimEnd();\n\n const ruleWidth = widths.reduce((a, b) => a + b, 0) + 2 * (widths.length - 1);\n const rule = \"-\".repeat(ruleWidth);\n\n const lines: string[] = [];\n lines.push(renderRow(headers));\n lines.push(rule);\n if (dataRows.length === 0) {\n lines.push(\"(no telemetry recorded)\");\n } else {\n for (const row of dataRows) lines.push(renderRow(row));\n }\n lines.push(rule);\n lines.push(renderRow(totalRow));\n\n // Legend — honest labeling of which confidence values are estimates.\n const hasEstimate = sorted.some((r) => ESTIMATE_SOURCES.has(r.confidence));\n if (hasEstimate) {\n lines.push(\"\");\n lines.push(\n \"note: heuristic and tokenizer-approx token counts are estimates, \" +\n \"not exact host-reported usage.\",\n );\n if (sorted.some((r) => r.confidence === \"tokenizer-calibrated\")) {\n lines.push(\n \"note: tokenizer-calibrated = local approx adjusted by a sampled \" +\n \"Anthropic count_tokens factor (opt-in; content sampled off-box only \" +\n \"when AGENT_CONNECTOR_CALIBRATE=anthropic).\",\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Ordered columns for {@link toCSV}, matching the {@link ToolEventRecord} shape. */\nconst CSV_COLUMNS = [\n \"id\",\n \"ts\",\n \"connectorId\",\n \"toolName\",\n \"scope\",\n \"hostPlatform\",\n \"sessionId\",\n \"projectKey\",\n \"projectDir\",\n \"inputTokens\",\n \"outputTokens\",\n \"confidenceSource\",\n \"isError\",\n // installScope / launchMethod mirror the JSON export so the scope dimension is\n // not silently dropped from CSV; absent on a record → an empty cell.\n \"installScope\",\n \"launchMethod\",\n] as const satisfies ReadonlyArray<keyof ToolEventRecord>;\n\n/** RFC-4180-ish CSV escaping: quote when the cell holds a comma, quote, or newline. */\nfunction csvCell(value: unknown): string {\n // An absent field (optional column like installScope/launchMethod) renders as\n // an empty cell rather than the literal \"undefined\" — the JSON export omits\n // the key entirely, so the CSV should likewise carry no value.\n if (value === undefined || value === null) return \"\";\n const s = String(value);\n if (/[\",\\n\\r]/.test(s)) {\n return `\"${s.replace(/\"/g, '\"\"')}\"`;\n }\n return s;\n}\n\n/** Serialize raw records to CSV (header + one line per record, CRLF-terminated). */\nexport function toCSV(records: ToolEventRecord[]): string {\n const lines: string[] = [];\n lines.push(CSV_COLUMNS.join(\",\"));\n for (const record of records) {\n lines.push(CSV_COLUMNS.map((col) => csvCell(record[col])).join(\",\"));\n }\n return lines.join(\"\\r\\n\");\n}\n\n/** Serialize raw records to a pretty-printed JSON array string. */\nexport function toJSONExport(records: ToolEventRecord[]): string {\n return JSON.stringify(records, null, 2);\n}\n\n/** Options for {@link summarize}. */\nexport interface SummarizeOptions {\n /** Grouping dimension. Default \"tool\". */\n by?: RollupDimension;\n /** Query filter forwarded to the store. Default: no filter (all records). */\n filter?: QueryFilter;\n}\n\n/**\n * Roll up a store and render it in one call. Returns the structured rows (for\n * machine use) alongside the formatted text table (for the CLI).\n */\nexport function summarize(\n store: TelemetryStore,\n opts?: SummarizeOptions,\n): { rows: RollupRow[]; text: string } {\n const by = opts?.by ?? \"tool\";\n const filter = opts?.filter ?? {};\n const rows = store.rollup(by, filter);\n return { rows, text: formatReport(rows, by) };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/commands/telemetry.ts","../src/telemetry/report.ts"],"sourcesContent":["/**\n * cli/commands/telemetry — inspect the local per-tool token telemetry store.\n *\n * Subcommands:\n * report --by tool|session|project (default tool) --since 7d|24h|… --connector <id> [--json]\n * → summarize(openStore({}), …) + formatReport (the aligned table).\n * export --format csv|json (default json) --out <file> [--since/--connector …]\n * → toCSV / toJSONExport of the raw records.\n *\n * Telemetry rows are aggregate counts only (never raw arguments/results).\n */\n\nimport { writeFileSync } from \"node:fs\";\nimport { parseArgs } from \"node:util\";\n\nimport type { QueryFilter } from \"../../telemetry/types.js\";\nimport type { RollupDimension } from \"../../telemetry/report.js\";\nimport { openStore } from \"../../telemetry/store.js\";\nimport { summarize, toCSV, toJSONExport } from \"../../telemetry/report.js\";\nimport {\n formatMcpLeaderboard,\n formatSurfaceLeaderboard,\n formatToolLeaderboard,\n isScopeFilter,\n mcpLeaderboard,\n SCOPE_FILTER_VALUES,\n surfaceLeaderboard,\n toolLeaderboard,\n type LeaderboardOptions,\n type ScopeFilter,\n type SurfaceLeaderboardOptions,\n} from \"../../telemetry/leaderboard.js\";\nimport {\n connectorFromMeta,\n listRegisteredConnectors,\n loadRegisteredConnector,\n readRegisteredMeta,\n} from \"../../core/load-connector.js\";\nimport type { ResolvedConnector } from \"../../core/types.js\";\nimport { fail, print } from \"../app.js\";\n\n/**\n * Parse a relative duration (`Ns`/`Nm`/`Nh`/`Nd`) to a lower-bound epoch ms.\n * Returns undefined for an empty input and null for a malformed one.\n */\nexport function parseSince(since: string | undefined): number | null | undefined {\n if (since == null || since.trim() === \"\") return undefined;\n const m = since.trim().match(/^(\\d+)\\s*([smhd])$/i);\n if (!m || !m[1] || !m[2]) return null;\n const n = Number(m[1]);\n const unitMs: Record<string, number> = {\n s: 1000,\n m: 60_000,\n h: 3_600_000,\n d: 86_400_000,\n };\n const factor = unitMs[m[2].toLowerCase()];\n if (factor == null) return null;\n return Date.now() - n * factor;\n}\n\n/** Build a QueryFilter from the shared --since / --connector flags. */\nfunction buildFilter(\n since: string | undefined,\n connectorId: string | undefined,\n): QueryFilter | null {\n const sinceMs = parseSince(since);\n if (sinceMs === null) return null;\n const filter: QueryFilter = {};\n if (sinceMs !== undefined) filter.sinceMs = sinceMs;\n if (connectorId && connectorId.trim() !== \"\") filter.connectorId = connectorId;\n return filter;\n}\n\nfunction runReport(argv: string[]): number {\n const { values } = parseArgs({\n args: argv,\n options: {\n by: { type: \"string\", default: \"tool\" },\n since: { type: \"string\" },\n connector: { type: \"string\" },\n json: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const by = values.by;\n if (by !== \"tool\" && by !== \"session\" && by !== \"project\") {\n return fail(`invalid --by \"${by}\" (use tool|session|project)`);\n }\n const dimension: RollupDimension = by;\n\n const filter = buildFilter(values.since, values.connector);\n if (filter === null) {\n return fail(`invalid --since \"${values.since}\" (use forms like 30s, 15m, 24h, 7d)`);\n }\n\n const store = openStore({});\n try {\n const { rows, text } = summarize(store, { by: dimension, filter });\n if (values.json) {\n print(JSON.stringify(rows, null, 2));\n } else {\n print(text);\n }\n } finally {\n store.close();\n }\n return 0;\n}\n\nfunction runExport(argv: string[]): number {\n const { values } = parseArgs({\n args: argv,\n options: {\n format: { type: \"string\", default: \"json\" },\n out: { type: \"string\" },\n since: { type: \"string\" },\n connector: { type: \"string\" },\n },\n allowPositionals: false,\n });\n\n const format = values.format;\n if (format !== \"csv\" && format !== \"json\") {\n return fail(`invalid --format \"${format}\" (use csv|json)`);\n }\n\n const filter = buildFilter(values.since, values.connector);\n if (filter === null) {\n return fail(`invalid --since \"${values.since}\" (use forms like 30s, 15m, 24h, 7d)`);\n }\n\n const store = openStore({});\n let serialized: string;\n try {\n const records = store.query(filter);\n serialized = format === \"csv\" ? toCSV(records) : toJSONExport(records);\n } finally {\n store.close();\n }\n\n if (values.out && values.out.trim() !== \"\") {\n writeFileSync(values.out, serialized, \"utf8\");\n print(`wrote ${format.toUpperCase()} export → ${values.out}`);\n } else {\n print(serialized);\n }\n return 0;\n}\n\n/**\n * `telemetry leaderboard` — rank the per-MCP telemetry by connector (--by mcp,\n * the default and signature \"which MCP server costs the most\" metric), by tool\n * (--by tool), or by developer-axis surface (--by surface — the FIVE surfaces:\n * server + hook runtime rows plus static command/skill/subagent footprints).\n * Honors --since / --connector and the scope slice (--scope).\n */\nasync function runLeaderboard(argv: string[]): Promise<number> {\n const { values } = parseArgs({\n args: argv,\n options: {\n by: { type: \"string\", default: \"mcp\" },\n since: { type: \"string\" },\n connector: { type: \"string\" },\n scope: { type: \"string\" },\n json: { type: \"boolean\", default: false },\n },\n allowPositionals: false,\n });\n\n const by = values.by;\n if (by !== \"mcp\" && by !== \"tool\" && by !== \"surface\") {\n return fail(`invalid --by \"${by}\" (use mcp|tool|surface)`);\n }\n\n const sinceMs = parseSince(values.since);\n if (sinceMs === null) {\n return fail(`invalid --since \"${values.since}\" (use forms like 30s, 15m, 24h, 7d)`);\n }\n\n let scope: ScopeFilter | undefined;\n if (values.scope !== undefined && values.scope.trim() !== \"\") {\n const s = values.scope.trim();\n if (!isScopeFilter(s)) {\n return fail(`invalid --scope \"${s}\" (use ${SCOPE_FILTER_VALUES.join(\"|\")})`);\n }\n scope = s;\n }\n\n const opts: LeaderboardOptions = {};\n if (sinceMs !== undefined) opts.sinceMs = sinceMs;\n if (values.connector && values.connector.trim() !== \"\") {\n opts.connectorId = values.connector.trim();\n }\n if (scope !== undefined) opts.scope = scope;\n\n if (by === \"tool\") {\n const rows = toolLeaderboard(opts);\n print(values.json ? JSON.stringify(rows, null, 2) : formatToolLeaderboard(rows));\n } else if (by === \"surface\") {\n // The per-surface view folds the STATIC command/skill/subagent footprints of\n // the registered connector(s) into the runtime server/hook rows.\n const connectorId = values.connector?.trim();\n const surfaceOpts: SurfaceLeaderboardOptions = {\n ...opts,\n connectors: await gatherConnectors(connectorId),\n };\n const rows = surfaceLeaderboard(surfaceOpts);\n print(values.json ? JSON.stringify(rows, null, 2) : formatSurfaceLeaderboard(rows));\n } else {\n const rows = mcpLeaderboard(opts);\n print(values.json ? JSON.stringify(rows, null, 2) : formatMcpLeaderboard(rows));\n }\n return 0;\n}\n\n/**\n * Gather the registered connector(s) whose STATIC command/skill/subagent\n * footprints feed the per-surface view. When `connectorId` is given, prefer the\n * LIVE module (freshest content) and fall back to the persisted meta record;\n * otherwise enumerate every registered connector from its meta. Best-effort: a\n * connector that cannot be loaded is skipped (the surface view still renders the\n * runtime rows it can read from the store).\n */\nasync function gatherConnectors(\n connectorId: string | undefined,\n): Promise<ResolvedConnector[]> {\n if (connectorId !== undefined && connectorId !== \"\") {\n try {\n return [await loadRegisteredConnector(connectorId)];\n } catch {\n const meta = readRegisteredMetaSafe(connectorId);\n return meta ? [connectorFromMeta(meta)] : [];\n }\n }\n return listRegisteredConnectors();\n}\n\n/** readRegisteredMeta wrapped so a missing/corrupt record never throws here. */\nfunction readRegisteredMetaSafe(id: string): ReturnType<typeof readRegisteredMeta> {\n try {\n return readRegisteredMeta(id);\n } catch {\n return null;\n }\n}\n\nexport async function run(argv: string[]): Promise<number> {\n const sub = argv[0];\n const rest = argv.slice(1);\n\n switch (sub) {\n case \"report\":\n return runReport(rest);\n case \"export\":\n return runExport(rest);\n case \"leaderboard\":\n return await runLeaderboard(rest);\n case undefined:\n case \"--help\":\n case \"-h\":\n print(\"usage: agent-connector telemetry <report|export|leaderboard> [flags]\");\n print(\" report --by tool|session|project --since 7d --connector <id> --json\");\n print(\" export --format csv|json --out <file> --since 7d --connector <id>\");\n print(\" leaderboard --by mcp|tool|surface --since 7d --connector <id> --scope <slice> --json\");\n return sub === undefined ? 1 : 0;\n default:\n return fail(`unknown telemetry subcommand \"${sub}\" (use report|export|leaderboard)`);\n }\n}\n","/**\n * telemetry/report — CLI-facing formatting for telemetry rollups and exports.\n *\n * Pure functions: take store output (rollup rows / raw records) and render text,\n * CSV, or JSON. No IO except {@link summarize}, which reads through a passed-in\n * {@link TelemetryStore}. Confidence is surfaced verbatim so heuristic/approx\n * numbers are never mistaken for exact host-reported usage.\n */\n\nimport type { TelemetryStore } from \"./types.js\";\nimport type {\n ConfidenceSource,\n QueryFilter,\n RollupRow,\n ToolEventRecord,\n} from \"./types.js\";\n\n/** Grouping dimension, mirrored from {@link TelemetryStore.rollup}. */\nexport type RollupDimension = \"tool\" | \"session\" | \"project\";\n\n/** Human label for the leading KEY column, per grouping dimension. */\nconst KEY_HEADER: Record<RollupDimension, string> = {\n tool: \"TOOL\",\n session: \"SESSION\",\n project: \"PROJECT\",\n};\n\n/**\n * Sources whose counts are estimates (vs. real / host-reported numbers).\n * `tokenizer-calibrated` is still an estimate — an approximation nudged toward\n * truth by a sampled Anthropic count_tokens factor — so it belongs here too.\n */\nconst ESTIMATE_SOURCES: ReadonlySet<ConfidenceSource> = new Set<ConfidenceSource>([\n \"heuristic\",\n \"tokenizer-approx\",\n \"tokenizer-calibrated\",\n]);\n\n/** Compact, fixed-width integer formatting with thousands separators. */\nfunction fmtInt(n: number): string {\n return n.toLocaleString(\"en-US\");\n}\n\n/** Pad a cell to a column width (right-pad text, used for left-aligned cols). */\nfunction padRight(s: string, width: number): string {\n return s.length >= width ? s : s + \" \".repeat(width - s.length);\n}\n\n/** Pad a cell to a column width (left-pad, used for right-aligned numbers). */\nfunction padLeft(s: string, width: number): string {\n return s.length >= width ? s : \" \".repeat(width - s.length) + s;\n}\n\n/**\n * Render an aligned text table of rollup rows, sorted by total tokens desc, with\n * a TOTAL footer and a short legend noting which confidence labels are estimates.\n */\nexport function formatReport(rows: RollupRow[], by: RollupDimension): string {\n const keyHeader = KEY_HEADER[by];\n const headers = [keyHeader, \"CALLS\", \"IN\", \"OUT\", \"TOTAL\", \"CONFIDENCE\"];\n\n const sorted = [...rows].sort((a, b) => b.totalTokens - a.totalTokens);\n\n // Build the data matrix (string cells) first so we can measure widths.\n const dataRows = sorted.map((r) => [\n r.key,\n fmtInt(r.calls),\n fmtInt(r.inputTokens),\n fmtInt(r.outputTokens),\n fmtInt(r.totalTokens),\n r.confidence,\n ]);\n\n // Totals footer. Confidence is the worst (least-confident) across all rows.\n const totals = sorted.reduce(\n (acc, r) => {\n acc.calls += r.calls;\n acc.inputTokens += r.inputTokens;\n acc.outputTokens += r.outputTokens;\n acc.totalTokens += r.totalTokens;\n return acc;\n },\n { calls: 0, inputTokens: 0, outputTokens: 0, totalTokens: 0 },\n );\n const totalRow = [\n \"TOTAL\",\n fmtInt(totals.calls),\n fmtInt(totals.inputTokens),\n fmtInt(totals.outputTokens),\n fmtInt(totals.totalTokens),\n \"\",\n ];\n\n // Column widths: max over header, every data cell, and the totals row.\n const widths = headers.map((h, col) => {\n let w = h.length;\n for (const row of dataRows) w = Math.max(w, (row[col] ?? \"\").length);\n w = Math.max(w, (totalRow[col] ?? \"\").length);\n return w;\n });\n\n // Column 0 (KEY) is left-aligned; numeric/label columns are right-aligned.\n const renderRow = (cells: string[]): string =>\n cells\n .map((c, col) =>\n col === 0\n ? padRight(c, widths[col] ?? 0)\n : padLeft(c, widths[col] ?? 0),\n )\n .join(\" \")\n .trimEnd();\n\n const ruleWidth = widths.reduce((a, b) => a + b, 0) + 2 * (widths.length - 1);\n const rule = \"-\".repeat(ruleWidth);\n\n const lines: string[] = [];\n lines.push(renderRow(headers));\n lines.push(rule);\n if (dataRows.length === 0) {\n lines.push(\"(no telemetry recorded)\");\n } else {\n for (const row of dataRows) lines.push(renderRow(row));\n }\n lines.push(rule);\n lines.push(renderRow(totalRow));\n\n // Legend — honest labeling of which confidence values are estimates.\n const hasEstimate = sorted.some((r) => ESTIMATE_SOURCES.has(r.confidence));\n if (hasEstimate) {\n lines.push(\"\");\n lines.push(\n \"note: heuristic and tokenizer-approx token counts are estimates, \" +\n \"not exact host-reported usage.\",\n );\n if (sorted.some((r) => r.confidence === \"tokenizer-calibrated\")) {\n lines.push(\n \"note: tokenizer-calibrated = local approx adjusted by a sampled \" +\n \"Anthropic count_tokens factor (opt-in; content sampled off-box only \" +\n \"when AGENT_CONNECTOR_CALIBRATE=anthropic).\",\n );\n }\n }\n\n return lines.join(\"\\n\");\n}\n\n/** Ordered columns for {@link toCSV}, matching the {@link ToolEventRecord} shape. */\nconst CSV_COLUMNS = [\n \"id\",\n \"ts\",\n \"connectorId\",\n \"toolName\",\n \"scope\",\n \"hostPlatform\",\n \"sessionId\",\n \"projectKey\",\n \"projectDir\",\n \"inputTokens\",\n \"outputTokens\",\n \"confidenceSource\",\n \"isError\",\n // installScope / launchMethod mirror the JSON export so the scope dimension is\n // not silently dropped from CSV; absent on a record → an empty cell.\n \"installScope\",\n \"launchMethod\",\n] as const satisfies ReadonlyArray<keyof ToolEventRecord>;\n\n/** RFC-4180-ish CSV escaping: quote when the cell holds a comma, quote, or newline. */\nfunction csvCell(value: unknown): string {\n // An absent field (optional column like installScope/launchMethod) renders as\n // an empty cell rather than the literal \"undefined\" — the JSON export omits\n // the key entirely, so the CSV should likewise carry no value.\n if (value === undefined || value === null) return \"\";\n const s = String(value);\n if (/[\",\\n\\r]/.test(s)) {\n return `\"${s.replace(/\"/g, '\"\"')}\"`;\n }\n return s;\n}\n\n/** Serialize raw records to CSV (header + one line per record, CRLF-terminated). */\nexport function toCSV(records: ToolEventRecord[]): string {\n const lines: string[] = [];\n lines.push(CSV_COLUMNS.join(\",\"));\n for (const record of records) {\n lines.push(CSV_COLUMNS.map((col) => csvCell(record[col])).join(\",\"));\n }\n return lines.join(\"\\r\\n\");\n}\n\n/** Serialize raw records to a pretty-printed JSON array string. */\nexport function toJSONExport(records: ToolEventRecord[]): string {\n return JSON.stringify(records, null, 2);\n}\n\n/** Options for {@link summarize}. */\nexport interface SummarizeOptions {\n /** Grouping dimension. Default \"tool\". */\n by?: RollupDimension;\n /** Query filter forwarded to the store. Default: no filter (all records). */\n filter?: QueryFilter;\n}\n\n/**\n * Roll up a store and render it in one call. Returns the structured rows (for\n * machine use) alongside the formatted text table (for the CLI).\n */\nexport function summarize(\n store: TelemetryStore,\n opts?: SummarizeOptions,\n): { rows: RollupRow[]; text: string } {\n const by = opts?.by ?? \"tool\";\n const filter = opts?.filter ?? {};\n const rows = store.rollup(by, filter);\n return { rows, text: formatReport(rows, by) };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -4,13 +4,14 @@ import {
|
|
|
4
4
|
} from "./chunk-DBQMX75U.js";
|
|
5
5
|
import {
|
|
6
6
|
BaseAdapter
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-PD4VFEBY.js";
|
|
8
8
|
import "./chunk-7L6ITC4T.js";
|
|
9
9
|
import {
|
|
10
10
|
buildServeWrapperCommand,
|
|
11
11
|
isHomeBinHookCommand,
|
|
12
12
|
shouldWrapForTelemetry
|
|
13
13
|
} from "./chunk-MEH7GC7R.js";
|
|
14
|
+
import "./chunk-N6HH7K6P.js";
|
|
14
15
|
import "./chunk-TRQKHP7D.js";
|
|
15
16
|
|
|
16
17
|
// src/adapters/trae/index.ts
|
|
@@ -24,6 +25,9 @@ var TraeAdapter = class extends BaseAdapter {
|
|
|
24
25
|
name = "Trae";
|
|
25
26
|
paradigm = "mcp-only";
|
|
26
27
|
capabilities = {
|
|
28
|
+
// Memory surface: AGENTS.md-first managed block via the BaseAdapter default
|
|
29
|
+
// (memoryTargets: project <projectDir>/AGENTS.md; user scope where documented).
|
|
30
|
+
supportsMemory: true,
|
|
27
31
|
// Trae has no lifecycle hook system we can target — every hook capability
|
|
28
32
|
// is false.
|
|
29
33
|
preToolUse: false,
|
|
@@ -180,6 +184,9 @@ var TraeAdapter = class extends BaseAdapter {
|
|
|
180
184
|
{
|
|
181
185
|
name: `${this.name}: server entry registered`,
|
|
182
186
|
check: () => {
|
|
187
|
+
if (!ctx.connector.server) {
|
|
188
|
+
return { status: "OK", detail: "no MCP server declared" };
|
|
189
|
+
}
|
|
183
190
|
const cfg = this.readJson(mcpPath);
|
|
184
191
|
const bucket = cfg?.[MCP_ROOT_KEY];
|
|
185
192
|
if (!cfg || !bucket) {
|
|
@@ -201,4 +208,4 @@ export {
|
|
|
201
208
|
adapter,
|
|
202
209
|
trae_default as default
|
|
203
210
|
};
|
|
204
|
-
//# sourceMappingURL=trae-
|
|
211
|
+
//# sourceMappingURL=trae-CQC72RHH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapters/trae/index.ts"],"sourcesContent":["/**\n * adapters/trae — Trae (ByteDance) platform adapter for agent-connector.\n *\n * Trae is an **mcp-only** host for our purposes: it exposes MCP servers as its\n * extensibility mechanism but has no lifecycle hook system we can register\n * against. This adapter therefore installs only the MCP server and reports hooks\n * as unavailable, mirroring the Warp reference path that validates the\n * `mcp-only` paradigm end-to-end.\n *\n * MCP config (medium-confidence path — still implemented; doctor reports presence):\n * - user scope → ~/.trae/mcp.json\n * - project scope → <projectDir>/.trae/mcp.json\n * Both are JSON, root key \"mcpServers\", and are the SAME file used for the\n * (non-existent) hook registration — there is no separate hook file here.\n *\n * A stdio server entry uses the standard Claude/Cursor shape:\n * { command, args, env } (object-keyed by connector id).\n *\n * Trae documents no native `${env:VAR}` interpolation token, so env/header/url\n * refs are resolved to literals at install time (the no-native-token path).\n */\n\nimport { existsSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport type { Adapter, InstallContext } from \"../spi.js\";\nimport type {\n ChangeRecord,\n DetectedPlatform,\n HealthCheck,\n HookParadigm,\n PlatformCapabilities,\n PlatformId,\n ServerDef,\n Transport,\n} from \"../../core/types.js\";\nimport { resolveEnvRefsDeep } from \"../../core/interpolate.js\";\nimport {\n buildServeWrapperCommand,\n isHomeBinHookCommand,\n shouldWrapForTelemetry,\n} from \"../../core/spawn.js\";\n\nconst HOST: PlatformId = \"trae\";\nconst MCP_ROOT_KEY = \"mcpServers\";\n\n/** Native MCP server entry shapes Trae accepts under `mcpServers`. */\ninterface TraeStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\ninterface TraeHttpServer {\n url: string;\n headers?: Record<string, string>;\n}\n\nexport class TraeAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Trae\";\n readonly paradigm: HookParadigm = \"mcp-only\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: AGENTS.md-first managed block via the BaseAdapter default\n // (memoryTargets: project <projectDir>/AGENTS.md; user scope where documented).\n supportsMemory: true,\n // Trae has no lifecycle hook system we can target — every hook capability\n // is false.\n preToolUse: false,\n postToolUse: false,\n preCompact: false,\n sessionStart: false,\n sessionEnd: false,\n userPromptSubmit: false,\n stop: false,\n notification: false,\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: false,\n // Trae registers stdio, SSE, and Streamable HTTP MCP servers.\n transports: [\"stdio\", \"sse\", \"http\"],\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(projectDir: string): DetectedPlatform {\n const userDir = join(homedir(), \".trae\");\n const userMcp = join(userDir, \"mcp.json\");\n const projDir = join(projectDir, \".trae\");\n const projMcp = join(projDir, \"mcp.json\");\n\n const userInstalled = existsSync(userDir) || existsSync(userMcp);\n const projInstalled = existsSync(projDir) || existsSync(projMcp);\n const installed = userInstalled || projInstalled;\n const scope = projInstalled && !userInstalled ? \"project\" : \"user\";\n const configPath = scope === \"project\" ? projMcp : userMcp;\n\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath,\n scope,\n reason: installed\n ? `found Trae config (${scope})`\n : `no Trae config at ${userDir} or ${projDir}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n getConfigDir(ctx: InstallContext): string {\n return ctx.scope === \"project\"\n ? join(ctx.projectDir, \".trae\")\n : join(homedir(), \".trae\");\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"mcp.json\");\n }\n\n /**\n * Trae has no hook file — hooks are not a thing here. The hook \"config path\"\n * is the same mcp.json so the generic doctor/backup behave sensibly.\n */\n getHookConfigPath(ctx: InstallContext): string {\n return this.getServerConfigPath(ctx);\n }\n\n // ── MCP server install / uninstall ───────────────────────────────────────\n\n installServer(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const override = connector.platforms[HOST]?.server;\n if (!connector.server || override === false) {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: connector.server\n ? \"server registration disabled for trae\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n // Shallow-merge any per-platform server override into the base ServerDef.\n const server: ServerDef =\n override && typeof override === \"object\"\n ? { ...connector.server, ...override }\n : connector.server;\n\n const serverPath = this.getServerConfigPath(ctx);\n const entry = this.renderServerEntry(ctx, server);\n\n return [\n this.upsertServerInJson(serverPath, MCP_ROOT_KEY, connector.id, entry, ctx.dryRun),\n ];\n }\n\n uninstallServer(ctx: InstallContext): ChangeRecord[] {\n const serverPath = this.getServerConfigPath(ctx);\n return [\n this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun),\n ];\n }\n\n /** Render a normalized ServerDef into Trae's native mcpServers entry. */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): TraeStdioServer | TraeHttpServer {\n const transport: Transport = server.transport;\n\n if (transport === \"stdio\") {\n let command = server.command ?? \"\";\n let args = [...(server.args ?? [])];\n\n // Transparent telemetry wrapping: route the real command through\n // `<homeBin> serve --connector <id> -- <command> <args...>`.\n if (shouldWrapForTelemetry(server, ctx.connector.telemetry)) {\n const wrapped = buildServeWrapperCommand(\n ctx.homeBinPath,\n ctx.connector.id,\n command,\n args,\n ctx.scope,\n this.id,\n );\n command = wrapped.command;\n args = wrapped.args;\n }\n\n // Trae has no documented native interpolation token, so resolve every\n // ${env:VAR} to a literal at install time.\n const entry: TraeStdioServer = { command: resolveEnvRefsDeep(command) };\n if (args.length > 0) entry.args = resolveEnvRefsDeep(args);\n const env = this.renderEnv(server.env);\n if (env) entry.env = env;\n return entry;\n }\n\n // sse / http (and any other remote transport) — Trae registers a URL.\n const entry: TraeHttpServer = { url: resolveEnvRefsDeep(server.url ?? \"\") };\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /**\n * Render env/header values. Trae documents no native interpolation token, so\n * resolve `${env:VAR}` references to literals at install time.\n */\n private renderEnv(\n env: Record<string, string> | undefined,\n ): Record<string, string> | undefined {\n if (!env || Object.keys(env).length === 0) return undefined;\n return resolveEnvRefsDeep({ ...env });\n }\n\n // ── Hooks (unavailable — Trae is mcp-only) ───────────────────────────────\n\n installHooks(_ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"hooks unavailable (Trae is mcp-only)\",\n },\n ];\n }\n\n uninstallHooks(_ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"hooks unavailable (Trae is mcp-only)\",\n },\n ];\n }\n\n /**\n * True when a hook command references our home binary AND this connector id\n * (anchored so a shared-prefix id can't collide — see isHomeBinHookCommand).\n * Trae installs no hooks, but this guard keeps any future shared-file edit\n * from removing another connector's entries.\n */\n private isOurCommand(command: string | undefined, ctx: InstallContext): boolean {\n return isHomeBinHookCommand(command, ctx.homeBinPath, ctx.connector.id);\n }\n\n // ── Diagnostics ──────────────────────────────────────────────────────────\n\n override getHealthChecks(ctx: InstallContext): readonly HealthCheck[] {\n const mcpPath = this.getServerConfigPath(ctx);\n const connectorId = ctx.connector.id;\n return [\n {\n name: `${this.name}: mcp.json present`,\n check: () =>\n existsSync(mcpPath)\n ? { status: \"OK\", detail: mcpPath }\n : { status: \"FAIL\", detail: `not found: ${mcpPath}` },\n },\n {\n name: `${this.name}: server entry registered`,\n check: () => {\n // Only assert what the connector declares: a server-less connector —\n // e.g. a catalog-only bundle of agents/skills/commands — never writes\n // an mcpServers entry, so its absence is healthy.\n if (!ctx.connector.server) {\n return { status: \"OK\", detail: \"no MCP server declared\" };\n }\n const cfg = this.readJson<{ [k: string]: Record<string, unknown> }>(mcpPath);\n const bucket = cfg?.[MCP_ROOT_KEY];\n if (!cfg || !bucket) {\n return { status: \"FAIL\", detail: `no ${MCP_ROOT_KEY} in ${mcpPath}` };\n }\n return connectorId in bucket\n ? { status: \"OK\", detail: `${MCP_ROOT_KEY}.${connectorId} present` }\n : {\n status: \"FAIL\",\n detail: `no ${MCP_ROOT_KEY}.${connectorId} in ${mcpPath}`,\n };\n },\n },\n ];\n }\n}\n\nexport const adapter = new TraeAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
|