vibelet 0.1.35 → 0.1.37

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 (323) hide show
  1. package/app.json +5 -0
  2. package/dist/advertised-hosts.d.ts +34 -0
  3. package/dist/advertised-hosts.d.ts.map +1 -0
  4. package/dist/advertised-hosts.js +176 -0
  5. package/dist/advertised-hosts.js.map +1 -0
  6. package/dist/advertised-hosts.test.d.ts +2 -0
  7. package/dist/advertised-hosts.test.d.ts.map +1 -0
  8. package/dist/advertised-hosts.test.js +96 -0
  9. package/dist/advertised-hosts.test.js.map +1 -0
  10. package/dist/audit.d.ts +30 -0
  11. package/dist/audit.d.ts.map +1 -0
  12. package/dist/audit.js +73 -0
  13. package/dist/audit.js.map +1 -0
  14. package/dist/audit.test.d.ts +2 -0
  15. package/dist/audit.test.d.ts.map +1 -0
  16. package/dist/audit.test.js +33 -0
  17. package/dist/audit.test.js.map +1 -0
  18. package/dist/auth.d.ts +6 -0
  19. package/dist/auth.d.ts.map +1 -0
  20. package/dist/auth.js +27 -0
  21. package/dist/auth.js.map +1 -0
  22. package/dist/claude-hooks.d.ts +58 -0
  23. package/dist/claude-hooks.d.ts.map +1 -0
  24. package/dist/claude-hooks.js +129 -0
  25. package/dist/claude-hooks.js.map +1 -0
  26. package/dist/cli-version.d.ts +3 -0
  27. package/dist/cli-version.d.ts.map +1 -0
  28. package/dist/cli-version.js +35 -0
  29. package/dist/cli-version.js.map +1 -0
  30. package/dist/cli-version.test.d.ts +2 -0
  31. package/dist/cli-version.test.d.ts.map +1 -0
  32. package/dist/cli-version.test.js +38 -0
  33. package/dist/cli-version.test.js.map +1 -0
  34. package/dist/config.d.ts +30 -0
  35. package/dist/config.d.ts.map +1 -0
  36. package/dist/config.js +327 -0
  37. package/dist/config.js.map +1 -0
  38. package/dist/config.test.d.ts +2 -0
  39. package/dist/config.test.d.ts.map +1 -0
  40. package/dist/config.test.js +184 -0
  41. package/dist/config.test.js.map +1 -0
  42. package/dist/dev-auth.test.d.ts +2 -0
  43. package/dist/dev-auth.test.d.ts.map +1 -0
  44. package/dist/dev-auth.test.js +154 -0
  45. package/dist/dev-auth.test.js.map +1 -0
  46. package/dist/dev-script.test.d.ts +2 -0
  47. package/dist/dev-script.test.d.ts.map +1 -0
  48. package/dist/dev-script.test.js +412 -0
  49. package/dist/dev-script.test.js.map +1 -0
  50. package/dist/drivers/claude.d.ts +34 -0
  51. package/dist/drivers/claude.d.ts.map +1 -0
  52. package/dist/drivers/claude.js +413 -0
  53. package/dist/drivers/claude.js.map +1 -0
  54. package/dist/drivers/claude.test.d.ts +2 -0
  55. package/dist/drivers/claude.test.d.ts.map +1 -0
  56. package/dist/drivers/claude.test.js +951 -0
  57. package/dist/drivers/claude.test.js.map +1 -0
  58. package/dist/drivers/codex.d.ts +38 -0
  59. package/dist/drivers/codex.d.ts.map +1 -0
  60. package/dist/drivers/codex.js +771 -0
  61. package/dist/drivers/codex.js.map +1 -0
  62. package/dist/drivers/codex.test.d.ts +2 -0
  63. package/dist/drivers/codex.test.d.ts.map +1 -0
  64. package/dist/drivers/codex.test.js +939 -0
  65. package/dist/drivers/codex.test.js.map +1 -0
  66. package/dist/drivers/types.d.ts +14 -0
  67. package/dist/drivers/types.d.ts.map +1 -0
  68. package/dist/drivers/types.js +2 -0
  69. package/dist/drivers/types.js.map +1 -0
  70. package/dist/e2e.test.d.ts +2 -0
  71. package/dist/e2e.test.d.ts.map +1 -0
  72. package/dist/e2e.test.js +111 -0
  73. package/dist/e2e.test.js.map +1 -0
  74. package/dist/identity.d.ts +10 -0
  75. package/dist/identity.d.ts.map +1 -0
  76. package/dist/identity.js +66 -0
  77. package/dist/identity.js.map +1 -0
  78. package/dist/identity.test.d.ts +2 -0
  79. package/dist/identity.test.d.ts.map +1 -0
  80. package/dist/identity.test.js +25 -0
  81. package/dist/identity.test.js.map +1 -0
  82. package/dist/index-entry.test.d.ts +2 -0
  83. package/dist/index-entry.test.d.ts.map +1 -0
  84. package/dist/index-entry.test.js +272 -0
  85. package/dist/index-entry.test.js.map +1 -0
  86. package/dist/index.d.ts +2 -0
  87. package/dist/index.d.ts.map +1 -0
  88. package/dist/index.js +707 -0
  89. package/dist/index.js.map +1 -0
  90. package/dist/logger.d.ts +31 -0
  91. package/dist/logger.d.ts.map +1 -0
  92. package/dist/logger.js +75 -0
  93. package/dist/logger.js.map +1 -0
  94. package/dist/metrics.d.ts +52 -0
  95. package/dist/metrics.d.ts.map +1 -0
  96. package/dist/metrics.js +89 -0
  97. package/dist/metrics.js.map +1 -0
  98. package/dist/pairing-store.d.ts +29 -0
  99. package/dist/pairing-store.d.ts.map +1 -0
  100. package/dist/pairing-store.js +131 -0
  101. package/dist/pairing-store.js.map +1 -0
  102. package/dist/pairing-store.test.d.ts +2 -0
  103. package/dist/pairing-store.test.d.ts.map +1 -0
  104. package/dist/pairing-store.test.js +47 -0
  105. package/dist/pairing-store.test.js.map +1 -0
  106. package/dist/paths.d.ts +16 -0
  107. package/dist/paths.d.ts.map +1 -0
  108. package/dist/paths.js +18 -0
  109. package/dist/paths.js.map +1 -0
  110. package/dist/perf-compare.d.ts +13 -0
  111. package/dist/perf-compare.d.ts.map +1 -0
  112. package/dist/perf-compare.js +125 -0
  113. package/dist/perf-compare.js.map +1 -0
  114. package/dist/port-conflict.d.ts +9 -0
  115. package/dist/port-conflict.d.ts.map +1 -0
  116. package/dist/port-conflict.js +33 -0
  117. package/dist/port-conflict.js.map +1 -0
  118. package/dist/port-conflict.test.d.ts +2 -0
  119. package/dist/port-conflict.test.d.ts.map +1 -0
  120. package/dist/port-conflict.test.js +38 -0
  121. package/dist/port-conflict.test.js.map +1 -0
  122. package/dist/process-scanner.d.ts +43 -0
  123. package/dist/process-scanner.d.ts.map +1 -0
  124. package/dist/process-scanner.js +453 -0
  125. package/dist/process-scanner.js.map +1 -0
  126. package/dist/process-scanner.perf.test.d.ts +2 -0
  127. package/dist/process-scanner.perf.test.d.ts.map +1 -0
  128. package/dist/process-scanner.perf.test.js +186 -0
  129. package/dist/process-scanner.perf.test.js.map +1 -0
  130. package/dist/process-scanner.test.d.ts +2 -0
  131. package/dist/process-scanner.test.d.ts.map +1 -0
  132. package/dist/process-scanner.test.js +399 -0
  133. package/dist/process-scanner.test.js.map +1 -0
  134. package/dist/push-protocol.d.ts +15 -0
  135. package/dist/push-protocol.d.ts.map +1 -0
  136. package/dist/push-protocol.js +23 -0
  137. package/dist/push-protocol.js.map +1 -0
  138. package/dist/push-protocol.test.d.ts +2 -0
  139. package/dist/push-protocol.test.d.ts.map +1 -0
  140. package/dist/push-protocol.test.js +57 -0
  141. package/dist/push-protocol.test.js.map +1 -0
  142. package/dist/push-store.d.ts +22 -0
  143. package/dist/push-store.d.ts.map +1 -0
  144. package/dist/push-store.js +103 -0
  145. package/dist/push-store.js.map +1 -0
  146. package/dist/push-store.test.d.ts +2 -0
  147. package/dist/push-store.test.d.ts.map +1 -0
  148. package/dist/push-store.test.js +79 -0
  149. package/dist/push-store.test.js.map +1 -0
  150. package/dist/push.d.ts +65 -0
  151. package/dist/push.d.ts.map +1 -0
  152. package/dist/push.js +202 -0
  153. package/dist/push.js.map +1 -0
  154. package/dist/push.test.d.ts +2 -0
  155. package/dist/push.test.d.ts.map +1 -0
  156. package/dist/push.test.js +199 -0
  157. package/dist/push.test.js.map +1 -0
  158. package/dist/safe-stdio.d.ts +3 -0
  159. package/dist/safe-stdio.d.ts.map +1 -0
  160. package/dist/safe-stdio.js +46 -0
  161. package/dist/safe-stdio.js.map +1 -0
  162. package/dist/scanner.d.ts +30 -0
  163. package/dist/scanner.d.ts.map +1 -0
  164. package/dist/scanner.js +859 -0
  165. package/dist/scanner.js.map +1 -0
  166. package/dist/scanner.perf.test.d.ts +2 -0
  167. package/dist/scanner.perf.test.d.ts.map +1 -0
  168. package/dist/scanner.perf.test.js +320 -0
  169. package/dist/scanner.perf.test.js.map +1 -0
  170. package/dist/scanner.test.d.ts +2 -0
  171. package/dist/scanner.test.d.ts.map +1 -0
  172. package/dist/scanner.test.js +948 -0
  173. package/dist/scanner.test.js.map +1 -0
  174. package/dist/session-inventory.d.ts +63 -0
  175. package/dist/session-inventory.d.ts.map +1 -0
  176. package/dist/session-inventory.js +525 -0
  177. package/dist/session-inventory.js.map +1 -0
  178. package/dist/session-inventory.perf.test.d.ts +2 -0
  179. package/dist/session-inventory.perf.test.d.ts.map +1 -0
  180. package/dist/session-inventory.perf.test.js +220 -0
  181. package/dist/session-inventory.perf.test.js.map +1 -0
  182. package/dist/session-inventory.test.d.ts +2 -0
  183. package/dist/session-inventory.test.d.ts.map +1 -0
  184. package/dist/session-inventory.test.js +712 -0
  185. package/dist/session-inventory.test.js.map +1 -0
  186. package/dist/session-manager.d.ts +75 -0
  187. package/dist/session-manager.d.ts.map +1 -0
  188. package/dist/session-manager.js +1515 -0
  189. package/dist/session-manager.js.map +1 -0
  190. package/dist/session-manager.test.d.ts +2 -0
  191. package/dist/session-manager.test.d.ts.map +1 -0
  192. package/dist/session-manager.test.js +2861 -0
  193. package/dist/session-manager.test.js.map +1 -0
  194. package/dist/session-store.d.ts +42 -0
  195. package/dist/session-store.d.ts.map +1 -0
  196. package/dist/session-store.js +163 -0
  197. package/dist/session-store.js.map +1 -0
  198. package/dist/session-store.test.d.ts +2 -0
  199. package/dist/session-store.test.d.ts.map +1 -0
  200. package/dist/session-store.test.js +236 -0
  201. package/dist/session-store.test.js.map +1 -0
  202. package/dist/session-title.d.ts +6 -0
  203. package/dist/session-title.d.ts.map +1 -0
  204. package/dist/session-title.js +105 -0
  205. package/dist/session-title.js.map +1 -0
  206. package/dist/session-title.perf.test.d.ts +2 -0
  207. package/dist/session-title.perf.test.d.ts.map +1 -0
  208. package/dist/session-title.perf.test.js +99 -0
  209. package/dist/session-title.perf.test.js.map +1 -0
  210. package/dist/session-title.test.d.ts +2 -0
  211. package/dist/session-title.test.d.ts.map +1 -0
  212. package/dist/session-title.test.js +199 -0
  213. package/dist/session-title.test.js.map +1 -0
  214. package/dist/shutdown-endpoint.test.d.ts +2 -0
  215. package/dist/shutdown-endpoint.test.d.ts.map +1 -0
  216. package/dist/shutdown-endpoint.test.js +93 -0
  217. package/dist/shutdown-endpoint.test.js.map +1 -0
  218. package/dist/storage-housekeeping.d.ts +28 -0
  219. package/dist/storage-housekeeping.d.ts.map +1 -0
  220. package/dist/storage-housekeeping.js +76 -0
  221. package/dist/storage-housekeeping.js.map +1 -0
  222. package/dist/storage-housekeeping.test.d.ts +2 -0
  223. package/dist/storage-housekeeping.test.d.ts.map +1 -0
  224. package/dist/storage-housekeeping.test.js +65 -0
  225. package/dist/storage-housekeeping.test.js.map +1 -0
  226. package/dist/test-daemon-harness.d.ts +31 -0
  227. package/dist/test-daemon-harness.d.ts.map +1 -0
  228. package/dist/test-daemon-harness.js +337 -0
  229. package/dist/test-daemon-harness.js.map +1 -0
  230. package/dist/token-auth.test.d.ts +2 -0
  231. package/dist/token-auth.test.d.ts.map +1 -0
  232. package/dist/token-auth.test.js +52 -0
  233. package/dist/token-auth.test.js.map +1 -0
  234. package/dist/utils.d.ts +4 -0
  235. package/dist/utils.d.ts.map +1 -0
  236. package/dist/utils.js +40 -0
  237. package/dist/utils.js.map +1 -0
  238. package/dist/utils.test.d.ts +2 -0
  239. package/dist/utils.test.d.ts.map +1 -0
  240. package/dist/utils.test.js +54 -0
  241. package/dist/utils.test.js.map +1 -0
  242. package/dist/ws-data.d.ts +4 -0
  243. package/dist/ws-data.d.ts.map +1 -0
  244. package/dist/ws-data.js +20 -0
  245. package/dist/ws-data.js.map +1 -0
  246. package/dist/ws-data.test.d.ts +2 -0
  247. package/dist/ws-data.test.d.ts.map +1 -0
  248. package/dist/ws-data.test.js +17 -0
  249. package/dist/ws-data.test.js.map +1 -0
  250. package/package.json +24 -24
  251. package/perf-reporter.mjs +138 -0
  252. package/scripts/build-release.mjs +41 -0
  253. package/scripts/dev.mjs +537 -0
  254. package/src/advertised-hosts.test.ts +125 -0
  255. package/src/advertised-hosts.ts +225 -0
  256. package/src/audit.test.ts +38 -0
  257. package/src/audit.ts +117 -0
  258. package/src/auth.ts +31 -0
  259. package/src/claude-hooks.ts +195 -0
  260. package/src/cli-version.test.ts +36 -0
  261. package/src/cli-version.ts +46 -0
  262. package/src/config.test.ts +254 -0
  263. package/src/config.ts +324 -0
  264. package/src/dev-auth.test.ts +183 -0
  265. package/src/dev-script.test.ts +511 -0
  266. package/src/drivers/claude.test.ts +1186 -0
  267. package/src/drivers/claude.ts +443 -0
  268. package/src/drivers/codex.test.ts +1096 -0
  269. package/src/drivers/codex.ts +879 -0
  270. package/src/drivers/types.ts +15 -0
  271. package/src/e2e.test.ts +139 -0
  272. package/src/identity.test.ts +26 -0
  273. package/src/identity.ts +82 -0
  274. package/src/index-entry.test.ts +336 -0
  275. package/src/index.ts +781 -0
  276. package/src/logger.ts +112 -0
  277. package/src/metrics.ts +117 -0
  278. package/src/pairing-store.test.ts +53 -0
  279. package/src/pairing-store.ts +154 -0
  280. package/src/paths.ts +19 -0
  281. package/src/perf-compare.ts +164 -0
  282. package/src/port-conflict.test.ts +45 -0
  283. package/src/port-conflict.ts +44 -0
  284. package/src/process-scanner.perf.test.ts +222 -0
  285. package/src/process-scanner.test.ts +575 -0
  286. package/src/process-scanner.ts +514 -0
  287. package/src/push-protocol.test.ts +74 -0
  288. package/src/push-protocol.ts +36 -0
  289. package/src/push-store.test.ts +89 -0
  290. package/src/push-store.ts +126 -0
  291. package/src/push.test.ts +234 -0
  292. package/src/push.ts +318 -0
  293. package/src/safe-stdio.ts +51 -0
  294. package/src/scanner.perf.test.ts +359 -0
  295. package/src/scanner.test.ts +1045 -0
  296. package/src/scanner.ts +924 -0
  297. package/src/session-inventory.perf.test.ts +250 -0
  298. package/src/session-inventory.test.ts +1002 -0
  299. package/src/session-inventory.ts +721 -0
  300. package/src/session-manager.test.ts +3430 -0
  301. package/src/session-manager.ts +1775 -0
  302. package/src/session-store.test.ts +276 -0
  303. package/src/session-store.ts +202 -0
  304. package/src/session-title.perf.test.ts +118 -0
  305. package/src/session-title.test.ts +286 -0
  306. package/src/session-title.ts +108 -0
  307. package/src/shutdown-endpoint.test.ts +95 -0
  308. package/src/storage-housekeeping.test.ts +78 -0
  309. package/src/storage-housekeeping.ts +111 -0
  310. package/src/test-daemon-harness.ts +410 -0
  311. package/src/token-auth.test.ts +67 -0
  312. package/src/utils.test.ts +65 -0
  313. package/src/utils.ts +47 -0
  314. package/src/ws-data.test.ts +20 -0
  315. package/src/ws-data.ts +26 -0
  316. package/tsconfig.json +12 -0
  317. package/README.md +0 -80
  318. package/bin/cloudflared-quick-tunnel.mjs +0 -11
  319. package/bin/cloudflared-resolver.mjs +0 -68
  320. package/bin/vibelet-runtime-policy.mjs +0 -36
  321. package/bin/vibelet.cjs +0 -12
  322. package/bin/vibelet.mjs +0 -1035
  323. package/dist/index.cjs +0 -125
package/app.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "ios": {
3
+ "bundleIdentifier": "com.anonymous.-vibeletdaemon"
4
+ }
5
+ }
@@ -0,0 +1,34 @@
1
+ import { execFileSync } from 'child_process';
2
+ import type { NetworkInterfaceInfo } from 'os';
3
+ export interface AdvertisedHostsOptions {
4
+ canonicalHost: string;
5
+ configuredCanonicalHost?: string;
6
+ configuredFallbackHosts?: string[];
7
+ tailscaleCanonicalHost?: string;
8
+ tailscaleFallbackHosts?: string[];
9
+ interfaces: NodeJS.Dict<NetworkInterfaceInfo[]>;
10
+ }
11
+ export interface TailscaleHosts {
12
+ canonicalHost?: string;
13
+ fallbackHosts: string[];
14
+ }
15
+ export interface AdvertisedConnectionTargetOptions {
16
+ canonicalHost: string;
17
+ fallbackHosts?: string[];
18
+ port: number;
19
+ relayUrl?: string;
20
+ }
21
+ export interface AdvertisedConnectionTarget {
22
+ canonicalHost: string;
23
+ fallbackHosts: string[];
24
+ port: number;
25
+ }
26
+ export declare function readConfiguredFallbackHosts(rawValue: string | undefined): string[];
27
+ export declare function parseTailscaleStatus(rawStatus: string): TailscaleHosts;
28
+ export declare function readTailscaleHosts(runCommand?: typeof execFileSync): TailscaleHosts;
29
+ export declare function computeAdvertisedConnectionTarget(options: AdvertisedConnectionTargetOptions): AdvertisedConnectionTarget;
30
+ export declare function computeAdvertisedHosts(options: AdvertisedHostsOptions): {
31
+ canonicalHost: string;
32
+ fallbackHosts: string[];
33
+ };
34
+ //# sourceMappingURL=advertised-hosts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advertised-hosts.d.ts","sourceRoot":"","sources":["../src/advertised-hosts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,IAAI,CAAC;AAE/C,MAAM,WAAW,sBAAsB;IACrC,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,CAAC;CACjD;AASD,MAAM,WAAW,cAAc;IAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,iCAAiC;IAChD,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,0BAA0B;IACzC,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;CACd;AAiDD,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAMlF;AAsBD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,CAiBtE;AAED,wBAAgB,kBAAkB,CAAC,UAAU,GAAE,OAAO,YAA2B,GAAG,cAAc,CA6BjG;AAED,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,iCAAiC,GACzC,0BAA0B,CAmC5B;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,sBAAsB,GAAG;IAAE,aAAa,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,CAAA;CAAE,CAuB1H"}
@@ -0,0 +1,176 @@
1
+ import { execFileSync } from 'child_process';
2
+ function isIpv4(address) {
3
+ const parts = address.split('.');
4
+ if (parts.length !== 4)
5
+ return false;
6
+ return parts.every((part) => /^\d+$/.test(part) && Number(part) >= 0 && Number(part) <= 255);
7
+ }
8
+ function isTailscaleIpv4(address) {
9
+ if (!isIpv4(address))
10
+ return false;
11
+ const [first, second] = address.split('.').map(Number);
12
+ return first === 100 && second >= 64 && second <= 127;
13
+ }
14
+ function isLinkLocalIpv4(address) {
15
+ if (!isIpv4(address))
16
+ return false;
17
+ const [first, second] = address.split('.').map(Number);
18
+ return first === 169 && second === 254;
19
+ }
20
+ function isBenchmarkIpv4(address) {
21
+ if (!isIpv4(address))
22
+ return false;
23
+ const [first, second] = address.split('.').map(Number);
24
+ return first === 198 && (second === 18 || second === 19);
25
+ }
26
+ function isUsableHost(address) {
27
+ return Boolean(address)
28
+ && !isLinkLocalIpv4(address)
29
+ && !isBenchmarkIpv4(address);
30
+ }
31
+ function normalizeHost(host) {
32
+ if (!host)
33
+ return undefined;
34
+ const trimmed = host.trim().replace(/\.$/, '');
35
+ return trimmed ? trimmed.toLowerCase() : undefined;
36
+ }
37
+ function normalizeFallbackHosts(hosts, canonicalHost) {
38
+ return (hosts ?? [])
39
+ .map((host) => normalizeHost(host))
40
+ .filter((host) => Boolean(host))
41
+ .filter((host) => isUsableHost(host))
42
+ .filter((host, index, all) => host !== canonicalHost && all.indexOf(host) === index);
43
+ }
44
+ export function readConfiguredFallbackHosts(rawValue) {
45
+ if (!rawValue)
46
+ return [];
47
+ return rawValue
48
+ .split(',')
49
+ .map((entry) => entry.trim())
50
+ .filter(Boolean);
51
+ }
52
+ function collectInterfaceHosts(interfaces) {
53
+ const tailscaleHosts = [];
54
+ const lanHosts = [];
55
+ for (const entries of Object.values(interfaces)) {
56
+ if (!entries)
57
+ continue;
58
+ for (const entry of entries) {
59
+ if (entry.internal || entry.family !== 'IPv4')
60
+ continue;
61
+ if (!isUsableHost(entry.address))
62
+ continue;
63
+ if (isTailscaleIpv4(entry.address)) {
64
+ tailscaleHosts.push(entry.address);
65
+ }
66
+ else {
67
+ lanHosts.push(entry.address);
68
+ }
69
+ }
70
+ }
71
+ return [...tailscaleHosts, ...lanHosts];
72
+ }
73
+ export function parseTailscaleStatus(rawStatus) {
74
+ const parsed = JSON.parse(rawStatus);
75
+ const dnsName = normalizeHost(parsed.Self?.DNSName);
76
+ const tailscaleIps = (parsed.Self?.TailscaleIPs ?? [])
77
+ .map((host) => normalizeHost(host))
78
+ .filter((host) => Boolean(host))
79
+ .filter((host) => isTailscaleIpv4(host) && isUsableHost(host));
80
+ const canonicalHost = tailscaleIps[0] ?? dnsName;
81
+ const fallbackHosts = [
82
+ ...(dnsName && dnsName !== canonicalHost ? [dnsName] : []),
83
+ ...tailscaleIps.filter((host) => host !== canonicalHost),
84
+ ];
85
+ return {
86
+ canonicalHost,
87
+ fallbackHosts,
88
+ };
89
+ }
90
+ export function readTailscaleHosts(runCommand = execFileSync) {
91
+ const socketPaths = [
92
+ process.env.TAILSCALE_SOCKET,
93
+ '/tmp/tailscale.sock',
94
+ ].filter(Boolean);
95
+ // Try with custom socket paths first
96
+ for (const socket of socketPaths) {
97
+ try {
98
+ const rawStatus = runCommand('tailscale', ['--socket', socket, 'status', '--json'], {
99
+ encoding: 'utf8',
100
+ stdio: ['ignore', 'pipe', 'pipe'],
101
+ timeout: 1500,
102
+ });
103
+ return parseTailscaleStatus(rawStatus);
104
+ }
105
+ catch { /* try next */ }
106
+ }
107
+ // Fallback to default socket
108
+ try {
109
+ const rawStatus = runCommand('tailscale', ['status', '--json'], {
110
+ encoding: 'utf8',
111
+ stdio: ['ignore', 'pipe', 'pipe'],
112
+ timeout: 1500,
113
+ });
114
+ return parseTailscaleStatus(rawStatus);
115
+ }
116
+ catch {
117
+ return { fallbackHosts: [] };
118
+ }
119
+ }
120
+ export function computeAdvertisedConnectionTarget(options) {
121
+ const baseCanonicalHost = normalizeHost(options.canonicalHost) || 'localhost';
122
+ const baseFallbackHosts = normalizeFallbackHosts(options.fallbackHosts, baseCanonicalHost);
123
+ if (!options.relayUrl) {
124
+ return {
125
+ canonicalHost: baseCanonicalHost,
126
+ fallbackHosts: baseFallbackHosts,
127
+ port: options.port,
128
+ };
129
+ }
130
+ try {
131
+ const relay = new URL(options.relayUrl);
132
+ const relayCanonicalHost = normalizeHost(relay.hostname);
133
+ if (!relayCanonicalHost) {
134
+ throw new Error('invalid relay hostname');
135
+ }
136
+ const relayPort = relay.port
137
+ ? Number(relay.port)
138
+ : (relay.protocol === 'https:' ? 443 : 80);
139
+ return {
140
+ canonicalHost: relayCanonicalHost,
141
+ fallbackHosts: normalizeFallbackHosts([baseCanonicalHost, ...baseFallbackHosts], relayCanonicalHost),
142
+ port: Number.isFinite(relayPort) && relayPort > 0 ? Math.floor(relayPort) : options.port,
143
+ };
144
+ }
145
+ catch {
146
+ return {
147
+ canonicalHost: baseCanonicalHost,
148
+ fallbackHosts: baseFallbackHosts,
149
+ port: options.port,
150
+ };
151
+ }
152
+ }
153
+ export function computeAdvertisedHosts(options) {
154
+ const baseCanonicalHost = normalizeHost(options.canonicalHost);
155
+ const canonicalHost = normalizeHost(options.configuredCanonicalHost)
156
+ || normalizeHost(options.tailscaleCanonicalHost)
157
+ || baseCanonicalHost
158
+ || 'localhost';
159
+ const fallbackHosts = [
160
+ ...(baseCanonicalHost && baseCanonicalHost !== canonicalHost
161
+ ? [baseCanonicalHost]
162
+ : []),
163
+ ...(options.configuredFallbackHosts ?? []),
164
+ ...(options.tailscaleFallbackHosts ?? []),
165
+ ...collectInterfaceHosts(options.interfaces),
166
+ ]
167
+ .map((host) => normalizeHost(host))
168
+ .filter((host) => Boolean(host))
169
+ .filter((host) => isUsableHost(host))
170
+ .filter((host, index, all) => host !== canonicalHost && all.indexOf(host) === index);
171
+ return {
172
+ canonicalHost,
173
+ fallbackHosts,
174
+ };
175
+ }
176
+ //# sourceMappingURL=advertised-hosts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advertised-hosts.js","sourceRoot":"","sources":["../src/advertised-hosts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=advertised-hosts.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advertised-hosts.test.d.ts","sourceRoot":"","sources":["../src/advertised-hosts.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,96 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { computeAdvertisedConnectionTarget, computeAdvertisedHosts, parseTailscaleStatus, readConfiguredFallbackHosts, readTailscaleHosts, } from './advertised-hosts.js';
4
+ function ipv4(address) {
5
+ return {
6
+ address,
7
+ netmask: '255.255.255.0',
8
+ family: 'IPv4',
9
+ mac: '00:00:00:00:00:00',
10
+ internal: false,
11
+ cidr: `${address}/24`,
12
+ };
13
+ }
14
+ test('computeAdvertisedHosts prefers configured canonical host and prioritizes Tailscale IPs', () => {
15
+ const advertised = computeAdvertisedHosts({
16
+ canonicalHost: 'desk-mac.local',
17
+ configuredCanonicalHost: 'desk.tailnet.ts.net',
18
+ configuredFallbackHosts: ['100.88.1.9'],
19
+ tailscaleCanonicalHost: '100.77.2.3',
20
+ tailscaleFallbackHosts: ['desk.ts.net'],
21
+ interfaces: {
22
+ en0: [ipv4('192.168.31.20')],
23
+ utun8: [ipv4('100.77.2.3')],
24
+ },
25
+ });
26
+ assert.equal(advertised.canonicalHost, 'desk.tailnet.ts.net');
27
+ assert.deepStrictEqual(advertised.fallbackHosts, ['desk-mac.local', '100.88.1.9', 'desk.ts.net', '100.77.2.3', '192.168.31.20']);
28
+ });
29
+ test('computeAdvertisedHosts removes duplicates and excludes the canonical host', () => {
30
+ const advertised = computeAdvertisedHosts({
31
+ canonicalHost: '100.77.2.3',
32
+ configuredFallbackHosts: ['100.77.2.3', '192.168.31.20', '192.168.31.20'],
33
+ interfaces: {
34
+ utun8: [ipv4('100.77.2.3')],
35
+ en0: [ipv4('192.168.31.20')],
36
+ },
37
+ });
38
+ assert.equal(advertised.canonicalHost, '100.77.2.3');
39
+ assert.deepStrictEqual(advertised.fallbackHosts, ['192.168.31.20']);
40
+ });
41
+ test('computeAdvertisedHosts filters out link-local and benchmark addresses', () => {
42
+ const advertised = computeAdvertisedHosts({
43
+ canonicalHost: 'desk-mac.local',
44
+ interfaces: {
45
+ en0: [ipv4('192.168.31.20'), ipv4('169.254.12.2')],
46
+ utun4: [ipv4('198.19.0.1')],
47
+ },
48
+ });
49
+ assert.equal(advertised.canonicalHost, 'desk-mac.local');
50
+ assert.deepStrictEqual(advertised.fallbackHosts, ['192.168.31.20']);
51
+ });
52
+ test('parseTailscaleStatus prefers the first Tailscale IP and keeps MagicDNS as fallback', () => {
53
+ const advertised = parseTailscaleStatus(JSON.stringify({
54
+ Self: {
55
+ DNSName: 'desk.tailnet.ts.net.',
56
+ TailscaleIPs: ['100.88.1.9', '100.99.2.4'],
57
+ },
58
+ }));
59
+ assert.deepStrictEqual(advertised, {
60
+ canonicalHost: '100.88.1.9',
61
+ fallbackHosts: ['desk.tailnet.ts.net', '100.99.2.4'],
62
+ });
63
+ });
64
+ test('readTailscaleHosts returns empty data when tailscale is unavailable', () => {
65
+ const advertised = readTailscaleHosts(() => {
66
+ throw new Error('tailscale unavailable');
67
+ });
68
+ assert.deepStrictEqual(advertised, { fallbackHosts: [] });
69
+ });
70
+ test('readConfiguredFallbackHosts parses comma separated env values', () => {
71
+ assert.deepStrictEqual(readConfiguredFallbackHosts(' 100.77.2.3, desk.tailnet.ts.net , 192.168.31.20 '), ['100.77.2.3', 'desk.tailnet.ts.net', '192.168.31.20']);
72
+ });
73
+ test('computeAdvertisedConnectionTarget keeps the base host and port without a relay', () => {
74
+ assert.deepStrictEqual(computeAdvertisedConnectionTarget({
75
+ canonicalHost: 'desk-mac.local',
76
+ fallbackHosts: ['100.88.1.9', '192.168.31.20'],
77
+ port: 9876,
78
+ }), {
79
+ canonicalHost: 'desk-mac.local',
80
+ fallbackHosts: ['100.88.1.9', '192.168.31.20'],
81
+ port: 9876,
82
+ });
83
+ });
84
+ test('computeAdvertisedConnectionTarget prefers the relay host and preserves local fallbacks', () => {
85
+ assert.deepStrictEqual(computeAdvertisedConnectionTarget({
86
+ canonicalHost: 'desk-mac.local',
87
+ fallbackHosts: ['desk-mac.local', '100.88.1.9', '100.88.1.9', '192.168.31.20'],
88
+ port: 9876,
89
+ relayUrl: 'https://relay.example.com',
90
+ }), {
91
+ canonicalHost: 'relay.example.com',
92
+ fallbackHosts: ['desk-mac.local', '100.88.1.9', '192.168.31.20'],
93
+ port: 443,
94
+ });
95
+ });
96
+ //# sourceMappingURL=advertised-hosts.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"advertised-hosts.test.js","sourceRoot":"","sources":["../src/advertised-hosts.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AAExC,OAAO,EACL,iCAAiC,EACjC,sBAAsB,EACtB,oBAAoB,EACpB,2BAA2B,EAC3B,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAE/B,SAAS,IAAI,CAAC,OAAe;IAC3B,OAAO;QACL,OAAO;QACP,OAAO,EAAE,eAAe;QACxB,MAAM,EAAE,MAAM;QACd,GAAG,EAAE,mBAAmB;QACxB,QAAQ,EAAE,KAAK;QACf,IAAI,EAAE,GAAG,OAAO,KAAK;KACtB,CAAC;AACJ,CAAC;AAED,IAAI,CAAC,wFAAwF,EAAE,GAAG,EAAE;IAClG,MAAM,UAAU,GAAG,sBAAsB,CAAC;QACxC,aAAa,EAAE,gBAAgB;QAC/B,uBAAuB,EAAE,qBAAqB;QAC9C,uBAAuB,EAAE,CAAC,YAAY,CAAC;QACvC,sBAAsB,EAAE,YAAY;QACpC,sBAAsB,EAAE,CAAC,aAAa,CAAC;QACvC,UAAU,EAAE;YACV,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC5B,KAAK,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;SAC5B;KACF,CAAC,CAAC;IAEH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa,EAAE,qBAAqB,CAAC,CAAC;IAC9D,MAAM,CAAC,eAAe,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,gBAAgB,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;AACnI,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2EAA2E,EAAE,GAAG,EAAE;IACrF,MAAM,UAAU,GAAG,sBAAsB,CAAC;QACxC,aAAa,EAAE,YAAY;QAC3B,uBAAuB,EAAE,CAAC,YAAY,EAAE,eAAe,EAAE,eAAe,CAAC;QACzE,UAAU,EAAE;YACV,KAAK,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC3B,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;SAC7B;KACF,CAAC,CAAC;IAEH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IACrD,MAAM,CAAC,eAAe,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,uEAAuE,EAAE,GAAG,EAAE;IACjF,MAAM,UAAU,GAAG,sBAAsB,CAAC;QACxC,aAAa,EAAE,gBAAgB;QAC/B,UAAU,EAAE;YACV,GAAG,EAAE,CAAC,IAAI,CAAC,eAAe,CAAC,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;YAClD,KAAK,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;SAC5B;KACF,CAAC,CAAC;IAEH,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,aAAa,EAAE,gBAAgB,CAAC,CAAC;IACzD,MAAM,CAAC,eAAe,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC;AACtE,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,oFAAoF,EAAE,GAAG,EAAE;IAC9F,MAAM,UAAU,GAAG,oBAAoB,CAAC,IAAI,CAAC,SAAS,CAAC;QACrD,IAAI,EAAE;YACJ,OAAO,EAAE,sBAAsB;YAC/B,YAAY,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;SAC3C;KACF,CAAC,CAAC,CAAC;IAEJ,MAAM,CAAC,eAAe,CAAC,UAAU,EAAE;QACjC,aAAa,EAAE,YAAY;QAC3B,aAAa,EAAE,CAAC,qBAAqB,EAAE,YAAY,CAAC;KACrD,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,qEAAqE,EAAE,GAAG,EAAE;IAC/E,MAAM,UAAU,GAAG,kBAAkB,CAAC,GAAG,EAAE;QACzC,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAC3C,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,eAAe,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,EAAE,EAAE,CAAC,CAAC;AAC5D,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,+DAA+D,EAAE,GAAG,EAAE;IACzE,MAAM,CAAC,eAAe,CACpB,2BAA2B,CAAC,mDAAmD,CAAC,EAChF,CAAC,YAAY,EAAE,qBAAqB,EAAE,eAAe,CAAC,CACvD,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,gFAAgF,EAAE,GAAG,EAAE;IAC1F,MAAM,CAAC,eAAe,CACpB,iCAAiC,CAAC;QAChC,aAAa,EAAE,gBAAgB;QAC/B,aAAa,EAAE,CAAC,YAAY,EAAE,eAAe,CAAC;QAC9C,IAAI,EAAE,IAAI;KACX,CAAC,EACF;QACE,aAAa,EAAE,gBAAgB;QAC/B,aAAa,EAAE,CAAC,YAAY,EAAE,eAAe,CAAC;QAC9C,IAAI,EAAE,IAAI;KACX,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,wFAAwF,EAAE,GAAG,EAAE;IAClG,MAAM,CAAC,eAAe,CACpB,iCAAiC,CAAC;QAChC,aAAa,EAAE,gBAAgB;QAC/B,aAAa,EAAE,CAAC,gBAAgB,EAAE,YAAY,EAAE,YAAY,EAAE,eAAe,CAAC;QAC9E,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE,2BAA2B;KACtC,CAAC,EACF;QACE,aAAa,EAAE,mBAAmB;QAClC,aAAa,EAAE,CAAC,gBAAgB,EAAE,YAAY,EAAE,eAAe,CAAC;QAChE,IAAI,EAAE,GAAG;KACV,CACF,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Size-bounded audit log for session lifecycle events.
3
+ *
4
+ * Writes JSONL to ~/.vibelet/data/audit.jsonl.
5
+ * Each line is a self-contained event with timestamp, event type, and context.
6
+ *
7
+ * Usage:
8
+ * import { audit } from './audit.js';
9
+ * audit.emit('session.create', { sessionId, agent, cwd });
10
+ * audit.emit('session.done', { sessionId, cost, usage });
11
+ */
12
+ export type AuditEvent = 'session.create' | 'session.resume' | 'session.reconnect' | 'session.send' | 'session.done' | 'session.interrupted' | 'session.stop' | 'session.delete' | 'session.interrupt' | 'driver.spawn' | 'driver.init' | 'driver.exit' | 'driver.error' | 'driver.idle_timeout' | 'driver.stall_timeout' | 'approval.request' | 'approval.response' | 'ws.connect' | 'ws.disconnect' | 'daemon.start' | 'daemon.shutdown' | 'daemon.error' | 'app.log';
13
+ export type AuditSource = 'daemon' | 'app';
14
+ interface AuditEntry {
15
+ ts: string;
16
+ event: AuditEvent | string;
17
+ source?: AuditSource;
18
+ [key: string]: unknown;
19
+ }
20
+ export declare function sanitizeAppAuditData(data?: Record<string, unknown>): Record<string, unknown>;
21
+ export declare function buildAppAuditEntry(appEvent: string, level: string, data?: Record<string, unknown>, clientTs?: string): AuditEntry;
22
+ declare class AuditLog {
23
+ emit(event: AuditEvent, data?: Record<string, unknown>): void;
24
+ /** Write an app-reported log entry. Preserves client-side timestamp if provided. */
25
+ emitApp(appEvent: string, level: string, data?: Record<string, unknown>, clientTs?: string): void;
26
+ private write;
27
+ }
28
+ export declare const audit: AuditLog;
29
+ export {};
30
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH,MAAM,MAAM,UAAU,GAClB,gBAAgB,GAChB,gBAAgB,GAChB,mBAAmB,GACnB,cAAc,GACd,cAAc,GACd,qBAAqB,GACrB,cAAc,GACd,gBAAgB,GAChB,mBAAmB,GACnB,cAAc,GACd,aAAa,GACb,aAAa,GACb,cAAc,GACd,qBAAqB,GACrB,sBAAsB,GACtB,kBAAkB,GAClB,mBAAmB,GACnB,YAAY,GACZ,eAAe,GACf,cAAc,GACd,iBAAiB,GACjB,cAAc,GACd,SAAS,CAAC;AAEd,MAAM,MAAM,WAAW,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE3C,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,UAAU,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AASD,wBAAgB,oBAAoB,CAAC,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOhG;AAED,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAClC,QAAQ,CAAC,EAAE,MAAM,GAChB,UAAU,CASZ;AAQD,cAAM,QAAQ;IACZ,IAAI,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,GAAG,IAAI;IAIjE,oFAAoF;IACpF,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI;IAIrG,OAAO,CAAC,KAAK;CAcd;AAED,eAAO,MAAM,KAAK,UAAiB,CAAC"}
package/dist/audit.js ADDED
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Size-bounded audit log for session lifecycle events.
3
+ *
4
+ * Writes JSONL to ~/.vibelet/data/audit.jsonl.
5
+ * Each line is a self-contained event with timestamp, event type, and context.
6
+ *
7
+ * Usage:
8
+ * import { audit } from './audit.js';
9
+ * audit.emit('session.create', { sessionId, agent, cwd });
10
+ * audit.emit('session.done', { sessionId, cost, usage });
11
+ */
12
+ import { appendFileSync, mkdirSync } from 'fs';
13
+ import { dirname } from 'path';
14
+ import { AUDIT_PATH } from './paths.js';
15
+ import { config } from './config.js';
16
+ import { trimFileTailSync } from './storage-housekeeping.js';
17
+ let initialized = false;
18
+ const APP_AUDIT_RESERVED_FIELDS = new Set(['ts', 'event', 'source', 'appEvent', 'level']);
19
+ function isTestRuntime() {
20
+ return process.env.VIBE_TEST === '1' || process.argv.includes('--test');
21
+ }
22
+ export function sanitizeAppAuditData(data = {}) {
23
+ const sanitized = {};
24
+ for (const [key, value] of Object.entries(data)) {
25
+ if (APP_AUDIT_RESERVED_FIELDS.has(key))
26
+ continue;
27
+ sanitized[key] = value;
28
+ }
29
+ return sanitized;
30
+ }
31
+ export function buildAppAuditEntry(appEvent, level, data = {}, clientTs) {
32
+ return {
33
+ ts: clientTs ?? new Date().toISOString(),
34
+ event: 'app.log',
35
+ source: 'app',
36
+ appEvent,
37
+ level,
38
+ ...sanitizeAppAuditData(data),
39
+ };
40
+ }
41
+ function ensureDir() {
42
+ if (initialized)
43
+ return;
44
+ mkdirSync(dirname(AUDIT_PATH), { recursive: true });
45
+ initialized = true;
46
+ }
47
+ class AuditLog {
48
+ emit(event, data = {}) {
49
+ this.write({ ts: new Date().toISOString(), event, ...data });
50
+ }
51
+ /** Write an app-reported log entry. Preserves client-side timestamp if provided. */
52
+ emitApp(appEvent, level, data = {}, clientTs) {
53
+ this.write(buildAppAuditEntry(appEvent, level, data, clientTs));
54
+ }
55
+ write(entry) {
56
+ if (isTestRuntime())
57
+ return;
58
+ ensureDir();
59
+ try {
60
+ const line = JSON.stringify(entry) + '\n';
61
+ trimFileTailSync(AUDIT_PATH, {
62
+ maxBytes: config.auditMaxBytes,
63
+ incomingBytes: Buffer.byteLength(line),
64
+ });
65
+ appendFileSync(AUDIT_PATH, line);
66
+ }
67
+ catch {
68
+ // Audit log is best-effort — never crash the daemon
69
+ }
70
+ }
71
+ }
72
+ export const audit = new AuditLog();
73
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../src/audit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AAC/B,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAoC7D,IAAI,WAAW,GAAG,KAAK,CAAC;AACxB,MAAM,yBAAyB,GAAG,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;AAE1F,SAAS,aAAa;IACpB,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,KAAK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAgC,EAAE;IACrE,MAAM,SAAS,GAA4B,EAAE,CAAC;IAC9C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,yBAAyB,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,SAAS;QACjD,SAAS,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACzB,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAChC,QAAgB,EAChB,KAAa,EACb,OAAgC,EAAE,EAClC,QAAiB;IAEjB,OAAO;QACL,EAAE,EAAE,QAAQ,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACxC,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,KAAoB;QAC5B,QAAQ;QACR,KAAK;QACL,GAAG,oBAAoB,CAAC,IAAI,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED,SAAS,SAAS;IAChB,IAAI,WAAW;QAAE,OAAO;IACxB,SAAS,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,WAAW,GAAG,IAAI,CAAC;AACrB,CAAC;AAED,MAAM,QAAQ;IACZ,IAAI,CAAC,KAAiB,EAAE,OAAgC,EAAE;QACxD,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;IAC/D,CAAC;IAED,oFAAoF;IACpF,OAAO,CAAC,QAAgB,EAAE,KAAa,EAAE,OAAgC,EAAE,EAAE,QAAiB;QAC5F,IAAI,CAAC,KAAK,CAAC,kBAAkB,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;IAClE,CAAC;IAEO,KAAK,CAAC,KAA8B;QAC1C,IAAI,aAAa,EAAE;YAAE,OAAO;QAC5B,SAAS,EAAE,CAAC;QACZ,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC;YAC1C,gBAAgB,CAAC,UAAU,EAAE;gBAC3B,QAAQ,EAAE,MAAM,CAAC,aAAa;gBAC9B,aAAa,EAAE,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC;aACvC,CAAC,CAAC;YACH,cAAc,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QACnC,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;QACtD,CAAC;IACH,CAAC;CACF;AAED,MAAM,CAAC,MAAM,KAAK,GAAG,IAAI,QAAQ,EAAE,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=audit.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.test.d.ts","sourceRoot":"","sources":["../src/audit.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,33 @@
1
+ import test from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { buildAppAuditEntry, sanitizeAppAuditData } from './audit.js';
4
+ test('sanitizeAppAuditData strips reserved audit fields from client payloads', () => {
5
+ assert.deepEqual(sanitizeAppAuditData({
6
+ event: 'override',
7
+ source: 'app',
8
+ level: 'debug',
9
+ appEvent: 'fake',
10
+ ts: '2026-01-01T00:00:00.000Z',
11
+ sessionId: 'session-123',
12
+ agent: 'codex',
13
+ }), {
14
+ sessionId: 'session-123',
15
+ agent: 'codex',
16
+ });
17
+ });
18
+ test('buildAppAuditEntry preserves the audit envelope while keeping client data', () => {
19
+ const entry = buildAppAuditEntry('app.session.send', 'info', {
20
+ sessionId: 'session-123',
21
+ event: 'override',
22
+ level: 'debug',
23
+ }, '2026-03-21T12:00:00.000Z');
24
+ assert.deepEqual(entry, {
25
+ ts: '2026-03-21T12:00:00.000Z',
26
+ event: 'app.log',
27
+ source: 'app',
28
+ appEvent: 'app.session.send',
29
+ level: 'info',
30
+ sessionId: 'session-123',
31
+ });
32
+ });
33
+ //# sourceMappingURL=audit.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.test.js","sourceRoot":"","sources":["../src/audit.test.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEtE,IAAI,CAAC,wEAAwE,EAAE,GAAG,EAAE;IAClF,MAAM,CAAC,SAAS,CACd,oBAAoB,CAAC;QACnB,KAAK,EAAE,UAAU;QACjB,MAAM,EAAE,KAAK;QACb,KAAK,EAAE,OAAO;QACd,QAAQ,EAAE,MAAM;QAChB,EAAE,EAAE,0BAA0B;QAC9B,SAAS,EAAE,aAAa;QACxB,KAAK,EAAE,OAAO;KACf,CAAC,EACF;QACE,SAAS,EAAE,aAAa;QACxB,KAAK,EAAE,OAAO;KACf,CACF,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,2EAA2E,EAAE,GAAG,EAAE;IACrF,MAAM,KAAK,GAAG,kBAAkB,CAAC,kBAAkB,EAAE,MAAM,EAAE;QAC3D,SAAS,EAAE,aAAa;QACxB,KAAK,EAAE,UAAU;QACjB,KAAK,EAAE,OAAO;KACf,EAAE,0BAA0B,CAAC,CAAC;IAE/B,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE;QACtB,EAAE,EAAE,0BAA0B;QAC9B,KAAK,EAAE,SAAS;QAChB,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,kBAAkB;QAC5B,KAAK,EAAE,MAAM;QACb,SAAS,EAAE,aAAa;KACzB,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
package/dist/auth.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export declare function isLoopbackAddress(address: string | undefined): boolean;
2
+ export declare function readBearerToken(header: string | undefined): string | null;
3
+ export declare function resolveRequestToken(authHeader: string | undefined, queryToken: string | null): string | null;
4
+ export declare function isLegacyToken(token: string | null, legacyToken: string): boolean;
5
+ export declare function isAuthorizedToken(token: string | null, legacyToken: string, validatePairToken: (token: string, touch?: boolean) => unknown, touch?: boolean): boolean;
6
+ //# sourceMappingURL=auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAKtE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAIzE;AAED,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAE5G;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAEhF;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,MAAM,GAAG,IAAI,EACpB,WAAW,EAAE,MAAM,EACnB,iBAAiB,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,EAC9D,KAAK,UAAO,GACX,OAAO,CAIT"}
package/dist/auth.js ADDED
@@ -0,0 +1,27 @@
1
+ export function isLoopbackAddress(address) {
2
+ if (!address)
3
+ return false;
4
+ return address === '127.0.0.1'
5
+ || address === '::1'
6
+ || address === '::ffff:127.0.0.1';
7
+ }
8
+ export function readBearerToken(header) {
9
+ if (!header)
10
+ return null;
11
+ const match = header.match(/^Bearer\s+(.+)$/i);
12
+ return match?.[1]?.trim() || null;
13
+ }
14
+ export function resolveRequestToken(authHeader, queryToken) {
15
+ return readBearerToken(authHeader) ?? queryToken;
16
+ }
17
+ export function isLegacyToken(token, legacyToken) {
18
+ return Boolean(token && legacyToken && token === legacyToken);
19
+ }
20
+ export function isAuthorizedToken(token, legacyToken, validatePairToken, touch = true) {
21
+ if (!token)
22
+ return false;
23
+ if (isLegacyToken(token, legacyToken))
24
+ return true;
25
+ return Boolean(validatePairToken(token, touch));
26
+ }
27
+ //# sourceMappingURL=auth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auth.js","sourceRoot":"","sources":["../src/auth.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,iBAAiB,CAAC,OAA2B;IAC3D,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,OAAO,OAAO,KAAK,WAAW;WACzB,OAAO,KAAK,KAAK;WACjB,OAAO,KAAK,kBAAkB,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,MAA0B;IACxD,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC;IAC/C,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,UAA8B,EAAE,UAAyB;IAC3F,OAAO,eAAe,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAoB,EAAE,WAAmB;IACrE,OAAO,OAAO,CAAC,KAAK,IAAI,WAAW,IAAI,KAAK,KAAK,WAAW,CAAC,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAC/B,KAAoB,EACpB,WAAmB,EACnB,iBAA8D,EAC9D,KAAK,GAAG,IAAI;IAEZ,IAAI,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACzB,IAAI,aAAa,CAAC,KAAK,EAAE,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IACnD,OAAO,OAAO,CAAC,iBAAiB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,58 @@
1
+ export declare const CLAUDE_HOOK_APPROVAL_PREFIX = "claude-hook:";
2
+ export declare const CLAUDE_HOOK_SECRET_HEADER = "x-vibelet-claude-hook-secret";
3
+ export type ClaudeSessionHookData = {
4
+ session_id?: string;
5
+ sessionId?: string;
6
+ transcript_path?: string;
7
+ transcriptPath?: string;
8
+ cwd?: string;
9
+ hook_event_name?: string;
10
+ hookEventName?: string;
11
+ source?: string;
12
+ [key: string]: unknown;
13
+ };
14
+ export type ClaudePermissionHookData = {
15
+ session_id?: string;
16
+ sessionId?: string;
17
+ transcript_path?: string;
18
+ transcriptPath?: string;
19
+ cwd?: string;
20
+ hook_event_name?: string;
21
+ hookEventName?: string;
22
+ permission_mode?: string;
23
+ permissionMode?: string;
24
+ tool_name?: string;
25
+ toolName?: string;
26
+ tool_input?: unknown;
27
+ toolInput?: unknown;
28
+ tool_use_id?: string;
29
+ toolUseId?: string;
30
+ permission_suggestions?: unknown;
31
+ permissionSuggestions?: unknown;
32
+ [key: string]: unknown;
33
+ };
34
+ export type ClaudePermissionHookResponse = {
35
+ continue: boolean;
36
+ suppressOutput?: boolean;
37
+ stopReason?: string;
38
+ systemMessage?: string;
39
+ hookSpecificOutput?: {
40
+ hookEventName?: 'PreToolUse';
41
+ permissionDecision?: 'allow' | 'deny' | 'ask';
42
+ permissionDecisionReason?: string;
43
+ updatedInput?: unknown;
44
+ [key: string]: unknown;
45
+ };
46
+ [key: string]: unknown;
47
+ };
48
+ export type ClaudeHookFiles = {
49
+ secret: string;
50
+ dirPath: string;
51
+ settingsPath: string;
52
+ sessionScriptPath: string;
53
+ permissionScriptPath: string;
54
+ };
55
+ export declare const DEFAULT_CLAUDE_PERMISSION_HOOK_RESPONSE: ClaudePermissionHookResponse;
56
+ export declare function createClaudeHookFiles(port: number, secret: string): ClaudeHookFiles;
57
+ export declare function cleanupClaudeHookFiles(hookFiles: ClaudeHookFiles | null | undefined): void;
58
+ //# sourceMappingURL=claude-hooks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-hooks.d.ts","sourceRoot":"","sources":["../src/claude-hooks.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,2BAA2B,iBAAiB,CAAC;AAC1D,eAAO,MAAM,yBAAyB,iCAAiC,CAAC;AAExE,MAAM,MAAM,qBAAqB,GAAG;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sBAAsB,CAAC,EAAE,OAAO,CAAC;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,4BAA4B,GAAG;IACzC,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,kBAAkB,CAAC,EAAE;QACnB,aAAa,CAAC,EAAE,YAAY,CAAC;QAC7B,kBAAkB,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,CAAC;QAC9C,wBAAwB,CAAC,EAAE,MAAM,CAAC;QAClC,YAAY,CAAC,EAAE,OAAO,CAAC;QACvB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,CAAC;IACF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,oBAAoB,EAAE,MAAM,CAAC;CAC9B,CAAC;AAEF,eAAO,MAAM,uCAAuC,EAAE,4BAMrD,CAAC;AAmEF,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CAgDnF;AAED,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GAAG,IAAI,CAO1F"}