@percher/core 0.2.6 → 0.4.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 (226) hide show
  1. package/dist/ai-files-manifest.d.ts +28 -0
  2. package/dist/ai-files-manifest.d.ts.map +1 -0
  3. package/dist/ai-files-manifest.js +96 -0
  4. package/dist/ai-files-manifest.js.map +1 -0
  5. package/dist/commands/account.d.ts +51 -0
  6. package/dist/commands/account.d.ts.map +1 -0
  7. package/dist/commands/account.js +88 -0
  8. package/dist/commands/account.js.map +1 -0
  9. package/dist/commands/ai-files.d.ts +73 -0
  10. package/dist/commands/ai-files.d.ts.map +1 -0
  11. package/dist/commands/ai-files.js +179 -0
  12. package/dist/commands/ai-files.js.map +1 -0
  13. package/dist/commands/billing.d.ts +1 -1
  14. package/dist/commands/billing.d.ts.map +1 -1
  15. package/dist/commands/billing.js +1 -1
  16. package/dist/commands/billing.js.map +1 -1
  17. package/dist/commands/continue.d.ts +48 -0
  18. package/dist/commands/continue.d.ts.map +1 -0
  19. package/dist/commands/continue.js +121 -0
  20. package/dist/commands/continue.js.map +1 -0
  21. package/dist/commands/create.d.ts +1 -1
  22. package/dist/commands/create.d.ts.map +1 -1
  23. package/dist/commands/create.js +1 -1
  24. package/dist/commands/create.js.map +1 -1
  25. package/dist/commands/dashboard.d.ts +15 -0
  26. package/dist/commands/dashboard.d.ts.map +1 -0
  27. package/dist/commands/dashboard.js +33 -0
  28. package/dist/commands/dashboard.js.map +1 -0
  29. package/dist/commands/data-export.d.ts +21 -0
  30. package/dist/commands/data-export.d.ts.map +1 -0
  31. package/dist/commands/data-export.js +36 -0
  32. package/dist/commands/data-export.js.map +1 -0
  33. package/dist/commands/data.d.ts +3 -3
  34. package/dist/commands/data.d.ts.map +1 -1
  35. package/dist/commands/data.js +1 -1
  36. package/dist/commands/data.js.map +1 -1
  37. package/dist/commands/delete.d.ts +1 -1
  38. package/dist/commands/delete.d.ts.map +1 -1
  39. package/dist/commands/delete.js +1 -1
  40. package/dist/commands/delete.js.map +1 -1
  41. package/dist/commands/deploys.d.ts +2 -2
  42. package/dist/commands/deploys.d.ts.map +1 -1
  43. package/dist/commands/deploys.js +21 -5
  44. package/dist/commands/deploys.js.map +1 -1
  45. package/dist/commands/dev.d.ts +1 -9
  46. package/dist/commands/dev.d.ts.map +1 -1
  47. package/dist/commands/dev.js +79 -24
  48. package/dist/commands/dev.js.map +1 -1
  49. package/dist/commands/diagnose.d.ts +1 -1
  50. package/dist/commands/diagnose.d.ts.map +1 -1
  51. package/dist/commands/diagnose.js +1 -1
  52. package/dist/commands/diagnose.js.map +1 -1
  53. package/dist/commands/doctor.d.ts +75 -3
  54. package/dist/commands/doctor.d.ts.map +1 -1
  55. package/dist/commands/doctor.js +822 -10
  56. package/dist/commands/doctor.js.map +1 -1
  57. package/dist/commands/domains.d.ts +1 -1
  58. package/dist/commands/domains.d.ts.map +1 -1
  59. package/dist/commands/domains.js +1 -1
  60. package/dist/commands/domains.js.map +1 -1
  61. package/dist/commands/env-scan.d.ts +2 -0
  62. package/dist/commands/env-scan.d.ts.map +1 -0
  63. package/dist/commands/env-scan.js +92 -0
  64. package/dist/commands/env-scan.js.map +1 -0
  65. package/dist/commands/env.d.ts +1 -1
  66. package/dist/commands/env.d.ts.map +1 -1
  67. package/dist/commands/env.js +1 -1
  68. package/dist/commands/env.js.map +1 -1
  69. package/dist/commands/export.d.ts +1 -1
  70. package/dist/commands/export.js +1 -1
  71. package/dist/commands/generate.d.ts +1 -1
  72. package/dist/commands/generate.d.ts.map +1 -1
  73. package/dist/commands/generate.js +14 -9
  74. package/dist/commands/generate.js.map +1 -1
  75. package/dist/commands/github.d.ts +60 -0
  76. package/dist/commands/github.d.ts.map +1 -0
  77. package/dist/commands/github.js +112 -0
  78. package/dist/commands/github.js.map +1 -0
  79. package/dist/commands/import-project.d.ts +1 -1
  80. package/dist/commands/import-project.d.ts.map +1 -1
  81. package/dist/commands/import-project.js +1 -1
  82. package/dist/commands/import-project.js.map +1 -1
  83. package/dist/commands/init.d.ts +1 -1
  84. package/dist/commands/init.d.ts.map +1 -1
  85. package/dist/commands/init.js +1 -1
  86. package/dist/commands/init.js.map +1 -1
  87. package/dist/commands/insights.d.ts +1 -1
  88. package/dist/commands/insights.d.ts.map +1 -1
  89. package/dist/commands/insights.js +1 -1
  90. package/dist/commands/insights.js.map +1 -1
  91. package/dist/commands/login.d.ts +1 -1
  92. package/dist/commands/login.d.ts.map +1 -1
  93. package/dist/commands/login.js +1 -1
  94. package/dist/commands/login.js.map +1 -1
  95. package/dist/commands/logs.d.ts +1 -1
  96. package/dist/commands/logs.d.ts.map +1 -1
  97. package/dist/commands/logs.js +1 -1
  98. package/dist/commands/logs.js.map +1 -1
  99. package/dist/commands/mcp.d.ts +1 -1
  100. package/dist/commands/mcp.d.ts.map +1 -1
  101. package/dist/commands/mcp.js +1 -1
  102. package/dist/commands/mcp.js.map +1 -1
  103. package/dist/commands/open.d.ts +1 -1
  104. package/dist/commands/open.d.ts.map +1 -1
  105. package/dist/commands/open.js +1 -1
  106. package/dist/commands/open.js.map +1 -1
  107. package/dist/commands/publish-failure.d.ts +31 -0
  108. package/dist/commands/publish-failure.d.ts.map +1 -0
  109. package/dist/commands/publish-failure.js +150 -0
  110. package/dist/commands/publish-failure.js.map +1 -0
  111. package/dist/commands/publish-node.d.ts +16 -0
  112. package/dist/commands/publish-node.d.ts.map +1 -0
  113. package/dist/commands/publish-node.js +42 -0
  114. package/dist/commands/publish-node.js.map +1 -0
  115. package/dist/commands/publish.d.ts +105 -3
  116. package/dist/commands/publish.d.ts.map +1 -1
  117. package/dist/commands/publish.js +746 -158
  118. package/dist/commands/publish.js.map +1 -1
  119. package/dist/commands/push.d.ts +45 -8
  120. package/dist/commands/push.d.ts.map +1 -1
  121. package/dist/commands/push.js +233 -22
  122. package/dist/commands/push.js.map +1 -1
  123. package/dist/commands/redeploy.d.ts +28 -0
  124. package/dist/commands/redeploy.d.ts.map +1 -0
  125. package/dist/commands/redeploy.js +421 -0
  126. package/dist/commands/redeploy.js.map +1 -0
  127. package/dist/commands/rename.d.ts +1 -1
  128. package/dist/commands/rename.d.ts.map +1 -1
  129. package/dist/commands/rename.js +1 -1
  130. package/dist/commands/rename.js.map +1 -1
  131. package/dist/commands/reproduce.d.ts +64 -0
  132. package/dist/commands/reproduce.d.ts.map +1 -0
  133. package/dist/commands/reproduce.js +211 -0
  134. package/dist/commands/reproduce.js.map +1 -0
  135. package/dist/commands/reset-superuser.d.ts +1 -1
  136. package/dist/commands/reset-superuser.d.ts.map +1 -1
  137. package/dist/commands/reset-superuser.js +1 -1
  138. package/dist/commands/reset-superuser.js.map +1 -1
  139. package/dist/commands/restore.d.ts +79 -0
  140. package/dist/commands/restore.d.ts.map +1 -0
  141. package/dist/commands/restore.js +164 -0
  142. package/dist/commands/restore.js.map +1 -0
  143. package/dist/commands/resume.d.ts +1 -1
  144. package/dist/commands/resume.d.ts.map +1 -1
  145. package/dist/commands/resume.js +1 -1
  146. package/dist/commands/resume.js.map +1 -1
  147. package/dist/commands/rollback.d.ts +21 -8
  148. package/dist/commands/rollback.d.ts.map +1 -1
  149. package/dist/commands/rollback.js +12 -6
  150. package/dist/commands/rollback.js.map +1 -1
  151. package/dist/commands/status.d.ts +33 -0
  152. package/dist/commands/status.d.ts.map +1 -0
  153. package/dist/commands/status.js +48 -0
  154. package/dist/commands/status.js.map +1 -0
  155. package/dist/commands/unsuspend.d.ts +35 -0
  156. package/dist/commands/unsuspend.d.ts.map +1 -0
  157. package/dist/commands/unsuspend.js +27 -0
  158. package/dist/commands/unsuspend.js.map +1 -0
  159. package/dist/commands/versions.d.ts +1 -1
  160. package/dist/commands/versions.d.ts.map +1 -1
  161. package/dist/commands/versions.js +1 -1
  162. package/dist/commands/versions.js.map +1 -1
  163. package/dist/commands/wait-deploy.d.ts +92 -0
  164. package/dist/commands/wait-deploy.d.ts.map +1 -0
  165. package/dist/commands/wait-deploy.js +226 -0
  166. package/dist/commands/wait-deploy.js.map +1 -0
  167. package/dist/env-scan-source.d.ts +39 -0
  168. package/dist/env-scan-source.d.ts.map +1 -0
  169. package/dist/env-scan-source.js +332 -0
  170. package/dist/env-scan-source.js.map +1 -0
  171. package/dist/error-classifier.d.ts.map +1 -1
  172. package/dist/error-classifier.js +67 -4
  173. package/dist/error-classifier.js.map +1 -1
  174. package/dist/errors.d.ts +8 -1
  175. package/dist/errors.d.ts.map +1 -1
  176. package/dist/errors.js +2 -0
  177. package/dist/errors.js.map +1 -1
  178. package/dist/event-renderer.d.ts +17 -0
  179. package/dist/event-renderer.d.ts.map +1 -0
  180. package/dist/event-renderer.js +130 -0
  181. package/dist/event-renderer.js.map +1 -0
  182. package/dist/index.d.ts +16 -1
  183. package/dist/index.d.ts.map +1 -1
  184. package/dist/index.js +15 -0
  185. package/dist/index.js.map +1 -1
  186. package/dist/plans.d.ts +20 -0
  187. package/dist/plans.d.ts.map +1 -1
  188. package/dist/plans.js +15 -0
  189. package/dist/plans.js.map +1 -1
  190. package/dist/poll-deployment.d.ts +59 -0
  191. package/dist/poll-deployment.d.ts.map +1 -0
  192. package/dist/poll-deployment.js +93 -0
  193. package/dist/poll-deployment.js.map +1 -0
  194. package/dist/publish-retry.d.ts +29 -0
  195. package/dist/publish-retry.d.ts.map +1 -0
  196. package/dist/publish-retry.js +224 -0
  197. package/dist/publish-retry.js.map +1 -0
  198. package/dist/recovery.d.ts +356 -0
  199. package/dist/recovery.d.ts.map +1 -0
  200. package/dist/recovery.js +300 -0
  201. package/dist/recovery.js.map +1 -0
  202. package/dist/stream-utils.d.ts +21 -0
  203. package/dist/stream-utils.d.ts.map +1 -0
  204. package/dist/stream-utils.js +41 -0
  205. package/dist/stream-utils.js.map +1 -0
  206. package/dist/structured-error-codes.d.ts +30 -0
  207. package/dist/structured-error-codes.d.ts.map +1 -0
  208. package/dist/structured-error-codes.js +86 -0
  209. package/dist/structured-error-codes.js.map +1 -0
  210. package/dist/tarball.d.ts +11 -0
  211. package/dist/tarball.d.ts.map +1 -1
  212. package/dist/tarball.js +30 -9
  213. package/dist/tarball.js.map +1 -1
  214. package/dist/templates/ai-files/claude-md.d.ts +7 -0
  215. package/dist/templates/ai-files/claude-md.d.ts.map +1 -0
  216. package/dist/templates/ai-files/claude-md.js +78 -0
  217. package/dist/templates/ai-files/claude-md.js.map +1 -0
  218. package/dist/templates/ai-files/cursor-percher-mdc.d.ts +7 -0
  219. package/dist/templates/ai-files/cursor-percher-mdc.d.ts.map +1 -0
  220. package/dist/templates/ai-files/cursor-percher-mdc.js +111 -0
  221. package/dist/templates/ai-files/cursor-percher-mdc.js.map +1 -0
  222. package/dist/templates/ai-files/index.d.ts +8 -0
  223. package/dist/templates/ai-files/index.d.ts.map +1 -0
  224. package/dist/templates/ai-files/index.js +4 -0
  225. package/dist/templates/ai-files/index.js.map +1 -0
  226. package/package.json +6 -5
@@ -0,0 +1,332 @@
1
+ import { readFile, readdir, stat } from "node:fs/promises";
2
+ import { join, relative, sep } from "node:path";
3
+ /**
4
+ * Directories never scanned. Mirrors (a superset of) the tarball builder's
5
+ * exclude list — these dirs should never appear in a legit upload, but a
6
+ * defensive check is cheap.
7
+ */
8
+ const DEFAULT_EXCLUDE = new Set([
9
+ "node_modules",
10
+ ".git",
11
+ ".bun",
12
+ "dist",
13
+ "build",
14
+ ".next",
15
+ ".svelte-kit",
16
+ "coverage",
17
+ ".cache",
18
+ ".turbo",
19
+ ]);
20
+ /**
21
+ * Source extensions scanned. JS/TS family + popular SFCs + Python.
22
+ * HTML and other markup are not scanned — false positives outweigh the
23
+ * occasional inline-script env reference.
24
+ */
25
+ const SOURCE_EXTS = new Set([
26
+ ".js",
27
+ ".jsx",
28
+ ".ts",
29
+ ".tsx",
30
+ ".mjs",
31
+ ".cjs",
32
+ ".svelte",
33
+ ".vue",
34
+ ".astro",
35
+ ".py",
36
+ ]);
37
+ const DEFAULT_MAX_FILE_BYTES = 1024 * 1024;
38
+ /**
39
+ * Static patterns. Each pattern's first capture group (or first non-empty
40
+ * group, for the multi-quote alternation patterns) is the literal env key.
41
+ *
42
+ * Env-key shape inside the patterns: `[A-Za-z_][A-Za-z0-9_]*` — standard
43
+ * POSIX-ish identifier. Permissive on case to keep false negatives low; the
44
+ * Phase 6c gate enforces `UPPER_SNAKE_CASE` against the `[env]` contract.
45
+ *
46
+ * Word-boundary discipline:
47
+ * - `(?<![A-Za-z0-9_$])` (negative lookbehind) prevents `myprocess.env.KEY`
48
+ * or `xprocess.env.KEY` from matching.
49
+ * - The class includes `$` because JS identifiers can contain `$`.
50
+ * - For dot access, `(?![A-Za-z0-9_])` after the key prevents trailing-name
51
+ * confusion (defence in depth — the captured group is greedy on
52
+ * identifier chars so this is mostly belt-and-braces).
53
+ */
54
+ const STATIC_PATTERNS = [
55
+ // process.env.KEY | Bun.env.KEY | import.meta.env.KEY
56
+ /(?<![A-Za-z0-9_$])(?:process\.env|Bun\.env|import\.meta\.env)\.([A-Za-z_][A-Za-z0-9_]*)(?![A-Za-z0-9_])/g,
57
+ // process.env["KEY"] | process.env['KEY'] | Bun.env["KEY"] | Bun.env['KEY']
58
+ /(?<![A-Za-z0-9_$])(?:process\.env|Bun\.env)\[\s*(?:"([A-Za-z_][A-Za-z0-9_]*)"|'([A-Za-z_][A-Za-z0-9_]*)')\s*\]/g,
59
+ // Deno.env.get("KEY") | Deno.env.get('KEY')
60
+ /(?<![A-Za-z0-9_$])Deno\.env\.get\(\s*(?:"([A-Za-z_][A-Za-z0-9_]*)"|'([A-Za-z_][A-Za-z0-9_]*)')\s*\)/g,
61
+ // Python: os.environ.get("KEY") | os.environ.get('KEY')
62
+ // os.getenv("KEY") | os.getenv('KEY')
63
+ /(?<![A-Za-z0-9_])os\.(?:environ\.get|getenv)\(\s*(?:"([A-Za-z_][A-Za-z0-9_]*)"|'([A-Za-z_][A-Za-z0-9_]*)')\s*[,)]/g,
64
+ // Python: os.environ["KEY"] | os.environ['KEY']
65
+ /(?<![A-Za-z0-9_])os\.environ\[\s*(?:"([A-Za-z_][A-Za-z0-9_]*)"|'([A-Za-z_][A-Za-z0-9_]*)')\s*\]/g,
66
+ ];
67
+ /**
68
+ * Dynamic patterns — bracketed access where the argument is NOT a string
69
+ * literal. These are reported as advisory (`shape: "dynamic"`, `key: ""`).
70
+ *
71
+ * Heuristic: match the bracket form, then check the inside isn't a
72
+ * single-quoted or double-quoted string literal. We over-detect rather than
73
+ * under-detect here — Phase 6c surfaces these to users without blocking.
74
+ */
75
+ const DYNAMIC_PATTERNS = [
76
+ // process.env[<expr>] | Bun.env[<expr>]
77
+ { re: /(?<![A-Za-z0-9_$])(?:process\.env|Bun\.env)\[\s*([^\]]+?)\s*\]/g, argGroup: 1 },
78
+ // Deno.env.get(<expr>)
79
+ { re: /(?<![A-Za-z0-9_$])Deno\.env\.get\(\s*([^)]+?)\s*\)/g, argGroup: 1 },
80
+ // Python: os.environ[<expr>]
81
+ { re: /(?<![A-Za-z0-9_])os\.environ\[\s*([^\]]+?)\s*\]/g, argGroup: 1 },
82
+ // Python: os.environ.get(<expr>) | os.getenv(<expr>)
83
+ { re: /(?<![A-Za-z0-9_])os\.(?:environ\.get|getenv)\(\s*([^,)]+?)\s*[,)]/g, argGroup: 1 },
84
+ ];
85
+ /**
86
+ * True iff the bracket/argument expression is a plain quoted string literal
87
+ * with no interpolation. Backtick template literals containing `${...}` are
88
+ * NOT string literals here — they're dynamic. Plain backtick strings (no
89
+ * interpolation) are not flagged as static either, because the static
90
+ * patterns above only recognize `"..."` and `'...'`; treating them as
91
+ * "already static" would silently drop them. We restrict this check to
92
+ * `"..."` and `'...'` to keep static and dynamic detection in lockstep.
93
+ */
94
+ function isStringLiteralArg(arg) {
95
+ const trimmed = arg.trim();
96
+ if (trimmed.length < 2)
97
+ return false;
98
+ const first = trimmed.charCodeAt(0);
99
+ const last = trimmed.charCodeAt(trimmed.length - 1);
100
+ if (first !== last)
101
+ return false;
102
+ // 0x22 = " 0x27 = '
103
+ if (first !== 0x22 && first !== 0x27)
104
+ return false;
105
+ // Must not contain an unescaped same-quote in the middle (would mean two
106
+ // separate strings concatenated by some operator → that's dynamic).
107
+ for (let i = 1; i < trimmed.length - 1; i++) {
108
+ if (trimmed.charCodeAt(i) === first && trimmed.charCodeAt(i - 1) !== 0x5c) {
109
+ return false;
110
+ }
111
+ }
112
+ return true;
113
+ }
114
+ /**
115
+ * Strips `/* ... *​/` block comments from a source string, preserving line
116
+ * count by replacing comment characters with spaces (newlines kept). Best-
117
+ * effort — does not understand strings or template literals, so a `/*`
118
+ * embedded in a string literal will start a "comment". This produces false
119
+ * negatives (skipped real refs), which the spec prefers over false positives.
120
+ */
121
+ function stripBlockComments(src) {
122
+ let out = "";
123
+ let i = 0;
124
+ let inBlock = false;
125
+ while (i < src.length) {
126
+ const ch = src[i];
127
+ if (!inBlock && ch === "/" && src[i + 1] === "*") {
128
+ inBlock = true;
129
+ out += " ";
130
+ i += 2;
131
+ continue;
132
+ }
133
+ if (inBlock && ch === "*" && src[i + 1] === "/") {
134
+ inBlock = false;
135
+ out += " ";
136
+ i += 2;
137
+ continue;
138
+ }
139
+ if (inBlock) {
140
+ out += ch === "\n" ? "\n" : " ";
141
+ i += 1;
142
+ continue;
143
+ }
144
+ out += ch;
145
+ i += 1;
146
+ }
147
+ return out;
148
+ }
149
+ /**
150
+ * Returns the line stripped of trailing single-line comments. Honors `//`
151
+ * (JS/TS family) and `#` (Python). For JS, a negative lookbehind keeps URL
152
+ * protocols (`https://`) intact.
153
+ */
154
+ function stripLineComment(line, isPython) {
155
+ if (isPython) {
156
+ // Strip from the first `#` not inside a quote. Conservative: cut at the
157
+ // first `#` that has no `'` or `"` before it on this line, OR has equal
158
+ // counts. For our purposes (refs only matter before any `#`), this is
159
+ // enough: if a `#` precedes the env-ref pattern in a string, the line
160
+ // is exotic and falls under "prefer false negatives".
161
+ const idx = line.indexOf("#");
162
+ if (idx === -1)
163
+ return line;
164
+ return line.slice(0, idx);
165
+ }
166
+ // JS: strip `//comment` unless the `//` is preceded by `:` (URL). Iterate
167
+ // to handle multiple // candidates.
168
+ let off = 0;
169
+ while (true) {
170
+ const idx = line.indexOf("//", off);
171
+ if (idx === -1)
172
+ return line;
173
+ if (idx > 0 && line[idx - 1] === ":") {
174
+ off = idx + 2;
175
+ continue;
176
+ }
177
+ return line.slice(0, idx);
178
+ }
179
+ }
180
+ /** True iff a line is a pure comment (after leading whitespace). */
181
+ function isPureCommentLine(line, isPython) {
182
+ const trimmed = line.trimStart();
183
+ if (trimmed.length === 0)
184
+ return false;
185
+ if (isPython)
186
+ return trimmed.startsWith("#");
187
+ // `//` line comment, `*` JSDoc continuation, or `/*` start (block already
188
+ // stripped at file level — this catches single-line `/* ... */` survivors
189
+ // that mid-line stripping left behind, plus the leading-`*` JSDoc style).
190
+ return trimmed.startsWith("//") || trimmed.startsWith("*") || trimmed.startsWith("/*");
191
+ }
192
+ /**
193
+ * Extract env references from a single file's source.
194
+ *
195
+ * Pure function — exposed for tests but not exported from the package.
196
+ */
197
+ function extractFromSource(source, relPath, isPython) {
198
+ const refs = [];
199
+ const seen = new Set(); // key|line — line-level dedup
200
+ const stripped = isPython ? source : stripBlockComments(source);
201
+ const lines = stripped.split(/\r?\n/);
202
+ for (let i = 0; i < lines.length; i++) {
203
+ const raw = lines[i];
204
+ if (raw === undefined)
205
+ continue;
206
+ if (isPureCommentLine(raw, isPython))
207
+ continue;
208
+ const code = stripLineComment(raw, isPython);
209
+ if (code.length === 0)
210
+ continue;
211
+ const lineNo = i + 1;
212
+ const context = raw.trim();
213
+ // Static refs first — they take precedence over dynamic detection on the
214
+ // same span (a static `process.env["KEY"]` would also match the dynamic
215
+ // bracket pattern, so we record the static keys and let dynamic skip
216
+ // arguments that are string literals).
217
+ for (const re of STATIC_PATTERNS) {
218
+ re.lastIndex = 0;
219
+ let m;
220
+ // biome-ignore lint/suspicious/noAssignInExpressions: standard regex exec loop
221
+ while ((m = re.exec(code)) !== null) {
222
+ // The literal key is in whichever capture group fired.
223
+ let key = "";
224
+ for (let g = 1; g < m.length; g++) {
225
+ if (m[g]) {
226
+ key = m[g];
227
+ break;
228
+ }
229
+ }
230
+ if (!key)
231
+ continue;
232
+ const dedup = `s|${key}|${lineNo}`;
233
+ if (seen.has(dedup))
234
+ continue;
235
+ seen.add(dedup);
236
+ refs.push({
237
+ key,
238
+ file: relPath,
239
+ line: lineNo,
240
+ context,
241
+ shape: "static",
242
+ });
243
+ }
244
+ }
245
+ for (const { re, argGroup } of DYNAMIC_PATTERNS) {
246
+ re.lastIndex = 0;
247
+ let m;
248
+ // biome-ignore lint/suspicious/noAssignInExpressions: standard regex exec loop
249
+ while ((m = re.exec(code)) !== null) {
250
+ const arg = m[argGroup];
251
+ if (arg === undefined)
252
+ continue;
253
+ if (isStringLiteralArg(arg))
254
+ continue; // already counted as static
255
+ const dedup = `d|${lineNo}|${m.index}`;
256
+ if (seen.has(dedup))
257
+ continue;
258
+ seen.add(dedup);
259
+ refs.push({
260
+ key: "",
261
+ file: relPath,
262
+ line: lineNo,
263
+ context,
264
+ shape: "dynamic",
265
+ });
266
+ }
267
+ }
268
+ }
269
+ return refs;
270
+ }
271
+ /**
272
+ * Recursively scans `rootDir` for env references in supported source files.
273
+ *
274
+ * Read-only: never modifies the source tree. Tolerant of unreadable files and
275
+ * directories — they are skipped silently. Files exceeding `maxFileBytes` are
276
+ * skipped to bound runtime on pathological inputs (minified bundles, etc.).
277
+ */
278
+ export async function scanSourceForEnvRefs(rootDir, opts) {
279
+ const maxBytes = opts?.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES;
280
+ const extraExclude = new Set(opts?.exclude ?? []);
281
+ const refs = [];
282
+ async function walk(dir) {
283
+ let entries;
284
+ try {
285
+ entries = await readdir(dir);
286
+ }
287
+ catch {
288
+ return;
289
+ }
290
+ for (const name of entries) {
291
+ if (DEFAULT_EXCLUDE.has(name))
292
+ continue;
293
+ const full = join(dir, name);
294
+ const rel = relative(rootDir, full).split(sep).join("/");
295
+ if (extraExclude.has(rel) || extraExclude.has(name))
296
+ continue;
297
+ let st;
298
+ try {
299
+ st = await stat(full);
300
+ }
301
+ catch {
302
+ continue;
303
+ }
304
+ if (st.isDirectory()) {
305
+ await walk(full);
306
+ continue;
307
+ }
308
+ if (!st.isFile())
309
+ continue;
310
+ const dotIdx = name.lastIndexOf(".");
311
+ const ext = dotIdx === -1 ? "" : name.slice(dotIdx).toLowerCase();
312
+ if (!SOURCE_EXTS.has(ext))
313
+ continue;
314
+ if (st.size > maxBytes)
315
+ continue;
316
+ let content;
317
+ try {
318
+ content = await readFile(full, "utf8");
319
+ }
320
+ catch {
321
+ continue;
322
+ }
323
+ const isPython = ext === ".py";
324
+ for (const ref of extractFromSource(content, rel, isPython)) {
325
+ refs.push(ref);
326
+ }
327
+ }
328
+ }
329
+ await walk(rootDir);
330
+ return refs;
331
+ }
332
+ //# sourceMappingURL=env-scan-source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-scan-source.js","sourceRoot":"","sources":["../src/env-scan-source.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"error-classifier.d.ts","sourceRoot":"","sources":["../src/error-classifier.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,cAAc,GACd,sBAAsB,GACtB,eAAe,GACf,aAAa,GACb,YAAY,GACZ,mBAAmB,GACnB,eAAe,GACf,gBAAgB,GAChB,oBAAoB,GACpB,mBAAmB,CAAC;AAExB,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO,GAAG,cAAc,GAAG,QAAQ,GAAG,OAAO,CAAC;AAElF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,UAAU,EAAE,UAAU,CAAC;IACvB,4CAA4C;IAC5C,KAAK,EAAE,WAAW,CAAC;IACnB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AA4OD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA2B7F"}
1
+ {"version":3,"file":"error-classifier.d.ts","sourceRoot":"","sources":["../src/error-classifier.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAClB,cAAc,GACd,sBAAsB,GACtB,eAAe,GACf,aAAa,GACb,YAAY,GACZ,mBAAmB,GACnB,eAAe,GACf,gBAAgB,GAChB,oBAAoB,GACpB,mBAAmB,CAAC;AAExB,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO,GAAG,cAAc,GAAG,QAAQ,GAAG,OAAO,CAAC;AAElF,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,UAAU,EAAE,UAAU,CAAC;IACvB,4CAA4C;IAC5C,KAAK,EAAE,WAAW,CAAC;IACnB,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAiTD;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CA2B7F"}
@@ -14,19 +14,56 @@ function extractModuleFromLog(combined) {
14
14
  return match?.[1];
15
15
  }
16
16
  const patterns = [
17
+ {
18
+ // Phase 3 publish-resilience plan: deploys that the platform abandoned
19
+ // mid-flight. The API's deploy-reconciler stamps rows stuck in
20
+ // queued/building/deploying past the timeout with the literal token
21
+ // `DEPLOY_STALLED:` so the CLI can render a concrete "the platform
22
+ // dropped this deploy; retry once" message instead of leaving the
23
+ // user staring at the raw reconciler text. The token is the contract
24
+ // — keep it in lockstep with `DEPLOY_STALLED_PREFIX` in
25
+ // `packages/api/src/services/deploy-reconciler.ts`.
26
+ //
27
+ // This pattern lives FIRST so it wins over the generic infra match
28
+ // below (a stalled deploy is also "infra-ish", but the action is
29
+ // different — for infra we say "wait, retry"; for stalled we say
30
+ // "the platform abandoned this one, retry once and it'll go through").
31
+ pattern: /DEPLOY_STALLED:/,
32
+ result: {
33
+ title: "Deploy abandoned by the platform",
34
+ explanation: "The platform stopped tracking this deploy mid-flight — usually because the build worker or API process restarted between accepting the deploy and writing its outcome. Your code is fine; this deploy never reached a terminal state on its own and was auto-failed by the watchdog.",
35
+ suggestion: "Retry once with `bunx percher publish`. A single retry almost always lands a clean deploy — if it stalls again, check status.percher.app or contact support; that's a sign of an ongoing platform incident, not your app.",
36
+ errorClass: "infra_unavailable",
37
+ phase: "infra",
38
+ cause: "deploy_stalled",
39
+ relevantFiles: [],
40
+ missingEnvVars: [],
41
+ },
42
+ },
17
43
  {
18
44
  // Pre-build / infra-side failures: the build never actually started, so
19
45
  // the build log is empty and the user is left with "deployment failed,
20
46
  // see the log below" pointing at nothing. Match the symptoms reported
21
47
  // in the field — nixpacks unable to fetch from cache.nixos.org, the
22
- // worker daemon being unreachable, raw fetch failures from RemoteDeployer.
48
+ // worker daemon being unreachable, raw fetch failures from RemoteDeployer,
49
+ // bun fetch's generic socket-close which surfaces as
50
+ // "The socket connection was closed unexpectedly" when api->worker
51
+ // disconnects mid-deploy (observed live 2026-04-29 during platform
52
+ // self-deploy rollback cycles).
53
+ //
23
54
  // Order matters: this MUST come before the runtime ECONNREFUSED match
24
55
  // below, which talks about *the deployed app* failing to dial out.
25
- pattern: /Unable to connect.*?(access the url|cache\.nixos)|Could not resolve host|getaddrinfo ENOTFOUND|Worker \/[\w-]+(\/[\w-]+)? failed \(50\d\)|Failed to fetch.*?worker|deployer\/(run|build) failed/i,
56
+ pattern: /Unable to connect.*?(access the url|cache\.nixos)|Could not resolve host|getaddrinfo ENOTFOUND|Worker \/[\w-]+(\/[\w-]+)? failed \(50\d\)|Failed to fetch.*?worker|deployer\/(run|build) failed|The socket connection was closed unexpectedly|WORKER_UNAVAILABLE(_PERSISTENT)?:/i,
26
57
  result: {
27
58
  title: "Build infrastructure unavailable",
28
- explanation: "The Percher build server couldn't reach an upstream service it needs (Nix cache, worker daemon, or registry). This is a platform-side problem, not your app code.",
29
- suggestion: "Wait 30–60 seconds and run percher publish again. If it still fails, check status.percher.app or contact support — your code is fine, the build never started.",
59
+ explanation: "The Percher build server couldn't reach an upstream service it needs (Nix cache, worker daemon, or registry). This is a platform-side problem, not your app code. These failures are usually transient and clear within 1–2 minutes.",
60
+ // Agent-DX guidance: a buggy retry policy is what bit us live on
61
+ // 2026-04-29 — an agent made 7 attempts in 12 minutes, all during
62
+ // a partial-platform outage, then gave up ~10 minutes before the
63
+ // platform recovered. Spell out the cadence so the next agent
64
+ // backs off properly instead of burning retries during the
65
+ // outage window.
66
+ suggestion: "Wait 30 seconds and run percher publish again. If retry #2 also fails, pause 5 minutes before the next attempt — back-to-back retries during a partial outage just waste your time. After 3 spaced-out retries, check status.percher.app or contact support. Your code is fine; the build never started.",
30
67
  errorClass: "infra_unavailable",
31
68
  phase: "infra",
32
69
  cause: "upstream_unreachable",
@@ -47,6 +84,32 @@ const patterns = [
47
84
  missingEnvVars: [],
48
85
  },
49
86
  },
87
+ {
88
+ pattern: /Build timed out after \d+s|exit code 124/i,
89
+ result: {
90
+ title: "Build timed out",
91
+ explanation: "The build ran for too long and was stopped.",
92
+ suggestion: "Check the partial build log above for the last step that ran. Heavy dependency installs sometimes time out on first deploy — retrying once usually hits the build layer cache and completes in seconds.",
93
+ errorClass: "build_failed",
94
+ phase: "build",
95
+ cause: "build_timeout",
96
+ relevantFiles: [],
97
+ missingEnvVars: [],
98
+ },
99
+ },
100
+ {
101
+ pattern: /(?:bun|node|npm|yarn|pnpm)(?:\.exe)?: (?:not found|command not found)|no such file or directory.*(?:\/(?:usr\/(?:local\/)?bin\/)?(?:bun|node|npm|yarn|pnpm))|exec .*(?:bun|node|npm|yarn|pnpm).*not found/i,
102
+ result: {
103
+ title: "Start command not found",
104
+ explanation: "The container's start command could not be found. Your start script likely references a runtime that is not installed in the image.",
105
+ suggestion: 'If your start script uses bun, add \'runtime = "bun"\' to your [app] block in percher.toml. If it uses node, verify the start script in package.json uses "node" (not "bun" or "ts-node"). Then publish again.',
106
+ errorClass: "runtime_crash",
107
+ phase: "start",
108
+ cause: "command_not_found",
109
+ relevantFiles: ["percher.toml", "package.json"],
110
+ missingEnvVars: [],
111
+ },
112
+ },
50
113
  {
51
114
  pattern: /healthcheck failed|health check failed/i,
52
115
  result: {
@@ -1 +1 @@
1
- {"version":3,"file":"error-classifier.js","sourceRoot":"","sources":["../src/error-classifier.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"error-classifier.js","sourceRoot":"","sources":["../src/error-classifier.ts"],"names":[],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -1,12 +1,19 @@
1
- export type PercherCoreErrorCode = "init.exists" | "push.no-config-generated" | "push.cancelled" | "push.placeholder-env" | "push.too-large" | "push.suspicious" | "push.deploy-failed" | "push.deploy-timeout" | "logs.no-app" | "env.no-app" | "open.no-app" | "login.expired" | "login.rejected" | "doctor.no-app" | "doctor.api-unreachable" | "dev.no-app" | "data.no-app" | "create.invalid-template" | "create.dir-not-empty" | "create.failed" | "delete.confirmation-required" | "diagnose.no-app" | "insights.no-app" | "billing.checkout-failed" | "billing.portal-failed" | "deploys.no-app" | "deploys.no-id" | "deploys.no-failed";
1
+ export type PercherCoreErrorCode = "init.exists" | "push.no-config-generated" | "push.cancelled" | "push.placeholder-env" | "push.too-large" | "push.suspicious" | "push.deploy-failed" | "push.deploy-timeout" | "push.quota-exceeded" | "push.already-in-progress" | "push.retry-limit-reached" | "logs.no-app" | "env.no-app" | "open.no-app" | "login.expired" | "login.rejected" | "doctor.no-app" | "doctor.api-unreachable" | "dev.no-app" | "data.no-app" | "create.invalid-template" | "create.dir-not-empty" | "create.failed" | "delete.confirmation-required" | "delete.acknowledgement-mismatch" | "account.delete.confirmation-required" | "diagnose.no-app" | "insights.no-app" | "billing.checkout-failed" | "billing.portal-failed" | "deploys.no-app" | "deploys.no-id" | "deploys.no-failed" | "restore.source-not-found" | "restore.timeout" | "restore.failed" | "restore.rolled-back" | "data-export.no-app" | "dashboard.no-app" | "dashboard.invalid-tab";
2
2
  export interface PercherCoreErrorOptions {
3
3
  code: PercherCoreErrorCode;
4
4
  hint?: string;
5
5
  cause?: unknown;
6
+ /**
7
+ * Optional machine-readable next-step for AI agents. Same shape as
8
+ * `PublishResult.recovery`. Imported lazily as `Record<string, unknown>` to
9
+ * keep `errors.ts` free of cross-module dependencies.
10
+ */
11
+ recovery?: Record<string, unknown>;
6
12
  }
7
13
  export declare class PercherCoreError extends Error {
8
14
  readonly code: PercherCoreErrorCode;
9
15
  readonly hint?: string;
16
+ readonly recovery?: Record<string, unknown>;
10
17
  constructor(message: string, options: PercherCoreErrorOptions);
11
18
  }
12
19
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B,aAAa,GACb,0BAA0B,GAC1B,gBAAgB,GAChB,sBAAsB,GACtB,gBAAgB,GAChB,iBAAiB,GACjB,oBAAoB,GACpB,qBAAqB,GACrB,aAAa,GACb,YAAY,GACZ,aAAa,GACb,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,wBAAwB,GACxB,YAAY,GACZ,aAAa,GACb,yBAAyB,GACzB,sBAAsB,GACtB,eAAe,GACf,8BAA8B,GAC9B,iBAAiB,GACjB,iBAAiB,GACjB,yBAAyB,GACzB,uBAAuB,GACvB,gBAAgB,GAChB,eAAe,GACf,mBAAmB,CAAC;AAExB,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEX,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB;CAM9D"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,oBAAoB,GAC5B,aAAa,GACb,0BAA0B,GAC1B,gBAAgB,GAChB,sBAAsB,GACtB,gBAAgB,GAChB,iBAAiB,GACjB,oBAAoB,GACpB,qBAAqB,GACrB,qBAAqB,GACrB,0BAA0B,GAC1B,0BAA0B,GAC1B,aAAa,GACb,YAAY,GACZ,aAAa,GACb,eAAe,GACf,gBAAgB,GAChB,eAAe,GACf,wBAAwB,GACxB,YAAY,GACZ,aAAa,GACb,yBAAyB,GACzB,sBAAsB,GACtB,eAAe,GACf,8BAA8B,GAC9B,iCAAiC,GACjC,sCAAsC,GACtC,iBAAiB,GACjB,iBAAiB,GACjB,yBAAyB,GACzB,uBAAuB,GACvB,gBAAgB,GAChB,eAAe,GACf,mBAAmB,GACnB,0BAA0B,GAC1B,iBAAiB,GACjB,gBAAgB,GAChB,qBAAqB,GACrB,oBAAoB,GACpB,kBAAkB,GAClB,uBAAuB,CAAC;AAE5B,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,IAAI,EAAE,oBAAoB,CAAC;IACpC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBAEhC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB;CAO9D"}
package/dist/errors.js CHANGED
@@ -1,11 +1,13 @@
1
1
  export class PercherCoreError extends Error {
2
2
  code;
3
3
  hint;
4
+ recovery;
4
5
  constructor(message, options) {
5
6
  super(message, { cause: options.cause });
6
7
  this.name = "PercherCoreError";
7
8
  this.code = options.code;
8
9
  this.hint = options.hint;
10
+ this.recovery = options.recovery;
9
11
  }
10
12
  }
11
13
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAoCA,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,CAAuB;IAC3B,IAAI,CAAU;IAEvB,YAAY,OAAe,EAAE,OAAgC;QAC3D,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC3B,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAsDA,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,IAAI,CAAuB;IAC3B,IAAI,CAAU;IACd,QAAQ,CAA2B;IAE5C,YAAY,OAAe,EAAE,OAAgC;QAC3D,KAAK,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAC;QAC/B,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;QACzB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IACnC,CAAC;CACF"}
@@ -0,0 +1,17 @@
1
+ import type { DeployEvent } from "@percher/client";
2
+ /**
3
+ * Convert a DeployEvent row into a single line of CLI/MCP progress
4
+ * output. Returns `null` for rows that are intentionally hidden (e.g.
5
+ * `done/ok`, where the caller prints the final "live at <url>" line
6
+ * with full URL context the events table doesn't carry).
7
+ *
8
+ * The mapping is deliberately conservative: every line is short,
9
+ * past-tense for terminal `ok` rows, present-continuous for
10
+ * `started` rows. Sub-stage durations are appended in parens when
11
+ * available so the user sees real timings (`Image built (8.1s)`)
12
+ * instead of guessing whether the build is making progress.
13
+ *
14
+ * Phase 6.1 of the publish-resilience plan.
15
+ */
16
+ export declare function renderDeployEvent(event: DeployEvent): string | null;
17
+ //# sourceMappingURL=event-renderer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"event-renderer.d.ts","sourceRoot":"","sources":["../src/event-renderer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAEnD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,GAAG,IAAI,CA4CnE"}