workos 0.17.1 → 0.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (366) hide show
  1. package/README.md +11 -149
  2. package/dist/bin.js +155 -23
  3. package/dist/bin.js.map +1 -1
  4. package/dist/cli.config.d.ts +0 -2
  5. package/dist/cli.config.js +3 -3
  6. package/dist/cli.config.js.map +1 -1
  7. package/dist/commands/api/index.js +18 -10
  8. package/dist/commands/api/index.js.map +1 -1
  9. package/dist/commands/api/interactive.js +11 -11
  10. package/dist/commands/api/interactive.js.map +1 -1
  11. package/dist/commands/claim.js +28 -16
  12. package/dist/commands/claim.js.map +1 -1
  13. package/dist/commands/connection.js +3 -3
  14. package/dist/commands/connection.js.map +1 -1
  15. package/dist/commands/debug.d.ts +11 -0
  16. package/dist/commands/debug.js +30 -14
  17. package/dist/commands/debug.js.map +1 -1
  18. package/dist/commands/dev.d.ts +7 -8
  19. package/dist/commands/dev.js +14 -14
  20. package/dist/commands/dev.js.map +1 -1
  21. package/dist/commands/directory.js +3 -3
  22. package/dist/commands/directory.js.map +1 -1
  23. package/dist/commands/doctor.js +2 -2
  24. package/dist/commands/doctor.js.map +1 -1
  25. package/dist/commands/emulate.d.ts +1 -0
  26. package/dist/commands/emulate.js +3 -2
  27. package/dist/commands/emulate.js.map +1 -1
  28. package/dist/commands/env.d.ts +10 -0
  29. package/dist/commands/env.js +94 -18
  30. package/dist/commands/env.js.map +1 -1
  31. package/dist/commands/install.js +9 -10
  32. package/dist/commands/install.js.map +1 -1
  33. package/dist/commands/login.d.ts +25 -15
  34. package/dist/commands/login.js +126 -71
  35. package/dist/commands/login.js.map +1 -1
  36. package/dist/commands/logout.js +4 -4
  37. package/dist/commands/logout.js.map +1 -1
  38. package/dist/commands/mcp.d.ts +14 -0
  39. package/dist/commands/mcp.js +99 -0
  40. package/dist/commands/mcp.js.map +1 -0
  41. package/dist/commands/migrations.js +2 -1
  42. package/dist/commands/migrations.js.map +1 -1
  43. package/dist/commands/seed.js +5 -4
  44. package/dist/commands/seed.js.map +1 -1
  45. package/dist/commands/setup.d.ts +50 -0
  46. package/dist/commands/setup.js +237 -0
  47. package/dist/commands/setup.js.map +1 -0
  48. package/dist/commands/vault-run.js +3 -2
  49. package/dist/commands/vault-run.js.map +1 -1
  50. package/dist/commands/verify-login.d.ts +25 -0
  51. package/dist/commands/verify-login.js +158 -0
  52. package/dist/commands/verify-login.js.map +1 -0
  53. package/dist/doctor/checks/ai-analysis.js +2 -1
  54. package/dist/doctor/checks/ai-analysis.js.map +1 -1
  55. package/dist/doctor/checks/mcp.d.ts +15 -0
  56. package/dist/doctor/checks/mcp.js +34 -0
  57. package/dist/doctor/checks/mcp.js.map +1 -0
  58. package/dist/doctor/index.js +7 -1
  59. package/dist/doctor/index.js.map +1 -1
  60. package/dist/doctor/issues.js +18 -1
  61. package/dist/doctor/issues.js.map +1 -1
  62. package/dist/doctor/output.js +18 -3
  63. package/dist/doctor/output.js.map +1 -1
  64. package/dist/doctor/types.d.ts +17 -0
  65. package/dist/doctor/types.js.map +1 -1
  66. package/dist/integrations/dotnet/index.js +1 -1
  67. package/dist/integrations/dotnet/index.js.map +1 -1
  68. package/dist/integrations/elixir/index.js +1 -1
  69. package/dist/integrations/elixir/index.js.map +1 -1
  70. package/dist/integrations/go/index.js +1 -1
  71. package/dist/integrations/go/index.js.map +1 -1
  72. package/dist/integrations/nextjs/index.js +8 -5
  73. package/dist/integrations/nextjs/index.js.map +1 -1
  74. package/dist/integrations/nextjs/utils.d.ts +1 -1
  75. package/dist/integrations/nextjs/utils.js +21 -6
  76. package/dist/integrations/nextjs/utils.js.map +1 -1
  77. package/dist/integrations/react-router/index.js +5 -5
  78. package/dist/integrations/react-router/index.js.map +1 -1
  79. package/dist/integrations/react-router/utils.js +28 -12
  80. package/dist/integrations/react-router/utils.js.map +1 -1
  81. package/dist/integrations/ruby/index.js +1 -1
  82. package/dist/integrations/ruby/index.js.map +1 -1
  83. package/dist/lib/adapters/cli-adapter.d.ts +33 -4
  84. package/dist/lib/adapters/cli-adapter.js +251 -135
  85. package/dist/lib/adapters/cli-adapter.js.map +1 -1
  86. package/dist/lib/adapters/dashboard-adapter.js +3 -3
  87. package/dist/lib/adapters/dashboard-adapter.js.map +1 -1
  88. package/dist/lib/adapters/headless-adapter.d.ts +7 -0
  89. package/dist/lib/adapters/headless-adapter.js +42 -5
  90. package/dist/lib/adapters/headless-adapter.js.map +1 -1
  91. package/dist/lib/agent-interface.js +19 -5
  92. package/dist/lib/agent-interface.js.map +1 -1
  93. package/dist/lib/agent-runner.js +1 -1
  94. package/dist/lib/agent-runner.js.map +1 -1
  95. package/dist/lib/ai-content.js +2 -1
  96. package/dist/lib/ai-content.js.map +1 -1
  97. package/dist/lib/api-key.js +2 -1
  98. package/dist/lib/api-key.js.map +1 -1
  99. package/dist/lib/completion-data.d.ts +33 -0
  100. package/dist/lib/completion-data.js +33 -0
  101. package/dist/lib/completion-data.js.map +1 -0
  102. package/dist/lib/config-store.d.ts +13 -0
  103. package/dist/lib/config-store.js +24 -0
  104. package/dist/lib/config-store.js.map +1 -1
  105. package/dist/lib/config.d.ts +1 -1
  106. package/dist/lib/config.js +1 -1
  107. package/dist/lib/config.js.map +1 -1
  108. package/dist/lib/constants.d.ts +17 -0
  109. package/dist/lib/constants.js +17 -0
  110. package/dist/lib/constants.js.map +1 -1
  111. package/dist/lib/events.d.ts +34 -1
  112. package/dist/lib/events.js.map +1 -1
  113. package/dist/lib/framework-config.d.ts +6 -0
  114. package/dist/lib/framework-config.js.map +1 -1
  115. package/dist/lib/installer-core.d.ts +34 -21
  116. package/dist/lib/installer-core.js +24 -5
  117. package/dist/lib/installer-core.js.map +1 -1
  118. package/dist/lib/installer-core.types.d.ts +3 -1
  119. package/dist/lib/installer-core.types.js.map +1 -1
  120. package/dist/lib/mcp-clients.d.ts +45 -0
  121. package/dist/lib/mcp-clients.js +297 -0
  122. package/dist/lib/mcp-clients.js.map +1 -0
  123. package/dist/lib/port-detection.js +19 -13
  124. package/dist/lib/port-detection.js.map +1 -1
  125. package/dist/lib/preferences.d.ts +42 -0
  126. package/dist/lib/preferences.js +34 -5
  127. package/dist/lib/preferences.js.map +1 -1
  128. package/dist/lib/run-with-core.js +42 -4
  129. package/dist/lib/run-with-core.js.map +1 -1
  130. package/dist/lib/settings.d.ts +5 -14
  131. package/dist/lib/settings.js +5 -16
  132. package/dist/lib/settings.js.map +1 -1
  133. package/dist/lib/startup-notice-gate.d.ts +21 -0
  134. package/dist/lib/startup-notice-gate.js +29 -0
  135. package/dist/lib/startup-notice-gate.js.map +1 -0
  136. package/dist/lib/telemetry-notice.d.ts +5 -5
  137. package/dist/lib/telemetry-notice.js +10 -8
  138. package/dist/lib/telemetry-notice.js.map +1 -1
  139. package/dist/lib/unclaimed-env-provision.js +15 -12
  140. package/dist/lib/unclaimed-env-provision.js.map +1 -1
  141. package/dist/lib/unclaimed-warning.js +7 -3
  142. package/dist/lib/unclaimed-warning.js.map +1 -1
  143. package/dist/lib/validation/security-checks.js +2 -1
  144. package/dist/lib/validation/security-checks.js.map +1 -1
  145. package/dist/lib/validation/validator.js +30 -3
  146. package/dist/lib/validation/validator.js.map +1 -1
  147. package/dist/lib/workos-management.js +26 -19
  148. package/dist/lib/workos-management.js.map +1 -1
  149. package/dist/run.d.ts +1 -0
  150. package/dist/run.js +5 -1
  151. package/dist/run.js.map +1 -1
  152. package/dist/steps/add-or-update-environment-variables.js +10 -10
  153. package/dist/steps/add-or-update-environment-variables.js.map +1 -1
  154. package/dist/steps/run-prettier.js +3 -3
  155. package/dist/steps/run-prettier.js.map +1 -1
  156. package/dist/steps/upload-environment-variables/index.js +15 -3
  157. package/dist/steps/upload-environment-variables/index.js.map +1 -1
  158. package/dist/steps/upload-environment-variables/providers/vercel.js +2 -2
  159. package/dist/steps/upload-environment-variables/providers/vercel.js.map +1 -1
  160. package/dist/utils/analytics.d.ts +1 -0
  161. package/dist/utils/analytics.js +5 -1
  162. package/dist/utils/analytics.js.map +1 -1
  163. package/dist/utils/box.d.ts +6 -30
  164. package/dist/utils/box.js +8 -95
  165. package/dist/utils/box.js.map +1 -1
  166. package/dist/utils/cli-symbols.d.ts +14 -2
  167. package/dist/utils/cli-symbols.js +12 -0
  168. package/dist/utils/cli-symbols.js.map +1 -1
  169. package/dist/utils/debug.js +3 -3
  170. package/dist/utils/debug.js.map +1 -1
  171. package/dist/utils/environment.js +1 -1
  172. package/dist/utils/environment.js.map +1 -1
  173. package/dist/utils/help-json.js +153 -4
  174. package/dist/utils/help-json.js.map +1 -1
  175. package/dist/utils/interaction-mode.d.ts +1 -1
  176. package/dist/utils/interaction-mode.js +0 -3
  177. package/dist/utils/interaction-mode.js.map +1 -1
  178. package/dist/utils/output.d.ts +5 -3
  179. package/dist/utils/output.js +5 -5
  180. package/dist/utils/output.js.map +1 -1
  181. package/dist/utils/package-manager.js +1 -1
  182. package/dist/utils/package-manager.js.map +1 -1
  183. package/dist/utils/recovery-hints.d.ts +5 -0
  184. package/dist/utils/recovery-hints.js +12 -0
  185. package/dist/utils/recovery-hints.js.map +1 -1
  186. package/dist/utils/summary-box.d.ts +8 -1
  187. package/dist/utils/summary-box.js +67 -4
  188. package/dist/utils/summary-box.js.map +1 -1
  189. package/dist/utils/telemetry-types.d.ts +1 -1
  190. package/dist/utils/telemetry-types.js.map +1 -1
  191. package/dist/utils/types.d.ts +10 -0
  192. package/dist/utils/types.js.map +1 -1
  193. package/dist/utils/{clack-utils.d.ts → ui-utils.d.ts} +1 -1
  194. package/dist/utils/{clack-utils.js → ui-utils.js} +64 -37
  195. package/dist/utils/ui-utils.js.map +1 -0
  196. package/dist/utils/ui.d.ts +148 -0
  197. package/dist/utils/ui.js +368 -0
  198. package/dist/utils/ui.js.map +1 -0
  199. package/dist/utils/urls.d.ts +9 -3
  200. package/dist/utils/urls.js +10 -4
  201. package/dist/utils/urls.js.map +1 -1
  202. package/package.json +13 -20
  203. package/dist/check-coverage.ts +0 -237
  204. package/dist/emulate/core/id.d.ts +0 -48
  205. package/dist/emulate/core/id.js +0 -73
  206. package/dist/emulate/core/id.js.map +0 -1
  207. package/dist/emulate/core/index.d.ts +0 -8
  208. package/dist/emulate/core/index.js +0 -8
  209. package/dist/emulate/core/index.js.map +0 -1
  210. package/dist/emulate/core/jwt.d.ts +0 -28
  211. package/dist/emulate/core/jwt.js +0 -78
  212. package/dist/emulate/core/jwt.js.map +0 -1
  213. package/dist/emulate/core/middleware/auth.d.ts +0 -15
  214. package/dist/emulate/core/middleware/auth.js +0 -17
  215. package/dist/emulate/core/middleware/auth.js.map +0 -1
  216. package/dist/emulate/core/middleware/error-handler.d.ts +0 -22
  217. package/dist/emulate/core/middleware/error-handler.js +0 -72
  218. package/dist/emulate/core/middleware/error-handler.js.map +0 -1
  219. package/dist/emulate/core/pagination.d.ts +0 -27
  220. package/dist/emulate/core/pagination.js +0 -43
  221. package/dist/emulate/core/pagination.js.map +0 -1
  222. package/dist/emulate/core/plugin.d.ts +0 -15
  223. package/dist/emulate/core/plugin.js +0 -2
  224. package/dist/emulate/core/plugin.js.map +0 -1
  225. package/dist/emulate/core/server.d.ts +0 -17
  226. package/dist/emulate/core/server.js +0 -90
  227. package/dist/emulate/core/server.js.map +0 -1
  228. package/dist/emulate/core/store.d.ts +0 -44
  229. package/dist/emulate/core/store.js +0 -169
  230. package/dist/emulate/core/store.js.map +0 -1
  231. package/dist/emulate/index.d.ts +0 -25
  232. package/dist/emulate/index.js +0 -47
  233. package/dist/emulate/index.js.map +0 -1
  234. package/dist/emulate/workos/constants.d.ts +0 -56
  235. package/dist/emulate/workos/constants.js +0 -56
  236. package/dist/emulate/workos/constants.js.map +0 -1
  237. package/dist/emulate/workos/entities.d.ts +0 -360
  238. package/dist/emulate/workos/entities.js +0 -2
  239. package/dist/emulate/workos/entities.js.map +0 -1
  240. package/dist/emulate/workos/event-bus.d.ts +0 -17
  241. package/dist/emulate/workos/event-bus.js +0 -70
  242. package/dist/emulate/workos/event-bus.js.map +0 -1
  243. package/dist/emulate/workos/helpers.d.ts +0 -72
  244. package/dist/emulate/workos/helpers.js +0 -211
  245. package/dist/emulate/workos/helpers.js.map +0 -1
  246. package/dist/emulate/workos/index.d.ts +0 -93
  247. package/dist/emulate/workos/index.js +0 -326
  248. package/dist/emulate/workos/index.js.map +0 -1
  249. package/dist/emulate/workos/role-helpers.d.ts +0 -21
  250. package/dist/emulate/workos/role-helpers.js +0 -130
  251. package/dist/emulate/workos/role-helpers.js.map +0 -1
  252. package/dist/emulate/workos/routes/api-keys.d.ts +0 -2
  253. package/dist/emulate/workos/routes/api-keys.js +0 -32
  254. package/dist/emulate/workos/routes/api-keys.js.map +0 -1
  255. package/dist/emulate/workos/routes/audit-logs.d.ts +0 -2
  256. package/dist/emulate/workos/routes/audit-logs.js +0 -104
  257. package/dist/emulate/workos/routes/audit-logs.js.map +0 -1
  258. package/dist/emulate/workos/routes/auth-challenges.d.ts +0 -2
  259. package/dist/emulate/workos/routes/auth-challenges.js +0 -51
  260. package/dist/emulate/workos/routes/auth-challenges.js.map +0 -1
  261. package/dist/emulate/workos/routes/auth-factors.d.ts +0 -2
  262. package/dist/emulate/workos/routes/auth-factors.js +0 -51
  263. package/dist/emulate/workos/routes/auth-factors.js.map +0 -1
  264. package/dist/emulate/workos/routes/auth.d.ts +0 -2
  265. package/dist/emulate/workos/routes/auth.js +0 -350
  266. package/dist/emulate/workos/routes/auth.js.map +0 -1
  267. package/dist/emulate/workos/routes/authorization-checks.d.ts +0 -10
  268. package/dist/emulate/workos/routes/authorization-checks.js +0 -123
  269. package/dist/emulate/workos/routes/authorization-checks.js.map +0 -1
  270. package/dist/emulate/workos/routes/authorization-org-roles.d.ts +0 -2
  271. package/dist/emulate/workos/routes/authorization-org-roles.js +0 -64
  272. package/dist/emulate/workos/routes/authorization-org-roles.js.map +0 -1
  273. package/dist/emulate/workos/routes/authorization-permissions.d.ts +0 -2
  274. package/dist/emulate/workos/routes/authorization-permissions.js +0 -67
  275. package/dist/emulate/workos/routes/authorization-permissions.js.map +0 -1
  276. package/dist/emulate/workos/routes/authorization-resources.d.ts +0 -2
  277. package/dist/emulate/workos/routes/authorization-resources.js +0 -117
  278. package/dist/emulate/workos/routes/authorization-resources.js.map +0 -1
  279. package/dist/emulate/workos/routes/authorization-roles.d.ts +0 -2
  280. package/dist/emulate/workos/routes/authorization-roles.js +0 -13
  281. package/dist/emulate/workos/routes/authorization-roles.js.map +0 -1
  282. package/dist/emulate/workos/routes/config.d.ts +0 -2
  283. package/dist/emulate/workos/routes/config.js +0 -57
  284. package/dist/emulate/workos/routes/config.js.map +0 -1
  285. package/dist/emulate/workos/routes/connect.d.ts +0 -2
  286. package/dist/emulate/workos/routes/connect.js +0 -65
  287. package/dist/emulate/workos/routes/connect.js.map +0 -1
  288. package/dist/emulate/workos/routes/connections.d.ts +0 -2
  289. package/dist/emulate/workos/routes/connections.js +0 -73
  290. package/dist/emulate/workos/routes/connections.js.map +0 -1
  291. package/dist/emulate/workos/routes/data-integrations.d.ts +0 -2
  292. package/dist/emulate/workos/routes/data-integrations.js +0 -55
  293. package/dist/emulate/workos/routes/data-integrations.js.map +0 -1
  294. package/dist/emulate/workos/routes/directories.d.ts +0 -2
  295. package/dist/emulate/workos/routes/directories.js +0 -90
  296. package/dist/emulate/workos/routes/directories.js.map +0 -1
  297. package/dist/emulate/workos/routes/email-verification.d.ts +0 -2
  298. package/dist/emulate/workos/routes/email-verification.js +0 -49
  299. package/dist/emulate/workos/routes/email-verification.js.map +0 -1
  300. package/dist/emulate/workos/routes/events.d.ts +0 -2
  301. package/dist/emulate/workos/routes/events.js +0 -18
  302. package/dist/emulate/workos/routes/events.js.map +0 -1
  303. package/dist/emulate/workos/routes/feature-flags.d.ts +0 -2
  304. package/dist/emulate/workos/routes/feature-flags.js +0 -103
  305. package/dist/emulate/workos/routes/feature-flags.js.map +0 -1
  306. package/dist/emulate/workos/routes/invitations.d.ts +0 -2
  307. package/dist/emulate/workos/routes/invitations.js +0 -122
  308. package/dist/emulate/workos/routes/invitations.js.map +0 -1
  309. package/dist/emulate/workos/routes/legacy-mfa.d.ts +0 -2
  310. package/dist/emulate/workos/routes/legacy-mfa.js +0 -75
  311. package/dist/emulate/workos/routes/legacy-mfa.js.map +0 -1
  312. package/dist/emulate/workos/routes/magic-auth.d.ts +0 -2
  313. package/dist/emulate/workos/routes/magic-auth.js +0 -32
  314. package/dist/emulate/workos/routes/magic-auth.js.map +0 -1
  315. package/dist/emulate/workos/routes/memberships.d.ts +0 -2
  316. package/dist/emulate/workos/routes/memberships.js +0 -114
  317. package/dist/emulate/workos/routes/memberships.js.map +0 -1
  318. package/dist/emulate/workos/routes/organization-domains.d.ts +0 -2
  319. package/dist/emulate/workos/routes/organization-domains.js +0 -58
  320. package/dist/emulate/workos/routes/organization-domains.js.map +0 -1
  321. package/dist/emulate/workos/routes/organizations.d.ts +0 -2
  322. package/dist/emulate/workos/routes/organizations.js +0 -131
  323. package/dist/emulate/workos/routes/organizations.js.map +0 -1
  324. package/dist/emulate/workos/routes/password-reset.d.ts +0 -2
  325. package/dist/emulate/workos/routes/password-reset.js +0 -61
  326. package/dist/emulate/workos/routes/password-reset.js.map +0 -1
  327. package/dist/emulate/workos/routes/pipes.d.ts +0 -2
  328. package/dist/emulate/workos/routes/pipes.js +0 -82
  329. package/dist/emulate/workos/routes/pipes.js.map +0 -1
  330. package/dist/emulate/workos/routes/portal.d.ts +0 -2
  331. package/dist/emulate/workos/routes/portal.js +0 -18
  332. package/dist/emulate/workos/routes/portal.js.map +0 -1
  333. package/dist/emulate/workos/routes/radar.d.ts +0 -2
  334. package/dist/emulate/workos/routes/radar.js +0 -41
  335. package/dist/emulate/workos/routes/radar.js.map +0 -1
  336. package/dist/emulate/workos/routes/sessions.d.ts +0 -2
  337. package/dist/emulate/workos/routes/sessions.js +0 -51
  338. package/dist/emulate/workos/routes/sessions.js.map +0 -1
  339. package/dist/emulate/workos/routes/sso.d.ts +0 -2
  340. package/dist/emulate/workos/routes/sso.js +0 -161
  341. package/dist/emulate/workos/routes/sso.js.map +0 -1
  342. package/dist/emulate/workos/routes/user-features.d.ts +0 -2
  343. package/dist/emulate/workos/routes/user-features.js +0 -50
  344. package/dist/emulate/workos/routes/user-features.js.map +0 -1
  345. package/dist/emulate/workos/routes/users.d.ts +0 -2
  346. package/dist/emulate/workos/routes/users.js +0 -129
  347. package/dist/emulate/workos/routes/users.js.map +0 -1
  348. package/dist/emulate/workos/routes/webhook-endpoints.d.ts +0 -2
  349. package/dist/emulate/workos/routes/webhook-endpoints.js +0 -67
  350. package/dist/emulate/workos/routes/webhook-endpoints.js.map +0 -1
  351. package/dist/emulate/workos/routes/widgets.d.ts +0 -2
  352. package/dist/emulate/workos/routes/widgets.js +0 -27
  353. package/dist/emulate/workos/routes/widgets.js.map +0 -1
  354. package/dist/emulate/workos/store.d.ts +0 -48
  355. package/dist/emulate/workos/store.js +0 -102
  356. package/dist/emulate/workos/store.js.map +0 -1
  357. package/dist/emulate/workos/webhook-signer.d.ts +0 -1
  358. package/dist/emulate/workos/webhook-signer.js +0 -8
  359. package/dist/emulate/workos/webhook-signer.js.map +0 -1
  360. package/dist/gen-routes-lib.spec.ts +0 -659
  361. package/dist/gen-routes-lib.ts +0 -647
  362. package/dist/gen-routes.ts +0 -96
  363. package/dist/utils/clack-utils.js.map +0 -1
  364. package/dist/utils/clack.d.ts +0 -5
  365. package/dist/utils/clack.js +0 -34
  366. package/dist/utils/clack.js.map +0 -1
@@ -0,0 +1,33 @@
1
+ import type { CompletionData } from './events.js';
2
+ import type { DevCommandResult } from './dev-command.js';
3
+ import type { Integration } from './constants.js';
4
+ /**
5
+ * Machine-context slice needed to build completion data.
6
+ */
7
+ export interface CompletionContext {
8
+ integration: string;
9
+ changedFiles?: string[];
10
+ installDir: string;
11
+ }
12
+ /**
13
+ * Injected dependencies. The impure lookups (registry/settings) are resolved by
14
+ * the caller and passed as plain values so the builder stays pure + unit-testable.
15
+ */
16
+ export interface CompletionDataDeps {
17
+ resolveDevCommand: (dir: string) => Promise<DevCommandResult>;
18
+ detectPort: (integration: Integration, dir: string) => number;
19
+ docsUrl: string;
20
+ dashboardUrl: string;
21
+ /** Enriched getOutroNextSteps copy for the framework */
22
+ frameworkNextSteps?: string[];
23
+ /** Per-framework "add a sign-in link" snippet */
24
+ signInSnippet?: string;
25
+ }
26
+ /**
27
+ * Build the structured completion payload for a successful install.
28
+ *
29
+ * Deterministic given its inputs. The dev command is derived from the
30
+ * lockfile-aware `resolveDevCommand` (never from context.packageManager, which
31
+ * is flag/env-derived and unreliable). Copy fields are injected by the caller.
32
+ */
33
+ export declare function buildCompletionData(ctx: CompletionContext, deps: CompletionDataDeps): Promise<CompletionData>;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Build the structured completion payload for a successful install.
3
+ *
4
+ * Deterministic given its inputs. The dev command is derived from the
5
+ * lockfile-aware `resolveDevCommand` (never from context.packageManager, which
6
+ * is flag/env-derived and unreliable). Copy fields are injected by the caller.
7
+ */
8
+ export async function buildCompletionData(ctx, deps) {
9
+ const dev = await deps.resolveDevCommand(ctx.installDir);
10
+ const devCommand = [dev.command, ...dev.args].join(' ');
11
+ const port = deps.detectPort(ctx.integration, ctx.installDir);
12
+ const url = `http://localhost:${port}`;
13
+ const files = ctx.changedFiles ?? [];
14
+ const concrete = [
15
+ `Run \`${devCommand}\` to start your dev server`,
16
+ `Open ${url} to test authentication`,
17
+ ...(deps.signInSnippet ? [deps.signInSnippet] : []),
18
+ ];
19
+ // Drop the framework's generic "start dev server" line — the concrete step
20
+ // above already names the exact lockfile-aware command.
21
+ const framework = (deps.frameworkNextSteps ?? []).filter((s) => !/start .*dev(elopment)? server/i.test(s));
22
+ return {
23
+ integration: ctx.integration,
24
+ devCommand,
25
+ url,
26
+ files,
27
+ nextSteps: [...concrete, ...framework],
28
+ docsUrl: deps.docsUrl,
29
+ dashboardUrl: deps.dashboardUrl,
30
+ signInSnippet: deps.signInSnippet,
31
+ };
32
+ }
33
+ //# sourceMappingURL=completion-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"completion-data.js","sourceRoot":"","sources":["../../src/lib/completion-data.ts"],"names":[],"mappings":"AA4BA;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,GAAsB,EAAE,IAAwB;IACxF,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,WAA0B,EAAE,GAAG,CAAC,UAAU,CAAC,CAAC;IAC7E,MAAM,GAAG,GAAG,oBAAoB,IAAI,EAAE,CAAC;IACvC,MAAM,KAAK,GAAG,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC;IAErC,MAAM,QAAQ,GAAG;QACf,SAAS,UAAU,6BAA6B;QAChD,QAAQ,GAAG,yBAAyB;QACpC,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;KACpD,CAAC;IACF,2EAA2E;IAC3E,wDAAwD;IACxD,MAAM,SAAS,GAAG,CAAC,IAAI,CAAC,kBAAkB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,gCAAgC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IAE3G,OAAO;QACL,WAAW,EAAE,GAAG,CAAC,WAAW;QAC5B,UAAU;QACV,GAAG;QACH,KAAK;QACL,SAAS,EAAE,CAAC,GAAG,QAAQ,EAAE,GAAG,SAAS,CAAC;QACtC,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,YAAY,EAAE,IAAI,CAAC,YAAY;QAC/B,aAAa,EAAE,IAAI,CAAC,aAAa;KAClC,CAAC;AACJ,CAAC","sourcesContent":["import type { CompletionData } from './events.js';\nimport type { DevCommandResult } from './dev-command.js';\nimport type { Integration } from './constants.js';\n\n/**\n * Machine-context slice needed to build completion data.\n */\nexport interface CompletionContext {\n integration: string;\n changedFiles?: string[];\n installDir: string;\n}\n\n/**\n * Injected dependencies. The impure lookups (registry/settings) are resolved by\n * the caller and passed as plain values so the builder stays pure + unit-testable.\n */\nexport interface CompletionDataDeps {\n resolveDevCommand: (dir: string) => Promise<DevCommandResult>;\n detectPort: (integration: Integration, dir: string) => number;\n docsUrl: string;\n dashboardUrl: string;\n /** Enriched getOutroNextSteps copy for the framework */\n frameworkNextSteps?: string[];\n /** Per-framework \"add a sign-in link\" snippet */\n signInSnippet?: string;\n}\n\n/**\n * Build the structured completion payload for a successful install.\n *\n * Deterministic given its inputs. The dev command is derived from the\n * lockfile-aware `resolveDevCommand` (never from context.packageManager, which\n * is flag/env-derived and unreliable). Copy fields are injected by the caller.\n */\nexport async function buildCompletionData(ctx: CompletionContext, deps: CompletionDataDeps): Promise<CompletionData> {\n const dev = await deps.resolveDevCommand(ctx.installDir);\n const devCommand = [dev.command, ...dev.args].join(' ');\n const port = deps.detectPort(ctx.integration as Integration, ctx.installDir);\n const url = `http://localhost:${port}`;\n const files = ctx.changedFiles ?? [];\n\n const concrete = [\n `Run \\`${devCommand}\\` to start your dev server`,\n `Open ${url} to test authentication`,\n ...(deps.signInSnippet ? [deps.signInSnippet] : []),\n ];\n // Drop the framework's generic \"start dev server\" line — the concrete step\n // above already names the exact lockfile-aware command.\n const framework = (deps.frameworkNextSteps ?? []).filter((s) => !/start .*dev(elopment)? server/i.test(s));\n\n return {\n integration: ctx.integration,\n devCommand,\n url,\n files,\n nextSteps: [...concrete, ...framework],\n docsUrl: deps.docsUrl,\n dashboardUrl: deps.dashboardUrl,\n signInSnippet: deps.signInSnippet,\n };\n}\n"]}
@@ -12,6 +12,10 @@ interface BaseEnvironmentConfig {
12
12
  name: string;
13
13
  apiKey: string;
14
14
  endpoint?: string;
15
+ /** Email of the account that owns this environment. Stamped when `auth login` provisions Staging for a known account; undefined for unclaimed/manually-added envs. */
16
+ ownerEmail?: string;
17
+ /** User ID of the account that owns this environment. Stamped alongside ownerEmail. */
18
+ ownerUserId?: string;
15
19
  }
16
20
  export interface ClaimedEnvironmentConfig extends BaseEnvironmentConfig {
17
21
  type: 'production' | 'sandbox';
@@ -36,6 +40,15 @@ export declare function getConfig(): CliConfig | null;
36
40
  export declare function saveConfig(config: CliConfig): void;
37
41
  export declare function clearConfig(): void;
38
42
  export declare function getActiveEnvironment(): EnvironmentConfig | null;
43
+ /**
44
+ * Set the active environment by name.
45
+ *
46
+ * No-op when there is no config or the named environment does not exist —
47
+ * callers should not be able to point `activeEnvironment` at a missing key.
48
+ */
49
+ export declare function setActiveEnvironment(name: string): void;
50
+ /** Pick a non-colliding environments key: `base`, else `base-2`, `base-3`, … */
51
+ export declare function freshEnvKey(config: CliConfig, base: string): string;
39
52
  export declare function getConfigPath(): string;
40
53
  /**
41
54
  * Diagnostic info about config storage state — for debugging config persistence failures.
@@ -194,6 +194,28 @@ export function getActiveEnvironment() {
194
194
  return null;
195
195
  return config.environments[config.activeEnvironment] ?? null;
196
196
  }
197
+ /**
198
+ * Set the active environment by name.
199
+ *
200
+ * No-op when there is no config or the named environment does not exist —
201
+ * callers should not be able to point `activeEnvironment` at a missing key.
202
+ */
203
+ export function setActiveEnvironment(name) {
204
+ const config = getConfig();
205
+ if (!config || !config.environments[name])
206
+ return;
207
+ config.activeEnvironment = name;
208
+ saveConfig(config);
209
+ }
210
+ /** Pick a non-colliding environments key: `base`, else `base-2`, `base-3`, … */
211
+ export function freshEnvKey(config, base) {
212
+ if (!config.environments[base])
213
+ return base;
214
+ let i = 2;
215
+ while (config.environments[`${base}-${i}`])
216
+ i++;
217
+ return `${base}-${i}`;
218
+ }
197
219
  export function getConfigPath() {
198
220
  return getConfigFilePath();
199
221
  }
@@ -257,6 +279,8 @@ export function markEnvironmentClaimed() {
257
279
  apiKey: env.apiKey,
258
280
  clientId: env.clientId,
259
281
  ...(env.endpoint && { endpoint: env.endpoint }),
282
+ ...(env.ownerEmail && { ownerEmail: env.ownerEmail }),
283
+ ...(env.ownerUserId && { ownerUserId: env.ownerUserId }),
260
284
  };
261
285
  if (oldKey !== newKey) {
262
286
  delete config.environments[oldKey];
@@ -1 +1 @@
1
- {"version":3,"file":"config-store.js","sourceRoot":"","sources":["../../src/lib/config-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAqBrD;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,GAAsB;IAC3D,OAAO,GAAG,CAAC,IAAI,KAAK,WAAW,CAAC;AAClC,CAAC;AAOD,MAAM,YAAY,GAAG,YAAY,CAAC;AAClC,MAAM,YAAY,GAAG,QAAQ,CAAC;AAE9B,IAAI,oBAAoB,GAAG,KAAK,CAAC;AACjC,IAAI,oBAAoB,GAAG,KAAK,CAAC;AACjC,IAAI,kBAAkB,GAAG,KAAK,CAAC;AAE/B,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,oBAAoB,GAAG,KAAK,CAAC;IAC7B,kBAAkB,GAAG,KAAK,CAAC;AAC7B,CAAC;AAED,SAAS,YAAY;IACnB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,iBAAiB;IACxB,OAAO,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,aAAa,CAAC,CAAC;AAClD,CAAC;AAED,SAAS,UAAU;IACjB,OAAO,EAAE,CAAC,UAAU,CAAC,iBAAiB,EAAE,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,YAAY;IACnB,IAAI,CAAC,UAAU,EAAE;QAAE,OAAO,IAAI,CAAC;IAC/B,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACnD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,kBAAkB,CAAC,SAAS,EAAE,KAAK,EAAE;YACnC,SAAS,EAAE,MAAM;YACjB,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,sBAAsB;SAC9B,CAAC,CAAC;QACH,OAAO,CAAC,6BAA6B,EAAE,KAAK,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,MAAiB;IACpC,MAAM,GAAG,GAAG,YAAY,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACtD,CAAC;QACD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;YAC1D,IAAI,EAAE,KAAK;SACZ,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,kBAAkB,CAAC,SAAS,EAAE,KAAK,EAAE;YACnC,SAAS,EAAE,OAAO;YAClB,MAAM,EAAE,QAAQ;YAChB,KAAK,EAAE,sBAAsB;SAC9B,CAAC,CAAC;QACH,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,UAAU;IACjB,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,IAAI,UAAU,EAAE,EAAE,CAAC;QACjB,IAAI,CAAC;YACH,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,kBAAkB,CAAC,SAAS,EAAE,KAAK,EAAE;gBACnC,SAAS,EAAE,QAAQ;gBACnB,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,sBAAsB;aAC9B,CAAC,CAAC;YACH,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,eAAe;IACtB,OAAO,IAAI,KAAK,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;AAC/C,CAAC;AAED,SAAS,eAAe;IACtB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACjC,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAC;QACtD,kBAAkB,CAAC,UAAU,EAAE,KAAK,EAAE;YACpC,SAAS,EAAE,MAAM;YACjB,MAAM,EAAE,GAAG,YAAY,IAAI,YAAY,EAAE;YACzC,KAAK,EAAE,uBAAuB;SAC/B,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,MAAiB;IACvC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;QAChC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC1C,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;QACrD,kBAAkB,CAAC,UAAU,EAAE,KAAK,EAAE;YACpC,SAAS,EAAE,OAAO;YAClB,MAAM,EAAE,GAAG,YAAY,IAAI,YAAY,EAAE;YACzC,KAAK,EAAE,uBAAuB;SAC/B,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,SAAS,iBAAiB;IACxB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;QAChC,KAAK,CAAC,cAAc,EAAE,CAAC;IACzB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnE,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3D,OAAO,CAAC,uCAAuC,EAAE,KAAK,CAAC,CAAC;YACxD,kBAAkB,CAAC,UAAU,EAAE,KAAK,EAAE;gBACpC,SAAS,EAAE,QAAQ;gBACnB,MAAM,EAAE,GAAG,YAAY,IAAI,YAAY,EAAE;gBACzC,KAAK,EAAE,uBAAuB;aAC/B,CAAC,CAAC;QACL,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,mBAAmB;IAC1B,IAAI,oBAAoB,IAAI,oBAAoB;QAAE,OAAO;IACzD,oBAAoB,GAAG,IAAI,CAAC;IAC5B,OAAO,CACL,+DAA+D,EAC/D,uCAAuC,EACvC,kDAAkD,CACnD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,IAAI,oBAAoB;QAAE,OAAO,YAAY,EAAE,CAAC;IAEhD,MAAM,aAAa,GAAG,eAAe,EAAE,CAAC;IACxC,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IAExC,MAAM,UAAU,GAAG,YAAY,EAAE,CAAC;IAClC,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC,kBAAkB,EAAE,CAAC;YACxB,kBAAkB,GAAG,IAAI,CAAC;YAC1B,cAAc,CAAC,UAAU,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAiB;IAC1C,IAAI,oBAAoB;QAAE,OAAO,WAAW,CAAC,MAAM,CAAC,CAAC;IAErD,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,mBAAmB,EAAE,CAAC;QACtB,WAAW,CAAC,MAAM,CAAC,CAAC;QACpB,OAAO;IACT,CAAC;IAED,+EAA+E;IAC/E,+EAA+E;IAC/E,IAAI,CAAC,eAAe,EAAE,EAAE,CAAC;QACvB,OAAO,CAAC,qEAAqE,CAAC,CAAC;QAC/E,WAAW,CAAC,MAAM,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,iBAAiB,EAAE,CAAC;IACpB,UAAU,EAAE,CAAC;IACb,kBAAkB,GAAG,KAAK,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,MAAM,EAAE,iBAAiB;QAAE,OAAO,IAAI,CAAC;IAC5C,OAAO,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,iBAAiB,CAAC,IAAI,IAAI,CAAC;AAC/D,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,iBAAiB,EAAE,CAAC;AAC7B,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc;IAC5B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC;IACrC,MAAM,WAAW,GAAG,UAAU,EAAE,CAAC;IAEjC,KAAK,CAAC,IAAI,CAAC,SAAS,QAAQ,YAAY,WAAW,GAAG,CAAC,CAAC;IAExD,IAAI,WAAW,EAAE,CAAC;QAChB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAuB,CAAC;YACzD,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACnF,KAAK,CAAC,IAAI,CAAC,uBAAuB,MAAM,CAAC,iBAAiB,IAAI,MAAM,kBAAkB,QAAQ,EAAE,CAAC,CAAC;QACpG,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,KAAK,CAAC,IAAI,CAAC,8BAA8B,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzF,CAAC;IACH,CAAC;IAED,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,eAAe,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;QACjC,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAuB,CAAC;YACtD,MAAM,QAAQ,GAAG,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;YACnF,KAAK,CAAC,IAAI,CAAC,0BAA0B,MAAM,CAAC,iBAAiB,IAAI,MAAM,kBAAkB,QAAQ,EAAE,CAAC,CAAC;QACvG,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,KAAK,CAAC,IAAI,CAAC,oBAAoB,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/E,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,mBAAmB,oBAAoB,EAAE,CAAC,CAAC;IACtD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB;IACpC,MAAM,MAAM,GAAG,SAAS,EAAE,CAAC;IAC3B,IAAI,CAAC,MAAM,EAAE,iBAAiB;QAAE,OAAO;IACvC,MAAM,MAAM,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACxC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACpC,0DAA0D;QAC1D,IAAI,MAAM,GAAG,SAAS,CAAC;QACvB,IAAI,MAAM,KAAK,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC;YACrD,MAAM,GAAG,MAAM,CAAC,CAAC,kDAAkD;QACrE,CAAC;QAED,MAAM,OAAO,GAA6B;YACxC,IAAI,EAAE,MAAM;YACZ,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,GAAG,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,CAAC;SAChD,CAAC;QAEF,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,OAAO,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC;QACrC,CAAC;QACD,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC;QACtC,MAAM,CAAC,iBAAiB,GAAG,MAAM,CAAC;QAElC,UAAU,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;AACH,CAAC","sourcesContent":["/**\n * CLI config storage abstraction with keyring support and file fallback.\n *\n * Stores environment configurations (names, API keys, endpoints) separately\n * from OAuth credentials. Uses a second keyring entry under the same service.\n *\n * Storage priority:\n * 1. If insecure storage forced: use file only\n * 2. Try keyring, fall back to file with warning if unavailable\n */\n\nimport { Entry } from '@napi-rs/keyring';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { logWarn } from '../utils/debug.js';\nimport { observeHostFailure } from './host-probe.js';\n\ninterface BaseEnvironmentConfig {\n name: string;\n apiKey: string;\n endpoint?: string;\n}\n\nexport interface ClaimedEnvironmentConfig extends BaseEnvironmentConfig {\n type: 'production' | 'sandbox';\n clientId?: string;\n}\n\nexport interface UnclaimedEnvironmentConfig extends BaseEnvironmentConfig {\n type: 'unclaimed';\n clientId: string;\n claimToken: string;\n}\n\nexport type EnvironmentConfig = ClaimedEnvironmentConfig | UnclaimedEnvironmentConfig;\n\n/**\n * Type guard — narrows to UnclaimedEnvironmentConfig with required clientId and claimToken.\n */\nexport function isUnclaimedEnvironment(env: EnvironmentConfig): env is UnclaimedEnvironmentConfig {\n return env.type === 'unclaimed';\n}\n\nexport interface CliConfig {\n activeEnvironment?: string;\n environments: Record<string, EnvironmentConfig>;\n}\n\nconst SERVICE_NAME = 'workos-cli';\nconst ACCOUNT_NAME = 'config';\n\nlet fallbackWarningShown = false;\nlet forceInsecureStorage = false;\nlet migrationAttempted = false;\n\nexport function setInsecureConfigStorage(value: boolean): void {\n forceInsecureStorage = value;\n migrationAttempted = false;\n}\n\nfunction getConfigDir(): string {\n return path.join(os.homedir(), '.workos');\n}\n\nfunction getConfigFilePath(): string {\n return path.join(getConfigDir(), 'config.json');\n}\n\nfunction fileExists(): boolean {\n return fs.existsSync(getConfigFilePath());\n}\n\nfunction readFromFile(): CliConfig | null {\n if (!fileExists()) return null;\n const filePath = getConfigFilePath();\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n observeHostFailure('home-fs', error, {\n operation: 'read',\n target: filePath,\n label: 'config fallback file',\n });\n logWarn('Failed to read config file:', error);\n return null;\n }\n}\n\nfunction writeToFile(config: CliConfig): void {\n const dir = getConfigDir();\n const filePath = getConfigFilePath();\n try {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n fs.writeFileSync(filePath, JSON.stringify(config, null, 2), {\n mode: 0o600,\n });\n } catch (error) {\n observeHostFailure('home-fs', error, {\n operation: 'write',\n target: filePath,\n label: 'config fallback file',\n });\n throw error;\n }\n}\n\nfunction deleteFile(): void {\n const filePath = getConfigFilePath();\n if (fileExists()) {\n try {\n fs.unlinkSync(filePath);\n } catch (error) {\n observeHostFailure('home-fs', error, {\n operation: 'delete',\n target: filePath,\n label: 'config fallback file',\n });\n throw error;\n }\n }\n}\n\nfunction getKeyringEntry(): Entry {\n return new Entry(SERVICE_NAME, ACCOUNT_NAME);\n}\n\nfunction readFromKeyring(): CliConfig | null {\n try {\n const entry = getKeyringEntry();\n const data = entry.getPassword();\n if (!data) return null;\n return JSON.parse(data);\n } catch (error) {\n logWarn('Failed to read config from keyring:', error);\n observeHostFailure('keychain', error, {\n operation: 'read',\n target: `${SERVICE_NAME}/${ACCOUNT_NAME}`,\n label: 'config keychain entry',\n });\n return null;\n }\n}\n\nfunction writeToKeyring(config: CliConfig): boolean {\n try {\n const entry = getKeyringEntry();\n entry.setPassword(JSON.stringify(config));\n return true;\n } catch (error) {\n logWarn('Failed to write config to keyring:', error);\n observeHostFailure('keychain', error, {\n operation: 'write',\n target: `${SERVICE_NAME}/${ACCOUNT_NAME}`,\n label: 'config keychain entry',\n });\n return false;\n }\n}\n\nfunction deleteFromKeyring(): void {\n try {\n const entry = getKeyringEntry();\n entry.deletePassword();\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (!msg.includes('not found') && !msg.includes('No such')) {\n logWarn('Failed to delete config from keyring:', error);\n observeHostFailure('keychain', error, {\n operation: 'delete',\n target: `${SERVICE_NAME}/${ACCOUNT_NAME}`,\n label: 'config keychain entry',\n });\n }\n }\n}\n\nfunction showFallbackWarning(): void {\n if (fallbackWarningShown || forceInsecureStorage) return;\n fallbackWarningShown = true;\n logWarn(\n 'Unable to store config in system keyring. Using file storage.',\n 'Config saved to ~/.workos/config.json',\n 'Use --insecure-storage to suppress this warning.',\n );\n}\n\nexport function getConfig(): CliConfig | null {\n if (forceInsecureStorage) return readFromFile();\n\n const keyringConfig = readFromKeyring();\n if (keyringConfig) return keyringConfig;\n\n const fileConfig = readFromFile();\n if (fileConfig) {\n if (!migrationAttempted) {\n migrationAttempted = true;\n writeToKeyring(fileConfig);\n }\n return fileConfig;\n }\n\n return null;\n}\n\nexport function saveConfig(config: CliConfig): void {\n if (forceInsecureStorage) return writeToFile(config);\n\n if (!writeToKeyring(config)) {\n showFallbackWarning();\n writeToFile(config);\n return;\n }\n\n // Verify the keyring write is readable (guards against silent keyring failures\n // where setPassword succeeds but getPassword returns null in the same process)\n if (!readFromKeyring()) {\n logWarn('Keyring write succeeded but read-back failed — falling back to file');\n writeToFile(config);\n }\n}\n\nexport function clearConfig(): void {\n deleteFromKeyring();\n deleteFile();\n migrationAttempted = false;\n}\n\nexport function getActiveEnvironment(): EnvironmentConfig | null {\n const config = getConfig();\n if (!config?.activeEnvironment) return null;\n return config.environments[config.activeEnvironment] ?? null;\n}\n\nexport function getConfigPath(): string {\n return getConfigFilePath();\n}\n\n/**\n * Diagnostic info about config storage state — for debugging config persistence failures.\n */\nexport function diagnoseConfig(): string[] {\n const lines: string[] = [];\n const filePath = getConfigFilePath();\n const filePresent = fileExists();\n\n lines.push(`file: ${filePath} (exists=${filePresent})`);\n\n if (filePresent) {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(content) as Partial<CliConfig>;\n const envCount = parsed.environments ? Object.keys(parsed.environments).length : 0;\n lines.push(`file config: active=${parsed.activeEnvironment ?? 'none'}, environments=${envCount}`);\n } catch (e) {\n lines.push(`file config: parse error — ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n\n try {\n const entry = getKeyringEntry();\n const data = entry.getPassword();\n if (data) {\n const parsed = JSON.parse(data) as Partial<CliConfig>;\n const envCount = parsed.environments ? Object.keys(parsed.environments).length : 0;\n lines.push(`keyring: found, active=${parsed.activeEnvironment ?? 'none'}, environments=${envCount}`);\n } else {\n lines.push('keyring: empty (getPassword returned null)');\n }\n } catch (e) {\n lines.push(`keyring: error — ${e instanceof Error ? e.message : String(e)}`);\n }\n\n lines.push(`insecureStorage=${forceInsecureStorage}`);\n return lines;\n}\n\n/**\n * Mark the active unclaimed environment as claimed.\n * Updates type to 'sandbox', removes the claim token, and renames\n * the environment key from 'unclaimed' to 'sandbox'.\n */\nexport function markEnvironmentClaimed(): void {\n const config = getConfig();\n if (!config?.activeEnvironment) return;\n const oldKey = config.activeEnvironment;\n const env = config.environments[oldKey];\n if (env && env.type === 'unclaimed') {\n // Pick a key that won't overwrite an existing environment\n let newKey = 'sandbox';\n if (oldKey !== newKey && config.environments[newKey]) {\n newKey = oldKey; // keep existing key if 'sandbox' is already taken\n }\n\n const claimed: ClaimedEnvironmentConfig = {\n name: newKey,\n type: 'sandbox',\n apiKey: env.apiKey,\n clientId: env.clientId,\n ...(env.endpoint && { endpoint: env.endpoint }),\n };\n\n if (oldKey !== newKey) {\n delete config.environments[oldKey];\n }\n config.environments[newKey] = claimed;\n config.activeEnvironment = newKey;\n\n saveConfig(config);\n }\n}\n"]}
1
+ {"version":3,"file":"config-store.js","sourceRoot":"","sources":["../../src/lib/config-store.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * CLI config storage abstraction with keyring support and file fallback.\n *\n * Stores environment configurations (names, API keys, endpoints) separately\n * from OAuth credentials. Uses a second keyring entry under the same service.\n *\n * Storage priority:\n * 1. If insecure storage forced: use file only\n * 2. Try keyring, fall back to file with warning if unavailable\n */\n\nimport { Entry } from '@napi-rs/keyring';\nimport fs from 'node:fs';\nimport path from 'node:path';\nimport os from 'node:os';\nimport { logWarn } from '../utils/debug.js';\nimport { observeHostFailure } from './host-probe.js';\n\ninterface BaseEnvironmentConfig {\n name: string;\n apiKey: string;\n endpoint?: string;\n /** Email of the account that owns this environment. Stamped when `auth login` provisions Staging for a known account; undefined for unclaimed/manually-added envs. */\n ownerEmail?: string;\n /** User ID of the account that owns this environment. Stamped alongside ownerEmail. */\n ownerUserId?: string;\n}\n\nexport interface ClaimedEnvironmentConfig extends BaseEnvironmentConfig {\n type: 'production' | 'sandbox';\n clientId?: string;\n}\n\nexport interface UnclaimedEnvironmentConfig extends BaseEnvironmentConfig {\n type: 'unclaimed';\n clientId: string;\n claimToken: string;\n}\n\nexport type EnvironmentConfig = ClaimedEnvironmentConfig | UnclaimedEnvironmentConfig;\n\n/**\n * Type guard — narrows to UnclaimedEnvironmentConfig with required clientId and claimToken.\n */\nexport function isUnclaimedEnvironment(env: EnvironmentConfig): env is UnclaimedEnvironmentConfig {\n return env.type === 'unclaimed';\n}\n\nexport interface CliConfig {\n activeEnvironment?: string;\n environments: Record<string, EnvironmentConfig>;\n}\n\nconst SERVICE_NAME = 'workos-cli';\nconst ACCOUNT_NAME = 'config';\n\nlet fallbackWarningShown = false;\nlet forceInsecureStorage = false;\nlet migrationAttempted = false;\n\nexport function setInsecureConfigStorage(value: boolean): void {\n forceInsecureStorage = value;\n migrationAttempted = false;\n}\n\nfunction getConfigDir(): string {\n return path.join(os.homedir(), '.workos');\n}\n\nfunction getConfigFilePath(): string {\n return path.join(getConfigDir(), 'config.json');\n}\n\nfunction fileExists(): boolean {\n return fs.existsSync(getConfigFilePath());\n}\n\nfunction readFromFile(): CliConfig | null {\n if (!fileExists()) return null;\n const filePath = getConfigFilePath();\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n return JSON.parse(content);\n } catch (error) {\n observeHostFailure('home-fs', error, {\n operation: 'read',\n target: filePath,\n label: 'config fallback file',\n });\n logWarn('Failed to read config file:', error);\n return null;\n }\n}\n\nfunction writeToFile(config: CliConfig): void {\n const dir = getConfigDir();\n const filePath = getConfigFilePath();\n try {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n fs.writeFileSync(filePath, JSON.stringify(config, null, 2), {\n mode: 0o600,\n });\n } catch (error) {\n observeHostFailure('home-fs', error, {\n operation: 'write',\n target: filePath,\n label: 'config fallback file',\n });\n throw error;\n }\n}\n\nfunction deleteFile(): void {\n const filePath = getConfigFilePath();\n if (fileExists()) {\n try {\n fs.unlinkSync(filePath);\n } catch (error) {\n observeHostFailure('home-fs', error, {\n operation: 'delete',\n target: filePath,\n label: 'config fallback file',\n });\n throw error;\n }\n }\n}\n\nfunction getKeyringEntry(): Entry {\n return new Entry(SERVICE_NAME, ACCOUNT_NAME);\n}\n\nfunction readFromKeyring(): CliConfig | null {\n try {\n const entry = getKeyringEntry();\n const data = entry.getPassword();\n if (!data) return null;\n return JSON.parse(data);\n } catch (error) {\n logWarn('Failed to read config from keyring:', error);\n observeHostFailure('keychain', error, {\n operation: 'read',\n target: `${SERVICE_NAME}/${ACCOUNT_NAME}`,\n label: 'config keychain entry',\n });\n return null;\n }\n}\n\nfunction writeToKeyring(config: CliConfig): boolean {\n try {\n const entry = getKeyringEntry();\n entry.setPassword(JSON.stringify(config));\n return true;\n } catch (error) {\n logWarn('Failed to write config to keyring:', error);\n observeHostFailure('keychain', error, {\n operation: 'write',\n target: `${SERVICE_NAME}/${ACCOUNT_NAME}`,\n label: 'config keychain entry',\n });\n return false;\n }\n}\n\nfunction deleteFromKeyring(): void {\n try {\n const entry = getKeyringEntry();\n entry.deletePassword();\n } catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n if (!msg.includes('not found') && !msg.includes('No such')) {\n logWarn('Failed to delete config from keyring:', error);\n observeHostFailure('keychain', error, {\n operation: 'delete',\n target: `${SERVICE_NAME}/${ACCOUNT_NAME}`,\n label: 'config keychain entry',\n });\n }\n }\n}\n\nfunction showFallbackWarning(): void {\n if (fallbackWarningShown || forceInsecureStorage) return;\n fallbackWarningShown = true;\n logWarn(\n 'Unable to store config in system keyring. Using file storage.',\n 'Config saved to ~/.workos/config.json',\n 'Use --insecure-storage to suppress this warning.',\n );\n}\n\nexport function getConfig(): CliConfig | null {\n if (forceInsecureStorage) return readFromFile();\n\n const keyringConfig = readFromKeyring();\n if (keyringConfig) return keyringConfig;\n\n const fileConfig = readFromFile();\n if (fileConfig) {\n if (!migrationAttempted) {\n migrationAttempted = true;\n writeToKeyring(fileConfig);\n }\n return fileConfig;\n }\n\n return null;\n}\n\nexport function saveConfig(config: CliConfig): void {\n if (forceInsecureStorage) return writeToFile(config);\n\n if (!writeToKeyring(config)) {\n showFallbackWarning();\n writeToFile(config);\n return;\n }\n\n // Verify the keyring write is readable (guards against silent keyring failures\n // where setPassword succeeds but getPassword returns null in the same process)\n if (!readFromKeyring()) {\n logWarn('Keyring write succeeded but read-back failed — falling back to file');\n writeToFile(config);\n }\n}\n\nexport function clearConfig(): void {\n deleteFromKeyring();\n deleteFile();\n migrationAttempted = false;\n}\n\nexport function getActiveEnvironment(): EnvironmentConfig | null {\n const config = getConfig();\n if (!config?.activeEnvironment) return null;\n return config.environments[config.activeEnvironment] ?? null;\n}\n\n/**\n * Set the active environment by name.\n *\n * No-op when there is no config or the named environment does not exist —\n * callers should not be able to point `activeEnvironment` at a missing key.\n */\nexport function setActiveEnvironment(name: string): void {\n const config = getConfig();\n if (!config || !config.environments[name]) return;\n config.activeEnvironment = name;\n saveConfig(config);\n}\n\n/** Pick a non-colliding environments key: `base`, else `base-2`, `base-3`, … */\nexport function freshEnvKey(config: CliConfig, base: string): string {\n if (!config.environments[base]) return base;\n let i = 2;\n while (config.environments[`${base}-${i}`]) i++;\n return `${base}-${i}`;\n}\n\nexport function getConfigPath(): string {\n return getConfigFilePath();\n}\n\n/**\n * Diagnostic info about config storage state — for debugging config persistence failures.\n */\nexport function diagnoseConfig(): string[] {\n const lines: string[] = [];\n const filePath = getConfigFilePath();\n const filePresent = fileExists();\n\n lines.push(`file: ${filePath} (exists=${filePresent})`);\n\n if (filePresent) {\n try {\n const content = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(content) as Partial<CliConfig>;\n const envCount = parsed.environments ? Object.keys(parsed.environments).length : 0;\n lines.push(`file config: active=${parsed.activeEnvironment ?? 'none'}, environments=${envCount}`);\n } catch (e) {\n lines.push(`file config: parse error — ${e instanceof Error ? e.message : String(e)}`);\n }\n }\n\n try {\n const entry = getKeyringEntry();\n const data = entry.getPassword();\n if (data) {\n const parsed = JSON.parse(data) as Partial<CliConfig>;\n const envCount = parsed.environments ? Object.keys(parsed.environments).length : 0;\n lines.push(`keyring: found, active=${parsed.activeEnvironment ?? 'none'}, environments=${envCount}`);\n } else {\n lines.push('keyring: empty (getPassword returned null)');\n }\n } catch (e) {\n lines.push(`keyring: error — ${e instanceof Error ? e.message : String(e)}`);\n }\n\n lines.push(`insecureStorage=${forceInsecureStorage}`);\n return lines;\n}\n\n/**\n * Mark the active unclaimed environment as claimed.\n * Updates type to 'sandbox', removes the claim token, and renames\n * the environment key from 'unclaimed' to 'sandbox'.\n */\nexport function markEnvironmentClaimed(): void {\n const config = getConfig();\n if (!config?.activeEnvironment) return;\n const oldKey = config.activeEnvironment;\n const env = config.environments[oldKey];\n if (env && env.type === 'unclaimed') {\n // Pick a key that won't overwrite an existing environment\n let newKey = 'sandbox';\n if (oldKey !== newKey && config.environments[newKey]) {\n newKey = oldKey; // keep existing key if 'sandbox' is already taken\n }\n\n const claimed: ClaimedEnvironmentConfig = {\n name: newKey,\n type: 'sandbox',\n apiKey: env.apiKey,\n clientId: env.clientId,\n ...(env.endpoint && { endpoint: env.endpoint }),\n ...(env.ownerEmail && { ownerEmail: env.ownerEmail }),\n ...(env.ownerUserId && { ownerUserId: env.ownerUserId }),\n };\n\n if (oldKey !== newKey) {\n delete config.environments[oldKey];\n }\n config.environments[newKey] = claimed;\n config.activeEnvironment = newKey;\n\n saveConfig(config);\n }\n}\n"]}
@@ -25,7 +25,7 @@ export type IntegrationConfig = {
25
25
  };
26
26
  /**
27
27
  * Legacy detection configs for existing JS integrations.
28
- * Used by clack-utils.ts for abort/cancel messages.
28
+ * Used by ui-utils.ts for abort/cancel messages.
29
29
  * New integrations do NOT need to be added here.
30
30
  */
31
31
  export declare const INTEGRATION_CONFIG: Record<string, {
@@ -9,7 +9,7 @@
9
9
  */
10
10
  /**
11
11
  * Legacy detection configs for existing JS integrations.
12
- * Used by clack-utils.ts for abort/cancel messages.
12
+ * Used by ui-utils.ts for abort/cancel messages.
13
13
  * New integrations do NOT need to be added here.
14
14
  */
15
15
  export const INTEGRATION_CONFIG = {
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoBH;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAsD;IACnF,MAAM,EAAE;QACN,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,wDAAwD;KAClE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,uDAAuD;KACjE;IACD,gBAAgB,EAAE;QAChB,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,gEAAgE;KAC1E;IACD,cAAc,EAAE;QACd,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,8DAA8D;KACxE;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,4DAA4D;KACtE;CACF,CAAC","sourcesContent":["/**\n * Integration detection configuration.\n *\n * This module previously held hardcoded INTEGRATION_CONFIG and INTEGRATION_ORDER.\n * These are now provided by the auto-discovery registry (src/lib/registry.ts).\n *\n * This file is kept for backwards compatibility — functions that previously\n * used INTEGRATION_CONFIG now delegate to the registry.\n */\n\nimport type { InstallerOptions } from '../utils/types.js';\n\n/**\n * @deprecated Use registry.detectionOrder() + config.detection.detect() instead.\n * This type is kept for any code that still references it.\n */\nexport type IntegrationConfig = {\n name: string;\n filterPatterns: string[];\n ignorePatterns: string[];\n detect: (options: Pick<InstallerOptions, 'installDir'>) => Promise<boolean>;\n generateFilesRules: string;\n filterFilesRules: string;\n docsUrl: string;\n nextSteps: string;\n defaultChanges: string;\n};\n\n/**\n * Legacy detection configs for existing JS integrations.\n * Used by clack-utils.ts for abort/cancel messages.\n * New integrations do NOT need to be added here.\n */\nexport const INTEGRATION_CONFIG: Record<string, { docsUrl: string; name: string }> = {\n nextjs: {\n name: 'Next.js',\n docsUrl: 'https://workos.com/docs/user-management/authkit/nextjs',\n },\n react: {\n name: 'React (SPA)',\n docsUrl: 'https://workos.com/docs/user-management/authkit/react',\n },\n 'tanstack-start': {\n name: 'TanStack Start',\n docsUrl: 'https://workos.com/docs/user-management/authkit/tanstack-start',\n },\n 'react-router': {\n name: 'React Router',\n docsUrl: 'https://workos.com/docs/user-management/authkit/react-router',\n },\n 'vanilla-js': {\n name: 'Vanilla JavaScript',\n docsUrl: 'https://workos.com/docs/user-management/authkit/javascript',\n },\n};\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAoBH;;;;GAIG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAsD;IACnF,MAAM,EAAE;QACN,IAAI,EAAE,SAAS;QACf,OAAO,EAAE,wDAAwD;KAClE;IACD,KAAK,EAAE;QACL,IAAI,EAAE,aAAa;QACnB,OAAO,EAAE,uDAAuD;KACjE;IACD,gBAAgB,EAAE;QAChB,IAAI,EAAE,gBAAgB;QACtB,OAAO,EAAE,gEAAgE;KAC1E;IACD,cAAc,EAAE;QACd,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,8DAA8D;KACxE;IACD,YAAY,EAAE;QACZ,IAAI,EAAE,oBAAoB;QAC1B,OAAO,EAAE,4DAA4D;KACtE;CACF,CAAC","sourcesContent":["/**\n * Integration detection configuration.\n *\n * This module previously held hardcoded INTEGRATION_CONFIG and INTEGRATION_ORDER.\n * These are now provided by the auto-discovery registry (src/lib/registry.ts).\n *\n * This file is kept for backwards compatibility — functions that previously\n * used INTEGRATION_CONFIG now delegate to the registry.\n */\n\nimport type { InstallerOptions } from '../utils/types.js';\n\n/**\n * @deprecated Use registry.detectionOrder() + config.detection.detect() instead.\n * This type is kept for any code that still references it.\n */\nexport type IntegrationConfig = {\n name: string;\n filterPatterns: string[];\n ignorePatterns: string[];\n detect: (options: Pick<InstallerOptions, 'installDir'>) => Promise<boolean>;\n generateFilesRules: string;\n filterFilesRules: string;\n docsUrl: string;\n nextSteps: string;\n defaultChanges: string;\n};\n\n/**\n * Legacy detection configs for existing JS integrations.\n * Used by ui-utils.ts for abort/cancel messages.\n * New integrations do NOT need to be added here.\n */\nexport const INTEGRATION_CONFIG: Record<string, { docsUrl: string; name: string }> = {\n nextjs: {\n name: 'Next.js',\n docsUrl: 'https://workos.com/docs/user-management/authkit/nextjs',\n },\n react: {\n name: 'React (SPA)',\n docsUrl: 'https://workos.com/docs/user-management/authkit/react',\n },\n 'tanstack-start': {\n name: 'TanStack Start',\n docsUrl: 'https://workos.com/docs/user-management/authkit/tanstack-start',\n },\n 'react-router': {\n name: 'React Router',\n docsUrl: 'https://workos.com/docs/user-management/authkit/react-router',\n },\n 'vanilla-js': {\n name: 'Vanilla JavaScript',\n docsUrl: 'https://workos.com/docs/user-management/authkit/javascript',\n },\n};\n"]}
@@ -27,6 +27,23 @@ export declare const ISSUES_URL: string;
27
27
  export declare const ANALYTICS_ENABLED: boolean;
28
28
  export declare const INSTALLER_INTERACTION_EVENT_NAME: string;
29
29
  export declare const OAUTH_PORT: number;
30
+ /**
31
+ * WorkOS MCP server identity, shared by the `mcp` command group and the
32
+ * per-client writers in `lib/mcp-clients.ts`.
33
+ *
34
+ * The server is secret-free: HTTP transport with OAuth handled by each client
35
+ * on first connect, so configuring it never requires CLI auth.
36
+ */
37
+ export declare const MCP_SERVER_NAME = "workos";
38
+ export declare const MCP_SERVER_URL = "https://mcp.workos.com/mcp";
39
+ /**
40
+ * Shared description for the `migrations` command, referenced by both the yargs
41
+ * registration (`bin.ts`) and the JSON help registry (`help-json.ts`) so the two
42
+ * surfaces cannot drift. Advertises the generic-CSV path (e.g. Supabase) without
43
+ * implying a dedicated exporter exists for it. Hand-maintained — not derived from
44
+ * `@workos/migrations`.
45
+ */
46
+ export declare const MIGRATIONS_DESCRIPTION = "Migrate users to WorkOS from Auth0, Cognito, Clerk, Firebase, or any provider via CSV (e.g. Supabase)";
30
47
  /**
31
48
  * Common glob patterns to ignore when searching for files.
32
49
  * Used by multiple integrations.
@@ -19,6 +19,23 @@ export const ISSUES_URL = settings.documentation.issuesUrl;
19
19
  export const ANALYTICS_ENABLED = settings.telemetry.enabled;
20
20
  export const INSTALLER_INTERACTION_EVENT_NAME = settings.telemetry.eventName;
21
21
  export const OAUTH_PORT = settings.legacy.oauthPort;
22
+ /**
23
+ * WorkOS MCP server identity, shared by the `mcp` command group and the
24
+ * per-client writers in `lib/mcp-clients.ts`.
25
+ *
26
+ * The server is secret-free: HTTP transport with OAuth handled by each client
27
+ * on first connect, so configuring it never requires CLI auth.
28
+ */
29
+ export const MCP_SERVER_NAME = 'workos';
30
+ export const MCP_SERVER_URL = 'https://mcp.workos.com/mcp';
31
+ /**
32
+ * Shared description for the `migrations` command, referenced by both the yargs
33
+ * registration (`bin.ts`) and the JSON help registry (`help-json.ts`) so the two
34
+ * surfaces cannot drift. Advertises the generic-CSV path (e.g. Supabase) without
35
+ * implying a dedicated exporter exists for it. Hand-maintained — not derived from
36
+ * `@workos/migrations`.
37
+ */
38
+ export const MIGRATIONS_DESCRIPTION = 'Migrate users to WorkOS from Auth0, Cognito, Clerk, Firebase, or any provider via CSV (e.g. Supabase)';
22
39
  /**
23
40
  * Common glob patterns to ignore when searching for files.
24
41
  * Used by multiple integrations.
@@ -1 +1 @@
1
- {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAS1C;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,aAAa,EAAE,gBAAgB;IAC/B,WAAW,EAAE,cAAc;IAC3B,SAAS,EAAE,YAAY;CACf,CAAC;AAOX,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AAEnF,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;AAE7B,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;AAChD,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC;AACxE,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC;AAC3D,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC;AAC5D,MAAM,CAAC,MAAM,gCAAgC,GAAG,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC;AAC7E,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;AAEpD;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAa;IACvC,oBAAoB;IACpB,YAAY;IACZ,aAAa;IACb,cAAc;IACd,aAAa;CACd,CAAC","sourcesContent":["import { getConfig } from './settings.js';\n\n/**\n * Integration identifier type.\n * No longer an enum — each integration self-registers via the auto-discovery registry.\n * The string value matches the integration directory name (e.g., 'nextjs', 'react-router').\n */\nexport type Integration = string;\n\n/**\n * Well-known integration names for backwards compatibility.\n * New integrations do NOT need to be added here — they're auto-discovered.\n */\nexport const KNOWN_INTEGRATIONS = {\n nextjs: 'nextjs',\n react: 'react',\n tanstackStart: 'tanstack-start',\n reactRouter: 'react-router',\n vanillaJs: 'vanilla-js',\n} as const;\n\nexport interface Args {\n debug: boolean;\n integration: Integration;\n}\n\nexport const IS_DEV = ['test', 'development'].includes(process.env.NODE_ENV ?? '');\n\nconst settings = getConfig();\n\nexport const DEBUG = settings.logging.debugMode;\nexport const WORKOS_DOCS_URL = settings.documentation.workosDocsUrl;\nexport const WORKOS_DASHBOARD_URL = settings.documentation.dashboardUrl;\nexport const ISSUES_URL = settings.documentation.issuesUrl;\nexport const ANALYTICS_ENABLED = settings.telemetry.enabled;\nexport const INSTALLER_INTERACTION_EVENT_NAME = settings.telemetry.eventName;\nexport const OAUTH_PORT = settings.legacy.oauthPort;\n\n/**\n * Common glob patterns to ignore when searching for files.\n * Used by multiple integrations.\n */\nexport const IGNORE_PATTERNS: string[] = [\n '**/node_modules/**',\n '**/dist/**',\n '**/build/**',\n '**/public/**',\n '**/.next/**',\n];\n"]}
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/lib/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAS1C;;;GAGG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,MAAM,EAAE,QAAQ;IAChB,KAAK,EAAE,OAAO;IACd,aAAa,EAAE,gBAAgB;IAC/B,WAAW,EAAE,cAAc;IAC3B,SAAS,EAAE,YAAY;CACf,CAAC;AAOX,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;AAEnF,MAAM,QAAQ,GAAG,SAAS,EAAE,CAAC;AAE7B,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;AAChD,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,aAAa,CAAC;AACpE,MAAM,CAAC,MAAM,oBAAoB,GAAG,QAAQ,CAAC,aAAa,CAAC,YAAY,CAAC;AACxE,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC,aAAa,CAAC,SAAS,CAAC;AAC3D,MAAM,CAAC,MAAM,iBAAiB,GAAG,QAAQ,CAAC,SAAS,CAAC,OAAO,CAAC;AAC5D,MAAM,CAAC,MAAM,gCAAgC,GAAG,QAAQ,CAAC,SAAS,CAAC,SAAS,CAAC;AAC7E,MAAM,CAAC,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC;AAEpD;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC;AACxC,MAAM,CAAC,MAAM,cAAc,GAAG,4BAA4B,CAAC;AAE3D;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,sBAAsB,GACjC,uGAAuG,CAAC;AAE1G;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAa;IACvC,oBAAoB;IACpB,YAAY;IACZ,aAAa;IACb,cAAc;IACd,aAAa;CACd,CAAC","sourcesContent":["import { getConfig } from './settings.js';\n\n/**\n * Integration identifier type.\n * No longer an enum — each integration self-registers via the auto-discovery registry.\n * The string value matches the integration directory name (e.g., 'nextjs', 'react-router').\n */\nexport type Integration = string;\n\n/**\n * Well-known integration names for backwards compatibility.\n * New integrations do NOT need to be added here — they're auto-discovered.\n */\nexport const KNOWN_INTEGRATIONS = {\n nextjs: 'nextjs',\n react: 'react',\n tanstackStart: 'tanstack-start',\n reactRouter: 'react-router',\n vanillaJs: 'vanilla-js',\n} as const;\n\nexport interface Args {\n debug: boolean;\n integration: Integration;\n}\n\nexport const IS_DEV = ['test', 'development'].includes(process.env.NODE_ENV ?? '');\n\nconst settings = getConfig();\n\nexport const DEBUG = settings.logging.debugMode;\nexport const WORKOS_DOCS_URL = settings.documentation.workosDocsUrl;\nexport const WORKOS_DASHBOARD_URL = settings.documentation.dashboardUrl;\nexport const ISSUES_URL = settings.documentation.issuesUrl;\nexport const ANALYTICS_ENABLED = settings.telemetry.enabled;\nexport const INSTALLER_INTERACTION_EVENT_NAME = settings.telemetry.eventName;\nexport const OAUTH_PORT = settings.legacy.oauthPort;\n\n/**\n * WorkOS MCP server identity, shared by the `mcp` command group and the\n * per-client writers in `lib/mcp-clients.ts`.\n *\n * The server is secret-free: HTTP transport with OAuth handled by each client\n * on first connect, so configuring it never requires CLI auth.\n */\nexport const MCP_SERVER_NAME = 'workos';\nexport const MCP_SERVER_URL = 'https://mcp.workos.com/mcp';\n\n/**\n * Shared description for the `migrations` command, referenced by both the yargs\n * registration (`bin.ts`) and the JSON help registry (`help-json.ts`) so the two\n * surfaces cannot drift. Advertises the generic-CSV path (e.g. Supabase) without\n * implying a dedicated exporter exists for it. Hand-maintained — not derived from\n * `@workos/migrations`.\n */\nexport const MIGRATIONS_DESCRIPTION =\n 'Migrate users to WorkOS from Auth0, Cognito, Clerk, Firebase, or any provider via CSV (e.g. Supabase)';\n\n/**\n * Common glob patterns to ignore when searching for files.\n * Used by multiple integrations.\n */\nexport const IGNORE_PATTERNS: string[] = [\n '**/node_modules/**',\n '**/dist/**',\n '**/build/**',\n '**/public/**',\n '**/.next/**',\n];\n"]}
@@ -1,4 +1,30 @@
1
1
  import { EventEmitter } from 'events';
2
+ /**
3
+ * Structured data describing a successful installation, used to render the
4
+ * completion summary and enrich the headless `complete` NDJSON event.
5
+ *
6
+ * Defined here (not in installer-core.types.ts) to avoid an import cycle:
7
+ * installer-core.types.ts already imports from this module, so this module
8
+ * must not import back.
9
+ */
10
+ export interface CompletionData {
11
+ /** Integration identifier (e.g. 'nextjs') */
12
+ integration: string;
13
+ /** Lockfile-aware dev command, e.g. "pnpm run dev" */
14
+ devCommand: string;
15
+ /** App URL with the detected port, e.g. "http://localhost:3000" */
16
+ url: string;
17
+ /** Changed files (git-relative), full list — display cap lives in the renderer */
18
+ files: string[];
19
+ /** Composed concrete + framework next-step lines */
20
+ nextSteps: string[];
21
+ /** Per-framework docs URL */
22
+ docsUrl: string;
23
+ /** WorkOS dashboard URL */
24
+ dashboardUrl: string;
25
+ /** Optional per-framework "add a sign-in link" snippet */
26
+ signInSnippet?: string;
27
+ }
2
28
  export interface InstallerEvents {
3
29
  status: {
4
30
  message: string;
@@ -45,6 +71,7 @@ export interface InstallerEvents {
45
71
  complete: {
46
72
  success: boolean;
47
73
  summary?: string;
74
+ completion?: CompletionData;
48
75
  };
49
76
  error: {
50
77
  message: string;
@@ -103,7 +130,9 @@ export interface InstallerEvents {
103
130
  message: string;
104
131
  };
105
132
  'staging:fetching': Record<string, never>;
106
- 'staging:success': Record<string, never>;
133
+ 'staging:success': {
134
+ source?: 'device' | 'stored';
135
+ };
107
136
  'staging:error': {
108
137
  message: string;
109
138
  statusCode?: number;
@@ -126,6 +155,10 @@ export interface InstallerEvents {
126
155
  attempt: number;
127
156
  maxRetries: number;
128
157
  };
158
+ 'agent:tool': {
159
+ kind: 'command';
160
+ detail: string;
161
+ };
129
162
  'validation:retry:start': {
130
163
  attempt: number;
131
164
  };
@@ -1 +1 @@
1
- {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/lib/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAoGtC,MAAM,OAAO,qBAAsB,SAAQ,YAAY;IACrD,IAAI,CAA+B,KAAQ,EAAE,OAA2B;QACtE,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,EAAE,CAA+B,KAAQ,EAAE,QAA+C;QACxF,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,GAAG,CAA+B,KAAQ,EAAE,QAA+C;QACzF,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,CAA+B,KAAQ,EAAE,QAA+C;QAC1F,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;CACF;AAED,MAAM,UAAU,2BAA2B;IACzC,OAAO,IAAI,qBAAqB,EAAE,CAAC;AACrC,CAAC","sourcesContent":["import { EventEmitter } from 'events';\n\nexport interface InstallerEvents {\n status: { message: string };\n output: { text: string; isError?: boolean };\n 'file:write': { path: string; content: string };\n 'file:edit': { path: string; oldContent: string; newContent: string };\n 'prompt:request': { id: string; message: string; options?: string[] };\n 'prompt:response': { id: string; value: string };\n 'confirm:request': { id: string; message: string; warning?: string; files?: string[] };\n 'confirm:response': { id: string; confirmed: boolean };\n 'credentials:request': { requiresApiKey: boolean };\n 'credentials:response': { apiKey: string; clientId: string };\n complete: { success: boolean; summary?: string };\n error: { message: string; stack?: string };\n\n 'state:enter': { state: string };\n 'state:exit': { state: string };\n 'auth:checking': Record<string, never>;\n 'auth:required': Record<string, never>;\n 'auth:success': Record<string, never>;\n 'auth:failure': { message: string };\n 'detection:start': Record<string, never>;\n 'detection:complete': { integration: string };\n 'detection:none': Record<string, never>;\n 'git:checking': Record<string, never>;\n 'git:clean': Record<string, never>;\n 'git:dirty': { files: string[] };\n 'git:dirty:confirmed': Record<string, never>;\n 'git:dirty:cancelled': Record<string, never>;\n 'credentials:gathering': { requiresApiKey: boolean };\n 'credentials:found': Record<string, never>;\n // Credential discovery events\n 'credentials:env:detected': { files: string[] };\n 'credentials:env:prompt': { files: string[] };\n 'credentials:env:scanning': Record<string, never>;\n 'credentials:env:found': { sourcePath: string };\n 'credentials:env:notfound': Record<string, never>;\n // Device auth events\n 'device:started': { verificationUri: string; verificationUriComplete: string; userCode: string };\n 'device:polling': Record<string, never>;\n 'device:success': { email?: string };\n 'device:timeout': Record<string, never>;\n 'device:error': { message: string };\n // Staging API events\n 'staging:fetching': Record<string, never>;\n 'staging:success': Record<string, never>;\n 'staging:error': { message: string; statusCode?: number };\n 'config:start': Record<string, never>;\n 'config:complete': Record<string, never>;\n 'agent:start': Record<string, never>;\n 'agent:progress': { step: string; detail?: string };\n 'agent:success': { summary?: string };\n 'agent:failure': { message: string; stack?: string };\n 'agent:retry': { attempt: number; maxRetries: number };\n\n 'validation:retry:start': { attempt: number };\n 'validation:retry:complete': { attempt: number; passed: boolean };\n\n 'validation:start': { framework: string };\n 'validation:issues': { issues: import('./validation/types.js').ValidationIssue[] };\n 'validation:complete': { passed: boolean; issueCount: number; durationMs: number };\n\n // Scaffold events (empty-directory app scaffolding)\n 'scaffold:checking': Record<string, never>;\n 'scaffold:prompt': { packageManager: string };\n 'scaffold:start': { packageManager: string };\n 'scaffold:progress': { text: string };\n 'scaffold:complete': Record<string, never>;\n 'scaffold:failed': { error: string };\n 'scaffold:skipped': Record<string, never>;\n\n // Branch check events\n 'branch:checking': Record<string, never>;\n 'branch:protected': { branch: string };\n 'branch:prompt': { branch: string };\n 'branch:created': { branch: string };\n 'branch:create:failed': { error: string };\n 'branch:skipped': Record<string, never>;\n\n // Post-install events\n 'postinstall:changes': { files: string[] };\n 'postinstall:nochanges': Record<string, never>;\n 'postinstall:commit:prompt': Record<string, never>;\n 'postinstall:commit:generating': Record<string, never>;\n 'postinstall:commit:committing': { message: string };\n 'postinstall:commit:success': { message: string };\n 'postinstall:commit:failed': { error: string };\n 'postinstall:pr:prompt': Record<string, never>;\n 'postinstall:pr:generating': Record<string, never>;\n 'postinstall:pr:pushing': Record<string, never>;\n 'postinstall:pr:creating': Record<string, never>;\n 'postinstall:pr:success': { url: string };\n 'postinstall:pr:failed': { error: string };\n 'postinstall:push:failed': { error: string };\n 'postinstall:manual': { instructions: string };\n}\n\nexport type InstallerEventName = keyof InstallerEvents;\n\nexport class InstallerEventEmitter extends EventEmitter {\n emit<K extends InstallerEventName>(event: K, payload: InstallerEvents[K]): boolean {\n return super.emit(event, payload);\n }\n\n on<K extends InstallerEventName>(event: K, listener: (payload: InstallerEvents[K]) => void): this {\n return super.on(event, listener);\n }\n\n off<K extends InstallerEventName>(event: K, listener: (payload: InstallerEvents[K]) => void): this {\n return super.off(event, listener);\n }\n\n once<K extends InstallerEventName>(event: K, listener: (payload: InstallerEvents[K]) => void): this {\n return super.once(event, listener);\n }\n}\n\nexport function createInstallerEventEmitter(): InstallerEventEmitter {\n return new InstallerEventEmitter();\n}\n"]}
1
+ {"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/lib/events.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAiItC,MAAM,OAAO,qBAAsB,SAAQ,YAAY;IACrD,IAAI,CAA+B,KAAQ,EAAE,OAA2B;QACtE,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,EAAE,CAA+B,KAAQ,EAAE,QAA+C;QACxF,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACnC,CAAC;IAED,GAAG,CAA+B,KAAQ,EAAE,QAA+C;QACzF,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACpC,CAAC;IAED,IAAI,CAA+B,KAAQ,EAAE,QAA+C;QAC1F,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACrC,CAAC;CACF;AAED,MAAM,UAAU,2BAA2B;IACzC,OAAO,IAAI,qBAAqB,EAAE,CAAC;AACrC,CAAC","sourcesContent":["import { EventEmitter } from 'events';\n\n/**\n * Structured data describing a successful installation, used to render the\n * completion summary and enrich the headless `complete` NDJSON event.\n *\n * Defined here (not in installer-core.types.ts) to avoid an import cycle:\n * installer-core.types.ts already imports from this module, so this module\n * must not import back.\n */\nexport interface CompletionData {\n /** Integration identifier (e.g. 'nextjs') */\n integration: string;\n /** Lockfile-aware dev command, e.g. \"pnpm run dev\" */\n devCommand: string;\n /** App URL with the detected port, e.g. \"http://localhost:3000\" */\n url: string;\n /** Changed files (git-relative), full list — display cap lives in the renderer */\n files: string[];\n /** Composed concrete + framework next-step lines */\n nextSteps: string[];\n /** Per-framework docs URL */\n docsUrl: string;\n /** WorkOS dashboard URL */\n dashboardUrl: string;\n /** Optional per-framework \"add a sign-in link\" snippet */\n signInSnippet?: string;\n}\n\nexport interface InstallerEvents {\n status: { message: string };\n output: { text: string; isError?: boolean };\n 'file:write': { path: string; content: string };\n 'file:edit': { path: string; oldContent: string; newContent: string };\n 'prompt:request': { id: string; message: string; options?: string[] };\n 'prompt:response': { id: string; value: string };\n 'confirm:request': { id: string; message: string; warning?: string; files?: string[] };\n 'confirm:response': { id: string; confirmed: boolean };\n 'credentials:request': { requiresApiKey: boolean };\n 'credentials:response': { apiKey: string; clientId: string };\n complete: { success: boolean; summary?: string; completion?: CompletionData };\n error: { message: string; stack?: string };\n\n 'state:enter': { state: string };\n 'state:exit': { state: string };\n 'auth:checking': Record<string, never>;\n 'auth:required': Record<string, never>;\n 'auth:success': Record<string, never>;\n 'auth:failure': { message: string };\n 'detection:start': Record<string, never>;\n 'detection:complete': { integration: string };\n 'detection:none': Record<string, never>;\n 'git:checking': Record<string, never>;\n 'git:clean': Record<string, never>;\n 'git:dirty': { files: string[] };\n 'git:dirty:confirmed': Record<string, never>;\n 'git:dirty:cancelled': Record<string, never>;\n 'credentials:gathering': { requiresApiKey: boolean };\n 'credentials:found': Record<string, never>;\n // Credential discovery events\n 'credentials:env:detected': { files: string[] };\n 'credentials:env:prompt': { files: string[] };\n 'credentials:env:scanning': Record<string, never>;\n 'credentials:env:found': { sourcePath: string };\n 'credentials:env:notfound': Record<string, never>;\n // Device auth events\n 'device:started': { verificationUri: string; verificationUriComplete: string; userCode: string };\n 'device:polling': Record<string, never>;\n 'device:success': { email?: string };\n 'device:timeout': Record<string, never>;\n 'device:error': { message: string };\n // Staging API events\n 'staging:fetching': Record<string, never>;\n 'staging:success': { source?: 'device' | 'stored' };\n 'staging:error': { message: string; statusCode?: number };\n 'config:start': Record<string, never>;\n 'config:complete': Record<string, never>;\n 'agent:start': Record<string, never>;\n 'agent:progress': { step: string; detail?: string };\n 'agent:success': { summary?: string };\n 'agent:failure': { message: string; stack?: string };\n 'agent:retry': { attempt: number; maxRetries: number };\n // Surfaced agent tool activity (e.g. Bash commands run during install)\n 'agent:tool': { kind: 'command'; detail: string };\n\n 'validation:retry:start': { attempt: number };\n 'validation:retry:complete': { attempt: number; passed: boolean };\n\n 'validation:start': { framework: string };\n 'validation:issues': { issues: import('./validation/types.js').ValidationIssue[] };\n 'validation:complete': { passed: boolean; issueCount: number; durationMs: number };\n\n // Scaffold events (empty-directory app scaffolding)\n 'scaffold:checking': Record<string, never>;\n 'scaffold:prompt': { packageManager: string };\n 'scaffold:start': { packageManager: string };\n 'scaffold:progress': { text: string };\n 'scaffold:complete': Record<string, never>;\n 'scaffold:failed': { error: string };\n 'scaffold:skipped': Record<string, never>;\n\n // Branch check events\n 'branch:checking': Record<string, never>;\n 'branch:protected': { branch: string };\n 'branch:prompt': { branch: string };\n 'branch:created': { branch: string };\n 'branch:create:failed': { error: string };\n 'branch:skipped': Record<string, never>;\n\n // Post-install events\n 'postinstall:changes': { files: string[] };\n 'postinstall:nochanges': Record<string, never>;\n 'postinstall:commit:prompt': Record<string, never>;\n 'postinstall:commit:generating': Record<string, never>;\n 'postinstall:commit:committing': { message: string };\n 'postinstall:commit:success': { message: string };\n 'postinstall:commit:failed': { error: string };\n 'postinstall:pr:prompt': Record<string, never>;\n 'postinstall:pr:generating': Record<string, never>;\n 'postinstall:pr:pushing': Record<string, never>;\n 'postinstall:pr:creating': Record<string, never>;\n 'postinstall:pr:success': { url: string };\n 'postinstall:pr:failed': { error: string };\n 'postinstall:push:failed': { error: string };\n 'postinstall:manual': { instructions: string };\n}\n\nexport type InstallerEventName = keyof InstallerEvents;\n\nexport class InstallerEventEmitter extends EventEmitter {\n emit<K extends InstallerEventName>(event: K, payload: InstallerEvents[K]): boolean {\n return super.emit(event, payload);\n }\n\n on<K extends InstallerEventName>(event: K, listener: (payload: InstallerEvents[K]) => void): this {\n return super.on(event, listener);\n }\n\n off<K extends InstallerEventName>(event: K, listener: (payload: InstallerEvents[K]) => void): this {\n return super.off(event, listener);\n }\n\n once<K extends InstallerEventName>(event: K, listener: (payload: InstallerEvents[K]) => void): this {\n return super.once(event, listener);\n }\n}\n\nexport function createInstallerEventEmitter(): InstallerEventEmitter {\n return new InstallerEventEmitter();\n}\n"]}
@@ -116,6 +116,12 @@ export interface UIConfig {
116
116
  getOutroChanges: (context: any) => string[];
117
117
  /** Generate "Next steps" bullets from context */
118
118
  getOutroNextSteps: (context: any) => string[];
119
+ /**
120
+ * Optional per-framework "add a sign-in link" snippet, surfaced as a next
121
+ * step in the completion summary. Only defined for frameworks that scaffold
122
+ * interactive auth UI. Copy must stay accurate to what the agent scaffolds.
123
+ */
124
+ getSignInSnippet?: (context: any) => string;
119
125
  }
120
126
  /**
121
127
  * Generate welcome message from framework name
@@ -1 +1 @@
1
- {"version":3,"file":"framework-config.js","sourceRoot":"","sources":["../../src/lib/framework-config.ts"],"names":[],"mappings":"AAmJA;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,aAAqB;IACrD,OAAO,kBAAkB,aAAa,4BAA4B,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,iFAAiF,CAAC","sourcesContent":["import type { InstallerOptions } from '../utils/types.js';\n\n/**\n * Supported programming languages for framework integrations.\n */\nexport type Language = 'javascript' | 'python' | 'ruby' | 'php' | 'go' | 'kotlin' | 'dotnet' | 'elixir';\n\n/**\n * Configuration interface for framework-specific agent integrations.\n * Each framework exports a FrameworkConfig that the universal runner uses.\n */\nexport interface FrameworkConfig {\n metadata: FrameworkMetadata;\n detection: FrameworkDetection;\n environment: EnvironmentConfig;\n analytics: AnalyticsConfig;\n prompts: PromptConfig;\n ui: UIConfig;\n}\n\n/**\n * Basic framework information and documentation\n */\nexport interface FrameworkMetadata {\n /** Display name (e.g., \"Next.js\", \"React\") */\n name: string;\n\n /** Integration identifier (e.g., 'nextjs', 'python'). String, not enum — auto-discovered from registry. */\n integration: string;\n\n /** URL to framework-specific WorkOS AuthKit docs */\n docsUrl: string;\n\n /**\n * Optional URL to docs for users with unsupported framework versions.\n * If not provided, defaults to docsUrl.\n */\n unsupportedVersionDocsUrl?: string;\n\n /**\n * Optional function to gather framework-specific context before agent runs.\n * For Next.js: detects router type\n * For React Native: detects Expo vs bare\n */\n gatherContext?: (options: InstallerOptions) => Promise<Record<string, any>>;\n\n /**\n * Name of the framework-specific skill for agent integration.\n * Skills are located in .claude/skills/{skillName}/SKILL.md\n */\n skillName?: string;\n\n /** Language ecosystem this integration belongs to */\n language: Language;\n\n /** Stability tier: 'stable' for tested integrations, 'experimental' for new ones */\n stability: 'stable' | 'experimental';\n\n /** Detection priority — higher numbers are checked first */\n priority: number;\n\n /** Default package manager command (e.g., 'pip', 'gem', 'go'). Optional for JS integrations. */\n packageManager?: string;\n\n /** Primary manifest file (e.g., 'pyproject.toml', 'Gemfile'). Optional for JS integrations. */\n manifestFile?: string;\n\n /**\n * Optional custom detection override for non-JS integrations. When present,\n * the registry calls this instead of falling back to `manifestFile` existence.\n * Use when a single manifest file isn't enough (e.g., Django projects may\n * use `manage.py` + `requirements.txt` without a `pyproject.toml`).\n */\n detect?: (options: Pick<InstallerOptions, 'installDir'>) => boolean | Promise<boolean>;\n}\n\n/**\n * Framework detection and version handling\n */\nexport interface FrameworkDetection {\n /** Package name to check in package.json (e.g., \"next\", \"react\") */\n packageName: string;\n\n /** Human-readable name for error messages (e.g., \"Next.js\") */\n packageDisplayName: string;\n\n /** Extract version from package.json */\n getVersion: (packageJson: any) => string | undefined;\n\n /** Optional: Convert version to analytics bucket (e.g., \"15.x\") */\n getVersionBucket?: (version: string) => string;\n}\n\n/**\n * Environment variable configuration\n */\nexport interface EnvironmentConfig {\n /** Whether to upload env vars to hosting providers post-agent */\n uploadToHosting: boolean;\n\n /** Whether this framework requires API key (false for client-only SDKs) */\n requiresApiKey: boolean;\n\n /**\n * Build the environment variables object for this framework.\n * Returns the exact variable names and values to upload to hosting providers.\n */\n getEnvVars: (apiKey: string, clientId: string) => Record<string, string>;\n}\n\n/**\n * Analytics configuration\n */\nexport interface AnalyticsConfig {\n /** Generate tags from context (e.g., { 'nextjs-version': '15.x', 'router': 'app' }) */\n getTags: (context: any) => Record<string, any>;\n\n /** Optional: Additional event properties */\n getEventProperties?: (context: any) => Record<string, any>;\n}\n\n/**\n * Prompt configuration\n */\nexport interface PromptConfig {\n /**\n * Optional: Additional context lines to append to base prompt\n * For Next.js: \"- Router: app\"\n * For React Native: \"- Platform: Expo\"\n */\n getAdditionalContextLines?: (context: any) => string[];\n}\n\n/**\n * UI messaging configuration\n */\nexport interface UIConfig {\n /** Success message when agent completes */\n successMessage: string;\n\n /** Generate \"What the agent did\" bullets from context */\n getOutroChanges: (context: any) => string[];\n\n /** Generate \"Next steps\" bullets from context */\n getOutroNextSteps: (context: any) => string[];\n}\n\n/**\n * Generate welcome message from framework name\n */\nexport function getWelcomeMessage(frameworkName: string): string {\n return `WorkOS AuthKit ${frameworkName} installer (agent-powered)`;\n}\n\n/**\n * Shared spinner message for all frameworks\n */\nexport const SPINNER_MESSAGE = 'Setting up WorkOS AuthKit with login, authentication, and session management...';\n"]}
1
+ {"version":3,"file":"framework-config.js","sourceRoot":"","sources":["../../src/lib/framework-config.ts"],"names":[],"mappings":"AA0JA;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,aAAqB;IACrD,OAAO,kBAAkB,aAAa,4BAA4B,CAAC;AACrE,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,MAAM,eAAe,GAAG,iFAAiF,CAAC","sourcesContent":["import type { InstallerOptions } from '../utils/types.js';\n\n/**\n * Supported programming languages for framework integrations.\n */\nexport type Language = 'javascript' | 'python' | 'ruby' | 'php' | 'go' | 'kotlin' | 'dotnet' | 'elixir';\n\n/**\n * Configuration interface for framework-specific agent integrations.\n * Each framework exports a FrameworkConfig that the universal runner uses.\n */\nexport interface FrameworkConfig {\n metadata: FrameworkMetadata;\n detection: FrameworkDetection;\n environment: EnvironmentConfig;\n analytics: AnalyticsConfig;\n prompts: PromptConfig;\n ui: UIConfig;\n}\n\n/**\n * Basic framework information and documentation\n */\nexport interface FrameworkMetadata {\n /** Display name (e.g., \"Next.js\", \"React\") */\n name: string;\n\n /** Integration identifier (e.g., 'nextjs', 'python'). String, not enum — auto-discovered from registry. */\n integration: string;\n\n /** URL to framework-specific WorkOS AuthKit docs */\n docsUrl: string;\n\n /**\n * Optional URL to docs for users with unsupported framework versions.\n * If not provided, defaults to docsUrl.\n */\n unsupportedVersionDocsUrl?: string;\n\n /**\n * Optional function to gather framework-specific context before agent runs.\n * For Next.js: detects router type\n * For React Native: detects Expo vs bare\n */\n gatherContext?: (options: InstallerOptions) => Promise<Record<string, any>>;\n\n /**\n * Name of the framework-specific skill for agent integration.\n * Skills are located in .claude/skills/{skillName}/SKILL.md\n */\n skillName?: string;\n\n /** Language ecosystem this integration belongs to */\n language: Language;\n\n /** Stability tier: 'stable' for tested integrations, 'experimental' for new ones */\n stability: 'stable' | 'experimental';\n\n /** Detection priority — higher numbers are checked first */\n priority: number;\n\n /** Default package manager command (e.g., 'pip', 'gem', 'go'). Optional for JS integrations. */\n packageManager?: string;\n\n /** Primary manifest file (e.g., 'pyproject.toml', 'Gemfile'). Optional for JS integrations. */\n manifestFile?: string;\n\n /**\n * Optional custom detection override for non-JS integrations. When present,\n * the registry calls this instead of falling back to `manifestFile` existence.\n * Use when a single manifest file isn't enough (e.g., Django projects may\n * use `manage.py` + `requirements.txt` without a `pyproject.toml`).\n */\n detect?: (options: Pick<InstallerOptions, 'installDir'>) => boolean | Promise<boolean>;\n}\n\n/**\n * Framework detection and version handling\n */\nexport interface FrameworkDetection {\n /** Package name to check in package.json (e.g., \"next\", \"react\") */\n packageName: string;\n\n /** Human-readable name for error messages (e.g., \"Next.js\") */\n packageDisplayName: string;\n\n /** Extract version from package.json */\n getVersion: (packageJson: any) => string | undefined;\n\n /** Optional: Convert version to analytics bucket (e.g., \"15.x\") */\n getVersionBucket?: (version: string) => string;\n}\n\n/**\n * Environment variable configuration\n */\nexport interface EnvironmentConfig {\n /** Whether to upload env vars to hosting providers post-agent */\n uploadToHosting: boolean;\n\n /** Whether this framework requires API key (false for client-only SDKs) */\n requiresApiKey: boolean;\n\n /**\n * Build the environment variables object for this framework.\n * Returns the exact variable names and values to upload to hosting providers.\n */\n getEnvVars: (apiKey: string, clientId: string) => Record<string, string>;\n}\n\n/**\n * Analytics configuration\n */\nexport interface AnalyticsConfig {\n /** Generate tags from context (e.g., { 'nextjs-version': '15.x', 'router': 'app' }) */\n getTags: (context: any) => Record<string, any>;\n\n /** Optional: Additional event properties */\n getEventProperties?: (context: any) => Record<string, any>;\n}\n\n/**\n * Prompt configuration\n */\nexport interface PromptConfig {\n /**\n * Optional: Additional context lines to append to base prompt\n * For Next.js: \"- Router: app\"\n * For React Native: \"- Platform: Expo\"\n */\n getAdditionalContextLines?: (context: any) => string[];\n}\n\n/**\n * UI messaging configuration\n */\nexport interface UIConfig {\n /** Success message when agent completes */\n successMessage: string;\n\n /** Generate \"What the agent did\" bullets from context */\n getOutroChanges: (context: any) => string[];\n\n /** Generate \"Next steps\" bullets from context */\n getOutroNextSteps: (context: any) => string[];\n\n /**\n * Optional per-framework \"add a sign-in link\" snippet, surfaced as a next\n * step in the completion summary. Only defined for frameworks that scaffold\n * interactive auth UI. Copy must stay accurate to what the agent scaffolds.\n */\n getSignInSnippet?: (context: any) => string;\n}\n\n/**\n * Generate welcome message from framework name\n */\nexport function getWelcomeMessage(frameworkName: string): string {\n return `WorkOS AuthKit ${frameworkName} installer (agent-powered)`;\n}\n\n/**\n * Shared spinner message for all frameworks\n */\nexport const SPINNER_MESSAGE = 'Setting up WorkOS AuthKit with login, authentication, and session management...';\n"]}
@@ -1,6 +1,7 @@
1
1
  import { type ActorRefFrom } from 'xstate';
2
2
  import type { InstallerMachineContext, InstallerMachineInput, DetectionOutput, GitCheckOutput, AgentOutput, EnvFileInfo, DiscoveryResult, BranchCheckOutput, WorkspaceCheckOutput } from './installer-core.types.js';
3
3
  import type { InstallerOptions } from '../utils/types.js';
4
+ import type { CompletionData } from './events.js';
4
5
  import type { DeviceAuthResult, DeviceAuthResponse } from './device-auth.js';
5
6
  import type { StagingCredentials } from './staging-api.js';
6
7
  export declare const installerMachine: import("xstate").StateMachine<InstallerMachineContext, {
@@ -42,54 +43,56 @@ export declare const installerMachine: import("xstate").StateMachine<InstallerMa
42
43
  } | {
43
44
  type: "PR_DECLINED";
44
45
  }, {
45
- [x: string]: import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<string, {
46
- title: string;
47
- body: string;
48
- cwd: string;
49
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<boolean, {
46
+ [x: string]: import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<boolean, {
50
47
  options: InstallerOptions;
51
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<WorkspaceCheckOutput, {
48
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<WorkspaceCheckOutput, {
52
49
  options: InstallerOptions;
53
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<void, {
50
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<void, {
54
51
  context: InstallerMachineContext;
55
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<DetectionOutput, {
52
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<DetectionOutput, {
56
53
  options: InstallerOptions;
57
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<GitCheckOutput, {
54
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<GitCheckOutput, {
58
55
  installDir: string;
59
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<void, {
56
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<void, {
57
+ context: InstallerMachineContext;
58
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<AgentOutput, {
60
59
  context: InstallerMachineContext;
61
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<AgentOutput, {
60
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<CompletionData | undefined, {
62
61
  context: InstallerMachineContext;
63
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<EnvFileInfo, {
62
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<EnvFileInfo, {
64
63
  installDir: string;
65
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<DiscoveryResult, {
64
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<DiscoveryResult, {
66
65
  installDir: string;
67
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<boolean, void, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<{
66
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<boolean, void, import("xstate").EventObject> | import("xstate").PromiseActorLogic<{
68
67
  result: DeviceAuthResult;
69
68
  deviceAuth: DeviceAuthResponse;
70
69
  }, {
71
70
  emitter: InstallerMachineContext["emitter"];
72
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<StagingCredentials, void, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<BranchCheckOutput, void, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<{
71
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<StagingCredentials, void, import("xstate").EventObject> | import("xstate").PromiseActorLogic<BranchCheckOutput, void, import("xstate").EventObject> | import("xstate").PromiseActorLogic<{
73
72
  branch: string;
74
73
  }, {
75
74
  name: string;
76
75
  fallbackName: string;
77
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<{
76
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<{
78
77
  hasChanges: boolean;
79
78
  files: string[];
80
- }, void, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<string, {
79
+ }, void, import("xstate").EventObject> | import("xstate").PromiseActorLogic<string, {
81
80
  integration: string;
82
81
  files: string[];
83
82
  direct?: boolean;
84
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<void, {
83
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<void, {
85
84
  message: string;
86
85
  cwd: string;
87
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<string, {
86
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<string, {
88
87
  integration: string;
89
88
  files: string[];
90
89
  commitMessage: string;
91
90
  direct?: boolean;
92
- }, import("xstate").EventObject>> | import("xstate").ActorRefFromLogic<import("xstate").PromiseActorLogic<void, {
91
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<void, {
92
+ cwd: string;
93
+ }, import("xstate").EventObject> | import("xstate").PromiseActorLogic<string, {
94
+ title: string;
95
+ body: string;
93
96
  cwd: string;
94
97
  }, import("xstate").EventObject>> | undefined;
95
98
  }, {
@@ -142,6 +145,12 @@ export declare const installerMachine: import("xstate").StateMachine<InstallerMa
142
145
  context: InstallerMachineContext;
143
146
  }, import("xstate").EventObject>;
144
147
  id: string | undefined;
148
+ } | {
149
+ src: "buildCompletion";
150
+ logic: import("xstate").PromiseActorLogic<CompletionData | undefined, {
151
+ context: InstallerMachineContext;
152
+ }, import("xstate").EventObject>;
153
+ id: string | undefined;
145
154
  } | {
146
155
  src: "detectEnvFiles";
147
156
  logic: import("xstate").PromiseActorLogic<EnvFileInfo, {
@@ -442,6 +451,9 @@ export declare const installerMachine: import("xstate").StateMachine<InstallerMa
442
451
  } | {
443
452
  type: "emitComplete";
444
453
  params: unknown;
454
+ } | {
455
+ type: "assignCompletion";
456
+ params: unknown;
445
457
  }, {
446
458
  type: "shouldSkipAuth";
447
459
  params: unknown;
@@ -466,7 +478,7 @@ export declare const installerMachine: import("xstate").StateMachine<InstallerMa
466
478
  } | {
467
479
  type: "shouldAutoScaffold";
468
480
  params: unknown;
469
- }, never, "error" | "cancelled" | "complete" | "idle" | "authenticating" | "configuring" | "runningAgent" | {
481
+ }, never, "cancelled" | "error" | "complete" | "idle" | "authenticating" | "configuring" | "runningAgent" | "buildingCompletion" | {
470
482
  scaffold: "done" | "checking" | "running" | "prompting";
471
483
  } | {
472
484
  preparing: {
@@ -547,6 +559,7 @@ export declare const installerMachine: import("xstate").StateMachine<InstallerMa
547
559
  readonly done: {};
548
560
  };
549
561
  };
562
+ readonly buildingCompletion: {};
550
563
  readonly complete: {};
551
564
  readonly cancelled: {};
552
565
  readonly error: {};