@ken-jo/agent-connector 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/README.md +3 -3
  2. package/dist/{action-LEYTHNIU.js → action-EKK6FMPY.js} +8 -8
  3. package/dist/{audit-HPKCUCES.js → audit-H7PQWIVH.js} +5 -5
  4. package/dist/{chunk-BXPSDNIB.js → chunk-34RRWEWU.js} +2 -2
  5. package/dist/{chunk-SFY6YLVK.js → chunk-4YOYR3T5.js} +5 -6
  6. package/dist/{chunk-SFY6YLVK.js.map → chunk-4YOYR3T5.js.map} +1 -1
  7. package/dist/{chunk-6WN37NVN.js → chunk-6FRAVOVF.js} +2 -2
  8. package/dist/{chunk-2Y2MZRLP.js → chunk-CWUPIT72.js} +2 -2
  9. package/dist/{chunk-6XMV2OOA.js → chunk-CZOXXS77.js} +3 -3
  10. package/dist/{chunk-IRUYJD23.js → chunk-IVJUPNLD.js} +2 -8
  11. package/dist/chunk-IVJUPNLD.js.map +1 -0
  12. package/dist/{chunk-FKW5A6HE.js → chunk-IY3SSCNK.js} +4 -4
  13. package/dist/{chunk-U2XJWG7N.js → chunk-JUBEM3OR.js} +2 -2
  14. package/dist/{chunk-UM5S7DKK.js → chunk-KOFCNA5T.js} +11 -2
  15. package/dist/{chunk-UM5S7DKK.js.map → chunk-KOFCNA5T.js.map} +1 -1
  16. package/dist/{chunk-4KIXXJ7B.js → chunk-KY2VQGD7.js} +2 -2
  17. package/dist/{chunk-M6OS4OLU.js → chunk-R4FABNAL.js} +2 -2
  18. package/dist/{chunk-T5AI3AW3.js → chunk-SA6CSOH5.js} +19 -19
  19. package/dist/{chunk-G5HAIYRM.js → chunk-XJSVJD5T.js} +37 -29
  20. package/dist/chunk-XJSVJD5T.js.map +1 -0
  21. package/dist/{chunk-WZMSSIDN.js → chunk-XSR3GF55.js} +14 -6
  22. package/dist/chunk-XSR3GF55.js.map +1 -0
  23. package/dist/{claude-code-LJ6DVXWQ.js → claude-code-VEERATN5.js} +4 -4
  24. package/dist/cli/sdk.js +4 -4
  25. package/dist/cli.js +1 -1
  26. package/dist/{cline-JAPJNOZQ.js → cline-UW6WCQRK.js} +2 -2
  27. package/dist/cline-UW6WCQRK.js.map +1 -0
  28. package/dist/{codebuff-3VODFPD4.js → codebuff-R7QBLCSJ.js} +11 -11
  29. package/dist/codebuff-R7QBLCSJ.js.map +1 -0
  30. package/dist/{codex-RXIS5BHM.js → codex-S2RADR5K.js} +2 -2
  31. package/dist/{crush-YB3SK6NK.js → crush-AJNQRFVE.js} +2 -2
  32. package/dist/{define-connector-odRHEC4H.d.ts → define-connector-iosc34CA.d.ts} +1 -1
  33. package/dist/{detect-USP5JMWM.js → detect-ZC344YOJ.js} +4 -4
  34. package/dist/{doctor-VSW5KHBM.js → doctor-ABYQF2YX.js} +13 -13
  35. package/dist/{goose-3X7ID7YW.js → goose-SXFRT7UF.js} +2 -2
  36. package/dist/grok-build-EP2ZUFXZ.js +682 -0
  37. package/dist/grok-build-EP2ZUFXZ.js.map +1 -0
  38. package/dist/{grok-cli-4VFVF2CQ.js → grok-cli-UUNPOUYY.js} +4 -3
  39. package/dist/grok-cli-UUNPOUYY.js.map +1 -0
  40. package/dist/{hook-QRW3ON6C.js → hook-M3KQSEO3.js} +8 -8
  41. package/dist/index.d.ts +3 -3
  42. package/dist/index.js +2 -2
  43. package/dist/{install-ASTAUZKB.js → install-4X4JDKGY.js} +10 -10
  44. package/dist/{introspect-gTx6GzpW.d.ts → introspect-z3eKVWHN.d.ts} +1 -1
  45. package/dist/{kilo-SW7BH6EG.js → kilo-FVBFSS4Y.js} +1 -1
  46. package/dist/kilo-FVBFSS4Y.js.map +1 -0
  47. package/dist/{kilo-T4OXNUYY.js → kilo-N5T6KXAG.js} +2 -2
  48. package/dist/{kilo-cli-I2S3W245.js → kilo-cli-JOAEWYI4.js} +2 -2
  49. package/dist/{leaderboard-3XSVSGAJ.js → leaderboard-Q4YZ3LI7.js} +3 -3
  50. package/dist/{mux-BO2L5CTW.js → mux-WSZWWZOX.js} +27 -21
  51. package/dist/mux-WSZWWZOX.js.map +1 -0
  52. package/dist/{package-VWBPHCLA.js → package-FY2QZWRM.js} +6 -6
  53. package/dist/runtime/index.d.ts +1 -1
  54. package/dist/runtime/index.js +6 -6
  55. package/dist/sdk/index.d.ts +4 -4
  56. package/dist/sdk/index.js +3 -3
  57. package/dist/sdk/test.d.ts +2 -2
  58. package/dist/sdk/test.js +6 -6
  59. package/dist/{serve-IQGHE4SJ.js → serve-XT76DWUN.js} +8 -8
  60. package/dist/{status-BVLY6XDL.js → status-DHVWBRLI.js} +8 -8
  61. package/dist/{statusline-PRODZV2J.js → statusline-SY5UBQOJ.js} +7 -7
  62. package/dist/{telemetry-UU4SHJ23.js → telemetry-TJIFAKWX.js} +5 -5
  63. package/dist/{types-DWXnnx-N.d.ts → types-CAKApZpX.d.ts} +4 -4
  64. package/dist/{uninstall-WI5YLDCT.js → uninstall-VQO36IQ4.js} +10 -10
  65. package/dist/{upgrade-L45BTG6X.js → upgrade-QEYZOA7S.js} +10 -10
  66. package/dist/{usage-K3NQTAJP.js → usage-LV7UGO64.js} +3 -3
  67. package/dist/{usage-event-J5CQ6LNT.js → usage-event-MQMKMK2R.js} +7 -7
  68. package/dist/{windsurf-R6D2JUTN.js → windsurf-ZWVFNJ73.js} +1 -1
  69. package/dist/windsurf-ZWVFNJ73.js.map +1 -0
  70. package/dist/{zed-DQV3ZUCU.js → zed-JCOKXOLA.js} +2 -2
  71. package/package.json +1 -1
  72. package/dist/chunk-G5HAIYRM.js.map +0 -1
  73. package/dist/chunk-IRUYJD23.js.map +0 -1
  74. package/dist/chunk-WZMSSIDN.js.map +0 -1
  75. package/dist/cline-JAPJNOZQ.js.map +0 -1
  76. package/dist/codebuff-3VODFPD4.js.map +0 -1
  77. package/dist/grok-cli-4VFVF2CQ.js.map +0 -1
  78. package/dist/kilo-SW7BH6EG.js.map +0 -1
  79. package/dist/mux-BO2L5CTW.js.map +0 -1
  80. package/dist/roo-code-SUWI4BBN.js +0 -229
  81. package/dist/roo-code-SUWI4BBN.js.map +0 -1
  82. package/dist/roo-code-VI2ZKTZC.js +0 -361
  83. package/dist/roo-code-VI2ZKTZC.js.map +0 -1
  84. package/dist/windsurf-R6D2JUTN.js.map +0 -1
  85. /package/dist/{action-LEYTHNIU.js.map → action-EKK6FMPY.js.map} +0 -0
  86. /package/dist/{audit-HPKCUCES.js.map → audit-H7PQWIVH.js.map} +0 -0
  87. /package/dist/{chunk-BXPSDNIB.js.map → chunk-34RRWEWU.js.map} +0 -0
  88. /package/dist/{chunk-6WN37NVN.js.map → chunk-6FRAVOVF.js.map} +0 -0
  89. /package/dist/{chunk-2Y2MZRLP.js.map → chunk-CWUPIT72.js.map} +0 -0
  90. /package/dist/{chunk-6XMV2OOA.js.map → chunk-CZOXXS77.js.map} +0 -0
  91. /package/dist/{chunk-FKW5A6HE.js.map → chunk-IY3SSCNK.js.map} +0 -0
  92. /package/dist/{chunk-U2XJWG7N.js.map → chunk-JUBEM3OR.js.map} +0 -0
  93. /package/dist/{chunk-4KIXXJ7B.js.map → chunk-KY2VQGD7.js.map} +0 -0
  94. /package/dist/{chunk-M6OS4OLU.js.map → chunk-R4FABNAL.js.map} +0 -0
  95. /package/dist/{chunk-T5AI3AW3.js.map → chunk-SA6CSOH5.js.map} +0 -0
  96. /package/dist/{claude-code-LJ6DVXWQ.js.map → claude-code-VEERATN5.js.map} +0 -0
  97. /package/dist/{codex-RXIS5BHM.js.map → codex-S2RADR5K.js.map} +0 -0
  98. /package/dist/{crush-YB3SK6NK.js.map → crush-AJNQRFVE.js.map} +0 -0
  99. /package/dist/{detect-USP5JMWM.js.map → detect-ZC344YOJ.js.map} +0 -0
  100. /package/dist/{doctor-VSW5KHBM.js.map → doctor-ABYQF2YX.js.map} +0 -0
  101. /package/dist/{goose-3X7ID7YW.js.map → goose-SXFRT7UF.js.map} +0 -0
  102. /package/dist/{hook-QRW3ON6C.js.map → hook-M3KQSEO3.js.map} +0 -0
  103. /package/dist/{install-ASTAUZKB.js.map → install-4X4JDKGY.js.map} +0 -0
  104. /package/dist/{kilo-T4OXNUYY.js.map → kilo-N5T6KXAG.js.map} +0 -0
  105. /package/dist/{kilo-cli-I2S3W245.js.map → kilo-cli-JOAEWYI4.js.map} +0 -0
  106. /package/dist/{leaderboard-3XSVSGAJ.js.map → leaderboard-Q4YZ3LI7.js.map} +0 -0
  107. /package/dist/{package-VWBPHCLA.js.map → package-FY2QZWRM.js.map} +0 -0
  108. /package/dist/{serve-IQGHE4SJ.js.map → serve-XT76DWUN.js.map} +0 -0
  109. /package/dist/{status-BVLY6XDL.js.map → status-DHVWBRLI.js.map} +0 -0
  110. /package/dist/{statusline-PRODZV2J.js.map → statusline-SY5UBQOJ.js.map} +0 -0
  111. /package/dist/{telemetry-UU4SHJ23.js.map → telemetry-TJIFAKWX.js.map} +0 -0
  112. /package/dist/{uninstall-WI5YLDCT.js.map → uninstall-VQO36IQ4.js.map} +0 -0
  113. /package/dist/{upgrade-L45BTG6X.js.map → upgrade-QEYZOA7S.js.map} +0 -0
  114. /package/dist/{usage-K3NQTAJP.js.map → usage-LV7UGO64.js.map} +0 -0
  115. /package/dist/{usage-event-J5CQ6LNT.js.map → usage-event-MQMKMK2R.js.map} +0 -0
  116. /package/dist/{zed-DQV3ZUCU.js.map → zed-JCOKXOLA.js.map} +0 -0
@@ -1,17 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  runUsageEvent
4
- } from "./chunk-SFY6YLVK.js";
4
+ } from "./chunk-4YOYR3T5.js";
5
5
  import "./chunk-OP4KBXUO.js";
6
6
  import "./chunk-GDIAHWNY.js";
7
- import "./chunk-4KIXXJ7B.js";
8
- import "./chunk-6XMV2OOA.js";
7
+ import "./chunk-KY2VQGD7.js";
8
+ import "./chunk-CZOXXS77.js";
9
9
  import "./chunk-IVAWP6HH.js";
10
10
  import "./chunk-KHO5WNTP.js";
11
11
  import "./chunk-4NFDNY3C.js";
12
- import "./chunk-M6OS4OLU.js";
13
- import "./chunk-6WN37NVN.js";
14
- import "./chunk-G5HAIYRM.js";
12
+ import "./chunk-R4FABNAL.js";
13
+ import "./chunk-6FRAVOVF.js";
14
+ import "./chunk-XJSVJD5T.js";
15
15
  import "./chunk-NBYKLUF6.js";
16
16
  import "./chunk-QSY74NAP.js";
17
17
  import "./chunk-UMQ6NBQR.js";
@@ -51,4 +51,4 @@ async function run(argv) {
51
51
  export {
52
52
  run
53
53
  };
54
- //# sourceMappingURL=usage-event-J5CQ6LNT.js.map
54
+ //# sourceMappingURL=usage-event-MQMKMK2R.js.map
@@ -426,4 +426,4 @@ export {
426
426
  adapter,
427
427
  windsurf_default as default
428
428
  };
429
- //# sourceMappingURL=windsurf-R6D2JUTN.js.map
429
+ //# sourceMappingURL=windsurf-ZWVFNJ73.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/adapters/windsurf/index.ts"],"sourcesContent":["/**\n * adapters/windsurf — Windsurf (Codeium / Cognition's Cascade agent) adapter.\n *\n * Windsurf is an mcp-only host from agent-connector's perspective: there is no\n * user-installable hook/plugin layer (it is a GUI editor). AC registers the MCP\n * server PLUS three content surfaces (memory, workflows, skills — see below). The\n * MCP config is a Claude-Desktop-style OBJECT map keyed by server name (exactly\n * like the cursor adapter's `mcpServers`), NOT an array.\n *\n * MCP config (primary-verified — docs.devin.ai/desktop/cascade/mcp, formerly\n * docs.windsurf.com):\n * - user/global scope ONLY → ~/.codeium/windsurf/mcp_config.json\n * (Windows %USERPROFILE%\\.codeium\\windsurf\\mcp_config.json — homedir()\n * covers it). The docs specify NO project/workspace config path, so a\n * project-scope install returns a skip ChangeRecord.\n * - root key \"mcpServers\" — a JSON object/map keyed by server name.\n *\n * Server entry shapes (primary-verified):\n * - stdio: { command, args?, env? }\n * - remote: { serverUrl, headers? } — the docs use `serverUrl` (an `url`\n * alias is mentioned but `serverUrl` is the documented primary). There is\n * NO `type` discriminator and NO `disabled` field — stdio vs remote is\n * distinguished by `command` vs `serverUrl`. `headers` is emitted only when\n * the connector's remote server provides them.\n *\n * Native interpolation: Windsurf supports `${env:VAR}` / `${file:/path}`\n * tokens, but AC does not need to emit those — values are resolved to literals\n * at install time (the safe path, same as droid/crush/amazon-q).\n *\n * Memory / rules (primary-verified — docs.windsurf.com/windsurf/cascade/rules,\n * llms-full.txt): a `.windsurf/rules/` workspace directory holds `.md` rule\n * files, each declaring an activation mode \"in its frontmatter via the `trigger`\n * field\". `trigger: always_on` means \"full rule content is included in the\n * system prompt on every message\" (the docs' literal Activation-Modes table).\n * AC owns a DEDICATED file there (`.windsurf/rules/agent-connector.md`) that MUST\n * LEAD with that always-on frontmatter, so — like the continue adapter and unlike\n * the cline/amazon-q managed-block targets — we write the WHOLE file\n * (frontmatter + body) via the content-file writers and own it end-to-end\n * (install creates, uninstall deletes). The connector's memory `content` is\n * host-agnostic (MemoryDef forbids its own frontmatter), so the always-on\n * directive is an adapter-level wrapper. WORKSPACE/PROJECT SCOPE: `global_rules.md`\n * is a single SHARED global file (not an AC-owned dir), so user scope skip-warns.\n *\n * Content surfaces — workflows (slash commands) + skills, BOTH project AND user\n * scope:\n * - workflows → project `<projectDir>/.windsurf/workflows/<name>.md`,\n * user `~/.codeium/windsurf/global_workflows/<name>.md` (the user dir is\n * `global_workflows`, NOT `workflows`). Each becomes a `/<name>` slash\n * command. Windsurf caps each workflow file at 12,000 chars — over-budget\n * files are still written but warned.\n * - skills → project `<projectDir>/.windsurf/skills/<name>/SKILL.md`,\n * user `~/.codeium/windsurf/skills/<name>/SKILL.md` (the dir is `skills` in\n * BOTH scopes). Same SKILL.md convention cline/claude-code/qwen-code use.\n * Both reuse the shared claude-code renderers (renderCommandMd/renderSkillMd).\n *\n * Hook \"config path\" is aliased to the MCP file (no separate hook file) so the\n * base doctor/backup helpers behave sensibly (the amazon-q / cline idiom).\n */\n\nimport { existsSync, statSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { basename, join } from \"node:path\";\n\nimport { BaseAdapter } from \"../base.js\";\nimport { renderCommandMd, renderSkillMd } from \"../claude-code/render.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 buildWrappedStdio,\n} from \"../../core/spawn.js\";\n\nconst HOST: PlatformId = \"windsurf\";\nconst MCP_ROOT_KEY = \"mcpServers\";\n\n/**\n * Windsurf caps each workflow (slash-command) file at 12,000 characters\n * (docs.windsurf.com). We still write an over-budget file but emit a warn so the\n * author can trim it, mirroring base.ts's memory soft-budget warn. Skills have no\n * documented size cap, so they are not guarded.\n */\nconst WORKFLOW_MAX_CHARS = 12000;\n\n/**\n * Native MCP server entry shapes Windsurf accepts under `mcpServers` (an OBJECT\n * map keyed by server name, Claude-Desktop-style):\n * - stdio: { command, args?, env? } — transport inferred from `command`.\n * - remote: { serverUrl, headers? } — `serverUrl` (NOT `url`); NO `type`\n * discriminator and NO `disabled` flag. `headers` only when provided.\n */\ninterface WindsurfStdioServer {\n command: string;\n args?: string[];\n env?: Record<string, string>;\n}\ninterface WindsurfRemoteServer {\n serverUrl: string;\n headers?: Record<string, string>;\n}\n\nexport class WindsurfAdapter extends BaseAdapter implements Adapter {\n readonly id: PlatformId = HOST;\n readonly name = \"Windsurf\";\n readonly paradigm: HookParadigm = \"mcp-only\";\n\n readonly capabilities: PlatformCapabilities = {\n // Memory surface: WIRED. Windsurf reads `.windsurf/rules/*.md` (NOT\n // AGENTS.md), so the AGENTS.md-first BaseAdapter default does not apply — the\n // installMemory/uninstallMemory overrides below write a DEDICATED\n // agent-connector-owned file (<projectDir>/.windsurf/rules/agent-connector.md)\n // that LEADS with `trigger: always_on` frontmatter (full content in the\n // system prompt on every message). Workspace/project scope only; user scope\n // skip-warns (global_rules.md is a shared global file, not an AC-owned dir).\n supportsMemory: true,\n //\n // mcp-only: Windsurf is a GUI editor with no user-installable hook/plugin\n // layer. Every hook flag 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 // No hook layer → no arg/output rewrite, no context injection.\n canModifyArgs: false,\n canModifyOutput: false,\n canInjectSessionContext: false,\n // Windsurf registers stdio + remote (http/sse) MCP servers; the remote\n // entry is distinguished by `serverUrl` (vs stdio's `command`).\n transports: [\"stdio\", \"http\", \"sse\"],\n // Content surfaces: WIRED in BOTH scopes. Windsurf reads user-authored\n // WORKFLOWS (each becomes a `/<name>` slash command) and Agent SKILLS (the\n // same SKILL.md frontmatter convention cline/claude-code/qwen-code use):\n // workflows → project .windsurf/workflows/<name>.md,\n // user ~/.codeium/windsurf/global_workflows/<name>.md\n // skills → project .windsurf/skills/<name>/SKILL.md,\n // user ~/.codeium/windsurf/skills/<name>/SKILL.md\n // The install overrides below branch the path on ctx.scope and write at both.\n // Subagents stay UNSET (no documented user-authored dir): base skip-warns.\n supportsCommands: true,\n supportsSkills: true,\n };\n\n // ── Detection ────────────────────────────────────────────────────────────\n\n detectInstalled(_projectDir: string): DetectedPlatform {\n const userDir = join(homedir(), \".codeium\", \"windsurf\");\n const userMcp = join(userDir, \"mcp_config.json\");\n const installed = existsSync(userDir) || existsSync(userMcp);\n return {\n id: this.id,\n name: this.name,\n installed,\n paradigm: this.paradigm,\n capabilities: this.capabilities,\n configPath: userMcp,\n scope: \"user\",\n reason: installed\n ? `found Windsurf config under ${userDir}`\n : `no Windsurf config at ${userDir}`,\n confidence: installed ? \"high\" : \"low\",\n };\n }\n\n // ── Native paths ─────────────────────────────────────────────────────────\n\n /**\n * Windsurf's MCP config is USER/GLOBAL scope only — the docs specify no\n * project/workspace path. getConfigDir always resolves the user dir\n * (homedir() covers USERPROFILE on Windows); a project-scope install is\n * handled by installServer returning a skip, never a write under projectDir.\n */\n getConfigDir(_ctx: InstallContext): string {\n return join(homedir(), \".codeium\", \"windsurf\");\n }\n\n getServerConfigPath(ctx: InstallContext): string {\n return join(this.getConfigDir(ctx), \"mcp_config.json\");\n }\n\n /**\n * Windsurf has no separate hook file — hook config path aliases the MCP file\n * so the generic doctor/backup helpers behave sensibly (amazon-q idiom).\n */\n getHookConfigPath(ctx: InstallContext): string {\n return this.getServerConfigPath(ctx);\n }\n\n // ── Memory surface: the `.windsurf/rules` content tree ────────────────────\n // A DEDICATED agent-connector-owned file that MUST LEAD with `trigger:\n // always_on` frontmatter (full content in the system prompt on every message).\n // Because of that leading frontmatter we do NOT use the base managed-block\n // engine — we own the whole file via the content-file writers: install\n // writes/updates it idempotently, uninstall deletes it. WORKSPACE/PROJECT scope\n // only (global_rules.md is a shared global file, not an AC-owned dir).\n\n /** <projectDir>/.windsurf/rules/agent-connector.md — the dedicated owned file. */\n private memoryFilePath(ctx: InstallContext): string {\n return join(ctx.projectDir, \".windsurf\", \"rules\", \"agent-connector.md\");\n }\n\n /** True when `<projectDir>/.windsurf/rules` exists and is a regular FILE. */\n private rulesDirIsFile(ctx: InstallContext): boolean {\n const p = join(ctx.projectDir, \".windsurf\", \"rules\");\n if (!existsSync(p)) return false;\n try {\n return statSync(p).isFile();\n } catch {\n return false;\n }\n }\n\n /**\n * Compose the dedicated rule file: `trigger: always_on` frontmatter (the\n * always-on activation directive) + every declared memory entry's content,\n * joined with a blank line. The connector's content is host-agnostic markdown\n * (MemoryDef forbids its own frontmatter), so the directive is ours to add.\n */\n private renderMemoryFile(ctx: InstallContext): string {\n const body = (ctx.connector.memory ?? [])\n .map((m) => m.content.trim())\n .filter((c) => c.length > 0)\n .join(\"\\n\\n\");\n return this.renderFrontmatterMd({ trigger: \"always_on\" }, body);\n }\n\n override installMemory(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n const entries = connector.memory ?? [];\n if (connector.platforms[this.id]?.memory === false) {\n return [{ platform: this.id, action: \"skip\", detail: `memory disabled for ${this.id}` }];\n }\n if (entries.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no memory\" }];\n }\n // Windsurf's verified per-rule `.windsurf/rules` dir is WORKSPACE scope only.\n if (ctx.scope !== \"project\") {\n return [\n {\n platform: this.id,\n action: \"warn\",\n detail:\n `no ${ctx.scope}-scope rules dir verified for windsurf ` +\n `(.windsurf/rules is workspace-scope; global_rules.md is a shared file); ` +\n `${entries.length} skipped`,\n },\n ];\n }\n // Rules-path collision: never write under a `.windsurf/rules` that is a FILE.\n if (this.rulesDirIsFile(ctx)) {\n return [\n {\n platform: this.id,\n action: \"warn\",\n path: join(ctx.projectDir, \".windsurf\", \"rules\"),\n detail:\n \"existing .windsurf/rules is a file, not a directory; left untouched — \" +\n \"convert it to a .windsurf/rules/ directory to receive agent-connector memory\",\n },\n ];\n }\n return [this.writeContentFile(this.memoryFilePath(ctx), this.renderMemoryFile(ctx), ctx.dryRun)];\n }\n\n override uninstallMemory(ctx: InstallContext): ChangeRecord[] {\n // Only the project-scope dedicated file was ever written; a `.windsurf/rules`\n // that is a FILE was never ours (installMemory warned), so leave it.\n if (ctx.scope !== \"project\" || this.rulesDirIsFile(ctx)) {\n const path = this.memoryFilePath(ctx);\n return [\n { platform: this.id, action: \"skip\", path, detail: `${basename(path)} absent` },\n ];\n }\n return [this.removeContentFile(this.memoryFilePath(ctx), ctx.dryRun)];\n }\n\n // ── Content surfaces: commands (workflows) + skills ───────────────────────\n // CONTENT-ONLY native-file writers, structured like installMemory: dedicated-\n // file ownership, dryRun honored via writeContentFile/removeContentFile. Both\n // reuse the shared claude-code renderers (renderCommandMd / renderSkillMd) — no\n // new markdown serializer. BOTH scopes write (the project dir AND the\n // ~/.codeium/windsurf user/global dirs are documented surfaces):\n //\n // commands (workflows)\n // - project → <projectDir>/.windsurf/workflows/<name>.md\n // - user → ~/.codeium/windsurf/global_workflows/<name>.md\n // (NOTE: the user dir is `global_workflows`, NOT `workflows`.)\n // skills\n // - project → <projectDir>/.windsurf/skills/<name>/SKILL.md\n // - user → ~/.codeium/windsurf/skills/<name>/SKILL.md\n // (the dir is `skills` in BOTH scopes; same SKILL.md convention\n // cline/claude-code/qwen-code use.)\n //\n // renderCommandMd emits Claude-flavored frontmatter keys (argument-hint, model,\n // allowed-tools); Windsurf ignores unknown frontmatter keys, so they are inert/\n // tolerated — no Windsurf-specific renderer is needed.\n\n /** Workflow file: project `.windsurf/workflows`, user `~/.codeium/windsurf/global_workflows`. */\n private commandPath(ctx: InstallContext, name: string): string {\n const dir =\n ctx.scope === \"project\"\n ? join(ctx.projectDir, \".windsurf\", \"workflows\")\n : join(homedir(), \".codeium\", \"windsurf\", \"global_workflows\");\n return join(dir, `${name}.md`);\n }\n\n /** Skill dir: project `.windsurf/skills/<name>`, user `~/.codeium/windsurf/skills/<name>`. */\n private skillDir(ctx: InstallContext, name: string): string {\n const base =\n ctx.scope === \"project\"\n ? join(ctx.projectDir, \".windsurf\", \"skills\")\n : join(homedir(), \".codeium\", \"windsurf\", \"skills\");\n return join(base, name);\n }\n\n // ── Commands (workflows) ──────────────────────────────────────────────────\n\n override installCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.commands === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"commands disabled for windsurf\" }];\n }\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const cmd of connector.commands) {\n const rendered = renderCommandMd(cmd);\n changes.push(this.writeContentFile(this.commandPath(ctx, cmd.name), rendered, ctx.dryRun));\n // Windsurf caps each workflow file at 12,000 characters (docs.windsurf.com).\n // Still write the file — warn so the author can trim it (Windsurf may reject\n // or truncate the overflow), mirroring base.ts's memory soft-budget warn.\n if (rendered.length > WORKFLOW_MAX_CHARS) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n path: this.commandPath(ctx, cmd.name),\n detail:\n `workflow \"${cmd.name}\" is ${rendered.length} chars ` +\n `(Windsurf caps each workflow at ${WORKFLOW_MAX_CHARS}); ` +\n `the host may reject or truncate it — trim the command`,\n });\n }\n }\n return changes;\n }\n\n override uninstallCommands(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.commands.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no commands\" }];\n }\n return connector.commands.map((cmd) =>\n this.removeContentFile(this.commandPath(ctx, cmd.name), ctx.dryRun),\n );\n }\n\n // ── Skills ────────────────────────────────────────────────────────────────\n\n override installSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.platforms[HOST]?.skills === false) {\n return [{ platform: this.id, action: \"skip\", detail: \"skills disabled for windsurf\" }];\n }\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n changes.push(\n this.writeContentFile(join(dir, \"SKILL.md\"), renderSkillMd(skill), ctx.dryRun),\n );\n for (const [rel, contents] of Object.entries(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) {\n changes.push({\n platform: this.id,\n action: \"warn\",\n detail: `skill resource \"${rel}\" escapes the skill dir; skipped`,\n });\n continue;\n }\n changes.push(this.writeContentFile(target, contents, ctx.dryRun));\n }\n }\n return changes;\n }\n\n override uninstallSkills(ctx: InstallContext): ChangeRecord[] {\n const { connector } = ctx;\n if (connector.skills.length === 0) {\n return [{ platform: this.id, action: \"skip\", detail: \"connector declares no skills\" }];\n }\n const changes: ChangeRecord[] = [];\n for (const skill of connector.skills) {\n const dir = this.skillDir(ctx, skill.name);\n changes.push(this.removeContentFile(join(dir, \"SKILL.md\"), ctx.dryRun));\n for (const rel of Object.keys(skill.resources ?? {})) {\n const target = this.resolveWithin(dir, rel);\n if (target === null) continue;\n changes.push(this.removeContentFile(target, ctx.dryRun));\n }\n changes.push(this.removeDirIfEmpty(dir, ctx.dryRun));\n }\n return changes;\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 windsurf\"\n : \"connector declares no MCP server\",\n },\n ];\n }\n\n // Windsurf has no project-level MCP config (user scope only — the docs\n // document only ~/.codeium/windsurf/mcp_config.json). A project-scope\n // install is reported as a skip rather than written into the project tree.\n if (ctx.scope === \"project\") {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail:\n \"Windsurf has no project-level MCP config (user scope only); \" +\n \"re-run with --scope user\",\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\n // NEVER clobber a malformed `mcpServers`. The base upsert tolerates a\n // missing file / missing key (it creates the object), but a PRESENT-but-\n // non-object `mcpServers` (e.g. an array or string from a hand-edit) would\n // get a named property bolted on and silently corrupted — so skip-and-warn.\n const malformed = this.malformedRootKey(serverPath);\n if (malformed) return [malformed];\n\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 const malformed = this.malformedRootKey(serverPath);\n if (malformed) return [malformed];\n return [\n this.removeServerFromJson(serverPath, MCP_ROOT_KEY, ctx.connector.id, ctx.dryRun),\n ];\n }\n\n /**\n * Guard for a PRESENT-but-non-object `mcpServers` root key: returns a\n * skip-warn ChangeRecord when the existing config parses but its `mcpServers`\n * value is not a plain object (an array / string / number / null). Returns\n * undefined when the file is absent, unparseable (the base upsert's own\n * overwrite guard handles that), or `mcpServers` is absent / a plain object.\n */\n private malformedRootKey(configPath: string): ChangeRecord | undefined {\n const cfg = this.readJson<Record<string, unknown>>(configPath);\n if (!cfg || !(MCP_ROOT_KEY in cfg)) return undefined;\n const root = cfg[MCP_ROOT_KEY];\n if (root !== null && typeof root === \"object\" && !Array.isArray(root)) {\n return undefined;\n }\n return {\n platform: this.id,\n action: \"warn\",\n path: configPath,\n detail: `existing ${MCP_ROOT_KEY} in ${configPath} is not an object map; left untouched (back it up / fix it, then re-run)`,\n };\n }\n\n /** Render a normalized ServerDef into Windsurf's native mcpServers entry. */\n private renderServerEntry(\n ctx: InstallContext,\n server: ServerDef,\n ): WindsurfStdioServer | WindsurfRemoteServer {\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 ({ command, args } = buildWrappedStdio(ctx, server, this.id, command, args));\n\n // Windsurf supports ${env:VAR} natively, but AC resolves references to\n // literals at install time (the safe path, same as amazon-q/droid/crush).\n const entry: WindsurfStdioServer = {\n command: resolveEnvRefsDeep(command),\n };\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 // http / sse (and any other remote transport) — Windsurf registers a remote\n // URL under `serverUrl` (NOT `url`). NO `type` discriminator, NO `disabled`.\n // `headers` only when the connector's remote server provides them.\n const entry: WindsurfRemoteServer = {\n serverUrl: resolveEnvRefsDeep(server.url ?? \"\"),\n };\n const headers = this.renderEnv(server.headers);\n if (headers) entry.headers = headers;\n return entry;\n }\n\n /**\n * Render env/header values. Windsurf has a native ${env:VAR} token, but AC\n * resolves references to literals at install time (the safe path).\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 — Windsurf is mcp-only) ────────────────────────────\n\n installHooks(_ctx: InstallContext): ChangeRecord[] {\n return [\n {\n platform: this.id,\n action: \"skip\",\n detail: \"hooks unavailable (Windsurf 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 (Windsurf is mcp-only)\",\n },\n ];\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_config.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 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 WindsurfAdapter();\nexport default adapter;\n"],"mappings":"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","names":["entry"]}
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  roamingAppData
4
- } from "./chunk-UM5S7DKK.js";
4
+ } from "./chunk-KOFCNA5T.js";
5
5
  import {
6
6
  resolveEnvRefsDeep
7
7
  } from "./chunk-BEFVJ2OE.js";
@@ -427,4 +427,4 @@ export {
427
427
  adapter,
428
428
  zed_default as default
429
429
  };
430
- //# sourceMappingURL=zed-DQV3ZUCU.js.map
430
+ //# sourceMappingURL=zed-JCOKXOLA.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ken-jo/agent-connector",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "type": "module",
5
5
  "description": "SDK/runtime for branded MCP packages: declare your server + hooks once, install across the current AI-agent coverage matrix, and collect local-first token telemetry.",
6
6
  "keywords": [
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/adapters/registry.ts"],"sourcesContent":["/**\n * adapters/registry — single source of truth for the platforms agent-connector\n * targets. Generalized from context-mode's `ADAPTER_REGISTRY` pattern, adapted\n * to our `Adapter` / `AdapterFactory` contract (adapters/spi.ts).\n *\n * In context-mode the same platform set was redeclared in four places (env-var\n * detection, session-dir lookup, the lazy adapter loader, and per-adapter base\n * constructors); adding a platform meant editing all of them and missing one\n * was silent. Here the list lives ONCE below: each platform is one entry with a\n * lazy `load()` thunk that resolves the adapter singleton. Adding a platform is\n * a single new entry — `getFactory` / `loadAdapter` / `allAdapters` and the\n * detection cascade in detect.ts all derive from this list.\n *\n * `load()` returns the module's default export, which every adapter file is\n * required to provide as its singleton (`export default adapter;`). It is a\n * function (not an eager import) so module loading stays lazy: an adapter is\n * only imported when it is actually needed, keeping startup cheap.\n *\n * Order is load-bearing for runtime host detection (detect.ts iterates env\n * markers in registry order): forks MUST precede their parent so a session\n * running inside a derived shell is not misclassified as the parent. For the\n * three Phase-1 adapters this is moot, but the ordering convention is fixed now\n * so later additions (cursor is a VS Code fork, etc.) slot in correctly.\n */\n\nimport type { PlatformId } from \"../core/types.js\";\nimport type { Adapter, AdapterFactory } from \"./spi.js\";\n\n/**\n * Authoritative list of installable platforms. One entry per platform; the\n * `load` thunk lazily imports the adapter module and returns its default-export\n * singleton. To add a platform: drop its `src/adapters/<id>/index.ts` in place\n * (default-exporting an `Adapter`) and add one entry here.\n */\nexport const ADAPTER_REGISTRY: readonly AdapterFactory[] = [\n // codebuddy (Tencent CodeBuddy) is a Claude Code fork that ALSO exports\n // CLAUDE_SESSION_ID at runtime (its bundle sets both CODEBUDDY_SESSION_ID and\n // CLAUDE_SESSION_ID), so it must precede claude-code: the fork's exclusive\n // runtime markers are checked first during host detection (fork-before-parent).\n {\n id: \"codebuddy\",\n load: () => import(\"./codebuddy/index.js\").then((m) => m.default),\n },\n {\n id: \"claude-code\",\n load: () => import(\"./claude-code/index.js\").then((m) => m.default),\n },\n {\n id: \"codex\",\n load: () => import(\"./codex/index.js\").then((m) => m.default),\n },\n {\n id: \"cursor\",\n load: () => import(\"./cursor/index.js\").then((m) => m.default),\n },\n // vscode-copilot after cursor: cursor is a VS Code fork, so the fork's runtime\n // markers must be checked first during host detection.\n {\n id: \"vscode-copilot\",\n load: () => import(\"./vscode-copilot/index.js\").then((m) => m.default),\n },\n {\n id: \"copilot-cli\",\n load: () => import(\"./copilot-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"gemini-cli\",\n load: () => import(\"./gemini-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"warp\",\n load: () => import(\"./warp/index.js\").then((m) => m.default),\n },\n // ts-plugin paradigm: OpenCode loads a generated plugin module that bridges\n // its in-process events to the universal hook entrypoint.\n {\n id: \"opencode\",\n load: () => import(\"./opencode/index.js\").then((m) => m.default),\n },\n // mimo-code is Xiaomi's MiMoCode (@mimo-ai/cli, bin `mimo`) — an OpenCode FORK\n // (ts-plugin, MCP root key \"mcp\", ~/.config/mimocode/mimocode.json). Grouped\n // beside the OpenCode family whose config dialect + plugin contract it shares;\n // detected via the DISTINCT ~/.config/mimocode dir, so there is no fork-ordering\n // constraint vs opencode (no shared config file to disambiguate).\n {\n id: \"mimo-code\",\n load: () => import(\"./mimo-code/index.js\").then((m) => m.default),\n },\n // kilo-cli is the SQLite-backed OpenCode FORK command-line product (ts-plugin,\n // loads @kilocode/plugin modules registered in kilo.jsonc's \"plugin\" array;\n // MCP root key \"mcp\", ~/.config/kilo/kilo.jsonc). Grouped beside the OpenCode\n // family whose plugin contract + config dialect it shares; distinct host from\n // the \"kilo\" extension so there is no fork-ordering constraint between them.\n {\n id: \"kilo-cli\",\n load: () => import(\"./kilo-cli/index.js\").then((m) => m.default),\n },\n // Wave 1 — mcp-only adapters (no lifecycle hooks; MCP registration only).\n {\n id: \"droid\",\n load: () => import(\"./droid/index.js\").then((m) => m.default),\n },\n // openhands is the All-Hands-AI OpenHands CLI (`openhands`, ex-OpenDevin) —\n // a standalone json-stdio host: MCP at ~/.openhands/mcp.json (\"mcpServers\",\n // FastMCP entry shape) + a SEPARATE .openhands/hooks.json carrying the\n // Claude-Code-plugin-compatible nested-rule hooks (6 events). Its persistence\n // dir (~/.openhands) is distinct, so there is no fork-ordering constraint.\n {\n id: \"openhands\",\n load: () => import(\"./openhands/index.js\").then((m) => m.default),\n },\n {\n id: \"roo-code\",\n load: () => import(\"./roo-code/index.js\").then((m) => m.default),\n },\n // kilo is the Kilo Code VS Code extension (kilocode.kilo-code) — a Roo/Cline\n // fork, so it sits beside roo-code (mcp-only, root key \"mcpServers\", VS Code\n // globalStorage / .kilocode project scope). Distinct host from \"kilo-cli\".\n {\n id: \"kilo\",\n load: () => import(\"./kilo/index.js\").then((m) => m.default),\n },\n // cline is the Cline VS Code extension (saoudrizwan.claude-dev) — the most-\n // installed AI coding extension and the PARENT that roo-code and kilo forked.\n // mcp-only (no hook layer); MCP at the globalStorage cline_mcp_settings.json\n // (\"mcpServers\"); content lives in the .clinerules tree + ~/Documents/Cline.\n // NO runtime-marker collision with roo-code (rooveterinaryinc.roo-cline / .roo)\n // or kilo (kilocode.kilo-code / .kilo) — distinct ext ids + dotdirs — so there\n // is NO fork-before-parent ordering constraint here; it simply sits beside them.\n {\n id: \"cline\",\n load: () => import(\"./cline/index.js\").then((m) => m.default),\n },\n {\n id: \"trae\",\n load: () => import(\"./trae/index.js\").then((m) => m.default),\n },\n // antigravity-cli BEFORE antigravity: the `agy` CLI is a fork of the IDE\n // adapter with its own runtime markers (the universal hook command tags the\n // host as \"antigravity-cli\"), so the more-specific CLI marker must be checked\n // before the IDE/parent during host detection.\n {\n id: \"antigravity-cli\",\n load: () => import(\"./antigravity-cli/index.js\").then((m) => m.default),\n },\n {\n id: \"antigravity\",\n load: () => import(\"./antigravity/index.js\").then((m) => m.default),\n },\n {\n id: \"zed\",\n load: () => import(\"./zed/index.js\").then((m) => m.default),\n },\n {\n id: \"amp\",\n load: () => import(\"./amp/index.js\").then((m) => m.default),\n },\n {\n id: \"codebuff\",\n load: () => import(\"./codebuff/index.js\").then((m) => m.default),\n },\n {\n id: \"mux\",\n load: () => import(\"./mux/index.js\").then((m) => m.default),\n },\n // Pi — mcp-only host with no writable MCP config; drives the Agent Skills\n // surface only (writes <piDir>/skills/<name>/SKILL.md).\n {\n id: \"pi\",\n load: () => import(\"./pi/index.js\").then((m) => m.default),\n },\n // Wave 2 — json-stdio adapters (full hook dispatch via the universal entrypoint).\n // jetbrains-copilot before vscode-copilot is unnecessary (distinct hosts); grouped here.\n {\n id: \"jetbrains-copilot\",\n load: () => import(\"./jetbrains-copilot/index.js\").then((m) => m.default),\n },\n {\n id: \"qwen-code\",\n load: () => import(\"./qwen-code/index.js\").then((m) => m.default),\n },\n {\n id: \"kiro\",\n load: () => import(\"./kiro/index.js\").then((m) => m.default),\n },\n {\n id: \"kimi\",\n load: () => import(\"./kimi/index.js\").then((m) => m.default),\n },\n {\n id: \"crush\",\n load: () => import(\"./crush/index.js\").then((m) => m.default),\n },\n // Wave 3 — json-stdio adapters with YAML config (MCP in YAML; hooks per host).\n {\n id: \"goose\",\n load: () => import(\"./goose/index.js\").then((m) => m.default),\n },\n {\n id: \"hermes\",\n load: () => import(\"./hermes/index.js\").then((m) => m.default),\n },\n // Wave 4 — ts-plugin adapters (generate a bridge module to the universal entrypoint).\n {\n id: \"omp\",\n load: () => import(\"./omp/index.js\").then((m) => m.default),\n },\n // nemoclaw BEFORE openclaw (fork-before-parent convention). NVIDIA NemoClaw\n // wraps OpenClaw and DRIVES the SAME ~/.openclaw/openclaw.json, so a NemoClaw\n // box carries BOTH the ~/.nemoclaw/ and ~/.openclaw/ markers. Exclusivity is\n // enforced at the SOURCE: OpenClawAdapter.detectInstalled BOWS OUT when\n // ~/.nemoclaw/ is present, so the shared config is never double-targeted as two\n // platforms. This ordering is the deterministic tie-break (matching the\n // antigravity-cli/antigravity precedent). nemoclaw extends OpenClawAdapter\n // (id/name/detection overridden), so inherited server/hook registration still\n // lands in the wrapped openclaw.json.\n {\n id: \"nemoclaw\",\n load: () => import(\"./nemoclaw/index.js\").then((m) => m.default),\n },\n {\n id: \"openclaw\",\n load: () => import(\"./openclaw/index.js\").then((m) => m.default),\n },\n // Wave 5 — mcp-only: Amazon Q Developer CLI. JSON MCP config under ~/.aws/amazonq/\n // (user) and .amazonq/ (project); root key \"mcpServers\"; bare stdio entry\n // { command, args, env, timeout? } or remote entry { type: \"http\", url } (no\n // headers) for http. The agent-format hooks layer (cli-agents/*.json) +\n // agents/prompts content surfaces are separate, not-yet-wired surfaces; this\n // adapter installs MCP entries + the .amazonq/rules memory surface.\n {\n id: \"amazon-q\",\n load: () => import(\"./amazon-q/index.js\").then((m) => m.default),\n },\n // Continue (the `cn` terminal agent / Continue.dev, npm @continuedev/cli) —\n // json-stdio (Claude-compatible hooks). MCP config is YAML at ~/.continue/config.yaml (user) and\n // <projectDir>/.continue/config.yaml (project); root key \"mcpServers\" is a\n // YAML ARRAY of { name, command, type?, args?, env?, cwd?, url } entries (NOT a\n // keyed map). Hooks: a Claude-compatible json-stdio layer in settings.json\n // (~/.continue/settings.json — separate from the MCP config.yaml; PR #11029) +\n // nativeHooks for the host-specific events. Distinct ~/.continue marker — no\n // fork-ordering constraint vs any sibling.\n {\n id: \"continue\",\n load: () => import(\"./continue/index.js\").then((m) => m.default),\n },\n // Windsurf (Codeium / Cognition's Cascade agent) — mcp-only. USER/GLOBAL scope\n // ONLY: MCP config is JSON at ~/.codeium/windsurf/mcp_config.json (the docs\n // document no project/workspace path), root key \"mcpServers\" is a Claude-\n // Desktop-style OBJECT map keyed by server name (like cursor). stdio entry\n // { command, args?, env? }; remote entry { serverUrl, headers? } (NOT `url`;\n // no type/disabled). No user-installable hook/plugin layer (GUI editor), so it\n // stays mcp-only paradigm — but content surfaces ARE wired: workflows\n // (.windsurf/workflows + ~/.codeium/windsurf/global_workflows), skills\n // (.windsurf/skills + ~/.codeium/windsurf/skills), and the .windsurf/rules\n // memory surface. Distinct ~/.codeium marker — no fork-ordering constraint.\n {\n id: \"windsurf\",\n load: () => import(\"./windsurf/index.js\").then((m) => m.default),\n },\n // Grok CLI (the community superagent-ai/grok-cli, npm `grok-dev`, bin `grok`,\n // MIT) — json-stdio. Id is `grok-cli` (NOT `grok`) to stay distinct from xAI's\n // separate \"Grok Build\" product. USER-SCOPE ONLY: both MCP servers (nested\n // `mcp.servers` JSON ARRAY, keyed by `id`) and hooks (top-level `hooks`,\n // Claude nested-rule shape) live in ~/.grok/user-settings.json (project\n // .grok/settings.json holds neither — Grok excludes project hooks for\n // security). Distinct ~/.grok marker — no fork-ordering constraint vs any\n // sibling.\n {\n id: \"grok-cli\",\n load: () => import(\"./grok-cli/index.js\").then((m) => m.default),\n },\n // Devin CLI (Cognition) — json-stdio. A Rust binary (`devin`, installed via\n // `curl cli.devin.ai/install.sh` → ~/.local/bin/devin). MCP + hooks live in\n // ONE config.json per scope: user ~/.config/devin/config.json\n // (%APPDATA%\\devin\\config.json on Windows) / project <projectDir>/.devin/\n // config.json. MCP root key \"mcpServers\" (object map; stdio { command, args?,\n // env? }, remote { url, transport?, headers? }; native ${env:VAR}). Hooks\n // under the same file's \"hooks\" key (Claude-compatible NESTED-rule shape; reply\n // is the SIMPLE top-level {decision:\"approve\"|\"block\"|\"deny\", reason}). Distinct\n // ~/.config/devin / .devin marker — no fork-ordering constraint.\n {\n id: \"devin\",\n load: () => import(\"./devin/index.js\").then((m) => m.default),\n },\n // Open Interpreter (the new Rust `interpreter` / `i` CLI) — mcp-only. It is a\n // FORK of OpenAI's Codex (README: \"Open Interpreter is a fork of OpenAI's\n // Codex\"), so its native config is Codex's: a TOML `config.toml` carrying\n // `[mcp_servers.<id>]` tables (command/args/env stdio; url/bearer_token_env_var/\n // http_headers streamable-HTTP). The config home is DELIBERATELY isolated from\n // Codex — the `interpreter` binary honors ONLY `$INTERPRETER_HOME` (NOT\n // `$CODEX_HOME`, which it explicitly ignores) and defaults to ~/.openinterpreter\n // (codex-rs/utils/home-dir/src/lib.rs). That distinct dir means there is NO\n // fork-ordering constraint vs codex — the two never target the same file — so\n // it simply sits at the end of the registry. Kept mcp-only (the codex hook\n // subsystem is present in the fork, but the `interpreter` product's live hook\n // wire contract is not first-party-verified, so hooks are not claimed).\n {\n id: \"open-interpreter\",\n load: () => import(\"./open-interpreter/index.js\").then((m) => m.default),\n },\n // Junie (JetBrains' OWN LLM-agnostic coding agent — DISTINCT from\n // jetbrains-copilot, which is GitHub Copilot in JetBrains IDEs) — mcp-only.\n // The `junie` CLI (npm @jetbrains/junie, github.com/JetBrains/junie) shares its\n // MCP JSON config with Junie in JetBrains IDEs: object map \"mcpServers\" at\n // <projectDir>/.junie/mcp/mcp.json (project) and ~/.junie/mcp/mcp.json (user);\n // stdio { command, args?, env? }, remote { url, headers? }. No documented\n // user-installable hook surface → mcp-only. Distinct ~/.junie marker — no\n // fork-ordering constraint vs any sibling.\n {\n id: \"junie\",\n load: () => import(\"./junie/index.js\").then((m) => m.default),\n },\n // mistral-vibe is Mistral's coding-agent CLI — an mcp-only host. MCP config is\n // TOML at <projectDir>/.vibe/config.toml (project, precedence) → ~/.vibe/\n // config.toml (user); root key `mcp_servers` is a TOML ARRAY-OF-TABLES\n // ([[mcp_servers]], each entry carries a `name` short alias — distinct from\n // codex's table-keyed [mcp_servers.<name>]). Distinct ~/.vibe / .vibe marker —\n // no fork-ordering constraint.\n {\n id: \"mistral-vibe\",\n load: () => import(\"./mistral-vibe/index.js\").then((m) => m.default),\n },\n];\n\n/** O(1) lookup index, built once at module-load time. */\nconst REGISTRY_BY_ID: ReadonlyMap<PlatformId, AdapterFactory> = new Map(\n ADAPTER_REGISTRY.map((factory) => [factory.id, factory] as const),\n);\n\n/** Every platform id present in the registry (useful for matrix tests). */\nexport const REGISTERED_PLATFORM_IDS: ReadonlySet<PlatformId> = new Set(\n ADAPTER_REGISTRY.map((factory) => factory.id),\n);\n\n/**\n * Look up the lazy factory for a platform id. Returns `undefined` for ids that\n * are not registered (including `\"unknown\"` and typos) so callers can fall back\n * deliberately rather than crash.\n */\nexport function getFactory(id: PlatformId | string): AdapterFactory | undefined {\n return REGISTRY_BY_ID.get(id as PlatformId);\n}\n\n/**\n * Resolve a platform id to its adapter singleton. Returns `undefined` when the\n * id is not registered — callers decide whether to skip or fall back.\n */\nexport async function loadAdapter(id: PlatformId | string): Promise<Adapter | undefined> {\n const factory = getFactory(id);\n return factory ? factory.load() : undefined;\n}\n\n/**\n * Load every registered adapter. Imports run in parallel; the result preserves\n * registry order so downstream detection/install logic sees forks before\n * parents.\n */\nexport async function allAdapters(): Promise<Adapter[]> {\n return Promise.all(ADAPTER_REGISTRY.map((factory) => factory.load()));\n}\n"],"mappings":"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","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/usage/registry.ts","../src/usage/scan.ts","../src/usage/leaderboard.ts"],"sourcesContent":["/**\n * usage/registry — the single source of truth for HOST usage readers.\n *\n * Mirrors adapters/registry.ts: each platform is ONE entry with a lazy `load()`\n * thunk resolving the reader module's default export. Adding a platform is a\n * single new entry here plus one `readers/<id>.ts` file — `getUsageReader` /\n * `allUsageReaders` and the scan orchestrator all derive from this list.\n *\n * `format` and `kind` are declared on the factory so the scan layer can describe\n * a reader (e.g. note a \"synced\" reader as skipped) without importing it.\n */\n\nimport type { PlatformId } from \"../core/types.js\";\nimport type { UsageReader, UsageReaderFactory } from \"./types.js\";\n\n/**\n * Authoritative list of usage readers. To add a platform: drop\n * `src/usage/readers/<id>.ts` (default-exporting a {@link UsageReader}) and add\n * one entry below.\n */\nexport const USAGE_READER_REGISTRY: readonly UsageReaderFactory[] = [\n // U1 — JSONL readers\n {\n platformId: \"claude-code\",\n format: \"jsonl\",\n kind: \"local\",\n load: () => import(\"./readers/claude-code.js\").then((m) => m.default),\n },\n {\n platformId: \"codex\",\n format: \"jsonl\",\n kind: \"local\",\n load: () => import(\"./readers/codex.js\").then((m) => m.default),\n },\n {\n platformId: \"gemini-cli\",\n format: \"jsonl\",\n kind: \"local\",\n load: () => import(\"./readers/gemini-cli.js\").then((m) => m.default),\n },\n {\n platformId: \"qwen-code\",\n format: \"jsonl\",\n kind: \"local\",\n load: () => import(\"./readers/qwen-code.js\").then((m) => m.default),\n },\n {\n platformId: \"copilot-cli\",\n format: \"jsonl\",\n kind: \"local\",\n load: () => import(\"./readers/copilot-cli.js\").then((m) => m.default),\n },\n {\n platformId: \"pi\",\n format: \"jsonl\",\n kind: \"local\",\n load: () => import(\"./readers/pi.js\").then((m) => m.default),\n },\n {\n platformId: \"kimi\",\n format: \"jsonl\",\n kind: \"local\",\n load: () => import(\"./readers/kimi.js\").then((m) => m.default),\n },\n {\n platformId: \"openclaw\",\n format: \"jsonl\",\n kind: \"local\",\n load: () => import(\"./readers/openclaw.js\").then((m) => m.default),\n },\n // U2 — JSON readers\n {\n platformId: \"amp\",\n format: \"json\",\n kind: \"local\",\n load: () => import(\"./readers/amp.js\").then((m) => m.default),\n },\n {\n platformId: \"droid\",\n format: \"json\",\n kind: \"local\",\n load: () => import(\"./readers/droid.js\").then((m) => m.default),\n },\n {\n platformId: \"codebuff\",\n format: \"json\",\n kind: \"local\",\n load: () => import(\"./readers/codebuff.js\").then((m) => m.default),\n },\n {\n platformId: \"mux\",\n format: \"json\",\n kind: \"local\",\n load: () => import(\"./readers/mux.js\").then((m) => m.default),\n },\n {\n platformId: \"roo-code\",\n format: \"json\",\n kind: \"local\",\n load: () => import(\"./readers/roo-code.js\").then((m) => m.default),\n },\n {\n platformId: \"kilo\",\n format: \"json\",\n kind: \"local\",\n load: () => import(\"./readers/kilo.js\").then((m) => m.default),\n },\n {\n platformId: \"kiro\",\n format: \"json\",\n kind: \"local\",\n load: () => import(\"./readers/kiro.js\").then((m) => m.default),\n },\n // U3 — SQLite readers (via sql.js wasm)\n {\n platformId: \"opencode\",\n format: \"sqlite\",\n kind: \"local\",\n load: () => import(\"./readers/opencode.js\").then((m) => m.default),\n },\n {\n platformId: \"goose\",\n format: \"sqlite\",\n kind: \"local\",\n load: () => import(\"./readers/goose.js\").then((m) => m.default),\n },\n {\n platformId: \"hermes\",\n format: \"sqlite\",\n kind: \"local\",\n load: () => import(\"./readers/hermes.js\").then((m) => m.default),\n },\n {\n platformId: \"kilo-cli\",\n format: \"sqlite\",\n kind: \"local\",\n load: () => import(\"./readers/kilo-cli.js\").then((m) => m.default),\n },\n {\n platformId: \"synthetic\",\n format: \"sqlite\",\n kind: \"local\",\n load: () => import(\"./readers/synthetic.js\").then((m) => m.default),\n },\n {\n platformId: \"crush\",\n format: \"sqlite\",\n kind: \"local\",\n load: () => import(\"./readers/crush.js\").then((m) => m.default),\n },\n {\n platformId: \"zed\",\n format: \"sqlite\",\n kind: \"local\",\n load: () => import(\"./readers/zed.js\").then((m) => m.default),\n },\n // U4 — synced/cloud readers (read tokscale local cache if present, else skip)\n {\n platformId: \"cursor\",\n format: \"synced-cache\",\n kind: \"synced\",\n load: () => import(\"./readers/cursor.js\").then((m) => m.default),\n },\n {\n // Antigravity IDE: the native `~/.gemini/antigravity/conversations/<uuid>.pb`\n // store is PROTOBUF with no public schema (CONFIRMED by install) → not\n // parseable. So this is a SYNCED reader: it reads the tokscale synced-cache\n // if present, else [] (\"requires sync\"). The native dir is detection-only.\n platformId: \"antigravity\",\n format: \"synced-cache\",\n kind: \"synced\",\n load: () => import(\"./readers/antigravity.js\").then((m) => m.default),\n },\n {\n // Antigravity CLI (`agy`): SHARES the IDE's protobuf (.pb) store (no separate\n // dir, no public schema) → not parseable. SYNCED reader: tokscale cache if\n // present, else [] (\"requires sync\").\n platformId: \"antigravity-cli\",\n format: \"synced-cache\",\n kind: \"synced\",\n load: () => import(\"./readers/antigravity-cli.js\").then((m) => m.default),\n },\n {\n platformId: \"trae\",\n format: \"synced-cache\",\n kind: \"synced\",\n load: () => import(\"./readers/trae.js\").then((m) => m.default),\n },\n {\n platformId: \"warp\",\n format: \"synced-cache\",\n kind: \"synced\",\n load: () => import(\"./readers/warp.js\").then((m) => m.default),\n },\n];\n\n/** O(1) lookup index, built once at module-load time. */\nconst REGISTRY_BY_ID: ReadonlyMap<PlatformId, UsageReaderFactory> = new Map(\n USAGE_READER_REGISTRY.map((factory) => [factory.platformId, factory] as const),\n);\n\n/** Look up the lazy factory for a platform id, or undefined when unregistered. */\nexport function getUsageReaderFactory(id: PlatformId | string): UsageReaderFactory | undefined {\n return REGISTRY_BY_ID.get(id as PlatformId);\n}\n\n/** Resolve a platform id to its reader singleton, or undefined when unregistered. */\nexport async function getUsageReader(id: PlatformId | string): Promise<UsageReader | undefined> {\n const factory = getUsageReaderFactory(id);\n return factory ? factory.load() : undefined;\n}\n\n/** Load every registered reader (imports run in parallel; preserves order). */\nexport async function allUsageReaders(): Promise<UsageReader[]> {\n return Promise.all(USAGE_READER_REGISTRY.map((factory) => factory.load()));\n}\n","/**\n * usage/scan — orchestrate every registered reader into one deduped record set.\n *\n * Iterates USAGE_READER_REGISTRY (optionally filtered by platform), loads and\n * runs each reader, and folds the results together. Per-reader robustness:\n * • a reader that throws (it shouldn't — readers are fail-open) is CAUGHT and\n * recorded as skipped, never aborting the whole scan;\n * • a \"synced\" reader that returns no rows is noted as skipped(\"requires sync\")\n * so the report can honestly explain why a cloud platform shows nothing;\n * • a reader that simply has no local data returns [] silently (no root).\n *\n * After collection: global cross-source dedupe, then a final sinceMs filter\n * (readers also honor sinceMs, but the scan re-filters as a backstop).\n */\n\nimport type { PlatformId } from \"../core/types.js\";\nimport type { UsageReader, UsageReaderFactory, UsageRecord } from \"./types.js\";\nimport { dedupe } from \"./aggregate.js\";\nimport { USAGE_READER_REGISTRY } from \"./registry.js\";\n\n/** A platform the scan could not (fully) read, with a human reason. */\nexport interface SkippedPlatform {\n platformId: PlatformId;\n reason: string;\n}\n\n/** Options controlling a scan. */\nexport interface ScanOptions {\n /** Lower-bound epoch ms; records older than this are dropped. */\n sinceMs?: number;\n /** Restrict to these platforms; omit/empty to scan every registered reader. */\n platforms?: PlatformId[];\n}\n\n/** The result of a scan: deduped records + notes on anything skipped. */\nexport interface ScanResult {\n records: UsageRecord[];\n skipped: SkippedPlatform[];\n}\n\n/**\n * Scan host usage across the selected readers. Returns deduped, since-filtered\n * records plus a `skipped` list (load/read failures and synced-but-uncached\n * platforms). Never throws — a single bad reader is isolated.\n */\nexport async function scanUsage(opts: ScanOptions = {}): Promise<ScanResult> {\n const { sinceMs, platforms } = opts;\n const wanted = platforms && platforms.length > 0 ? new Set(platforms) : undefined;\n\n const factories = USAGE_READER_REGISTRY.filter(\n (f) => wanted === undefined || wanted.has(f.platformId),\n );\n\n const collected: UsageRecord[] = [];\n const skipped: SkippedPlatform[] = [];\n\n // Run readers concurrently; each result is independent.\n const results = await Promise.all(\n factories.map(async (factory) => readOne(factory, sinceMs)),\n );\n\n for (const r of results) {\n if (r.skipped) skipped.push(r.skipped);\n // Loop-push, never push(...spread): a reader over a large host history can\n // return hundreds of thousands of records, and spreading them as call\n // arguments overflows the stack (RangeError) — hit on a real machine the\n // first time the claude-code reader saw a multi-week log directory.\n for (const rec of r.records) collected.push(rec);\n }\n\n const deduped = dedupe(collected);\n const filtered =\n sinceMs === undefined ? deduped : deduped.filter((rec) => rec.ts >= sinceMs);\n\n return { records: filtered, skipped };\n}\n\n/** Load + run a single reader, isolating any failure into a skip note. */\nasync function readOne(\n factory: UsageReaderFactory,\n sinceMs: number | undefined,\n): Promise<{ records: UsageRecord[]; skipped?: SkippedPlatform }> {\n let reader: UsageReader;\n try {\n reader = await factory.load();\n } catch (err) {\n return {\n records: [],\n skipped: { platformId: factory.platformId, reason: `failed to load reader: ${errMsg(err)}` },\n };\n }\n\n let records: UsageRecord[];\n try {\n records = await reader.read(sinceMs === undefined ? {} : { sinceMs });\n } catch (err) {\n return {\n records: [],\n skipped: { platformId: factory.platformId, reason: `read error: ${errMsg(err)}` },\n };\n }\n\n if (records.length === 0 && factory.kind === \"synced\") {\n return {\n records: [],\n skipped: {\n platformId: factory.platformId,\n reason: \"requires sync (no local cache found)\",\n },\n };\n }\n\n return { records };\n}\n\nfunction errMsg(err: unknown): string {\n return err instanceof Error ? err.message : String(err);\n}\n","/**\n * usage/leaderboard — the USER / HOST leaderboard, derived from the host usage\n * readers (src/usage/*).\n *\n * Where {@link import(\"../telemetry/leaderboard.js\")} answers \"which MCP server\n * costs the most\" from the bytes WE wrap, this answers \"which CLI / host spent\n * the most\" from each agent's OWN native session logs. Origin is always\n * `host-native`; it is NEVER summed with the serve-proxy MCP leaderboard (they\n * measure different things: server bytes vs whole-conversation usage).\n *\n * Thin wrapper over {@link scanUsage} + {@link aggregateBy}: the ranking is just\n * the platform (or model) group-by, which `aggregateBy` already sorts by total\n * tokens desc. A dedicated formatter notes synced / host-estimated platforms.\n */\n\nimport type { SkippedPlatform } from \"./scan.js\";\nimport type { PlatformId } from \"../core/types.js\";\nimport type { UsageRecord, UsageSummary } from \"./types.js\";\nimport { aggregateBy } from \"./aggregate.js\";\nimport { scanUsage } from \"./scan.js\";\n\n/** Options for the host leaderboard queries. */\nexport interface HostLeaderboardOptions {\n /** Lower-bound epoch ms (inclusive); forwarded to {@link scanUsage}. */\n sinceMs?: number;\n /** Restrict to these platforms; omit/empty to scan every registered reader. */\n platforms?: PlatformId[];\n /** Rank dimension. \"platform\" (default) is the headline host leaderboard. */\n by?: \"platform\" | \"model\";\n}\n\n/** The host leaderboard result: ranked rows plus any honest skip notes. */\nexport interface HostLeaderboardResult {\n /** The ranking dimension actually used. */\n by: \"platform\" | \"model\";\n /** Ranked summary rows (sorted by total tokens desc by aggregateBy). */\n rows: UsageSummary[];\n /** Platforms the scan could not (fully) read (synced-but-uncached, errors). */\n skipped: SkippedPlatform[];\n}\n\n/**\n * The USER / HOST leaderboard: scan every host reader, then rank by platform\n * (the default — \"which CLI/host spent the most\") or by model. Returns the\n * ranked rows and the scan's skip notes so the formatter can stay honest about\n * cloud platforms that require a sync we do not perform.\n */\nexport async function hostLeaderboard(\n opts: HostLeaderboardOptions = {},\n): Promise<HostLeaderboardResult> {\n const by = opts.by ?? \"platform\";\n const scanOpts: { sinceMs?: number; platforms?: PlatformId[] } = {};\n if (opts.sinceMs !== undefined) scanOpts.sinceMs = opts.sinceMs;\n if (opts.platforms !== undefined && opts.platforms.length > 0) {\n scanOpts.platforms = opts.platforms;\n }\n const { records, skipped } = await scanUsage(scanOpts);\n const rows = aggregateBy(records, by);\n return { by, rows, skipped };\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Formatting (mirrors usage/report.ts style: aligned table + honesty legend)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Compact integer formatting with thousands separators. */\nfunction fmtInt(n: number): string {\n return n.toLocaleString(\"en-US\");\n}\n\n/** Right-pad (left-aligned columns). */\nfunction padRight(s: string, width: number): string {\n return s.length >= width ? s : s + \" \".repeat(width - s.length);\n}\n\n/** Left-pad (right-aligned numeric columns). */\nfunction padLeft(s: string, width: number): string {\n return s.length >= width ? s : \" \".repeat(width - s.length) + s;\n}\n\n/**\n * Format the host leaderboard as an aligned, ranked table:\n * RANK | PLATFORM|MODEL | IN | OUT | CACHE_R | CACHE_W | REASON | TOTAL | SESS | CONF\n * with a TOTAL footer (worst confidence across rows), an estimate legend, and\n * skip notes for synced-but-uncached platforms.\n */\nexport function formatHostLeaderboard(\n result: HostLeaderboardResult,\n): string {\n const keyHeader = result.by === \"model\" ? \"MODEL\" : \"PLATFORM\";\n const headers = [\n \"RANK\",\n keyHeader,\n \"IN\",\n \"OUT\",\n \"CACHE_R\",\n \"CACHE_W\",\n \"REASON\",\n \"TOTAL\",\n \"SESS\",\n \"CONF\",\n ];\n\n // aggregateBy already sorts by total desc; re-sort defensively for stability.\n const sorted = [...result.rows].sort(\n (a, b) => b.total - a.total || b.lastTs - a.lastTs,\n );\n\n const dataRows = sorted.map((r, i) => [\n `${i + 1}`,\n r.key,\n fmtInt(r.tokens.input),\n fmtInt(r.tokens.output),\n fmtInt(r.tokens.cacheRead),\n fmtInt(r.tokens.cacheWrite),\n fmtInt(r.tokens.reasoning),\n fmtInt(r.total),\n fmtInt(r.sessions),\n r.confidence,\n ]);\n\n const totals = sorted.reduce(\n (acc, r) => {\n acc.input += r.tokens.input;\n acc.output += r.tokens.output;\n acc.cacheRead += r.tokens.cacheRead;\n acc.cacheWrite += r.tokens.cacheWrite;\n acc.reasoning += r.tokens.reasoning;\n acc.total += r.total;\n acc.sessions += r.sessions;\n return acc;\n },\n { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, reasoning: 0, total: 0, sessions: 0 },\n );\n const totalRow = [\n \"\",\n \"TOTAL\",\n fmtInt(totals.input),\n fmtInt(totals.output),\n fmtInt(totals.cacheRead),\n fmtInt(totals.cacheWrite),\n fmtInt(totals.reasoning),\n fmtInt(totals.total),\n fmtInt(totals.sessions),\n \"\",\n ];\n\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 // Left-align RANK (0), the KEY column (1), and CONF (9); numbers right.\n const leftCols = new Set<number>([0, 1, 9]);\n const renderRow = (cells: string[]): string =>\n cells\n .map((c, col) =>\n leftCols.has(col) ? padRight(c, widths[col] ?? 0) : 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 host usage found)\");\n } else {\n for (const row of dataRows) lines.push(renderRow(row));\n }\n lines.push(rule);\n lines.push(renderRow(totalRow));\n\n // Honesty legend — estimated rows and skipped synced platforms.\n if (sorted.some((r) => r.confidence === \"host-estimated\")) {\n lines.push(\"\");\n lines.push(\n \"note: host-estimated rows are derived (e.g. char/4 or cost-only), \" +\n \"not exact host-reported token counts.\",\n );\n }\n if (result.skipped.length > 0) {\n lines.push(\"\");\n lines.push(\"skipped (synced/host-estimated platforms):\");\n for (const s of result.skipped) lines.push(` - ${s.platformId}: ${s.reason}`);\n }\n\n return lines.join(\"\\n\");\n}\n"],"mappings":"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","names":[]}