@ken-jo/agent-connector 0.4.0 → 0.4.6

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 (185) hide show
  1. package/README.md +9 -9
  2. package/dist/{action-PLZW5BGX.js → action-EV63GAPY.js} +11 -10
  3. package/dist/{action-PLZW5BGX.js.map → action-EV63GAPY.js.map} +1 -1
  4. package/dist/amazon-q-COAL3764.js +276 -0
  5. package/dist/amazon-q-COAL3764.js.map +1 -0
  6. package/dist/amp-XJQ4TDAU.js +666 -0
  7. package/dist/amp-XJQ4TDAU.js.map +1 -0
  8. package/dist/{antigravity-ANDKF3K7.js → antigravity-AMKKKHS4.js} +4 -4
  9. package/dist/{antigravity-cli-LLRPDDOT.js → antigravity-cli-XERXEH5W.js} +4 -4
  10. package/dist/{chunk-MAH6QQTO.js → chunk-2X4EH2D7.js} +5 -4
  11. package/dist/chunk-2X4EH2D7.js.map +1 -0
  12. package/dist/{chunk-G3ER4SY5.js → chunk-5G4EPJ4Y.js} +9 -9
  13. package/dist/chunk-BMD7ANKF.js +237 -0
  14. package/dist/chunk-BMD7ANKF.js.map +1 -0
  15. package/dist/{chunk-IW77FFNX.js → chunk-CPLK7GTE.js} +41 -5
  16. package/dist/chunk-CPLK7GTE.js.map +1 -0
  17. package/dist/{chunk-ADTHT2FN.js → chunk-DCK5FADX.js} +10 -173
  18. package/dist/chunk-DCK5FADX.js.map +1 -0
  19. package/dist/{chunk-J3D5W5T2.js → chunk-EROJDXMW.js} +2 -2
  20. package/dist/{chunk-22Y24V7O.js → chunk-F5RX62T7.js} +2 -2
  21. package/dist/chunk-FAHIMJRU.js +177 -0
  22. package/dist/chunk-FAHIMJRU.js.map +1 -0
  23. package/dist/{chunk-BHUCB6LY.js → chunk-H67V7DEL.js} +8 -7
  24. package/dist/{chunk-BHUCB6LY.js.map → chunk-H67V7DEL.js.map} +1 -1
  25. package/dist/{chunk-BXGFUENQ.js → chunk-I5MLE6S7.js} +14 -1
  26. package/dist/{chunk-BXGFUENQ.js.map → chunk-I5MLE6S7.js.map} +1 -1
  27. package/dist/{chunk-LL4OBGRU.js → chunk-LQRAPXS4.js} +3 -3
  28. package/dist/{chunk-KGJWE6A2.js → chunk-MZF2YCXX.js} +2 -2
  29. package/dist/{chunk-KGXDYGNJ.js → chunk-QC5A3TFQ.js} +19 -19
  30. package/dist/{chunk-KGXDYGNJ.js.map → chunk-QC5A3TFQ.js.map} +1 -1
  31. package/dist/{chunk-CIRDOY2V.js → chunk-QOGMDOUX.js} +3 -3
  32. package/dist/{chunk-KGGBNKI4.js → chunk-RQPKL62M.js} +144 -21
  33. package/dist/chunk-RQPKL62M.js.map +1 -0
  34. package/dist/{chunk-6XHB6BE3.js → chunk-SCVBYSF7.js} +1 -1
  35. package/dist/{chunk-76FUSVIA.js → chunk-SRVAA2VN.js} +6 -5
  36. package/dist/chunk-SRVAA2VN.js.map +1 -0
  37. package/dist/chunk-WZA4CSGJ.js +28 -0
  38. package/dist/chunk-WZA4CSGJ.js.map +1 -0
  39. package/dist/{claude-code-MLWS7CW6.js → claude-code-T2LPFNC3.js} +20 -30
  40. package/dist/claude-code-T2LPFNC3.js.map +1 -0
  41. package/dist/cli/sdk.js +5 -4
  42. package/dist/cli/sdk.js.map +1 -1
  43. package/dist/cli.js +1 -1
  44. package/dist/cline-WRYMNS7Z.js +442 -0
  45. package/dist/cline-WRYMNS7Z.js.map +1 -0
  46. package/dist/{codebuff-SH2S3QAN.js → codebuff-PODYPOOP.js} +130 -5
  47. package/dist/codebuff-PODYPOOP.js.map +1 -0
  48. package/dist/{codex-BXA4FIF4.js → codex-O4G7D7KK.js} +61 -13
  49. package/dist/codex-O4G7D7KK.js.map +1 -0
  50. package/dist/continue-K43SUHLQ.js +790 -0
  51. package/dist/continue-K43SUHLQ.js.map +1 -0
  52. package/dist/{copilot-cli-ROIBTTDT.js → copilot-cli-Q3SSPT4V.js} +70 -12
  53. package/dist/copilot-cli-Q3SSPT4V.js.map +1 -0
  54. package/dist/{crush-QLEFLHUC.js → crush-MBEH2R3I.js} +130 -6
  55. package/dist/crush-MBEH2R3I.js.map +1 -0
  56. package/dist/{cursor-ASJPWZ4R.js → cursor-TMBXDYR4.js} +119 -19
  57. package/dist/cursor-TMBXDYR4.js.map +1 -0
  58. package/dist/{detect-ZIIS55LD.js → detect-AHJIUMBO.js} +5 -4
  59. package/dist/{detect-ZIIS55LD.js.map → detect-AHJIUMBO.js.map} +1 -1
  60. package/dist/{doctor-TJUGSQ5C.js → doctor-G5MLCPAB.js} +221 -95
  61. package/dist/doctor-G5MLCPAB.js.map +1 -0
  62. package/dist/{droid-NCSS3B5Y.js → droid-JC2NT6S4.js} +135 -13
  63. package/dist/droid-JC2NT6S4.js.map +1 -0
  64. package/dist/{gemini-cli-SLVWLXJW.js → gemini-cli-ILR7M5X3.js} +62 -10
  65. package/dist/gemini-cli-ILR7M5X3.js.map +1 -0
  66. package/dist/{goose-PBA7KTE5.js → goose-SFO5BBGW.js} +15 -8
  67. package/dist/goose-SFO5BBGW.js.map +1 -0
  68. package/dist/{hermes-ONDCECP2.js → hermes-3N7WN4WS.js} +329 -15
  69. package/dist/hermes-3N7WN4WS.js.map +1 -0
  70. package/dist/{hook-OU522ABV.js → hook-76JBKTUX.js} +14 -11
  71. package/dist/hook-76JBKTUX.js.map +1 -0
  72. package/dist/index.d.ts +2 -2
  73. package/dist/index.js +3 -2
  74. package/dist/{install-UDCBL7HP.js → install-R7252QFH.js} +11 -10
  75. package/dist/{install-UDCBL7HP.js.map → install-R7252QFH.js.map} +1 -1
  76. package/dist/{introspect-DuZSPSHB.d.ts → introspect-Cn3MSA4_.d.ts} +1 -1
  77. package/dist/{jetbrains-copilot-YABZ3HFA.js → jetbrains-copilot-NRZHI5PC.js} +85 -18
  78. package/dist/jetbrains-copilot-NRZHI5PC.js.map +1 -0
  79. package/dist/{kilo-F3ZDZKCT.js → kilo-IX4T3OHJ.js} +115 -19
  80. package/dist/kilo-IX4T3OHJ.js.map +1 -0
  81. package/dist/{kilo-cli-3HWPWBY4.js → kilo-cli-2AYCXBQD.js} +109 -13
  82. package/dist/kilo-cli-2AYCXBQD.js.map +1 -0
  83. package/dist/{kimi-NV72FVAO.js → kimi-2YFK2GBA.js} +87 -25
  84. package/dist/kimi-2YFK2GBA.js.map +1 -0
  85. package/dist/{kiro-C5W6AGDR.js → kiro-YL6AWUYG.js} +3 -3
  86. package/dist/{leaderboard-TIBVONVT.js → leaderboard-V6VWA5ZV.js} +3 -3
  87. package/dist/{mimo-code-IMM5YM3M.js → mimo-code-FTMGSKMQ.js} +41 -5
  88. package/dist/mimo-code-FTMGSKMQ.js.map +1 -0
  89. package/dist/{mux-DSSH4AFS.js → mux-5XZFB44C.js} +156 -6
  90. package/dist/mux-5XZFB44C.js.map +1 -0
  91. package/dist/{nemoclaw-3EVNKD3I.js → nemoclaw-CQYXZVQN.js} +4 -4
  92. package/dist/{omp-Z6FRNDPN.js → omp-2QMEY6HD.js} +138 -18
  93. package/dist/omp-2QMEY6HD.js.map +1 -0
  94. package/dist/{openclaw-7G437NT7.js → openclaw-UZC437RW.js} +4 -4
  95. package/dist/{opencode-Q6KBSAKW.js → opencode-L4BGFP25.js} +87 -27
  96. package/dist/opencode-L4BGFP25.js.map +1 -0
  97. package/dist/{package-RMPN57YZ.js → package-DNLQTPNN.js} +8 -7
  98. package/dist/{package-RMPN57YZ.js.map → package-DNLQTPNN.js.map} +1 -1
  99. package/dist/{pi-LZT6WWAZ.js → pi-PVVPVWKG.js} +3 -2
  100. package/dist/{pi-LZT6WWAZ.js.map → pi-PVVPVWKG.js.map} +1 -1
  101. package/dist/{qwen-code-WQBKRPWJ.js → qwen-code-G4CXKUHR.js} +426 -10
  102. package/dist/qwen-code-G4CXKUHR.js.map +1 -0
  103. package/dist/{roo-code-GWSNU3OW.js → roo-code-67TYJIQR.js} +3 -3
  104. package/dist/runtime/index.d.ts +1 -1
  105. package/dist/runtime/index.js +9 -8
  106. package/dist/sdk/index.d.ts +3 -3
  107. package/dist/sdk/index.js +4 -3
  108. package/dist/sdk/index.js.map +1 -1
  109. package/dist/sdk/test.d.ts +2 -2
  110. package/dist/sdk/test.js +6 -5
  111. package/dist/sdk/test.js.map +1 -1
  112. package/dist/{serve-D3GO36UT.js → serve-EOVWYBGZ.js} +11 -10
  113. package/dist/{serve-D3GO36UT.js.map → serve-EOVWYBGZ.js.map} +1 -1
  114. package/dist/{status-KOSKCETC.js → status-VTD6XXLW.js} +7 -6
  115. package/dist/{status-KOSKCETC.js.map → status-VTD6XXLW.js.map} +1 -1
  116. package/dist/{statusline-ZNTCL5YC.js → statusline-3ET5YPQ5.js} +10 -9
  117. package/dist/{statusline-ZNTCL5YC.js.map → statusline-3ET5YPQ5.js.map} +1 -1
  118. package/dist/{telemetry-XIKUUGTQ.js → telemetry-QCTMKDBQ.js} +6 -5
  119. package/dist/{telemetry-XIKUUGTQ.js.map → telemetry-QCTMKDBQ.js.map} +1 -1
  120. package/dist/{trae-NWT3TMSZ.js → trae-7CZZGOGI.js} +3 -3
  121. package/dist/{types-BEKsAium.d.ts → types-_6arHbX9.d.ts} +67 -24
  122. package/dist/{uninstall-2LBLQVFA.js → uninstall-FL3SH2DT.js} +11 -10
  123. package/dist/{uninstall-2LBLQVFA.js.map → uninstall-FL3SH2DT.js.map} +1 -1
  124. package/dist/{upgrade-ZC2S7VRN.js → upgrade-SLFG2FCT.js} +11 -10
  125. package/dist/{upgrade-ZC2S7VRN.js.map → upgrade-SLFG2FCT.js.map} +1 -1
  126. package/dist/{usage-E2A4O2CY.js → usage-IRBLVUZM.js} +3 -3
  127. package/dist/{usage-event-JKMC4QC4.js → usage-event-VFF77WYY.js} +10 -9
  128. package/dist/{usage-event-JKMC4QC4.js.map → usage-event-VFF77WYY.js.map} +1 -1
  129. package/dist/{vscode-copilot-ALV45XF6.js → vscode-copilot-MF2CDNMT.js} +23 -10
  130. package/dist/vscode-copilot-MF2CDNMT.js.map +1 -0
  131. package/dist/{warp-H6IX4U3J.js → warp-VKG55TAT.js} +55 -4
  132. package/dist/warp-VKG55TAT.js.map +1 -0
  133. package/dist/windsurf-FU5G4SHF.js +443 -0
  134. package/dist/windsurf-FU5G4SHF.js.map +1 -0
  135. package/dist/{zed-RH34TNSW.js → zed-SFUHL3GS.js} +3 -3
  136. package/package.json +2 -2
  137. package/dist/amp-B524U6LO.js +0 -300
  138. package/dist/amp-B524U6LO.js.map +0 -1
  139. package/dist/chunk-3PFFTFCU.js +0 -190
  140. package/dist/chunk-3PFFTFCU.js.map +0 -1
  141. package/dist/chunk-76FUSVIA.js.map +0 -1
  142. package/dist/chunk-ADTHT2FN.js.map +0 -1
  143. package/dist/chunk-IW77FFNX.js.map +0 -1
  144. package/dist/chunk-KGGBNKI4.js.map +0 -1
  145. package/dist/chunk-MAH6QQTO.js.map +0 -1
  146. package/dist/claude-code-MLWS7CW6.js.map +0 -1
  147. package/dist/codebuff-SH2S3QAN.js.map +0 -1
  148. package/dist/codex-BXA4FIF4.js.map +0 -1
  149. package/dist/copilot-cli-ROIBTTDT.js.map +0 -1
  150. package/dist/crush-QLEFLHUC.js.map +0 -1
  151. package/dist/cursor-ASJPWZ4R.js.map +0 -1
  152. package/dist/doctor-TJUGSQ5C.js.map +0 -1
  153. package/dist/droid-NCSS3B5Y.js.map +0 -1
  154. package/dist/gemini-cli-SLVWLXJW.js.map +0 -1
  155. package/dist/goose-PBA7KTE5.js.map +0 -1
  156. package/dist/hermes-ONDCECP2.js.map +0 -1
  157. package/dist/hook-OU522ABV.js.map +0 -1
  158. package/dist/jetbrains-copilot-YABZ3HFA.js.map +0 -1
  159. package/dist/kilo-F3ZDZKCT.js.map +0 -1
  160. package/dist/kilo-cli-3HWPWBY4.js.map +0 -1
  161. package/dist/kimi-NV72FVAO.js.map +0 -1
  162. package/dist/mimo-code-IMM5YM3M.js.map +0 -1
  163. package/dist/mux-DSSH4AFS.js.map +0 -1
  164. package/dist/omp-Z6FRNDPN.js.map +0 -1
  165. package/dist/opencode-Q6KBSAKW.js.map +0 -1
  166. package/dist/qwen-code-WQBKRPWJ.js.map +0 -1
  167. package/dist/vscode-copilot-ALV45XF6.js.map +0 -1
  168. package/dist/warp-H6IX4U3J.js.map +0 -1
  169. /package/dist/{antigravity-ANDKF3K7.js.map → antigravity-AMKKKHS4.js.map} +0 -0
  170. /package/dist/{antigravity-cli-LLRPDDOT.js.map → antigravity-cli-XERXEH5W.js.map} +0 -0
  171. /package/dist/{chunk-G3ER4SY5.js.map → chunk-5G4EPJ4Y.js.map} +0 -0
  172. /package/dist/{chunk-J3D5W5T2.js.map → chunk-EROJDXMW.js.map} +0 -0
  173. /package/dist/{chunk-22Y24V7O.js.map → chunk-F5RX62T7.js.map} +0 -0
  174. /package/dist/{chunk-LL4OBGRU.js.map → chunk-LQRAPXS4.js.map} +0 -0
  175. /package/dist/{chunk-KGJWE6A2.js.map → chunk-MZF2YCXX.js.map} +0 -0
  176. /package/dist/{chunk-CIRDOY2V.js.map → chunk-QOGMDOUX.js.map} +0 -0
  177. /package/dist/{chunk-6XHB6BE3.js.map → chunk-SCVBYSF7.js.map} +0 -0
  178. /package/dist/{kiro-C5W6AGDR.js.map → kiro-YL6AWUYG.js.map} +0 -0
  179. /package/dist/{leaderboard-TIBVONVT.js.map → leaderboard-V6VWA5ZV.js.map} +0 -0
  180. /package/dist/{nemoclaw-3EVNKD3I.js.map → nemoclaw-CQYXZVQN.js.map} +0 -0
  181. /package/dist/{openclaw-7G437NT7.js.map → openclaw-UZC437RW.js.map} +0 -0
  182. /package/dist/{roo-code-GWSNU3OW.js.map → roo-code-67TYJIQR.js.map} +0 -0
  183. /package/dist/{trae-NWT3TMSZ.js.map → trae-7CZZGOGI.js.map} +0 -0
  184. /package/dist/{usage-E2A4O2CY.js.map → usage-IRBLVUZM.js.map} +0 -0
  185. /package/dist/{zed-RH34TNSW.js.map → zed-SFUHL3GS.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli/app.ts"],"sourcesContent":["/**\n * cli/app — shared CLI helpers + command dispatch (NO side effects).\n *\n * Command modules import the shared helpers (print, fail, parse-flags,\n * renderInstallResult) from here, and main() dispatches the first positional to a\n * command module.\n * This module never auto-runs — `cli/index.ts` is the thin bin entry that calls\n * `main()`. Keeping the auto-run out of here is what prevents a dispatch recursion\n * (a command module importing a helper must not re-trigger the program) and makes\n * it robust to bundler entry-splitting (the old import.meta.url entry-guard broke\n * once tsup hoisted this code into a shared chunk).\n */\n\nimport { createRequire } from \"node:module\";\n\nimport type {\n ChangeRecord,\n InstallResult,\n InstallScope,\n PlatformId,\n} from \"../core/types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Shared helpers (imported by the command modules)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Print a line to stdout (machine-readable payloads must stay on stdout). */\nexport function print(line: string): void {\n process.stdout.write(`${line}\\n`);\n}\n\n/**\n * The brand active for THIS invocation. main() sets it from\n * {@link MainOptions.programName} before dispatch, so error messages printed by\n * command modules via {@link fail} read as the embedding tool (e.g. `acme-db:`)\n * instead of always `agent-connector:`.\n */\nlet activeProgramName = \"agent-connector\";\n\n/** Print an error to stderr (branded) and return a non-zero exit code (default 2). */\nexport function fail(message: string, code = 2): number {\n process.stderr.write(`${activeProgramName}: ${message}\\n`);\n return code;\n}\n\n/**\n * Resolve agent-connector's own package version at runtime. Works from both the\n * bundled dist layout (dist/*.js → ../package.json) and the src layout under\n * tsx/vitest (src/cli/ → ../../package.json); the name check guards against\n * accidentally reading some other package.json on the walk.\n */\nexport function resolveOwnVersion(): string {\n const req = createRequire(import.meta.url);\n for (const rel of [\"../package.json\", \"../../package.json\", \"../../../package.json\"]) {\n try {\n const pkg = req(rel) as { name?: string; version?: string };\n if (pkg.name === \"@ken-jo/agent-connector\" && typeof pkg.version === \"string\") {\n return pkg.version;\n }\n } catch {\n /* keep walking */\n }\n }\n return \"0.0.0\";\n}\n\n/** Parse a --scope value the CLI accepts (user|project) into an InstallScope. */\nexport function parseScope(value: string | undefined): InstallScope | null {\n if (value === \"user\" || value === \"project\") return value;\n return null;\n}\n\n/**\n * Parse a comma-separated --targets value into PlatformId[]. Returns undefined\n * when the flag is absent/empty so callers can fall back to connector/detection.\n */\nexport function parseTargets(value: string | undefined): PlatformId[] | undefined {\n if (value == null || value.trim() === \"\") return undefined;\n const ids = value\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s !== \"\") as PlatformId[];\n return ids.length > 0 ? ids : undefined;\n}\n\nconst ACTION_GLYPH: Record<ChangeRecord[\"action\"], string> = {\n create: \"+\",\n update: \"~\",\n remove: \"-\",\n skip: \"=\",\n warn: \"!\",\n};\n\n/**\n * Render an InstallResult as a readable diff: one line per ChangeRecord (glyph,\n * platform, detail, path) followed by any warnings and a summary tally. Used by\n * install / upgrade / uninstall.\n */\nexport function renderInstallResult(\n result: InstallResult,\n verb: \"install\" | \"upgrade\" | \"uninstall\",\n): string {\n const lines: string[] = [];\n const mode = result.dryRun ? \" (dry-run — nothing written)\" : \"\";\n lines.push(`${verb} \"${result.connectorId}\"${mode}`);\n\n if (result.changes.length === 0) {\n lines.push(\" (no changes)\");\n } else {\n for (const c of result.changes) {\n const glyph = ACTION_GLYPH[c.action];\n const where = c.path ? ` ${c.path}` : \"\";\n lines.push(` ${glyph} [${c.platform}] ${c.action}: ${c.detail}${where}`);\n }\n }\n\n if (result.warnings.length > 0) {\n lines.push(\"\");\n lines.push(\"warnings:\");\n for (const w of result.warnings) lines.push(` ! ${w}`);\n }\n\n const tally = result.changes.reduce<Record<ChangeRecord[\"action\"], number>>(\n (acc, c) => {\n acc[c.action] += 1;\n return acc;\n },\n { create: 0, update: 0, remove: 0, skip: 0, warn: 0 },\n );\n lines.push(\"\");\n lines.push(\n `summary: ${tally.create} created, ${tally.update} updated, ` +\n `${tally.remove} removed, ${tally.skip} skipped, ${tally.warn} warning(s)`,\n );\n\n return lines.join(\"\\n\");\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Command dispatch\n// ─────────────────────────────────────────────────────────────────────────\n\n/** A command module: takes the post-command argv slice, returns an exit code. */\ntype CommandModule = { run: (argv: string[]) => Promise<number> | number };\n\n/** Lazy command loaders — keyed by the first positional. Imported on demand. */\nconst COMMANDS: Record<string, () => Promise<CommandModule>> = {\n detect: () => import(\"./commands/detect.js\"),\n install: () => import(\"./commands/install.js\"),\n uninstall: () => import(\"./commands/uninstall.js\"),\n // `upgrade` is the single \"bring everything current\" verb (re-render host\n // config + refresh the home pointer + managed channel guidance). `sync` and\n // `update` are kept as back-compat aliases that route to the same module so\n // existing scripts/docs keep working without a second concept to learn.\n upgrade: () => import(\"./commands/upgrade.js\"),\n sync: () => import(\"./commands/upgrade.js\"),\n update: () => import(\"./commands/upgrade.js\"),\n package: () => import(\"./commands/package.js\"),\n doctor: () => import(\"./commands/doctor.js\"),\n status: () => import(\"./commands/status.js\"),\n telemetry: () => import(\"./commands/telemetry.js\"),\n usage: () => import(\"./commands/usage.js\"),\n leaderboard: () => import(\"./commands/leaderboard.js\"),\n hook: () => import(\"./commands/hook.js\"),\n // Internal (omitted from USAGE): the statusline (HUD) entrypoint a host's\n // status line config points at. Fail-safe: always exits 0 with at most a\n // rendered line. See cli/commands/statusline.ts.\n statusline: () => import(\"./commands/statusline.js\"),\n // Internal (omitted from USAGE): the user-invokable action entrypoint a future\n // host affordance points at. USER-TRIGGERED: surfaces errors (exit 1 + stderr),\n // unlike the fail-open hook / fail-safe statusline. See cli/commands/action.ts.\n action: () => import(\"./commands/action.js\"),\n serve: () => import(\"./commands/serve.js\"),\n // Hidden (omitted from USAGE): the opt-in host-native turn-usage entrypoint an\n // AfterModel / PostInvocation hook points at. Always exits 0; records a\n // distinct `model_turn` row. See cli/commands/usage-event.ts.\n \"usage-event\": () => import(\"./commands/usage-event.js\"),\n};\n\n/** Default program name; an embedding SDK CLI overrides it via {@link MainOptions}. */\nexport const DEFAULT_PROGRAM_NAME = \"agent-connector\";\n\n/**\n * One-line usage signature per command — the single central copy behind\n * `<command> --help` and the friendly bad-flag error. Command modules use\n * node:util parseArgs (strict), which THROWS on an unknown flag; without the\n * dispatcher-level handling in {@link main}, `agent-connector install --help`\n * would die with a raw ERR_PARSE_ARGS stack trace — the very invocation the\n * root help tells users to run.\n */\nconst COMMAND_USAGE: Record<string, string> = {\n detect: \"detect [--json] [--project <dir>]\",\n install:\n \"install [--method direct|marketplace] [--connector <path>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run] [--force]\",\n uninstall:\n \"uninstall [--method auto|direct|marketplace] [--connector <path>] [--connector-id <id>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run] [--purge]\",\n upgrade:\n \"upgrade [--method direct|marketplace] [--channel stable|latest] [--connector <path>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run]\",\n sync: \"sync — alias of upgrade (see `upgrade --help`)\",\n update: \"update — alias of upgrade (see `upgrade --help`)\",\n package:\n \"package [--connector <path>] [--format <fmt>|all] [--out <dir>] [--project <dir>] [--dry-run]\",\n doctor:\n \"doctor [--targets a,b] [--connector <path>] [--scope user|project] [--project <dir>] [--probe] [--json]\",\n status: \"status [--connector <path>] [--scope user|project] [--project <dir>] [--json]\",\n telemetry:\n \"telemetry report|export|leaderboard [--by <dim>] [--since <dur>] [--connector <id>] [--scope <slice>] [--format csv|json] [--out <file>] [--json]\",\n usage:\n \"usage report|export|leaderboard [--by <dim>] [--since <dur>] [--platform <id>] [--format csv|json] [--out <file>] [--json]\",\n leaderboard: \"leaderboard [--since <dur>] [--connector <id>] [--scope <slice>] [--json]\",\n hook: \"hook <platform> <event> --connector <id> (internal — host hook configs point here)\",\n statusline:\n \"statusline <platform> --connector <id> (internal — host status line configs point here)\",\n action:\n \"action <platform> <actionId> --connector <id> (internal — host action affordances point here)\",\n serve:\n \"serve --connector <id> [--scope user|project] [--host <platformId>] -- <command> [args...] (internal — host MCP entries point here)\",\n};\n\n/**\n * Build the top-level usage string for a given program name. The brand replaces\n * \"agent-connector\" in the title, the `usage:` line, and the per-command help\n * footer so an embedded CLI (e.g. `acme-db`) reads as its own tool.\n */\nfunction buildUsage(programName: string): string {\n return `${programName} — write your MCP server + hooks once, install everywhere.\n\nusage: ${programName} <command> [flags]\n\ncommands:\n detect List the AI-agent platforms installed on this machine.\n install Deploy a connector across its target platforms (--method direct writes host config; --method marketplace drives the host's plugin install).\n uninstall Remove a connector's registrations (--method auto reverses whichever method is actually installed).\n upgrade Bring everything current: re-render host config + heal the home pointer + managed update guidance (alias: update, sync).\n package Emit a marketplace/extension bundle (9 host formats, or the standard artifacts mcp-server-json | mcpb).\n doctor Health-check every detected platform; non-zero exit on any failure.\n status Light install-state summary: which connectors are present on which hosts (always exits 0).\n telemetry Inspect local per-tool token telemetry (report | export | leaderboard).\n usage Inspect host-native token usage from agent CLI logs (report | export | leaderboard).\n leaderboard Three leaderboards: 🔌 MCP/plugin (mcp-self) + 🖥️ host/user (host-scan-logs) + 🛰️ host-native turns (host-native-live) — never summed.\n hook Universal json-stdio hook entrypoint (hosts call this).\n serve Telemetry-wrapping MCP stdio proxy (wraps a real server command).\n\nRun \\`${programName} <command> --help\\` for command-specific flags.`;\n}\n\n/** Options accepted by {@link main}. */\nexport interface MainOptions {\n /**\n * The brand shown in usage/help text. Defaults to {@link DEFAULT_PROGRAM_NAME}.\n * An embedding SDK CLI (see cli/sdk.ts) passes its own bin name so every\n * subcommand's help reads as the developer's tool.\n */\n programName?: string;\n}\n\nexport async function main(argv: string[], opts: MainOptions = {}): Promise<number> {\n const programName = opts.programName ?? DEFAULT_PROGRAM_NAME;\n activeProgramName = programName; // brand every fail() in this invocation\n const usage = buildUsage(programName);\n const command = argv[0];\n\n if (command == null || command === \"--help\" || command === \"-h\" || command === \"help\") {\n print(usage);\n return command == null ? 1 : 0;\n }\n if (command === \"--version\" || command === \"-v\") {\n print(`${programName} ${resolveOwnVersion()}`);\n return 0;\n }\n\n const loader = COMMANDS[command];\n if (!loader) {\n process.stderr.write(`${programName}: unknown command \"${command}\"\\n\\n`);\n process.stderr.write(`${usage}\\n`);\n return 2;\n }\n\n // Per-command help: no command module defines a --help flag (strict parseArgs\n // would throw on it), so answer it centrally from COMMAND_USAGE.\n const rest = argv.slice(1);\n if (rest.includes(\"--help\") || rest.includes(\"-h\")) {\n const sig = COMMAND_USAGE[command];\n if (sig) {\n print(`usage: ${programName} ${sig}`);\n return 0;\n }\n }\n\n const mod = await loader();\n try {\n return await mod.run(rest);\n } catch (err) {\n // Friendly bad-flag errors: strict parseArgs throws ERR_PARSE_ARGS_* for an\n // unknown/malformed option — print the message + the usage line instead of\n // letting a raw stack trace reach the user. Everything else still rethrows\n // (the bin entry reports those as fatal).\n const code = (err as { code?: string }).code;\n if (typeof code === \"string\" && code.startsWith(\"ERR_PARSE_ARGS\")) {\n const message = err instanceof Error ? err.message : String(err);\n const sig = COMMAND_USAGE[command];\n if (sig) process.stderr.write(`usage: ${programName} ${sig}\\n`);\n return fail(message);\n }\n throw err;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/cli/app.ts"],"sourcesContent":["/**\n * cli/app — shared CLI helpers + command dispatch (NO side effects).\n *\n * Command modules import the shared helpers (print, fail, parse-flags,\n * renderInstallResult) from here, and main() dispatches the first positional to a\n * command module.\n * This module never auto-runs — `cli/index.ts` is the thin bin entry that calls\n * `main()`. Keeping the auto-run out of here is what prevents a dispatch recursion\n * (a command module importing a helper must not re-trigger the program) and makes\n * it robust to bundler entry-splitting (the old import.meta.url entry-guard broke\n * once tsup hoisted this code into a shared chunk).\n */\n\nimport { createRequire } from \"node:module\";\n\nimport type {\n ChangeRecord,\n InstallResult,\n InstallScope,\n PlatformId,\n} from \"../core/types.js\";\n\n// ─────────────────────────────────────────────────────────────────────────\n// Shared helpers (imported by the command modules)\n// ─────────────────────────────────────────────────────────────────────────\n\n/** Print a line to stdout (machine-readable payloads must stay on stdout). */\nexport function print(line: string): void {\n process.stdout.write(`${line}\\n`);\n}\n\n/**\n * The brand active for THIS invocation. main() sets it from\n * {@link MainOptions.programName} before dispatch, so error messages printed by\n * command modules via {@link fail} read as the embedding tool (e.g. `acme-db:`)\n * instead of always `agent-connector:`.\n */\nlet activeProgramName = \"agent-connector\";\n\n/** Print an error to stderr (branded) and return a non-zero exit code (default 2). */\nexport function fail(message: string, code = 2): number {\n process.stderr.write(`${activeProgramName}: ${message}\\n`);\n return code;\n}\n\n/**\n * Resolve agent-connector's own package version at runtime. Works from both the\n * bundled dist layout (dist/*.js → ../package.json) and the src layout under\n * tsx/vitest (src/cli/ → ../../package.json); the name check guards against\n * accidentally reading some other package.json on the walk.\n */\nexport function resolveOwnVersion(): string {\n const req = createRequire(import.meta.url);\n for (const rel of [\"../package.json\", \"../../package.json\", \"../../../package.json\"]) {\n try {\n const pkg = req(rel) as { name?: string; version?: string };\n if (pkg.name === \"@ken-jo/agent-connector\" && typeof pkg.version === \"string\") {\n return pkg.version;\n }\n } catch {\n /* keep walking */\n }\n }\n return \"0.0.0\";\n}\n\n/** Parse a --scope value the CLI accepts (user|project) into an InstallScope. */\nexport function parseScope(value: string | undefined): InstallScope | null {\n if (value === \"user\" || value === \"project\") return value;\n return null;\n}\n\n/**\n * Parse a comma-separated --targets value into PlatformId[]. Returns undefined\n * when the flag is absent/empty so callers can fall back to connector/detection.\n */\nexport function parseTargets(value: string | undefined): PlatformId[] | undefined {\n if (value == null || value.trim() === \"\") return undefined;\n const ids = value\n .split(\",\")\n .map((s) => s.trim())\n .filter((s) => s !== \"\") as PlatformId[];\n return ids.length > 0 ? ids : undefined;\n}\n\nconst ACTION_GLYPH: Record<ChangeRecord[\"action\"], string> = {\n create: \"+\",\n update: \"~\",\n remove: \"-\",\n skip: \"=\",\n warn: \"!\",\n};\n\n/**\n * Render an InstallResult as a readable diff: one line per ChangeRecord (glyph,\n * platform, detail, path) followed by any warnings and a summary tally. Used by\n * install / upgrade / uninstall.\n */\nexport function renderInstallResult(\n result: InstallResult,\n verb: \"install\" | \"upgrade\" | \"uninstall\",\n): string {\n const lines: string[] = [];\n const mode = result.dryRun ? \" (dry-run — nothing written)\" : \"\";\n lines.push(`${verb} \"${result.connectorId}\"${mode}`);\n\n if (result.changes.length === 0) {\n lines.push(\" (no changes)\");\n } else {\n for (const c of result.changes) {\n const glyph = ACTION_GLYPH[c.action];\n const where = c.path ? ` ${c.path}` : \"\";\n lines.push(` ${glyph} [${c.platform}] ${c.action}: ${c.detail}${where}`);\n }\n }\n\n if (result.warnings.length > 0) {\n lines.push(\"\");\n lines.push(\"warnings:\");\n for (const w of result.warnings) lines.push(` ! ${w}`);\n }\n\n const tally = result.changes.reduce<Record<ChangeRecord[\"action\"], number>>(\n (acc, c) => {\n acc[c.action] += 1;\n return acc;\n },\n { create: 0, update: 0, remove: 0, skip: 0, warn: 0 },\n );\n lines.push(\"\");\n lines.push(\n `summary: ${tally.create} created, ${tally.update} updated, ` +\n `${tally.remove} removed, ${tally.skip} skipped, ${tally.warn} warning(s)`,\n );\n\n return lines.join(\"\\n\");\n}\n\n// ─────────────────────────────────────────────────────────────────────────\n// Command dispatch\n// ─────────────────────────────────────────────────────────────────────────\n\n/** A command module: takes the post-command argv slice, returns an exit code. */\ntype CommandModule = { run: (argv: string[]) => Promise<number> | number };\n\n/** Lazy command loaders — keyed by the first positional. Imported on demand. */\nconst COMMANDS: Record<string, () => Promise<CommandModule>> = {\n detect: () => import(\"./commands/detect.js\"),\n install: () => import(\"./commands/install.js\"),\n uninstall: () => import(\"./commands/uninstall.js\"),\n // `upgrade` is the single \"bring everything current\" verb (re-render host\n // config + refresh the home pointer + managed channel guidance). `sync` and\n // `update` are kept as back-compat aliases that route to the same module so\n // existing scripts/docs keep working without a second concept to learn.\n upgrade: () => import(\"./commands/upgrade.js\"),\n sync: () => import(\"./commands/upgrade.js\"),\n update: () => import(\"./commands/upgrade.js\"),\n package: () => import(\"./commands/package.js\"),\n doctor: () => import(\"./commands/doctor.js\"),\n status: () => import(\"./commands/status.js\"),\n telemetry: () => import(\"./commands/telemetry.js\"),\n usage: () => import(\"./commands/usage.js\"),\n leaderboard: () => import(\"./commands/leaderboard.js\"),\n hook: () => import(\"./commands/hook.js\"),\n // Internal (omitted from USAGE): the statusline (HUD) entrypoint a host's\n // status line config points at. Fail-safe: always exits 0 with at most a\n // rendered line. See cli/commands/statusline.ts.\n statusline: () => import(\"./commands/statusline.js\"),\n // Internal (omitted from USAGE): the user-invokable action entrypoint a future\n // host affordance points at. USER-TRIGGERED: surfaces errors (exit 1 + stderr),\n // unlike the fail-open hook / fail-safe statusline. See cli/commands/action.ts.\n action: () => import(\"./commands/action.js\"),\n serve: () => import(\"./commands/serve.js\"),\n // Hidden (omitted from USAGE): the opt-in host-native turn-usage entrypoint an\n // AfterModel / PostInvocation hook points at. Always exits 0; records a\n // distinct `model_turn` row. See cli/commands/usage-event.ts.\n \"usage-event\": () => import(\"./commands/usage-event.js\"),\n};\n\n/** Default program name; an embedding SDK CLI overrides it via {@link MainOptions}. */\nexport const DEFAULT_PROGRAM_NAME = \"agent-connector\";\n\n/**\n * One-line usage signature per command — the single central copy behind\n * `<command> --help` and the friendly bad-flag error. Command modules use\n * node:util parseArgs (strict), which THROWS on an unknown flag; without the\n * dispatcher-level handling in {@link main}, `agent-connector install --help`\n * would die with a raw ERR_PARSE_ARGS stack trace — the very invocation the\n * root help tells users to run.\n */\nconst COMMAND_USAGE: Record<string, string> = {\n detect: \"detect [--json] [--project <dir>]\",\n install:\n \"install [--method direct|marketplace] [--connector <path>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run] [--force]\",\n uninstall:\n \"uninstall [--method auto|direct|marketplace] [--connector <path>] [--connector-id <id>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run] [--purge]\",\n upgrade:\n \"upgrade [--method direct|marketplace] [--channel stable|latest] [--connector <path>] [--scope user|project] [--targets a,b] [--project <dir>] [--dry-run]\",\n sync: \"sync — alias of upgrade (see `upgrade --help`)\",\n update: \"update — alias of upgrade (see `upgrade --help`)\",\n package:\n \"package [--connector <path>] [--format <fmt>|all] [--out <dir>] [--project <dir>] [--dry-run]\",\n doctor:\n \"doctor [--targets a,b] [--connector <path>] [--scope user|project] [--project <dir>] [--probe] [--json] [--heal] [--dry-run]\",\n status: \"status [--connector <path>] [--scope user|project] [--project <dir>] [--json]\",\n telemetry:\n \"telemetry report|export|leaderboard [--by <dim>] [--since <dur>] [--connector <id>] [--scope <slice>] [--format csv|json] [--out <file>] [--json]\",\n usage:\n \"usage report|export|leaderboard [--by <dim>] [--since <dur>] [--platform <id>] [--format csv|json] [--out <file>] [--json]\",\n leaderboard: \"leaderboard [--since <dur>] [--connector <id>] [--scope <slice>] [--json]\",\n hook: \"hook <platform> <event> --connector <id> (internal — host hook configs point here)\",\n statusline:\n \"statusline <platform> --connector <id> (internal — host status line configs point here)\",\n action:\n \"action <platform> <actionId> --connector <id> (internal — host action affordances point here)\",\n serve:\n \"serve --connector <id> [--scope user|project] [--host <platformId>] -- <command> [args...] (internal — host MCP entries point here)\",\n};\n\n/**\n * Build the top-level usage string for a given program name. The brand replaces\n * \"agent-connector\" in the title, the `usage:` line, and the per-command help\n * footer so an embedded CLI (e.g. `acme-db`) reads as its own tool.\n */\nfunction buildUsage(programName: string): string {\n return `${programName} — write your MCP server + hooks once, install everywhere.\n\nusage: ${programName} <command> [flags]\n\ncommands:\n detect List the AI-agent platforms installed on this machine.\n install Deploy a connector across its target platforms (--method direct writes host config; --method marketplace drives the host's plugin install).\n uninstall Remove a connector's registrations (--method auto reverses whichever method is actually installed).\n upgrade Bring everything current: re-render host config + heal the home pointer + managed update guidance (alias: update, sync).\n package Emit a marketplace/extension bundle (9 host formats, or the standard artifacts mcp-server-json | mcpb).\n doctor Health-check every detected platform; non-zero exit on any failure.\n status Light install-state summary: which connectors are present on which hosts (always exits 0).\n telemetry Inspect local per-tool token telemetry (report | export | leaderboard).\n usage Inspect host-native token usage from agent CLI logs (report | export | leaderboard).\n leaderboard Three leaderboards: 🔌 MCP/plugin (mcp-self) + 🖥️ host/user (host-scan-logs) + 🛰️ host-native turns (host-native-live) — never summed.\n hook Universal json-stdio hook entrypoint (hosts call this).\n serve Telemetry-wrapping MCP stdio proxy (wraps a real server command).\n\nRun \\`${programName} <command> --help\\` for command-specific flags.`;\n}\n\n/** Options accepted by {@link main}. */\nexport interface MainOptions {\n /**\n * The brand shown in usage/help text. Defaults to {@link DEFAULT_PROGRAM_NAME}.\n * An embedding SDK CLI (see cli/sdk.ts) passes its own bin name so every\n * subcommand's help reads as the developer's tool.\n */\n programName?: string;\n}\n\nexport async function main(argv: string[], opts: MainOptions = {}): Promise<number> {\n const programName = opts.programName ?? DEFAULT_PROGRAM_NAME;\n activeProgramName = programName; // brand every fail() in this invocation\n const usage = buildUsage(programName);\n const command = argv[0];\n\n if (command == null || command === \"--help\" || command === \"-h\" || command === \"help\") {\n print(usage);\n return command == null ? 1 : 0;\n }\n if (command === \"--version\" || command === \"-v\") {\n print(`${programName} ${resolveOwnVersion()}`);\n return 0;\n }\n\n const loader = COMMANDS[command];\n if (!loader) {\n process.stderr.write(`${programName}: unknown command \"${command}\"\\n\\n`);\n process.stderr.write(`${usage}\\n`);\n return 2;\n }\n\n // Per-command help: no command module defines a --help flag (strict parseArgs\n // would throw on it), so answer it centrally from COMMAND_USAGE.\n const rest = argv.slice(1);\n if (rest.includes(\"--help\") || rest.includes(\"-h\")) {\n const sig = COMMAND_USAGE[command];\n if (sig) {\n print(`usage: ${programName} ${sig}`);\n return 0;\n }\n }\n\n const mod = await loader();\n try {\n return await mod.run(rest);\n } catch (err) {\n // Friendly bad-flag errors: strict parseArgs throws ERR_PARSE_ARGS_* for an\n // unknown/malformed option — print the message + the usage line instead of\n // letting a raw stack trace reach the user. Everything else still rethrows\n // (the bin entry reports those as fatal).\n const code = (err as { code?: string }).code;\n if (typeof code === \"string\" && code.startsWith(\"ERR_PARSE_ARGS\")) {\n const message = err instanceof Error ? err.message : String(err);\n const sig = COMMAND_USAGE[command];\n if (sig) process.stderr.write(`usage: ${programName} ${sig}\\n`);\n return fail(message);\n }\n throw err;\n }\n}\n"],"mappings":"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","names":[]}
@@ -12,11 +12,11 @@ import {
12
12
  import {
13
13
  loadRegisteredConnector,
14
14
  readRegisteredMeta
15
- } from "./chunk-KGJWE6A2.js";
15
+ } from "./chunk-MZF2YCXX.js";
16
16
  import {
17
17
  REGISTERED_PLATFORM_IDS,
18
18
  loadAdapter
19
- } from "./chunk-3PFFTFCU.js";
19
+ } from "./chunk-BMD7ANKF.js";
20
20
  import {
21
21
  projectIdentity
22
22
  } from "./chunk-TRQKHP7D.js";
@@ -348,4 +348,4 @@ export {
348
348
  isNativeHookDeclared,
349
349
  runNativeHook
350
350
  };
351
- //# sourceMappingURL=chunk-CIRDOY2V.js.map
351
+ //# sourceMappingURL=chunk-QOGMDOUX.js.map
@@ -5,11 +5,11 @@ import {
5
5
  import {
6
6
  BaseAdapter,
7
7
  parseJsonc
8
- } from "./chunk-IW77FFNX.js";
8
+ } from "./chunk-CPLK7GTE.js";
9
9
  import {
10
10
  buildServeWrapperCommand,
11
11
  shouldWrapForTelemetry
12
- } from "./chunk-BXGFUENQ.js";
12
+ } from "./chunk-I5MLE6S7.js";
13
13
 
14
14
  // src/adapters/openclaw/index.ts
15
15
  import {
@@ -34,6 +34,8 @@ var EVENT_TO_OPENCLAW = {
34
34
  PreToolUse: "before_tool_call",
35
35
  PostToolUse: "after_tool_call",
36
36
  SessionStart: "session_start",
37
+ // Per-turn context injection at prompt assembly (context-only, no blocking).
38
+ UserPromptSubmit: "before_prompt_build",
37
39
  // Subagent lifecycle: OpenClaw observes launch + completion (no decision
38
40
  // control on either). PermissionRequest is deliberately ABSENT — OpenClaw's
39
41
  // permission gate is the requireApproval RETURN VALUE of before_tool_call,
@@ -63,7 +65,10 @@ var OpenClawAdapter = class extends BaseAdapter {
63
65
  preCompact: false,
64
66
  sessionStart: true,
65
67
  sessionEnd: false,
66
- userPromptSubmit: false,
68
+ // before_prompt_build fires per-turn and injects context (no blocking), so
69
+ // UserPromptSubmit is supported as CONTEXT-INJECTION-ONLY: a block/deny
70
+ // decision degrades to a no-op (it cannot stop the prompt here).
71
+ userPromptSubmit: true,
67
72
  stop: false,
68
73
  notification: false,
69
74
  // Newer events: OpenClaw observes the full subagent lifecycle via
@@ -81,14 +86,27 @@ var OpenClawAdapter = class extends BaseAdapter {
81
86
  canModifyOutput: false,
82
87
  // injected via before_prompt_build at prompt assembly.
83
88
  canInjectSessionContext: true,
84
- // OpenClaw's MCP sidecar registration is stdio-only in practice.
85
- transports: ["stdio"],
89
+ // stdio sidecars + remote servers. OpenClaw's validator accepts a remote
90
+ // transport of "sse" | "streamable-http" (AC "http" → "streamable-http");
91
+ // verified against OpenClaw 2026.6.1 + docs.openclaw.ai/gateway/configuration-reference.
92
+ transports: ["stdio", "sse", "http"],
86
93
  // Content surface: OpenClaw follows the AgentSkills spec (dir-per-skill
87
94
  // SKILL.md with {name, description} frontmatter + body). User scope →
88
95
  // ~/.openclaw/skills (the `openclaw skills install --global` target);
89
96
  // project scope → the resolved <workspace>/skills (the highest-priority
90
97
  // documented skill root, the same workspace the memory surface anchors to).
91
- supportsSkills: true
98
+ supportsSkills: true,
99
+ // Action surface: each declared action becomes a user-invokable slash
100
+ // command registered INSIDE the generated plugin module (api.registerCommand),
101
+ // shelling out to the home-bin action verb with the install target baked as
102
+ // the host token (this.id), so a fork like NemoClaw emits `action nemoclaw`.
103
+ // supportsActions -> the installActions/uninstallActions overrides below.
104
+ supportsActions: true,
105
+ // Native passthrough: OpenClaw lifecycle hook names with no canonical analog
106
+ // (declared on platforms.<id>.nativeHooks) are bridged verbatim by the
107
+ // generated plugin via the same on(...) helper → home-bin runNativeHook
108
+ // dispatch (mirrors omp/opencode). Independent of hooks:false.
109
+ supportsNativeHooks: true
92
110
  };
93
111
  // ── Tolerant JSON5/JSONC read (override base strict JSON.parse) ──────────
94
112
  /**
@@ -225,7 +243,7 @@ var OpenClawAdapter = class extends BaseAdapter {
225
243
  * stdio → { command, args?, env? } (NO transport key — a stdio sidecar is
226
244
  * inferred from `command`; OpenClaw's validator rejects
227
245
  * transport:"stdio" and only accepts "sse"/"streamable-http")
228
- * remote → { url, transport: "sse"|"http", headers? }
246
+ * remote → { url, transport: "sse"|"streamable-http", headers? }
229
247
  *
230
248
  * OpenClaw documents no native ${env:VAR} token, so refs resolve to literals.
231
249
  */
@@ -255,7 +273,7 @@ var OpenClawAdapter = class extends BaseAdapter {
255
273
  if (server.enabled === false) entry2.enabled = false;
256
274
  return entry2;
257
275
  }
258
- const transport = server.transport === "http" ? "http" : "sse";
276
+ const transport = server.transport === "http" ? "streamable-http" : "sse";
259
277
  const entry = {
260
278
  url: resolveEnvRefsDeep(server.url ?? ""),
261
279
  transport
@@ -340,17 +358,69 @@ var OpenClawAdapter = class extends BaseAdapter {
340
358
  // ── Hook install / uninstall (ts-plugin + DUAL REGISTRATION) ────────────
341
359
  installHooks(ctx) {
342
360
  const pluginPath = this.getHookConfigPath(ctx);
343
- const configPath = this.getServerConfigPath(ctx);
344
- if (ctx.connector.platforms[this.id]?.hooks === false) {
361
+ const canonicalDisabled = ctx.connector.platforms[this.id]?.hooks === false;
362
+ const hasCanonical = !canonicalDisabled && ctx.connector.hookEvents.length > 0;
363
+ const hasNative = this.nativeHookEvents(ctx).length > 0;
364
+ if (!hasCanonical && !hasNative) {
365
+ return [
366
+ {
367
+ platform: this.id,
368
+ action: "skip",
369
+ path: pluginPath,
370
+ detail: canonicalDisabled ? `hooks disabled for ${this.id}` : this.actionTriggers(ctx).length > 0 ? "no hooks (plugin written for actions)" : "connector declares no hooks"
371
+ }
372
+ ];
373
+ }
374
+ return this.ensurePlugin(ctx, `openclaw plugin module (${this.hookDetail(ctx)})`);
375
+ }
376
+ // ── Action install / uninstall (slash commands in the shared plugin) ────
377
+ /**
378
+ * Each declared action becomes an `api.registerCommand(...)` inside the SAME
379
+ * synthesized plugin module (see buildPluginSource). So installActions ensures
380
+ * that shared module is on disk AND dual-registered: when hooks already wrote
381
+ * the identical bytes the content-compare yields "skip" (no double material
382
+ * write), and an actions-only connector gets the plugin written + registered
383
+ * here. Honors platforms.<id>.actions === false and the empty-actions skip.
384
+ */
385
+ installActions(ctx) {
386
+ const pluginPath = this.getHookConfigPath(ctx);
387
+ if (ctx.connector.platforms[this.id]?.actions === false) {
345
388
  return [
346
- { platform: this.id, action: "skip", path: pluginPath, detail: `hooks disabled for ${this.id}` }
389
+ { platform: this.id, action: "skip", path: pluginPath, detail: `actions disabled for ${this.id}` }
347
390
  ];
348
391
  }
349
- if (ctx.connector.hookEvents.length === 0) {
392
+ if (this.actionTriggers(ctx).length === 0) {
350
393
  return [
351
- { platform: this.id, action: "skip", path: pluginPath, detail: "connector declares no hooks" }
394
+ { platform: this.id, action: "skip", path: pluginPath, detail: "connector declares no actions" }
352
395
  ];
353
396
  }
397
+ return this.ensurePlugin(ctx, "openclaw plugin module (action commands)");
398
+ }
399
+ /**
400
+ * Actions live INSIDE the shared plugin module, which uninstallHooks removes
401
+ * (file + manifest + dual-registration entry) unconditionally — it runs last
402
+ * in the teardown pass. Removing the plugin here too would race uninstallHooks,
403
+ * so this is a single informational skip.
404
+ */
405
+ uninstallActions(ctx) {
406
+ return [
407
+ {
408
+ platform: this.id,
409
+ action: "skip",
410
+ path: this.getHookConfigPath(ctx),
411
+ detail: "action commands are embedded in the plugin module; removed by uninstallHooks"
412
+ }
413
+ ];
414
+ }
415
+ /**
416
+ * Synthesize + content-compare-write the plugin module(s) AND upsert the dual-
417
+ * registration entry. Shared by installHooks and installActions: the generator
418
+ * is a pure function of ctx, so whichever surface runs second sees byte-
419
+ * identical files (and an already-present entry) and reports "skip" — no double
420
+ * material write. `moduleDetail` flavors the module ChangeRecord per surface.
421
+ */
422
+ ensurePlugin(ctx, moduleDetail) {
423
+ const configPath = this.getServerConfigPath(ctx);
354
424
  const changes = [];
355
425
  for (const file of this.synthesizePlugin(ctx)) {
356
426
  const before = existsSync(file.path) ? this.safeRead(file.path) : void 0;
@@ -367,7 +437,7 @@ var OpenClawAdapter = class extends BaseAdapter {
367
437
  platform: this.id,
368
438
  action,
369
439
  path: file.path,
370
- detail: `openclaw plugin module (${this.hookDetail(ctx)})`
440
+ detail: moduleDetail
371
441
  });
372
442
  }
373
443
  changes.push(this.upsertPluginEntry(configPath, ctx, this.pluginDir(ctx)));
@@ -380,12 +450,25 @@ var OpenClawAdapter = class extends BaseAdapter {
380
450
  * as "unsupported here" so the detail never overstates coverage.
381
451
  */
382
452
  hookDetail(ctx) {
383
- const declared = ctx.connector.hookEvents;
453
+ const declared = ctx.connector.platforms[this.id]?.hooks === false ? [] : ctx.connector.hookEvents;
384
454
  const mapped = declared.filter((e) => EVENT_TO_OPENCLAW[e] !== void 0);
385
455
  const unsupported = declared.filter((e) => EVENT_TO_OPENCLAW[e] === void 0);
386
- const base = mapped.join(",");
456
+ const native = this.nativeHookEvents(ctx);
457
+ const parts = [];
458
+ if (mapped.length > 0) parts.push(mapped.join(","));
459
+ if (native.length > 0) parts.push(`native: ${native.join(",")}`);
460
+ const base = parts.join("; ") || "no canonical hooks";
387
461
  return unsupported.length > 0 ? `${base}; unsupported here: ${unsupported.join(",")}` : base;
388
462
  }
463
+ /**
464
+ * OpenClaw-native passthrough events declared on platforms.<id>.nativeHooks
465
+ * (host lifecycle hook names with no canonical HookEventName). Emitted as
466
+ * generic on(...) bridge registrations and dispatched host-generically by the
467
+ * home-bin's runNativeHook. Independent of hooks:false (supportsNativeHooks).
468
+ */
469
+ nativeHookEvents(ctx) {
470
+ return Object.keys(ctx.connector.platforms[this.id]?.nativeHooks ?? {});
471
+ }
389
472
  uninstallHooks(ctx) {
390
473
  const pluginPath = this.getHookConfigPath(ctx);
391
474
  const configPath = this.getServerConfigPath(ctx);
@@ -652,7 +735,8 @@ var OpenClawAdapter = class extends BaseAdapter {
652
735
  const homeBin = JSON.stringify(ctx.homeBinPath);
653
736
  const connectorId = JSON.stringify(ctx.connector.id);
654
737
  const connectorName = JSON.stringify(ctx.connector.displayName || ctx.connector.id);
655
- const events = ctx.connector.hookEvents.filter(
738
+ const canonicalOff = ctx.connector.platforms[this.id]?.hooks === false;
739
+ const events = canonicalOff ? [] : ctx.connector.hookEvents.filter(
656
740
  (e) => EVENT_TO_OPENCLAW[e] !== void 0
657
741
  );
658
742
  const has = (e) => events.includes(e);
@@ -667,7 +751,7 @@ var OpenClawAdapter = class extends BaseAdapter {
667
751
  */
668
752
  import { execFileSync, execSync } from "node:child_process";
669
753
 
670
- const HOME_BIN = ` + homeBin + ";\nconst CONNECTOR_ID = " + connectorId + ';\n\n/**\n * Invoke the universal hook entrypoint for one canonical event.\n * @param {string} event canonical event name\n * (PreToolUse|PostToolUse|SessionStart|SubagentStart|SubagentStop)\n * @param {object} payload OpenClaw-shaped payload posted on stdin\n * @returns {object|null} normalized HookResponse, or null on any failure\n */\nfunction bridge(event, payload) {\n try {\n // On Windows HOME_BIN is the agent-connector.cmd launcher: Node cannot\n // execFile a batch file, and shell+args is deprecated (DEP0190), so run\n // one quoted command line via a shell. POSIX keeps the direct execFile.\n const args = ["hook", ' + JSON.stringify(this.id) + `, event, "--connector", CONNECTOR_ID];
754
+ const HOME_BIN = ` + homeBin + ";\nconst CONNECTOR_ID = " + connectorId + ';\n\n/**\n * Invoke the universal hook entrypoint for one canonical event.\n * @param {string} event canonical (or native passthrough) event name\n * (PreToolUse|PostToolUse|SessionStart|UserPromptSubmit|SubagentStart|SubagentStop)\n * @param {object} payload OpenClaw-shaped payload posted on stdin\n * @returns {object|null} normalized HookResponse, or null on any failure\n */\nfunction bridge(event, payload) {\n try {\n // On Windows HOME_BIN is the agent-connector.cmd launcher: Node cannot\n // execFile a batch file, and shell+args is deprecated (DEP0190), so run\n // one quoted command line via a shell. POSIX keeps the direct execFile.\n const args = ["hook", ' + JSON.stringify(this.id) + `, event, "--connector", CONNECTOR_ID];
671
755
  const opts = { input: JSON.stringify(payload), encoding: "utf8" };
672
756
  const stdout =
673
757
  process.platform === "win32"
@@ -734,7 +818,39 @@ let contextInjected = false;
734
818
  }
735
819
  if (has("SessionStart")) {
736
820
  reg.push(
737
- '\n // SessionStart \u2192 session_start records the real session id and fetches\n // the additionalContext to inject; before_prompt_build performs the\n // injection (the verified context-injection point upstream).\n on("session_start", async (event) => {\n const e = event || {};\n SESSION_ID = e.sessionId || e.sessionKey || SESSION_ID;\n const res = bridge("SessionStart", {\n sessionId: SESSION_ID,\n source: e.resumedFrom ? "resume" : "startup",\n projectDir: PROJECT_DIR,\n });\n contextInjected = false;\n pendingContext =\n res && typeof res.additionalContext === "string" && res.additionalContext\n ? res.additionalContext\n : null;\n return undefined;\n });\n\n // Inject the session-start context once, at prompt-build time.\n on("before_prompt_build", () => {\n if (contextInjected || !pendingContext) return undefined;\n contextInjected = true;\n return { appendSystemContext: pendingContext };\n });\n'
821
+ '\n // SessionStart \u2192 session_start records the real session id and fetches\n // the additionalContext to inject; before_prompt_build performs the\n // injection (the verified context-injection point upstream).\n on("session_start", async (event) => {\n const e = event || {};\n SESSION_ID = e.sessionId || e.sessionKey || SESSION_ID;\n const res = bridge("SessionStart", {\n sessionId: SESSION_ID,\n source: e.resumedFrom ? "resume" : "startup",\n projectDir: PROJECT_DIR,\n });\n contextInjected = false;\n pendingContext =\n res && typeof res.additionalContext === "string" && res.additionalContext\n ? res.additionalContext\n : null;\n return undefined;\n });\n'
822
+ );
823
+ }
824
+ if (has("SessionStart") || has("UserPromptSubmit")) {
825
+ let body = "";
826
+ if (has("SessionStart")) {
827
+ body += " // SessionStart: inject the session-start context exactly once.\n if (!contextInjected && pendingContext) {\n contextInjected = true;\n out.appendSystemContext = pendingContext;\n }\n";
828
+ }
829
+ if (has("UserPromptSubmit")) {
830
+ body += ' // UserPromptSubmit: per-turn context injection. before_prompt_build\n // cannot block, so a deny/block decision degrades to a no-op.\n const e = event || {};\n const ures = bridge("UserPromptSubmit", {\n prompt: typeof e.prompt === "string" ? e.prompt : "",\n sessionId: SESSION_ID,\n projectDir: PROJECT_DIR,\n });\n if (ures && typeof ures.additionalContext === "string" && ures.additionalContext) {\n out.appendContext = ures.additionalContext;\n }\n';
831
+ }
832
+ reg.push(
833
+ '\n // before_prompt_build \u2192 coexisting SessionStart (once) + UserPromptSubmit\n // (per-turn) context injection. Context-only: it cannot block a prompt.\n on("before_prompt_build", (event) => {\n const out = {};\n' + body + " return Object.keys(out).length > 0 ? out : undefined;\n });\n"
834
+ );
835
+ }
836
+ for (const ev of this.nativeHookEvents(ctx)) {
837
+ const key = JSON.stringify(ev);
838
+ reg.push(
839
+ "\n // nativeHooks passthrough \u2192 " + ev + "\n on(" + key + ", (event) => {\n bridge(" + key + ", { sessionId: SESSION_ID, projectDir: PROJECT_DIR, raw: event });\n return undefined;\n });\n"
840
+ );
841
+ }
842
+ for (const action of this.actionTriggers(ctx)) {
843
+ const id = JSON.stringify(action.id);
844
+ const description = JSON.stringify(action.description);
845
+ reg.push(
846
+ "\n // Action /" + action.id + " -> run the home-bin action verb directly.\n api.registerCommand({\n name: " + id + ",\n description: " + description + ',\n handler: async (_ctx) => {\n try {\n const args = ["action", ' + JSON.stringify(this.id) + ", " + id + `, "--connector", CONNECTOR_ID];
847
+ const out =
848
+ process.platform === "win32"
849
+ ? execSync([HOME_BIN, ...args].map((a) => '"' + a + '"').join(" "), { encoding: "utf8" })
850
+ : execFileSync(HOME_BIN, args, { encoding: "utf8" });
851
+ return { text: (out || "").trim() };
852
+ } catch (e) {
853
+ return { text: "action " + ` + id + ' + " failed: " + (e && e.message ? e.message : "error") };\n }\n },\n });\n'
738
854
  );
739
855
  }
740
856
  reg.push(" },\n");
@@ -780,6 +896,13 @@ let contextInjected = false;
780
896
  const ev = { ...base, source };
781
897
  return ev;
782
898
  }
899
+ case "UserPromptSubmit": {
900
+ const ev = {
901
+ ...base,
902
+ prompt: typeof input.prompt === "string" ? input.prompt : ""
903
+ };
904
+ return ev;
905
+ }
783
906
  case "SubagentStart": {
784
907
  const ev = {
785
908
  ...base,
@@ -820,7 +943,7 @@ let contextInjected = false;
820
943
  const pluginPath = this.getHookConfigPath(ctx);
821
944
  const pluginDir = this.pluginDir(ctx);
822
945
  const id = ctx.connector.id;
823
- const hasHooks = ctx.connector.hookEvents.length > 0;
946
+ const hasHooks = ctx.connector.hookEvents.length > 0 || this.nativeHookEvents(ctx).length > 0 || this.actionTriggers(ctx).length > 0;
824
947
  const hasServer = Boolean(ctx.connector.server);
825
948
  return [
826
949
  {
@@ -937,4 +1060,4 @@ export {
937
1060
  adapter,
938
1061
  openclaw_default
939
1062
  };
940
- //# sourceMappingURL=chunk-KGGBNKI4.js.map
1063
+ //# sourceMappingURL=chunk-RQPKL62M.js.map