@pellux/goodvibes-sdk 0.38.0 → 1.0.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 (474) hide show
  1. package/dist/contracts/artifacts/operator-contract.json +3171 -929
  2. package/dist/daemon.d.ts +2 -0
  3. package/dist/daemon.d.ts.map +1 -1
  4. package/dist/daemon.js +4 -0
  5. package/dist/events/surfaces.d.ts +25 -3
  6. package/dist/events/surfaces.d.ts.map +1 -1
  7. package/dist/events/surfaces.js +22 -1
  8. package/dist/events/workflows.d.ts +7 -6
  9. package/dist/events/workflows.d.ts.map +1 -1
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/platform/agents/archetypes.d.ts.map +1 -1
  13. package/dist/platform/agents/archetypes.js +7 -0
  14. package/dist/platform/agents/index.d.ts +1 -0
  15. package/dist/platform/agents/index.d.ts.map +1 -1
  16. package/dist/platform/agents/index.js +1 -0
  17. package/dist/platform/agents/orchestrator-runner.d.ts +13 -0
  18. package/dist/platform/agents/orchestrator-runner.d.ts.map +1 -1
  19. package/dist/platform/agents/orchestrator-runner.js +14 -0
  20. package/dist/platform/agents/orchestrator.d.ts +38 -6
  21. package/dist/platform/agents/orchestrator.d.ts.map +1 -1
  22. package/dist/platform/agents/orchestrator.js +66 -18
  23. package/dist/platform/agents/planner-decomposition-runner.d.ts +38 -0
  24. package/dist/platform/agents/planner-decomposition-runner.d.ts.map +1 -0
  25. package/dist/platform/agents/planner-decomposition-runner.js +113 -0
  26. package/dist/platform/agents/turn-knowledge-injection.d.ts +88 -3
  27. package/dist/platform/agents/turn-knowledge-injection.d.ts.map +1 -1
  28. package/dist/platform/agents/turn-knowledge-injection.js +147 -30
  29. package/dist/platform/agents/worktree.d.ts +126 -8
  30. package/dist/platform/agents/worktree.d.ts.map +1 -1
  31. package/dist/platform/agents/worktree.js +240 -19
  32. package/dist/platform/agents/wrfc-controller.d.ts +23 -0
  33. package/dist/platform/agents/wrfc-controller.d.ts.map +1 -1
  34. package/dist/platform/agents/wrfc-controller.js +158 -32
  35. package/dist/platform/agents/wrfc-gate-runtime.d.ts +9 -0
  36. package/dist/platform/agents/wrfc-gate-runtime.d.ts.map +1 -1
  37. package/dist/platform/agents/wrfc-gate-runtime.js +7 -3
  38. package/dist/platform/agents/wrfc-gates.d.ts +1 -1
  39. package/dist/platform/agents/wrfc-gates.d.ts.map +1 -1
  40. package/dist/platform/agents/wrfc-gates.js +7 -1
  41. package/dist/platform/agents/wrfc-types.d.ts +23 -3
  42. package/dist/platform/agents/wrfc-types.d.ts.map +1 -1
  43. package/dist/platform/automation/types.d.ts +9 -1
  44. package/dist/platform/automation/types.d.ts.map +1 -1
  45. package/dist/platform/calendar/calendar-api-shared.d.ts +25 -0
  46. package/dist/platform/calendar/calendar-api-shared.d.ts.map +1 -0
  47. package/dist/platform/calendar/calendar-api-shared.js +100 -0
  48. package/dist/platform/calendar/calendar-connector.d.ts +79 -0
  49. package/dist/platform/calendar/calendar-connector.d.ts.map +1 -0
  50. package/dist/platform/calendar/calendar-connector.js +155 -0
  51. package/dist/platform/calendar/google-calendar-api.d.ts +25 -0
  52. package/dist/platform/calendar/google-calendar-api.d.ts.map +1 -0
  53. package/dist/platform/calendar/google-calendar-api.js +89 -0
  54. package/dist/platform/calendar/http-fetch-adapter.d.ts +25 -0
  55. package/dist/platform/calendar/http-fetch-adapter.d.ts.map +1 -0
  56. package/dist/platform/calendar/http-fetch-adapter.js +25 -0
  57. package/dist/platform/calendar/ics-parser.d.ts +35 -0
  58. package/dist/platform/calendar/ics-parser.d.ts.map +1 -0
  59. package/dist/platform/calendar/ics-parser.js +236 -0
  60. package/dist/platform/calendar/index.d.ts +41 -0
  61. package/dist/platform/calendar/index.d.ts.map +1 -0
  62. package/dist/platform/calendar/index.js +49 -0
  63. package/dist/platform/calendar/merged-calendar-model.d.ts +67 -0
  64. package/dist/platform/calendar/merged-calendar-model.d.ts.map +1 -0
  65. package/dist/platform/calendar/merged-calendar-model.js +181 -0
  66. package/dist/platform/calendar/microsoft-graph-api.d.ts +25 -0
  67. package/dist/platform/calendar/microsoft-graph-api.d.ts.map +1 -0
  68. package/dist/platform/calendar/microsoft-graph-api.js +95 -0
  69. package/dist/platform/calendar/oauth-flow.d.ts +62 -0
  70. package/dist/platform/calendar/oauth-flow.d.ts.map +1 -0
  71. package/dist/platform/calendar/oauth-flow.js +305 -0
  72. package/dist/platform/calendar/oauth-providers.d.ts +43 -0
  73. package/dist/platform/calendar/oauth-providers.d.ts.map +1 -0
  74. package/dist/platform/calendar/oauth-providers.js +120 -0
  75. package/dist/platform/calendar/oauth-token-store.d.ts +72 -0
  76. package/dist/platform/calendar/oauth-token-store.d.ts.map +1 -0
  77. package/dist/platform/calendar/oauth-token-store.js +189 -0
  78. package/dist/platform/calendar/oauth-types.d.ts +274 -0
  79. package/dist/platform/calendar/oauth-types.d.ts.map +1 -0
  80. package/dist/platform/calendar/oauth-types.js +22 -0
  81. package/dist/platform/calendar/rrule.d.ts +39 -0
  82. package/dist/platform/calendar/rrule.d.ts.map +1 -0
  83. package/dist/platform/calendar/rrule.js +261 -0
  84. package/dist/platform/calendar/subscription-store.d.ts +118 -0
  85. package/dist/platform/calendar/subscription-store.d.ts.map +1 -0
  86. package/dist/platform/calendar/subscription-store.js +293 -0
  87. package/dist/platform/calendar/types.d.ts +170 -0
  88. package/dist/platform/calendar/types.d.ts.map +1 -0
  89. package/dist/platform/calendar/types.js +21 -0
  90. package/dist/platform/companion/companion-chat-attachments.d.ts +29 -0
  91. package/dist/platform/companion/companion-chat-attachments.d.ts.map +1 -0
  92. package/dist/platform/companion/companion-chat-attachments.js +121 -0
  93. package/dist/platform/companion/companion-chat-broker-bridge.d.ts +40 -0
  94. package/dist/platform/companion/companion-chat-broker-bridge.d.ts.map +1 -0
  95. package/dist/platform/companion/companion-chat-broker-bridge.js +14 -0
  96. package/dist/platform/companion/companion-chat-broker-sync.d.ts +38 -0
  97. package/dist/platform/companion/companion-chat-broker-sync.d.ts.map +1 -0
  98. package/dist/platform/companion/companion-chat-broker-sync.js +80 -0
  99. package/dist/platform/companion/companion-chat-gc.d.ts +63 -0
  100. package/dist/platform/companion/companion-chat-gc.d.ts.map +1 -0
  101. package/dist/platform/companion/companion-chat-gc.js +38 -0
  102. package/dist/platform/companion/companion-chat-manager.d.ts +67 -20
  103. package/dist/platform/companion/companion-chat-manager.d.ts.map +1 -1
  104. package/dist/platform/companion/companion-chat-manager.js +130 -144
  105. package/dist/platform/companion/companion-chat-persistence.d.ts +9 -1
  106. package/dist/platform/companion/companion-chat-persistence.d.ts.map +1 -1
  107. package/dist/platform/companion/companion-chat-persistence.js +10 -2
  108. package/dist/platform/companion/companion-chat-routes.d.ts +2 -1
  109. package/dist/platform/companion/companion-chat-routes.d.ts.map +1 -1
  110. package/dist/platform/companion/companion-chat-routes.js +37 -4
  111. package/dist/platform/config/credential-status.d.ts +28 -0
  112. package/dist/platform/config/credential-status.d.ts.map +1 -0
  113. package/dist/platform/config/credential-status.js +75 -0
  114. package/dist/platform/config/index.d.ts +25 -0
  115. package/dist/platform/config/index.d.ts.map +1 -1
  116. package/dist/platform/config/index.js +18 -0
  117. package/dist/platform/config/manager.d.ts +9 -0
  118. package/dist/platform/config/manager.d.ts.map +1 -1
  119. package/dist/platform/config/manager.js +21 -2
  120. package/dist/platform/config/migrations.d.ts +48 -0
  121. package/dist/platform/config/migrations.d.ts.map +1 -0
  122. package/dist/platform/config/migrations.js +54 -0
  123. package/dist/platform/config/schema-domain-core.d.ts +10 -1
  124. package/dist/platform/config/schema-domain-core.d.ts.map +1 -1
  125. package/dist/platform/config/schema-domain-core.js +46 -3
  126. package/dist/platform/config/schema-types.d.ts +13 -7
  127. package/dist/platform/config/schema-types.d.ts.map +1 -1
  128. package/dist/platform/config/schema.d.ts.map +1 -1
  129. package/dist/platform/config/schema.js +2 -0
  130. package/dist/platform/control-plane/approval-broker.d.ts +11 -0
  131. package/dist/platform/control-plane/approval-broker.d.ts.map +1 -1
  132. package/dist/platform/control-plane/approval-broker.js +17 -1
  133. package/dist/platform/control-plane/approval-hunk-apply.d.ts +77 -0
  134. package/dist/platform/control-plane/approval-hunk-apply.d.ts.map +1 -0
  135. package/dist/platform/control-plane/approval-hunk-apply.js +80 -0
  136. package/dist/platform/control-plane/gateway-disabled-response.d.ts +20 -0
  137. package/dist/platform/control-plane/gateway-disabled-response.d.ts.map +1 -0
  138. package/dist/platform/control-plane/gateway-disabled-response.js +24 -0
  139. package/dist/platform/control-plane/gateway-scope-enforcement.d.ts +68 -0
  140. package/dist/platform/control-plane/gateway-scope-enforcement.d.ts.map +1 -0
  141. package/dist/platform/control-plane/gateway-scope-enforcement.js +91 -0
  142. package/dist/platform/control-plane/gateway-utils.d.ts +17 -0
  143. package/dist/platform/control-plane/gateway-utils.d.ts.map +1 -1
  144. package/dist/platform/control-plane/gateway-utils.js +30 -0
  145. package/dist/platform/control-plane/gateway.d.ts +12 -2
  146. package/dist/platform/control-plane/gateway.d.ts.map +1 -1
  147. package/dist/platform/control-plane/gateway.js +27 -31
  148. package/dist/platform/control-plane/index.d.ts +6 -1
  149. package/dist/platform/control-plane/index.d.ts.map +1 -1
  150. package/dist/platform/control-plane/index.js +4 -0
  151. package/dist/platform/control-plane/invoke-input-validation.d.ts +56 -0
  152. package/dist/platform/control-plane/invoke-input-validation.d.ts.map +1 -0
  153. package/dist/platform/control-plane/invoke-input-validation.js +163 -0
  154. package/dist/platform/control-plane/method-catalog-admin.d.ts.map +1 -1
  155. package/dist/platform/control-plane/method-catalog-admin.js +12 -1
  156. package/dist/platform/control-plane/method-catalog-calendar.d.ts +16 -0
  157. package/dist/platform/control-plane/method-catalog-calendar.d.ts.map +1 -1
  158. package/dist/platform/control-plane/method-catalog-calendar.js +21 -0
  159. package/dist/platform/control-plane/method-catalog-channels.d.ts.map +1 -1
  160. package/dist/platform/control-plane/method-catalog-channels.js +32 -3
  161. package/dist/platform/control-plane/method-catalog-control-automation.d.ts.map +1 -1
  162. package/dist/platform/control-plane/method-catalog-control-automation.js +19 -34
  163. package/dist/platform/control-plane/method-catalog-control-companion.d.ts +15 -0
  164. package/dist/platform/control-plane/method-catalog-control-companion.d.ts.map +1 -0
  165. package/dist/platform/control-plane/method-catalog-control-companion.js +133 -0
  166. package/dist/platform/control-plane/method-catalog-control-core.d.ts.map +1 -1
  167. package/dist/platform/control-plane/method-catalog-control-core.js +104 -122
  168. package/dist/platform/control-plane/method-catalog-control.d.ts.map +1 -1
  169. package/dist/platform/control-plane/method-catalog-control.js +4 -0
  170. package/dist/platform/control-plane/method-catalog-email.d.ts +17 -0
  171. package/dist/platform/control-plane/method-catalog-email.d.ts.map +1 -1
  172. package/dist/platform/control-plane/method-catalog-email.js +21 -0
  173. package/dist/platform/control-plane/method-catalog-events.d.ts +28 -0
  174. package/dist/platform/control-plane/method-catalog-events.d.ts.map +1 -1
  175. package/dist/platform/control-plane/method-catalog-events.js +74 -1
  176. package/dist/platform/control-plane/method-catalog-fleet.d.ts +24 -0
  177. package/dist/platform/control-plane/method-catalog-fleet.d.ts.map +1 -0
  178. package/dist/platform/control-plane/method-catalog-fleet.js +65 -0
  179. package/dist/platform/control-plane/method-catalog-route-reconcile.d.ts +84 -0
  180. package/dist/platform/control-plane/method-catalog-route-reconcile.d.ts.map +1 -0
  181. package/dist/platform/control-plane/method-catalog-route-reconcile.js +103 -0
  182. package/dist/platform/control-plane/method-catalog-shared.d.ts +29 -0
  183. package/dist/platform/control-plane/method-catalog-shared.d.ts.map +1 -1
  184. package/dist/platform/control-plane/method-catalog.d.ts +9 -0
  185. package/dist/platform/control-plane/method-catalog.d.ts.map +1 -1
  186. package/dist/platform/control-plane/method-catalog.js +32 -3
  187. package/dist/platform/control-plane/operator-contract-schemas-admin.d.ts +8 -0
  188. package/dist/platform/control-plane/operator-contract-schemas-admin.d.ts.map +1 -1
  189. package/dist/platform/control-plane/operator-contract-schemas-admin.js +22 -1
  190. package/dist/platform/control-plane/operator-contract-schemas-fleet.d.ts +18 -0
  191. package/dist/platform/control-plane/operator-contract-schemas-fleet.d.ts.map +1 -0
  192. package/dist/platform/control-plane/operator-contract-schemas-fleet.js +182 -0
  193. package/dist/platform/control-plane/operator-contract-schemas-permissions.d.ts.map +1 -1
  194. package/dist/platform/control-plane/operator-contract-schemas-permissions.js +5 -0
  195. package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts +29 -0
  196. package/dist/platform/control-plane/operator-contract-schemas-runtime.d.ts.map +1 -1
  197. package/dist/platform/control-plane/operator-contract-schemas-runtime.js +57 -3
  198. package/dist/platform/control-plane/operator-contract-schemas.d.ts +1 -0
  199. package/dist/platform/control-plane/operator-contract-schemas.d.ts.map +1 -1
  200. package/dist/platform/control-plane/operator-contract-schemas.js +1 -0
  201. package/dist/platform/control-plane/operator-contract.d.ts.map +1 -1
  202. package/dist/platform/control-plane/operator-contract.js +8 -0
  203. package/dist/platform/control-plane/routes/checkpoints.d.ts +39 -0
  204. package/dist/platform/control-plane/routes/checkpoints.d.ts.map +1 -0
  205. package/dist/platform/control-plane/routes/checkpoints.js +166 -0
  206. package/dist/platform/control-plane/routes/fleet.d.ts +53 -0
  207. package/dist/platform/control-plane/routes/fleet.d.ts.map +1 -0
  208. package/dist/platform/control-plane/routes/fleet.js +153 -0
  209. package/dist/platform/control-plane/routes/gateway-verb-error.d.ts +30 -0
  210. package/dist/platform/control-plane/routes/gateway-verb-error.d.ts.map +1 -0
  211. package/dist/platform/control-plane/routes/gateway-verb-error.js +36 -0
  212. package/dist/platform/control-plane/routes/index.d.ts +0 -6
  213. package/dist/platform/control-plane/routes/index.d.ts.map +1 -1
  214. package/dist/platform/control-plane/routes/index.js +5 -5
  215. package/dist/platform/control-plane/routes/invocation-params.d.ts +23 -0
  216. package/dist/platform/control-plane/routes/invocation-params.d.ts.map +1 -0
  217. package/dist/platform/control-plane/routes/invocation-params.js +9 -0
  218. package/dist/platform/control-plane/routes/register-w3-s2.d.ts +26 -0
  219. package/dist/platform/control-plane/routes/register-w3-s2.d.ts.map +1 -0
  220. package/dist/platform/control-plane/routes/register-w3-s2.js +8 -0
  221. package/dist/platform/control-plane/routes/session-search.d.ts +37 -0
  222. package/dist/platform/control-plane/routes/session-search.d.ts.map +1 -0
  223. package/dist/platform/control-plane/routes/session-search.js +113 -0
  224. package/dist/platform/control-plane/session-broker-gc.d.ts +16 -0
  225. package/dist/platform/control-plane/session-broker-gc.d.ts.map +1 -1
  226. package/dist/platform/control-plane/session-broker-gc.js +23 -6
  227. package/dist/platform/control-plane/session-broker-helpers.d.ts +3 -3
  228. package/dist/platform/control-plane/session-broker-helpers.d.ts.map +1 -1
  229. package/dist/platform/control-plane/session-broker-inputs.d.ts +18 -0
  230. package/dist/platform/control-plane/session-broker-inputs.d.ts.map +1 -1
  231. package/dist/platform/control-plane/session-broker-inputs.js +34 -0
  232. package/dist/platform/control-plane/session-broker-sessions.d.ts +102 -3
  233. package/dist/platform/control-plane/session-broker-sessions.d.ts.map +1 -1
  234. package/dist/platform/control-plane/session-broker-sessions.js +179 -5
  235. package/dist/platform/control-plane/session-broker-state.d.ts +20 -1
  236. package/dist/platform/control-plane/session-broker-state.d.ts.map +1 -1
  237. package/dist/platform/control-plane/session-broker-state.js +67 -5
  238. package/dist/platform/control-plane/session-broker.d.ts +51 -38
  239. package/dist/platform/control-plane/session-broker.d.ts.map +1 -1
  240. package/dist/platform/control-plane/session-broker.js +183 -75
  241. package/dist/platform/control-plane/session-store-importer.d.ts +57 -0
  242. package/dist/platform/control-plane/session-store-importer.d.ts.map +1 -0
  243. package/dist/platform/control-plane/session-store-importer.js +227 -0
  244. package/dist/platform/control-plane/session-types.d.ts +142 -7
  245. package/dist/platform/control-plane/session-types.d.ts.map +1 -1
  246. package/dist/platform/core/execution-plan.d.ts +43 -1
  247. package/dist/platform/core/execution-plan.d.ts.map +1 -1
  248. package/dist/platform/core/execution-plan.js +46 -10
  249. package/dist/platform/core/index.d.ts +1 -0
  250. package/dist/platform/core/index.d.ts.map +1 -1
  251. package/dist/platform/core/index.js +1 -0
  252. package/dist/platform/core/orchestrator-runtime.d.ts +21 -1
  253. package/dist/platform/core/orchestrator-runtime.d.ts.map +1 -1
  254. package/dist/platform/core/orchestrator-tool-runtime.d.ts +7 -0
  255. package/dist/platform/core/orchestrator-tool-runtime.d.ts.map +1 -1
  256. package/dist/platform/core/orchestrator-tool-runtime.js +10 -0
  257. package/dist/platform/core/orchestrator-turn-loop.d.ts +8 -1
  258. package/dist/platform/core/orchestrator-turn-loop.d.ts.map +1 -1
  259. package/dist/platform/core/orchestrator-turn-loop.js +6 -0
  260. package/dist/platform/core/orchestrator.d.ts +6 -0
  261. package/dist/platform/core/orchestrator.d.ts.map +1 -1
  262. package/dist/platform/core/orchestrator.js +15 -0
  263. package/dist/platform/core/plan-decomposition.d.ts +196 -0
  264. package/dist/platform/core/plan-decomposition.d.ts.map +1 -0
  265. package/dist/platform/core/plan-decomposition.js +417 -0
  266. package/dist/platform/core/plan-proposal.d.ts +39 -0
  267. package/dist/platform/core/plan-proposal.d.ts.map +1 -1
  268. package/dist/platform/core/wrfc-routing.d.ts +1 -0
  269. package/dist/platform/core/wrfc-routing.d.ts.map +1 -1
  270. package/dist/platform/core/wrfc-routing.js +51 -1
  271. package/dist/platform/daemon/boot.d.ts +63 -0
  272. package/dist/platform/daemon/boot.d.ts.map +1 -0
  273. package/dist/platform/daemon/boot.js +60 -0
  274. package/dist/platform/daemon/cli.js +2 -1
  275. package/dist/platform/daemon/control-plane.d.ts.map +1 -1
  276. package/dist/platform/daemon/control-plane.js +50 -1
  277. package/dist/platform/daemon/facade-composition.d.ts.map +1 -1
  278. package/dist/platform/daemon/facade-composition.js +6 -0
  279. package/dist/platform/daemon/facade.d.ts +18 -6
  280. package/dist/platform/daemon/facade.d.ts.map +1 -1
  281. package/dist/platform/daemon/facade.js +50 -43
  282. package/dist/platform/daemon/http/router-route-contexts.d.ts +1 -0
  283. package/dist/platform/daemon/http/router-route-contexts.d.ts.map +1 -1
  284. package/dist/platform/daemon/http/router-route-contexts.js +1 -0
  285. package/dist/platform/daemon/http/router-session-broker-adapter.d.ts +13 -0
  286. package/dist/platform/daemon/http/router-session-broker-adapter.d.ts.map +1 -0
  287. package/dist/platform/daemon/http/router-session-broker-adapter.js +27 -0
  288. package/dist/platform/daemon/http/router.d.ts +1 -1
  289. package/dist/platform/daemon/http/router.d.ts.map +1 -1
  290. package/dist/platform/daemon/http/router.js +7 -22
  291. package/dist/platform/daemon/http/runtime-route-types.d.ts +42 -4
  292. package/dist/platform/daemon/http/runtime-route-types.d.ts.map +1 -1
  293. package/dist/platform/daemon/index.d.ts +2 -0
  294. package/dist/platform/daemon/index.d.ts.map +1 -1
  295. package/dist/platform/daemon/index.js +1 -0
  296. package/dist/platform/daemon/service-manager.d.ts +16 -0
  297. package/dist/platform/daemon/service-manager.d.ts.map +1 -1
  298. package/dist/platform/daemon/service-manager.js +79 -15
  299. package/dist/platform/intelligence/tree-sitter/service.d.ts.map +1 -1
  300. package/dist/platform/intelligence/tree-sitter/service.js +16 -2
  301. package/dist/platform/knowledge/browser-history/readers.d.ts.map +1 -1
  302. package/dist/platform/knowledge/browser-history/readers.js +15 -5
  303. package/dist/platform/knowledge/project-planning/service.d.ts +14 -1
  304. package/dist/platform/knowledge/project-planning/service.d.ts.map +1 -1
  305. package/dist/platform/knowledge/project-planning/service.js +77 -0
  306. package/dist/platform/knowledge/project-planning/types.d.ts +32 -0
  307. package/dist/platform/knowledge/project-planning/types.d.ts.map +1 -1
  308. package/dist/platform/orchestration/bookkeeping.d.ts +12 -0
  309. package/dist/platform/orchestration/bookkeeping.d.ts.map +1 -0
  310. package/dist/platform/orchestration/bookkeeping.js +91 -0
  311. package/dist/platform/orchestration/controller-compat.d.ts +14 -0
  312. package/dist/platform/orchestration/controller-compat.d.ts.map +1 -1
  313. package/dist/platform/orchestration/controller-compat.js +18 -4
  314. package/dist/platform/orchestration/engine.d.ts +26 -1
  315. package/dist/platform/orchestration/engine.d.ts.map +1 -1
  316. package/dist/platform/orchestration/engine.js +226 -21
  317. package/dist/platform/orchestration/index.d.ts +6 -4
  318. package/dist/platform/orchestration/index.d.ts.map +1 -1
  319. package/dist/platform/orchestration/index.js +3 -2
  320. package/dist/platform/orchestration/persistence.d.ts.map +1 -1
  321. package/dist/platform/orchestration/persistence.js +4 -1
  322. package/dist/platform/orchestration/phase-runner.d.ts +29 -2
  323. package/dist/platform/orchestration/phase-runner.d.ts.map +1 -1
  324. package/dist/platform/orchestration/phase-runner.js +98 -25
  325. package/dist/platform/orchestration/proposal-workstream.d.ts +56 -0
  326. package/dist/platform/orchestration/proposal-workstream.d.ts.map +1 -0
  327. package/dist/platform/orchestration/proposal-workstream.js +76 -0
  328. package/dist/platform/orchestration/scheduler.d.ts +19 -0
  329. package/dist/platform/orchestration/scheduler.d.ts.map +1 -1
  330. package/dist/platform/orchestration/scheduler.js +16 -0
  331. package/dist/platform/orchestration/types.d.ts +286 -1
  332. package/dist/platform/orchestration/types.d.ts.map +1 -1
  333. package/dist/platform/orchestration/types.js +32 -0
  334. package/dist/platform/orchestration/worktree-isolation.d.ts +33 -0
  335. package/dist/platform/orchestration/worktree-isolation.d.ts.map +1 -0
  336. package/dist/platform/orchestration/worktree-isolation.js +248 -0
  337. package/dist/platform/presentation/glyphs.d.ts +91 -0
  338. package/dist/platform/presentation/glyphs.d.ts.map +1 -0
  339. package/dist/platform/presentation/glyphs.js +93 -0
  340. package/dist/platform/presentation/index.d.ts +28 -0
  341. package/dist/platform/presentation/index.d.ts.map +1 -0
  342. package/dist/platform/presentation/index.js +27 -0
  343. package/dist/platform/presentation/thinking-phrases.d.ts +12 -0
  344. package/dist/platform/presentation/thinking-phrases.d.ts.map +1 -0
  345. package/dist/platform/presentation/thinking-phrases.js +32 -0
  346. package/dist/platform/presentation/tones.d.ts +121 -0
  347. package/dist/platform/presentation/tones.d.ts.map +1 -0
  348. package/dist/platform/presentation/tones.js +145 -0
  349. package/dist/platform/presentation/waiting-wording.d.ts +54 -0
  350. package/dist/platform/presentation/waiting-wording.d.ts.map +1 -0
  351. package/dist/platform/presentation/waiting-wording.js +51 -0
  352. package/dist/platform/providers/runtime-snapshot.d.ts.map +1 -1
  353. package/dist/platform/providers/runtime-snapshot.js +12 -2
  354. package/dist/platform/runtime/bootstrap-services.d.ts +62 -2
  355. package/dist/platform/runtime/bootstrap-services.d.ts.map +1 -1
  356. package/dist/platform/runtime/bootstrap-services.js +217 -50
  357. package/dist/platform/runtime/daemon-version-compat.d.ts +39 -0
  358. package/dist/platform/runtime/daemon-version-compat.d.ts.map +1 -0
  359. package/dist/platform/runtime/daemon-version-compat.js +75 -0
  360. package/dist/platform/runtime/detached-daemon-runtime.d.ts +26 -0
  361. package/dist/platform/runtime/detached-daemon-runtime.d.ts.map +1 -0
  362. package/dist/platform/runtime/detached-daemon-runtime.js +49 -0
  363. package/dist/platform/runtime/emitters/workflows.d.ts +1 -1
  364. package/dist/platform/runtime/emitters/workflows.d.ts.map +1 -1
  365. package/dist/platform/runtime/events/index.d.ts +13 -0
  366. package/dist/platform/runtime/events/index.d.ts.map +1 -1
  367. package/dist/platform/runtime/events/index.js +13 -0
  368. package/dist/platform/runtime/feature-flags/flags.d.ts.map +1 -1
  369. package/dist/platform/runtime/feature-flags/flags.js +39 -1
  370. package/dist/platform/runtime/fleet/adapters/orchestration.d.ts +40 -18
  371. package/dist/platform/runtime/fleet/adapters/orchestration.d.ts.map +1 -1
  372. package/dist/platform/runtime/fleet/adapters/orchestration.js +138 -34
  373. package/dist/platform/runtime/fleet/adapters/wrfc.d.ts +13 -0
  374. package/dist/platform/runtime/fleet/adapters/wrfc.d.ts.map +1 -1
  375. package/dist/platform/runtime/fleet/adapters/wrfc.js +48 -1
  376. package/dist/platform/runtime/fleet/registry.d.ts.map +1 -1
  377. package/dist/platform/runtime/fleet/registry.js +38 -4
  378. package/dist/platform/runtime/operator-client.d.ts +20 -2
  379. package/dist/platform/runtime/operator-client.d.ts.map +1 -1
  380. package/dist/platform/runtime/operator-client.js +11 -1
  381. package/dist/platform/runtime/provider-accounts/registry.d.ts.map +1 -1
  382. package/dist/platform/runtime/provider-accounts/registry.js +11 -1
  383. package/dist/platform/runtime/services.d.ts +9 -7
  384. package/dist/platform/runtime/services.d.ts.map +1 -1
  385. package/dist/platform/runtime/services.js +19 -4
  386. package/dist/platform/runtime/session-spine/client.d.ts +234 -0
  387. package/dist/platform/runtime/session-spine/client.d.ts.map +1 -0
  388. package/dist/platform/runtime/session-spine/client.js +449 -0
  389. package/dist/platform/runtime/session-spine/index.d.ts +12 -0
  390. package/dist/platform/runtime/session-spine/index.d.ts.map +1 -0
  391. package/dist/platform/runtime/session-spine/index.js +11 -0
  392. package/dist/platform/runtime/session-spine/union-cache.d.ts +225 -0
  393. package/dist/platform/runtime/session-spine/union-cache.d.ts.map +1 -0
  394. package/dist/platform/runtime/session-spine/union-cache.js +333 -0
  395. package/dist/platform/runtime/shell-command-ops.d.ts +3 -1
  396. package/dist/platform/runtime/shell-command-ops.d.ts.map +1 -1
  397. package/dist/platform/runtime/transports/daemon-http-client-validators.d.ts.map +1 -1
  398. package/dist/platform/runtime/transports/daemon-http-client-validators.js +22 -0
  399. package/dist/platform/runtime/transports/daemon-http-client.d.ts.map +1 -1
  400. package/dist/platform/runtime/transports/daemon-http-client.js +25 -2
  401. package/dist/platform/runtime/transports/http-types.d.ts +9 -2
  402. package/dist/platform/runtime/transports/http-types.d.ts.map +1 -1
  403. package/dist/platform/state/canonical-memory.d.ts +95 -0
  404. package/dist/platform/state/canonical-memory.d.ts.map +1 -0
  405. package/dist/platform/state/canonical-memory.js +155 -0
  406. package/dist/platform/state/code-index-reindex.d.ts +73 -0
  407. package/dist/platform/state/code-index-reindex.d.ts.map +1 -0
  408. package/dist/platform/state/code-index-reindex.js +156 -0
  409. package/dist/platform/state/code-index-store.d.ts.map +1 -1
  410. package/dist/platform/state/code-index-store.js +10 -2
  411. package/dist/platform/state/index.d.ts +8 -0
  412. package/dist/platform/state/index.d.ts.map +1 -1
  413. package/dist/platform/state/index.js +4 -0
  414. package/dist/platform/state/memory-recall-contract.d.ts +63 -0
  415. package/dist/platform/state/memory-recall-contract.d.ts.map +1 -0
  416. package/dist/platform/state/memory-recall-contract.js +94 -0
  417. package/dist/platform/state/memory-store.d.ts +2 -0
  418. package/dist/platform/state/memory-store.d.ts.map +1 -1
  419. package/dist/platform/state/memory-store.js +4 -0
  420. package/dist/platform/state/memory-vector-store.d.ts.map +1 -1
  421. package/dist/platform/state/memory-vector-store.js +13 -2
  422. package/dist/platform/state/sqlite-store.d.ts +2 -0
  423. package/dist/platform/state/sqlite-store.d.ts.map +1 -1
  424. package/dist/platform/state/sqlite-store.js +4 -0
  425. package/dist/platform/state/vibe-projection.d.ts +67 -0
  426. package/dist/platform/state/vibe-projection.d.ts.map +1 -0
  427. package/dist/platform/state/vibe-projection.js +115 -0
  428. package/dist/platform/tools/agent/index.d.ts.map +1 -1
  429. package/dist/platform/tools/agent/index.js +8 -0
  430. package/dist/platform/tools/agent/manager.d.ts +12 -0
  431. package/dist/platform/tools/agent/manager.d.ts.map +1 -1
  432. package/dist/platform/tools/agent/manager.js +6 -0
  433. package/dist/platform/tools/agent/schema.d.ts +26 -0
  434. package/dist/platform/tools/agent/schema.d.ts.map +1 -1
  435. package/dist/platform/tools/agent/schema.js +2 -2
  436. package/dist/platform/tools/agent/wrfc-batch-policy.d.ts +13 -0
  437. package/dist/platform/tools/agent/wrfc-batch-policy.d.ts.map +1 -1
  438. package/dist/platform/tools/agent/wrfc-batch-policy.js +60 -0
  439. package/dist/platform/tools/exec/runtime.d.ts +10 -0
  440. package/dist/platform/tools/exec/runtime.d.ts.map +1 -1
  441. package/dist/platform/tools/exec/runtime.js +22 -5
  442. package/dist/platform/tools/exec/schema.d.ts +1 -1
  443. package/dist/platform/tools/exec/schema.d.ts.map +1 -1
  444. package/dist/platform/tools/exec/schema.js +2 -1
  445. package/dist/platform/tools/index.d.ts +2 -0
  446. package/dist/platform/tools/index.d.ts.map +1 -1
  447. package/dist/platform/tools/index.js +2 -0
  448. package/dist/platform/tools/state/index.d.ts +9 -0
  449. package/dist/platform/tools/state/index.d.ts.map +1 -1
  450. package/dist/platform/tools/state/index.js +60 -3
  451. package/dist/platform/types/foundation-contract.d.ts +1 -1
  452. package/dist/platform/types/foundation-contract.d.ts.map +1 -1
  453. package/dist/platform/types/index.d.ts +1 -1
  454. package/dist/platform/types/index.d.ts.map +1 -1
  455. package/dist/platform/version.js +1 -1
  456. package/package.json +21 -9
  457. package/dist/platform/control-plane/routes/automation.d.ts +0 -3
  458. package/dist/platform/control-plane/routes/automation.d.ts.map +0 -1
  459. package/dist/platform/control-plane/routes/automation.js +0 -63
  460. package/dist/platform/control-plane/routes/context.d.ts +0 -2
  461. package/dist/platform/control-plane/routes/context.d.ts.map +0 -1
  462. package/dist/platform/control-plane/routes/context.js +0 -1
  463. package/dist/platform/control-plane/routes/operator.d.ts +0 -8
  464. package/dist/platform/control-plane/routes/operator.d.ts.map +0 -1
  465. package/dist/platform/control-plane/routes/operator.js +0 -415
  466. package/dist/platform/control-plane/routes/remote.d.ts +0 -3
  467. package/dist/platform/control-plane/routes/remote.d.ts.map +0 -1
  468. package/dist/platform/control-plane/routes/remote.js +0 -35
  469. package/dist/platform/control-plane/routes/sessions.d.ts +0 -3
  470. package/dist/platform/control-plane/routes/sessions.d.ts.map +0 -1
  471. package/dist/platform/control-plane/routes/sessions.js +0 -43
  472. package/dist/platform/control-plane/routes/tasks.d.ts +0 -3
  473. package/dist/platform/control-plane/routes/tasks.d.ts.map +0 -1
  474. package/dist/platform/control-plane/routes/tasks.js +0 -22
@@ -0,0 +1,95 @@
1
+ /**
2
+ * microsoft-graph-api.ts — the Microsoft Graph client over an access token and the
3
+ * injected HttpFetch. Lists calendars (me/calendars), lists events over a window
4
+ * (me/calendars/{id}/calendarView, which returns expanded instances), and creates
5
+ * events (me/calendars/{id}/events). A Prefer: outlook.timezone="UTC" header makes
6
+ * Graph return UTC wall times so normalization is honest. Paging follows
7
+ * @odata.nextLink; failures are named degraded states via CalendarApiError.
8
+ */
9
+ import { authedRequest } from './calendar-api-shared.js';
10
+ import { normalizeGraphEvent } from './merged-calendar-model.js';
11
+ const BASE = 'https://graph.microsoft.com/v1.0';
12
+ const UTC_PREFER = { Prefer: 'outlook.timezone="UTC"' };
13
+ /** List the user's calendars; write access comes from canEdit. */
14
+ export async function listGraphCalendars(fetchImpl, token) {
15
+ const out = [];
16
+ let next = `${BASE}/me/calendars?$select=id,name,canEdit,isDefaultCalendar&$top=100`;
17
+ while (next) {
18
+ const body = (await authedRequest(fetchImpl, 'microsoft', { url: next, method: 'GET', token }));
19
+ for (const raw of body.value ?? []) {
20
+ const item = (raw ?? {});
21
+ if (typeof item.id !== 'string')
22
+ continue;
23
+ out.push({
24
+ id: item.id,
25
+ name: typeof item.name === 'string' ? item.name : item.id,
26
+ provider: 'microsoft',
27
+ ...(item.isDefaultCalendar === true ? { primary: true } : {}),
28
+ canWrite: item.canEdit === true,
29
+ });
30
+ }
31
+ next = typeof body['@odata.nextLink'] === 'string' ? body['@odata.nextLink'] : undefined;
32
+ }
33
+ return out;
34
+ }
35
+ /** List events over a window via calendarView, paging @odata.nextLink to exhaustion. */
36
+ export async function listGraphEvents(fetchImpl, token, query) {
37
+ const out = [];
38
+ const first = new URL(`${BASE}/me/calendars/${encodeURIComponent(query.calendarId)}/calendarView`);
39
+ first.searchParams.set('startDateTime', query.start);
40
+ first.searchParams.set('endDateTime', query.end);
41
+ first.searchParams.set('$select', 'id,iCalUId,subject,bodyPreview,location,start,end,isAllDay');
42
+ first.searchParams.set('$orderby', 'start/dateTime');
43
+ first.searchParams.set('$top', String(query.pageSize ?? 100));
44
+ let next = first.toString();
45
+ while (next) {
46
+ const body = (await authedRequest(fetchImpl, 'microsoft', {
47
+ url: next,
48
+ method: 'GET',
49
+ token,
50
+ extraHeaders: UTC_PREFER,
51
+ }));
52
+ for (const raw of body.value ?? []) {
53
+ const event = normalizeGraphEvent(raw, query.calendarId, query.calendarLabel);
54
+ if (event)
55
+ out.push(event);
56
+ }
57
+ next = typeof body['@odata.nextLink'] === 'string' ? body['@odata.nextLink'] : undefined;
58
+ }
59
+ return out;
60
+ }
61
+ /** Create an event; returns it normalized into the merged model. */
62
+ export async function createGraphEvent(fetchImpl, token, calendarId, calendarLabel, event) {
63
+ const isAllDay = event.start.kind === 'date';
64
+ const payload = {
65
+ subject: event.summary,
66
+ isAllDay,
67
+ start: graphEventDate(event.start),
68
+ end: graphEventDate(event.end ?? event.start),
69
+ ...(event.location ? { location: { displayName: event.location } } : {}),
70
+ ...(event.description ? { body: { contentType: 'text', content: event.description } } : {}),
71
+ };
72
+ const url = `${BASE}/me/calendars/${encodeURIComponent(calendarId)}/events`;
73
+ const created = await authedRequest(fetchImpl, 'microsoft', {
74
+ url,
75
+ method: 'POST',
76
+ token,
77
+ body: payload,
78
+ extraHeaders: UTC_PREFER,
79
+ });
80
+ const normalized = normalizeGraphEvent(created, calendarId, calendarLabel);
81
+ if (!normalized)
82
+ throw new Error('Microsoft Graph accepted the event but returned an unreadable body.');
83
+ return normalized;
84
+ }
85
+ /** Map an EventDateTime to a Graph {dateTime,timeZone} object. */
86
+ function graphEventDate(dt) {
87
+ if (dt.kind === 'date')
88
+ return { dateTime: `${dt.value}T00:00:00`, timeZone: 'UTC' };
89
+ if (dt.zone === 'tzid' && dt.tzid)
90
+ return { dateTime: stripZ(dt.value), timeZone: dt.tzid };
91
+ return { dateTime: stripZ(dt.value), timeZone: 'UTC' };
92
+ }
93
+ function stripZ(value) {
94
+ return value.endsWith('Z') ? value.slice(0, -1) : value;
95
+ }
@@ -0,0 +1,62 @@
1
+ /**
2
+ * oauth-flow.ts — the OAuth 2.0 machinery for calendar connectivity: the
3
+ * authorization-code flow with a loopback redirect and mandatory PKCE (the standard
4
+ * native-app pattern, RFC 8252/7636), and the device-code flow (RFC 8628) as the
5
+ * headless fallback. Token exchange, refresh, and revocation live here too.
6
+ *
7
+ * Every network call goes through the injected HttpFetch — this file never imports
8
+ * a real fetch — so the full flow runs against fake servers in tests with no real
9
+ * network and no real port. PKCE hashing/randomness reuse the SDK's runtime-neutral
10
+ * crypto adapter.
11
+ */
12
+ import type { AuthCodeFlowStart, DeviceCodeFlowStart, FlowFailureReason, HttpFetch, LoopbackListenerFactory, LoopbackWaiter, ResolvedClientConfig, StoredTokenSet } from './oauth-types.js';
13
+ /** A typed flow failure carrying the honest reason a caller surfaces to the user. */
14
+ export declare class OAuthFlowError extends Error {
15
+ readonly reason: FlowFailureReason;
16
+ /** The provider status, when the failure came from an HTTP response. */
17
+ readonly status?: number;
18
+ constructor(reason: FlowFailureReason, message: string, status?: number);
19
+ }
20
+ export interface PkcePair {
21
+ readonly verifier: string;
22
+ readonly challenge: string;
23
+ }
24
+ /** Create a PKCE verifier + S256 challenge. */
25
+ export declare function createPkcePair(): Promise<PkcePair>;
26
+ /** Turn a provider token response into a StoredTokenSet, keeping a prior refresh
27
+ * token when the response omits one (Google omits it on refresh). */
28
+ export declare function parseTokenResponse(raw: unknown, now: number, priorRefreshToken?: string): StoredTokenSet;
29
+ /**
30
+ * Begin the authorization-code flow: bind a loopback listener, build the PKCE
31
+ * authorization URL, and return both. The caller opens the URL in a browser and
32
+ * awaits waiter.waitForCode(), then calls completeAuthCodeFlow.
33
+ */
34
+ export declare function beginAuthCodeFlow(config: ResolvedClientConfig, listenerFactory: LoopbackListenerFactory): Promise<{
35
+ readonly start: AuthCodeFlowStart;
36
+ readonly waiter: LoopbackWaiter;
37
+ }>;
38
+ /** Exchange an authorization code for tokens (PKCE). */
39
+ export declare function completeAuthCodeFlow(config: ResolvedClientConfig, fetchImpl: HttpFetch, input: {
40
+ readonly code: string;
41
+ readonly verifier: string;
42
+ readonly redirectUri: string;
43
+ }, now: number): Promise<StoredTokenSet>;
44
+ /** Begin the device-code flow: request a device + user code to display. */
45
+ export declare function beginDeviceCodeFlow(config: ResolvedClientConfig, fetchImpl: HttpFetch, now: number): Promise<DeviceCodeFlowStart>;
46
+ /** Injected delay so device-code polling is deterministic in tests. */
47
+ export type Sleep = (ms: number) => Promise<void>;
48
+ /**
49
+ * Poll the token endpoint until the user approves the device code, the code expires,
50
+ * or the request is denied. Honors authorization_pending (keep polling) and slow_down
51
+ * (widen the interval) per RFC 8628.
52
+ */
53
+ export declare function pollDeviceCodeFlow(config: ResolvedClientConfig, fetchImpl: HttpFetch, start: DeviceCodeFlowStart, clock: () => number, sleep: Sleep): Promise<StoredTokenSet>;
54
+ /** Exchange a refresh token for a fresh access token. */
55
+ export declare function refreshAccessToken(config: ResolvedClientConfig, fetchImpl: HttpFetch, refreshToken: string, now: number): Promise<StoredTokenSet>;
56
+ /**
57
+ * Revoke a token at the provider (Google). Returns true when the provider confirms.
58
+ * When the provider has no revocation endpoint (Microsoft), returns false so the
59
+ * caller knows disconnect is local-only.
60
+ */
61
+ export declare function revokeToken(config: ResolvedClientConfig, fetchImpl: HttpFetch, token: string): Promise<boolean>;
62
+ //# sourceMappingURL=oauth-flow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-flow.d.ts","sourceRoot":"","sources":["../../../src/platform/calendar/oauth-flow.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,iBAAiB,EACjB,SAAS,EACT,uBAAuB,EACvB,cAAc,EACd,oBAAoB,EACpB,cAAc,EACf,MAAM,kBAAkB,CAAC;AAE1B,qFAAqF;AACrF,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,wEAAwE;IACxE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;gBACb,MAAM,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM;CAMxE;AAgBD,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,+CAA+C;AAC/C,wBAAsB,cAAc,IAAI,OAAO,CAAC,QAAQ,CAAC,CAIxD;AAwCD;sEACsE;AACtE,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,MAAM,EACX,iBAAiB,CAAC,EAAE,MAAM,GACzB,cAAc,CAqBhB;AAeD;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,oBAAoB,EAC5B,eAAe,EAAE,uBAAuB,GACvC,OAAO,CAAC;IAAE,QAAQ,CAAC,KAAK,EAAE,iBAAiB,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,cAAc,CAAA;CAAE,CAAC,CAwBjF;AAED,wDAAwD;AACxD,wBAAsB,oBAAoB,CACxC,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAA;CAAE,EACzF,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CAwBzB;AAMD,2EAA2E;AAC3E,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,SAAS,EACpB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,mBAAmB,CAAC,CA2C9B;AAED,uEAAuE;AACvE,MAAM,MAAM,KAAK,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAElD;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,MAAM,MAAM,EACnB,KAAK,EAAE,KAAK,GACX,OAAO,CAAC,cAAc,CAAC,CAqCzB;AAMD,yDAAyD;AACzD,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,MAAM,EACpB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,cAAc,CAAC,CAuBzB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,oBAAoB,EAC5B,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,OAAO,CAAC,CAclB"}
@@ -0,0 +1,305 @@
1
+ /**
2
+ * oauth-flow.ts — the OAuth 2.0 machinery for calendar connectivity: the
3
+ * authorization-code flow with a loopback redirect and mandatory PKCE (the standard
4
+ * native-app pattern, RFC 8252/7636), and the device-code flow (RFC 8628) as the
5
+ * headless fallback. Token exchange, refresh, and revocation live here too.
6
+ *
7
+ * Every network call goes through the injected HttpFetch — this file never imports
8
+ * a real fetch — so the full flow runs against fake servers in tests with no real
9
+ * network and no real port. PKCE hashing/randomness reuse the SDK's runtime-neutral
10
+ * crypto adapter.
11
+ */
12
+ import { createSha256Hash, randomBytesBase64url } from '../runtime/auth/crypto-adapter.js';
13
+ /** A typed flow failure carrying the honest reason a caller surfaces to the user. */
14
+ export class OAuthFlowError extends Error {
15
+ reason;
16
+ /** The provider status, when the failure came from an HTTP response. */
17
+ status;
18
+ constructor(reason, message, status) {
19
+ super(message);
20
+ this.name = 'OAuthFlowError';
21
+ this.reason = reason;
22
+ if (typeof status === 'number')
23
+ this.status = status;
24
+ }
25
+ }
26
+ function assertClientConfigured(config) {
27
+ if (config.isPlaceholder) {
28
+ throw new OAuthFlowError('client-not-configured', `No ${config.provider} client id is configured. Either this build ships no project default yet, ` +
29
+ 'or supply your own client id under advanced settings.');
30
+ }
31
+ }
32
+ /** Create a PKCE verifier + S256 challenge. */
33
+ export async function createPkcePair() {
34
+ const verifier = randomBytesBase64url(32);
35
+ const challenge = await createSha256Hash(verifier);
36
+ return { verifier, challenge };
37
+ }
38
+ /**
39
+ * A conservative fallback lifetime (seconds) used when a provider's token response
40
+ * omits `expires_in` or sends something we cannot parse as a positive number. Never
41
+ * treat that as "never expires" — an access token that silently 401s later, with no
42
+ * expiry recorded to trigger a proactive refresh, is worse than refreshing a bit
43
+ * early. One hour matches the common real-world default (Google/Microsoft both
44
+ * normally send 3600).
45
+ */
46
+ const DEFAULT_EXPIRES_IN_SECONDS = 3600;
47
+ /**
48
+ * Coerce a token response's `expires_in` into a positive number of seconds.
49
+ * Accepts a real number, a numeric string (some providers send `"3600"` instead of
50
+ * `3600`), and falls back to {@link DEFAULT_EXPIRES_IN_SECONDS} for anything else
51
+ * (absent, non-numeric, zero, or negative) — this build never emits a token set with
52
+ * no expiry at all, which the store would otherwise read as "connected forever".
53
+ */
54
+ function coerceExpiresInSeconds(raw) {
55
+ if (typeof raw === 'number' && Number.isFinite(raw) && raw > 0)
56
+ return raw;
57
+ if (typeof raw === 'string') {
58
+ const parsed = Number(raw.trim());
59
+ if (Number.isFinite(parsed) && parsed > 0)
60
+ return parsed;
61
+ }
62
+ return DEFAULT_EXPIRES_IN_SECONDS;
63
+ }
64
+ /** Turn a provider token response into a StoredTokenSet, keeping a prior refresh
65
+ * token when the response omits one (Google omits it on refresh). */
66
+ export function parseTokenResponse(raw, now, priorRefreshToken) {
67
+ const json = (raw ?? {});
68
+ if (typeof json.access_token !== 'string' || json.access_token.length === 0) {
69
+ throw new OAuthFlowError('token-request-rejected', 'Token response did not include an access token.');
70
+ }
71
+ const refreshToken = typeof json.refresh_token === 'string' && json.refresh_token.length > 0
72
+ ? json.refresh_token
73
+ : priorRefreshToken;
74
+ const scopes = typeof json.scope === 'string' && json.scope.trim().length > 0
75
+ ? json.scope.trim().split(/\s+/)
76
+ : undefined;
77
+ return {
78
+ accessToken: json.access_token,
79
+ ...(refreshToken ? { refreshToken } : {}),
80
+ tokenType: typeof json.token_type === 'string' && json.token_type.length > 0 ? json.token_type : 'Bearer',
81
+ // Always set expiresAt — never omit it just because expires_in was absent or
82
+ // unparsable — a coerced/defaulted lifetime beats "never expires".
83
+ expiresAt: now + coerceExpiresInSeconds(json.expires_in) * 1000,
84
+ ...(scopes ? { scopes } : {}),
85
+ obtainedAt: now,
86
+ };
87
+ }
88
+ function formBody(payload) {
89
+ return new URLSearchParams(payload).toString();
90
+ }
91
+ async function readError(res) {
92
+ const body = await res.text().catch(() => '');
93
+ return body.length > 0 ? `${res.status}: ${body}` : `HTTP ${res.status}`;
94
+ }
95
+ // ---------------------------------------------------------------------------
96
+ // Authorization-code flow
97
+ // ---------------------------------------------------------------------------
98
+ /**
99
+ * Begin the authorization-code flow: bind a loopback listener, build the PKCE
100
+ * authorization URL, and return both. The caller opens the URL in a browser and
101
+ * awaits waiter.waitForCode(), then calls completeAuthCodeFlow.
102
+ */
103
+ export async function beginAuthCodeFlow(config, listenerFactory) {
104
+ assertClientConfigured(config);
105
+ const state = randomBytesBase64url(24);
106
+ const { verifier, challenge } = await createPkcePair();
107
+ const waiter = await listenerFactory({
108
+ expectedState: state,
109
+ ...(config.redirectHost ? { host: config.redirectHost } : {}),
110
+ ...(typeof config.redirectPort === 'number' ? { port: config.redirectPort } : {}),
111
+ });
112
+ const url = new URL(config.authorizationEndpoint);
113
+ url.searchParams.set('response_type', 'code');
114
+ url.searchParams.set('client_id', config.clientId);
115
+ url.searchParams.set('redirect_uri', waiter.redirectUri);
116
+ url.searchParams.set('state', state);
117
+ url.searchParams.set('scope', config.scopes.join(' '));
118
+ url.searchParams.set('code_challenge', challenge);
119
+ url.searchParams.set('code_challenge_method', 'S256');
120
+ for (const [key, value] of Object.entries(config.extraAuthParams ?? {})) {
121
+ url.searchParams.set(key, value);
122
+ }
123
+ return {
124
+ start: { authorizationUrl: url.toString(), state, verifier, redirectUri: waiter.redirectUri },
125
+ waiter,
126
+ };
127
+ }
128
+ /** Exchange an authorization code for tokens (PKCE). */
129
+ export async function completeAuthCodeFlow(config, fetchImpl, input, now) {
130
+ const payload = {
131
+ grant_type: 'authorization_code',
132
+ client_id: config.clientId,
133
+ code: input.code,
134
+ redirect_uri: input.redirectUri,
135
+ code_verifier: input.verifier,
136
+ };
137
+ if (config.clientSecret)
138
+ payload.client_secret = config.clientSecret;
139
+ let res;
140
+ try {
141
+ res = await fetchImpl({
142
+ url: config.tokenEndpoint,
143
+ method: 'POST',
144
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' },
145
+ body: formBody(payload),
146
+ });
147
+ }
148
+ catch (error) {
149
+ throw new OAuthFlowError('network-error', `Reaching the token endpoint failed: ${describe(error)}`);
150
+ }
151
+ if (!res.ok) {
152
+ throw new OAuthFlowError('token-request-rejected', `Token exchange failed (${await readError(res)}).`, res.status);
153
+ }
154
+ return parseTokenResponse(await res.json(), now);
155
+ }
156
+ // ---------------------------------------------------------------------------
157
+ // Device-code flow (RFC 8628)
158
+ // ---------------------------------------------------------------------------
159
+ /** Begin the device-code flow: request a device + user code to display. */
160
+ export async function beginDeviceCodeFlow(config, fetchImpl, now) {
161
+ assertClientConfigured(config);
162
+ let res;
163
+ try {
164
+ res = await fetchImpl({
165
+ url: config.deviceAuthorizationEndpoint,
166
+ method: 'POST',
167
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' },
168
+ body: formBody({ client_id: config.clientId, scope: config.scopes.join(' ') }),
169
+ });
170
+ }
171
+ catch (error) {
172
+ throw new OAuthFlowError('network-error', `Reaching the device endpoint failed: ${describe(error)}`);
173
+ }
174
+ if (!res.ok) {
175
+ throw new OAuthFlowError('token-request-rejected', `Device authorization failed (${await readError(res)}).`, res.status);
176
+ }
177
+ const json = (await res.json());
178
+ const deviceCode = requireString(json.device_code, 'device_code');
179
+ const userCode = requireString(json.user_code, 'user_code');
180
+ // Google returns verification_url; the RFC and Microsoft use verification_uri.
181
+ const verificationUri = typeof json.verification_uri === 'string'
182
+ ? json.verification_uri
183
+ : requireString(json.verification_url, 'verification_uri');
184
+ const expiresIn = typeof json.expires_in === 'number' ? json.expires_in : 900;
185
+ const interval = typeof json.interval === 'number' ? json.interval : 5;
186
+ return {
187
+ deviceCode,
188
+ userCode,
189
+ verificationUri,
190
+ ...(typeof json.verification_uri_complete === 'string'
191
+ ? { verificationUriComplete: json.verification_uri_complete }
192
+ : {}),
193
+ expiresAt: now + expiresIn * 1000,
194
+ intervalMs: interval * 1000,
195
+ };
196
+ }
197
+ /**
198
+ * Poll the token endpoint until the user approves the device code, the code expires,
199
+ * or the request is denied. Honors authorization_pending (keep polling) and slow_down
200
+ * (widen the interval) per RFC 8628.
201
+ */
202
+ export async function pollDeviceCodeFlow(config, fetchImpl, start, clock, sleep) {
203
+ let intervalMs = start.intervalMs;
204
+ for (;;) {
205
+ if (clock() >= start.expiresAt) {
206
+ throw new OAuthFlowError('device-code-expired', 'The device code expired before it was approved.');
207
+ }
208
+ await sleep(intervalMs);
209
+ const payload = {
210
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
211
+ client_id: config.clientId,
212
+ device_code: start.deviceCode,
213
+ };
214
+ if (config.clientSecret)
215
+ payload.client_secret = config.clientSecret;
216
+ let res;
217
+ try {
218
+ res = await fetchImpl({
219
+ url: config.tokenEndpoint,
220
+ method: 'POST',
221
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' },
222
+ body: formBody(payload),
223
+ });
224
+ }
225
+ catch (error) {
226
+ throw new OAuthFlowError('network-error', `Polling the token endpoint failed: ${describe(error)}`);
227
+ }
228
+ if (res.ok)
229
+ return parseTokenResponse(await res.json(), clock());
230
+ const body = (await res.json().catch(() => ({})));
231
+ const err = typeof body.error === 'string' ? body.error : `http_${res.status}`;
232
+ if (err === 'authorization_pending')
233
+ continue;
234
+ if (err === 'slow_down') {
235
+ intervalMs += 5000;
236
+ continue;
237
+ }
238
+ if (err === 'expired_token') {
239
+ throw new OAuthFlowError('device-code-expired', 'The device code expired before it was approved.');
240
+ }
241
+ throw new OAuthFlowError('token-request-rejected', `Device authorization was rejected (${err}).`, res.status);
242
+ }
243
+ }
244
+ // ---------------------------------------------------------------------------
245
+ // Refresh + revoke
246
+ // ---------------------------------------------------------------------------
247
+ /** Exchange a refresh token for a fresh access token. */
248
+ export async function refreshAccessToken(config, fetchImpl, refreshToken, now) {
249
+ const payload = {
250
+ grant_type: 'refresh_token',
251
+ client_id: config.clientId,
252
+ refresh_token: refreshToken,
253
+ };
254
+ if (config.clientSecret)
255
+ payload.client_secret = config.clientSecret;
256
+ let res;
257
+ try {
258
+ res = await fetchImpl({
259
+ url: config.tokenEndpoint,
260
+ method: 'POST',
261
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded', Accept: 'application/json' },
262
+ body: formBody(payload),
263
+ });
264
+ }
265
+ catch (error) {
266
+ throw new OAuthFlowError('network-error', `Reaching the token endpoint failed: ${describe(error)}`);
267
+ }
268
+ if (!res.ok) {
269
+ throw new OAuthFlowError('token-request-rejected', `Token refresh failed (${await readError(res)}).`, res.status);
270
+ }
271
+ // Preserve the prior refresh token when the provider omits a new one.
272
+ return parseTokenResponse(await res.json(), now, refreshToken);
273
+ }
274
+ /**
275
+ * Revoke a token at the provider (Google). Returns true when the provider confirms.
276
+ * When the provider has no revocation endpoint (Microsoft), returns false so the
277
+ * caller knows disconnect is local-only.
278
+ */
279
+ export async function revokeToken(config, fetchImpl, token) {
280
+ if (!config.revocationEndpoint)
281
+ return false;
282
+ try {
283
+ const res = await fetchImpl({
284
+ url: config.revocationEndpoint,
285
+ method: 'POST',
286
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
287
+ body: formBody({ token }),
288
+ });
289
+ return res.ok;
290
+ }
291
+ catch {
292
+ // A revocation network failure must not block a local disconnect.
293
+ return false;
294
+ }
295
+ }
296
+ // ---------------------------------------------------------------------------
297
+ function requireString(value, field) {
298
+ if (typeof value !== 'string' || value.length === 0) {
299
+ throw new OAuthFlowError('token-request-rejected', `Provider response missing ${field}.`);
300
+ }
301
+ return value;
302
+ }
303
+ function describe(error) {
304
+ return error instanceof Error ? error.message : String(error);
305
+ }
@@ -0,0 +1,43 @@
1
+ /**
2
+ * oauth-providers.ts — the fixed provider profiles for Google Calendar and
3
+ * Microsoft Outlook (Graph), plus client-config resolution.
4
+ *
5
+ * Design (One-Platform Wave 4, A10, per Mike's least-friction rule): the DEFAULT
6
+ * experience uses a bundled project-level client id (rclone/gh pattern). A native-
7
+ * app / public-client id is not a secret (RFC 8252), so paired with PKCE no client
8
+ * secret is needed. Power users MAY override with their own client id (+ secret for
9
+ * a confidential registration) — surfaced only under an "advanced" affordance, never
10
+ * as a required step.
11
+ *
12
+ * The bundledClientId ships as an honest PLACEHOLDER. Mike registers the two project
13
+ * apps once and drops the real ids into config defaults; after that every user's flow
14
+ * is just: connect -> browser opens -> approve -> done. Until then, resolveClientConfig
15
+ * reports isPlaceholder:true and flows refuse with `client-not-configured` rather than
16
+ * faking a success.
17
+ */
18
+ import type { CalendarProviderId, OAuthClientOverrides, OAuthProviderProfile, ResolvedClientConfig } from './oauth-types.js';
19
+ /** Honest placeholders — replaced once the project apps are registered. */
20
+ export declare const GOOGLE_PLACEHOLDER_CLIENT_ID = "REPLACE_WITH_PROJECT_GOOGLE_CLIENT_ID.apps.googleusercontent.com";
21
+ export declare const MICROSOFT_PLACEHOLDER_CLIENT_ID = "REPLACE_WITH_PROJECT_MICROSOFT_CLIENT_ID";
22
+ /** Google Calendar read scope and read/write events scope. Read-write is the default
23
+ * so event creation works; a user may narrow to read-only via overrides. */
24
+ export declare const GOOGLE_SCOPES_DEFAULT: readonly ["https://www.googleapis.com/auth/calendar.readonly", "https://www.googleapis.com/auth/calendar.events"];
25
+ /** Microsoft Graph read/write calendar scope (+ offline_access for a refresh token). */
26
+ export declare const MICROSOFT_SCOPES_DEFAULT: readonly ["offline_access", "Calendars.ReadWrite"];
27
+ export declare const GOOGLE_PROFILE: OAuthProviderProfile;
28
+ export declare const MICROSOFT_PROFILE: OAuthProviderProfile;
29
+ /** Look up a provider profile. */
30
+ export declare function providerProfile(provider: CalendarProviderId): OAuthProviderProfile;
31
+ /**
32
+ * Merge a profile with a user's optional overrides into the config a flow runs with.
33
+ * A bundled profile whose id is still the placeholder resolves isPlaceholder:true
34
+ * UNLESS the user supplied their own clientId.
35
+ */
36
+ export declare function resolveClientConfig(profile: OAuthProviderProfile, overrides?: OAuthClientOverrides): ResolvedClientConfig;
37
+ /**
38
+ * The exact provider-console steps a user (or Mike, registering the project apps)
39
+ * follows. Surfaced verbatim by the wizard's "advanced" help and copied into the
40
+ * module docs. Kept as data so the wizard and docs never drift.
41
+ */
42
+ export declare const PROVIDER_SETUP_STEPS: Readonly<Record<CalendarProviderId, readonly string[]>>;
43
+ //# sourceMappingURL=oauth-providers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-providers.d.ts","sourceRoot":"","sources":["../../../src/platform/calendar/oauth-providers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACrB,MAAM,kBAAkB,CAAC;AAE1B,2EAA2E;AAC3E,eAAO,MAAM,4BAA4B,qEAC2B,CAAC;AACrE,eAAO,MAAM,+BAA+B,6CACA,CAAC;AAE7C;6EAC6E;AAC7E,eAAO,MAAM,qBAAqB,mHAGxB,CAAC;AAEX,wFAAwF;AACxF,eAAO,MAAM,wBAAwB,oDAG3B,CAAC;AAEX,eAAO,MAAM,cAAc,EAAE,oBAc5B,CAAC;AAEF,eAAO,MAAM,iBAAiB,EAAE,oBAY/B,CAAC;AAOF,kCAAkC;AAClC,wBAAgB,eAAe,CAAC,QAAQ,EAAE,kBAAkB,GAAG,oBAAoB,CAElF;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,oBAAoB,EAC7B,SAAS,CAAC,EAAE,oBAAoB,GAC/B,oBAAoB,CAwBtB;AAED;;;;GAIG;AACH,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,MAAM,CAAC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC,CAiBxF,CAAC"}
@@ -0,0 +1,120 @@
1
+ /**
2
+ * oauth-providers.ts — the fixed provider profiles for Google Calendar and
3
+ * Microsoft Outlook (Graph), plus client-config resolution.
4
+ *
5
+ * Design (One-Platform Wave 4, A10, per Mike's least-friction rule): the DEFAULT
6
+ * experience uses a bundled project-level client id (rclone/gh pattern). A native-
7
+ * app / public-client id is not a secret (RFC 8252), so paired with PKCE no client
8
+ * secret is needed. Power users MAY override with their own client id (+ secret for
9
+ * a confidential registration) — surfaced only under an "advanced" affordance, never
10
+ * as a required step.
11
+ *
12
+ * The bundledClientId ships as an honest PLACEHOLDER. Mike registers the two project
13
+ * apps once and drops the real ids into config defaults; after that every user's flow
14
+ * is just: connect -> browser opens -> approve -> done. Until then, resolveClientConfig
15
+ * reports isPlaceholder:true and flows refuse with `client-not-configured` rather than
16
+ * faking a success.
17
+ */
18
+ /** Honest placeholders — replaced once the project apps are registered. */
19
+ export const GOOGLE_PLACEHOLDER_CLIENT_ID = 'REPLACE_WITH_PROJECT_GOOGLE_CLIENT_ID.apps.googleusercontent.com';
20
+ export const MICROSOFT_PLACEHOLDER_CLIENT_ID = 'REPLACE_WITH_PROJECT_MICROSOFT_CLIENT_ID';
21
+ /** Google Calendar read scope and read/write events scope. Read-write is the default
22
+ * so event creation works; a user may narrow to read-only via overrides. */
23
+ export const GOOGLE_SCOPES_DEFAULT = [
24
+ 'https://www.googleapis.com/auth/calendar.readonly',
25
+ 'https://www.googleapis.com/auth/calendar.events',
26
+ ];
27
+ /** Microsoft Graph read/write calendar scope (+ offline_access for a refresh token). */
28
+ export const MICROSOFT_SCOPES_DEFAULT = [
29
+ 'offline_access',
30
+ 'Calendars.ReadWrite',
31
+ ];
32
+ export const GOOGLE_PROFILE = {
33
+ provider: 'google',
34
+ displayName: 'Google Calendar',
35
+ authorizationEndpoint: 'https://accounts.google.com/o/oauth2/v2/auth',
36
+ tokenEndpoint: 'https://oauth2.googleapis.com/token',
37
+ deviceAuthorizationEndpoint: 'https://oauth2.googleapis.com/device/code',
38
+ revocationEndpoint: 'https://oauth2.googleapis.com/revoke',
39
+ apiBaseUrl: 'https://www.googleapis.com/calendar/v3',
40
+ defaultScopes: GOOGLE_SCOPES_DEFAULT,
41
+ bundledClientId: GOOGLE_PLACEHOLDER_CLIENT_ID,
42
+ placeholderClientId: GOOGLE_PLACEHOLDER_CLIENT_ID,
43
+ // access_type=offline + prompt=consent so Google returns a refresh token on the
44
+ // first authorization and re-issues one on re-consent.
45
+ extraAuthParams: { access_type: 'offline', prompt: 'consent' },
46
+ };
47
+ export const MICROSOFT_PROFILE = {
48
+ provider: 'microsoft',
49
+ displayName: 'Microsoft Outlook',
50
+ // 'common' lets both personal and work/school accounts authenticate.
51
+ authorizationEndpoint: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
52
+ tokenEndpoint: 'https://login.microsoftonline.com/common/oauth2/v2.0/token',
53
+ deviceAuthorizationEndpoint: 'https://login.microsoftonline.com/common/oauth2/v2.0/devicecode',
54
+ // Microsoft has no OAuth revocation endpoint; disconnect is local token deletion.
55
+ apiBaseUrl: 'https://graph.microsoft.com/v1.0',
56
+ defaultScopes: MICROSOFT_SCOPES_DEFAULT,
57
+ bundledClientId: MICROSOFT_PLACEHOLDER_CLIENT_ID,
58
+ placeholderClientId: MICROSOFT_PLACEHOLDER_CLIENT_ID,
59
+ };
60
+ const PROFILES = {
61
+ google: GOOGLE_PROFILE,
62
+ microsoft: MICROSOFT_PROFILE,
63
+ };
64
+ /** Look up a provider profile. */
65
+ export function providerProfile(provider) {
66
+ return PROFILES[provider];
67
+ }
68
+ /**
69
+ * Merge a profile with a user's optional overrides into the config a flow runs with.
70
+ * A bundled profile whose id is still the placeholder resolves isPlaceholder:true
71
+ * UNLESS the user supplied their own clientId.
72
+ */
73
+ export function resolveClientConfig(profile, overrides) {
74
+ const overrodeClientId = typeof overrides?.clientId === 'string' && overrides.clientId.trim().length > 0;
75
+ const clientId = overrodeClientId ? overrides.clientId.trim() : profile.bundledClientId;
76
+ const usingBundledDefault = !overrodeClientId;
77
+ const isPlaceholder = usingBundledDefault && clientId === profile.placeholderClientId;
78
+ const scopes = overrides?.scopes && overrides.scopes.length > 0 ? overrides.scopes : profile.defaultScopes;
79
+ return {
80
+ provider: profile.provider,
81
+ clientId,
82
+ ...(overrides?.clientSecret && overrides.clientSecret.length > 0
83
+ ? { clientSecret: overrides.clientSecret }
84
+ : {}),
85
+ scopes,
86
+ authorizationEndpoint: profile.authorizationEndpoint,
87
+ tokenEndpoint: profile.tokenEndpoint,
88
+ deviceAuthorizationEndpoint: profile.deviceAuthorizationEndpoint,
89
+ ...(profile.revocationEndpoint ? { revocationEndpoint: profile.revocationEndpoint } : {}),
90
+ apiBaseUrl: profile.apiBaseUrl,
91
+ ...(profile.extraAuthParams ? { extraAuthParams: profile.extraAuthParams } : {}),
92
+ ...(overrides?.redirectHost ? { redirectHost: overrides.redirectHost } : {}),
93
+ ...(typeof overrides?.redirectPort === 'number' ? { redirectPort: overrides.redirectPort } : {}),
94
+ usingBundledDefault,
95
+ isPlaceholder,
96
+ };
97
+ }
98
+ /**
99
+ * The exact provider-console steps a user (or Mike, registering the project apps)
100
+ * follows. Surfaced verbatim by the wizard's "advanced" help and copied into the
101
+ * module docs. Kept as data so the wizard and docs never drift.
102
+ */
103
+ export const PROVIDER_SETUP_STEPS = {
104
+ google: [
105
+ 'Open the Google Cloud Console (console.cloud.google.com) and select or create a project.',
106
+ 'APIs & Services -> Library -> enable "Google Calendar API".',
107
+ 'APIs & Services -> OAuth consent screen -> configure (External is fine for personal use); add your Google account under Test users while the app is unverified.',
108
+ 'APIs & Services -> Credentials -> Create Credentials -> OAuth client ID -> Application type "Desktop app".',
109
+ 'Copy the generated Client ID. A Desktop-app client needs NO client secret with PKCE; leave the secret field blank unless you deliberately use a Web-app client.',
110
+ 'Paste the Client ID into the wizard under "advanced", or (project owner) drop it into the config default calendar.google.clientId.',
111
+ ],
112
+ microsoft: [
113
+ 'Open the Azure portal (portal.azure.com) -> Microsoft Entra ID -> App registrations -> New registration.',
114
+ 'Name the app; under "Supported account types" pick "Accounts in any organizational directory and personal Microsoft accounts" for the broadest reach.',
115
+ 'Under "Redirect URI" add a "Mobile and desktop applications" platform and the entry http://localhost (the loopback flow supplies its own 127.0.0.1 port).',
116
+ 'Registration -> Authentication -> enable "Allow public client flows" = Yes (this is the public-client / device-code property; no client secret is needed).',
117
+ 'Registration -> API permissions -> Add a permission -> Microsoft Graph -> Delegated -> add Calendars.ReadWrite and offline_access.',
118
+ 'Copy the "Application (client) ID". Paste it into the wizard under "advanced", or (project owner) drop it into the config default calendar.microsoft.clientId.',
119
+ ],
120
+ };