@pushto/cli 0.2.0 → 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 (188) 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 +344 -68
  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 +401 -69
  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 +70 -18
  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 +80 -39
  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 +32 -8
  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 +123 -13
  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 +2 -0
  114. package/dist/lib/api.d.ts.map +1 -1
  115. package/dist/lib/api.js +38 -5
  116. package/dist/lib/api.js.map +1 -1
  117. package/dist/lib/ask.d.ts +15 -0
  118. package/dist/lib/ask.d.ts.map +1 -0
  119. package/dist/lib/ask.js +24 -0
  120. package/dist/lib/ask.js.map +1 -0
  121. package/dist/lib/build-runner.d.ts +25 -0
  122. package/dist/lib/build-runner.d.ts.map +1 -0
  123. package/dist/lib/build-runner.js +141 -0
  124. package/dist/lib/build-runner.js.map +1 -0
  125. package/dist/lib/config.d.ts +6 -0
  126. package/dist/lib/config.d.ts.map +1 -1
  127. package/dist/lib/config.js +13 -2
  128. package/dist/lib/config.js.map +1 -1
  129. package/dist/lib/cron-tail.d.ts +10 -0
  130. package/dist/lib/cron-tail.d.ts.map +1 -0
  131. package/dist/lib/cron-tail.js +5 -0
  132. package/dist/lib/cron-tail.js.map +1 -0
  133. package/dist/lib/detect-static-framework.d.ts +31 -0
  134. package/dist/lib/detect-static-framework.d.ts.map +1 -0
  135. package/dist/lib/detect-static-framework.js +96 -0
  136. package/dist/lib/detect-static-framework.js.map +1 -0
  137. package/dist/lib/env-parse.d.ts +48 -0
  138. package/dist/lib/env-parse.d.ts.map +1 -0
  139. package/dist/lib/env-parse.js +91 -0
  140. package/dist/lib/env-parse.js.map +1 -0
  141. package/dist/lib/errors.d.ts +111 -0
  142. package/dist/lib/errors.d.ts.map +1 -0
  143. package/dist/lib/errors.js +64 -0
  144. package/dist/lib/errors.js.map +1 -0
  145. package/dist/lib/file-walker.d.ts +23 -0
  146. package/dist/lib/file-walker.d.ts.map +1 -0
  147. package/dist/lib/file-walker.js +114 -0
  148. package/dist/lib/file-walker.js.map +1 -0
  149. package/dist/lib/interactive.d.ts +13 -0
  150. package/dist/lib/interactive.d.ts.map +1 -0
  151. package/dist/lib/interactive.js +24 -0
  152. package/dist/lib/interactive.js.map +1 -0
  153. package/dist/lib/output.d.ts +24 -0
  154. package/dist/lib/output.d.ts.map +1 -0
  155. package/dist/lib/output.js +71 -0
  156. package/dist/lib/output.js.map +1 -0
  157. package/dist/lib/prepare-artifact.d.ts +22 -0
  158. package/dist/lib/prepare-artifact.d.ts.map +1 -0
  159. package/dist/lib/prepare-artifact.js +26 -0
  160. package/dist/lib/prepare-artifact.js.map +1 -0
  161. package/dist/lib/preview-args.d.ts +20 -0
  162. package/dist/lib/preview-args.d.ts.map +1 -0
  163. package/dist/lib/preview-args.js +19 -0
  164. package/dist/lib/preview-args.js.map +1 -0
  165. package/dist/lib/resolve-slug.d.ts.map +1 -1
  166. package/dist/lib/resolve-slug.js +9 -2
  167. package/dist/lib/resolve-slug.js.map +1 -1
  168. package/dist/lib/safe-json.d.ts +7 -2
  169. package/dist/lib/safe-json.d.ts.map +1 -1
  170. package/dist/lib/safe-json.js +23 -4
  171. package/dist/lib/safe-json.js.map +1 -1
  172. package/dist/lib/update-check.d.ts +17 -0
  173. package/dist/lib/update-check.d.ts.map +1 -0
  174. package/dist/lib/update-check.js +81 -0
  175. package/dist/lib/update-check.js.map +1 -0
  176. package/dist/lib/upload-limits.d.ts +17 -0
  177. package/dist/lib/upload-limits.d.ts.map +1 -0
  178. package/dist/lib/upload-limits.js +17 -0
  179. package/dist/lib/upload-limits.js.map +1 -0
  180. package/dist/lib/zip-project.d.ts +19 -0
  181. package/dist/lib/zip-project.d.ts.map +1 -0
  182. package/dist/lib/zip-project.js +39 -0
  183. package/dist/lib/zip-project.js.map +1 -0
  184. package/dist/version.d.ts +2 -0
  185. package/dist/version.d.ts.map +1 -0
  186. package/dist/version.js +16 -0
  187. package/dist/version.js.map +1 -0
  188. package/package.json +5 -8
@@ -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,OAYjC,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);
@@ -29,8 +35,13 @@ export const isTokenExpired = () => {
29
35
  if (!token)
30
36
  return true;
31
37
  try {
32
- const payload = JSON.parse(Buffer.from(token.split('.')[1], 'base64').toString());
38
+ const parts = token.split('.');
39
+ if (parts.length < 2 || !parts[1])
40
+ return true;
41
+ const payload = JSON.parse(Buffer.from(parts[1], 'base64').toString());
33
42
  const exp = payload.exp;
43
+ if (typeof exp !== 'number')
44
+ return true;
34
45
  // Refresh 60 seconds before actual expiry
35
46
  return Date.now() / 1000 > exp - 60;
36
47
  }
@@ -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,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAa,CAAC;QAClC,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"}
@@ -0,0 +1,91 @@
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
+ /**
30
+ * Full parse: valid pairs plus a per-line skip list with reasons, so
31
+ * consumers can tell the user WHICH lines didn't make it and why instead
32
+ * of importing silently-fewer vars than the file holds.
33
+ */
34
+ export const parseEnvContent = (content) => {
35
+ const vars = {};
36
+ const skipped = [];
37
+ const lines = content.split('\n');
38
+ for (let i = 0; i < lines.length; i++) {
39
+ let trimmed = lines[i].trim();
40
+ if (!trimmed || trimmed.startsWith('#'))
41
+ continue;
42
+ // Strip the bash-export prefix that people copy from their shell or
43
+ // .bashrc (`export DATABASE_URL=postgres://...`). Pre-fix this parsed
44
+ // as key=`export DATABASE_URL` which the server rejects on the
45
+ // [A-Z_] validator — DATABASE_URL silently never made it remote
46
+ // despite the success message claiming X vars imported.
47
+ if (trimmed.startsWith('export ')) {
48
+ trimmed = trimmed.slice(7).trim();
49
+ }
50
+ const eqIdx = trimmed.indexOf('=');
51
+ if (eqIdx === -1) {
52
+ skipped.push({ key: `line ${i + 1}`, reason: 'no `=` separator' });
53
+ continue;
54
+ }
55
+ const key = trimmed.slice(0, eqIdx).trim();
56
+ let value = trimmed.slice(eqIdx + 1).trim();
57
+ // Strip inline comments AFTER the value (only when not inside quotes).
58
+ // Common pattern: `PORT=3000 # default port`. The space-before-hash
59
+ // requirement avoids eating fragments of values that legitimately
60
+ // contain # (e.g. URLs with fragments, color codes like #ff0000 in
61
+ // some configs).
62
+ if (!value.startsWith('"') && !value.startsWith("'")) {
63
+ const hashIdx = value.indexOf('#');
64
+ if (hashIdx > 0 && /\s/.test(value[hashIdx - 1] ?? '')) {
65
+ value = value.slice(0, hashIdx).trim();
66
+ }
67
+ }
68
+ // Strip surrounding quotes (matched pair only; a lone quote stays).
69
+ if (value.length >= 2 &&
70
+ ((value.startsWith('"') && value.endsWith('"')) ||
71
+ (value.startsWith("'") && value.endsWith("'")))) {
72
+ value = value.slice(1, -1);
73
+ }
74
+ if (!key) {
75
+ skipped.push({ key: `line ${i + 1}`, reason: 'missing key before `=`' });
76
+ continue;
77
+ }
78
+ if (!value) {
79
+ skipped.push({ key, reason: 'empty value' });
80
+ continue;
81
+ }
82
+ vars[key] = value;
83
+ }
84
+ return { vars, skipped };
85
+ };
86
+ /**
87
+ * Record-only view for callers that don't surface skip reasons.
88
+ * Same parse, skips dropped.
89
+ */
90
+ export const parseEnvFile = (content) => parseEnvContent(content).vars;
91
+ //# sourceMappingURL=env-parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-parse.js","sourceRoot":"","sources":["../../src/lib/env-parse.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,111 @@
1
+ import type { PushtoError, PushtoErrorFix, PushtoErrorStage } from '@pushto/shared/errors';
2
+ /**
3
+ * Exit bands. A caller that reads only $? still behaves correctly, because
4
+ * the band alone says what to do next.
5
+ */
6
+ export declare const EXIT: {
7
+ readonly OK: 0;
8
+ /** reserved for genuinely unclassified failures — never reachable from a known code */
9
+ readonly UNCLASSIFIED: 1;
10
+ readonly USAGE: 2;
11
+ readonly AUTH: 10;
12
+ readonly NOT_FOUND: 20;
13
+ readonly INVALID_INPUT: 30;
14
+ readonly BUILD_FAILED: 40;
15
+ readonly QUOTA: 50;
16
+ readonly UPSTREAM: 60;
17
+ };
18
+ /**
19
+ * The closed registry. Adding a code here is the ONLY way to add one, which
20
+ * is what stops a call site from inventing an exit number under time
21
+ * pressure — the failure mode that produced 112 identical exit(1)s.
22
+ */
23
+ export declare const CODES: {
24
+ readonly NOT_AUTHENTICATED: {
25
+ readonly band: 10;
26
+ readonly retryable: false;
27
+ };
28
+ readonly SESSION_EXPIRED: {
29
+ readonly band: 10;
30
+ readonly retryable: false;
31
+ };
32
+ readonly NO_PROJECT: {
33
+ readonly band: 20;
34
+ readonly retryable: false;
35
+ };
36
+ readonly PROJECT_NOT_FOUND: {
37
+ readonly band: 20;
38
+ readonly retryable: false;
39
+ };
40
+ readonly NO_DEPLOYMENT: {
41
+ readonly band: 20;
42
+ readonly retryable: false;
43
+ };
44
+ readonly BAD_USAGE: {
45
+ readonly band: 2;
46
+ readonly retryable: false;
47
+ };
48
+ readonly MISSING_ENTRYPOINT: {
49
+ readonly band: 30;
50
+ readonly retryable: false;
51
+ };
52
+ readonly NO_FILES: {
53
+ readonly band: 30;
54
+ readonly retryable: false;
55
+ };
56
+ readonly ARTIFACT_TOO_LARGE: {
57
+ readonly band: 30;
58
+ readonly retryable: false;
59
+ };
60
+ readonly INVALID_ENV_KEY: {
61
+ readonly band: 30;
62
+ readonly retryable: false;
63
+ };
64
+ readonly DB_ALREADY_EXISTS: {
65
+ readonly band: 30;
66
+ readonly retryable: false;
67
+ };
68
+ readonly BUILD_FAILED: {
69
+ readonly band: 40;
70
+ readonly retryable: false;
71
+ };
72
+ readonly CONTAINER_BOOT_FAILED: {
73
+ readonly band: 40;
74
+ readonly retryable: false;
75
+ };
76
+ readonly PAID_FEATURE: {
77
+ readonly band: 50;
78
+ readonly retryable: false;
79
+ };
80
+ readonly QUOTA_EXCEEDED: {
81
+ readonly band: 50;
82
+ readonly retryable: false;
83
+ };
84
+ readonly NETWORK: {
85
+ readonly band: 60;
86
+ readonly retryable: true;
87
+ };
88
+ readonly SERVER_ERROR: {
89
+ readonly band: 60;
90
+ readonly retryable: true;
91
+ };
92
+ readonly DB_PROVISION_FAILED: {
93
+ readonly band: 60;
94
+ readonly retryable: true;
95
+ };
96
+ };
97
+ export type PushtoErrorCode = keyof typeof CODES;
98
+ export declare const exitCodeFor: (code: PushtoErrorCode) => number;
99
+ export declare const isRetryable: (code: PushtoErrorCode) => boolean;
100
+ /**
101
+ * Build an error carrying the retryable bit derived from its code, so a call
102
+ * site can never disagree with the registry about whether a retry is sane.
103
+ * Optional keys are omitted rather than set to undefined, so JSON.stringify
104
+ * produces a clean payload.
105
+ */
106
+ export declare const buildError: (code: PushtoErrorCode, human: string, extra?: {
107
+ fix?: PushtoErrorFix;
108
+ stage?: PushtoErrorStage;
109
+ details?: Record<string, unknown>;
110
+ }) => PushtoError;
111
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAE3F;;;GAGG;AACH,eAAO,MAAM,IAAI;;IAEf,uFAAuF;;;;;;;;;CAS/E,CAAC;AAOX;;;;GAIG;AACH,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuB2B,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG,MAAM,OAAO,KAAK,CAAC;AAEjD,eAAO,MAAM,WAAW,GAAI,MAAM,eAAe,KAAG,MAA0B,CAAC;AAE/E,eAAO,MAAM,WAAW,GAAI,MAAM,eAAe,KAAG,OAAgC,CAAC;AAErF;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GACrB,MAAM,eAAe,EACrB,OAAO,MAAM,EACb,QAAQ;IAAE,GAAG,CAAC,EAAE,cAAc,CAAC;IAAC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,KAC5F,WAMF,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Exit bands. A caller that reads only $? still behaves correctly, because
3
+ * the band alone says what to do next.
4
+ */
5
+ export const EXIT = {
6
+ OK: 0,
7
+ /** reserved for genuinely unclassified failures — never reachable from a known code */
8
+ UNCLASSIFIED: 1,
9
+ USAGE: 2,
10
+ AUTH: 10,
11
+ NOT_FOUND: 20,
12
+ INVALID_INPUT: 30,
13
+ BUILD_FAILED: 40,
14
+ QUOTA: 50,
15
+ UPSTREAM: 60,
16
+ };
17
+ /**
18
+ * The closed registry. Adding a code here is the ONLY way to add one, which
19
+ * is what stops a call site from inventing an exit number under time
20
+ * pressure — the failure mode that produced 112 identical exit(1)s.
21
+ */
22
+ export const CODES = {
23
+ NOT_AUTHENTICATED: { band: EXIT.AUTH, retryable: false },
24
+ SESSION_EXPIRED: { band: EXIT.AUTH, retryable: false },
25
+ NO_PROJECT: { band: EXIT.NOT_FOUND, retryable: false },
26
+ PROJECT_NOT_FOUND: { band: EXIT.NOT_FOUND, retryable: false },
27
+ NO_DEPLOYMENT: { band: EXIT.NOT_FOUND, retryable: false },
28
+ BAD_USAGE: { band: EXIT.USAGE, retryable: false },
29
+ MISSING_ENTRYPOINT: { band: EXIT.INVALID_INPUT, retryable: false },
30
+ NO_FILES: { band: EXIT.INVALID_INPUT, retryable: false },
31
+ ARTIFACT_TOO_LARGE: { band: EXIT.INVALID_INPUT, retryable: false },
32
+ INVALID_ENV_KEY: { band: EXIT.INVALID_INPUT, retryable: false },
33
+ // The request was well-formed but wrong for the current state: the project
34
+ // already has a live database. Retrying identically cannot succeed, and the
35
+ // caller's move is to use the existing one, so this sits with invalid input
36
+ // rather than in the upstream/retryable band.
37
+ DB_ALREADY_EXISTS: { band: EXIT.INVALID_INPUT, retryable: false },
38
+ BUILD_FAILED: { band: EXIT.BUILD_FAILED, retryable: false },
39
+ CONTAINER_BOOT_FAILED: { band: EXIT.BUILD_FAILED, retryable: false },
40
+ PAID_FEATURE: { band: EXIT.QUOTA, retryable: false },
41
+ QUOTA_EXCEEDED: { band: EXIT.QUOTA, retryable: false },
42
+ NETWORK: { band: EXIT.UPSTREAM, retryable: true },
43
+ SERVER_ERROR: { band: EXIT.UPSTREAM, retryable: true },
44
+ DB_PROVISION_FAILED: { band: EXIT.UPSTREAM, retryable: true },
45
+ };
46
+ export const exitCodeFor = (code) => CODES[code].band;
47
+ export const isRetryable = (code) => CODES[code].retryable;
48
+ /**
49
+ * Build an error carrying the retryable bit derived from its code, so a call
50
+ * site can never disagree with the registry about whether a retry is sane.
51
+ * Optional keys are omitted rather than set to undefined, so JSON.stringify
52
+ * produces a clean payload.
53
+ */
54
+ export const buildError = (code, human, extra) => {
55
+ const err = { code, human, retryable: isRetryable(code) };
56
+ if (extra?.fix)
57
+ err.fix = extra.fix;
58
+ if (extra?.stage)
59
+ err.stage = extra.stage;
60
+ if (extra?.details)
61
+ err.details = extra.details;
62
+ return err;
63
+ };
64
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/lib/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import { type Ignore } from 'ignore';
2
+ export declare const ALWAYS_IGNORE: string[];
3
+ export declare const loadIgnoreFilter: (rootDir: string) => Ignore;
4
+ export interface WalkedFile {
5
+ /** Absolute filesystem path. */
6
+ fullPath: string;
7
+ /** Path relative to rootDir, with forward-slash separators (zip-archive style). */
8
+ archivePath: string;
9
+ /** File size in bytes. */
10
+ sizeBytes: number;
11
+ }
12
+ /**
13
+ * Walk a project directory using the same ignore semantics deploy.ts uses
14
+ * to build the deploy zip. Skips symlinks (traversal protection) and
15
+ * caps depth at 20.
16
+ *
17
+ * Both deploy.ts (zip the matched files) and doctor.ts (preview the
18
+ * matched files: count, total size, biggest) call this. If the two ever
19
+ * disagreed, doctor's "looks fine" would mismatch deploy's "exceeds limit"
20
+ * — frustrating to debug. One source = one truth.
21
+ */
22
+ export declare const walkProject: (rootDir: string) => WalkedFile[];
23
+ //# sourceMappingURL=file-walker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-walker.d.ts","sourceRoot":"","sources":["../../src/lib/file-walker.ts"],"names":[],"mappings":"AAEA,OAAe,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAY7C,eAAO,MAAM,aAAa,UA0BzB,CAAC;AAWF,eAAO,MAAM,gBAAgB,GAAI,SAAS,MAAM,KAAG,MAclD,CAAC;AAEF,MAAM,WAAW,UAAU;IACzB,gCAAgC;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,WAAW,GAAI,SAAS,MAAM,KAAG,UAAU,EAyCvD,CAAC"}