@aligndottech/cli 0.50.0 → 0.52.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 (323) hide show
  1. package/README.md +1 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +6 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/config.d.ts +8 -0
  6. package/dist/commands/config.d.ts.map +1 -0
  7. package/dist/commands/config.js +33 -0
  8. package/dist/commands/config.js.map +1 -0
  9. package/dist/commands/connect-agents.d.ts.map +1 -1
  10. package/dist/commands/connect-agents.js +3 -1
  11. package/dist/commands/connect-agents.js.map +1 -1
  12. package/dist/commands/env.d.ts.map +1 -1
  13. package/dist/commands/env.js +11 -0
  14. package/dist/commands/env.js.map +1 -1
  15. package/dist/commands/invite.d.ts +8 -18
  16. package/dist/commands/invite.d.ts.map +1 -1
  17. package/dist/commands/invite.js +23 -46
  18. package/dist/commands/invite.js.map +1 -1
  19. package/dist/commands/join.d.ts +5 -0
  20. package/dist/commands/join.d.ts.map +1 -0
  21. package/dist/commands/join.js +49 -0
  22. package/dist/commands/join.js.map +1 -0
  23. package/dist/commands/local-relink.d.ts +35 -0
  24. package/dist/commands/local-relink.d.ts.map +1 -0
  25. package/dist/commands/local-relink.js +72 -0
  26. package/dist/commands/local-relink.js.map +1 -0
  27. package/dist/commands/local.d.ts.map +1 -1
  28. package/dist/commands/local.js +37 -0
  29. package/dist/commands/local.js.map +1 -1
  30. package/dist/commands/login.d.ts.map +1 -1
  31. package/dist/commands/login.js +21 -2
  32. package/dist/commands/login.js.map +1 -1
  33. package/dist/commands/mcp.d.ts +8 -0
  34. package/dist/commands/mcp.d.ts.map +1 -1
  35. package/dist/commands/mcp.js +12 -5
  36. package/dist/commands/mcp.js.map +1 -1
  37. package/dist/commands/registry.d.ts.map +1 -1
  38. package/dist/commands/registry.js +4 -0
  39. package/dist/commands/registry.js.map +1 -1
  40. package/dist/commands/share.d.ts.map +1 -1
  41. package/dist/commands/share.js +81 -12
  42. package/dist/commands/share.js.map +1 -1
  43. package/dist/commands/status.d.ts.map +1 -1
  44. package/dist/commands/status.js +10 -0
  45. package/dist/commands/status.js.map +1 -1
  46. package/dist/detector/detector-version.d.ts +16 -0
  47. package/dist/detector/detector-version.d.ts.map +1 -0
  48. package/dist/detector/detector-version.js +36 -0
  49. package/dist/detector/detector-version.js.map +1 -0
  50. package/dist/detector/relationship-contract.d.ts +30 -0
  51. package/dist/detector/relationship-contract.d.ts.map +1 -0
  52. package/dist/detector/relationship-contract.js +120 -0
  53. package/dist/detector/relationship-contract.js.map +1 -0
  54. package/dist/detector/relationship-contract.v1.json +53 -0
  55. package/dist/detector/relationship-prompt.d.ts +20 -0
  56. package/dist/detector/relationship-prompt.d.ts.map +1 -0
  57. package/dist/detector/relationship-prompt.js +55 -0
  58. package/dist/detector/relationship-prompt.js.map +1 -0
  59. package/dist/detector/relationship-prompt.v1.json +13 -0
  60. package/dist/detector/resolve-pair.d.ts +39 -0
  61. package/dist/detector/resolve-pair.d.ts.map +1 -0
  62. package/dist/detector/resolve-pair.js +345 -0
  63. package/dist/detector/resolve-pair.js.map +1 -0
  64. package/dist/detector/similar-item.d.ts +20 -0
  65. package/dist/detector/similar-item.d.ts.map +1 -0
  66. package/dist/detector/similar-item.js +16 -0
  67. package/dist/detector/similar-item.js.map +1 -0
  68. package/dist/index.js +37 -13
  69. package/dist/index.js.map +1 -1
  70. package/dist/lib/advisory-dedup.d.ts.map +1 -1
  71. package/dist/lib/advisory-dedup.js +16 -8
  72. package/dist/lib/advisory-dedup.js.map +1 -1
  73. package/dist/lib/advisory-verdict.d.ts +19 -0
  74. package/dist/lib/advisory-verdict.d.ts.map +1 -1
  75. package/dist/lib/advisory-verdict.js +6 -3
  76. package/dist/lib/advisory-verdict.js.map +1 -1
  77. package/dist/lib/backup-exclusion.d.ts +10 -0
  78. package/dist/lib/backup-exclusion.d.ts.map +1 -0
  79. package/dist/lib/backup-exclusion.js +58 -0
  80. package/dist/lib/backup-exclusion.js.map +1 -0
  81. package/dist/lib/cli-oauth.d.ts +2 -0
  82. package/dist/lib/cli-oauth.d.ts.map +1 -1
  83. package/dist/lib/cli-oauth.js +61 -10
  84. package/dist/lib/cli-oauth.js.map +1 -1
  85. package/dist/lib/config.d.ts +41 -1
  86. package/dist/lib/config.d.ts.map +1 -1
  87. package/dist/lib/config.js +109 -1
  88. package/dist/lib/config.js.map +1 -1
  89. package/dist/lib/curation/guardrail.d.ts.map +1 -1
  90. package/dist/lib/curation/guardrail.js +2 -0
  91. package/dist/lib/curation/guardrail.js.map +1 -1
  92. package/dist/lib/curation/judgements-db.d.ts +1 -0
  93. package/dist/lib/curation/judgements-db.d.ts.map +1 -1
  94. package/dist/lib/curation/judgements-db.js +9 -3
  95. package/dist/lib/curation/judgements-db.js.map +1 -1
  96. package/dist/lib/curation/mark.js +4 -2
  97. package/dist/lib/curation/mark.js.map +1 -1
  98. package/dist/lib/destination-name.d.ts +24 -0
  99. package/dist/lib/destination-name.d.ts.map +1 -0
  100. package/dist/lib/destination-name.js +39 -0
  101. package/dist/lib/destination-name.js.map +1 -0
  102. package/dist/lib/destination-summary.d.ts +6 -0
  103. package/dist/lib/destination-summary.d.ts.map +1 -0
  104. package/dist/lib/destination-summary.js +27 -0
  105. package/dist/lib/destination-summary.js.map +1 -0
  106. package/dist/lib/destination-trust.d.ts +54 -0
  107. package/dist/lib/destination-trust.d.ts.map +1 -0
  108. package/dist/lib/destination-trust.js +107 -0
  109. package/dist/lib/destination-trust.js.map +1 -0
  110. package/dist/lib/env-resolver.d.ts.map +1 -1
  111. package/dist/lib/env-resolver.js +3 -0
  112. package/dist/lib/env-resolver.js.map +1 -1
  113. package/dist/lib/fatal.d.ts +11 -0
  114. package/dist/lib/fatal.d.ts.map +1 -0
  115. package/dist/lib/fatal.js +22 -0
  116. package/dist/lib/fatal.js.map +1 -0
  117. package/dist/lib/gateway-client.d.ts +8 -16
  118. package/dist/lib/gateway-client.d.ts.map +1 -1
  119. package/dist/lib/gateway-client.js +30 -20
  120. package/dist/lib/gateway-client.js.map +1 -1
  121. package/dist/lib/invite-prompt.d.ts +4 -4
  122. package/dist/lib/invite-prompt.d.ts.map +1 -1
  123. package/dist/lib/invite-prompt.js +4 -4
  124. package/dist/lib/invite-prompt.js.map +1 -1
  125. package/dist/lib/invite-settings.d.ts +18 -0
  126. package/dist/lib/invite-settings.d.ts.map +1 -0
  127. package/dist/lib/invite-settings.js +29 -0
  128. package/dist/lib/invite-settings.js.map +1 -0
  129. package/dist/lib/join-flow.d.ts +60 -0
  130. package/dist/lib/join-flow.d.ts.map +1 -0
  131. package/dist/lib/join-flow.js +282 -0
  132. package/dist/lib/join-flow.js.map +1 -0
  133. package/dist/lib/launch/mcp-child-env.d.ts.map +1 -1
  134. package/dist/lib/launch/mcp-child-env.js +5 -2
  135. package/dist/lib/launch/mcp-child-env.js.map +1 -1
  136. package/dist/lib/lead-prompt.d.ts +106 -0
  137. package/dist/lib/lead-prompt.d.ts.map +1 -0
  138. package/dist/lib/lead-prompt.js +175 -0
  139. package/dist/lib/lead-prompt.js.map +1 -0
  140. package/dist/lib/local-candidate-classify.d.ts +26 -0
  141. package/dist/lib/local-candidate-classify.d.ts.map +1 -0
  142. package/dist/lib/local-candidate-classify.js +53 -0
  143. package/dist/lib/local-candidate-classify.js.map +1 -0
  144. package/dist/lib/local-db-migrate.d.ts +1 -1
  145. package/dist/lib/local-db-migrate.d.ts.map +1 -1
  146. package/dist/lib/local-db-migrate.js +45 -1
  147. package/dist/lib/local-db-migrate.js.map +1 -1
  148. package/dist/lib/local-db-v12.d.ts +17 -0
  149. package/dist/lib/local-db-v12.d.ts.map +1 -0
  150. package/dist/lib/local-db-v12.js +8 -0
  151. package/dist/lib/local-db-v12.js.map +1 -0
  152. package/dist/lib/local-db.d.ts +13 -13
  153. package/dist/lib/local-db.d.ts.map +1 -1
  154. package/dist/lib/local-db.js +41 -6
  155. package/dist/lib/local-db.js.map +1 -1
  156. package/dist/lib/local-gateway-client.d.ts +1 -0
  157. package/dist/lib/local-gateway-client.d.ts.map +1 -1
  158. package/dist/lib/local-gateway-client.js +31 -20
  159. package/dist/lib/local-gateway-client.js.map +1 -1
  160. package/dist/lib/local-ingest.d.ts +2 -0
  161. package/dist/lib/local-ingest.d.ts.map +1 -1
  162. package/dist/lib/local-ingest.js.map +1 -1
  163. package/dist/lib/local-link-pass.d.ts.map +1 -1
  164. package/dist/lib/local-link-pass.js +25 -29
  165. package/dist/lib/local-link-pass.js.map +1 -1
  166. package/dist/lib/local-llm.d.ts +1 -1
  167. package/dist/lib/local-llm.d.ts.map +1 -1
  168. package/dist/lib/local-llm.js +3 -2
  169. package/dist/lib/local-llm.js.map +1 -1
  170. package/dist/lib/local-mode.d.ts +5 -1
  171. package/dist/lib/local-mode.d.ts.map +1 -1
  172. package/dist/lib/local-mode.js +11 -6
  173. package/dist/lib/local-mode.js.map +1 -1
  174. package/dist/lib/local-relationship-classifier.d.ts +4 -0
  175. package/dist/lib/local-relationship-classifier.d.ts.map +1 -1
  176. package/dist/lib/local-relationship-classifier.js +9 -4
  177. package/dist/lib/local-relationship-classifier.js.map +1 -1
  178. package/dist/lib/local-relink.d.ts +59 -0
  179. package/dist/lib/local-relink.d.ts.map +1 -0
  180. package/dist/lib/local-relink.js +171 -0
  181. package/dist/lib/local-relink.js.map +1 -0
  182. package/dist/lib/local-set-classifier.d.ts +36 -0
  183. package/dist/lib/local-set-classifier.d.ts.map +1 -0
  184. package/dist/lib/local-set-classifier.js +81 -0
  185. package/dist/lib/local-set-classifier.js.map +1 -0
  186. package/dist/lib/local-snapshot-loader.d.ts +29 -0
  187. package/dist/lib/local-snapshot-loader.d.ts.map +1 -0
  188. package/dist/lib/local-snapshot-loader.js +108 -0
  189. package/dist/lib/local-snapshot-loader.js.map +1 -0
  190. package/dist/lib/login-flow.d.ts +15 -0
  191. package/dist/lib/login-flow.d.ts.map +1 -1
  192. package/dist/lib/login-flow.js +80 -4
  193. package/dist/lib/login-flow.js.map +1 -1
  194. package/dist/lib/mcp/share-status-tool.d.ts +13 -0
  195. package/dist/lib/mcp/share-status-tool.d.ts.map +1 -0
  196. package/dist/lib/mcp/share-status-tool.js +116 -0
  197. package/dist/lib/mcp/share-status-tool.js.map +1 -0
  198. package/dist/lib/mcp/share-tool.d.ts +18 -14
  199. package/dist/lib/mcp/share-tool.d.ts.map +1 -1
  200. package/dist/lib/mcp/share-tool.js +127 -21
  201. package/dist/lib/mcp/share-tool.js.map +1 -1
  202. package/dist/lib/model-cache.d.ts +10 -0
  203. package/dist/lib/model-cache.d.ts.map +1 -0
  204. package/dist/lib/model-cache.js +35 -0
  205. package/dist/lib/model-cache.js.map +1 -0
  206. package/dist/lib/next-step.d.ts.map +1 -1
  207. package/dist/lib/next-step.js +2 -1
  208. package/dist/lib/next-step.js.map +1 -1
  209. package/dist/lib/private-files.d.ts +38 -0
  210. package/dist/lib/private-files.d.ts.map +1 -0
  211. package/dist/lib/private-files.js +102 -0
  212. package/dist/lib/private-files.js.map +1 -0
  213. package/dist/lib/redaction-notice.d.ts +7 -0
  214. package/dist/lib/redaction-notice.d.ts.map +1 -0
  215. package/dist/lib/redaction-notice.js +32 -0
  216. package/dist/lib/redaction-notice.js.map +1 -0
  217. package/dist/lib/relink-estimate.d.ts +16 -0
  218. package/dist/lib/relink-estimate.d.ts.map +1 -0
  219. package/dist/lib/relink-estimate.js +30 -0
  220. package/dist/lib/relink-estimate.js.map +1 -0
  221. package/dist/lib/resolve-env.d.ts +15 -1
  222. package/dist/lib/resolve-env.d.ts.map +1 -1
  223. package/dist/lib/resolve-env.js +27 -7
  224. package/dist/lib/resolve-env.js.map +1 -1
  225. package/dist/lib/scope-defaults.d.ts.map +1 -1
  226. package/dist/lib/scope-defaults.js +2 -0
  227. package/dist/lib/scope-defaults.js.map +1 -1
  228. package/dist/lib/scope-real.d.ts +57 -0
  229. package/dist/lib/scope-real.d.ts.map +1 -1
  230. package/dist/lib/setup-route.d.ts +4 -2
  231. package/dist/lib/setup-route.d.ts.map +1 -1
  232. package/dist/lib/setup-route.js +12 -6
  233. package/dist/lib/setup-route.js.map +1 -1
  234. package/dist/lib/share/approval.d.ts +71 -0
  235. package/dist/lib/share/approval.d.ts.map +1 -0
  236. package/dist/lib/share/approval.js +139 -0
  237. package/dist/lib/share/approval.js.map +1 -0
  238. package/dist/lib/share/approve-link.d.ts +31 -0
  239. package/dist/lib/share/approve-link.d.ts.map +1 -0
  240. package/dist/lib/share/approve-link.js +46 -0
  241. package/dist/lib/share/approve-link.js.map +1 -0
  242. package/dist/lib/share/browser-flow.d.ts +85 -0
  243. package/dist/lib/share/browser-flow.d.ts.map +1 -0
  244. package/dist/lib/share/browser-flow.js +168 -0
  245. package/dist/lib/share/browser-flow.js.map +1 -0
  246. package/dist/lib/share/command.d.ts +34 -1
  247. package/dist/lib/share/command.d.ts.map +1 -1
  248. package/dist/lib/share/command.js +153 -11
  249. package/dist/lib/share/command.js.map +1 -1
  250. package/dist/lib/share/delivery-options.d.ts +15 -0
  251. package/dist/lib/share/delivery-options.d.ts.map +1 -0
  252. package/dist/lib/share/delivery-options.js +16 -0
  253. package/dist/lib/share/delivery-options.js.map +1 -0
  254. package/dist/lib/share/delivery.d.ts +83 -0
  255. package/dist/lib/share/delivery.d.ts.map +1 -0
  256. package/dist/lib/share/delivery.js +134 -0
  257. package/dist/lib/share/delivery.js.map +1 -0
  258. package/dist/lib/share/envelope.d.ts +61 -0
  259. package/dist/lib/share/envelope.d.ts.map +1 -0
  260. package/dist/lib/share/envelope.js +99 -0
  261. package/dist/lib/share/envelope.js.map +1 -0
  262. package/dist/lib/share/ledger.d.ts.map +1 -1
  263. package/dist/lib/share/ledger.js +3 -1
  264. package/dist/lib/share/ledger.js.map +1 -1
  265. package/dist/lib/share/payload.d.ts +9 -0
  266. package/dist/lib/share/payload.d.ts.map +1 -1
  267. package/dist/lib/share/payload.js +9 -0
  268. package/dist/lib/share/payload.js.map +1 -1
  269. package/dist/lib/share/pending.d.ts +47 -1
  270. package/dist/lib/share/pending.d.ts.map +1 -1
  271. package/dist/lib/share/pending.js +139 -13
  272. package/dist/lib/share/pending.js.map +1 -1
  273. package/dist/lib/share/preview.d.ts +5 -1
  274. package/dist/lib/share/preview.d.ts.map +1 -1
  275. package/dist/lib/share/preview.js +3 -1
  276. package/dist/lib/share/preview.js.map +1 -1
  277. package/dist/lib/share/qr.d.ts +13 -0
  278. package/dist/lib/share/qr.d.ts.map +1 -0
  279. package/dist/lib/share/qr.js +77 -0
  280. package/dist/lib/share/qr.js.map +1 -0
  281. package/dist/lib/share/requests-client.d.ts +63 -0
  282. package/dist/lib/share/requests-client.d.ts.map +1 -0
  283. package/dist/lib/share/requests-client.js +69 -0
  284. package/dist/lib/share/requests-client.js.map +1 -0
  285. package/dist/lib/share/run.d.ts +20 -1
  286. package/dist/lib/share/run.d.ts.map +1 -1
  287. package/dist/lib/share/run.js +27 -10
  288. package/dist/lib/share/run.js.map +1 -1
  289. package/dist/lib/share/secret-scan.d.ts +5 -0
  290. package/dist/lib/share/secret-scan.d.ts.map +1 -1
  291. package/dist/lib/share/secret-scan.js +43 -2
  292. package/dist/lib/share/secret-scan.js.map +1 -1
  293. package/dist/lib/share/target.d.ts +38 -0
  294. package/dist/lib/share/target.d.ts.map +1 -0
  295. package/dist/lib/share/target.js +80 -0
  296. package/dist/lib/share/target.js.map +1 -0
  297. package/dist/lib/share/tty.d.ts +8 -0
  298. package/dist/lib/share/tty.d.ts.map +1 -1
  299. package/dist/lib/share/tty.js +45 -0
  300. package/dist/lib/share/tty.js.map +1 -1
  301. package/dist/lib/source-sync-state.d.ts.map +1 -1
  302. package/dist/lib/source-sync-state.js +2 -0
  303. package/dist/lib/source-sync-state.js.map +1 -1
  304. package/dist/lib/sync/blocked.d.ts.map +1 -1
  305. package/dist/lib/sync/blocked.js +2 -1
  306. package/dist/lib/sync/blocked.js.map +1 -1
  307. package/dist/lib/sync/classify.d.ts.map +1 -1
  308. package/dist/lib/sync/classify.js +2 -0
  309. package/dist/lib/sync/classify.js.map +1 -1
  310. package/dist/lib/sync/real-env.d.ts +57 -0
  311. package/dist/lib/sync/real-env.d.ts.map +1 -1
  312. package/dist/lib/sync/sync-state.d.ts.map +1 -1
  313. package/dist/lib/sync/sync-state.js +3 -1
  314. package/dist/lib/sync/sync-state.js.map +1 -1
  315. package/dist/lib/usage-telemetry.d.ts +2 -2
  316. package/dist/lib/usage-telemetry.d.ts.map +1 -1
  317. package/dist/lib/usage-telemetry.js +21 -3
  318. package/dist/lib/usage-telemetry.js.map +1 -1
  319. package/package.json +4 -2
  320. package/dist/lib/personal-email-domains.d.ts +0 -8
  321. package/dist/lib/personal-email-domains.d.ts.map +0 -1
  322. package/dist/lib/personal-email-domains.js +0 -39
  323. package/dist/lib/personal-email-domains.js.map +0 -1
@@ -1,6 +1,19 @@
1
- import { type EnvName } from './config.js';
1
+ import { createConfigStore, type EnvName } from './config.js';
2
+ /**
3
+ * A name that is neither a builtin nor a saved team destination. Resolution used to fall back to
4
+ * the stored default for any such name, so `--env prodd` quietly ran against prod and
5
+ * `--env acme` against whatever the default was. A name the user typed on purpose now either
6
+ * means what they said or stops (join plan S6).
7
+ */
8
+ export declare class UnknownEnvError extends Error {
9
+ constructor(value: string, destinations: string[]);
10
+ }
11
+ type ConfigStore = ReturnType<typeof createConfigStore>;
12
+ /** A builtin or a saved team destination, or UnknownEnvError. The one place a typed name is accepted. */
13
+ export declare function acceptEnvName(name: string, config: Pick<ConfigStore, 'hasTeamDestination' | 'listTeamDestinationNames'>): EnvName;
2
14
  export declare function resolveEnv(flagValue?: string, opts?: {
3
15
  preferLocalEmbedded?: boolean;
16
+ config?: ConfigStore;
4
17
  }): EnvName;
5
18
  /**
6
19
  * Env resolution for `align connect <tool>` (ALI-675).
@@ -17,4 +30,5 @@ export declare function resolveEnv(flagValue?: string, opts?: {
17
30
  * an explicit --env always wins, and a logged-in user is never hijacked.
18
31
  */
19
32
  export declare function resolveImportEnv(flagValue?: string): EnvName;
33
+ export {};
20
34
  //# sourceMappingURL=resolve-env.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-env.d.ts","sourceRoot":"","sources":["../../src/lib/resolve-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAI9D,wBAAgB,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,OAAO,CAwBpG;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAE5D"}
1
+ {"version":3,"file":"resolve-env.d.ts","sourceRoot":"","sources":["../../src/lib/resolve-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,iBAAiB,EAAE,KAAK,OAAO,EAAE,MAAM,aAAa,CAAC;AAI/E;;;;;GAKG;AACH,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE;CAMlD;AAED,KAAK,WAAW,GAAG,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAExD,yGAAyG;AACzG,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,WAAW,EAAE,oBAAoB,GAAG,0BAA0B,CAAC,GAAG,OAAO,CAIjI;AAED,wBAAgB,UAAU,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GAAG,OAAO,CAoB1H;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAE5D"}
@@ -1,14 +1,34 @@
1
1
  import { createConfigStore } from './config.js';
2
2
  const VALID_ENVS = ['local', 'preview', 'prod'];
3
- export function resolveEnv(flagValue, opts = {}) {
4
- if (flagValue && VALID_ENVS.includes(flagValue)) {
5
- return flagValue;
3
+ /**
4
+ * A name that is neither a builtin nor a saved team destination. Resolution used to fall back to
5
+ * the stored default for any such name, so `--env prodd` quietly ran against prod and
6
+ * `--env acme` against whatever the default was. A name the user typed on purpose now either
7
+ * means what they said or stops (join plan S6).
8
+ */
9
+ export class UnknownEnvError extends Error {
10
+ constructor(value, destinations) {
11
+ const shown = value.replace(/[^\x20-\x7e]/g, '?').slice(0, 40);
12
+ const valid = [...VALID_ENVS, ...destinations].join(', ');
13
+ super(`Unknown environment "${shown}". Valid environments: ${valid}.`);
14
+ this.name = 'UnknownEnvError';
6
15
  }
16
+ }
17
+ /** A builtin or a saved team destination, or UnknownEnvError. The one place a typed name is accepted. */
18
+ export function acceptEnvName(name, config) {
19
+ if (VALID_ENVS.includes(name))
20
+ return name;
21
+ if (config.hasTeamDestination(name))
22
+ return name;
23
+ throw new UnknownEnvError(name, config.listTeamDestinationNames());
24
+ }
25
+ export function resolveEnv(flagValue, opts = {}) {
26
+ const config = opts.config ?? createConfigStore();
27
+ if (flagValue)
28
+ return acceptEnvName(flagValue, config);
7
29
  const fromEnvVar = process.env['ALIGN_ENV'];
8
- if (fromEnvVar && VALID_ENVS.includes(fromEnvVar)) {
9
- return fromEnvVar;
10
- }
11
- const config = createConfigStore();
30
+ if (fromEnvVar)
31
+ return acceptEnvName(fromEnvVar, config);
12
32
  const defaultEnv = config.getDefaultEnv();
13
33
  // A user who ran `align setup --local` has local-embedded configured but the
14
34
  // default env stays a cloud env (deliberate, so cloud-only commands are not
@@ -1 +1 @@
1
- {"version":3,"file":"resolve-env.js","sourceRoot":"","sources":["../../src/lib/resolve-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAgB,MAAM,aAAa,CAAC;AAE9D,MAAM,UAAU,GAAc,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAE3D,MAAM,UAAU,UAAU,CAAC,SAAkB,EAAE,OAA0C,EAAE;IACzF,IAAI,SAAS,IAAI,UAAU,CAAC,QAAQ,CAAC,SAAoB,CAAC,EAAE,CAAC;QAC3D,OAAO,SAAoB,CAAC;IAC9B,CAAC;IACD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC5C,IAAI,UAAU,IAAI,UAAU,CAAC,QAAQ,CAAC,UAAqB,CAAC,EAAE,CAAC;QAC7D,OAAO,UAAqB,CAAC;IAC/B,CAAC;IACD,MAAM,MAAM,GAAG,iBAAiB,EAAE,CAAC;IACnC,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;IAC1C,6EAA6E;IAC7E,4EAA4E;IAC5E,4EAA4E;IAC5E,6EAA6E;IAC7E,iFAAiF;IACjF,8DAA8D;IAC9D,IAAI,IAAI,CAAC,mBAAmB,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QACvD,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACjF,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAkB;IACjD,OAAO,UAAU,CAAC,SAAS,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"resolve-env.js","sourceRoot":"","sources":["../../src/lib/resolve-env.ts"],"names":[],"mappings":"AAAA,OAAO,EAAmB,iBAAiB,EAAgB,MAAM,aAAa,CAAC;AAE/E,MAAM,UAAU,GAAiB,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,KAAa,EAAE,YAAsB;QAC/C,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,eAAe,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC/D,MAAM,KAAK,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,KAAK,CAAC,wBAAwB,KAAK,0BAA0B,KAAK,GAAG,CAAC,CAAC;QACvE,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAID,yGAAyG;AACzG,MAAM,UAAU,aAAa,CAAC,IAAY,EAAE,MAA4E;IACtH,IAAK,UAAuB,CAAC,QAAQ,CAAC,IAAI,CAAC;QAAE,OAAO,IAAe,CAAC;IACpE,IAAI,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC;QAAE,OAAO,IAAe,CAAC;IAC5D,MAAM,IAAI,eAAe,CAAC,IAAI,EAAE,MAAM,CAAC,wBAAwB,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,SAAkB,EAAE,OAAgE,EAAE;IAC/G,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,iBAAiB,EAAE,CAAC;IAClD,IAAI,SAAS;QAAE,OAAO,aAAa,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;IACvD,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAC5C,IAAI,UAAU;QAAE,OAAO,aAAa,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;IAC1C,6EAA6E;IAC7E,4EAA4E;IAC5E,4EAA4E;IAC5E,6EAA6E;IAC7E,iFAAiF;IACjF,8DAA8D;IAC9D,IAAI,IAAI,CAAC,mBAAmB,IAAI,UAAU,KAAK,OAAO,EAAE,CAAC;QACvD,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACjF,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,gBAAgB,CAAC,SAAkB;IACjD,OAAO,UAAU,CAAC,SAAS,EAAE,EAAE,mBAAmB,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"scope-defaults.d.ts","sourceRoot":"","sources":["../../src/lib/scope-defaults.ts"],"names":[],"mappings":"AAYA,oHAAoH;AACpH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAyBzD"}
1
+ {"version":3,"file":"scope-defaults.d.ts","sourceRoot":"","sources":["../../src/lib/scope-defaults.ts"],"names":[],"mappings":"AAaA,oHAAoH;AACpH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CA0BzD"}
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import fs from 'node:fs';
7
7
  import { DatabaseSync } from 'node:sqlite';
8
+ import { tightenGraphFiles } from './private-files.js';
8
9
  const MAX_SUGGESTED = 10;
9
10
  const TICKET = /(?:^|\/)([A-Z][A-Z0-9_]+)-\d+$/;
10
11
  const codeUnit = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
@@ -14,6 +15,7 @@ export function citedProjectKeys(dbPath) {
14
15
  if (!fs.existsSync(dbPath))
15
16
  return [];
16
17
  let rows;
18
+ tightenGraphFiles(dbPath); // owner-only on every open (private-files.ts)
17
19
  const db = new DatabaseSync(dbPath, { readOnly: true });
18
20
  try {
19
21
  db.exec('PRAGMA busy_timeout = 30000');
@@ -1 +1 @@
1
- {"version":3,"file":"scope-defaults.js","sourceRoot":"","sources":["../../src/lib/scope-defaults.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,MAAM,aAAa,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,GAAG,gCAAgC,CAAC;AAChD,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhF,oHAAoH;AACpH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,4GAA4G;IAC5G,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,IAAI,IAAiD,CAAC;IACtD,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QACvC,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,kFAAkF,CAAC,CAAC,GAAG,EAAiB,CAAC;IAC7H,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC,CAAC,mCAAmC;IAChD,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QAChC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;QAClD,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;SAC1B,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,IAAI,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;SACnE,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC;SACvB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"scope-defaults.js","sourceRoot":"","sources":["../../src/lib/scope-defaults.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,aAAa,GAAG,EAAE,CAAC;AACzB,MAAM,MAAM,GAAG,gCAAgC,CAAC;AAChD,MAAM,QAAQ,GAAG,CAAC,CAAS,EAAE,CAAS,EAAU,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhF,oHAAoH;AACpH,MAAM,UAAU,gBAAgB,CAAC,MAAc;IAC7C,4GAA4G;IAC5G,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,EAAE,CAAC;IACtC,IAAI,IAAiD,CAAC;IACtD,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,8CAA8C;IACzE,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;IACxD,IAAI,CAAC;QACH,EAAE,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;QACvC,IAAI,GAAG,EAAE,CAAC,OAAO,CAAC,kFAAkF,CAAC,CAAC,GAAG,EAAiB,CAAC;IAC7H,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC,CAAC,mCAAmC;IAChD,CAAC;YAAS,CAAC;QACT,EAAE,CAAC,KAAK,EAAE,CAAC;IACb,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;QACrB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,GAAG,KAAK,SAAS;YAAE,SAAS;QAChC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,IAAI,GAAG,EAAU,CAAC;QAClD,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;SAC1B,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,IAAI,QAAQ,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;SACnE,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC;SACvB,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC"}
@@ -9,9 +9,22 @@ import { type ActiveScope } from './scope-values.js';
9
9
  export declare function gitlabPlaceOf(identity: string | null): string | undefined;
10
10
  export declare function configScopeStore(config?: {
11
11
  getEnvironment(env: import("./config.js").EnvName): import("./config.js").EnvironmentConfig;
12
+ saveTeamDestination(name: string, d: {
13
+ gatewayUrl: string;
14
+ appUrl: string;
15
+ authToken: string;
16
+ tenantId: string | null;
17
+ orgNameClaimed?: string;
18
+ }, now?: Date): void;
19
+ clearTeamToken(name: string): void;
20
+ getShareDestination(): string | null;
21
+ setShareDestination(name: string): void;
22
+ clearShareDestination(): void;
12
23
  setAuthToken(env: import("./config.js").EnvName, token: string): void;
13
24
  setTenantId(env: import("./config.js").EnvName, tenantId: string): void;
14
25
  setNgrokUrl(url: string): void;
26
+ hasTeamDestination(name: string): boolean;
27
+ listTeamDestinationNames(): string[];
15
28
  setDefaultEnv(env: import("./config.js").EnvName): void;
16
29
  getDefaultEnv(): import("./config.js").EnvName;
17
30
  getConnectorToken(env: import("./config.js").EnvName, connectorKey: string): string | null;
@@ -39,6 +52,8 @@ export declare function configScopeStore(config?: {
39
52
  setAgent(agent: string): void;
40
53
  isLaunchOff(): boolean;
41
54
  setLaunchOff(off: boolean): void;
55
+ getDetector(): string | undefined;
56
+ setDetector(detector: string): void;
42
57
  clearAgent(): void;
43
58
  isBackgroundSyncOff(): boolean;
44
59
  setBackgroundSyncOff(off: boolean): void;
@@ -62,6 +77,10 @@ export declare function configScopeStore(config?: {
62
77
  } | undefined;
63
78
  getTelemetryNoticeShownAt(): string | undefined;
64
79
  markTelemetryNoticeShown(): void;
80
+ getLeadState(): import("./config.js").LeadState;
81
+ markLeadPromptShown(version: string, now?: Date): void;
82
+ setLeadOutcome(outcome: import("./config.js").LeadPromptOutcome, now?: Date): void;
83
+ clearLeadPromptShown(): void;
65
84
  getProviderKey(provider: import("./config.js").GuidedProviderKey): string | null;
66
85
  setProviderKey(provider: import("./config.js").GuidedProviderKey, key: string): void;
67
86
  clearProviderKey(provider: import("./config.js").GuidedProviderKey): void;
@@ -78,9 +97,22 @@ export declare function configScopeStore(config?: {
78
97
  /** The stored choice IN FORCE for a source (a waiting agent choice is not), or null when nothing was chosen. For callers outside the scope code. */
79
98
  export declare function activeStoredScope(source: string, config?: {
80
99
  getEnvironment(env: import("./config.js").EnvName): import("./config.js").EnvironmentConfig;
100
+ saveTeamDestination(name: string, d: {
101
+ gatewayUrl: string;
102
+ appUrl: string;
103
+ authToken: string;
104
+ tenantId: string | null;
105
+ orgNameClaimed?: string;
106
+ }, now?: Date): void;
107
+ clearTeamToken(name: string): void;
108
+ getShareDestination(): string | null;
109
+ setShareDestination(name: string): void;
110
+ clearShareDestination(): void;
81
111
  setAuthToken(env: import("./config.js").EnvName, token: string): void;
82
112
  setTenantId(env: import("./config.js").EnvName, tenantId: string): void;
83
113
  setNgrokUrl(url: string): void;
114
+ hasTeamDestination(name: string): boolean;
115
+ listTeamDestinationNames(): string[];
84
116
  setDefaultEnv(env: import("./config.js").EnvName): void;
85
117
  getDefaultEnv(): import("./config.js").EnvName;
86
118
  getConnectorToken(env: import("./config.js").EnvName, connectorKey: string): string | null;
@@ -108,6 +140,8 @@ export declare function activeStoredScope(source: string, config?: {
108
140
  setAgent(agent: string): void;
109
141
  isLaunchOff(): boolean;
110
142
  setLaunchOff(off: boolean): void;
143
+ getDetector(): string | undefined;
144
+ setDetector(detector: string): void;
111
145
  clearAgent(): void;
112
146
  isBackgroundSyncOff(): boolean;
113
147
  setBackgroundSyncOff(off: boolean): void;
@@ -131,6 +165,10 @@ export declare function activeStoredScope(source: string, config?: {
131
165
  } | undefined;
132
166
  getTelemetryNoticeShownAt(): string | undefined;
133
167
  markTelemetryNoticeShown(): void;
168
+ getLeadState(): import("./config.js").LeadState;
169
+ markLeadPromptShown(version: string, now?: Date): void;
170
+ setLeadOutcome(outcome: import("./config.js").LeadPromptOutcome, now?: Date): void;
171
+ clearLeadPromptShown(): void;
134
172
  getProviderKey(provider: import("./config.js").GuidedProviderKey): string | null;
135
173
  setProviderKey(provider: import("./config.js").GuidedProviderKey, key: string): void;
136
174
  clearProviderKey(provider: import("./config.js").GuidedProviderKey): void;
@@ -147,9 +185,22 @@ export declare function activeStoredScope(source: string, config?: {
147
185
  /** What the sync status needs to know about the scope in force, from the stored choice. An unchosen source answers undefined (the most recently started row is used). */
148
186
  export declare function scopeStatusHooks(config?: {
149
187
  getEnvironment(env: import("./config.js").EnvName): import("./config.js").EnvironmentConfig;
188
+ saveTeamDestination(name: string, d: {
189
+ gatewayUrl: string;
190
+ appUrl: string;
191
+ authToken: string;
192
+ tenantId: string | null;
193
+ orgNameClaimed?: string;
194
+ }, now?: Date): void;
195
+ clearTeamToken(name: string): void;
196
+ getShareDestination(): string | null;
197
+ setShareDestination(name: string): void;
198
+ clearShareDestination(): void;
150
199
  setAuthToken(env: import("./config.js").EnvName, token: string): void;
151
200
  setTenantId(env: import("./config.js").EnvName, tenantId: string): void;
152
201
  setNgrokUrl(url: string): void;
202
+ hasTeamDestination(name: string): boolean;
203
+ listTeamDestinationNames(): string[];
153
204
  setDefaultEnv(env: import("./config.js").EnvName): void;
154
205
  getDefaultEnv(): import("./config.js").EnvName;
155
206
  getConnectorToken(env: import("./config.js").EnvName, connectorKey: string): string | null;
@@ -177,6 +228,8 @@ export declare function scopeStatusHooks(config?: {
177
228
  setAgent(agent: string): void;
178
229
  isLaunchOff(): boolean;
179
230
  setLaunchOff(off: boolean): void;
231
+ getDetector(): string | undefined;
232
+ setDetector(detector: string): void;
180
233
  clearAgent(): void;
181
234
  isBackgroundSyncOff(): boolean;
182
235
  setBackgroundSyncOff(off: boolean): void;
@@ -200,6 +253,10 @@ export declare function scopeStatusHooks(config?: {
200
253
  } | undefined;
201
254
  getTelemetryNoticeShownAt(): string | undefined;
202
255
  markTelemetryNoticeShown(): void;
256
+ getLeadState(): import("./config.js").LeadState;
257
+ markLeadPromptShown(version: string, now?: Date): void;
258
+ setLeadOutcome(outcome: import("./config.js").LeadPromptOutcome, now?: Date): void;
259
+ clearLeadPromptShown(): void;
203
260
  getProviderKey(provider: import("./config.js").GuidedProviderKey): string | null;
204
261
  setProviderKey(provider: import("./config.js").GuidedProviderKey, key: string): void;
205
262
  clearProviderKey(provider: import("./config.js").GuidedProviderKey): void;
@@ -1 +1 @@
1
- {"version":3,"file":"scope-real.d.ts","sourceRoot":"","sources":["../../src/lib/scope-real.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAA2B,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,KAAK,WAAW,EAAmD,MAAM,mBAAmB,CAAC;AAEtG,wHAAwH;AACxH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAEzE;AAED,wBAAgB,gBAAgB,CAAC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAsB,GAAG,UAAU,CAUzE;AAED,oJAAoJ;AACpJ,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAsB,GAAG,WAAW,GAAG,IAAI,CAGlG;AAED,yKAAyK;AACzK,wBAAgB,gBAAgB,CAAC,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAAsB,GAAG;IAAE,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAAC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAAC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,CAgB7M;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,GAAE;IAAE,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;CAAO,GAAG,SAAS,CAW9H"}
1
+ {"version":3,"file":"scope-real.d.ts","sourceRoot":"","sources":["../../src/lib/scope-real.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,EAA2B,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,EAAE,KAAK,WAAW,EAAmD,MAAM,mBAAmB,CAAC;AAEtG,wHAAwH;AACxH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAEzE;AAED,wBAAgB,gBAAgB,CAAC,MAAM;;;;;;;sBAiDytP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAjDpsP,GAAG,UAAU,CAUzE;AAED,oJAAoJ;AACpJ,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM;;;;;;;sBAoCwsP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CApCnrP,GAAG,WAAW,GAAG,IAAI,CAGlG;AAED,yKAAyK;AACzK,wBAAgB,gBAAgB,CAAC,MAAM;;;;;;;sBA8BytP,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA9BpsP,GAAG;IAAE,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAAC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAAC,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAA;CAAE,CAgB7M;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE,CAAC,GAAE;IAAE,MAAM,CAAC,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAA;CAAO,GAAG,SAAS,CAW9H"}
@@ -11,10 +11,10 @@ export type SetupRoute = {
11
11
  teamLoginUntouched?: 'prod' | 'preview';
12
12
  } | {
13
13
  kind: 'team';
14
- env: 'prod' | 'preview';
14
+ env: EnvName;
15
15
  };
16
16
  export declare class InvalidEnvError extends Error {
17
- constructor(value: string);
17
+ constructor(value: string, destinations?: string[]);
18
18
  }
19
19
  export declare function routeSetup(opts: {
20
20
  env?: string;
@@ -22,5 +22,7 @@ export declare function routeSetup(opts: {
22
22
  }, config: {
23
23
  getEnvironment(env: EnvName): EnvironmentConfig;
24
24
  getDefaultEnv(): EnvName;
25
+ hasTeamDestination(name: string): boolean;
26
+ listTeamDestinationNames(): string[];
25
27
  }, processEnv: Record<string, string | undefined>): SetupRoute;
26
28
  //# sourceMappingURL=setup-route.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"setup-route.d.ts","sourceRoot":"","sources":["../../src/lib/setup-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE9D;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,OAAO,EAAiC,CAAC;AAE3E,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAE9C,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,KAAK,EAAE,MAAM;CAI1B;AAID,wBAAgB,UAAU,CACxB,IAAI,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EACvC,MAAM,EAAE;IAAE,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,CAAC;IAAC,aAAa,IAAI,OAAO,CAAA;CAAE,EACrF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAC7C,UAAU,CAkBZ"}
1
+ {"version":3,"file":"setup-route.d.ts","sourceRoot":"","sources":["../../src/lib/setup-route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAE9D;;;;;GAKG;AACH,eAAO,MAAM,UAAU,EAAE,SAAS,OAAO,EAAiC,CAAC;AAE3E,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAAC;AAEnC,qBAAa,eAAgB,SAAQ,KAAK;gBAC5B,KAAK,EAAE,MAAM,EAAE,YAAY,GAAE,MAAM,EAAO;CAIvD;AAID,wBAAgB,UAAU,CACxB,IAAI,EAAE;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,EACvC,MAAM,EAAE;IACN,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,iBAAiB,CAAC;IAChD,aAAa,IAAI,OAAO,CAAC;IACzB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IAC1C,wBAAwB,IAAI,MAAM,EAAE,CAAC;CACtC,EACD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAC7C,UAAU,CAuBZ"}
@@ -6,15 +6,21 @@
6
6
  */
7
7
  export const VALID_ENVS = ['local', 'preview', 'prod'];
8
8
  export class InvalidEnvError extends Error {
9
- constructor(value) {
10
- super(`Unknown environment "${value}". Valid environments: ${VALID_ENVS.join(', ')}.`);
9
+ constructor(value, destinations = []) {
10
+ super(`Unknown environment "${value}". Valid environments: ${[...VALID_ENVS, ...destinations].join(', ')}.`);
11
11
  this.name = 'InvalidEnvError';
12
12
  }
13
13
  }
14
14
  const isTeamEnv = (v) => v === 'prod' || v === 'preview';
15
15
  export function routeSetup(opts, config, processEnv) {
16
- if (opts.env !== undefined && !VALID_ENVS.includes(opts.env))
17
- throw new InvalidEnvError(opts.env);
16
+ // A saved team destination (`align join`) is a team env too: setup runs against it. Anything else that is
17
+ // not a builtin is an error, from --env and from ALIGN_ENV alike, as in resolveEnv (join plan S6).
18
+ const known = (v) => VALID_ENVS.includes(v) || config.hasTeamDestination(v);
19
+ if (opts.env !== undefined && !known(opts.env))
20
+ throw new InvalidEnvError(opts.env, config.listTeamDestinationNames());
21
+ const ambient = processEnv['ALIGN_ENV'];
22
+ if (opts.env === undefined && !opts.local && ambient && !known(ambient))
23
+ throw new InvalidEnvError(ambient, config.listTeamDestinationNames());
18
24
  // The team env this machine is logged in to: the default env first, then prod, then preview.
19
25
  const defaultEnv = config.getDefaultEnv();
20
26
  const order = [defaultEnv, 'prod', 'preview'].filter(isTeamEnv);
@@ -22,12 +28,12 @@ export function routeSetup(opts, config, processEnv) {
22
28
  if (opts.local || opts.env === 'local') {
23
29
  return loggedInEnv ? { kind: 'local', teamLoginUntouched: loggedInEnv } : { kind: 'local' };
24
30
  }
25
- if (isTeamEnv(opts.env))
31
+ if (opts.env !== undefined)
26
32
  return { kind: 'team', env: opts.env };
27
33
  const fromEnvVar = processEnv['ALIGN_ENV'];
28
34
  if (fromEnvVar === 'local')
29
35
  return loggedInEnv ? { kind: 'local', teamLoginUntouched: loggedInEnv } : { kind: 'local' };
30
- if (isTeamEnv(fromEnvVar))
36
+ if (fromEnvVar && fromEnvVar !== 'local')
31
37
  return { kind: 'team', env: fromEnvVar };
32
38
  if (loggedInEnv)
33
39
  return { kind: 'team', env: loggedInEnv };
@@ -1 +1 @@
1
- {"version":3,"file":"setup-route.js","sourceRoot":"","sources":["../../src/lib/setup-route.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAuB,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAM3E,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,KAAa;QACvB,KAAK,CAAC,wBAAwB,KAAK,0BAA0B,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACvF,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,SAAS,GAAG,CAAC,CAAqB,EAA2B,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,SAAS,CAAC;AAEtG,MAAM,UAAU,UAAU,CACxB,IAAuC,EACvC,MAAqF,EACrF,UAA8C;IAE9C,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAc,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE7G,6FAA6F;IAC7F,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAChE,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAEnF,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;QACvC,OAAO,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC9F,CAAC;IACD,IAAI,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC;IAEhE,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,UAAU,KAAK,OAAO;QAAE,OAAO,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACxH,IAAI,SAAS,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,CAAC;IACpE,IAAI,WAAW;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;IAC3D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC"}
1
+ {"version":3,"file":"setup-route.js","sourceRoot":"","sources":["../../src/lib/setup-route.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,MAAM,CAAC,MAAM,UAAU,GAAuB,CAAC,OAAO,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAM3E,MAAM,OAAO,eAAgB,SAAQ,KAAK;IACxC,YAAY,KAAa,EAAE,eAAyB,EAAE;QACpD,KAAK,CAAC,wBAAwB,KAAK,0BAA0B,CAAC,GAAG,UAAU,EAAE,GAAG,YAAY,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7G,IAAI,CAAC,IAAI,GAAG,iBAAiB,CAAC;IAChC,CAAC;CACF;AAED,MAAM,SAAS,GAAG,CAAC,CAAqB,EAA2B,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,CAAC,KAAK,SAAS,CAAC;AAEtG,MAAM,UAAU,UAAU,CACxB,IAAuC,EACvC,MAKC,EACD,UAA8C;IAE9C,0GAA0G;IAC1G,mGAAmG;IACnG,MAAM,KAAK,GAAG,CAAC,CAAS,EAAW,EAAE,CAAE,UAAgC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;IACpH,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,wBAAwB,EAAE,CAAC,CAAC;IACvH,MAAM,OAAO,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IACxC,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,eAAe,CAAC,OAAO,EAAE,MAAM,CAAC,wBAAwB,EAAE,CAAC,CAAC;IAE/I,6FAA6F;IAC7F,MAAM,UAAU,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAChE,MAAM,WAAW,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAEnF,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;QACvC,OAAO,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC9F,CAAC;IACD,IAAI,IAAI,CAAC,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,CAAC,GAAc,EAAE,CAAC;IAE9E,MAAM,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAC3C,IAAI,UAAU,KAAK,OAAO;QAAE,OAAO,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACxH,IAAI,UAAU,IAAI,UAAU,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,UAAqB,EAAE,CAAC;IAC9F,IAAI,WAAW;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,EAAE,CAAC;IAC3D,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC"}
@@ -0,0 +1,71 @@
1
+ import type { RequestKind } from './envelope.js';
2
+ import type { ShareRequestsApi, StagedRequest } from './requests-client.js';
3
+ import { ShareError } from './run.js';
4
+ import type { BatchResponse } from './wire.js';
5
+ /** Sleep that ends early when `signal` aborts (Ctrl-C), so a cancel is not delayed by a poll interval. */
6
+ export declare function abortableSleep(ms: number, signal?: AbortSignal): Promise<void>;
7
+ export interface StageInput {
8
+ kind: RequestKind;
9
+ plaintext: Buffer;
10
+ tenantId: string;
11
+ userId: string;
12
+ itemCount: number;
13
+ judgementCount: number;
14
+ label: string;
15
+ agent?: string;
16
+ }
17
+ /** `id` is the gateway's row id (every route and the link use it); `envelopeId` is the CLI's own, bound in the AAD. */
18
+ export interface Staged extends StagedRequest {
19
+ envelopeId: string;
20
+ keyB64Url: string;
21
+ sha256: string;
22
+ /** The exact plaintext, base64: what `complete` sends and what the gateway re-hashes. */
23
+ bytesB64: string;
24
+ }
25
+ /** A machine label the person will read on the page as "a machine calling itself ...": printable, one line, at most 120 characters. */
26
+ export declare function cleanLabel(raw: string): string;
27
+ export declare function stageRequest(client: Pick<ShareRequestsApi, 'stageShareRequest'>, input: StageInput, makeId?: () => string, signal?: AbortSignal): Promise<Staged>;
28
+ /** The link the person opens. The key is in the fragment, never the path or query. */
29
+ export declare function approveUrl(appUrl: string, requestId: string, keyB64Url: string): string;
30
+ export type Decision = 'approved' | 'declined' | 'expired' | 'cancelled' | 'failed' | 'aborted';
31
+ export interface PollDeps {
32
+ client: Pick<ShareRequestsApi, 'getShareRequest'>;
33
+ now: () => number;
34
+ /** Resolves after `ms`, or as soon as `signal` aborts. */
35
+ sleep: (ms: number, signal?: AbortSignal) => Promise<void>;
36
+ signal?: AbortSignal;
37
+ /** The longest this run will wait however far off `expires_at` says: the config's pending_ttl_s + complete_ttl_s. */
38
+ maxWaitMs?: number;
39
+ }
40
+ export declare const POLL_START_MS = 2000;
41
+ export declare const POLL_MAX_MS = 5000;
42
+ export declare const POLL_GROWTH = 1.3;
43
+ /** Consecutive failed status reads before giving up. One blip is not a decision. */
44
+ export declare const POLL_MAX_FAILURES = 3;
45
+ /** Used when the gateway's config gives no lifetimes: pending (15 min) plus the window to complete after approval (10 min). */
46
+ export declare const DEFAULT_MAX_WAIT_MS: number;
47
+ /**
48
+ * Poll until the person decides. The expiry is the gateway's own `expires_at`; at that moment the answer is read
49
+ * ONE more time before calling it expired, because this machine's clock may run ahead of the gateway's and an
50
+ * approval can land in the last second. The deadline is clamped to `maxWaitMs` from now, so a far-future `expires_at`
51
+ * (a broken or hostile gateway) cannot keep this polling forever. `signal` reaches every status read, so Ctrl-C ends a
52
+ * read that is hanging, not only the sleep between reads.
53
+ */
54
+ export declare function pollUntilDecided(id: string, expiresAt: string, deps: PollDeps): Promise<Decision>;
55
+ /**
56
+ * A completion that failed. `retryable` is true when no verdict came back (5xx, a dropped connection) or the gateway says it
57
+ * is already completing: the same bytes may be sent again. `sent` says what may be claimed: 'no' (the gateway refused, nothing
58
+ * was written) or 'maybe' (it may have finished; only the team graph knows).
59
+ */
60
+ export declare class CompletionError extends ShareError {
61
+ readonly retryable: boolean;
62
+ readonly sent: 'no' | 'maybe';
63
+ constructor(message: string, retryable: boolean, sent?: 'no' | 'maybe');
64
+ }
65
+ /**
66
+ * Send the approved bytes. The gateway re-hashes them against what the person approved, so a payload that
67
+ * differs by one character is refused there. An error here is explained by status; a 5xx or a dropped
68
+ * connection is an UNKNOWN outcome, not a failure, because the gateway may have finished before the answer got lost.
69
+ */
70
+ export declare function completeRequest(client: Pick<ShareRequestsApi, 'completeShareRequest'>, id: string, bytesB64: string): Promise<BatchResponse>;
71
+ //# sourceMappingURL=approval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval.d.ts","sourceRoot":"","sources":["../../../src/lib/share/approval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * ALI-1540: the client side of an approval, as functions over an injected client, a clock and a sleep.
3
+ *
4
+ * stage - make the request id, seal, send the ciphertext, check the answer is about THIS request.
5
+ * poll - ask the gateway what the person did, backing off, stopping at the expiry, stopping on Ctrl-C.
6
+ * link - build the approve URL. The key goes in the fragment ONLY, which a browser never sends.
7
+ * complete - after (and only after) the gateway says approved, send the exact approved bytes.
8
+ *
9
+ * Nothing here can approve: the approve route refuses the CLI's token. A person does that in a browser.
10
+ */
11
+ import { randomUUID } from 'node:crypto';
12
+ import { seal } from './envelope.js';
13
+ import { visible } from './visible.js';
14
+ import { ShareError } from './run.js';
15
+ /** Sleep that ends early when `signal` aborts (Ctrl-C), so a cancel is not delayed by a poll interval. */
16
+ export function abortableSleep(ms, signal) {
17
+ return new Promise((resolve) => {
18
+ if (signal?.aborted) {
19
+ resolve();
20
+ return;
21
+ }
22
+ const done = () => { clearTimeout(timer); signal?.removeEventListener('abort', done); resolve(); };
23
+ const timer = setTimeout(done, ms);
24
+ signal?.addEventListener('abort', done, { once: true });
25
+ });
26
+ }
27
+ /** A machine label the person will read on the page as "a machine calling itself ...": printable, one line, at most 120 characters. */
28
+ export function cleanLabel(raw) {
29
+ return visible(raw).replace(/\s+/g, ' ').trim().slice(0, 120);
30
+ }
31
+ export async function stageRequest(client, input, makeId = randomUUID, signal) {
32
+ const envelopeId = makeId();
33
+ const sealed = seal(input.plaintext, { envelopeId, tenantId: input.tenantId, userId: input.userId, kind: input.kind });
34
+ const label = cleanLabel(input.label);
35
+ const res = await client.stageShareRequest({
36
+ envelope_id: envelopeId, kind: input.kind, envelope: sealed.envelopeB64, payload_sha256: sealed.sha256,
37
+ item_count: input.itemCount, judgement_count: input.judgementCount,
38
+ ...(label ? { requester_label: label } : {}), ...(input.agent ? { agent: input.agent } : {}),
39
+ }, signal);
40
+ return { ...res, envelopeId, keyB64Url: sealed.keyB64Url, sha256: sealed.sha256, bytesB64: input.plaintext.toString('base64') };
41
+ }
42
+ /** The link the person opens. The key is in the fragment, never the path or query. */
43
+ export function approveUrl(appUrl, requestId, keyB64Url) {
44
+ return `${appUrl.replace(/\/+$/, '')}/share/approve/${requestId}#k=${keyB64Url}`;
45
+ }
46
+ export const POLL_START_MS = 2000;
47
+ export const POLL_MAX_MS = 5000;
48
+ export const POLL_GROWTH = 1.3;
49
+ /** Consecutive failed status reads before giving up. One blip is not a decision. */
50
+ export const POLL_MAX_FAILURES = 3;
51
+ /** Used when the gateway's config gives no lifetimes: pending (15 min) plus the window to complete after approval (10 min). */
52
+ export const DEFAULT_MAX_WAIT_MS = (900 + 600) * 1000;
53
+ /**
54
+ * Poll until the person decides. The expiry is the gateway's own `expires_at`; at that moment the answer is read
55
+ * ONE more time before calling it expired, because this machine's clock may run ahead of the gateway's and an
56
+ * approval can land in the last second. The deadline is clamped to `maxWaitMs` from now, so a far-future `expires_at`
57
+ * (a broken or hostile gateway) cannot keep this polling forever. `signal` reaches every status read, so Ctrl-C ends a
58
+ * read that is hanging, not only the sleep between reads.
59
+ */
60
+ export async function pollUntilDecided(id, expiresAt, deps) {
61
+ const stated = Date.parse(expiresAt);
62
+ if (Number.isNaN(stated))
63
+ throw new ShareError('The gateway gave this request no usable expiry, so it was not waited on.');
64
+ const deadline = Math.min(stated, deps.now() + (deps.maxWaitMs ?? DEFAULT_MAX_WAIT_MS));
65
+ let delay = POLL_START_MS;
66
+ let failures = 0;
67
+ for (;;) {
68
+ if (deps.signal?.aborted)
69
+ return 'aborted';
70
+ const last = deps.now() >= deadline;
71
+ try {
72
+ const { state } = await deps.client.getShareRequest(id, deps.signal);
73
+ failures = 0;
74
+ switch (state) {
75
+ case 'approved': return 'approved';
76
+ case 'declined':
77
+ case 'expired':
78
+ case 'cancelled':
79
+ case 'failed': return state;
80
+ case 'pending': break;
81
+ // completing and completed mean something other than this process acted on the request: not ours to wait on.
82
+ default: throw new ShareError(`The request is already ${visible(state)} on the gateway, and this run did not cause that. This run stopped waiting on it.`);
83
+ }
84
+ }
85
+ catch (e) {
86
+ if (e instanceof ShareError)
87
+ throw e;
88
+ if (deps.signal?.aborted)
89
+ return 'aborted';
90
+ failures += 1;
91
+ if (failures >= POLL_MAX_FAILURES)
92
+ throw new ShareError(`Could not read the request's status ${POLL_MAX_FAILURES} times in a row (${visible(e.message)}). The request stays open on the gateway until it expires.`);
93
+ }
94
+ if (last)
95
+ return 'expired';
96
+ await deps.sleep(delay, deps.signal);
97
+ delay = Math.min(Math.round(delay * POLL_GROWTH), POLL_MAX_MS);
98
+ }
99
+ }
100
+ /**
101
+ * A completion that failed. `retryable` is true when no verdict came back (5xx, a dropped connection) or the gateway says it
102
+ * is already completing: the same bytes may be sent again. `sent` says what may be claimed: 'no' (the gateway refused, nothing
103
+ * was written) or 'maybe' (it may have finished; only the team graph knows).
104
+ */
105
+ export class CompletionError extends ShareError {
106
+ retryable;
107
+ sent;
108
+ constructor(message, retryable, sent = retryable ? 'maybe' : 'no') {
109
+ super(message);
110
+ this.retryable = retryable;
111
+ this.sent = sent;
112
+ this.name = 'CompletionError';
113
+ }
114
+ }
115
+ const MAYBE_SENT = 'It may have been sent, so check your team graph. This machine has no record of the result yet, so `align share --retract` will not find it until you share the same decision again. That is safe: it will not make a second copy.';
116
+ /**
117
+ * Send the approved bytes. The gateway re-hashes them against what the person approved, so a payload that
118
+ * differs by one character is refused there. An error here is explained by status; a 5xx or a dropped
119
+ * connection is an UNKNOWN outcome, not a failure, because the gateway may have finished before the answer got lost.
120
+ */
121
+ export async function completeRequest(client, id, bytesB64) {
122
+ try {
123
+ return await client.completeShareRequest(id, bytesB64);
124
+ }
125
+ catch (e) {
126
+ const status = e.statusCode ?? 0;
127
+ const msg = visible(e.message);
128
+ if (status === 409 && /already_(completing|completed)/.test(msg))
129
+ throw new CompletionError(`The gateway says this request is already being completed, or was (${msg}). ${MAYBE_SENT}`, true);
130
+ if (status === 410)
131
+ throw new CompletionError('The approval was too old to use (it lasts 10 minutes). Nothing was sent. Run the share again.', false);
132
+ if (status === 422)
133
+ throw new CompletionError(`The gateway refused what was approved: ${msg}. Nothing was sent.`, false);
134
+ if (status >= 400 && status < 500)
135
+ throw new CompletionError(`The gateway would not complete it: ${msg}. Nothing was sent.`, false);
136
+ throw new CompletionError(`The gateway did not say whether the share finished (${msg}). ${MAYBE_SENT}`, true);
137
+ }
138
+ }
139
+ //# sourceMappingURL=approval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approval.js","sourceRoot":"","sources":["../../../src/lib/share/approval.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The gate between an approval link and anything that acts on it: a browser launch, a QR code, a clipboard write.
3
+ *
4
+ * The link is built from three parts the CLI does not fully control: the app URL (from config or an env var),
5
+ * the request id (the gateway's answer) and the key (random, ours). Before any of it reaches a child process or the
6
+ * terminal as anything but text, the WHOLE string must match one exact shape:
7
+ *
8
+ * <scheme>://<host[:port]>/share/approve/<uuid>#k=<43 base64url characters>
9
+ *
10
+ * with the origin equal to the configured app's origin, https (http only for a localhost dev app), no userinfo, no
11
+ * query, no extra path, no whitespace or control characters, and a length cap. A string that passes contains none of
12
+ * the characters a shell, a PowerShell string or an argv parser treats specially. Callers must still pass it as an
13
+ * argument vector and never build a shell string from it; this is the second belt, not the first.
14
+ *
15
+ * WHAT THIS IS NOT. It is a SHAPE check, not a destination control. The link is built from the configured app URL and
16
+ * then compared with that same app URL, so the host check only catches a link that was altered after it was built. Where
17
+ * the link points is whatever the configuration (gateway URL, ALIGN_GATEWAY_URL) says. Only the host is
18
+ * case-insensitive; the scheme, the path and `#k=` must be exactly as written.
19
+ */
20
+ export type LinkCheck = {
21
+ ok: true;
22
+ url: string;
23
+ } | {
24
+ ok: false;
25
+ reason: string;
26
+ };
27
+ export declare const MAX_LINK_LENGTH = 220;
28
+ export declare function checkApproveLink(url: string, appUrl: string): LinkCheck;
29
+ /** The same gate as checkApproveLink, for the one settings link: exact shape, the configured app's origin, https or a localhost http app. */
30
+ export declare function checkSettingsLink(url: string, appUrl: string): LinkCheck;
31
+ //# sourceMappingURL=approve-link.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"approve-link.d.ts","sourceRoot":"","sources":["../../../src/lib/share/approve-link.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,MAAM,SAAS,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAElF,eAAO,MAAM,eAAe,MAAM,CAAC;AAUnC,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAWvE;AAKD,6IAA6I;AAC7I,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,SAAS,CAUxE"}