patchwork-os 0.2.0-beta.1 → 0.2.0-beta.10.canary.95

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 (652) hide show
  1. package/README.bridge.md +14 -14
  2. package/README.md +201 -34
  3. package/deploy/README.md +1 -1
  4. package/deploy/bootstrap-vps.sh +14 -9
  5. package/deploy/deploy-dashboard.sh +25 -1
  6. package/deploy/macos/README.md +153 -0
  7. package/deploy/macos/com.patchwork.bridge.plist.template +54 -0
  8. package/deploy/macos/com.patchwork.tunnel.plist.template +76 -0
  9. package/deploy/macos/install-mac-bridge.sh +244 -0
  10. package/deploy/macos/uninstall-mac-bridge.sh +22 -0
  11. package/dist/activityLog.d.ts +6 -0
  12. package/dist/activityLog.js +63 -26
  13. package/dist/activityLog.js.map +1 -1
  14. package/dist/adapters/claude.js +22 -16
  15. package/dist/adapters/claude.js.map +1 -1
  16. package/dist/adapters/gemini.js +15 -11
  17. package/dist/adapters/gemini.js.map +1 -1
  18. package/dist/adapters/openai.js +9 -9
  19. package/dist/adapters/openai.js.map +1 -1
  20. package/dist/ajv2020.d.ts +25 -0
  21. package/dist/ajv2020.js +33 -0
  22. package/dist/ajv2020.js.map +1 -0
  23. package/dist/analyticsAggregator.js +1 -1
  24. package/dist/analyticsAggregator.js.map +1 -1
  25. package/dist/analyticsConfig.d.ts +29 -0
  26. package/dist/analyticsConfig.js +102 -0
  27. package/dist/analyticsConfig.js.map +1 -0
  28. package/dist/analyticsPrefs.d.ts +38 -2
  29. package/dist/analyticsPrefs.js +148 -23
  30. package/dist/analyticsPrefs.js.map +1 -1
  31. package/dist/analyticsSend.d.ts +17 -1
  32. package/dist/analyticsSend.js +67 -5
  33. package/dist/analyticsSend.js.map +1 -1
  34. package/dist/approvalHttp.d.ts +14 -0
  35. package/dist/approvalHttp.js +212 -9
  36. package/dist/approvalHttp.js.map +1 -1
  37. package/dist/approvalInsights.js +13 -5
  38. package/dist/approvalInsights.js.map +1 -1
  39. package/dist/approvalQueue.d.ts +97 -3
  40. package/dist/approvalQueue.js +193 -19
  41. package/dist/approvalQueue.js.map +1 -1
  42. package/dist/approvalSignals.js +19 -11
  43. package/dist/approvalSignals.js.map +1 -1
  44. package/dist/automation.d.ts +35 -10
  45. package/dist/automation.js +133 -37
  46. package/dist/automation.js.map +1 -1
  47. package/dist/automationSuggestions.js +10 -8
  48. package/dist/automationSuggestions.js.map +1 -1
  49. package/dist/bridge.d.ts +2 -0
  50. package/dist/bridge.js +202 -25
  51. package/dist/bridge.js.map +1 -1
  52. package/dist/bridgeLockDiscovery.d.ts +27 -1
  53. package/dist/bridgeLockDiscovery.js +38 -11
  54. package/dist/bridgeLockDiscovery.js.map +1 -1
  55. package/dist/bridgeToken.js +3 -2
  56. package/dist/bridgeToken.js.map +1 -1
  57. package/dist/claudeDriver.js +23 -8
  58. package/dist/claudeDriver.js.map +1 -1
  59. package/dist/claudeOrchestrator.d.ts +1 -1
  60. package/dist/claudeOrchestrator.js +87 -44
  61. package/dist/claudeOrchestrator.js.map +1 -1
  62. package/dist/commands/analytics.d.ts +8 -0
  63. package/dist/commands/analytics.js +134 -0
  64. package/dist/commands/analytics.js.map +1 -0
  65. package/dist/commands/auditEnv.d.ts +36 -0
  66. package/dist/commands/auditEnv.js +202 -0
  67. package/dist/commands/auditEnv.js.map +1 -0
  68. package/dist/commands/dashboard.js +8 -1
  69. package/dist/commands/dashboard.js.map +1 -1
  70. package/dist/commands/doctor.d.ts +35 -0
  71. package/dist/commands/doctor.js +51 -0
  72. package/dist/commands/doctor.js.map +1 -0
  73. package/dist/commands/install.js +3 -0
  74. package/dist/commands/install.js.map +1 -1
  75. package/dist/commands/launchd.js +15 -16
  76. package/dist/commands/launchd.js.map +1 -1
  77. package/dist/commands/patchworkInit.d.ts +5 -0
  78. package/dist/commands/patchworkInit.js +89 -7
  79. package/dist/commands/patchworkInit.js.map +1 -1
  80. package/dist/commands/recipe.d.ts +110 -0
  81. package/dist/commands/recipe.js +512 -9
  82. package/dist/commands/recipe.js.map +1 -1
  83. package/dist/commands/recipeInstall.js +11 -4
  84. package/dist/commands/recipeInstall.js.map +1 -1
  85. package/dist/commands/shadowScan.d.ts +34 -0
  86. package/dist/commands/shadowScan.js +142 -0
  87. package/dist/commands/shadowScan.js.map +1 -0
  88. package/dist/commands/task.js +2 -2
  89. package/dist/commands/task.js.map +1 -1
  90. package/dist/commands/tools.d.ts +20 -1
  91. package/dist/commands/tools.js +112 -3
  92. package/dist/commands/tools.js.map +1 -1
  93. package/dist/commands/tracesImport.js +21 -4
  94. package/dist/commands/tracesImport.js.map +1 -1
  95. package/dist/commitIssueLinkLog.d.ts +16 -0
  96. package/dist/commitIssueLinkLog.js +110 -24
  97. package/dist/commitIssueLinkLog.js.map +1 -1
  98. package/dist/companions/registry.js +15 -7
  99. package/dist/companions/registry.js.map +1 -1
  100. package/dist/config.d.ts +47 -3
  101. package/dist/config.js +111 -21
  102. package/dist/config.js.map +1 -1
  103. package/dist/connectorRoutes.js +866 -57
  104. package/dist/connectorRoutes.js.map +1 -1
  105. package/dist/connectors/airtable.d.ts +230 -0
  106. package/dist/connectors/airtable.js +700 -0
  107. package/dist/connectors/airtable.js.map +1 -0
  108. package/dist/connectors/asana.js +13 -9
  109. package/dist/connectors/asana.js.map +1 -1
  110. package/dist/connectors/baseConnector.js +25 -3
  111. package/dist/connectors/baseConnector.js.map +1 -1
  112. package/dist/connectors/caldiy.d.ts +137 -0
  113. package/dist/connectors/caldiy.js +424 -0
  114. package/dist/connectors/caldiy.js.map +1 -0
  115. package/dist/connectors/circleci.d.ts +162 -0
  116. package/dist/connectors/circleci.js +576 -0
  117. package/dist/connectors/circleci.js.map +1 -0
  118. package/dist/connectors/cloudflare.d.ts +132 -0
  119. package/dist/connectors/cloudflare.js +622 -0
  120. package/dist/connectors/cloudflare.js.map +1 -0
  121. package/dist/connectors/confluence.js +35 -0
  122. package/dist/connectors/confluence.js.map +1 -1
  123. package/dist/connectors/connectorRedirectUri.d.ts +30 -0
  124. package/dist/connectors/connectorRedirectUri.js +38 -0
  125. package/dist/connectors/connectorRedirectUri.js.map +1 -0
  126. package/dist/connectors/connectorRegistry.d.ts +63 -0
  127. package/dist/connectors/connectorRegistry.js +354 -0
  128. package/dist/connectors/connectorRegistry.js.map +1 -0
  129. package/dist/connectors/datadog.js +33 -4
  130. package/dist/connectors/datadog.js.map +1 -1
  131. package/dist/connectors/discord.js +14 -10
  132. package/dist/connectors/discord.js.map +1 -1
  133. package/dist/connectors/elasticsearch.d.ts +141 -0
  134. package/dist/connectors/elasticsearch.js +601 -0
  135. package/dist/connectors/elasticsearch.js.map +1 -0
  136. package/dist/connectors/figma.d.ts +130 -0
  137. package/dist/connectors/figma.js +387 -0
  138. package/dist/connectors/figma.js.map +1 -0
  139. package/dist/connectors/github.d.ts +17 -0
  140. package/dist/connectors/github.js +53 -2
  141. package/dist/connectors/github.js.map +1 -1
  142. package/dist/connectors/gitlab.js +12 -6
  143. package/dist/connectors/gitlab.js.map +1 -1
  144. package/dist/connectors/gmail.js +72 -21
  145. package/dist/connectors/gmail.js.map +1 -1
  146. package/dist/connectors/googleCalendar.js +8 -8
  147. package/dist/connectors/googleCalendar.js.map +1 -1
  148. package/dist/connectors/googleDocs.d.ts +103 -0
  149. package/dist/connectors/googleDocs.js +409 -0
  150. package/dist/connectors/googleDocs.js.map +1 -0
  151. package/dist/connectors/googleDrive.d.ts +12 -0
  152. package/dist/connectors/googleDrive.js +35 -8
  153. package/dist/connectors/googleDrive.js.map +1 -1
  154. package/dist/connectors/grafana.d.ts +133 -0
  155. package/dist/connectors/grafana.js +478 -0
  156. package/dist/connectors/grafana.js.map +1 -0
  157. package/dist/connectors/jira.d.ts +25 -0
  158. package/dist/connectors/jira.js +227 -1
  159. package/dist/connectors/jira.js.map +1 -1
  160. package/dist/connectors/linear.js +1 -1
  161. package/dist/connectors/linear.js.map +1 -1
  162. package/dist/connectors/mcpOAuth.js +78 -16
  163. package/dist/connectors/mcpOAuth.js.map +1 -1
  164. package/dist/connectors/monday.d.ts +217 -0
  165. package/dist/connectors/monday.js +655 -0
  166. package/dist/connectors/monday.js.map +1 -0
  167. package/dist/connectors/mongodb.d.ts +139 -0
  168. package/dist/connectors/mongodb.js +455 -0
  169. package/dist/connectors/mongodb.js.map +1 -0
  170. package/dist/connectors/oauthStateStore.d.ts +20 -0
  171. package/dist/connectors/oauthStateStore.js +94 -4
  172. package/dist/connectors/oauthStateStore.js.map +1 -1
  173. package/dist/connectors/obsidian.d.ts +83 -0
  174. package/dist/connectors/obsidian.js +441 -0
  175. package/dist/connectors/obsidian.js.map +1 -0
  176. package/dist/connectors/paystack.d.ts +159 -0
  177. package/dist/connectors/paystack.js +607 -0
  178. package/dist/connectors/paystack.js.map +1 -0
  179. package/dist/connectors/pipedrive.d.ts +189 -0
  180. package/dist/connectors/pipedrive.js +559 -0
  181. package/dist/connectors/pipedrive.js.map +1 -0
  182. package/dist/connectors/postgres.d.ts +127 -0
  183. package/dist/connectors/postgres.js +512 -0
  184. package/dist/connectors/postgres.js.map +1 -0
  185. package/dist/connectors/posthog.d.ts +119 -0
  186. package/dist/connectors/posthog.js +479 -0
  187. package/dist/connectors/posthog.js.map +1 -0
  188. package/dist/connectors/redis.d.ts +140 -0
  189. package/dist/connectors/redis.js +571 -0
  190. package/dist/connectors/redis.js.map +1 -0
  191. package/dist/connectors/resend.d.ts +131 -0
  192. package/dist/connectors/resend.js +529 -0
  193. package/dist/connectors/resend.js.map +1 -0
  194. package/dist/connectors/salesforce.d.ts +136 -0
  195. package/dist/connectors/salesforce.js +603 -0
  196. package/dist/connectors/salesforce.js.map +1 -0
  197. package/dist/connectors/secrets.d.ts +51 -0
  198. package/dist/connectors/secrets.js +102 -0
  199. package/dist/connectors/secrets.js.map +1 -0
  200. package/dist/connectors/sendgrid.d.ts +102 -0
  201. package/dist/connectors/sendgrid.js +423 -0
  202. package/dist/connectors/sendgrid.js.map +1 -0
  203. package/dist/connectors/shopify.d.ts +145 -0
  204. package/dist/connectors/shopify.js +502 -0
  205. package/dist/connectors/shopify.js.map +1 -0
  206. package/dist/connectors/slack.d.ts +1 -1
  207. package/dist/connectors/slack.js +61 -9
  208. package/dist/connectors/slack.js.map +1 -1
  209. package/dist/connectors/snowflake.d.ts +119 -0
  210. package/dist/connectors/snowflake.js +615 -0
  211. package/dist/connectors/snowflake.js.map +1 -0
  212. package/dist/connectors/supabase.d.ts +92 -0
  213. package/dist/connectors/supabase.js +630 -0
  214. package/dist/connectors/supabase.js.map +1 -0
  215. package/dist/connectors/todoist.d.ts +117 -0
  216. package/dist/connectors/todoist.js +485 -0
  217. package/dist/connectors/todoist.js.map +1 -0
  218. package/dist/connectors/tokenStorage.js +56 -14
  219. package/dist/connectors/tokenStorage.js.map +1 -1
  220. package/dist/connectors/twilio.d.ts +118 -0
  221. package/dist/connectors/twilio.js +475 -0
  222. package/dist/connectors/twilio.js.map +1 -0
  223. package/dist/connectors/vercel.d.ts +110 -0
  224. package/dist/connectors/vercel.js +479 -0
  225. package/dist/connectors/vercel.js.map +1 -0
  226. package/dist/connectors/webflow.d.ts +118 -0
  227. package/dist/connectors/webflow.js +393 -0
  228. package/dist/connectors/webflow.js.map +1 -0
  229. package/dist/connectors/woocommerce.d.ts +220 -0
  230. package/dist/connectors/woocommerce.js +464 -0
  231. package/dist/connectors/woocommerce.js.map +1 -0
  232. package/dist/crypto.js +7 -2
  233. package/dist/crypto.js.map +1 -1
  234. package/dist/decisionReplay.js +15 -6
  235. package/dist/decisionReplay.js.map +1 -1
  236. package/dist/decisionTraceLog.d.ts +28 -0
  237. package/dist/decisionTraceLog.js +156 -29
  238. package/dist/decisionTraceLog.js.map +1 -1
  239. package/dist/drivers/claude/api.js +5 -4
  240. package/dist/drivers/claude/api.js.map +1 -1
  241. package/dist/drivers/claude/envSanitizer.d.ts +0 -6
  242. package/dist/drivers/claude/envSanitizer.js +17 -2
  243. package/dist/drivers/claude/envSanitizer.js.map +1 -1
  244. package/dist/drivers/claude/streamParser.js +5 -4
  245. package/dist/drivers/claude/streamParser.js.map +1 -1
  246. package/dist/drivers/claude/subprocess.js +22 -3
  247. package/dist/drivers/claude/subprocess.js.map +1 -1
  248. package/dist/drivers/gemini/index.d.ts +22 -0
  249. package/dist/drivers/gemini/index.js +256 -129
  250. package/dist/drivers/gemini/index.js.map +1 -1
  251. package/dist/drivers/local/index.d.ts +17 -0
  252. package/dist/drivers/local/index.js +99 -0
  253. package/dist/drivers/local/index.js.map +1 -1
  254. package/dist/drivers/openai/index.js +30 -2
  255. package/dist/drivers/openai/index.js.map +1 -1
  256. package/dist/extensionClient.d.ts +37 -4
  257. package/dist/extensionClient.js +58 -16
  258. package/dist/extensionClient.js.map +1 -1
  259. package/dist/featureFlags.d.ts +91 -0
  260. package/dist/featureFlags.js +174 -3
  261. package/dist/featureFlags.js.map +1 -1
  262. package/dist/fileLock.js +21 -12
  263. package/dist/fileLock.js.map +1 -1
  264. package/dist/fileLockSync.d.ts +67 -0
  265. package/dist/fileLockSync.js +126 -0
  266. package/dist/fileLockSync.js.map +1 -0
  267. package/dist/fp/activityAnalytics.js +26 -12
  268. package/dist/fp/activityAnalytics.js.map +1 -1
  269. package/dist/fp/automationInterpreter.d.ts +15 -1
  270. package/dist/fp/automationInterpreter.js +217 -82
  271. package/dist/fp/automationInterpreter.js.map +1 -1
  272. package/dist/fp/automationProgram.d.ts +30 -0
  273. package/dist/fp/automationProgram.js.map +1 -1
  274. package/dist/fp/automationState.d.ts +24 -5
  275. package/dist/fp/automationState.js +56 -9
  276. package/dist/fp/automationState.js.map +1 -1
  277. package/dist/fp/automationUtils.js +1 -1
  278. package/dist/fp/automationUtils.js.map +1 -1
  279. package/dist/fp/commandDescription.js +7 -1
  280. package/dist/fp/commandDescription.js.map +1 -1
  281. package/dist/fp/extensionSnapshot.js +8 -2
  282. package/dist/fp/extensionSnapshot.js.map +1 -1
  283. package/dist/fp/interpreterContext.d.ts +66 -1
  284. package/dist/fp/interpreterContext.js +91 -1
  285. package/dist/fp/interpreterContext.js.map +1 -1
  286. package/dist/fp/policyParser.js +29 -1
  287. package/dist/fp/policyParser.js.map +1 -1
  288. package/dist/fsWatchWithFallback.d.ts +36 -0
  289. package/dist/fsWatchWithFallback.js +128 -0
  290. package/dist/fsWatchWithFallback.js.map +1 -0
  291. package/dist/haltPushDispatch.d.ts +33 -0
  292. package/dist/haltPushDispatch.js +103 -0
  293. package/dist/haltPushDispatch.js.map +1 -0
  294. package/dist/httpBodyValidation.d.ts +41 -0
  295. package/dist/httpBodyValidation.js +45 -0
  296. package/dist/httpBodyValidation.js.map +1 -0
  297. package/dist/inboxRoutes.d.ts +22 -0
  298. package/dist/inboxRoutes.js +61 -1
  299. package/dist/inboxRoutes.js.map +1 -1
  300. package/dist/index.js +1053 -76
  301. package/dist/index.js.map +1 -1
  302. package/dist/installGuard.js +6 -2
  303. package/dist/installGuard.js.map +1 -1
  304. package/dist/lockfile.js +31 -4
  305. package/dist/lockfile.js.map +1 -1
  306. package/dist/oauth.d.ts +9 -0
  307. package/dist/oauth.js +33 -0
  308. package/dist/oauth.js.map +1 -1
  309. package/dist/oauthRoutes.d.ts +1 -1
  310. package/dist/oauthRoutes.js +5 -3
  311. package/dist/oauthRoutes.js.map +1 -1
  312. package/dist/orchestrator/childBridgeRegistry.js +29 -11
  313. package/dist/orchestrator/childBridgeRegistry.js.map +1 -1
  314. package/dist/patchworkConfig.d.ts +44 -1
  315. package/dist/patchworkConfig.js +28 -3
  316. package/dist/patchworkConfig.js.map +1 -1
  317. package/dist/pluginLoader.js +10 -1
  318. package/dist/pluginLoader.js.map +1 -1
  319. package/dist/pluginWatcher.js +12 -14
  320. package/dist/pluginWatcher.js.map +1 -1
  321. package/dist/preToolUseHook.js +3 -2
  322. package/dist/preToolUseHook.js.map +1 -1
  323. package/dist/processTree.d.ts +34 -0
  324. package/dist/processTree.js +105 -0
  325. package/dist/processTree.js.map +1 -0
  326. package/dist/prompts.js +3 -3
  327. package/dist/prompts.js.map +1 -1
  328. package/dist/recipeOrchestration.d.ts +9 -0
  329. package/dist/recipeOrchestration.js +341 -24
  330. package/dist/recipeOrchestration.js.map +1 -1
  331. package/dist/recipeRoutes.d.ts +58 -2
  332. package/dist/recipeRoutes.js +744 -115
  333. package/dist/recipeRoutes.js.map +1 -1
  334. package/dist/recipes/RecipeOrchestrator.d.ts +2 -0
  335. package/dist/recipes/RecipeOrchestrator.js +6 -1
  336. package/dist/recipes/RecipeOrchestrator.js.map +1 -1
  337. package/dist/recipes/agentExecutor.d.ts +25 -5
  338. package/dist/recipes/agentExecutor.js.map +1 -1
  339. package/dist/recipes/chainedRunner.d.ts +2 -0
  340. package/dist/recipes/chainedRunner.js +142 -5
  341. package/dist/recipes/chainedRunner.js.map +1 -1
  342. package/dist/recipes/connectorPreflight.d.ts +66 -0
  343. package/dist/recipes/connectorPreflight.js +169 -0
  344. package/dist/recipes/connectorPreflight.js.map +1 -0
  345. package/dist/recipes/dependencyGraph.js +13 -5
  346. package/dist/recipes/dependencyGraph.js.map +1 -1
  347. package/dist/recipes/githubInstallSource.d.ts +128 -0
  348. package/dist/recipes/githubInstallSource.js +206 -0
  349. package/dist/recipes/githubInstallSource.js.map +1 -0
  350. package/dist/recipes/haltCategory.d.ts +119 -0
  351. package/dist/recipes/haltCategory.js +188 -0
  352. package/dist/recipes/haltCategory.js.map +1 -0
  353. package/dist/recipes/idempotencyKey.d.ts +134 -0
  354. package/dist/recipes/idempotencyKey.js +322 -0
  355. package/dist/recipes/idempotencyKey.js.map +1 -0
  356. package/dist/recipes/installer.js +48 -2
  357. package/dist/recipes/installer.js.map +1 -1
  358. package/dist/recipes/judgeSummary.d.ts +50 -0
  359. package/dist/recipes/judgeSummary.js +47 -0
  360. package/dist/recipes/judgeSummary.js.map +1 -0
  361. package/dist/recipes/judgeVerdict.d.ts +48 -0
  362. package/dist/recipes/judgeVerdict.js +174 -0
  363. package/dist/recipes/judgeVerdict.js.map +1 -0
  364. package/dist/recipes/migrations/index.d.ts +9 -0
  365. package/dist/recipes/migrations/index.js +133 -0
  366. package/dist/recipes/migrations/index.js.map +1 -1
  367. package/dist/recipes/names.d.ts +20 -0
  368. package/dist/recipes/names.js +25 -0
  369. package/dist/recipes/names.js.map +1 -1
  370. package/dist/recipes/parser.js +88 -5
  371. package/dist/recipes/parser.js.map +1 -1
  372. package/dist/recipes/replayRun.js +1 -1
  373. package/dist/recipes/replayRun.js.map +1 -1
  374. package/dist/recipes/runBudget.d.ts +70 -0
  375. package/dist/recipes/runBudget.js +109 -0
  376. package/dist/recipes/runBudget.js.map +1 -0
  377. package/dist/recipes/scheduler.d.ts +30 -0
  378. package/dist/recipes/scheduler.js +69 -19
  379. package/dist/recipes/scheduler.js.map +1 -1
  380. package/dist/recipes/schema.d.ts +36 -0
  381. package/dist/recipes/schemaGenerator.js +103 -5
  382. package/dist/recipes/schemaGenerator.js.map +1 -1
  383. package/dist/recipes/stepObservation.js +9 -0
  384. package/dist/recipes/stepObservation.js.map +1 -1
  385. package/dist/recipes/toolRegistry.js +20 -3
  386. package/dist/recipes/toolRegistry.js.map +1 -1
  387. package/dist/recipes/tools/fanOut.d.ts +20 -0
  388. package/dist/recipes/tools/fanOut.js +199 -0
  389. package/dist/recipes/tools/fanOut.js.map +1 -0
  390. package/dist/recipes/tools/file.js +5 -2
  391. package/dist/recipes/tools/file.js.map +1 -1
  392. package/dist/recipes/tools/github.d.ts +1 -1
  393. package/dist/recipes/tools/github.js +75 -1
  394. package/dist/recipes/tools/github.js.map +1 -1
  395. package/dist/recipes/tools/gmail.js +27 -5
  396. package/dist/recipes/tools/gmail.js.map +1 -1
  397. package/dist/recipes/tools/googleDrive.js +64 -0
  398. package/dist/recipes/tools/googleDrive.js.map +1 -1
  399. package/dist/recipes/tools/http.d.ts +10 -0
  400. package/dist/recipes/tools/http.js +176 -0
  401. package/dist/recipes/tools/http.js.map +1 -0
  402. package/dist/recipes/tools/index.d.ts +2 -0
  403. package/dist/recipes/tools/index.js +2 -0
  404. package/dist/recipes/tools/index.js.map +1 -1
  405. package/dist/recipes/tools/slack.js +1 -1
  406. package/dist/recipes/validation.d.ts +17 -0
  407. package/dist/recipes/validation.js +29 -11
  408. package/dist/recipes/validation.js.map +1 -1
  409. package/dist/recipes/workspaceRoot.d.ts +37 -0
  410. package/dist/recipes/workspaceRoot.js +73 -0
  411. package/dist/recipes/workspaceRoot.js.map +1 -0
  412. package/dist/recipes/yamlPositions.d.ts +56 -0
  413. package/dist/recipes/yamlPositions.js +183 -0
  414. package/dist/recipes/yamlPositions.js.map +1 -0
  415. package/dist/recipes/yamlRunner.d.ts +182 -8
  416. package/dist/recipes/yamlRunner.js +877 -217
  417. package/dist/recipes/yamlRunner.js.map +1 -1
  418. package/dist/recipesHttp.d.ts +19 -3
  419. package/dist/recipesHttp.js +67 -11
  420. package/dist/recipesHttp.js.map +1 -1
  421. package/dist/resources.js +21 -13
  422. package/dist/resources.js.map +1 -1
  423. package/dist/runLog.d.ts +58 -5
  424. package/dist/runLog.js +98 -21
  425. package/dist/runLog.js.map +1 -1
  426. package/dist/sanitizeParsedJson.d.ts +39 -0
  427. package/dist/sanitizeParsedJson.js +55 -0
  428. package/dist/sanitizeParsedJson.js.map +1 -0
  429. package/dist/schemas/recipe.v1.json +885 -196
  430. package/dist/server.d.ts +160 -3
  431. package/dist/server.js +1099 -122
  432. package/dist/server.js.map +1 -1
  433. package/dist/sessionCheckpoint.d.ts +8 -0
  434. package/dist/sessionCheckpoint.js +33 -3
  435. package/dist/sessionCheckpoint.js.map +1 -1
  436. package/dist/ssrfGuard.d.ts +16 -0
  437. package/dist/ssrfGuard.js +87 -4
  438. package/dist/ssrfGuard.js.map +1 -1
  439. package/dist/streamableHttp.d.ts +9 -4
  440. package/dist/streamableHttp.js +76 -20
  441. package/dist/streamableHttp.js.map +1 -1
  442. package/dist/telemetry.js +19 -12
  443. package/dist/telemetry.js.map +1 -1
  444. package/dist/testing/shadowRun.d.ts +52 -0
  445. package/dist/testing/shadowRun.js +71 -0
  446. package/dist/testing/shadowRun.js.map +1 -0
  447. package/dist/tools/batchLsp.d.ts +3 -0
  448. package/dist/tools/bridgeDoctor.d.ts +11 -0
  449. package/dist/tools/bridgeDoctor.js +48 -2
  450. package/dist/tools/bridgeDoctor.js.map +1 -1
  451. package/dist/tools/bridgeStatus.d.ts +0 -12
  452. package/dist/tools/bridgeStatus.js +2 -28
  453. package/dist/tools/bridgeStatus.js.map +1 -1
  454. package/dist/tools/cancelClaudeTask.d.ts +1 -0
  455. package/dist/tools/clipboard.d.ts +2 -0
  456. package/dist/tools/closeTabs.d.ts +1 -0
  457. package/dist/tools/codeLens.d.ts +1 -0
  458. package/dist/tools/createIssueFromAIComment.d.ts +1 -0
  459. package/dist/tools/ctxGetTaskContext.d.ts +9 -0
  460. package/dist/tools/ctxGetTaskContext.js +50 -2
  461. package/dist/tools/ctxGetTaskContext.js.map +1 -1
  462. package/dist/tools/ctxQueryTraces.js +32 -24
  463. package/dist/tools/ctxQueryTraces.js.map +1 -1
  464. package/dist/tools/ctxSaveTrace.d.ts +1 -0
  465. package/dist/tools/debug.d.ts +4 -0
  466. package/dist/tools/decorations.d.ts +2 -0
  467. package/dist/tools/detectUnusedCode.js +9 -7
  468. package/dist/tools/detectUnusedCode.js.map +1 -1
  469. package/dist/tools/documentLinks.d.ts +1 -0
  470. package/dist/tools/editText.d.ts +1 -0
  471. package/dist/tools/editText.js +2 -1
  472. package/dist/tools/editText.js.map +1 -1
  473. package/dist/tools/enrichCommit.d.ts +1 -0
  474. package/dist/tools/enrichStackTrace.js +11 -5
  475. package/dist/tools/enrichStackTrace.js.map +1 -1
  476. package/dist/tools/explainDiagnostic.d.ts +1 -0
  477. package/dist/tools/explainSymbol.d.ts +1 -0
  478. package/dist/tools/fileOperations.d.ts +3 -0
  479. package/dist/tools/fileOperations.js +2 -1
  480. package/dist/tools/fileOperations.js.map +1 -1
  481. package/dist/tools/fileWatcher.d.ts +2 -0
  482. package/dist/tools/fileWatcher.js +8 -2
  483. package/dist/tools/fileWatcher.js.map +1 -1
  484. package/dist/tools/findFiles.d.ts +1 -0
  485. package/dist/tools/fixAllLintErrors.d.ts +1 -0
  486. package/dist/tools/fixAllLintErrors.js +10 -5
  487. package/dist/tools/fixAllLintErrors.js.map +1 -1
  488. package/dist/tools/foldingRanges.d.ts +1 -0
  489. package/dist/tools/formatDocument.d.ts +1 -0
  490. package/dist/tools/formatDocument.js +10 -5
  491. package/dist/tools/formatDocument.js.map +1 -1
  492. package/dist/tools/generateTests.d.ts +1 -0
  493. package/dist/tools/getAIComments.d.ts +1 -0
  494. package/dist/tools/getAnalyticsReport.js +5 -1
  495. package/dist/tools/getAnalyticsReport.js.map +1 -1
  496. package/dist/tools/getBufferContent.d.ts +1 -0
  497. package/dist/tools/getChangeImpact.d.ts +1 -0
  498. package/dist/tools/getChangeImpact.js +23 -14
  499. package/dist/tools/getChangeImpact.js.map +1 -1
  500. package/dist/tools/getClaudeTaskStatus.d.ts +1 -0
  501. package/dist/tools/getCodeCoverage.d.ts +1 -0
  502. package/dist/tools/getCodeCoverage.js +32 -14
  503. package/dist/tools/getCodeCoverage.js.map +1 -1
  504. package/dist/tools/getCommitsForIssue.d.ts +1 -0
  505. package/dist/tools/getDebugState.d.ts +1 -0
  506. package/dist/tools/getDiagnostics.js +32 -29
  507. package/dist/tools/getDiagnostics.js.map +1 -1
  508. package/dist/tools/getDiffFromHandoff.js +8 -2
  509. package/dist/tools/getDiffFromHandoff.js.map +1 -1
  510. package/dist/tools/getDocumentSymbols.d.ts +1 -0
  511. package/dist/tools/getGitHotspots.d.ts +1 -0
  512. package/dist/tools/getImportedSignatures.d.ts +1 -0
  513. package/dist/tools/getImportedSignatures.js +18 -14
  514. package/dist/tools/getImportedSignatures.js.map +1 -1
  515. package/dist/tools/getPRTemplate.d.ts +1 -0
  516. package/dist/tools/getProjectContext.js +23 -10
  517. package/dist/tools/getProjectContext.js.map +1 -1
  518. package/dist/tools/getSymbolHistory.d.ts +1 -0
  519. package/dist/tools/getToolCapabilities.d.ts +10 -5
  520. package/dist/tools/getToolCapabilities.js +79 -202
  521. package/dist/tools/getToolCapabilities.js.map +1 -1
  522. package/dist/tools/getTypeSignature.d.ts +1 -0
  523. package/dist/tools/getWorkspaceSettings.d.ts +1 -0
  524. package/dist/tools/gitWrite.d.ts +11 -0
  525. package/dist/tools/github/actions.d.ts +2 -0
  526. package/dist/tools/github/composite.d.ts +3 -0
  527. package/dist/tools/github/issues.d.ts +4 -0
  528. package/dist/tools/github/pr.d.ts +7 -0
  529. package/dist/tools/handoffNote.d.ts +1 -0
  530. package/dist/tools/handoffNote.js +2 -1
  531. package/dist/tools/handoffNote.js.map +1 -1
  532. package/dist/tools/headless/lspClient.js +3 -0
  533. package/dist/tools/headless/lspClient.js.map +1 -1
  534. package/dist/tools/hoverAtCursor.d.ts +1 -0
  535. package/dist/tools/httpClient.d.ts +2 -0
  536. package/dist/tools/httpClient.js +38 -71
  537. package/dist/tools/httpClient.js.map +1 -1
  538. package/dist/tools/inlayHints.d.ts +1 -0
  539. package/dist/tools/launchQuickTask.d.ts +1 -0
  540. package/dist/tools/listClaudeTasks.d.ts +1 -0
  541. package/dist/tools/listClaudeTasks.js +10 -8
  542. package/dist/tools/listClaudeTasks.js.map +1 -1
  543. package/dist/tools/listTerminals.d.ts +1 -0
  544. package/dist/tools/lsp.d.ts +15 -0
  545. package/dist/tools/lsp.js +17 -0
  546. package/dist/tools/lsp.js.map +1 -1
  547. package/dist/tools/navigateToSymbolByName.d.ts +1 -0
  548. package/dist/tools/openDiff.d.ts +1 -0
  549. package/dist/tools/openDiff.js +4 -1
  550. package/dist/tools/openDiff.js.map +1 -1
  551. package/dist/tools/openFile.d.ts +1 -0
  552. package/dist/tools/openFile.js +4 -1
  553. package/dist/tools/openFile.js.map +1 -1
  554. package/dist/tools/openInBrowser.js +6 -1
  555. package/dist/tools/openInBrowser.js.map +1 -1
  556. package/dist/tools/organizeImports.d.ts +1 -0
  557. package/dist/tools/organizeImports.js +5 -3
  558. package/dist/tools/organizeImports.js.map +1 -1
  559. package/dist/tools/performanceReport.js +5 -3
  560. package/dist/tools/performanceReport.js.map +1 -1
  561. package/dist/tools/planPersistence.d.ts +3 -0
  562. package/dist/tools/planPersistence.js +4 -1
  563. package/dist/tools/planPersistence.js.map +1 -1
  564. package/dist/tools/previewEdit.d.ts +1 -0
  565. package/dist/tools/previewEdit.js +15 -4
  566. package/dist/tools/previewEdit.js.map +1 -1
  567. package/dist/tools/recentTracesDigest.js +54 -11
  568. package/dist/tools/recentTracesDigest.js.map +1 -1
  569. package/dist/tools/refactorAnalyze.d.ts +1 -0
  570. package/dist/tools/refactorExtractFunction.js +4 -1
  571. package/dist/tools/refactorExtractFunction.js.map +1 -1
  572. package/dist/tools/refactorPreview.d.ts +1 -0
  573. package/dist/tools/refactorPreview.js +10 -2
  574. package/dist/tools/refactorPreview.js.map +1 -1
  575. package/dist/tools/replaceBlock.d.ts +1 -0
  576. package/dist/tools/replaceBlock.js +2 -1
  577. package/dist/tools/replaceBlock.js.map +1 -1
  578. package/dist/tools/resumeClaudeTask.d.ts +1 -0
  579. package/dist/tools/runClaudeTask.d.ts +1 -0
  580. package/dist/tools/runTests.js +15 -4
  581. package/dist/tools/runTests.js.map +1 -1
  582. package/dist/tools/screenshot.d.ts +1 -0
  583. package/dist/tools/screenshotAndAnnotate.js +6 -2
  584. package/dist/tools/screenshotAndAnnotate.js.map +1 -1
  585. package/dist/tools/searchAndReplace.d.ts +1 -0
  586. package/dist/tools/searchAndReplace.js +17 -7
  587. package/dist/tools/searchAndReplace.js.map +1 -1
  588. package/dist/tools/searchTools.js +20 -19
  589. package/dist/tools/searchTools.js.map +1 -1
  590. package/dist/tools/searchWorkspace.d.ts +1 -0
  591. package/dist/tools/selectionRanges.d.ts +1 -0
  592. package/dist/tools/semanticTokens.d.ts +1 -0
  593. package/dist/tools/signatureHelp.d.ts +1 -0
  594. package/dist/tools/spawnWorkspace.js +15 -7
  595. package/dist/tools/spawnWorkspace.js.map +1 -1
  596. package/dist/tools/terminal.d.ts +6 -0
  597. package/dist/tools/testRunners/pytest.js +6 -2
  598. package/dist/tools/testRunners/pytest.js.map +1 -1
  599. package/dist/tools/testRunners/vitestJest.js +3 -1
  600. package/dist/tools/testRunners/vitestJest.js.map +1 -1
  601. package/dist/tools/testTraceToSource.d.ts +1 -0
  602. package/dist/tools/transaction.d.ts +4 -0
  603. package/dist/tools/transaction.js +4 -1
  604. package/dist/tools/transaction.js.map +1 -1
  605. package/dist/tools/typeHierarchy.d.ts +1 -0
  606. package/dist/tools/utils.d.ts +18 -0
  607. package/dist/tools/utils.js +103 -18
  608. package/dist/tools/utils.js.map +1 -1
  609. package/dist/tools/vscodeCommands.d.ts +2 -0
  610. package/dist/tools/vscodeTasks.d.ts +2 -0
  611. package/dist/tools/workspaceSettings.d.ts +1 -0
  612. package/dist/transport.d.ts +3 -1
  613. package/dist/transport.js +103 -52
  614. package/dist/transport.js.map +1 -1
  615. package/dist/winShim.d.ts +34 -0
  616. package/dist/winShim.js +94 -0
  617. package/dist/winShim.js.map +1 -0
  618. package/dist/wireHaltPushDispatch.d.ts +38 -0
  619. package/dist/wireHaltPushDispatch.js +71 -0
  620. package/dist/wireHaltPushDispatch.js.map +1 -0
  621. package/dist/writeFileAtomic.d.ts +23 -0
  622. package/dist/writeFileAtomic.js +121 -0
  623. package/dist/writeFileAtomic.js.map +1 -0
  624. package/package.json +23 -7
  625. package/scripts/postinstall.mjs +42 -2
  626. package/scripts/smoke/run-all.mjs +213 -0
  627. package/scripts/start-all.mjs +572 -0
  628. package/scripts/start-all.ps1 +209 -0
  629. package/scripts/start-all.sh +73 -17
  630. package/scripts/start-orchestrator.ps1 +158 -0
  631. package/scripts/start-remote.mjs +122 -0
  632. package/templates/automation-policies/recipe-authoring.json +1 -1
  633. package/templates/automation-policies/security-first.json +1 -1
  634. package/templates/automation-policies/strict-lint.json +1 -1
  635. package/templates/automation-policies/test-driven.json +1 -1
  636. package/templates/automation-policy.example.json +1 -1
  637. package/templates/co.patchwork-os.bridge.plist +2 -2
  638. package/templates/recipes/approval-queue-ui-test.yaml +1 -1
  639. package/templates/recipes/ctx-loop-test.yaml +1 -1
  640. package/templates/recipes/fix-errors-on-save.yaml +71 -0
  641. package/templates/recipes/morning-brief.yaml +5 -2
  642. package/templates/recipes/project-health-check.yaml +4 -1
  643. package/templates/recipes/sentry-to-linear.yaml +72 -38
  644. package/templates/recipes/webhook/apple-watch-health-log.yaml +145 -0
  645. package/templates/recipes/webhook/customer-escalation.yaml +8 -9
  646. package/templates/recipes/webhook/meeting-prep.yaml +11 -5
  647. package/dist/commands/marketplace.d.ts +0 -16
  648. package/dist/commands/marketplace.js +0 -32
  649. package/dist/commands/marketplace.js.map +0 -1
  650. package/dist/recipes/legacyRecipeCompat.d.ts +0 -10
  651. package/dist/recipes/legacyRecipeCompat.js +0 -131
  652. package/dist/recipes/legacyRecipeCompat.js.map +0 -1
@@ -0,0 +1,102 @@
1
+ /**
2
+ * On-disk config for the opt-in telemetry collector (endpoint + shared secret).
3
+ *
4
+ * Lives at ~/.claude/ide/analytics-config.json (respects CLAUDE_CONFIG_DIR).
5
+ * Mode 0600. Atomic writes via temp + rename.
6
+ *
7
+ * Resolution order in analyticsSend.ts:
8
+ * 1. process.env.PATCHWORK_ANALYTICS_ENDPOINT / _KEY (highest)
9
+ * 2. this file
10
+ * 3. upstream default (no key)
11
+ *
12
+ * Reason for the file: keeps the shared secret out of launchd plists
13
+ * (which are Time-Machine backed, iCloud synced, and survive reinstalls
14
+ * in an inconsistent way) and gives operators a single source of truth
15
+ * managed by the `patchwork analytics configure` CLI.
16
+ */
17
+ import fs from "node:fs";
18
+ import os from "node:os";
19
+ import path from "node:path";
20
+ export function configPath() {
21
+ const claudeDir = process.env.CLAUDE_CONFIG_DIR ?? path.join(os.homedir(), ".claude");
22
+ return path.join(claudeDir, "ide", "analytics-config.json");
23
+ }
24
+ function isValidEndpoint(value) {
25
+ if (typeof value !== "string" || value.length === 0)
26
+ return false;
27
+ try {
28
+ const u = new URL(value);
29
+ return u.protocol === "http:" || u.protocol === "https:";
30
+ }
31
+ catch {
32
+ return false;
33
+ }
34
+ }
35
+ /** Read the config file. Returns empty object on missing/invalid file. */
36
+ export function getAnalyticsConfig() {
37
+ try {
38
+ const raw = fs.readFileSync(configPath(), "utf-8");
39
+ const obj = JSON.parse(raw);
40
+ if (typeof obj !== "object" || obj === null)
41
+ return {};
42
+ const rec = obj;
43
+ const out = {};
44
+ if (isValidEndpoint(rec.endpoint))
45
+ out.endpoint = rec.endpoint;
46
+ if (typeof rec.key === "string" && rec.key.length > 0)
47
+ out.key = rec.key;
48
+ return out;
49
+ }
50
+ catch {
51
+ return {};
52
+ }
53
+ }
54
+ /**
55
+ * Atomic write with mode 0600. Merges with existing config — pass
56
+ * `{ endpoint: undefined }` to clear a field explicitly.
57
+ */
58
+ export function setAnalyticsConfig(update) {
59
+ const current = getAnalyticsConfig();
60
+ const next = { ...current };
61
+ if ("endpoint" in update) {
62
+ if (update.endpoint === undefined)
63
+ delete next.endpoint;
64
+ else if (isValidEndpoint(update.endpoint))
65
+ next.endpoint = update.endpoint;
66
+ else
67
+ throw new Error(`invalid endpoint (must be http(s) URL): ${update.endpoint}`);
68
+ }
69
+ if ("key" in update) {
70
+ if (update.key === undefined)
71
+ delete next.key;
72
+ else
73
+ next.key = update.key;
74
+ }
75
+ const p = configPath();
76
+ fs.mkdirSync(path.dirname(p), { recursive: true });
77
+ const tmp = `${p}.tmp.${process.pid}`;
78
+ fs.writeFileSync(tmp, JSON.stringify(next, null, 2) + "\n", { mode: 0o600 });
79
+ // On Windows, renameSync throws EEXIST when target exists; POSIX atomically replaces.
80
+ try {
81
+ fs.renameSync(tmp, p);
82
+ }
83
+ catch (renameErr) {
84
+ if (process.platform === "win32" &&
85
+ renameErr.code === "EEXIST") {
86
+ fs.unlinkSync(p);
87
+ fs.renameSync(tmp, p);
88
+ }
89
+ else {
90
+ throw renameErr;
91
+ }
92
+ }
93
+ }
94
+ export function clearAnalyticsConfig() {
95
+ try {
96
+ fs.unlinkSync(configPath());
97
+ }
98
+ catch {
99
+ /* file may not exist */
100
+ }
101
+ }
102
+ //# sourceMappingURL=analyticsConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyticsConfig.js","sourceRoot":"","sources":["../src/analyticsConfig.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,46 @@
1
1
  /**
2
- * Reads and writes the opt-in analytics preference.
2
+ * Reads and writes the opt-in telemetry preferences.
3
3
  * Stored in ~/.claude/ide/analytics.json (respects CLAUDE_CONFIG_DIR).
4
4
  * File created with 0o600 permissions (owner read/write only).
5
5
  */
6
+ export interface TelemetryPrefs {
7
+ crashReports: boolean;
8
+ usageStats: boolean;
9
+ localDiagnostics: boolean;
10
+ }
11
+ interface PrefsFileV2 {
12
+ crashReports: boolean;
13
+ usageStats: boolean;
14
+ localDiagnostics: boolean;
15
+ decidedAt: string;
16
+ lastSentAt?: string;
17
+ }
18
+ /** Public paths for the /telemetry-prefs DELETE handler. */
19
+ export declare function getAnalyticsPrefsPath(): string;
20
+ export declare function getAnalyticsSaltPath(): string;
21
+ /**
22
+ * Read and migrate the on-disk prefs to the v2 shape.
23
+ * Old files with only `enabled` map to:
24
+ * { crashReports: enabled, usageStats: enabled, localDiagnostics: false }
25
+ */
26
+ export declare function getTelemetryPrefs(): TelemetryPrefs;
27
+ /** Partial-merge update. Reads current prefs, applies supplied fields, writes back. */
28
+ export declare function setTelemetryPrefs(prefs: Partial<TelemetryPrefs>): void;
29
+ /**
30
+ * Returns the raw prefs file contents including optional `lastSentAt` timestamp.
31
+ * Returns null when no prefs file exists yet.
32
+ */
33
+ export declare function getAnalyticsPrefsAll(): (PrefsFileV2 & {
34
+ lastSentAt?: string;
35
+ }) | null;
36
+ /**
37
+ * Records the current time as `lastSentAt` in the prefs file.
38
+ * No-op if no prefs file exists yet (user never opted in, nothing to record).
39
+ */
40
+ export declare function recordAnalyticsSent(): void;
6
41
  /** Returns the current opt-in state, or null if no preference has been set. */
7
42
  export declare function getAnalyticsPref(): boolean | null;
8
- /** Persists the opt-in preference. Creates file with 0o600 permissions. */
43
+ /** Persists the opt-in preference (legacy single-boolean form). */
9
44
  export declare function setAnalyticsPref(enabled: boolean): void;
10
45
  /**
11
46
  * Returns the per-install salt used to hash plugin tool names before they're
@@ -18,3 +53,4 @@ export declare function setAnalyticsPref(enabled: boolean): void;
18
53
  * on different machines.
19
54
  */
20
55
  export declare function getAnalyticsSalt(): string;
56
+ export {};
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Reads and writes the opt-in analytics preference.
2
+ * Reads and writes the opt-in telemetry preferences.
3
3
  * Stored in ~/.claude/ide/analytics.json (respects CLAUDE_CONFIG_DIR).
4
4
  * File created with 0o600 permissions (owner read/write only).
5
5
  */
@@ -7,6 +7,25 @@ import crypto from "node:crypto";
7
7
  import fs from "node:fs";
8
8
  import os from "node:os";
9
9
  import path from "node:path";
10
+ /**
11
+ * Atomic rename helper: on Windows `renameSync` throws EEXIST when the target
12
+ * already exists (unlike POSIX which replaces atomically). Unlink + retry once.
13
+ */
14
+ function atomicRename(tmp, target) {
15
+ try {
16
+ fs.renameSync(tmp, target);
17
+ }
18
+ catch (err) {
19
+ if (process.platform === "win32" &&
20
+ err.code === "EEXIST") {
21
+ fs.unlinkSync(target);
22
+ fs.renameSync(tmp, target);
23
+ }
24
+ else {
25
+ throw err;
26
+ }
27
+ }
28
+ }
10
29
  function prefsPath() {
11
30
  const claudeDir = process.env.CLAUDE_CONFIG_DIR ?? path.join(os.homedir(), ".claude");
12
31
  return path.join(claudeDir, "ide", "analytics.json");
@@ -15,42 +34,148 @@ function saltPath() {
15
34
  const claudeDir = process.env.CLAUDE_CONFIG_DIR ?? path.join(os.homedir(), ".claude");
16
35
  return path.join(claudeDir, "ide", "analytics-salt");
17
36
  }
18
- /** Returns the current opt-in state, or null if no preference has been set. */
19
- export function getAnalyticsPref() {
37
+ /** Public paths for the /telemetry-prefs DELETE handler. */
38
+ export function getAnalyticsPrefsPath() {
39
+ return prefsPath();
40
+ }
41
+ export function getAnalyticsSaltPath() {
42
+ return saltPath();
43
+ }
44
+ /**
45
+ * Read and migrate the on-disk prefs to the v2 shape.
46
+ * Old files with only `enabled` map to:
47
+ * { crashReports: enabled, usageStats: enabled, localDiagnostics: false }
48
+ */
49
+ export function getTelemetryPrefs() {
20
50
  const p = prefsPath();
21
51
  try {
22
52
  const raw = fs.readFileSync(p, "utf-8");
23
53
  const obj = JSON.parse(raw);
24
- if (typeof obj === "object" &&
25
- obj !== null &&
26
- "enabled" in obj &&
27
- typeof obj.enabled === "boolean") {
28
- return obj.enabled;
54
+ if (typeof obj !== "object" || obj === null) {
55
+ return {
56
+ crashReports: false,
57
+ usageStats: false,
58
+ localDiagnostics: false,
59
+ };
29
60
  }
30
- return null;
61
+ const rec = obj;
62
+ // v2 shape
63
+ if (typeof rec.crashReports === "boolean") {
64
+ return {
65
+ crashReports: rec.crashReports,
66
+ usageStats: typeof rec.usageStats === "boolean" ? rec.usageStats : false,
67
+ localDiagnostics: typeof rec.localDiagnostics === "boolean"
68
+ ? rec.localDiagnostics
69
+ : false,
70
+ };
71
+ }
72
+ // v1 migration — `enabled` only
73
+ if (typeof rec.enabled === "boolean") {
74
+ return {
75
+ crashReports: rec.enabled,
76
+ usageStats: rec.enabled,
77
+ localDiagnostics: false,
78
+ };
79
+ }
80
+ return { crashReports: false, usageStats: false, localDiagnostics: false };
31
81
  }
32
- catch (err) {
33
- const code = err.code;
34
- if (code === "ENOENT")
35
- return null;
36
- return null;
82
+ catch (_err) {
83
+ return { crashReports: false, usageStats: false, localDiagnostics: false };
37
84
  }
38
85
  }
39
- /** Persists the opt-in preference. Creates file with 0o600 permissions. */
40
- export function setAnalyticsPref(enabled) {
86
+ /** Partial-merge update. Reads current prefs, applies supplied fields, writes back. */
87
+ export function setTelemetryPrefs(prefs) {
88
+ const current = getTelemetryPrefs();
89
+ const next = {
90
+ crashReports: prefs.crashReports !== undefined
91
+ ? prefs.crashReports
92
+ : current.crashReports,
93
+ usageStats: prefs.usageStats !== undefined ? prefs.usageStats : current.usageStats,
94
+ localDiagnostics: prefs.localDiagnostics !== undefined
95
+ ? prefs.localDiagnostics
96
+ : current.localDiagnostics,
97
+ decidedAt: new Date().toISOString(),
98
+ };
99
+ writePrefs(next);
100
+ }
101
+ function writePrefs(content) {
41
102
  const p = prefsPath();
42
103
  const dir = path.dirname(p);
43
104
  fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
44
- const content = {
45
- enabled,
46
- decidedAt: new Date().toISOString(),
47
- };
48
- // Write to temp file then rename for atomicity
49
105
  const tmp = `${p}.tmp`;
50
106
  fs.writeFileSync(tmp, `${JSON.stringify(content, null, 2)}\n`, {
51
107
  mode: 0o600,
52
108
  });
53
- fs.renameSync(tmp, p);
109
+ atomicRename(tmp, p);
110
+ }
111
+ /**
112
+ * Returns the raw prefs file contents including optional `lastSentAt` timestamp.
113
+ * Returns null when no prefs file exists yet.
114
+ */
115
+ export function getAnalyticsPrefsAll() {
116
+ const p = prefsPath();
117
+ try {
118
+ const raw = fs.readFileSync(p, "utf-8");
119
+ const obj = JSON.parse(raw);
120
+ if (typeof obj === "object" && obj !== null) {
121
+ return obj;
122
+ }
123
+ return null;
124
+ }
125
+ catch (err) {
126
+ const code = err.code;
127
+ if (code === "ENOENT")
128
+ return null;
129
+ return null;
130
+ }
131
+ }
132
+ /**
133
+ * Records the current time as `lastSentAt` in the prefs file.
134
+ * No-op if no prefs file exists yet (user never opted in, nothing to record).
135
+ */
136
+ export function recordAnalyticsSent() {
137
+ const p = prefsPath();
138
+ try {
139
+ const raw = fs.readFileSync(p, "utf-8");
140
+ const obj = JSON.parse(raw);
141
+ if (typeof obj === "object" && obj !== null) {
142
+ const updated = {
143
+ ...obj,
144
+ lastSentAt: new Date().toISOString(),
145
+ };
146
+ const dir = path.dirname(p);
147
+ fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
148
+ const tmp = `${p}.tmp`;
149
+ fs.writeFileSync(tmp, `${JSON.stringify(updated, null, 2)}\n`, {
150
+ mode: 0o600,
151
+ });
152
+ atomicRename(tmp, p);
153
+ }
154
+ }
155
+ catch {
156
+ // No prefs file or unreadable — nothing to update
157
+ }
158
+ }
159
+ // ---------------------------------------------------------------------------
160
+ // Legacy API — kept for callers that predate the three-flag shape.
161
+ // Derived from usageStats so existing analytics collection doesn't change.
162
+ // ---------------------------------------------------------------------------
163
+ /** Returns the current opt-in state, or null if no preference has been set. */
164
+ export function getAnalyticsPref() {
165
+ const p = prefsPath();
166
+ try {
167
+ const raw = fs.readFileSync(p, "utf-8");
168
+ JSON.parse(raw);
169
+ }
170
+ catch {
171
+ return null;
172
+ }
173
+ const prefs = getTelemetryPrefs();
174
+ return prefs.usageStats;
175
+ }
176
+ /** Persists the opt-in preference (legacy single-boolean form). */
177
+ export function setAnalyticsPref(enabled) {
178
+ setTelemetryPrefs({ usageStats: enabled, crashReports: enabled });
54
179
  }
55
180
  /**
56
181
  * Returns the per-install salt used to hash plugin tool names before they're
@@ -77,7 +202,7 @@ export function getAnalyticsSalt() {
77
202
  const salt = crypto.randomBytes(16).toString("hex");
78
203
  const tmp = `${p}.tmp`;
79
204
  fs.writeFileSync(tmp, `${salt}\n`, { mode: 0o600 });
80
- fs.renameSync(tmp, p);
205
+ atomicRename(tmp, p);
81
206
  return salt;
82
207
  }
83
208
  //# sourceMappingURL=analyticsPrefs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"analyticsPrefs.js","sourceRoot":"","sources":["../src/analyticsPrefs.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"analyticsPrefs.js","sourceRoot":"","sources":["../src/analyticsPrefs.ts"],"names":[],"mappings":"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"}
@@ -2,9 +2,25 @@
2
2
  * Sends an anonymized analytics summary to the usage endpoint.
3
3
  * - Fire-and-forget is NOT used: callers must await this with a timeout race.
4
4
  * - All errors are caught and swallowed — telemetry must never affect bridge operation.
5
- * - Endpoint is hardcoded (not runtime-configurable) to prevent redirect attacks.
5
+ * - Endpoint defaults to the upstream collector. Operators may override via:
6
+ * 1. env: PATCHWORK_ANALYTICS_ENDPOINT (highest precedence; for CI/headless)
7
+ * 2. config file: ~/.claude/ide/analytics-config.json (preferred — managed by
8
+ * `patchwork analytics configure`, keeps secrets out of launchd plists)
9
+ * 3. default upstream collector
10
+ * Endpoint is resolved per-call (cheap fs read) so live config changes take
11
+ * effect on the next send without restart. Invalid values fall back through.
12
+ * Never read from the network or summary payload — preserves the
13
+ * redirect-attack property the original hardcoded constant was protecting.
6
14
  */
7
15
  import type { AnalyticsSummary } from "./analyticsAggregator.js";
16
+ export declare function resolveAnalyticsTarget(): {
17
+ endpoint: string;
18
+ key: string | undefined;
19
+ source: {
20
+ endpoint: "env" | "config" | "default";
21
+ key: "env" | "config" | "none";
22
+ };
23
+ };
8
24
  /**
9
25
  * Sends the summary to the analytics endpoint.
10
26
  * Resolves (never rejects) — all errors are swallowed silently.
@@ -2,10 +2,63 @@
2
2
  * Sends an anonymized analytics summary to the usage endpoint.
3
3
  * - Fire-and-forget is NOT used: callers must await this with a timeout race.
4
4
  * - All errors are caught and swallowed — telemetry must never affect bridge operation.
5
- * - Endpoint is hardcoded (not runtime-configurable) to prevent redirect attacks.
5
+ * - Endpoint defaults to the upstream collector. Operators may override via:
6
+ * 1. env: PATCHWORK_ANALYTICS_ENDPOINT (highest precedence; for CI/headless)
7
+ * 2. config file: ~/.claude/ide/analytics-config.json (preferred — managed by
8
+ * `patchwork analytics configure`, keeps secrets out of launchd plists)
9
+ * 3. default upstream collector
10
+ * Endpoint is resolved per-call (cheap fs read) so live config changes take
11
+ * effect on the next send without restart. Invalid values fall back through.
12
+ * Never read from the network or summary payload — preserves the
13
+ * redirect-attack property the original hardcoded constant was protecting.
6
14
  */
7
- /** Hardcoded endpoint not configurable at runtime. */
8
- const ANALYTICS_ENDPOINT = "https://analytics.claude-ide-bridge.dev/v1/usage";
15
+ import { getAnalyticsConfig } from "./analyticsConfig.js";
16
+ import { recordAnalyticsSent } from "./analyticsPrefs.js";
17
+ const DEFAULT_ENDPOINT = "https://analytics.claude-ide-bridge.dev/v1/usage";
18
+ function validUrl(value) {
19
+ if (!value)
20
+ return undefined;
21
+ try {
22
+ const u = new URL(value);
23
+ if (u.protocol !== "https:" && u.protocol !== "http:")
24
+ return undefined;
25
+ return u.toString();
26
+ }
27
+ catch {
28
+ return undefined;
29
+ }
30
+ }
31
+ export function resolveAnalyticsTarget() {
32
+ const envEndpoint = validUrl(process.env.PATCHWORK_ANALYTICS_ENDPOINT);
33
+ const envKey = process.env.PATCHWORK_ANALYTICS_KEY;
34
+ const cfg = getAnalyticsConfig();
35
+ const cfgEndpoint = validUrl(cfg.endpoint);
36
+ let endpoint = DEFAULT_ENDPOINT;
37
+ let endpointSource = "default";
38
+ if (envEndpoint) {
39
+ endpoint = envEndpoint;
40
+ endpointSource = "env";
41
+ }
42
+ else if (cfgEndpoint) {
43
+ endpoint = cfgEndpoint;
44
+ endpointSource = "config";
45
+ }
46
+ let key;
47
+ let keySource = "none";
48
+ if (envKey) {
49
+ key = envKey;
50
+ keySource = "env";
51
+ }
52
+ else if (cfg.key) {
53
+ key = cfg.key;
54
+ keySource = "config";
55
+ }
56
+ return {
57
+ endpoint,
58
+ key,
59
+ source: { endpoint: endpointSource, key: keySource },
60
+ };
61
+ }
9
62
  const SEND_TIMEOUT_MS = 3000;
10
63
  /**
11
64
  * Sends the summary to the analytics endpoint.
@@ -13,15 +66,24 @@ const SEND_TIMEOUT_MS = 3000;
13
66
  */
14
67
  export async function sendAnalytics(summary) {
15
68
  try {
69
+ const { endpoint, key } = resolveAnalyticsTarget();
16
70
  const controller = new AbortController();
17
71
  const timer = setTimeout(() => controller.abort(), SEND_TIMEOUT_MS);
18
72
  try {
19
- await fetch(ANALYTICS_ENDPOINT, {
73
+ const headers = {
74
+ "Content-Type": "application/json",
75
+ };
76
+ if (key)
77
+ headers["X-Analytics-Key"] = key;
78
+ const res = await fetch(endpoint, {
20
79
  method: "POST",
21
- headers: { "Content-Type": "application/json" },
80
+ headers,
22
81
  body: JSON.stringify(summary),
23
82
  signal: controller.signal,
24
83
  });
84
+ if (res.ok) {
85
+ recordAnalyticsSent();
86
+ }
25
87
  }
26
88
  finally {
27
89
  clearTimeout(timer);
@@ -1 +1 @@
1
- {"version":3,"file":"analyticsSend.js","sourceRoot":"","sources":["../src/analyticsSend.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,wDAAwD;AACxD,MAAM,kBAAkB,GAAG,kDAAkD,CAAC;AAE9E,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAyB;IAC3D,IAAI,CAAC;QACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,eAAe,CAAC,CAAC;QACpE,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,kBAAkB,EAAE;gBAC9B,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;gBAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;QACL,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,yEAAyE;IAC3E,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"analyticsSend.js","sourceRoot":"","sources":["../src/analyticsSend.ts"],"names":[],"mappings":"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"}
@@ -39,6 +39,20 @@ export interface ApprovalHttpDeps {
39
39
  pushServiceToken?: string;
40
40
  /** Public base URL of this bridge (e.g. https://mybridge.example.com). Embedded in push payload as callback base. */
41
41
  pushServiceBaseUrl?: string;
42
+ /**
43
+ * ntfy.sh topic for direct phone-path approvals via action buttons. When set
44
+ * AND `pushServiceBaseUrl` is set (so the action URLs can reach the bridge),
45
+ * each queued approval is published to the topic with Approve / Reject HTTP
46
+ * action buttons that POST back to the bridge with the single-use approval
47
+ * token. Independent of `pushServiceUrl` — ntfy can be the sole phone path
48
+ * (no FCM/APNS relay needed) or run alongside it.
49
+ */
50
+ ntfyTopic?: string;
51
+ /**
52
+ * ntfy server. Defaults to `https://ntfy.sh`. Set to a self-hosted instance
53
+ * (e.g. `https://ntfy.your-domain.tld`) for auth/private-topic deployments.
54
+ */
55
+ ntfyServer?: string;
42
56
  /**
43
57
  * Optional ActivityLog used to compute passive risk personalization
44
58
  * signals (`src/approvalSignals.ts`). When omitted, personalSignals are