@hs-x/cli 0.1.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 (302) hide show
  1. package/README.md +1001 -0
  2. package/dist/account-store.d.ts +51 -0
  3. package/dist/account-store.d.ts.map +1 -0
  4. package/dist/account-store.js +138 -0
  5. package/dist/account-store.js.map +1 -0
  6. package/dist/bin/hs-x.d.ts +3 -0
  7. package/dist/bin/hs-x.d.ts.map +1 -0
  8. package/dist/bin/hs-x.js +47 -0
  9. package/dist/bin/hs-x.js.map +1 -0
  10. package/dist/cli/index.d.ts +3 -0
  11. package/dist/cli/index.d.ts.map +1 -0
  12. package/dist/cli/index.js +595 -0
  13. package/dist/cli/index.js.map +1 -0
  14. package/dist/cli-error.d.ts +36 -0
  15. package/dist/cli-error.d.ts.map +1 -0
  16. package/dist/cli-error.js +40 -0
  17. package/dist/cli-error.js.map +1 -0
  18. package/dist/cloudflare-auth.d.ts +25 -0
  19. package/dist/cloudflare-auth.d.ts.map +1 -0
  20. package/dist/cloudflare-auth.js +251 -0
  21. package/dist/cloudflare-auth.js.map +1 -0
  22. package/dist/cloudflare-kv.d.ts +23 -0
  23. package/dist/cloudflare-kv.d.ts.map +1 -0
  24. package/dist/cloudflare-kv.js +101 -0
  25. package/dist/cloudflare-kv.js.map +1 -0
  26. package/dist/cloudflare-oauth-store.d.ts +16 -0
  27. package/dist/cloudflare-oauth-store.d.ts.map +1 -0
  28. package/dist/cloudflare-oauth-store.js +80 -0
  29. package/dist/cloudflare-oauth-store.js.map +1 -0
  30. package/dist/cloudflare-oauth.d.ts +82 -0
  31. package/dist/cloudflare-oauth.d.ts.map +1 -0
  32. package/dist/cloudflare-oauth.js +336 -0
  33. package/dist/cloudflare-oauth.js.map +1 -0
  34. package/dist/cloudflare-pointer.d.ts +13 -0
  35. package/dist/cloudflare-pointer.d.ts.map +1 -0
  36. package/dist/cloudflare-pointer.js +46 -0
  37. package/dist/cloudflare-pointer.js.map +1 -0
  38. package/dist/command-history.d.ts +7 -0
  39. package/dist/command-history.d.ts.map +1 -0
  40. package/dist/command-history.js +34 -0
  41. package/dist/command-history.js.map +1 -0
  42. package/dist/commands/account.d.ts +7 -0
  43. package/dist/commands/account.d.ts.map +1 -0
  44. package/dist/commands/account.js +315 -0
  45. package/dist/commands/account.js.map +1 -0
  46. package/dist/commands/api.d.ts +36 -0
  47. package/dist/commands/api.d.ts.map +1 -0
  48. package/dist/commands/api.js +521 -0
  49. package/dist/commands/api.js.map +1 -0
  50. package/dist/commands/completion.d.ts +7 -0
  51. package/dist/commands/completion.d.ts.map +1 -0
  52. package/dist/commands/completion.js +121 -0
  53. package/dist/commands/completion.js.map +1 -0
  54. package/dist/commands/connect.d.ts +7 -0
  55. package/dist/commands/connect.d.ts.map +1 -0
  56. package/dist/commands/connect.js +1123 -0
  57. package/dist/commands/connect.js.map +1 -0
  58. package/dist/commands/control-plane-read.d.ts +22 -0
  59. package/dist/commands/control-plane-read.d.ts.map +1 -0
  60. package/dist/commands/control-plane-read.js +350 -0
  61. package/dist/commands/control-plane-read.js.map +1 -0
  62. package/dist/commands/deploy-promote.d.ts +14 -0
  63. package/dist/commands/deploy-promote.d.ts.map +1 -0
  64. package/dist/commands/deploy-promote.js +105 -0
  65. package/dist/commands/deploy-promote.js.map +1 -0
  66. package/dist/commands/deploy.d.ts +18 -0
  67. package/dist/commands/deploy.d.ts.map +1 -0
  68. package/dist/commands/deploy.js +2764 -0
  69. package/dist/commands/deploy.js.map +1 -0
  70. package/dist/commands/dev.d.ts +7 -0
  71. package/dist/commands/dev.d.ts.map +1 -0
  72. package/dist/commands/dev.js +913 -0
  73. package/dist/commands/dev.js.map +1 -0
  74. package/dist/commands/doctor.d.ts +8 -0
  75. package/dist/commands/doctor.d.ts.map +1 -0
  76. package/dist/commands/doctor.js +258 -0
  77. package/dist/commands/doctor.js.map +1 -0
  78. package/dist/commands/flags.d.ts +22 -0
  79. package/dist/commands/flags.d.ts.map +1 -0
  80. package/dist/commands/flags.js +185 -0
  81. package/dist/commands/flags.js.map +1 -0
  82. package/dist/commands/help-command.d.ts +13 -0
  83. package/dist/commands/help-command.d.ts.map +1 -0
  84. package/dist/commands/help-command.js +482 -0
  85. package/dist/commands/help-command.js.map +1 -0
  86. package/dist/commands/history.d.ts +6 -0
  87. package/dist/commands/history.d.ts.map +1 -0
  88. package/dist/commands/history.js +42 -0
  89. package/dist/commands/history.js.map +1 -0
  90. package/dist/commands/init.d.ts +8 -0
  91. package/dist/commands/init.d.ts.map +1 -0
  92. package/dist/commands/init.js +233 -0
  93. package/dist/commands/init.js.map +1 -0
  94. package/dist/commands/link.d.ts +26 -0
  95. package/dist/commands/link.d.ts.map +1 -0
  96. package/dist/commands/link.js +441 -0
  97. package/dist/commands/link.js.map +1 -0
  98. package/dist/commands/login.d.ts +8 -0
  99. package/dist/commands/login.d.ts.map +1 -0
  100. package/dist/commands/login.js +381 -0
  101. package/dist/commands/login.js.map +1 -0
  102. package/dist/commands/migrate.d.ts +8 -0
  103. package/dist/commands/migrate.d.ts.map +1 -0
  104. package/dist/commands/migrate.js +258 -0
  105. package/dist/commands/migrate.js.map +1 -0
  106. package/dist/commands/rollback.d.ts +21 -0
  107. package/dist/commands/rollback.d.ts.map +1 -0
  108. package/dist/commands/rollback.js +301 -0
  109. package/dist/commands/rollback.js.map +1 -0
  110. package/dist/commands/secrets.d.ts +7 -0
  111. package/dist/commands/secrets.d.ts.map +1 -0
  112. package/dist/commands/secrets.js +230 -0
  113. package/dist/commands/secrets.js.map +1 -0
  114. package/dist/commands/status.d.ts +7 -0
  115. package/dist/commands/status.d.ts.map +1 -0
  116. package/dist/commands/status.js +241 -0
  117. package/dist/commands/status.js.map +1 -0
  118. package/dist/commands/unlink.d.ts +21 -0
  119. package/dist/commands/unlink.d.ts.map +1 -0
  120. package/dist/commands/unlink.js +83 -0
  121. package/dist/commands/unlink.js.map +1 -0
  122. package/dist/commands/update.d.ts +11 -0
  123. package/dist/commands/update.d.ts.map +1 -0
  124. package/dist/commands/update.js +154 -0
  125. package/dist/commands/update.js.map +1 -0
  126. package/dist/commands/validate.d.ts +9 -0
  127. package/dist/commands/validate.d.ts.map +1 -0
  128. package/dist/commands/validate.js +39 -0
  129. package/dist/commands/validate.js.map +1 -0
  130. package/dist/config.d.ts +12 -0
  131. package/dist/config.d.ts.map +1 -0
  132. package/dist/config.js +64 -0
  133. package/dist/config.js.map +1 -0
  134. package/dist/constants.d.ts +4 -0
  135. package/dist/constants.d.ts.map +1 -0
  136. package/dist/constants.js +4 -0
  137. package/dist/constants.js.map +1 -0
  138. package/dist/control-plane-fetch.d.ts +34 -0
  139. package/dist/control-plane-fetch.d.ts.map +1 -0
  140. package/dist/control-plane-fetch.js +73 -0
  141. package/dist/control-plane-fetch.js.map +1 -0
  142. package/dist/control-plane-loader.d.ts +16 -0
  143. package/dist/control-plane-loader.d.ts.map +1 -0
  144. package/dist/control-plane-loader.js +24 -0
  145. package/dist/control-plane-loader.js.map +1 -0
  146. package/dist/dev/compat-shim.d.ts +40 -0
  147. package/dist/dev/compat-shim.d.ts.map +1 -0
  148. package/dist/dev/compat-shim.js +65 -0
  149. package/dist/dev/compat-shim.js.map +1 -0
  150. package/dist/dev/event-bus.d.ts +27 -0
  151. package/dist/dev/event-bus.d.ts.map +1 -0
  152. package/dist/dev/event-bus.js +32 -0
  153. package/dist/dev/event-bus.js.map +1 -0
  154. package/dist/dev/log-server.d.ts +52 -0
  155. package/dist/dev/log-server.d.ts.map +1 -0
  156. package/dist/dev/log-server.js +216 -0
  157. package/dist/dev/log-server.js.map +1 -0
  158. package/dist/dev/session-manager.d.ts +33 -0
  159. package/dist/dev/session-manager.d.ts.map +1 -0
  160. package/dist/dev/session-manager.js +132 -0
  161. package/dist/dev/session-manager.js.map +1 -0
  162. package/dist/dev/stream-renderer.d.ts +22 -0
  163. package/dist/dev/stream-renderer.d.ts.map +1 -0
  164. package/dist/dev/stream-renderer.js +65 -0
  165. package/dist/dev/stream-renderer.js.map +1 -0
  166. package/dist/dev/tunnel.d.ts +40 -0
  167. package/dist/dev/tunnel.d.ts.map +1 -0
  168. package/dist/dev/tunnel.js +139 -0
  169. package/dist/dev/tunnel.js.map +1 -0
  170. package/dist/effect-http.d.ts +10 -0
  171. package/dist/effect-http.d.ts.map +1 -0
  172. package/dist/effect-http.js +38 -0
  173. package/dist/effect-http.js.map +1 -0
  174. package/dist/errors-registry.d.ts +11 -0
  175. package/dist/errors-registry.d.ts.map +1 -0
  176. package/dist/errors-registry.js +554 -0
  177. package/dist/errors-registry.js.map +1 -0
  178. package/dist/errors.d.ts +58 -0
  179. package/dist/errors.d.ts.map +1 -0
  180. package/dist/errors.js +30 -0
  181. package/dist/errors.js.map +1 -0
  182. package/dist/help.d.ts +6 -0
  183. package/dist/help.d.ts.map +1 -0
  184. package/dist/help.js +100 -0
  185. package/dist/help.js.map +1 -0
  186. package/dist/history.d.ts +15 -0
  187. package/dist/history.d.ts.map +1 -0
  188. package/dist/history.js +69 -0
  189. package/dist/history.js.map +1 -0
  190. package/dist/hubspot-auth.d.ts +53 -0
  191. package/dist/hubspot-auth.d.ts.map +1 -0
  192. package/dist/hubspot-auth.js +301 -0
  193. package/dist/hubspot-auth.js.map +1 -0
  194. package/dist/hubspot-developer-client.d.ts +10 -0
  195. package/dist/hubspot-developer-client.d.ts.map +1 -0
  196. package/dist/hubspot-developer-client.js +212 -0
  197. package/dist/hubspot-developer-client.js.map +1 -0
  198. package/dist/index.d.ts +5 -0
  199. package/dist/index.d.ts.map +1 -0
  200. package/dist/index.js +4 -0
  201. package/dist/index.js.map +1 -0
  202. package/dist/init/templates.d.ts +18 -0
  203. package/dist/init/templates.d.ts.map +1 -0
  204. package/dist/init/templates.js +239 -0
  205. package/dist/init/templates.js.map +1 -0
  206. package/dist/load-env.d.ts +16 -0
  207. package/dist/load-env.d.ts.map +1 -0
  208. package/dist/load-env.js +69 -0
  209. package/dist/load-env.js.map +1 -0
  210. package/dist/machine-id.d.ts +3 -0
  211. package/dist/machine-id.d.ts.map +1 -0
  212. package/dist/machine-id.js +41 -0
  213. package/dist/machine-id.js.map +1 -0
  214. package/dist/paths.d.ts +4 -0
  215. package/dist/paths.d.ts.map +1 -0
  216. package/dist/paths.js +19 -0
  217. package/dist/paths.js.map +1 -0
  218. package/dist/prompt.d.ts +43 -0
  219. package/dist/prompt.d.ts.map +1 -0
  220. package/dist/prompt.js +379 -0
  221. package/dist/prompt.js.map +1 -0
  222. package/dist/reporter/human.d.ts +28 -0
  223. package/dist/reporter/human.d.ts.map +1 -0
  224. package/dist/reporter/human.js +126 -0
  225. package/dist/reporter/human.js.map +1 -0
  226. package/dist/reporter/index.d.ts +14 -0
  227. package/dist/reporter/index.d.ts.map +1 -0
  228. package/dist/reporter/index.js +37 -0
  229. package/dist/reporter/index.js.map +1 -0
  230. package/dist/reporter/json.d.ts +43 -0
  231. package/dist/reporter/json.d.ts.map +1 -0
  232. package/dist/reporter/json.js +146 -0
  233. package/dist/reporter/json.js.map +1 -0
  234. package/dist/reporter/style.d.ts +34 -0
  235. package/dist/reporter/style.d.ts.map +1 -0
  236. package/dist/reporter/style.js +97 -0
  237. package/dist/reporter/style.js.map +1 -0
  238. package/dist/reporter/types.d.ts +41 -0
  239. package/dist/reporter/types.d.ts.map +1 -0
  240. package/dist/reporter/types.js +2 -0
  241. package/dist/reporter/types.js.map +1 -0
  242. package/dist/result.d.ts +4 -0
  243. package/dist/result.d.ts.map +1 -0
  244. package/dist/result.js +2 -0
  245. package/dist/result.js.map +1 -0
  246. package/dist/services/account-store.d.ts +31 -0
  247. package/dist/services/account-store.d.ts.map +1 -0
  248. package/dist/services/account-store.js +135 -0
  249. package/dist/services/account-store.js.map +1 -0
  250. package/dist/services/app-paths.d.ts +25 -0
  251. package/dist/services/app-paths.d.ts.map +1 -0
  252. package/dist/services/app-paths.js +34 -0
  253. package/dist/services/app-paths.js.map +1 -0
  254. package/dist/services/cloudflare-auth.d.ts +83 -0
  255. package/dist/services/cloudflare-auth.d.ts.map +1 -0
  256. package/dist/services/cloudflare-auth.js +30 -0
  257. package/dist/services/cloudflare-auth.js.map +1 -0
  258. package/dist/services/cloudflare-kv.d.ts +45 -0
  259. package/dist/services/cloudflare-kv.d.ts.map +1 -0
  260. package/dist/services/cloudflare-kv.js +151 -0
  261. package/dist/services/cloudflare-kv.js.map +1 -0
  262. package/dist/services/command-history.d.ts +29 -0
  263. package/dist/services/command-history.d.ts.map +1 -0
  264. package/dist/services/command-history.js +62 -0
  265. package/dist/services/command-history.js.map +1 -0
  266. package/dist/services/control-plane.d.ts +32 -0
  267. package/dist/services/control-plane.d.ts.map +1 -0
  268. package/dist/services/control-plane.js +57 -0
  269. package/dist/services/control-plane.js.map +1 -0
  270. package/dist/services/env-loader.d.ts +18 -0
  271. package/dist/services/env-loader.d.ts.map +1 -0
  272. package/dist/services/env-loader.js +34 -0
  273. package/dist/services/env-loader.js.map +1 -0
  274. package/dist/services/http.d.ts +19 -0
  275. package/dist/services/http.d.ts.map +1 -0
  276. package/dist/services/http.js +9 -0
  277. package/dist/services/http.js.map +1 -0
  278. package/dist/services/live.d.ts +16 -0
  279. package/dist/services/live.d.ts.map +1 -0
  280. package/dist/services/live.js +26 -0
  281. package/dist/services/live.js.map +1 -0
  282. package/dist/services/machine-id.d.ts +18 -0
  283. package/dist/services/machine-id.d.ts.map +1 -0
  284. package/dist/services/machine-id.js +39 -0
  285. package/dist/services/machine-id.js.map +1 -0
  286. package/dist/services/reporter.d.ts +55 -0
  287. package/dist/services/reporter.d.ts.map +1 -0
  288. package/dist/services/reporter.js +49 -0
  289. package/dist/services/reporter.js.map +1 -0
  290. package/dist/state-store.d.ts +39 -0
  291. package/dist/state-store.d.ts.map +1 -0
  292. package/dist/state-store.js +89 -0
  293. package/dist/state-store.js.map +1 -0
  294. package/dist/telemetry.d.ts +13 -0
  295. package/dist/telemetry.d.ts.map +1 -0
  296. package/dist/telemetry.js +129 -0
  297. package/dist/telemetry.js.map +1 -0
  298. package/dist/tenant-state.d.ts +69 -0
  299. package/dist/tenant-state.d.ts.map +1 -0
  300. package/dist/tenant-state.js +161 -0
  301. package/dist/tenant-state.js.map +1 -0
  302. package/package.json +38 -0
@@ -0,0 +1,29 @@
1
+ import { FileSystem, Path } from '@effect/platform';
2
+ import { Context, Effect, Layer } from 'effect';
3
+ import type { HistoryEntry } from '../history.js';
4
+ import { AppPaths } from './app-paths.js';
5
+ /**
6
+ * Append-only command history (`$XDG_STATE_HOME/hs-x/history.jsonl`), powering
7
+ * `hs-x history`. Best-effort: writes never fail the command. Time is read from
8
+ * `Clock`, paths from `AppPaths` (override `HSX_HISTORY_PATH`).
9
+ */
10
+ export interface CommandHistoryApi {
11
+ readonly append: (entry: HistoryEntry) => Effect.Effect<void>;
12
+ readonly read: (options?: {
13
+ readonly limit?: number;
14
+ }) => Effect.Effect<HistoryEntry[]>;
15
+ /** Record a finished command run; resolves the account id from argv/env. */
16
+ readonly record: (input: {
17
+ readonly command: string;
18
+ readonly argv: readonly string[];
19
+ readonly exitCode: number;
20
+ readonly startedAtMs: number;
21
+ readonly accountId?: string;
22
+ }) => Effect.Effect<void>;
23
+ }
24
+ declare const CommandHistory_base: Context.TagClass<CommandHistory, "cli/CommandHistory", CommandHistoryApi>;
25
+ export declare class CommandHistory extends CommandHistory_base {
26
+ }
27
+ export declare const layer: Layer.Layer<CommandHistory, never, FileSystem.FileSystem | Path.Path | AppPaths>;
28
+ export {};
29
+ //# sourceMappingURL=command-history.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-history.d.ts","sourceRoot":"","sources":["../../src/services/command-history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAiB,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C;;;;GAIG;AACH,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC9D,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IACxF,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE;QACvB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;QACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;KAC7B,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CAC3B;;AAED,qBAAa,cAAe,SAAQ,mBAGjC;CAAG;AAyBN,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,KAAK,CAC7B,cAAc,EACd,KAAK,EACL,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,QAAQ,CAiD7C,CAAC"}
@@ -0,0 +1,62 @@
1
+ import { FileSystem, Path } from '@effect/platform';
2
+ import { Clock, Config, Context, Effect, Layer } from 'effect';
3
+ import { AppPaths } from './app-paths.js';
4
+ export class CommandHistory extends Context.Tag('cli/CommandHistory')() {
5
+ }
6
+ function parseEntry(line) {
7
+ try {
8
+ const parsed = JSON.parse(line);
9
+ if (typeof parsed.ts === 'string' &&
10
+ typeof parsed.command === 'string' &&
11
+ typeof parsed.exit_code === 'number' &&
12
+ typeof parsed.duration_ms === 'number') {
13
+ return {
14
+ ts: parsed.ts,
15
+ command: parsed.command,
16
+ exit_code: parsed.exit_code,
17
+ duration_ms: parsed.duration_ms,
18
+ ...(typeof parsed.account_id === 'string' ? { account_id: parsed.account_id } : {}),
19
+ };
20
+ }
21
+ }
22
+ catch {
23
+ // skip malformed lines
24
+ }
25
+ return undefined;
26
+ }
27
+ export const layer = Layer.effect(CommandHistory, Effect.gen(function* () {
28
+ const fs = yield* FileSystem.FileSystem;
29
+ const path = yield* Path.Path;
30
+ const paths = yield* AppPaths;
31
+ const override = yield* Config.string('HSX_HISTORY_PATH')
32
+ .pipe(Config.withDefault(''))
33
+ .pipe(Effect.orDie);
34
+ const target = override.length > 0 ? override : paths.statePath('history.jsonl');
35
+ const append = (entry) => fs
36
+ .makeDirectory(path.dirname(target), { recursive: true })
37
+ .pipe(Effect.zipRight(fs.writeFileString(target, `${JSON.stringify(entry)}\n`, { flag: 'a' })), Effect.ignore);
38
+ const read = (options = {}) => Effect.gen(function* () {
39
+ const limit = options.limit ?? 50;
40
+ const raw = yield* fs.readFileString(target).pipe(Effect.orElseSucceed(() => ''));
41
+ const lines = raw.split('\n').filter((l) => l.trim() !== '');
42
+ const out = [];
43
+ for (const line of lines.slice(-limit)) {
44
+ const entry = parseEntry(line);
45
+ if (entry)
46
+ out.push(entry);
47
+ }
48
+ return out;
49
+ });
50
+ const record = (input) => Effect.gen(function* () {
51
+ const nowMs = yield* Clock.currentTimeMillis;
52
+ yield* append({
53
+ ts: new Date(nowMs).toISOString(),
54
+ command: input.command,
55
+ exit_code: input.exitCode,
56
+ duration_ms: nowMs - input.startedAtMs,
57
+ ...(input.accountId ? { account_id: input.accountId } : {}),
58
+ });
59
+ });
60
+ return { append, read, record };
61
+ }));
62
+ //# sourceMappingURL=command-history.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-history.js","sourceRoot":"","sources":["../../src/services/command-history.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ import { Context, Effect, Layer } from 'effect';
2
+ import { type CliError } from '../cli-error.js';
3
+ import { AccountStore } from './account-store.js';
4
+ import { CliHttp } from './http.js';
5
+ export interface ControlPlaneRequest {
6
+ readonly controlPlaneUrl: string;
7
+ readonly path: string;
8
+ readonly method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
9
+ readonly body?: unknown;
10
+ readonly headers?: Record<string, string>;
11
+ }
12
+ /**
13
+ * Authenticated control-plane access. Attaches the locally-stored bearer
14
+ * session (`hs-x login`) as `Authorization: Bearer …`. Fails with a typed
15
+ * `CliError` (`HSX_E_NOT_LOGGED_IN` / `HSX_E_SESSION_EXPIRED`) when no usable
16
+ * session exists; otherwise returns the raw `Response` for status branching.
17
+ */
18
+ export interface ControlPlaneClientApi {
19
+ readonly fetch: (input: ControlPlaneRequest) => Effect.Effect<Response, CliError>;
20
+ /**
21
+ * Auth headers for a control-plane request: a live bearer session when
22
+ * present, else the `x-hsx-user-id` fallback (in-memory/local control planes),
23
+ * else empty (the call then fails loud with 401).
24
+ */
25
+ readonly authHeaders: (fallbackUserId?: string) => Effect.Effect<Record<string, string>>;
26
+ }
27
+ declare const ControlPlaneClient_base: Context.TagClass<ControlPlaneClient, "cli/ControlPlaneClient", ControlPlaneClientApi>;
28
+ export declare class ControlPlaneClient extends ControlPlaneClient_base {
29
+ }
30
+ export declare const layer: Layer.Layer<ControlPlaneClient, never, AccountStore | CliHttp>;
31
+ export {};
32
+ //# sourceMappingURL=control-plane.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-plane.d.ts","sourceRoot":"","sources":["../../src/services/control-plane.ts"],"names":[],"mappings":"AACA,OAAO,EAAS,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACvD,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,eAAe,EAAE,MAAM,CAAC;IACjC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,CAAC;IAC9D,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3C;AAED;;;;;GAKG;AACH,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAClF;;;;OAIG;IACH,QAAQ,CAAC,WAAW,EAAE,CAAC,cAAc,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC1F;;AAED,qBAAa,kBAAmB,SAAQ,uBAGrC;CAAG;AAEN,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,EAAE,YAAY,GAAG,OAAO,CA6DhF,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { HttpClientRequest } from '@hs-x/types';
2
+ import { Clock, Context, Effect, Layer } from 'effect';
3
+ import { cliError } from '../cli-error.js';
4
+ import { AccountStore } from './account-store.js';
5
+ import { CliHttp } from './http.js';
6
+ export class ControlPlaneClient extends Context.Tag('cli/ControlPlaneClient')() {
7
+ }
8
+ export const layer = Layer.effect(ControlPlaneClient, Effect.gen(function* () {
9
+ const store = yield* AccountStore;
10
+ const http = yield* CliHttp;
11
+ const liveSession = Effect.gen(function* () {
12
+ const loaded = yield* store.load;
13
+ const session = loaded.userSession;
14
+ if (!session)
15
+ return undefined;
16
+ const nowMs = yield* Clock.currentTimeMillis;
17
+ return sessionExpired(session, nowMs) ? undefined : session;
18
+ });
19
+ const fetch = (input) => Effect.gen(function* () {
20
+ const loaded = yield* store.load;
21
+ const session = loaded.userSession;
22
+ if (!session) {
23
+ return yield* Effect.fail(cliError('HSX_E_NOT_LOGGED_IN', 'No local HS-X session. Run `hs-x login` first.'));
24
+ }
25
+ const nowMs = yield* Clock.currentTimeMillis;
26
+ if (sessionExpired(session, nowMs)) {
27
+ return yield* Effect.fail(cliError('HSX_E_SESSION_EXPIRED', 'Stored HS-X session has expired. Run `hs-x login` again.'));
28
+ }
29
+ const url = new URL(input.path, input.controlPlaneUrl);
30
+ const method = input.method ?? 'GET';
31
+ const headers = {
32
+ accept: 'application/json',
33
+ authorization: `Bearer ${session.sessionToken}`,
34
+ ...(input.headers ?? {}),
35
+ };
36
+ let request = HttpClientRequest.make(method)(url).pipe(HttpClientRequest.setHeaders(headers));
37
+ if (input.body !== undefined) {
38
+ const contentType = headers['content-type'] ?? 'application/json';
39
+ const bodyText = typeof input.body === 'string' ? input.body : JSON.stringify(input.body);
40
+ request = request.pipe(HttpClientRequest.bodyText(bodyText, contentType));
41
+ }
42
+ return yield* http.execute(request);
43
+ });
44
+ const authHeaders = (fallbackUserId) => Effect.map(liveSession, (session) => session
45
+ ? { authorization: `Bearer ${session.sessionToken}` }
46
+ : fallbackUserId
47
+ ? { 'x-hsx-user-id': fallbackUserId }
48
+ : {});
49
+ return { fetch, authHeaders };
50
+ }));
51
+ function sessionExpired(session, nowMs) {
52
+ const expires = Date.parse(session.expiresAt);
53
+ if (!Number.isFinite(expires))
54
+ return false;
55
+ return expires <= nowMs;
56
+ }
57
+ //# sourceMappingURL=control-plane.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"control-plane.js","sourceRoot":"","sources":["../../src/services/control-plane.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { FileSystem, Path } from '@effect/platform';
2
+ import { Context, Effect, Layer } from 'effect';
3
+ /**
4
+ * Collects dotenv vars from the CWD up to the filesystem root, so a deploy from
5
+ * a nested app dir still sees a repo-root `.env.local`. Unlike the old
6
+ * `hydrateAncestorEnv`, this does NOT mutate `process.env` — it returns a map
7
+ * that the dispatch layers into the `ConfigProvider`. Nearer ancestors win;
8
+ * `.env.local` beats `.env` at the same level.
9
+ */
10
+ export interface EnvLoaderApi {
11
+ readonly ancestorDotenv: (start: string) => Effect.Effect<ReadonlyMap<string, string>>;
12
+ }
13
+ declare const EnvLoader_base: Context.TagClass<EnvLoader, "cli/EnvLoader", EnvLoaderApi>;
14
+ export declare class EnvLoader extends EnvLoader_base {
15
+ }
16
+ export declare const layer: Layer.Layer<EnvLoader, never, FileSystem.FileSystem | Path.Path>;
17
+ export {};
18
+ //# sourceMappingURL=env-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-loader.d.ts","sourceRoot":"","sources":["../../src/services/env-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAU,MAAM,QAAQ,CAAC;AAGxD;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACxF;;AAED,qBAAa,SAAU,SAAQ,cAAuD;CAAG;AAEzF,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CA8BlF,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { FileSystem, Path } from '@effect/platform';
2
+ import { Context, Effect, Layer, Option } from 'effect';
3
+ import { parseDotenv } from '../load-env.js';
4
+ export class EnvLoader extends Context.Tag('cli/EnvLoader')() {
5
+ }
6
+ export const layer = Layer.effect(EnvLoader, Effect.gen(function* () {
7
+ const fs = yield* FileSystem.FileSystem;
8
+ const path = yield* Path.Path;
9
+ const ancestorDotenv = (start) => Effect.gen(function* () {
10
+ const out = new Map();
11
+ let dir = path.resolve(start);
12
+ for (;;) {
13
+ // nearer dirs are visited first; only fill keys not already set (nearer wins)
14
+ for (const name of ['.env.local', '.env']) {
15
+ const content = yield* fs
16
+ .readFileString(path.join(dir, name))
17
+ .pipe(Effect.option);
18
+ if (Option.isNone(content))
19
+ continue;
20
+ for (const [key, value] of parseDotenv(content.value)) {
21
+ if (!out.has(key))
22
+ out.set(key, value);
23
+ }
24
+ }
25
+ const parent = path.dirname(dir);
26
+ if (parent === dir)
27
+ break;
28
+ dir = parent;
29
+ }
30
+ return out;
31
+ });
32
+ return { ancestorDotenv };
33
+ }));
34
+ //# sourceMappingURL=env-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-loader.js","sourceRoot":"","sources":["../../src/services/env-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAa7C,MAAM,OAAO,SAAU,SAAQ,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,EAA2B;CAAG;AAEzF,MAAM,CAAC,MAAM,KAAK,GAAqE,KAAK,CAAC,MAAM,CACjG,SAAS,EACT,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IACxC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAE9B,MAAM,cAAc,GAAmC,CAAC,KAAK,EAAE,EAAE,CAC/D,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;QAClB,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;QACtC,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9B,SAAS,CAAC;YACR,8EAA8E;YAC9E,KAAK,MAAM,IAAI,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC,EAAE,CAAC;gBAC1C,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,EAAE;qBACtB,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;qBACpC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACvB,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;oBAAE,SAAS;gBACrC,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,WAAW,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBACtD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;wBAAE,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;YACD,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACjC,IAAI,MAAM,KAAK,GAAG;gBAAE,MAAM;YAC1B,GAAG,GAAG,MAAM,CAAC;QACf,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;IAEL,OAAO,EAAE,cAAc,EAAyB,CAAC;AACnD,CAAC,CAAC,CACH,CAAC"}
@@ -0,0 +1,19 @@
1
+ import type { HttpClientRequest } from '@hs-x/types';
2
+ import { Context, Effect, Layer } from 'effect';
3
+ import { type CliError } from '../cli-error.js';
4
+ import { type ExecuteCliHttpOptions } from '../effect-http.js';
5
+ /**
6
+ * The CLI's HTTP primitive as an injectable service. Encapsulates the
7
+ * `@hs-x/types` HttpClient stack so command/handler code never touches raw
8
+ * `fetch`; transport failures surface as a typed `CliError` (network, exit 40).
9
+ * The concrete `Response` is returned so callers branch on status themselves.
10
+ */
11
+ export interface CliHttpApi {
12
+ readonly execute: (request: HttpClientRequest.HttpClientRequest, options?: ExecuteCliHttpOptions) => Effect.Effect<Response, CliError>;
13
+ }
14
+ declare const CliHttp_base: Context.TagClass<CliHttp, "cli/Http", CliHttpApi>;
15
+ export declare class CliHttp extends CliHttp_base {
16
+ }
17
+ export declare const layer: Layer.Layer<CliHttp>;
18
+ export {};
19
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/services/http.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAwB,KAAK,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAErF;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,OAAO,EAAE,CAChB,OAAO,EAAE,iBAAiB,CAAC,iBAAiB,EAC5C,OAAO,CAAC,EAAE,qBAAqB,KAC5B,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;CACxC;;AAED,qBAAa,OAAQ,SAAQ,YAA8C;CAAG;AAE9E,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,OAAO,CAOrC,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { Context, Effect, Layer } from 'effect';
2
+ import { cliError } from '../cli-error.js';
3
+ import { executeCliHttpEffect } from '../effect-http.js';
4
+ export class CliHttp extends Context.Tag('cli/Http')() {
5
+ }
6
+ export const layer = Layer.succeed(CliHttp, {
7
+ execute: (request, options) => executeCliHttpEffect(request, options).pipe(Effect.mapError((cause) => cliError('HSX_E_API_NETWORK', `Request failed: ${String(cause)}`))),
8
+ });
9
+ //# sourceMappingURL=http.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.js","sourceRoot":"","sources":["../../src/services/http.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,QAAQ,EAAiB,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,oBAAoB,EAA8B,MAAM,mBAAmB,CAAC;AAerF,MAAM,OAAO,OAAQ,SAAQ,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,EAAuB;CAAG;AAE9E,MAAM,CAAC,MAAM,KAAK,GAAyB,KAAK,CAAC,OAAO,CAAC,OAAO,EAAE;IAChE,OAAO,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAC5B,oBAAoB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,IAAI,CACzC,MAAM,CAAC,QAAQ,CAAC,CAAC,KAAK,EAAE,EAAE,CACxB,QAAQ,CAAC,mBAAmB,EAAE,mBAAmB,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAClE,CACF;CACJ,CAAC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { BunContext } from '@effect/platform-bun';
2
+ import { Layer } from 'effect';
3
+ import * as AccountStore from './account-store.js';
4
+ import * as AppPaths from './app-paths.js';
5
+ import * as CommandHistory from './command-history.js';
6
+ import * as ControlPlane from './control-plane.js';
7
+ import * as EnvLoader from './env-loader.js';
8
+ import * as CliHttp from './http.js';
9
+ import * as MachineId from './machine-id.js';
10
+ /**
11
+ * Platform layer: FileSystem, Path, Terminal, CommandExecutor, HttpClient.
12
+ * The single place the CLI binds to the Bun runtime.
13
+ */
14
+ export declare const PlatformLive: Layer.Layer<BunContext.BunContext, never, never>;
15
+ export declare const ServicesLive: Layer.Layer<BunContext.BunContext | AppPaths.AppPaths | AccountStore.AccountStore | CliHttp.CliHttp | CommandHistory.CommandHistory | ControlPlane.ControlPlaneClient | EnvLoader.EnvLoader | MachineId.MachineId, never, never>;
16
+ //# sourceMappingURL=live.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../src/services/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,YAAY,kDAAmB,CAAC;AAqB7C,eAAO,MAAM,YAAY,kOAAoD,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { BunContext } from '@effect/platform-bun';
2
+ import { Layer } from 'effect';
3
+ import * as AccountStore from './account-store.js';
4
+ import * as AppPaths from './app-paths.js';
5
+ import * as CommandHistory from './command-history.js';
6
+ import * as ControlPlane from './control-plane.js';
7
+ import * as EnvLoader from './env-loader.js';
8
+ import * as CliHttp from './http.js';
9
+ import * as MachineId from './machine-id.js';
10
+ /**
11
+ * Platform layer: FileSystem, Path, Terminal, CommandExecutor, HttpClient.
12
+ * The single place the CLI binds to the Bun runtime.
13
+ */
14
+ export const PlatformLive = BunContext.layer;
15
+ /**
16
+ * All CLI domain services, wired and provided the platform layer. Grows as
17
+ * each phase lands; consumers (`bin`, tests) provide just this.
18
+ *
19
+ * AppPaths is the shared dependency of the store/history/machine-id services,
20
+ * so it is provideMerge'd once and re-exposed to all of them.
21
+ */
22
+ const StoresLive = Layer.mergeAll(AccountStore.layer, CommandHistory.layer, MachineId.layer, EnvLoader.layer).pipe(Layer.provideMerge(AppPaths.layer));
23
+ /** Stores + the HTTP primitive + clients built on them (control plane). */
24
+ const DomainLive = ControlPlane.layer.pipe(Layer.provideMerge(Layer.merge(StoresLive, CliHttp.layer)));
25
+ export const ServicesLive = DomainLive.pipe(Layer.provideMerge(PlatformLive));
26
+ //# sourceMappingURL=live.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live.js","sourceRoot":"","sources":["../../src/services/live.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,cAAc,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,OAAO,MAAM,WAAW,CAAC;AACrC,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAE7C;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC,KAAK,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAC/B,YAAY,CAAC,KAAK,EAClB,cAAc,CAAC,KAAK,EACpB,SAAS,CAAC,KAAK,EACf,SAAS,CAAC,KAAK,CAChB,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AAE3C,2EAA2E;AAC3E,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CACxC,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAC3D,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,YAAY,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { FileSystem, Path } from '@effect/platform';
2
+ import { Context, Effect, Layer } from 'effect';
3
+ import { type CliError } from '../cli-error.js';
4
+ import { AppPaths } from './app-paths.js';
5
+ /**
6
+ * Stable per-machine identifier for telemetry correlation. Read order:
7
+ * `HSX_MACHINE_ID` env → `$XDG_STATE_HOME/hs-x/machine-id` → freshly minted +
8
+ * persisted. Randomness flows through Effect's `Random`, never `node:crypto`.
9
+ */
10
+ export interface MachineIdApi {
11
+ readonly get: Effect.Effect<string, CliError>;
12
+ }
13
+ declare const MachineId_base: Context.TagClass<MachineId, "cli/MachineId", MachineIdApi>;
14
+ export declare class MachineId extends MachineId_base {
15
+ }
16
+ export declare const layer: Layer.Layer<MachineId, never, FileSystem.FileSystem | Path.Path | AppPaths>;
17
+ export {};
18
+ //# sourceMappingURL=machine-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-id.d.ts","sourceRoot":"","sources":["../../src/services/machine-id.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAU,OAAO,EAAE,MAAM,EAAE,KAAK,EAAkB,MAAM,QAAQ,CAAC;AACxE,OAAO,EAAY,KAAK,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAK1C;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CAC/C;;AAED,qBAAa,SAAU,SAAQ,cAAuD;CAAG;AAmBzF,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,EAAE,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,GAAG,QAAQ,CA8B3F,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { FileSystem, Path } from '@effect/platform';
2
+ import { Config, Context, Effect, Layer, Option, Random } from 'effect';
3
+ import { cliError } from '../cli-error.js';
4
+ import { AppPaths } from './app-paths.js';
5
+ const MACHINE_ID_PATTERN = /^m_[a-z0-9]{16,64}$/;
6
+ const HEX = '0123456789abcdef';
7
+ export class MachineId extends Context.Tag('cli/MachineId')() {
8
+ }
9
+ function normalize(value) {
10
+ const normalized = value.trim().toLowerCase();
11
+ return MACHINE_ID_PATTERN.test(normalized)
12
+ ? Effect.succeed(normalized)
13
+ : Effect.fail(cliError('HSX_E_INPUT_INVALID', 'HSX_MACHINE_ID must match m_<16+ lowercase letters or digits>.'));
14
+ }
15
+ const randomMachineId = Effect.map(Effect.replicateEffect(Random.nextIntBetween(0, 16), 20), (nibbles) => `m_${nibbles.map((n) => HEX[n]).join('')}`);
16
+ export const layer = Layer.effect(MachineId, Effect.gen(function* () {
17
+ const fs = yield* FileSystem.FileSystem;
18
+ const path = yield* Path.Path;
19
+ const paths = yield* AppPaths;
20
+ const env = yield* Config.all({
21
+ machineId: Config.string('HSX_MACHINE_ID').pipe(Config.withDefault('')),
22
+ machineIdPath: Config.string('HSX_MACHINE_ID_PATH').pipe(Config.withDefault('')),
23
+ }).pipe(Effect.orDie);
24
+ const target = env.machineIdPath.length > 0 ? env.machineIdPath : paths.statePath('machine-id');
25
+ const get = Effect.gen(function* () {
26
+ if (env.machineId.length > 0)
27
+ return yield* normalize(env.machineId);
28
+ const existing = yield* fs.readFileString(target).pipe(Effect.option);
29
+ if (Option.isSome(existing))
30
+ return yield* normalize(existing.value.trim());
31
+ const machineId = yield* randomMachineId;
32
+ yield* fs.makeDirectory(path.dirname(target), { recursive: true, mode: 0o700 }).pipe(Effect.zipRight(fs.writeFileString(target, `${machineId}\n`)), Effect.zipRight(fs.chmod(target, 0o600).pipe(Effect.ignore)),
33
+ // minting an id must not fail the command — fall through to the value
34
+ Effect.ignore);
35
+ return machineId;
36
+ });
37
+ return { get };
38
+ }));
39
+ //# sourceMappingURL=machine-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"machine-id.js","sourceRoot":"","sources":["../../src/services/machine-id.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { Context, Effect, Layer } from 'effect';
2
+ import type { Reporter as ReporterImpl, ErrorContext, ReporterMode } from '../reporter/types.js';
3
+ /**
4
+ * Effect-facing step handle: the terminal sub-lines of a `step` each return an
5
+ * Effect so handlers stay in Effect-land (`yield* step.ok('done')`).
6
+ */
7
+ export interface StepHandle {
8
+ readonly ok: (detail?: string) => Effect.Effect<void>;
9
+ readonly fail: (detail?: string) => Effect.Effect<void>;
10
+ readonly warn: (detail?: string) => Effect.Effect<void>;
11
+ }
12
+ /**
13
+ * The Reporter service. Mirrors the synchronous `Reporter` interface in
14
+ * `reporter/types.ts`, but every method returns an Effect so command handlers
15
+ * never perform raw I/O. The rendering engine (human/json/ndjson) is unchanged;
16
+ * the service is a thin Effect facade over it.
17
+ */
18
+ export interface ReporterApi {
19
+ readonly mode: ReporterMode;
20
+ readonly command: string;
21
+ readonly banner: Effect.Effect<void>;
22
+ readonly header: (subject?: string) => Effect.Effect<void>;
23
+ readonly step: (label: string) => Effect.Effect<StepHandle>;
24
+ readonly info: (msg: string) => Effect.Effect<void>;
25
+ readonly block: (text: string) => Effect.Effect<void>;
26
+ readonly warn: (code: string, msg: string) => Effect.Effect<void>;
27
+ readonly error: (code: string, msg: string, ctx?: ErrorContext) => Effect.Effect<void>;
28
+ readonly event: (name: string, data?: Record<string, unknown>) => Effect.Effect<void>;
29
+ readonly data: (payload: unknown) => Effect.Effect<void>;
30
+ readonly done: (summary?: string, exitCode?: number) => Effect.Effect<void>;
31
+ }
32
+ declare const Reporter_base: Context.TagClass<Reporter, "cli/Reporter", ReporterApi>;
33
+ export declare class Reporter extends Reporter_base {
34
+ }
35
+ /** Wrap a synchronous reporter implementation in the Effect facade. */
36
+ export declare function fromImpl(impl: ReporterImpl): ReporterApi;
37
+ export interface ReporterLayerInput {
38
+ readonly command: string;
39
+ readonly argv: readonly string[];
40
+ readonly entry?: boolean;
41
+ }
42
+ /**
43
+ * Live layer: constructs the rendering engine from the parsed global flags
44
+ * (`--json`, `--verbose`, …). This is the single sanctioned edge where the
45
+ * process std streams + env are captured — analogous to `BunContext`. Command
46
+ * handlers receive only the Effect facade.
47
+ */
48
+ export declare function layer(input: ReporterLayerInput): Layer.Layer<Reporter>;
49
+ /**
50
+ * Test layer: routes all output into a provided in-memory implementation so
51
+ * specs can assert on emitted lines without spawning a subprocess.
52
+ */
53
+ export declare function layerFrom(impl: ReporterImpl): Layer.Layer<Reporter>;
54
+ export {};
55
+ //# sourceMappingURL=reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../../src/services/reporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEhD,OAAO,KAAK,EAAE,QAAQ,IAAI,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEjG;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtD,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACxD,QAAQ,CAAC,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CACzD;AAED;;;;;GAKG;AACH,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC3D,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;IAC5D,QAAQ,CAAC,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACpD,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtD,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAClE,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,YAAY,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACvF,QAAQ,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACtF,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACzD,QAAQ,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;CAC7E;;AAED,qBAAa,QAAS,SAAQ,aAAoD;CAAG;AAErF,uEAAuE;AACvE,wBAAgB,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,WAAW,CAuBxD;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,KAAK,EAAE,kBAAkB,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAUtE;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,CAEnE"}
@@ -0,0 +1,49 @@
1
+ import { Context, Effect, Layer } from 'effect';
2
+ import { createReporter } from '../reporter/index.js';
3
+ export class Reporter extends Context.Tag('cli/Reporter')() {
4
+ }
5
+ /** Wrap a synchronous reporter implementation in the Effect facade. */
6
+ export function fromImpl(impl) {
7
+ return {
8
+ mode: impl.mode,
9
+ command: impl.command,
10
+ banner: Effect.sync(() => impl.banner()),
11
+ header: (subject) => Effect.sync(() => impl.header(subject)),
12
+ step: (label) => Effect.sync(() => {
13
+ const handle = impl.step(label);
14
+ return {
15
+ ok: (detail) => Effect.sync(() => handle.ok(detail)),
16
+ fail: (detail) => Effect.sync(() => handle.fail(detail)),
17
+ warn: (detail) => Effect.sync(() => handle.warn(detail)),
18
+ };
19
+ }),
20
+ info: (msg) => Effect.sync(() => impl.info(msg)),
21
+ block: (text) => Effect.sync(() => impl.block(text)),
22
+ warn: (code, msg) => Effect.sync(() => impl.warn(code, msg)),
23
+ error: (code, msg, ctx) => Effect.sync(() => impl.error(code, msg, ctx)),
24
+ event: (name, data) => Effect.sync(() => impl.event(name, data)),
25
+ data: (payload) => Effect.sync(() => impl.data(payload)),
26
+ done: (summary, exitCode) => Effect.sync(() => impl.done(summary, exitCode)),
27
+ };
28
+ }
29
+ /**
30
+ * Live layer: constructs the rendering engine from the parsed global flags
31
+ * (`--json`, `--verbose`, …). This is the single sanctioned edge where the
32
+ * process std streams + env are captured — analogous to `BunContext`. Command
33
+ * handlers receive only the Effect facade.
34
+ */
35
+ export function layer(input) {
36
+ return Layer.sync(Reporter, () => fromImpl(createReporter({
37
+ command: input.command,
38
+ argv: input.argv,
39
+ ...(input.entry === undefined ? {} : { entry: input.entry }),
40
+ })));
41
+ }
42
+ /**
43
+ * Test layer: routes all output into a provided in-memory implementation so
44
+ * specs can assert on emitted lines without spawning a subprocess.
45
+ */
46
+ export function layerFrom(impl) {
47
+ return Layer.succeed(Reporter, fromImpl(impl));
48
+ }
49
+ //# sourceMappingURL=reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../src/services/reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,39 @@
1
+ import { Schema, schemas } from '@hs-x/types';
2
+ import type { CloudflareKvClient } from './cloudflare-kv.js';
3
+ type CloudflarePointer = Schema.Schema.Type<typeof schemas.CloudflarePointer>;
4
+ type LocalDeployEntry = Schema.Schema.Type<typeof schemas.LocalDeployEntry>;
5
+ type LocalActiveDeploy = Schema.Schema.Type<typeof schemas.LocalActiveDeploy>;
6
+ type LocalAppRuntimeBinding = Schema.Schema.Type<typeof schemas.LocalAppRuntimeBinding>;
7
+ type LocalOwnerMeta = Schema.Schema.Type<typeof schemas.LocalOwnerMeta>;
8
+ type HubSpotAppId = Schema.Schema.Type<typeof schemas.HubSpotAppId>;
9
+ export interface StateStore {
10
+ getOwnerMeta(): Promise<LocalOwnerMeta | undefined>;
11
+ putOwnerMeta(meta: LocalOwnerMeta): Promise<void>;
12
+ recordDeploy(entry: LocalDeployEntry): Promise<void>;
13
+ getDeploy(input: {
14
+ readonly projectId: string;
15
+ readonly deployId: string;
16
+ }): Promise<LocalDeployEntry | undefined>;
17
+ listDeploys(input: {
18
+ readonly projectId: string;
19
+ }): Promise<readonly LocalDeployEntry[]>;
20
+ getActive(input: {
21
+ readonly projectId: string;
22
+ readonly environment: string;
23
+ }): Promise<LocalActiveDeploy | undefined>;
24
+ setActive(active: LocalActiveDeploy): Promise<void>;
25
+ getBinding(input: {
26
+ readonly projectId: string;
27
+ readonly environment: string;
28
+ readonly hubSpotAppId: HubSpotAppId;
29
+ }): Promise<LocalAppRuntimeBinding | undefined>;
30
+ putBinding(binding: LocalAppRuntimeBinding): Promise<void>;
31
+ listOwners(): Promise<readonly string[]>;
32
+ listProjects(): Promise<readonly string[]>;
33
+ }
34
+ export declare function createStateStore(deps: {
35
+ readonly pointer: CloudflarePointer;
36
+ readonly kv: CloudflareKvClient;
37
+ }): StateStore;
38
+ export {};
39
+ //# sourceMappingURL=state-store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-store.d.ts","sourceRoot":"","sources":["../src/state-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D,KAAK,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAC9E,KAAK,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,gBAAgB,CAAC,CAAC;AAC5E,KAAK,iBAAiB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,iBAAiB,CAAC,CAAC;AAC9E,KAAK,sBAAsB,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,sBAAsB,CAAC,CAAC;AACxF,KAAK,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,cAAc,CAAC,CAAC;AACxE,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,OAAO,CAAC,YAAY,CAAC,CAAC;AAEpE,MAAM,WAAW,UAAU;IACzB,YAAY,IAAI,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAAC;IACpD,YAAY,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClD,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrD,SAAS,CAAC,KAAK,EAAE;QACf,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;KAC3B,GAAG,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;IAC1C,WAAW,CAAC,KAAK,EAAE;QAAE,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CAAC;IACzF,SAAS,CAAC,KAAK,EAAE;QACf,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;KAC9B,GAAG,OAAO,CAAC,iBAAiB,GAAG,SAAS,CAAC,CAAC;IAC3C,SAAS,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACpD,UAAU,CAAC,KAAK,EAAE;QAChB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;QAC3B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;QAC7B,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;KACrC,GAAG,OAAO,CAAC,sBAAsB,GAAG,SAAS,CAAC,CAAC;IAChD,UAAU,CAAC,OAAO,EAAE,sBAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,UAAU,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IACzC,YAAY,IAAI,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;CAC5C;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,QAAQ,CAAC,OAAO,EAAE,iBAAiB,CAAC;IACpC,QAAQ,CAAC,EAAE,EAAE,kBAAkB,CAAC;CACjC,GAAG,UAAU,CAgFb"}