@0xmaxma/claude-gateway 1.7.9 → 1.8.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 (258) hide show
  1. package/README.md +178 -44
  2. package/dist/agent/builtin-commands.js +2 -2
  3. package/dist/agent/builtin-commands.js.map +1 -1
  4. package/dist/agent/dreaming/accept.d.ts.map +1 -1
  5. package/dist/agent/dreaming/accept.js +4 -1
  6. package/dist/agent/dreaming/accept.js.map +1 -1
  7. package/dist/agent/dreaming/config.d.ts.map +1 -1
  8. package/dist/agent/dreaming/config.js +2 -0
  9. package/dist/agent/dreaming/config.js.map +1 -1
  10. package/dist/agent/dreaming/reviewer.d.ts.map +1 -1
  11. package/dist/agent/dreaming/reviewer.js +9 -2
  12. package/dist/agent/dreaming/reviewer.js.map +1 -1
  13. package/dist/agent/dreaming/staleness.d.ts +7 -1
  14. package/dist/agent/dreaming/staleness.d.ts.map +1 -1
  15. package/dist/agent/dreaming/staleness.js +17 -2
  16. package/dist/agent/dreaming/staleness.js.map +1 -1
  17. package/dist/agent/dreaming/types.d.ts +17 -1
  18. package/dist/agent/dreaming/types.d.ts.map +1 -1
  19. package/dist/agent/knowledge/archive-db.d.ts +43 -0
  20. package/dist/agent/knowledge/archive-db.d.ts.map +1 -1
  21. package/dist/agent/knowledge/archive-db.js +130 -0
  22. package/dist/agent/knowledge/archive-db.js.map +1 -1
  23. package/dist/agent/knowledge/config.d.ts +3 -1
  24. package/dist/agent/knowledge/config.d.ts.map +1 -1
  25. package/dist/agent/knowledge/config.js +32 -10
  26. package/dist/agent/knowledge/config.js.map +1 -1
  27. package/dist/agent/knowledge/index.d.ts +11 -4
  28. package/dist/agent/knowledge/index.d.ts.map +1 -1
  29. package/dist/agent/knowledge/index.js +22 -1
  30. package/dist/agent/knowledge/index.js.map +1 -1
  31. package/dist/agent/knowledge/indexer.d.ts +0 -7
  32. package/dist/agent/knowledge/indexer.d.ts.map +1 -1
  33. package/dist/agent/knowledge/indexer.js +34 -7
  34. package/dist/agent/knowledge/indexer.js.map +1 -1
  35. package/dist/agent/knowledge/lifecycle.d.ts +20 -4
  36. package/dist/agent/knowledge/lifecycle.d.ts.map +1 -1
  37. package/dist/agent/knowledge/lifecycle.js +33 -4
  38. package/dist/agent/knowledge/lifecycle.js.map +1 -1
  39. package/dist/agent/knowledge/reflection.d.ts +114 -0
  40. package/dist/agent/knowledge/reflection.d.ts.map +1 -0
  41. package/dist/agent/knowledge/reflection.js +447 -0
  42. package/dist/agent/knowledge/reflection.js.map +1 -0
  43. package/dist/agent/knowledge/shared-dedup.d.ts +85 -0
  44. package/dist/agent/knowledge/shared-dedup.d.ts.map +1 -0
  45. package/dist/agent/knowledge/shared-dedup.js +187 -0
  46. package/dist/agent/knowledge/shared-dedup.js.map +1 -0
  47. package/dist/agent/knowledge/shared-promote.d.ts +82 -7
  48. package/dist/agent/knowledge/shared-promote.d.ts.map +1 -1
  49. package/dist/agent/knowledge/shared-promote.js +244 -11
  50. package/dist/agent/knowledge/shared-promote.js.map +1 -1
  51. package/dist/agent/knowledge/shared-staleness.d.ts +51 -0
  52. package/dist/agent/knowledge/shared-staleness.d.ts.map +1 -0
  53. package/dist/agent/knowledge/shared-staleness.js +149 -0
  54. package/dist/agent/knowledge/shared-staleness.js.map +1 -0
  55. package/dist/agent/knowledge/shared-writer.d.ts +19 -0
  56. package/dist/agent/knowledge/shared-writer.d.ts.map +1 -1
  57. package/dist/agent/knowledge/shared-writer.js +42 -0
  58. package/dist/agent/knowledge/shared-writer.js.map +1 -1
  59. package/dist/agent/knowledge/types.d.ts +24 -0
  60. package/dist/agent/knowledge/types.d.ts.map +1 -1
  61. package/dist/agent/model-catalog.d.ts +62 -0
  62. package/dist/agent/model-catalog.d.ts.map +1 -0
  63. package/dist/agent/model-catalog.js +264 -0
  64. package/dist/agent/model-catalog.js.map +1 -0
  65. package/dist/agent/runner.d.ts +83 -0
  66. package/dist/agent/runner.d.ts.map +1 -1
  67. package/dist/agent/runner.js +281 -51
  68. package/dist/agent/runner.js.map +1 -1
  69. package/dist/agent/workspace-loader.d.ts +17 -2
  70. package/dist/agent/workspace-loader.d.ts.map +1 -1
  71. package/dist/agent/workspace-loader.js +17 -1
  72. package/dist/agent/workspace-loader.js.map +1 -1
  73. package/dist/api/cron-router.d.ts +12 -8
  74. package/dist/api/cron-router.d.ts.map +1 -1
  75. package/dist/api/cron-router.js +82 -16
  76. package/dist/api/cron-router.js.map +1 -1
  77. package/dist/api/gateway-router.d.ts +4 -0
  78. package/dist/api/gateway-router.d.ts.map +1 -1
  79. package/dist/api/gateway-router.js +16 -1
  80. package/dist/api/gateway-router.js.map +1 -1
  81. package/dist/api/manifest-sources.d.ts +15 -0
  82. package/dist/api/manifest-sources.d.ts.map +1 -0
  83. package/dist/api/manifest-sources.js +27 -0
  84. package/dist/api/manifest-sources.js.map +1 -0
  85. package/dist/api/meta-router.d.ts +13 -0
  86. package/dist/api/meta-router.d.ts.map +1 -0
  87. package/dist/api/meta-router.js +26 -0
  88. package/dist/api/meta-router.js.map +1 -0
  89. package/dist/api/packages.d.ts.map +1 -1
  90. package/dist/api/packages.js +18 -198
  91. package/dist/api/packages.js.map +1 -1
  92. package/dist/api/route-registry.d.ts +81 -0
  93. package/dist/api/route-registry.d.ts.map +1 -0
  94. package/dist/api/route-registry.js +44 -0
  95. package/dist/api/route-registry.js.map +1 -0
  96. package/dist/api/router.d.ts.map +1 -1
  97. package/dist/api/router.js +21 -3
  98. package/dist/api/router.js.map +1 -1
  99. package/dist/apps/compose-generator.js +7 -4
  100. package/dist/apps/compose-generator.js.map +1 -1
  101. package/dist/apps/installer.d.ts +154 -0
  102. package/dist/apps/installer.d.ts.map +1 -1
  103. package/dist/apps/installer.js +657 -54
  104. package/dist/apps/installer.js.map +1 -1
  105. package/dist/cli/args.d.ts +25 -0
  106. package/dist/cli/args.d.ts.map +1 -0
  107. package/dist/cli/args.js +55 -0
  108. package/dist/cli/args.js.map +1 -0
  109. package/dist/cli/colors.d.ts +37 -0
  110. package/dist/cli/colors.d.ts.map +1 -0
  111. package/dist/cli/colors.js +63 -0
  112. package/dist/cli/colors.js.map +1 -0
  113. package/dist/cli/command-names.d.ts +98 -0
  114. package/dist/cli/command-names.d.ts.map +1 -0
  115. package/dist/cli/command-names.js +109 -0
  116. package/dist/cli/command-names.js.map +1 -0
  117. package/dist/cli/commands/agents.d.ts +28 -0
  118. package/dist/cli/commands/agents.d.ts.map +1 -0
  119. package/dist/cli/commands/agents.js +321 -0
  120. package/dist/cli/commands/agents.js.map +1 -0
  121. package/dist/cli/commands/channels.d.ts +17 -0
  122. package/dist/cli/commands/channels.d.ts.map +1 -0
  123. package/dist/cli/commands/channels.js +101 -0
  124. package/dist/cli/commands/channels.js.map +1 -0
  125. package/dist/cli/commands/debug-bundle.d.ts +6 -0
  126. package/dist/cli/commands/debug-bundle.d.ts.map +1 -0
  127. package/dist/cli/commands/debug-bundle.js +220 -0
  128. package/dist/cli/commands/debug-bundle.js.map +1 -0
  129. package/dist/cli/commands/doctor.d.ts +3 -0
  130. package/dist/cli/commands/doctor.d.ts.map +1 -0
  131. package/dist/cli/commands/doctor.js +104 -0
  132. package/dist/cli/commands/doctor.js.map +1 -0
  133. package/dist/cli/commands/gateway.d.ts +12 -0
  134. package/dist/cli/commands/gateway.d.ts.map +1 -0
  135. package/dist/cli/commands/gateway.js +145 -0
  136. package/dist/cli/commands/gateway.js.map +1 -0
  137. package/dist/cli/commands/service.d.ts +33 -0
  138. package/dist/cli/commands/service.d.ts.map +1 -0
  139. package/dist/cli/commands/service.js +513 -0
  140. package/dist/cli/commands/service.js.map +1 -0
  141. package/dist/cli/commands/update.d.ts +16 -0
  142. package/dist/cli/commands/update.d.ts.map +1 -0
  143. package/dist/cli/commands/update.js +149 -0
  144. package/dist/cli/commands/update.js.map +1 -0
  145. package/dist/cli/commands.generated.d.ts +4 -0
  146. package/dist/cli/commands.generated.d.ts.map +1 -0
  147. package/dist/cli/commands.generated.js +220 -0
  148. package/dist/cli/commands.generated.js.map +1 -0
  149. package/dist/cli/health.d.ts +31 -0
  150. package/dist/cli/health.d.ts.map +1 -0
  151. package/dist/cli/health.js +49 -0
  152. package/dist/cli/health.js.map +1 -0
  153. package/dist/cli/http-client.d.ts +140 -0
  154. package/dist/cli/http-client.d.ts.map +1 -0
  155. package/dist/cli/http-client.js +332 -0
  156. package/dist/cli/http-client.js.map +1 -0
  157. package/dist/cli/index.d.ts +27 -0
  158. package/dist/cli/index.d.ts.map +1 -0
  159. package/dist/cli/index.js +372 -0
  160. package/dist/cli/index.js.map +1 -0
  161. package/dist/cli/manager.d.ts +64 -0
  162. package/dist/cli/manager.d.ts.map +1 -0
  163. package/dist/cli/manager.js +181 -0
  164. package/dist/cli/manager.js.map +1 -0
  165. package/dist/cli/output.d.ts +49 -0
  166. package/dist/cli/output.d.ts.map +1 -0
  167. package/dist/cli/output.js +101 -0
  168. package/dist/cli/output.js.map +1 -0
  169. package/dist/cli/prompt.d.ts +29 -0
  170. package/dist/cli/prompt.d.ts.map +1 -0
  171. package/dist/cli/prompt.js +154 -0
  172. package/dist/cli/prompt.js.map +1 -0
  173. package/dist/cli/redact.d.ts +3 -0
  174. package/dist/cli/redact.d.ts.map +1 -0
  175. package/dist/cli/redact.js +33 -0
  176. package/dist/cli/redact.js.map +1 -0
  177. package/dist/cli/types.d.ts +22 -0
  178. package/dist/cli/types.d.ts.map +1 -0
  179. package/dist/cli/types.js +4 -0
  180. package/dist/cli/types.js.map +1 -0
  181. package/dist/config/bootstrap.d.ts +33 -0
  182. package/dist/config/bootstrap.d.ts.map +1 -0
  183. package/dist/config/bootstrap.js +117 -0
  184. package/dist/config/bootstrap.js.map +1 -0
  185. package/dist/config/loader.d.ts.map +1 -1
  186. package/dist/config/loader.js +5 -1
  187. package/dist/config/loader.js.map +1 -1
  188. package/dist/config/watcher.d.ts.map +1 -1
  189. package/dist/config/watcher.js +2 -35
  190. package/dist/config/watcher.js.map +1 -1
  191. package/dist/discord/receiver.d.ts +6 -1
  192. package/dist/discord/receiver.d.ts.map +1 -1
  193. package/dist/discord/receiver.js +9 -1
  194. package/dist/discord/receiver.js.map +1 -1
  195. package/dist/entry.d.ts +3 -0
  196. package/dist/entry.d.ts.map +1 -0
  197. package/dist/entry.js +83 -0
  198. package/dist/entry.js.map +1 -0
  199. package/dist/index.js +197 -47
  200. package/dist/index.js.map +1 -1
  201. package/dist/load-dotenv.d.ts +2 -0
  202. package/dist/load-dotenv.d.ts.map +1 -0
  203. package/dist/load-dotenv.js +68 -0
  204. package/dist/load-dotenv.js.map +1 -0
  205. package/dist/packages/registry.d.ts +50 -0
  206. package/dist/packages/registry.d.ts.map +1 -0
  207. package/dist/packages/registry.js +209 -0
  208. package/dist/packages/registry.js.map +1 -0
  209. package/dist/session/process.d.ts +20 -3
  210. package/dist/session/process.d.ts.map +1 -1
  211. package/dist/session/process.js +120 -5
  212. package/dist/session/process.js.map +1 -1
  213. package/dist/shell/claude-pty-shell.js +146 -27
  214. package/dist/shell/claude-pty-shell.js.map +1 -1
  215. package/dist/shell/draft-phantom.d.ts +49 -0
  216. package/dist/shell/draft-phantom.d.ts.map +1 -0
  217. package/dist/shell/draft-phantom.js +59 -0
  218. package/dist/shell/draft-phantom.js.map +1 -0
  219. package/dist/shell/submit-diag.d.ts +67 -0
  220. package/dist/shell/submit-diag.d.ts.map +1 -0
  221. package/dist/shell/submit-diag.js +69 -0
  222. package/dist/shell/submit-diag.js.map +1 -0
  223. package/dist/shutdown-signals.d.ts +47 -0
  224. package/dist/shutdown-signals.d.ts.map +1 -0
  225. package/dist/shutdown-signals.js +62 -0
  226. package/dist/shutdown-signals.js.map +1 -0
  227. package/dist/telegram/receiver.d.ts +6 -1
  228. package/dist/telegram/receiver.d.ts.map +1 -1
  229. package/dist/telegram/receiver.js +9 -1
  230. package/dist/telegram/receiver.js.map +1 -1
  231. package/dist/types.d.ts +25 -0
  232. package/dist/types.d.ts.map +1 -1
  233. package/dist/utils/orphan-receivers.d.ts +90 -0
  234. package/dist/utils/orphan-receivers.d.ts.map +1 -0
  235. package/dist/utils/orphan-receivers.js +218 -0
  236. package/dist/utils/orphan-receivers.js.map +1 -0
  237. package/dist/utils/paths.d.ts +16 -0
  238. package/dist/utils/paths.d.ts.map +1 -0
  239. package/dist/utils/paths.js +60 -0
  240. package/dist/utils/paths.js.map +1 -0
  241. package/dist/utils/stop-child.d.ts +21 -0
  242. package/dist/utils/stop-child.d.ts.map +1 -0
  243. package/dist/utils/stop-child.js +64 -0
  244. package/dist/utils/stop-child.js.map +1 -0
  245. package/lib/pairing.ts +1 -1
  246. package/mcp/tools/agent/handlers.ts +1 -1
  247. package/mcp/tools/discord/module.ts +23 -15
  248. package/mcp/tools/discord/receiver-server.ts +4 -0
  249. package/mcp/tools/memory/archive-reader.test.ts +25 -1
  250. package/mcp/tools/memory/archive-reader.ts +70 -12
  251. package/mcp/tools/memory/archive-writer.test.ts +168 -0
  252. package/mcp/tools/memory/archive-writer.ts +137 -0
  253. package/mcp/tools/memory/module.test.ts +187 -0
  254. package/mcp/tools/memory/module.ts +192 -6
  255. package/mcp/tools/telegram/module.ts +10 -2
  256. package/mcp/tools/telegram/receiver-server.ts +15 -6
  257. package/mcp/tools/telegram/typing.ts +178 -34
  258. package/package.json +6 -4
@@ -0,0 +1,49 @@
1
+ /**
2
+ * stdout is the CLI's result channel and carries JSON only — help, prompts,
3
+ * progress and errors all go to stderr, so a caller can pipe stdout straight
4
+ * into `jq` from any command.
5
+ *
6
+ * `compact` (the global `--json` flag) prints one minified line for scripts;
7
+ * the default is pretty-printed for humans. Either way the output is valid
8
+ * JSON. Shared so every command formats its result identically.
9
+ */
10
+ export declare function printResult(data: unknown, compact: boolean): void;
11
+ /** `printResult` driven straight from a parsed flag bag. */
12
+ export declare function printJson(data: unknown, flags: Record<string, string | boolean>): void;
13
+ /**
14
+ * Wait for stdout/stderr to reach the OS, then exit with `code`.
15
+ *
16
+ * When stdout is a pipe Node's writes are asynchronous, so `process.exit()`
17
+ * discards whatever is still buffered — a large `--json` payload piped into
18
+ * `jq` arrives truncated at the pipe buffer (64 KiB on Linux) and the pipeline
19
+ * fails on invalid JSON. Draining first is what makes `printResult` safe to
20
+ * pipe from any command.
21
+ *
22
+ * `process.exitCode` alone is not enough: a stray handle (an interval, a
23
+ * lingering socket) would keep the CLI alive after its output is done, so the
24
+ * exit is still explicit. `timeoutMs` bounds the wait — a reader that goes
25
+ * away mid-write must not hang the CLI.
26
+ */
27
+ export declare function exitAfterFlush(code: number, timeoutMs?: number): Promise<never>;
28
+ /**
29
+ * Where a help listing goes.
30
+ *
31
+ * An explicitly requested `--help` exits 0: it *is* the command's result, so it
32
+ * belongs on stdout, where it can be paged, grepped or redirected like any
33
+ * other output. The same listing printed because the invocation was wrong is
34
+ * diagnostic and stays on stderr, so stdout still carries results only. Both
35
+ * cases previously went to stderr, which left `claude-gateway --help | less`
36
+ * showing an empty screen.
37
+ */
38
+ export declare function helpStream(requested: boolean): NodeJS.WriteStream;
39
+ /**
40
+ * The shared shape of a command's help: a bold `claude-gateway <command>`
41
+ * banner naming what it does, then its usage line, then anything specific.
42
+ *
43
+ * Every command renders through this so the surface reads as one program —
44
+ * `doctor` and `agents` grew a banner while `gateway` and `update` printed a
45
+ * bare `Usage:` line, which is the kind of drift a shared renderer prevents.
46
+ * The brand tone stays reserved for the general help banner.
47
+ */
48
+ export declare function writeCommandHelp(requested: boolean, command: string, summary: string, usage: string, extra?: string[]): void;
49
+ //# sourceMappingURL=output.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.d.ts","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,wBAAgB,WAAW,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAMjE;AAED,4DAA4D;AAC5D,wBAAgB,SAAS,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,IAAI,CAEtF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAuBnF;AAED;;;;;;;;;GASG;AACH,wBAAgB,UAAU,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,CAAC,WAAW,CAEjE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,OAAO,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,KAAK,GAAE,MAAM,EAAO,GACnB,IAAI,CAUN"}
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ /**
3
+ * stdout is the CLI's result channel and carries JSON only — help, prompts,
4
+ * progress and errors all go to stderr, so a caller can pipe stdout straight
5
+ * into `jq` from any command.
6
+ *
7
+ * `compact` (the global `--json` flag) prints one minified line for scripts;
8
+ * the default is pretty-printed for humans. Either way the output is valid
9
+ * JSON. Shared so every command formats its result identically.
10
+ */
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.printResult = printResult;
13
+ exports.printJson = printJson;
14
+ exports.exitAfterFlush = exitAfterFlush;
15
+ exports.helpStream = helpStream;
16
+ exports.writeCommandHelp = writeCommandHelp;
17
+ const colors_1 = require("./colors");
18
+ function printResult(data, compact) {
19
+ if (typeof data === 'string') {
20
+ process.stdout.write(data + '\n');
21
+ return;
22
+ }
23
+ process.stdout.write((compact ? JSON.stringify(data) : JSON.stringify(data, null, 2)) + '\n');
24
+ }
25
+ /** `printResult` driven straight from a parsed flag bag. */
26
+ function printJson(data, flags) {
27
+ printResult(data, flags.json === true);
28
+ }
29
+ /**
30
+ * Wait for stdout/stderr to reach the OS, then exit with `code`.
31
+ *
32
+ * When stdout is a pipe Node's writes are asynchronous, so `process.exit()`
33
+ * discards whatever is still buffered — a large `--json` payload piped into
34
+ * `jq` arrives truncated at the pipe buffer (64 KiB on Linux) and the pipeline
35
+ * fails on invalid JSON. Draining first is what makes `printResult` safe to
36
+ * pipe from any command.
37
+ *
38
+ * `process.exitCode` alone is not enough: a stray handle (an interval, a
39
+ * lingering socket) would keep the CLI alive after its output is done, so the
40
+ * exit is still explicit. `timeoutMs` bounds the wait — a reader that goes
41
+ * away mid-write must not hang the CLI.
42
+ */
43
+ async function exitAfterFlush(code, timeoutMs = 2000) {
44
+ process.exitCode = code;
45
+ const drain = (s) => new Promise((resolve) => {
46
+ if (s.writableLength === 0 || s.destroyed || s.writableEnded) {
47
+ resolve();
48
+ return;
49
+ }
50
+ // An empty write's callback runs after every pending chunk has flushed.
51
+ s.write('', () => resolve());
52
+ s.once('error', () => resolve());
53
+ });
54
+ let timer;
55
+ const deadline = new Promise((resolve) => {
56
+ timer = setTimeout(resolve, timeoutMs);
57
+ timer.unref?.();
58
+ });
59
+ try {
60
+ await Promise.race([Promise.all([drain(process.stdout), drain(process.stderr)]), deadline]);
61
+ }
62
+ finally {
63
+ if (timer)
64
+ clearTimeout(timer);
65
+ }
66
+ process.exit(code);
67
+ }
68
+ /**
69
+ * Where a help listing goes.
70
+ *
71
+ * An explicitly requested `--help` exits 0: it *is* the command's result, so it
72
+ * belongs on stdout, where it can be paged, grepped or redirected like any
73
+ * other output. The same listing printed because the invocation was wrong is
74
+ * diagnostic and stays on stderr, so stdout still carries results only. Both
75
+ * cases previously went to stderr, which left `claude-gateway --help | less`
76
+ * showing an empty screen.
77
+ */
78
+ function helpStream(requested) {
79
+ return requested ? process.stdout : process.stderr;
80
+ }
81
+ /**
82
+ * The shared shape of a command's help: a bold `claude-gateway <command>`
83
+ * banner naming what it does, then its usage line, then anything specific.
84
+ *
85
+ * Every command renders through this so the surface reads as one program —
86
+ * `doctor` and `agents` grew a banner while `gateway` and `update` printed a
87
+ * bare `Usage:` line, which is the kind of drift a shared renderer prevents.
88
+ * The brand tone stays reserved for the general help banner.
89
+ */
90
+ function writeCommandHelp(requested, command, summary, usage, extra = []) {
91
+ const stream = helpStream(requested);
92
+ const c = (0, colors_1.paletteFor)(stream);
93
+ const lines = [
94
+ `${c.bold(`claude-gateway ${command}`)} — ${summary}`,
95
+ '',
96
+ `${c.bold('Usage:')} ${usage}`,
97
+ ...(extra.length ? ['', ...extra] : []),
98
+ ];
99
+ stream.write(lines.join('\n') + '\n');
100
+ }
101
+ //# sourceMappingURL=output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output.js","sourceRoot":"","sources":["../../src/cli/output.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import * as readline from 'readline';
2
+ /**
3
+ * Small interactive-prompt helpers shared by CLI wizards (`agents create`,
4
+ * `agents update`). Deliberately minimal — plain readline, no raw-mode
5
+ * arrow-key UI — so it works over any TTY without extra terminal handling.
6
+ */
7
+ export declare function createRl(): readline.Interface;
8
+ export declare function ask(rl: readline.Interface, question: string): Promise<string>;
9
+ /** Reads lines until a blank line (after at least one non-blank line). */
10
+ export declare function askMultiline(rl: readline.Interface, intro: string): Promise<string>;
11
+ /** `write` defaults to stdout via console.log (the wizards' channel). Commands
12
+ * that reserve stdout for JSON results pass a stderr writer instead. */
13
+ export declare function printFilePreview(filename: string, content: string, write?: (line: string) => void): void;
14
+ /**
15
+ * Open $VISUAL/$EDITOR/vim/vi/nano on a temp copy of `content`; returns the
16
+ * edited text, or null if no editor could be launched.
17
+ *
18
+ * The scratch file lives in a fresh `mkdtemp` directory (mode 0700) rather than
19
+ * at a fixed path under the shared temp directory. A predictable name such as
20
+ * `/tmp/claude-gateway-AGENTS.md` can be pre-created by another local user as a
21
+ * symlink: the write then lands on whatever the link points at, and the
22
+ * read-back feeds that user's content into the file the wizard uploads.
23
+ */
24
+ export declare function editInEditor(content: string, tmpName: string): string | null;
25
+ /** Preview each file and let the user accept / edit / skip it. Required files
26
+ * (not in `optional`) cannot be skipped. Returns the accepted map in the same
27
+ * order as `files`. */
28
+ export declare function previewAndAccept(rl: readline.Interface, files: Map<string, string>, optional: ReadonlySet<string>): Promise<Map<string, string>>;
29
+ //# sourceMappingURL=prompt.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,QAAQ,MAAM,UAAU,CAAC;AAGrC;;;;GAIG;AAEH,wBAAgB,QAAQ,IAAI,QAAQ,CAAC,SAAS,CAE7C;AAED,wBAAgB,GAAG,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAE7E;AAED,0EAA0E;AAC1E,wBAAsB,YAAY,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CASzF;AAID;yEACyE;AACzE,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAkC,GAC1D,IAAI,CAMN;AAED;;;;;;;;;GASG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAsB5E;AAED;;wBAEwB;AACxB,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,QAAQ,CAAC,SAAS,EACtB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,EAC1B,QAAQ,EAAE,WAAW,CAAC,MAAM,CAAC,GAC5B,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAiC9B"}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.createRl = createRl;
37
+ exports.ask = ask;
38
+ exports.askMultiline = askMultiline;
39
+ exports.printFilePreview = printFilePreview;
40
+ exports.editInEditor = editInEditor;
41
+ exports.previewAndAccept = previewAndAccept;
42
+ const fs = __importStar(require("fs"));
43
+ const os = __importStar(require("os"));
44
+ const path = __importStar(require("path"));
45
+ const readline = __importStar(require("readline"));
46
+ const child_process_1 = require("child_process");
47
+ /**
48
+ * Small interactive-prompt helpers shared by CLI wizards (`agents create`,
49
+ * `agents update`). Deliberately minimal — plain readline, no raw-mode
50
+ * arrow-key UI — so it works over any TTY without extra terminal handling.
51
+ */
52
+ function createRl() {
53
+ return readline.createInterface({ input: process.stdin, output: process.stdout, terminal: true });
54
+ }
55
+ function ask(rl, question) {
56
+ return new Promise((resolve) => rl.question(question, (answer) => resolve(answer)));
57
+ }
58
+ /** Reads lines until a blank line (after at least one non-blank line). */
59
+ async function askMultiline(rl, intro) {
60
+ console.log(intro);
61
+ const lines = [];
62
+ while (true) {
63
+ const line = await ask(rl, '');
64
+ if (line.trim() === '' && lines.length > 0)
65
+ break;
66
+ if (line.trim() !== '')
67
+ lines.push(line);
68
+ }
69
+ return lines.join('\n');
70
+ }
71
+ const SEPARATOR_WIDTH = 42;
72
+ /** `write` defaults to stdout via console.log (the wizards' channel). Commands
73
+ * that reserve stdout for JSON results pass a stderr writer instead. */
74
+ function printFilePreview(filename, content, write = (line) => console.log(line)) {
75
+ const label = `─── ${filename} `;
76
+ const padding = Math.max(0, SEPARATOR_WIDTH - label.length);
77
+ write('\n' + label + '─'.repeat(padding));
78
+ write(content);
79
+ write('─'.repeat(SEPARATOR_WIDTH));
80
+ }
81
+ /**
82
+ * Open $VISUAL/$EDITOR/vim/vi/nano on a temp copy of `content`; returns the
83
+ * edited text, or null if no editor could be launched.
84
+ *
85
+ * The scratch file lives in a fresh `mkdtemp` directory (mode 0700) rather than
86
+ * at a fixed path under the shared temp directory. A predictable name such as
87
+ * `/tmp/claude-gateway-AGENTS.md` can be pre-created by another local user as a
88
+ * symlink: the write then lands on whatever the link points at, and the
89
+ * read-back feeds that user's content into the file the wizard uploads.
90
+ */
91
+ function editInEditor(content, tmpName) {
92
+ const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'claude-gateway-'));
93
+ // `basename` so a caller's key can never escape the scratch directory.
94
+ const tmpFile = path.join(dir, path.basename(tmpName) || 'draft');
95
+ const cleanup = () => {
96
+ try {
97
+ fs.rmSync(dir, { recursive: true, force: true });
98
+ }
99
+ catch {
100
+ /* best effort — the directory is per-invocation and 0700 */
101
+ }
102
+ };
103
+ try {
104
+ fs.writeFileSync(tmpFile, content, 'utf8');
105
+ const candidates = [process.env['VISUAL'], process.env['EDITOR'], 'vim', 'vi', 'nano'].filter(Boolean);
106
+ for (const candidate of candidates) {
107
+ const result = (0, child_process_1.spawnSync)(candidate, [tmpFile], { stdio: 'inherit' });
108
+ if (!result.error)
109
+ return fs.readFileSync(tmpFile, 'utf8');
110
+ }
111
+ return null;
112
+ }
113
+ finally {
114
+ cleanup();
115
+ }
116
+ }
117
+ /** Preview each file and let the user accept / edit / skip it. Required files
118
+ * (not in `optional`) cannot be skipped. Returns the accepted map in the same
119
+ * order as `files`. */
120
+ async function previewAndAccept(rl, files, optional) {
121
+ const accepted = new Map();
122
+ for (const [filename, content] of files) {
123
+ printFilePreview(filename, content);
124
+ while (true) {
125
+ const answer = (await ask(rl, 'Accept? (y/edit/skip) [y]: ')).trim().toLowerCase() || 'y';
126
+ if (answer === 'y' || answer === 'yes') {
127
+ accepted.set(filename, content);
128
+ break;
129
+ }
130
+ if (answer === 'edit') {
131
+ const edited = editInEditor(content, filename);
132
+ if (edited === null) {
133
+ console.log(' Could not open an editor (set $EDITOR and try again, or choose y/skip).');
134
+ continue;
135
+ }
136
+ printFilePreview(filename, edited);
137
+ console.log(' (edited, accepted)');
138
+ accepted.set(filename, edited);
139
+ break;
140
+ }
141
+ if (answer === 'skip') {
142
+ if (optional.has(filename)) {
143
+ console.log(` Skipping ${filename}`);
144
+ break;
145
+ }
146
+ console.log(` Cannot skip ${filename} — it is required.`);
147
+ continue;
148
+ }
149
+ console.log(' Please enter y, edit, or skip.');
150
+ }
151
+ }
152
+ return accepted;
153
+ }
154
+ //# sourceMappingURL=prompt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt.js","sourceRoot":"","sources":["../../src/cli/prompt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function redactLine(line: string): string;
2
+ export declare function redactLines(lines: string[]): string[];
3
+ //# sourceMappingURL=redact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/cli/redact.ts"],"names":[],"mappings":"AAoBA,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAI/C;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAErD"}
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.redactLine = redactLine;
4
+ exports.redactLines = redactLines;
5
+ /**
6
+ * Redaction for the debug bundle. A gateway session log can contain arbitrary
7
+ * text; before any of it is put into a shareable bundle, mask the things that
8
+ * must never leave the machine — bearer tokens, API-key/secret assignments, and
9
+ * long opaque token-like strings. submit-diag lines are already redacted at the
10
+ * source (length + hash), so this is defense in depth.
11
+ *
12
+ * Pure and deterministic so it can be unit-tested.
13
+ */
14
+ const RULES = [
15
+ // Authorization: Bearer <token> / "Bearer xxxxx"
16
+ [/\bBearer\s+[A-Za-z0-9._\-]+/gi, 'Bearer «redacted»'],
17
+ // key/token/secret/password : "value" or = value (json/env/prose)
18
+ [/\b(api[_-]?key|apikey|token|secret|password|passwd|authorization)\b(["']?\s*[:=]\s*["']?)([^\s"',}]+)/gi, '$1$2«redacted»'],
19
+ // OpenAI/Anthropic-style keys
20
+ [/\b(sk|pk|ak)-[A-Za-z0-9]{8,}/g, '«redacted-key»'],
21
+ // Long opaque tokens (>=32 chars of key-ish alphabet) not already handled
22
+ [/\b[A-Za-z0-9_\-]{32,}\b/g, '«redacted-token»'],
23
+ ];
24
+ function redactLine(line) {
25
+ let out = line;
26
+ for (const [re, repl] of RULES)
27
+ out = out.replace(re, repl);
28
+ return out;
29
+ }
30
+ function redactLines(lines) {
31
+ return lines.map(redactLine);
32
+ }
33
+ //# sourceMappingURL=redact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/cli/redact.ts"],"names":[],"mappings":";;AAoBA,gCAIC;AAED,kCAEC;AA5BD;;;;;;;;GAQG;AACH,MAAM,KAAK,GAA4B;IACrC,mDAAmD;IACnD,CAAC,+BAA+B,EAAE,mBAAmB,CAAC;IACtD,qEAAqE;IACrE,CAAC,yGAAyG,EAAE,gBAAgB,CAAC;IAC7H,8BAA8B;IAC9B,CAAC,+BAA+B,EAAE,gBAAgB,CAAC;IACnD,0EAA0E;IAC1E,CAAC,0BAA0B,EAAE,kBAAkB,CAAC;CACjD,CAAC;AAEF,SAAgB,UAAU,CAAC,IAAY;IACrC,IAAI,GAAG,GAAG,IAAI,CAAC;IACf,KAAK,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,IAAI,KAAK;QAAE,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IAC5D,OAAO,GAAG,CAAC;AACb,CAAC;AAED,SAAgB,WAAW,CAAC,KAAe;IACzC,OAAO,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,22 @@
1
+ /** Types shared between the CLI runtime and the generated command table. */
2
+ export interface GeneratedFlag {
3
+ name: string;
4
+ in: 'query' | 'body';
5
+ boolean?: boolean;
6
+ required?: boolean;
7
+ description?: string;
8
+ }
9
+ /** One friendly `<noun> <verb>` command, derived from a route's CLI mapping. */
10
+ export interface GeneratedCommand {
11
+ noun: string;
12
+ verb: string;
13
+ method: string;
14
+ /** API path with `:param` placeholders (mounted under /api server-side). */
15
+ path: string;
16
+ /** Positional argument names, in order, filling the path params. */
17
+ args: string[];
18
+ flags: GeneratedFlag[];
19
+ summary: string;
20
+ auth: string;
21
+ }
22
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,GAAG,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,gFAAgF;AAChF,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,aAAa,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;CACd"}
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ /** Types shared between the CLI runtime and the generated command table. */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/cli/types.ts"],"names":[],"mappings":";AAAA,4EAA4E"}
@@ -0,0 +1,33 @@
1
+ export interface BootstrapResult {
2
+ created: boolean;
3
+ /** Present only when `created` is true — the generated admin key is not recoverable afterward. */
4
+ adminKey?: string;
5
+ }
6
+ /**
7
+ * Create config.json from the template with a fresh random admin API key when
8
+ * no config file exists yet (genuine first run). Never touches an existing file.
9
+ *
10
+ * Reuses the same template-cleaning path as migration (`loadCleanTemplate` +
11
+ * `stripIgnoredPaths`) so a fresh install starts on the current `configVersion`
12
+ * with the same defaults migration would otherwise converge it to — the only
13
+ * addition is a real `gateway.api.keys` admin entry, since `_migration.ignorePaths`
14
+ * strips that block out (it normally holds unresolved `${VAR}` placeholders that
15
+ * would leak into the file with no matching env var).
16
+ */
17
+ export declare function ensureConfigExists(configPath: string, templatePath: string): BootstrapResult;
18
+ /**
19
+ * The lines printed once, after a config has been generated on first run.
20
+ *
21
+ * The admin key is deliberately absent. config.json is written 0600 precisely
22
+ * to keep it away from other local users; echoing it to stdout hands it to the
23
+ * journal under a service unit — or to `docker logs` — where it persists with
24
+ * weaker protection than the file it was just written to, and outlives the
25
+ * process that printed it. The last four characters are enough to tell two keys
26
+ * apart when checking which one a client is using, and not enough to
27
+ * authenticate with.
28
+ *
29
+ * Pure, so the "never prints the key" property is testable rather than a
30
+ * property of a console.log nobody exercises.
31
+ */
32
+ export declare function firstRunNotice(configPath: string, adminKey: string): string[];
33
+ //# sourceMappingURL=bootstrap.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.d.ts","sourceRoot":"","sources":["../../src/config/bootstrap.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,kGAAkG;IAClG,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,eAAe,CA2C5F;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,CAQ7E"}
@@ -0,0 +1,117 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.ensureConfigExists = ensureConfigExists;
37
+ exports.firstRunNotice = firstRunNotice;
38
+ const fs = __importStar(require("fs"));
39
+ const path = __importStar(require("path"));
40
+ const crypto_1 = require("crypto");
41
+ const migrator_1 = require("./migrator");
42
+ /**
43
+ * Create config.json from the template with a fresh random admin API key when
44
+ * no config file exists yet (genuine first run). Never touches an existing file.
45
+ *
46
+ * Reuses the same template-cleaning path as migration (`loadCleanTemplate` +
47
+ * `stripIgnoredPaths`) so a fresh install starts on the current `configVersion`
48
+ * with the same defaults migration would otherwise converge it to — the only
49
+ * addition is a real `gateway.api.keys` admin entry, since `_migration.ignorePaths`
50
+ * strips that block out (it normally holds unresolved `${VAR}` placeholders that
51
+ * would leak into the file with no matching env var).
52
+ */
53
+ function ensureConfigExists(configPath, templatePath) {
54
+ if (fs.existsSync(configPath)) {
55
+ return { created: false };
56
+ }
57
+ let config;
58
+ try {
59
+ const { template, ignorePaths } = (0, migrator_1.loadCleanTemplate)(templatePath);
60
+ (0, migrator_1.stripIgnoredPaths)(template, ignorePaths);
61
+ config = template;
62
+ }
63
+ catch {
64
+ config = { gateway: { logDir: '~/.claude-gateway/logs', timezone: 'UTC' } };
65
+ }
66
+ config.agents = [];
67
+ const adminKey = (0, crypto_1.randomBytes)(24).toString('hex');
68
+ const gateway = (config.gateway ?? (config.gateway = {}));
69
+ gateway.api = {
70
+ keys: [
71
+ { key: adminKey, description: 'Admin (auto-generated on first run)', agents: '*', admin: true },
72
+ ],
73
+ };
74
+ fs.mkdirSync(path.dirname(configPath), { recursive: true });
75
+ try {
76
+ // 'wx' fails with EEXIST instead of overwriting if another process won a
77
+ // concurrent first-boot race; mode 0o600 keeps the embedded admin key
78
+ // from being readable by other local users (matches installer.ts's
79
+ // convention for secret-bearing files).
80
+ fs.writeFileSync(configPath, JSON.stringify(config, null, 2) + '\n', {
81
+ encoding: 'utf-8',
82
+ mode: 0o600,
83
+ flag: 'wx',
84
+ });
85
+ }
86
+ catch (err) {
87
+ if (err.code === 'EEXIST') {
88
+ return { created: false };
89
+ }
90
+ throw err;
91
+ }
92
+ return { created: true, adminKey };
93
+ }
94
+ /**
95
+ * The lines printed once, after a config has been generated on first run.
96
+ *
97
+ * The admin key is deliberately absent. config.json is written 0600 precisely
98
+ * to keep it away from other local users; echoing it to stdout hands it to the
99
+ * journal under a service unit — or to `docker logs` — where it persists with
100
+ * weaker protection than the file it was just written to, and outlives the
101
+ * process that printed it. The last four characters are enough to tell two keys
102
+ * apart when checking which one a client is using, and not enough to
103
+ * authenticate with.
104
+ *
105
+ * Pure, so the "never prints the key" property is testable rather than a
106
+ * property of a console.log nobody exercises.
107
+ */
108
+ function firstRunNotice(configPath, adminKey) {
109
+ const tail = adminKey.slice(-4);
110
+ return [
111
+ `[gateway] No config found — created one at ${configPath}`,
112
+ `[gateway] A fresh admin API key was generated (ends …${tail}) and stored there, mode 0600.`,
113
+ `[gateway] The CLI (claude-gateway agents create, etc.) reads it from ${configPath} automatically;`,
114
+ `[gateway] for another machine, copy it out of that file rather than from this log.`,
115
+ ];
116
+ }
117
+ //# sourceMappingURL=bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../../src/config/bootstrap.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsBA,gDA2CC;AAgBD,wCAQC;AAzFD,uCAAyB;AACzB,2CAA6B;AAC7B,mCAAqC;AACrC,yCAAkE;AAQlE;;;;;;;;;;GAUG;AACH,SAAgB,kBAAkB,CAAC,UAAkB,EAAE,YAAoB;IACzE,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9B,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,IAAI,MAA+B,CAAC;IACpC,IAAI,CAAC;QACH,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAA,4BAAiB,EAAC,YAAY,CAAC,CAAC;QAClE,IAAA,4BAAiB,EAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACzC,MAAM,GAAG,QAAQ,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,GAAG,EAAE,OAAO,EAAE,EAAE,MAAM,EAAE,wBAAwB,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC;IAC9E,CAAC;IAED,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;IAEnB,MAAM,QAAQ,GAAG,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;IACjD,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,OAAO,KAAd,MAAM,CAAC,OAAO,GAAK,EAAE,EAA4B,CAAC;IACnE,OAAO,CAAC,GAAG,GAAG;QACZ,IAAI,EAAE;YACJ,EAAE,GAAG,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE,MAAM,EAAE,GAAG,EAAE,KAAK,EAAE,IAAI,EAAE;SAChG;KACF,CAAC;IAEF,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,IAAI,CAAC;QACH,yEAAyE;QACzE,sEAAsE;QACtE,mEAAmE;QACnE,wCAAwC;QACxC,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,EAAE;YACnE,QAAQ,EAAE,OAAO;YACjB,IAAI,EAAE,KAAK;YACX,IAAI,EAAE,IAAI;SACX,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAC5B,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,cAAc,CAAC,UAAkB,EAAE,QAAgB;IACjE,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,OAAO;QACL,8CAA8C,UAAU,EAAE;QAC1D,wDAAwD,IAAI,gCAAgC;QAC5F,wEAAwE,UAAU,iBAAiB;QACnG,oFAAoF;KACrF,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,EAAE,EAAE,MAAM;CAIvB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAuED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CA2I5D"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,EAAE,EAAE,MAAM;CAIvB;AAED,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAuED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,aAAa,CA+I5D"}
@@ -237,7 +237,11 @@ function loadConfig(configPath) {
237
237
  throw err;
238
238
  }
239
239
  }
240
- if (interpolatedAgents.length === 0) {
240
+ // A genuinely empty "agents": [] is a valid bootstrap state (start the gateway,
241
+ // then use `claude-gateway agents create` to add the first one). Only error when
242
+ // agents WERE declared but every single one got filtered out — that's a real
243
+ // misconfiguration (e.g. a missing ${VAR}), not an intentional empty install.
244
+ if (interpolatedAgents.length === 0 && config.agents.length > 0) {
241
245
  const bakPath = configPath + '.bak';
242
246
  const migrationHint = fs.existsSync(bakPath)
243
247
  ? ` A migration backup exists at "${bakPath}" — this may be a migration issue where credential fields were incorrectly injected into your agents. Check the backup and restore if needed.`