@pushto/cli 0.2.1 → 0.4.6

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 (184) hide show
  1. package/dist/commands/__tests__/deploy-domain.test.d.ts +2 -0
  2. package/dist/commands/__tests__/deploy-domain.test.d.ts.map +1 -0
  3. package/dist/commands/__tests__/deploy-domain.test.js +41 -0
  4. package/dist/commands/__tests__/deploy-domain.test.js.map +1 -0
  5. package/dist/commands/__tests__/headless-smoke.test.d.ts +2 -0
  6. package/dist/commands/__tests__/headless-smoke.test.d.ts.map +1 -0
  7. package/dist/commands/__tests__/headless-smoke.test.js +110 -0
  8. package/dist/commands/__tests__/headless-smoke.test.js.map +1 -0
  9. package/dist/commands/auth.d.ts +2 -0
  10. package/dist/commands/auth.d.ts.map +1 -0
  11. package/dist/commands/auth.js +77 -0
  12. package/dist/commands/auth.js.map +1 -0
  13. package/dist/commands/cron.d.ts +2 -0
  14. package/dist/commands/cron.d.ts.map +1 -0
  15. package/dist/commands/cron.js +157 -0
  16. package/dist/commands/cron.js.map +1 -0
  17. package/dist/commands/db.d.ts +4 -0
  18. package/dist/commands/db.d.ts.map +1 -0
  19. package/dist/commands/db.js +63 -0
  20. package/dist/commands/db.js.map +1 -0
  21. package/dist/commands/deploy.d.ts +16 -1
  22. package/dist/commands/deploy.d.ts.map +1 -1
  23. package/dist/commands/deploy.js +230 -150
  24. package/dist/commands/deploy.js.map +1 -1
  25. package/dist/commands/doctor.d.ts.map +1 -1
  26. package/dist/commands/doctor.js +289 -54
  27. package/dist/commands/doctor.js.map +1 -1
  28. package/dist/commands/domain.d.ts.map +1 -1
  29. package/dist/commands/domain.js +52 -7
  30. package/dist/commands/domain.js.map +1 -1
  31. package/dist/commands/echo.d.ts +2 -0
  32. package/dist/commands/echo.d.ts.map +1 -0
  33. package/dist/commands/echo.js +227 -0
  34. package/dist/commands/echo.js.map +1 -0
  35. package/dist/commands/env.d.ts +3 -1
  36. package/dist/commands/env.d.ts.map +1 -1
  37. package/dist/commands/env.js +76 -50
  38. package/dist/commands/env.js.map +1 -1
  39. package/dist/commands/init.d.ts +3 -1
  40. package/dist/commands/init.d.ts.map +1 -1
  41. package/dist/commands/init.js +58 -11
  42. package/dist/commands/init.js.map +1 -1
  43. package/dist/commands/login.d.ts.map +1 -1
  44. package/dist/commands/login.js +50 -23
  45. package/dist/commands/login.js.map +1 -1
  46. package/dist/commands/logs.d.ts +3 -1
  47. package/dist/commands/logs.d.ts.map +1 -1
  48. package/dist/commands/logs.js +77 -21
  49. package/dist/commands/logs.js.map +1 -1
  50. package/dist/commands/mail.d.ts +2 -0
  51. package/dist/commands/mail.d.ts.map +1 -0
  52. package/dist/commands/mail.js +105 -0
  53. package/dist/commands/mail.js.map +1 -0
  54. package/dist/commands/open.d.ts.map +1 -1
  55. package/dist/commands/open.js +21 -1
  56. package/dist/commands/open.js.map +1 -1
  57. package/dist/commands/preview.d.ts +22 -0
  58. package/dist/commands/preview.d.ts.map +1 -0
  59. package/dist/commands/preview.js +223 -0
  60. package/dist/commands/preview.js.map +1 -0
  61. package/dist/commands/status.d.ts +3 -1
  62. package/dist/commands/status.d.ts.map +1 -1
  63. package/dist/commands/status.js +62 -12
  64. package/dist/commands/status.js.map +1 -1
  65. package/dist/commands/upgrade.d.ts.map +1 -1
  66. package/dist/commands/upgrade.js +73 -10
  67. package/dist/commands/upgrade.js.map +1 -1
  68. package/dist/commands/use.d.ts +2 -0
  69. package/dist/commands/use.d.ts.map +1 -0
  70. package/dist/commands/use.js +108 -0
  71. package/dist/commands/use.js.map +1 -0
  72. package/dist/commands/vault.d.ts +2 -0
  73. package/dist/commands/vault.d.ts.map +1 -0
  74. package/dist/commands/vault.js +119 -0
  75. package/dist/commands/vault.js.map +1 -0
  76. package/dist/commands/whoami.d.ts.map +1 -1
  77. package/dist/commands/whoami.js +12 -1
  78. package/dist/commands/whoami.js.map +1 -1
  79. package/dist/index.js +117 -14
  80. package/dist/index.js.map +1 -1
  81. package/dist/lib/__tests__/build-runner.test.d.ts +2 -0
  82. package/dist/lib/__tests__/build-runner.test.d.ts.map +1 -0
  83. package/dist/lib/__tests__/build-runner.test.js +119 -0
  84. package/dist/lib/__tests__/build-runner.test.js.map +1 -0
  85. package/dist/lib/__tests__/cron-tail.test.d.ts +2 -0
  86. package/dist/lib/__tests__/cron-tail.test.d.ts.map +1 -0
  87. package/dist/lib/__tests__/cron-tail.test.js +27 -0
  88. package/dist/lib/__tests__/cron-tail.test.js.map +1 -0
  89. package/dist/lib/__tests__/detect-static-framework.test.d.ts +2 -0
  90. package/dist/lib/__tests__/detect-static-framework.test.d.ts.map +1 -0
  91. package/dist/lib/__tests__/detect-static-framework.test.js +146 -0
  92. package/dist/lib/__tests__/detect-static-framework.test.js.map +1 -0
  93. package/dist/lib/__tests__/errors.test.d.ts +2 -0
  94. package/dist/lib/__tests__/errors.test.d.ts.map +1 -0
  95. package/dist/lib/__tests__/errors.test.js +56 -0
  96. package/dist/lib/__tests__/errors.test.js.map +1 -0
  97. package/dist/lib/__tests__/interactive.test.d.ts +2 -0
  98. package/dist/lib/__tests__/interactive.test.d.ts.map +1 -0
  99. package/dist/lib/__tests__/interactive.test.js +79 -0
  100. package/dist/lib/__tests__/interactive.test.js.map +1 -0
  101. package/dist/lib/__tests__/output.test.d.ts +2 -0
  102. package/dist/lib/__tests__/output.test.d.ts.map +1 -0
  103. package/dist/lib/__tests__/output.test.js +144 -0
  104. package/dist/lib/__tests__/output.test.js.map +1 -0
  105. package/dist/lib/__tests__/prepare-artifact.test.d.ts +2 -0
  106. package/dist/lib/__tests__/prepare-artifact.test.d.ts.map +1 -0
  107. package/dist/lib/__tests__/prepare-artifact.test.js +55 -0
  108. package/dist/lib/__tests__/prepare-artifact.test.js.map +1 -0
  109. package/dist/lib/__tests__/preview-args.test.d.ts +2 -0
  110. package/dist/lib/__tests__/preview-args.test.d.ts.map +1 -0
  111. package/dist/lib/__tests__/preview-args.test.js +37 -0
  112. package/dist/lib/__tests__/preview-args.test.js.map +1 -0
  113. package/dist/lib/api.d.ts.map +1 -1
  114. package/dist/lib/api.js +22 -4
  115. package/dist/lib/api.js.map +1 -1
  116. package/dist/lib/ask.d.ts +15 -0
  117. package/dist/lib/ask.d.ts.map +1 -0
  118. package/dist/lib/ask.js +24 -0
  119. package/dist/lib/ask.js.map +1 -0
  120. package/dist/lib/build-runner.d.ts +25 -0
  121. package/dist/lib/build-runner.d.ts.map +1 -0
  122. package/dist/lib/build-runner.js +141 -0
  123. package/dist/lib/build-runner.js.map +1 -0
  124. package/dist/lib/config.d.ts +6 -0
  125. package/dist/lib/config.d.ts.map +1 -1
  126. package/dist/lib/config.js +7 -1
  127. package/dist/lib/config.js.map +1 -1
  128. package/dist/lib/cron-tail.d.ts +10 -0
  129. package/dist/lib/cron-tail.d.ts.map +1 -0
  130. package/dist/lib/cron-tail.js +5 -0
  131. package/dist/lib/cron-tail.js.map +1 -0
  132. package/dist/lib/detect-static-framework.d.ts +31 -0
  133. package/dist/lib/detect-static-framework.d.ts.map +1 -0
  134. package/dist/lib/detect-static-framework.js +96 -0
  135. package/dist/lib/detect-static-framework.js.map +1 -0
  136. package/dist/lib/env-parse.d.ts +48 -0
  137. package/dist/lib/env-parse.d.ts.map +1 -0
  138. package/dist/lib/env-parse.js +91 -0
  139. package/dist/lib/env-parse.js.map +1 -0
  140. package/dist/lib/errors.d.ts +111 -0
  141. package/dist/lib/errors.d.ts.map +1 -0
  142. package/dist/lib/errors.js +64 -0
  143. package/dist/lib/errors.js.map +1 -0
  144. package/dist/lib/file-walker.d.ts +23 -0
  145. package/dist/lib/file-walker.d.ts.map +1 -0
  146. package/dist/lib/file-walker.js +114 -0
  147. package/dist/lib/file-walker.js.map +1 -0
  148. package/dist/lib/interactive.d.ts +13 -0
  149. package/dist/lib/interactive.d.ts.map +1 -0
  150. package/dist/lib/interactive.js +24 -0
  151. package/dist/lib/interactive.js.map +1 -0
  152. package/dist/lib/output.d.ts +24 -0
  153. package/dist/lib/output.d.ts.map +1 -0
  154. package/dist/lib/output.js +71 -0
  155. package/dist/lib/output.js.map +1 -0
  156. package/dist/lib/prepare-artifact.d.ts +22 -0
  157. package/dist/lib/prepare-artifact.d.ts.map +1 -0
  158. package/dist/lib/prepare-artifact.js +26 -0
  159. package/dist/lib/prepare-artifact.js.map +1 -0
  160. package/dist/lib/preview-args.d.ts +20 -0
  161. package/dist/lib/preview-args.d.ts.map +1 -0
  162. package/dist/lib/preview-args.js +19 -0
  163. package/dist/lib/preview-args.js.map +1 -0
  164. package/dist/lib/safe-json.d.ts +7 -2
  165. package/dist/lib/safe-json.d.ts.map +1 -1
  166. package/dist/lib/safe-json.js +23 -4
  167. package/dist/lib/safe-json.js.map +1 -1
  168. package/dist/lib/update-check.d.ts +17 -0
  169. package/dist/lib/update-check.d.ts.map +1 -0
  170. package/dist/lib/update-check.js +81 -0
  171. package/dist/lib/update-check.js.map +1 -0
  172. package/dist/lib/upload-limits.d.ts +17 -0
  173. package/dist/lib/upload-limits.d.ts.map +1 -0
  174. package/dist/lib/upload-limits.js +17 -0
  175. package/dist/lib/upload-limits.js.map +1 -0
  176. package/dist/lib/zip-project.d.ts +19 -0
  177. package/dist/lib/zip-project.d.ts.map +1 -0
  178. package/dist/lib/zip-project.js +39 -0
  179. package/dist/lib/zip-project.js.map +1 -0
  180. package/dist/version.d.ts +2 -0
  181. package/dist/version.d.ts.map +1 -0
  182. package/dist/version.js +16 -0
  183. package/dist/version.js.map +1 -0
  184. package/package.json +5 -8
package/dist/lib/api.js CHANGED
@@ -1,8 +1,13 @@
1
1
  import { config, getToken, getRefreshToken, setToken, clearToken, isTokenExpired } from './config.js';
2
2
  /** Default timeout for API requests (30 seconds) */
3
3
  const DEFAULT_TIMEOUT_MS = 30_000;
4
- /** Extended timeout for upload/deploy operations (5 minutes) */
5
- const DEPLOY_TIMEOUT_MS = 300_000;
4
+ /** Extended timeout for upload/deploy operations (10 minutes).
5
+ * Matches the web route's MAX_WAIT poll budget so the CLI doesn't abort
6
+ * with `network error` while the server is still legitimately polling
7
+ * the deploy-agent for a slow first build (Rust workspace, large
8
+ * Next.js app). When the server times out, it returns 504 with
9
+ * `stillBuilding: true` and the CLI shows a "still building" message. */
10
+ const DEPLOY_TIMEOUT_MS = 600_000;
6
11
  /** Timeout for token refresh requests (10 seconds) */
7
12
  const REFRESH_TIMEOUT_MS = 10_000;
8
13
  /**
@@ -24,8 +29,18 @@ const ensureFreshToken = async () => {
24
29
  signal: AbortSignal.timeout(REFRESH_TIMEOUT_MS),
25
30
  });
26
31
  if (res.status === 401 || res.status === 403) {
27
- // Refresh token is expired/revoked — clear credentials
32
+ // Refresh token is expired/revoked — clear credentials AND tell the
33
+ // user exactly what to do. Without this hint, the upcoming API call
34
+ // returns a generic "not authenticated" and the user has no idea
35
+ // their multi-week session just rolled off — they assume their
36
+ // login is broken or pushto is broken.
37
+ //
38
+ // Stderr keeps the message out of any captured stdout (e.g. when
39
+ // the user pipes `pushto env list | grep ...` and we don't want to
40
+ // pollute the pipe). Plain text — no chalk import here to keep this
41
+ // module dependency-free for the auth-bootstrap path.
28
42
  clearToken();
43
+ process.stderr.write('your pushto session expired. run `pushto login` to sign back in.\n');
29
44
  return;
30
45
  }
31
46
  if (!res.ok)
@@ -48,7 +63,10 @@ export const api = async (path, options = {}) => {
48
63
  const headers = {
49
64
  ...existingHeaders,
50
65
  };
51
- if (!headers['Content-Type']) {
66
+ // Skip Content-Type for FormData — fetch needs to generate its own
67
+ // multipart/form-data boundary, which it only does when Content-Type is unset.
68
+ const isFormData = typeof FormData !== 'undefined' && options.body instanceof FormData;
69
+ if (!headers['Content-Type'] && !isFormData) {
52
70
  headers['Content-Type'] = 'application/json';
53
71
  }
54
72
  if (token) {
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAEtG,oDAAoD;AACpD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC,gEAAgE;AAChE,MAAM,iBAAiB,GAAG,OAAO,CAAC;AAElC,sDAAsD;AACtD,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAElC;;;GAGG;AACH,MAAM,gBAAgB,GAAG,KAAK,IAAmB,EAAE;IACjD,IAAI,CAAC,cAAc,EAAE;QAAE,OAAO;IAE9B,MAAM,YAAY,GAAG,eAAe,EAAE,CAAC;IACvC,IAAI,CAAC,YAAY;QAAE,OAAO;IAE1B,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,OAAO,kBAAkB,EAAE;YACpD,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,YAAY,EAAE,CAAC;YACtC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;SAChD,CAAC,CAAC;QAEH,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC7C,uDAAuD;YACvD,UAAU,EAAE,CAAC;YACb,OAAO;QACT,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO;QAEpB,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAoD,CAAC;QACnF,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,QAAQ,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,+EAA+E;IACjF,CAAC;AACH,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,GAAG,GAAG,KAAK,EAAE,IAAY,EAAE,UAAuB,EAAE,EAAqB,EAAE;IACtF,wDAAwD;IACxD,MAAM,gBAAgB,EAAE,CAAC;IAEzB,MAAM,OAAO,GAAG,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACrC,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IAEzB,MAAM,eAAe,GAAI,OAAO,CAAC,OAAkC,IAAI,EAAE,CAAC;IAC1E,MAAM,OAAO,GAA2B;QACtC,GAAG,eAAe;KACnB,CAAC;IAEF,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,EAAE,CAAC;QAC7B,OAAO,CAAC,cAAc,CAAC,GAAG,kBAAkB,CAAC;IAC/C,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,CAAC,eAAe,CAAC,GAAG,UAAU,KAAK,EAAE,CAAC;IAC/C,CAAC;IAED,OAAO,KAAK,CAAC,GAAG,OAAO,OAAO,IAAI,EAAE,EAAE;QACpC,GAAG,OAAO;QACV,OAAO;QACP,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,WAAW,CAAC,OAAO,CAAC,kBAAkB,CAAC;KAClE,CAAC,CAAC;AACL,CAAC,CAAC;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,YAAY,GAAG,GAAgB,EAAE,CAAC,WAAW,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/lib/api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The only readline interface in the CLI.
3
+ *
4
+ * Callers MUST gate this behind canPrompt() from ./interactive.js. It lives
5
+ * here rather than in a command so the guard
6
+ * (apps/web/scripts/guard-cli-interactive.mjs) can prove no command reaches
7
+ * for stdin on its own — which is exactly how the deploy hang happened.
8
+ *
9
+ * Note what this cannot do: readline's question callback never fires on EOF,
10
+ * so with stdin closed the returned promise never settles. There is no
11
+ * timeout and no rejection to catch. That is not a bug to fix here; it is
12
+ * why the decision to call this at all belongs to canPrompt().
13
+ */
14
+ export declare const ask: (question: string) => Promise<string>;
15
+ //# sourceMappingURL=ask.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask.d.ts","sourceRoot":"","sources":["../../src/lib/ask.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,GAAG,GAAI,UAAU,MAAM,KAAG,OAAO,CAAC,MAAM,CAQpD,CAAC"}
@@ -0,0 +1,24 @@
1
+ import { createInterface } from 'node:readline';
2
+ /**
3
+ * The only readline interface in the CLI.
4
+ *
5
+ * Callers MUST gate this behind canPrompt() from ./interactive.js. It lives
6
+ * here rather than in a command so the guard
7
+ * (apps/web/scripts/guard-cli-interactive.mjs) can prove no command reaches
8
+ * for stdin on its own — which is exactly how the deploy hang happened.
9
+ *
10
+ * Note what this cannot do: readline's question callback never fires on EOF,
11
+ * so with stdin closed the returned promise never settles. There is no
12
+ * timeout and no rejection to catch. That is not a bug to fix here; it is
13
+ * why the decision to call this at all belongs to canPrompt().
14
+ */
15
+ export const ask = (question) => {
16
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
17
+ return new Promise((resolve) => {
18
+ rl.question(question, (answer) => {
19
+ rl.close();
20
+ resolve(answer.trim());
21
+ });
22
+ });
23
+ };
24
+ //# sourceMappingURL=ask.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ask.js","sourceRoot":"","sources":["../../src/lib/ask.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEhD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,QAAgB,EAAmB,EAAE;IACvD,MAAM,EAAE,GAAG,eAAe,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAC7E,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,EAAE;YAC/B,EAAE,CAAC,KAAK,EAAE,CAAC;YACX,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACzB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
@@ -0,0 +1,25 @@
1
+ import type { StaticFrameworkDetection } from './detect-static-framework.js';
2
+ /**
3
+ * Runs a static-output framework build on the user's machine and resolves
4
+ * where the artifact landed. Every failure returns { ok: false } with the
5
+ * captured output — the caller never uploads on failure, and never falls
6
+ * back to stale output (honest failure beats stale success).
7
+ */
8
+ export declare const ARTIFACT_META_NAME = "_pushto_meta.json";
9
+ export type BuildOutcome = {
10
+ ok: true;
11
+ outputDir: string;
12
+ typeWarnings: string | null;
13
+ } | {
14
+ ok: false;
15
+ message: string;
16
+ buildOutput: string;
17
+ };
18
+ export declare const runStaticBuild: (dir: string, detection: StaticFrameworkDetection, opts?: {
19
+ log?: (line: string) => void;
20
+ }) => Promise<BuildOutcome>;
21
+ export declare const writeArtifactMeta: (outputDir: string, meta: {
22
+ framework: string;
23
+ spa: boolean;
24
+ }) => (() => void);
25
+ //# sourceMappingURL=build-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-runner.d.ts","sourceRoot":"","sources":["../../src/lib/build-runner.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAE7E;;;;;GAKG;AAEH,eAAO,MAAM,kBAAkB,sBAAsB,CAAC;AAUtD,MAAM,MAAM,YAAY,GACpB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAC5D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAyExD,eAAO,MAAM,cAAc,GACzB,KAAK,MAAM,EACX,WAAW,wBAAwB,EACnC,OAAO;IAAE,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;CAAE,KACtC,OAAO,CAAC,YAAY,CA0DtB,CAAC;AAEF,eAAO,MAAM,iBAAiB,GAC5B,WAAW,MAAM,EACjB,MAAM;IAAE,SAAS,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,KACxC,CAAC,MAAM,IAAI,CAMb,CAAC"}
@@ -0,0 +1,141 @@
1
+ import { spawn } from 'node:child_process';
2
+ import fs from 'node:fs';
3
+ import path from 'node:path';
4
+ /**
5
+ * Runs a static-output framework build on the user's machine and resolves
6
+ * where the artifact landed. Every failure returns { ok: false } with the
7
+ * captured output — the caller never uploads on failure, and never falls
8
+ * back to stale output (honest failure beats stale success).
9
+ */
10
+ export const ARTIFACT_META_NAME = '_pushto_meta.json';
11
+ const BUILD_TIMEOUT_MS = 10 * 60 * 1000; // generous: old laptops, cold gatsby
12
+ const FALLBACK_SCAN_DIRS = ['dist', 'build', 'out', '_site'];
13
+ /** The stock Vite React-TS scaffold build script. Only this exact shape
14
+ * earns the tsc-fallback retry (Scott's call, spec decision #4): any
15
+ * customized script is the user's contract and fails honestly. */
16
+ const STOCK_TSC_VITE = /^\s*tsc(?:\s+-b)?\s*&&\s*vite\s+build\s*$/;
17
+ const detectPm = (dir) => {
18
+ if (fs.existsSync(path.join(dir, 'pnpm-lock.yaml')))
19
+ return 'pnpm';
20
+ if (fs.existsSync(path.join(dir, 'yarn.lock')))
21
+ return 'yarn';
22
+ return 'npm';
23
+ };
24
+ const exec = (cmd, cwd) => new Promise((resolve) => {
25
+ const [bin, ...args] = cmd;
26
+ const child = spawn(bin, args, {
27
+ cwd,
28
+ // Windows needs a shell to resolve npm.cmd / pnpm.cmd shims.
29
+ shell: process.platform === 'win32',
30
+ });
31
+ const chunks = [];
32
+ child.stdout.on('data', (d) => chunks.push(d.toString()));
33
+ child.stderr.on('data', (d) => chunks.push(d.toString()));
34
+ const timer = setTimeout(() => {
35
+ child.kill('SIGKILL');
36
+ chunks.push('\n(build timed out after 10 minutes)');
37
+ }, BUILD_TIMEOUT_MS);
38
+ child.on('close', (code) => {
39
+ clearTimeout(timer);
40
+ resolve({ code: code ?? 1, output: chunks.join('') });
41
+ });
42
+ child.on('error', (err) => {
43
+ clearTimeout(timer);
44
+ resolve({ code: 1, output: String(err) });
45
+ });
46
+ });
47
+ const installCmd = (pm) => pm === 'pnpm' ? ['pnpm', 'install'] : pm === 'yarn' ? ['yarn', 'install'] : ['npm', 'install'];
48
+ const runScriptCmd = (pm, script) => pm === 'pnpm' ? ['pnpm', 'run', script] : pm === 'yarn' ? ['yarn', 'run', script] : ['npm', 'run', script];
49
+ /** Run a local bin directly (the tsc-fallback retry). */
50
+ const execLocalBinCmd = (pm, bin, args) => pm === 'pnpm' ? ['pnpm', 'exec', bin, ...args]
51
+ : pm === 'yarn' ? ['yarn', bin, ...args]
52
+ : ['npx', '--no-install', bin, ...args];
53
+ /** First candidate dir containing an index.html written after buildStart. */
54
+ const resolveOutputDir = (dir, candidates, buildStart) => {
55
+ const all = [...candidates, ...FALLBACK_SCAN_DIRS.filter((d) => !candidates.includes(d))];
56
+ for (const c of all) {
57
+ const indexPath = path.join(dir, c, 'index.html');
58
+ try {
59
+ const stat = fs.statSync(indexPath);
60
+ if (stat.mtimeMs >= buildStart)
61
+ return path.join(dir, c);
62
+ }
63
+ catch { /* not there — next candidate */ }
64
+ }
65
+ return null;
66
+ };
67
+ /** The real build command per framework — the message must name a fix
68
+ * that actually works when pasted into package.json. */
69
+ const BUILD_SCRIPT_SUGGESTION = {
70
+ vite: 'vite build',
71
+ astro: 'astro build',
72
+ gatsby: 'gatsby build',
73
+ angular: 'ng build',
74
+ cra: 'react-scripts build',
75
+ eleventy: 'eleventy',
76
+ };
77
+ export const runStaticBuild = async (dir, detection, opts) => {
78
+ const log = opts?.log ?? (() => undefined);
79
+ const pm = detectPm(dir);
80
+ const pkgRaw = fs.readFileSync(path.join(dir, 'package.json'), 'utf-8');
81
+ // JSON.parse returns any; scripts is optional-chained below, so an
82
+ // unexpected shape yields undefined rather than a crash.
83
+ const pkg = JSON.parse(pkgRaw);
84
+ const buildScript = pkg.scripts?.build;
85
+ if (!buildScript) {
86
+ return {
87
+ ok: false,
88
+ buildOutput: '',
89
+ message: `your package.json has no build script. ${detection.framework} projects need one. add "build": "${BUILD_SCRIPT_SUGGESTION[detection.framework]}" and run pushto again.`,
90
+ };
91
+ }
92
+ if (!fs.existsSync(path.join(dir, 'node_modules'))) {
93
+ log(`installing dependencies (${pm})...`);
94
+ const install = await exec(installCmd(pm), dir);
95
+ if (install.code !== 0) {
96
+ return { ok: false, message: 'dependency install failed. run the install yourself to see the full story, then pushto again.', buildOutput: install.output };
97
+ }
98
+ }
99
+ const buildStart = Date.now();
100
+ log(`building (${detection.framework})...`);
101
+ const build = await exec(runScriptCmd(pm, 'build'), dir);
102
+ let typeWarnings = null;
103
+ if (build.code !== 0) {
104
+ // Stock-scaffold typecheck fallback: dev mode never typechecks, so
105
+ // AI-scaffolded apps that work in dev routinely die here on type
106
+ // errors. For the EXACT stock script shape only, retry vite alone,
107
+ // ship, and surface the type errors as a warning.
108
+ if (detection.framework === 'vite' && STOCK_TSC_VITE.test(buildScript)) {
109
+ log('type errors found. retrying with vite alone...');
110
+ const retry = await exec(execLocalBinCmd(pm, 'vite', ['build']), dir);
111
+ if (retry.code !== 0) {
112
+ return { ok: false, message: 'the build failed. the output below is the real story. fix it, or run the build yourself to iterate faster.', buildOutput: retry.output };
113
+ }
114
+ typeWarnings = build.output;
115
+ }
116
+ else {
117
+ return { ok: false, message: 'the build failed. the output below is the real story. fix it, or run the build yourself to iterate faster.', buildOutput: build.output };
118
+ }
119
+ }
120
+ const outputDir = resolveOutputDir(dir, detection.outputDirs, buildStart);
121
+ if (!outputDir) {
122
+ const looked = [...detection.outputDirs, ...FALLBACK_SCAN_DIRS].join(', ');
123
+ return {
124
+ ok: false,
125
+ buildOutput: build.output,
126
+ message: `the build finished but produced no fresh index.html. looked in: ${looked}. if your build outputs somewhere else, point it at one of those. server-rendered setups need the container path instead.`,
127
+ };
128
+ }
129
+ return { ok: true, outputDir, typeWarnings };
130
+ };
131
+ export const writeArtifactMeta = (outputDir, meta) => {
132
+ const metaPath = path.join(outputDir, ARTIFACT_META_NAME);
133
+ fs.writeFileSync(metaPath, JSON.stringify({ ...meta, generator: 'pushto-cli' }));
134
+ return () => {
135
+ try {
136
+ fs.rmSync(metaPath, { force: true });
137
+ }
138
+ catch { /* best effort */ }
139
+ };
140
+ };
141
+ //# sourceMappingURL=build-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build-runner.js","sourceRoot":"","sources":["../../src/lib/build-runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAC3C,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B;;;;;GAKG;AAEH,MAAM,CAAC,MAAM,kBAAkB,GAAG,mBAAmB,CAAC;AAEtD,MAAM,gBAAgB,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,qCAAqC;AAC9E,MAAM,kBAAkB,GAAG,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;AAE7D;;mEAEmE;AACnE,MAAM,cAAc,GAAG,2CAA2C,CAAC;AAQnE,MAAM,QAAQ,GAAG,CAAC,GAAW,EAAM,EAAE;IACnC,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IACnE,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,MAAM,CAAC;IAC9D,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAIF,MAAM,IAAI,GAAG,CAAC,GAAa,EAAE,GAAW,EAAuB,EAAE,CAC/D,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;IACtB,MAAM,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC;IAC3B,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE;QAC7B,GAAG;QACH,6DAA6D;QAC7D,KAAK,EAAE,OAAO,CAAC,QAAQ,KAAK,OAAO;KACpC,CAAC,CAAC;IACH,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAClE,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;IAClE,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;QAC5B,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACtB,MAAM,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IACtD,CAAC,EAAE,gBAAgB,CAAC,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,EAAE;QACzB,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,GAAG,EAAE,EAAE;QACxB,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,OAAO,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,MAAM,UAAU,GAAG,CAAC,EAAM,EAAY,EAAE,CACtC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;AAEjG,MAAM,YAAY,GAAG,CAAC,EAAM,EAAE,MAAc,EAAY,EAAE,CACxD,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;AAE7G,yDAAyD;AACzD,MAAM,eAAe,GAAG,CAAC,EAAM,EAAE,GAAW,EAAE,IAAc,EAAY,EAAE,CACxE,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC5C,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;QACtC,CAAC,CAAC,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;AAE9C,6EAA6E;AAC7E,MAAM,gBAAgB,GAAG,CAAC,GAAW,EAAE,UAAoB,EAAE,UAAkB,EAAiB,EAAE;IAChG,MAAM,GAAG,GAAG,CAAC,GAAG,UAAU,EAAE,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1F,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;QACpB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;QAClD,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;YACpC,IAAI,IAAI,CAAC,OAAO,IAAI,UAAU;gBAAE,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC,CAAC,gCAAgC,CAAC,CAAC;IAC9C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF;yDACyD;AACzD,MAAM,uBAAuB,GAA0D;IACrF,IAAI,EAAE,YAAY;IAClB,KAAK,EAAE,aAAa;IACpB,MAAM,EAAE,cAAc;IACtB,OAAO,EAAE,UAAU;IACnB,GAAG,EAAE,qBAAqB;IAC1B,QAAQ,EAAE,UAAU;CACrB,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EACjC,GAAW,EACX,SAAmC,EACnC,IAAuC,EAChB,EAAE;IACzB,MAAM,GAAG,GAAG,IAAI,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC3C,MAAM,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAEzB,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC;IACxE,mEAAmE;IACnE,yDAAyD;IACzD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAyC,CAAC;IACvE,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC;IACvC,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,WAAW,EAAE,EAAE;YACf,OAAO,EAAE,0CAA0C,SAAS,CAAC,SAAS,qCAAqC,uBAAuB,CAAC,SAAS,CAAC,SAAS,CAAC,yBAAyB;SACjL,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,4BAA4B,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAChD,IAAI,OAAO,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,+FAA+F,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;QAC9J,CAAC;IACH,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC9B,GAAG,CAAC,aAAa,SAAS,CAAC,SAAS,MAAM,CAAC,CAAC;IAC5C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,OAAO,CAAC,EAAE,GAAG,CAAC,CAAC;IAEzD,IAAI,YAAY,GAAkB,IAAI,CAAC;IACvC,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACrB,mEAAmE;QACnE,iEAAiE;QACjE,mEAAmE;QACnE,kDAAkD;QAClD,IAAI,SAAS,CAAC,SAAS,KAAK,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;YACvE,GAAG,CAAC,gDAAgD,CAAC,CAAC;YACtD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YACtE,IAAI,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACrB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,4GAA4G,EAAE,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;YACzK,CAAC;YACD,YAAY,GAAG,KAAK,CAAC,MAAM,CAAC;QAC9B,CAAC;aAAM,CAAC;YACN,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,4GAA4G,EAAE,WAAW,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;QACzK,CAAC;IACH,CAAC;IAED,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,EAAE,SAAS,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IAC1E,IAAI,CAAC,SAAS,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,CAAC,GAAG,SAAS,CAAC,UAAU,EAAE,GAAG,kBAAkB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC3E,OAAO;YACL,EAAE,EAAE,KAAK;YACT,WAAW,EAAE,KAAK,CAAC,MAAM;YACzB,OAAO,EAAE,mEAAmE,MAAM,2HAA2H;SAC9M,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;AAC/C,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAC/B,SAAiB,EACjB,IAAyC,EAC3B,EAAE;IAChB,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,CAAC;IAC1D,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC;IACjF,OAAO,GAAG,EAAE;QACV,IAAI,CAAC;YAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;IAC3E,CAAC,CAAC;AACJ,CAAC,CAAC"}
@@ -6,6 +6,12 @@ interface PushtoConfig {
6
6
  projectSlug?: string;
7
7
  }
8
8
  export declare const config: Conf<PushtoConfig>;
9
+ /**
10
+ * PUSHTO_TOKEN wins over stored config so a headless caller never has to run
11
+ * the browser login flow. An empty value is treated as unset, so
12
+ * `PUSHTO_TOKEN= pushto deploy` falls back rather than authenticating as "".
13
+ * This is also the bootstrap path for MCP auth, which expects a bearer token.
14
+ */
9
15
  export declare const getToken: () => string | undefined;
10
16
  export declare const getRefreshToken: () => string | undefined;
11
17
  export declare const setToken: (token: string, refreshToken?: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,MAAM,oBAKjB,CAAC;AAEH,eAAO,MAAM,QAAQ,QAAO,MAAM,GAAG,SAAgC,CAAC;AACtE,eAAO,MAAM,eAAe,QAAO,MAAM,GAAG,SAAuC,CAAC;AAEpF,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,EAAE,eAAe,MAAM,KAAG,IAG/D,CAAC;AAEF,eAAO,MAAM,UAAU,QAAO,IAG7B,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,MAAM,GAAG,SAAsC,CAAC;AAElF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,IAE7C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,OAejC,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,UAAU,YAAY;IACpB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,eAAO,MAAM,MAAM,oBAKjB,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAO,MAAM,GAAG,SAA4D,CAAC;AAClG,eAAO,MAAM,eAAe,QAAO,MAAM,GAAG,SAAuC,CAAC;AAEpF,eAAO,MAAM,QAAQ,GAAI,OAAO,MAAM,EAAE,eAAe,MAAM,KAAG,IAG/D,CAAC;AAEF,eAAO,MAAM,UAAU,QAAO,IAG7B,CAAC;AAEF,eAAO,MAAM,cAAc,QAAO,MAAM,GAAG,SAAsC,CAAC;AAElF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,IAE7C,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,cAAc,QAAO,OAejC,CAAC"}
@@ -5,7 +5,13 @@ export const config = new Conf({
5
5
  apiUrl: 'https://pushto.host',
6
6
  },
7
7
  });
8
- export const getToken = () => config.get('token');
8
+ /**
9
+ * PUSHTO_TOKEN wins over stored config so a headless caller never has to run
10
+ * the browser login flow. An empty value is treated as unset, so
11
+ * `PUSHTO_TOKEN= pushto deploy` falls back rather than authenticating as "".
12
+ * This is also the bootstrap path for MCP auth, which expects a bearer token.
13
+ */
14
+ export const getToken = () => process.env.PUSHTO_TOKEN || config.get('token');
9
15
  export const getRefreshToken = () => config.get('refreshToken');
10
16
  export const setToken = (token, refreshToken) => {
11
17
  config.set('token', token);
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AASxB,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAe;IAC3C,WAAW,EAAE,QAAQ;IACrB,QAAQ,EAAE;QACR,MAAM,EAAE,qBAAqB;KAC9B;CACF,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAuB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AACtE,MAAM,CAAC,MAAM,eAAe,GAAG,GAAuB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAEpF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,YAAqB,EAAQ,EAAE;IACrE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3B,IAAI,YAAY;QAAE,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;AAC7D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,GAAS,EAAE;IACnC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvB,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAuB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAElF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAQ,EAAE;IACnD,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAY,EAAE;IAC1C,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAa,CAAC;QAClC,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACzC,0CAA0C;QAC1C,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC"}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AASxB,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,IAAI,CAAe;IAC3C,WAAW,EAAE,QAAQ;IACrB,QAAQ,EAAE;QACR,MAAM,EAAE,qBAAqB;KAC9B;CACF,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAuB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAClG,MAAM,CAAC,MAAM,eAAe,GAAG,GAAuB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;AAEpF,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAAa,EAAE,YAAqB,EAAQ,EAAE;IACrE,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC3B,IAAI,YAAY;QAAE,MAAM,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,CAAC;AAC7D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,UAAU,GAAG,GAAS,EAAE;IACnC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACvB,MAAM,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,GAAuB,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAElF,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,IAAY,EAAQ,EAAE;IACnD,MAAM,CAAC,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAY,EAAE;IAC1C,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IAExB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAAE,OAAO,IAAI,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QACvE,MAAM,GAAG,GAAG,OAAO,CAAC,GAAa,CAAC;QAClC,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACzC,0CAA0C;QAC1C,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Follow-loop primitive for `pushto cron tail`: the history endpoint
3
+ * returns newest-first, a live tail prints unseen rows oldest-first.
4
+ */
5
+ export interface TailExecution {
6
+ id: string;
7
+ executedAt: string;
8
+ }
9
+ export declare const selectNewExecutions: <T extends TailExecution>(seen: Set<string>, executions: T[]) => T[];
10
+ //# sourceMappingURL=cron-tail.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-tail.d.ts","sourceRoot":"","sources":["../../src/lib/cron-tail.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,eAAO,MAAM,mBAAmB,GAAI,CAAC,SAAS,aAAa,EACzD,MAAM,GAAG,CAAC,MAAM,CAAC,EACjB,YAAY,CAAC,EAAE,KACd,CAAC,EAIoF,CAAC"}
@@ -0,0 +1,5 @@
1
+ export const selectNewExecutions = (seen, executions) => executions
2
+ .filter((e) => !seen.has(e.id))
3
+ .slice()
4
+ .sort((a, b) => new Date(a.executedAt).getTime() - new Date(b.executedAt).getTime());
5
+ //# sourceMappingURL=cron-tail.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cron-tail.js","sourceRoot":"","sources":["../../src/lib/cron-tail.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,IAAiB,EACjB,UAAe,EACV,EAAE,CACP,UAAU;KACP,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;KAC9B,KAAK,EAAE;KACP,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * CLI-side detection for static-output frameworks — the ones `pushto`
3
+ * builds locally and ships as an artifact (spec: docs/superpowers/specs/
4
+ * 2026-07-10-static-build-pipeline-design.md).
5
+ *
6
+ * This table deliberately does NOT import @pushto/shared: the published
7
+ * CLI ships standalone (npm + Homebrew Bun-compile). The shared
8
+ * FRAMEWORK_TABLE in packages/shared/src/constants.ts is the truth; a
9
+ * sync test in apps/web/__tests__/frameworks-docs-sync.test.ts fails CI
10
+ * if the two drift.
11
+ */
12
+ export interface CliFrameworkEntry {
13
+ id: 'vite' | 'astro' | 'gatsby' | 'angular' | 'cra' | 'eleventy';
14
+ deps: readonly string[];
15
+ configFiles: readonly string[];
16
+ outputDirs: readonly string[];
17
+ spa: boolean;
18
+ /** `scripts.start` commands that are the framework's OWN dev server
19
+ * (stock CRA/Angular/Gatsby/Eleventy scaffolds all ship one). Mirrors
20
+ * packages/shared/src/constants.ts's FrameworkEntry.devStartCommands —
21
+ * the sync test compares the two field-for-field. */
22
+ devStartCommands: readonly string[];
23
+ }
24
+ export declare const STATIC_BUILD_FRAMEWORKS: readonly CliFrameworkEntry[];
25
+ export interface StaticFrameworkDetection {
26
+ framework: CliFrameworkEntry['id'];
27
+ spa: boolean;
28
+ outputDirs: string[];
29
+ }
30
+ export declare const detectStaticFramework: (dir: string) => StaticFrameworkDetection | null;
31
+ //# sourceMappingURL=detect-static-framework.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-static-framework.d.ts","sourceRoot":"","sources":["../../src/lib/detect-static-framework.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;GAUG;AAEH,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,UAAU,CAAC;IACjE,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAC9B,GAAG,EAAE,OAAO,CAAC;IACb;;;0DAGsD;IACtD,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC;AAMD,eAAO,MAAM,uBAAuB,EAAE,SAAS,iBAAiB,EAOtD,CAAC;AASX,MAAM,WAAW,wBAAwB;IACvC,SAAS,EAAE,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACnC,GAAG,EAAE,OAAO,CAAC;IACb,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAgDD,eAAO,MAAM,qBAAqB,GAAI,KAAK,MAAM,KAAG,wBAAwB,GAAG,IA4C9E,CAAC"}
@@ -0,0 +1,96 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ // Order matters: specific frameworks first, the vite catch-all LAST
4
+ // (astro/gatsby/etc. may pull vite in transitively; direct-dep checks
5
+ // keep this unambiguous, but a user adding vite as a sibling devDep
6
+ // must still land on the specific framework).
7
+ export const STATIC_BUILD_FRAMEWORKS = [
8
+ { id: 'astro', deps: ['astro'], configFiles: [], outputDirs: ['dist'], spa: false, devStartCommands: ['astro dev', 'astro preview'] },
9
+ { id: 'gatsby', deps: ['gatsby'], configFiles: [], outputDirs: ['public'], spa: false, devStartCommands: ['gatsby develop', 'gatsby serve'] },
10
+ { id: 'angular', deps: ['@angular/core'], configFiles: ['angular.json'], outputDirs: ['ANGULAR_JSON'], spa: true, devStartCommands: ['ng serve'] },
11
+ { id: 'cra', deps: ['react-scripts'], configFiles: [], outputDirs: ['build'], spa: true, devStartCommands: ['react-scripts start'] },
12
+ { id: 'eleventy', deps: ['@11ty/eleventy'], configFiles: [], outputDirs: ['_site'], spa: false, devStartCommands: ['eleventy --serve', 'npx @11ty/eleventy --serve', 'npx eleventy --serve', '@11ty/eleventy --serve'] },
13
+ { id: 'vite', deps: ['vite'], configFiles: ['vite.config.js', 'vite.config.ts', 'vite.config.mjs', 'vite.config.mts'], outputDirs: ['dist'], spa: true, devStartCommands: ['vite', 'vite dev', 'vite preview'] },
14
+ ];
15
+ // A dep from this list means the project is SSR-shaped and belongs on
16
+ // the container path even though vite is probably also present.
17
+ const SSR_MARKERS = [
18
+ 'next', 'nuxt', '@sveltejs/kit',
19
+ '@solidjs/start', 'solid-start',
20
+ ];
21
+ const readJson = (file) => {
22
+ try {
23
+ // JSON.parse returns any; treat as unknown and narrow field-by-field below
24
+ return JSON.parse(fs.readFileSync(file, 'utf-8'));
25
+ }
26
+ catch {
27
+ return null;
28
+ }
29
+ };
30
+ /** Expand angular.json into concrete output-dir candidates. */
31
+ const angularOutputDirs = (dir) => {
32
+ const parsed = readJson(path.join(dir, 'angular.json'));
33
+ const projects = parsed && typeof parsed === 'object'
34
+ ? // Shape probed optionally; every access below is optional-chained, so wrong shape yields undefined
35
+ parsed.projects
36
+ : undefined;
37
+ const name = projects ? Object.keys(projects)[0] : undefined;
38
+ if (!name)
39
+ return ['dist'];
40
+ const project = projects?.[name];
41
+ const outputPath = project && typeof project === 'object'
42
+ ? // Shape probed optionally with nested optional chains; wrong structure yields undefined, not a crash
43
+ (project
44
+ .architect?.build?.options?.outputPath)
45
+ : undefined;
46
+ // outputPath can be a string or (v17 application builder) { base: string }
47
+ const base = typeof outputPath === 'string'
48
+ ? outputPath
49
+ : outputPath && typeof outputPath === 'object' && typeof
50
+ // Narrowed to object; check for base property before accessing
51
+ outputPath.base === 'string'
52
+ ? // Base is now proven string; safe to cast
53
+ outputPath.base
54
+ : `dist/${name}`;
55
+ return [`${base}/browser`, base];
56
+ };
57
+ export const detectStaticFramework = (dir) => {
58
+ const pkgPath = path.join(dir, 'package.json');
59
+ if (!fs.existsSync(pkgPath))
60
+ return null;
61
+ const parsed = readJson(pkgPath);
62
+ if (!parsed || typeof parsed !== 'object')
63
+ return null;
64
+ // Proven to be a non-null object above; narrow to PkgJson shape
65
+ const pkg = parsed;
66
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
67
+ // Tie-breaker 1: SSR frameworks are container-path regardless of scripts.
68
+ if (SSR_MARKERS.some((d) => d in allDeps) ||
69
+ Object.keys(allDeps).some((d) => d.startsWith('@remix-run/'))) {
70
+ return null;
71
+ }
72
+ for (const entry of STATIC_BUILD_FRAMEWORKS) {
73
+ const byDep = entry.deps.some((d) => d in allDeps);
74
+ const byConfig = entry.configFiles.some((f) => fs.existsSync(path.join(dir, f)));
75
+ if (!byDep && !byConfig)
76
+ continue;
77
+ // Tie-breaker 2: a start script means "this is a server" — UNLESS it's
78
+ // just the matched framework's own dev server (stock CRA/Angular/
79
+ // Gatsby/Eleventy scaffolds all ship one; the old rule treated any
80
+ // start script as dynamic and routed every one of them past the
81
+ // static-build path). Word-boundary match: the command IS the dev
82
+ // command, or continues with a space (flags) — `vite-custom-wrapper.js`
83
+ // must not match `vite`.
84
+ const rawStart = pkg.scripts?.start;
85
+ if (rawStart) {
86
+ const cmd = rawStart.trim();
87
+ const isOwnDevServer = entry.devStartCommands.some((c) => cmd === c || cmd.startsWith(`${c} `));
88
+ if (!isOwnDevServer)
89
+ return null;
90
+ }
91
+ const outputDirs = entry.outputDirs[0] === 'ANGULAR_JSON' ? angularOutputDirs(dir) : [...entry.outputDirs];
92
+ return { framework: entry.id, spa: entry.spa, outputDirs };
93
+ }
94
+ return null;
95
+ };
96
+ //# sourceMappingURL=detect-static-framework.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-static-framework.js","sourceRoot":"","sources":["../../src/lib/detect-static-framework.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Parse a .env file's content into a key/value record.
3
+ *
4
+ * Every surface that accepts a .env file speaks through this parser:
5
+ * `pushto deploy` (auto-import on every deploy), `pushto env push`, and the
6
+ * dashboard's import box + raw editor. Pre-fix the dashboard hand-rolled its
7
+ * own parse and the two drifted — `export KEY=value` lines (copied from a
8
+ * .bashrc) were rejected in the dashboard, and inline comments were stored
9
+ * INTO the value (`PORT=3000 # default port` saved a value of
10
+ * `3000 # default port`).
11
+ *
12
+ * This file exists twice, byte-identical: apps/cli/src/lib/env-parse.ts and
13
+ * apps/web/lib/env-parse.ts. The web app can't import from apps/cli, and the
14
+ * published CLI deliberately carries no workspace deps — a vitest pin
15
+ * (apps/web/lib/__tests__/env-parse.test.ts) keeps the copies in sync
16
+ * instead. Edit one, copy to the other, or the pin fails.
17
+ *
18
+ * Supports:
19
+ * - bare assignments: KEY=value
20
+ * - `export` prefix: export KEY=value ← copied from .bashrc
21
+ * - quoted values: KEY="value with spaces" KEY='single quoted'
22
+ * - inline trailing comment: PORT=3000 # default port (only when value is unquoted)
23
+ * - blank lines + #-comments
24
+ *
25
+ * Does NOT support (and pushto's server-side validator would reject):
26
+ * - multi-line quoted values
27
+ * - escape sequences inside double quotes (treated literally)
28
+ */
29
+ export type EnvParseSkip = {
30
+ key: string;
31
+ reason: string;
32
+ };
33
+ export type EnvParseResult = {
34
+ vars: Record<string, string>;
35
+ skipped: EnvParseSkip[];
36
+ };
37
+ /**
38
+ * Full parse: valid pairs plus a per-line skip list with reasons, so
39
+ * consumers can tell the user WHICH lines didn't make it and why instead
40
+ * of importing silently-fewer vars than the file holds.
41
+ */
42
+ export declare const parseEnvContent: (content: string) => EnvParseResult;
43
+ /**
44
+ * Record-only view for callers that don't surface skip reasons.
45
+ * Same parse, skips dropped.
46
+ */
47
+ export declare const parseEnvFile: (content: string) => Record<string, string>;
48
+ //# sourceMappingURL=env-parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-parse.d.ts","sourceRoot":"","sources":["../../src/lib/env-parse.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,MAAM,MAAM,YAAY,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3D,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,eAAe,GAAI,SAAS,MAAM,KAAG,cA4DjD,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,GAAI,SAAS,MAAM,KAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CACrC,CAAC"}