runwork 0.15.0 → 0.15.2

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 (403) hide show
  1. package/dist/index.js +19272 -116
  2. package/package.json +4 -4
  3. package/dist/__tests__/curl-parser.test.d.ts +0 -1
  4. package/dist/__tests__/curl-parser.test.js +0 -250
  5. package/dist/__tests__/install-scripts.test.d.ts +0 -1
  6. package/dist/__tests__/install-scripts.test.js +0 -280
  7. package/dist/__tests__/types-manager.test.d.ts +0 -1
  8. package/dist/__tests__/types-manager.test.js +0 -89
  9. package/dist/agents/__tests__/chatgpt-registry.test.d.ts +0 -1
  10. package/dist/agents/__tests__/chatgpt-registry.test.js +0 -61
  11. package/dist/agents/__tests__/claude-code-managed-block.test.d.ts +0 -1
  12. package/dist/agents/__tests__/claude-code-managed-block.test.js +0 -97
  13. package/dist/agents/__tests__/claude-code-plugin.test.d.ts +0 -1
  14. package/dist/agents/__tests__/claude-code-plugin.test.js +0 -47
  15. package/dist/agents/__tests__/claude-code-stats.test.d.ts +0 -1
  16. package/dist/agents/__tests__/claude-code-stats.test.js +0 -390
  17. package/dist/agents/__tests__/claude-desktop-memory.test.d.ts +0 -1
  18. package/dist/agents/__tests__/claude-desktop-memory.test.js +0 -154
  19. package/dist/agents/__tests__/claude-desktop-plugin-tree.test.d.ts +0 -1
  20. package/dist/agents/__tests__/claude-desktop-plugin-tree.test.js +0 -161
  21. package/dist/agents/__tests__/claude-desktop-plugin.test.d.ts +0 -1
  22. package/dist/agents/__tests__/claude-desktop-plugin.test.js +0 -117
  23. package/dist/agents/__tests__/claude-desktop-rpm.test.d.ts +0 -1
  24. package/dist/agents/__tests__/claude-desktop-rpm.test.js +0 -126
  25. package/dist/agents/__tests__/claude-desktop-stats.test.d.ts +0 -1
  26. package/dist/agents/__tests__/claude-desktop-stats.test.js +0 -280
  27. package/dist/agents/__tests__/codex-instructions.test.d.ts +0 -1
  28. package/dist/agents/__tests__/codex-instructions.test.js +0 -57
  29. package/dist/agents/__tests__/codex-minimum-permissions.test.d.ts +0 -1
  30. package/dist/agents/__tests__/codex-minimum-permissions.test.js +0 -82
  31. package/dist/agents/__tests__/codex-stats.test.d.ts +0 -1
  32. package/dist/agents/__tests__/codex-stats.test.js +0 -370
  33. package/dist/agents/__tests__/cursor-merge.test.d.ts +0 -1
  34. package/dist/agents/__tests__/cursor-merge.test.js +0 -66
  35. package/dist/agents/__tests__/cursor-stats.test.d.ts +0 -1
  36. package/dist/agents/__tests__/cursor-stats.test.js +0 -183
  37. package/dist/agents/__tests__/defaults-merge.test.d.ts +0 -1
  38. package/dist/agents/__tests__/defaults-merge.test.js +0 -268
  39. package/dist/agents/__tests__/detection.test.d.ts +0 -1
  40. package/dist/agents/__tests__/detection.test.js +0 -89
  41. package/dist/agents/__tests__/graceful-degradation.test.d.ts +0 -1
  42. package/dist/agents/__tests__/graceful-degradation.test.js +0 -129
  43. package/dist/agents/__tests__/instruction-hint.test.d.ts +0 -1
  44. package/dist/agents/__tests__/instruction-hint.test.js +0 -69
  45. package/dist/agents/__tests__/intro-skill.test.d.ts +0 -1
  46. package/dist/agents/__tests__/intro-skill.test.js +0 -193
  47. package/dist/agents/__tests__/schema-validation.test.d.ts +0 -1
  48. package/dist/agents/__tests__/schema-validation.test.js +0 -212
  49. package/dist/agents/__tests__/skill-slug.test.d.ts +0 -1
  50. package/dist/agents/__tests__/skill-slug.test.js +0 -77
  51. package/dist/agents/claude-code.d.ts +0 -53
  52. package/dist/agents/claude-code.js +0 -754
  53. package/dist/agents/claude-desktop-plugin-tree.d.ts +0 -59
  54. package/dist/agents/claude-desktop-plugin-tree.js +0 -143
  55. package/dist/agents/claude-desktop.d.ts +0 -47
  56. package/dist/agents/claude-desktop.js +0 -684
  57. package/dist/agents/cline.d.ts +0 -15
  58. package/dist/agents/cline.js +0 -130
  59. package/dist/agents/codex.d.ts +0 -44
  60. package/dist/agents/codex.js +0 -453
  61. package/dist/agents/conversation-skills.d.ts +0 -18
  62. package/dist/agents/conversation-skills.js +0 -229
  63. package/dist/agents/cursor.d.ts +0 -48
  64. package/dist/agents/cursor.js +0 -324
  65. package/dist/agents/default-config.d.ts +0 -30
  66. package/dist/agents/default-config.js +0 -67
  67. package/dist/agents/defaults-merge.d.ts +0 -72
  68. package/dist/agents/defaults-merge.js +0 -131
  69. package/dist/agents/detect.d.ts +0 -4
  70. package/dist/agents/detect.js +0 -67
  71. package/dist/agents/detection.d.ts +0 -18
  72. package/dist/agents/detection.js +0 -94
  73. package/dist/agents/gemini.d.ts +0 -15
  74. package/dist/agents/gemini.js +0 -122
  75. package/dist/agents/generic-adapter.d.ts +0 -25
  76. package/dist/agents/generic-adapter.js +0 -151
  77. package/dist/agents/intro-skill.d.ts +0 -45
  78. package/dist/agents/intro-skill.js +0 -447
  79. package/dist/agents/registry-data.d.ts +0 -192
  80. package/dist/agents/registry-data.js +0 -669
  81. package/dist/agents/registry.d.ts +0 -13
  82. package/dist/agents/registry.js +0 -36
  83. package/dist/agents/runtime-detection.d.ts +0 -82
  84. package/dist/agents/runtime-detection.js +0 -271
  85. package/dist/agents/session-start-hook.d.ts +0 -37
  86. package/dist/agents/session-start-hook.js +0 -159
  87. package/dist/agents/types.d.ts +0 -171
  88. package/dist/agents/types.js +0 -75
  89. package/dist/agents/utils/instruction-hint.d.ts +0 -21
  90. package/dist/agents/utils/instruction-hint.js +0 -108
  91. package/dist/agents/utils/json-config.d.ts +0 -19
  92. package/dist/agents/utils/json-config.js +0 -69
  93. package/dist/agents/utils/toml-config.d.ts +0 -8
  94. package/dist/agents/utils/toml-config.js +0 -27
  95. package/dist/agents/windsurf.d.ts +0 -14
  96. package/dist/agents/windsurf.js +0 -102
  97. package/dist/api/__tests__/client.test.d.ts +0 -1
  98. package/dist/api/__tests__/client.test.js +0 -272
  99. package/dist/api/client.d.ts +0 -326
  100. package/dist/api/client.js +0 -427
  101. package/dist/auth/__tests__/login-flow.test.d.ts +0 -1
  102. package/dist/auth/__tests__/login-flow.test.js +0 -101
  103. package/dist/auth/__tests__/store.test.d.ts +0 -1
  104. package/dist/auth/__tests__/store.test.js +0 -132
  105. package/dist/auth/login-flow.d.ts +0 -26
  106. package/dist/auth/login-flow.js +0 -137
  107. package/dist/auth/store.d.ts +0 -5
  108. package/dist/auth/store.js +0 -62
  109. package/dist/commands/__tests__/clone-args.test.d.ts +0 -1
  110. package/dist/commands/__tests__/clone-args.test.js +0 -51
  111. package/dist/commands/__tests__/clone-source-result.test.d.ts +0 -1
  112. package/dist/commands/__tests__/clone-source-result.test.js +0 -45
  113. package/dist/commands/__tests__/info-merge.test.d.ts +0 -1
  114. package/dist/commands/__tests__/info-merge.test.js +0 -55
  115. package/dist/commands/__tests__/mcp-entries.test.d.ts +0 -1
  116. package/dist/commands/__tests__/mcp-entries.test.js +0 -48
  117. package/dist/commands/__tests__/setup-persona.test.d.ts +0 -1
  118. package/dist/commands/__tests__/setup-persona.test.js +0 -31
  119. package/dist/commands/__tests__/setup.test.d.ts +0 -1
  120. package/dist/commands/__tests__/setup.test.js +0 -81
  121. package/dist/commands/__tests__/sync-redetect.test.d.ts +0 -1
  122. package/dist/commands/__tests__/sync-redetect.test.js +0 -96
  123. package/dist/commands/__tests__/sync-telemetry.test.d.ts +0 -1
  124. package/dist/commands/__tests__/sync-telemetry.test.js +0 -281
  125. package/dist/commands/__tests__/upgrade.test.d.ts +0 -1
  126. package/dist/commands/__tests__/upgrade.test.js +0 -157
  127. package/dist/commands/agents.d.ts +0 -2
  128. package/dist/commands/agents.js +0 -160
  129. package/dist/commands/api-keys.d.ts +0 -2
  130. package/dist/commands/api-keys.js +0 -95
  131. package/dist/commands/apps.d.ts +0 -2
  132. package/dist/commands/apps.js +0 -82
  133. package/dist/commands/build-plugin.d.ts +0 -2
  134. package/dist/commands/build-plugin.js +0 -135
  135. package/dist/commands/clone.d.ts +0 -60
  136. package/dist/commands/clone.js +0 -271
  137. package/dist/commands/components.d.ts +0 -2
  138. package/dist/commands/components.js +0 -43
  139. package/dist/commands/deploy.d.ts +0 -2
  140. package/dist/commands/deploy.js +0 -279
  141. package/dist/commands/dev.d.ts +0 -11
  142. package/dist/commands/dev.js +0 -1011
  143. package/dist/commands/doctor.d.ts +0 -2
  144. package/dist/commands/doctor.js +0 -230
  145. package/dist/commands/endpoints.d.ts +0 -2
  146. package/dist/commands/endpoints.js +0 -189
  147. package/dist/commands/entities.d.ts +0 -2
  148. package/dist/commands/entities.js +0 -198
  149. package/dist/commands/files.d.ts +0 -2
  150. package/dist/commands/files.js +0 -193
  151. package/dist/commands/inbox.d.ts +0 -11
  152. package/dist/commands/inbox.js +0 -60
  153. package/dist/commands/info.d.ts +0 -178
  154. package/dist/commands/info.js +0 -455
  155. package/dist/commands/init.d.ts +0 -21
  156. package/dist/commands/init.js +0 -185
  157. package/dist/commands/integrations.d.ts +0 -2
  158. package/dist/commands/integrations.js +0 -233
  159. package/dist/commands/login.d.ts +0 -2
  160. package/dist/commands/login.js +0 -44
  161. package/dist/commands/logout.d.ts +0 -2
  162. package/dist/commands/logout.js +0 -13
  163. package/dist/commands/logs.d.ts +0 -2
  164. package/dist/commands/logs.js +0 -232
  165. package/dist/commands/mcp-entries.d.ts +0 -13
  166. package/dist/commands/mcp-entries.js +0 -26
  167. package/dist/commands/mcp.d.ts +0 -2
  168. package/dist/commands/mcp.js +0 -245
  169. package/dist/commands/open.d.ts +0 -2
  170. package/dist/commands/open.js +0 -53
  171. package/dist/commands/resume.d.ts +0 -2
  172. package/dist/commands/resume.js +0 -289
  173. package/dist/commands/save-convo.d.ts +0 -8
  174. package/dist/commands/save-convo.js +0 -20
  175. package/dist/commands/schedules.d.ts +0 -2
  176. package/dist/commands/schedules.js +0 -221
  177. package/dist/commands/setup.d.ts +0 -27
  178. package/dist/commands/setup.js +0 -177
  179. package/dist/commands/share-convo.d.ts +0 -24
  180. package/dist/commands/share-convo.js +0 -167
  181. package/dist/commands/skills.d.ts +0 -2
  182. package/dist/commands/skills.js +0 -352
  183. package/dist/commands/sync-telemetry.d.ts +0 -33
  184. package/dist/commands/sync-telemetry.js +0 -186
  185. package/dist/commands/sync.d.ts +0 -37
  186. package/dist/commands/sync.js +0 -702
  187. package/dist/commands/uninstall.d.ts +0 -2
  188. package/dist/commands/uninstall.js +0 -145
  189. package/dist/commands/upgrade.d.ts +0 -14
  190. package/dist/commands/upgrade.js +0 -217
  191. package/dist/commands/validate.d.ts +0 -2
  192. package/dist/commands/validate.js +0 -89
  193. package/dist/commands/welcome.d.ts +0 -1
  194. package/dist/commands/welcome.js +0 -86
  195. package/dist/commands/workflows.d.ts +0 -2
  196. package/dist/commands/workflows.js +0 -187
  197. package/dist/deploy/__tests__/deploy-state.test.d.ts +0 -1
  198. package/dist/deploy/__tests__/deploy-state.test.js +0 -80
  199. package/dist/deploy/__tests__/deploy-status.test.d.ts +0 -1
  200. package/dist/deploy/__tests__/deploy-status.test.js +0 -41
  201. package/dist/deploy/__tests__/detach-args.test.d.ts +0 -1
  202. package/dist/deploy/__tests__/detach-args.test.js +0 -30
  203. package/dist/deploy/deploy-state.d.ts +0 -36
  204. package/dist/deploy/deploy-state.js +0 -63
  205. package/dist/deploy/deploy-status.d.ts +0 -21
  206. package/dist/deploy/deploy-status.js +0 -36
  207. package/dist/deploy/detach.d.ts +0 -32
  208. package/dist/deploy/detach.js +0 -71
  209. package/dist/dev/__tests__/attach.test.d.ts +0 -1
  210. package/dist/dev/__tests__/attach.test.js +0 -296
  211. package/dist/dev/__tests__/detach.test.d.ts +0 -1
  212. package/dist/dev/__tests__/detach.test.js +0 -404
  213. package/dist/dev/__tests__/preview-url-poller.test.d.ts +0 -1
  214. package/dist/dev/__tests__/preview-url-poller.test.js +0 -149
  215. package/dist/dev/__tests__/session.test.d.ts +0 -1
  216. package/dist/dev/__tests__/session.test.js +0 -446
  217. package/dist/dev/__tests__/startup-sync.test.d.ts +0 -1
  218. package/dist/dev/__tests__/startup-sync.test.js +0 -32
  219. package/dist/dev/__tests__/stop.test.d.ts +0 -1
  220. package/dist/dev/__tests__/stop.test.js +0 -172
  221. package/dist/dev/attach.d.ts +0 -120
  222. package/dist/dev/attach.js +0 -269
  223. package/dist/dev/detach.d.ts +0 -187
  224. package/dist/dev/detach.js +0 -292
  225. package/dist/dev/preview-url-poller.d.ts +0 -35
  226. package/dist/dev/preview-url-poller.js +0 -50
  227. package/dist/dev/session.d.ts +0 -175
  228. package/dist/dev/session.js +0 -258
  229. package/dist/dev/startup-sync.d.ts +0 -23
  230. package/dist/dev/startup-sync.js +0 -14
  231. package/dist/dev/stop.d.ts +0 -52
  232. package/dist/dev/stop.js +0 -101
  233. package/dist/devtools/registry-data.d.ts +0 -46
  234. package/dist/devtools/registry-data.js +0 -40
  235. package/dist/generated/bundled-types.d.ts +0 -1
  236. package/dist/generated/bundled-types.js +0 -46
  237. package/dist/generated/version.d.ts +0 -1
  238. package/dist/generated/version.js +0 -2
  239. package/dist/git/__tests__/auto-commit.test.d.ts +0 -1
  240. package/dist/git/__tests__/auto-commit.test.js +0 -431
  241. package/dist/git/__tests__/classify-sync-error.test.d.ts +0 -1
  242. package/dist/git/__tests__/classify-sync-error.test.js +0 -57
  243. package/dist/git/__tests__/credential-helper-e2e.test.d.ts +0 -21
  244. package/dist/git/__tests__/credential-helper-e2e.test.js +0 -195
  245. package/dist/git/__tests__/credentials.test.d.ts +0 -1
  246. package/dist/git/__tests__/credentials.test.js +0 -141
  247. package/dist/git/__tests__/deploy-guard.test.d.ts +0 -1
  248. package/dist/git/__tests__/deploy-guard.test.js +0 -61
  249. package/dist/git/__tests__/ensure-git-credential-helper.test.d.ts +0 -1
  250. package/dist/git/__tests__/ensure-git-credential-helper.test.js +0 -133
  251. package/dist/git/__tests__/ensure-runwork-remote.test.d.ts +0 -1
  252. package/dist/git/__tests__/ensure-runwork-remote.test.js +0 -109
  253. package/dist/git/__tests__/identity.test.d.ts +0 -1
  254. package/dist/git/__tests__/identity.test.js +0 -146
  255. package/dist/git/__tests__/manifest.test.d.ts +0 -1
  256. package/dist/git/__tests__/manifest.test.js +0 -446
  257. package/dist/git/__tests__/preflight-resolution.test.d.ts +0 -1
  258. package/dist/git/__tests__/preflight-resolution.test.js +0 -366
  259. package/dist/git/__tests__/preflight.test.d.ts +0 -1
  260. package/dist/git/__tests__/preflight.test.js +0 -36
  261. package/dist/git/__tests__/repo-config.test.d.ts +0 -1
  262. package/dist/git/__tests__/repo-config.test.js +0 -26
  263. package/dist/git/__tests__/sync.test.d.ts +0 -1
  264. package/dist/git/__tests__/sync.test.js +0 -405
  265. package/dist/git/auto-commit.d.ts +0 -35
  266. package/dist/git/auto-commit.js +0 -293
  267. package/dist/git/classify-sync-error.d.ts +0 -21
  268. package/dist/git/classify-sync-error.js +0 -111
  269. package/dist/git/credentials.d.ts +0 -75
  270. package/dist/git/credentials.js +0 -164
  271. package/dist/git/critical-files.d.ts +0 -20
  272. package/dist/git/critical-files.js +0 -68
  273. package/dist/git/deploy-guard.d.ts +0 -53
  274. package/dist/git/deploy-guard.js +0 -78
  275. package/dist/git/identity.d.ts +0 -44
  276. package/dist/git/identity.js +0 -133
  277. package/dist/git/preflight.d.ts +0 -57
  278. package/dist/git/preflight.js +0 -276
  279. package/dist/git/remote.d.ts +0 -37
  280. package/dist/git/remote.js +0 -75
  281. package/dist/git/repo-config.d.ts +0 -8
  282. package/dist/git/repo-config.js +0 -29
  283. package/dist/git/sync.d.ts +0 -15
  284. package/dist/git/sync.js +0 -159
  285. package/dist/health/__tests__/checks.test.d.ts +0 -1
  286. package/dist/health/__tests__/checks.test.js +0 -357
  287. package/dist/health/__tests__/cli-distribution-checks.test.d.ts +0 -1
  288. package/dist/health/__tests__/cli-distribution-checks.test.js +0 -196
  289. package/dist/health/__tests__/fix.test.d.ts +0 -1
  290. package/dist/health/__tests__/fix.test.js +0 -72
  291. package/dist/health/__tests__/runner-filter.test.d.ts +0 -1
  292. package/dist/health/__tests__/runner-filter.test.js +0 -61
  293. package/dist/health/checks.d.ts +0 -42
  294. package/dist/health/checks.js +0 -636
  295. package/dist/health/fix.d.ts +0 -22
  296. package/dist/health/fix.js +0 -62
  297. package/dist/health/runner.d.ts +0 -8
  298. package/dist/health/runner.js +0 -47
  299. package/dist/health/types.d.ts +0 -12
  300. package/dist/health/types.js +0 -1
  301. package/dist/index.d.ts +0 -1
  302. package/dist/logs/__tests__/tailer-format.test.d.ts +0 -1
  303. package/dist/logs/__tests__/tailer-format.test.js +0 -43
  304. package/dist/logs/tailer.d.ts +0 -17
  305. package/dist/logs/tailer.js +0 -217
  306. package/dist/sync/__tests__/change-detect.test.d.ts +0 -1
  307. package/dist/sync/__tests__/change-detect.test.js +0 -123
  308. package/dist/sync/__tests__/hash.test.d.ts +0 -1
  309. package/dist/sync/__tests__/hash.test.js +0 -18
  310. package/dist/sync/change-detect.d.ts +0 -19
  311. package/dist/sync/change-detect.js +0 -136
  312. package/dist/sync/conflict-ui.d.ts +0 -5
  313. package/dist/sync/conflict-ui.js +0 -78
  314. package/dist/sync/executor.d.ts +0 -23
  315. package/dist/sync/executor.js +0 -102
  316. package/dist/sync/hash.d.ts +0 -1
  317. package/dist/sync/hash.js +0 -4
  318. package/dist/sync/types.d.ts +0 -24
  319. package/dist/sync/types.js +0 -1
  320. package/dist/template/manifest.d.ts +0 -17
  321. package/dist/template/manifest.js +0 -145
  322. package/dist/tools/types.d.ts +0 -52
  323. package/dist/tools/types.js +0 -8
  324. package/dist/types-manager.d.ts +0 -1
  325. package/dist/types-manager.js +0 -35
  326. package/dist/types.d.ts +0 -349
  327. package/dist/types.js +0 -1
  328. package/dist/ui/__tests__/banner.test.d.ts +0 -1
  329. package/dist/ui/__tests__/banner.test.js +0 -98
  330. package/dist/ui/__tests__/colors.test.d.ts +0 -1
  331. package/dist/ui/__tests__/colors.test.js +0 -22
  332. package/dist/ui/__tests__/keyboard.test.d.ts +0 -1
  333. package/dist/ui/__tests__/keyboard.test.js +0 -34
  334. package/dist/ui/__tests__/status-line.test.d.ts +0 -1
  335. package/dist/ui/__tests__/status-line.test.js +0 -54
  336. package/dist/ui/banner.d.ts +0 -29
  337. package/dist/ui/banner.js +0 -153
  338. package/dist/ui/colors.d.ts +0 -4
  339. package/dist/ui/colors.js +0 -7
  340. package/dist/ui/keyboard.d.ts +0 -12
  341. package/dist/ui/keyboard.js +0 -61
  342. package/dist/ui/status-line.d.ts +0 -6
  343. package/dist/ui/status-line.js +0 -53
  344. package/dist/utils/__tests__/format-error.test.d.ts +0 -1
  345. package/dist/utils/__tests__/format-error.test.js +0 -43
  346. package/dist/utils/__tests__/help-json.test.d.ts +0 -1
  347. package/dist/utils/__tests__/help-json.test.js +0 -39
  348. package/dist/utils/__tests__/http.test.d.ts +0 -1
  349. package/dist/utils/__tests__/http.test.js +0 -381
  350. package/dist/utils/__tests__/ignore-matcher.test.d.ts +0 -1
  351. package/dist/utils/__tests__/ignore-matcher.test.js +0 -205
  352. package/dist/utils/__tests__/output.test.d.ts +0 -1
  353. package/dist/utils/__tests__/output.test.js +0 -38
  354. package/dist/utils/__tests__/prompt.test.d.ts +0 -1
  355. package/dist/utils/__tests__/prompt.test.js +0 -27
  356. package/dist/utils/__tests__/resolve.test.d.ts +0 -1
  357. package/dist/utils/__tests__/resolve.test.js +0 -95
  358. package/dist/utils/__tests__/sqlite.test.d.ts +0 -1
  359. package/dist/utils/__tests__/sqlite.test.js +0 -89
  360. package/dist/utils/agent-guidance.d.ts +0 -47
  361. package/dist/utils/agent-guidance.js +0 -128
  362. package/dist/utils/app-info.d.ts +0 -70
  363. package/dist/utils/app-info.js +0 -167
  364. package/dist/utils/curl-parser.d.ts +0 -12
  365. package/dist/utils/curl-parser.js +0 -162
  366. package/dist/utils/data-input.d.ts +0 -1
  367. package/dist/utils/data-input.js +0 -38
  368. package/dist/utils/format-error.d.ts +0 -10
  369. package/dist/utils/format-error.js +0 -38
  370. package/dist/utils/fs.d.ts +0 -5
  371. package/dist/utils/fs.js +0 -23
  372. package/dist/utils/help-json.d.ts +0 -70
  373. package/dist/utils/help-json.js +0 -88
  374. package/dist/utils/http.d.ts +0 -46
  375. package/dist/utils/http.js +0 -421
  376. package/dist/utils/ignore-matcher.d.ts +0 -47
  377. package/dist/utils/ignore-matcher.js +0 -132
  378. package/dist/utils/output.d.ts +0 -17
  379. package/dist/utils/output.js +0 -27
  380. package/dist/utils/prompt.d.ts +0 -5
  381. package/dist/utils/prompt.js +0 -42
  382. package/dist/utils/resolve.d.ts +0 -12
  383. package/dist/utils/resolve.js +0 -52
  384. package/dist/utils/setup-state.d.ts +0 -3
  385. package/dist/utils/setup-state.js +0 -19
  386. package/dist/utils/sqlite-adapter.d.ts +0 -48
  387. package/dist/utils/sqlite-adapter.js +0 -147
  388. package/dist/utils/sqlite.d.ts +0 -14
  389. package/dist/utils/sqlite.js +0 -14
  390. package/dist/utils/subprocess.d.ts +0 -19
  391. package/dist/utils/subprocess.js +0 -27
  392. package/dist/utils/which.d.ts +0 -14
  393. package/dist/utils/which.js +0 -47
  394. package/dist/utils/zip.d.ts +0 -7
  395. package/dist/utils/zip.js +0 -42
  396. package/dist/validate/__tests__/validate.test.d.ts +0 -1
  397. package/dist/validate/__tests__/validate.test.js +0 -42
  398. package/dist/validate/freshness.d.ts +0 -28
  399. package/dist/validate/freshness.js +0 -48
  400. package/dist/validate/preview.d.ts +0 -21
  401. package/dist/validate/preview.js +0 -39
  402. package/dist/workspace/resolve.d.ts +0 -19
  403. package/dist/workspace/resolve.js +0 -100
@@ -1,381 +0,0 @@
1
- import { describe, it, expect, beforeAll, afterAll, vi } from 'vitest';
2
- import { createServer } from 'node:http';
3
- import { gzipSync, deflateSync, brotliCompressSync } from 'node:zlib';
4
- import { spawnSync } from 'node:child_process';
5
- import { httpFetch, __setTransportForTests } from '../http.js';
6
- let server;
7
- let port;
8
- const calls = [];
9
- function startServer() {
10
- return new Promise((resolve) => {
11
- server = createServer(async (req, res) => {
12
- const chunks = [];
13
- for await (const chunk of req)
14
- chunks.push(chunk);
15
- const body = Buffer.concat(chunks).toString('utf-8');
16
- calls.push({ url: req.url || '', method: req.method || '', headers: req.headers, body });
17
- const url = req.url || '/';
18
- // Simple endpoints exercised by the test cases below.
19
- if (url === '/json') {
20
- res.writeHead(200, { 'content-type': 'application/json' });
21
- res.end(JSON.stringify({ hello: 'world' }));
22
- return;
23
- }
24
- if (url === '/text') {
25
- res.writeHead(200, { 'content-type': 'text/plain' });
26
- res.end('plain body');
27
- return;
28
- }
29
- if (url === '/binary') {
30
- res.writeHead(200, { 'content-type': 'application/octet-stream' });
31
- res.end(Buffer.from([1, 2, 3, 4, 5]));
32
- return;
33
- }
34
- if (url === '/echo-headers') {
35
- res.writeHead(200, { 'content-type': 'application/json' });
36
- res.end(JSON.stringify({ headers: req.headers, method: req.method }));
37
- return;
38
- }
39
- if (url === '/echo-body') {
40
- res.writeHead(200, { 'content-type': 'application/json' });
41
- res.end(JSON.stringify({ body, contentType: req.headers['content-type'] }));
42
- return;
43
- }
44
- if (url === '/status/404') {
45
- res.writeHead(404, { 'content-type': 'text/plain' });
46
- res.end('not found');
47
- return;
48
- }
49
- if (url === '/status/500') {
50
- res.writeHead(500, { 'content-type': 'text/plain' });
51
- res.end('boom');
52
- return;
53
- }
54
- if (url === '/redirect/302') {
55
- res.writeHead(302, { location: '/json' });
56
- res.end();
57
- return;
58
- }
59
- if (url === '/redirect/303-post') {
60
- res.writeHead(303, { location: '/echo-headers' });
61
- res.end();
62
- return;
63
- }
64
- if (url === '/redirect/307') {
65
- res.writeHead(307, { location: '/echo-body' });
66
- res.end();
67
- return;
68
- }
69
- if (url === '/redirect/loop') {
70
- res.writeHead(302, { location: '/redirect/loop' });
71
- res.end();
72
- return;
73
- }
74
- if (url === '/gzip') {
75
- res.writeHead(200, { 'content-type': 'text/plain', 'content-encoding': 'gzip' });
76
- res.end(gzipSync(Buffer.from('compressed-gzip-body')));
77
- return;
78
- }
79
- if (url === '/deflate') {
80
- res.writeHead(200, { 'content-type': 'text/plain', 'content-encoding': 'deflate' });
81
- res.end(deflateSync(Buffer.from('compressed-deflate-body')));
82
- return;
83
- }
84
- if (url === '/brotli') {
85
- res.writeHead(200, { 'content-type': 'text/plain', 'content-encoding': 'br' });
86
- res.end(brotliCompressSync(Buffer.from('compressed-brotli-body')));
87
- return;
88
- }
89
- if (url === '/head') {
90
- res.writeHead(200, { 'content-type': 'text/plain', 'x-marker': 'present' });
91
- res.end();
92
- return;
93
- }
94
- res.writeHead(404);
95
- res.end();
96
- });
97
- server.listen(0, '127.0.0.1', () => {
98
- const addr = server.address();
99
- if (typeof addr === 'object' && addr && 'port' in addr) {
100
- port = addr.port;
101
- }
102
- resolve();
103
- });
104
- });
105
- }
106
- beforeAll(async () => { await startServer(); });
107
- afterAll(() => new Promise((resolve) => server.close(() => resolve())));
108
- function url(path) { return `http://127.0.0.1:${port}${path}`; }
109
- describe('httpFetch — basic Response surface', () => {
110
- it('parses JSON responses', async () => {
111
- const res = await httpFetch(url('/json'));
112
- expect(res.ok).toBe(true);
113
- expect(res.status).toBe(200);
114
- expect(res.headers.get('content-type')).toContain('application/json');
115
- expect(await res.json()).toEqual({ hello: 'world' });
116
- });
117
- it('reads text responses', async () => {
118
- const res = await httpFetch(url('/text'));
119
- expect(res.ok).toBe(true);
120
- expect(await res.text()).toBe('plain body');
121
- });
122
- it('reads binary responses as ArrayBuffer with the exact byte content', async () => {
123
- const res = await httpFetch(url('/binary'));
124
- const ab = await res.arrayBuffer();
125
- expect(new Uint8Array(ab)).toEqual(new Uint8Array([1, 2, 3, 4, 5]));
126
- });
127
- it('returns ok=false for 4xx without throwing', async () => {
128
- const res = await httpFetch(url('/status/404'));
129
- expect(res.ok).toBe(false);
130
- expect(res.status).toBe(404);
131
- expect(await res.text()).toBe('not found');
132
- });
133
- it('returns ok=false for 5xx without throwing', async () => {
134
- const res = await httpFetch(url('/status/500'));
135
- expect(res.ok).toBe(false);
136
- expect(res.status).toBe(500);
137
- });
138
- });
139
- describe('httpFetch — request shape', () => {
140
- it('passes through plain object headers, lowercased per HTTP convention', async () => {
141
- const res = await httpFetch(url('/echo-headers'), {
142
- headers: { 'X-Custom-Foo': 'bar', Authorization: 'Bearer abc' },
143
- });
144
- const data = await res.json();
145
- expect(data.method).toBe('GET');
146
- expect(data.headers['x-custom-foo']).toBe('bar');
147
- expect(data.headers['authorization']).toBe('Bearer abc');
148
- });
149
- it('passes through Headers instance', async () => {
150
- const headers = new Headers();
151
- headers.set('X-One', 'a');
152
- headers.set('X-Two', 'b');
153
- const res = await httpFetch(url('/echo-headers'), { headers });
154
- const data = await res.json();
155
- expect(data.headers['x-one']).toBe('a');
156
- expect(data.headers['x-two']).toBe('b');
157
- });
158
- it('uppercases lowercase methods', async () => {
159
- const res = await httpFetch(url('/echo-headers'), { method: 'post', body: '' });
160
- const data = await res.json();
161
- expect(data.method).toBe('POST');
162
- });
163
- it('sends string body and content-length', async () => {
164
- const res = await httpFetch(url('/echo-body'), {
165
- method: 'POST',
166
- headers: { 'content-type': 'application/json' },
167
- body: JSON.stringify({ a: 1 }),
168
- });
169
- const data = await res.json();
170
- expect(data.body).toBe('{"a":1}');
171
- expect(data.contentType).toBe('application/json');
172
- });
173
- it('sends Buffer body', async () => {
174
- const res = await httpFetch(url('/echo-body'), {
175
- method: 'PUT',
176
- body: Buffer.from('raw-buffer'),
177
- });
178
- const data = await res.json();
179
- expect(data.body).toBe('raw-buffer');
180
- });
181
- it('sends Uint8Array body with offset', async () => {
182
- const backing = new Uint8Array([0, 0, 65, 66, 67, 0]);
183
- const view = backing.subarray(2, 5); // "ABC"
184
- const res = await httpFetch(url('/echo-body'), { method: 'POST', body: view });
185
- const data = await res.json();
186
- expect(data.body).toBe('ABC');
187
- });
188
- it('sends ArrayBuffer body', async () => {
189
- const ab = new TextEncoder().encode('via-arraybuffer').buffer;
190
- const res = await httpFetch(url('/echo-body'), { method: 'POST', body: ab });
191
- const data = await res.json();
192
- expect(data.body).toBe('via-arraybuffer');
193
- });
194
- it('drops body on bodyless GET/HEAD methods (matches fetch behavior)', async () => {
195
- const res = await httpFetch(url('/echo-body'), {
196
- method: 'GET',
197
- // GET requests with bodies are non-conformant; fetch silently drops the body.
198
- body: 'should-not-be-sent',
199
- });
200
- const data = await res.json();
201
- expect(data.body).toBe('');
202
- });
203
- });
204
- describe('httpFetch — redirects', () => {
205
- it('follows a 302 to the final URL', async () => {
206
- const res = await httpFetch(url('/redirect/302'));
207
- expect(res.status).toBe(200);
208
- expect(res.url.endsWith('/json')).toBe(true);
209
- expect(await res.json()).toEqual({ hello: 'world' });
210
- });
211
- it('downgrades POST to GET on 303 (matches fetch semantics)', async () => {
212
- const res = await httpFetch(url('/redirect/303-post'), {
213
- method: 'POST',
214
- body: 'ignored-after-303',
215
- });
216
- const data = await res.json();
217
- expect(data.method).toBe('GET');
218
- });
219
- it('preserves method and body on 307', async () => {
220
- const res = await httpFetch(url('/redirect/307'), {
221
- method: 'POST',
222
- body: 'preserved-on-307',
223
- });
224
- const data = await res.json();
225
- expect(data.body).toBe('preserved-on-307');
226
- });
227
- it('rejects after exceeding the redirect limit', async () => {
228
- // The endpoint redirects to itself; after MAX_REDIRECTS we stop following
229
- // and return the redirect response itself rather than crash.
230
- const res = await httpFetch(url('/redirect/loop'));
231
- expect(res.status).toBe(302);
232
- });
233
- });
234
- describe('httpFetch — content decoding', () => {
235
- it('advertises gzip/deflate/br by default', async () => {
236
- await httpFetch(url('/echo-headers'));
237
- const last = calls[calls.length - 1];
238
- expect(last.headers['accept-encoding']).toBe('gzip, deflate, br');
239
- });
240
- it('decompresses gzip responses transparently', async () => {
241
- const res = await httpFetch(url('/gzip'));
242
- expect(await res.text()).toBe('compressed-gzip-body');
243
- });
244
- it('decompresses brotli responses transparently', async () => {
245
- const res = await httpFetch(url('/brotli'));
246
- expect(await res.text()).toBe('compressed-brotli-body');
247
- });
248
- it('decompresses deflate responses transparently', async () => {
249
- const res = await httpFetch(url('/deflate'));
250
- expect(await res.text()).toBe('compressed-deflate-body');
251
- });
252
- });
253
- describe('httpFetch — HEAD requests', () => {
254
- it('returns headers and an empty body', async () => {
255
- const res = await httpFetch(url('/head'), { method: 'HEAD' });
256
- expect(res.status).toBe(200);
257
- expect(res.headers.get('x-marker')).toBe('present');
258
- expect(await res.text()).toBe('');
259
- });
260
- });
261
- describe('httpFetch — errors', () => {
262
- it('rejects on connection failure', async () => {
263
- // 127.0.0.1:1 is virtually guaranteed to refuse connections.
264
- await expect(httpFetch('http://127.0.0.1:1/')).rejects.toThrow();
265
- });
266
- it('rejects on unsupported protocols', async () => {
267
- await expect(httpFetch('ftp://example.com/')).rejects.toThrow(/Unsupported protocol/);
268
- });
269
- });
270
- // ────────────────────────────────────────────────────────────────────────
271
- // curl-transport tests
272
- //
273
- // `curl` is the opt-in escape hatch (`RUNWORK_HTTP_TRANSPORT=curl`). It
274
- // shells out to the system `curl` so HTTP runs in a subprocess, immune to
275
- // any future runtime regression. These tests force the curl path via the
276
- // test-only override so the break-glass path stays exercised in CI even
277
- // though the default transport is `node:https`. Skipped when curl is
278
- // missing on the host.
279
- // ────────────────────────────────────────────────────────────────────────
280
- const curlAvailable = (() => {
281
- try {
282
- const r = spawnSync('curl', ['--version'], { encoding: 'utf-8' });
283
- return r.status === 0;
284
- }
285
- catch {
286
- return false;
287
- }
288
- })();
289
- describe.skipIf(!curlAvailable)('httpFetch — curl transport (opt-in via env var)', () => {
290
- beforeAll(() => { __setTransportForTests('curl'); });
291
- afterAll(() => { __setTransportForTests('auto'); });
292
- it('parses JSON responses through curl', async () => {
293
- const res = await httpFetch(url('/json'));
294
- expect(res.ok).toBe(true);
295
- expect(res.status).toBe(200);
296
- expect(await res.json()).toEqual({ hello: 'world' });
297
- });
298
- it('reads binary responses with exact byte content', async () => {
299
- const res = await httpFetch(url('/binary'));
300
- const ab = await res.arrayBuffer();
301
- expect(new Uint8Array(ab)).toEqual(new Uint8Array([1, 2, 3, 4, 5]));
302
- });
303
- it('returns ok=false for 4xx without throwing', async () => {
304
- const res = await httpFetch(url('/status/404'));
305
- expect(res.ok).toBe(false);
306
- expect(res.status).toBe(404);
307
- expect(await res.text()).toBe('not found');
308
- });
309
- it('follows 302 redirects to the final URL', async () => {
310
- const res = await httpFetch(url('/redirect/302'));
311
- expect(res.status).toBe(200);
312
- expect(res.url.endsWith('/json')).toBe(true);
313
- expect(await res.json()).toEqual({ hello: 'world' });
314
- });
315
- it('downgrades POST to GET on 303 (matches fetch semantics)', async () => {
316
- const res = await httpFetch(url('/redirect/303-post'), {
317
- method: 'POST',
318
- body: 'ignored-after-303',
319
- });
320
- const data = await res.json();
321
- expect(data.method).toBe('GET');
322
- });
323
- it('preserves method and body on 307', async () => {
324
- const res = await httpFetch(url('/redirect/307'), {
325
- method: 'POST',
326
- body: 'preserved-on-307',
327
- });
328
- const data = await res.json();
329
- expect(data.body).toBe('preserved-on-307');
330
- });
331
- it('passes plain object headers through', async () => {
332
- const res = await httpFetch(url('/echo-headers'), {
333
- headers: { 'X-Custom': 'curl-roundtrip', Authorization: 'Bearer abc' },
334
- });
335
- const data = await res.json();
336
- expect(data.headers['x-custom']).toBe('curl-roundtrip');
337
- expect(data.headers['authorization']).toBe('Bearer abc');
338
- });
339
- it('sends string body and content-type', async () => {
340
- const res = await httpFetch(url('/echo-body'), {
341
- method: 'POST',
342
- headers: { 'content-type': 'application/json' },
343
- body: JSON.stringify({ a: 1 }),
344
- });
345
- const data = await res.json();
346
- expect(data.body).toBe('{"a":1}');
347
- expect(data.contentType).toBe('application/json');
348
- });
349
- it('sends binary Uint8Array body with offset', async () => {
350
- const backing = new Uint8Array([0, 0, 65, 66, 67, 0]);
351
- const view = backing.subarray(2, 5); // "ABC"
352
- const res = await httpFetch(url('/echo-body'), { method: 'POST', body: view });
353
- const data = await res.json();
354
- expect(data.body).toBe('ABC');
355
- });
356
- it('returns headers and an empty body for HEAD', async () => {
357
- const res = await httpFetch(url('/head'), { method: 'HEAD' });
358
- expect(res.status).toBe(200);
359
- expect(res.headers.get('x-marker')).toBe('present');
360
- expect(await res.text()).toBe('');
361
- });
362
- it('warns and returns raw bytes on unexpected gzip', async () => {
363
- const stderr = vi.spyOn(process.stderr, 'write').mockImplementation(() => true);
364
- try {
365
- const res = await httpFetch(url('/gzip'));
366
- expect(res.ok).toBe(true);
367
- const ab = await res.arrayBuffer();
368
- expect(ab.byteLength).toBeGreaterThan(0);
369
- expect(stderr).toHaveBeenCalledWith(expect.stringMatching(/Content-Encoding: gzip/));
370
- }
371
- finally {
372
- stderr.mockRestore();
373
- }
374
- });
375
- it('rejects on connection failure', async () => {
376
- await expect(httpFetch('http://127.0.0.1:1/')).rejects.toThrow();
377
- });
378
- it('rejects on unsupported protocols', async () => {
379
- await expect(httpFetch('ftp://example.com/')).rejects.toThrow(/Unsupported protocol/);
380
- });
381
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,205 +0,0 @@
1
- import { describe, it, expect, afterEach } from 'vitest';
2
- import { mkdtempSync, writeFileSync, rmSync } from 'fs';
3
- import { join } from 'path';
4
- import { tmpdir } from 'os';
5
- import { buildIgnoreSets, defaultIgnoreSets, isPathIgnored, isRelPathIgnored, parseGitignoreContent, } from '../ignore-matcher.js';
6
- const tempDirs = [];
7
- function makeTempDir(prefix) {
8
- const dir = mkdtempSync(join(tmpdir(), `runwork-ignore-${prefix}-`));
9
- tempDirs.push(dir);
10
- return dir;
11
- }
12
- afterEach(() => {
13
- for (const dir of tempDirs) {
14
- try {
15
- rmSync(dir, { recursive: true, force: true });
16
- }
17
- catch { /* best effort */ }
18
- }
19
- tempDirs.length = 0;
20
- });
21
- describe('defaultIgnoreSets()', () => {
22
- it('includes the historical defaults plus .bun-cache', () => {
23
- const sets = defaultIgnoreSets();
24
- expect(sets.dirs.has('.git')).toBe(true);
25
- expect(sets.dirs.has('node_modules')).toBe(true);
26
- expect(sets.dirs.has('.runwork')).toBe(true);
27
- expect(sets.dirs.has('.bun-cache')).toBe(true);
28
- });
29
- it('excludes every .runwork/ state file from deploy/dev auto-commit staging', () => {
30
- // commitWorkingTree() filters untracked files through isRelPathIgnored,
31
- // so any path with a .runwork segment must be excluded -- including the
32
- // local deploy-state/status files written before the detached child
33
- // commits (Codex review P1).
34
- const sets = defaultIgnoreSets();
35
- for (const p of [
36
- '.runwork/deploy-status.json',
37
- '.runwork/last-deploy.json',
38
- '.runwork/deploy-stdout.log',
39
- '.runwork/dev-session.json',
40
- '.runwork/setup.json',
41
- '.runwork/preview-url',
42
- ]) {
43
- expect(isRelPathIgnored(p, sets), `${p} must be ignored`).toBe(true);
44
- }
45
- });
46
- it('includes .dev.vars and .env file defaults', () => {
47
- const sets = defaultIgnoreSets();
48
- expect(sets.files.has('.dev.vars')).toBe(true);
49
- expect(sets.files.has('.env')).toBe(true);
50
- });
51
- it('includes .log extension default', () => {
52
- const sets = defaultIgnoreSets();
53
- expect(sets.extensions.has('.log')).toBe(true);
54
- });
55
- it('returns independent set instances on each call', () => {
56
- const a = defaultIgnoreSets();
57
- const b = defaultIgnoreSets();
58
- a.dirs.add('mutated');
59
- expect(b.dirs.has('mutated')).toBe(false);
60
- });
61
- });
62
- describe('parseGitignoreContent()', () => {
63
- it('parses simple basename patterns', () => {
64
- const { dirs, files } = parseGitignoreContent('node_modules\n.cache\n');
65
- expect(dirs.has('node_modules')).toBe(true);
66
- expect(dirs.has('.cache')).toBe(true);
67
- expect(files.has('node_modules')).toBe(true);
68
- expect(files.has('.cache')).toBe(true);
69
- });
70
- it('treats trailing-slash patterns as directory-only', () => {
71
- const { dirs, files } = parseGitignoreContent('dist/\n');
72
- expect(dirs.has('dist')).toBe(true);
73
- expect(files.has('dist')).toBe(false);
74
- });
75
- it('strips leading slash on top-level patterns', () => {
76
- const { dirs } = parseGitignoreContent('/dist/\n');
77
- expect(dirs.has('dist')).toBe(true);
78
- });
79
- it('skips comments and blank lines', () => {
80
- const { dirs } = parseGitignoreContent('# a comment\n\n \n.cache\n');
81
- expect(dirs.size).toBe(1);
82
- expect(dirs.has('.cache')).toBe(true);
83
- });
84
- it('skips negation patterns', () => {
85
- const { dirs } = parseGitignoreContent('!keepme\n.cache\n');
86
- expect(dirs.has('keepme')).toBe(false);
87
- expect(dirs.has('.cache')).toBe(true);
88
- });
89
- it('skips patterns containing glob characters', () => {
90
- const { dirs, files } = parseGitignoreContent('*.local\nfoo[1].txt\nq?.tmp\n.cache\n');
91
- expect(dirs.has('*.local')).toBe(false);
92
- expect(files.has('*.local')).toBe(false);
93
- expect(dirs.has('foo[1].txt')).toBe(false);
94
- expect(dirs.has('q?.tmp')).toBe(false);
95
- expect(dirs.has('.cache')).toBe(true);
96
- });
97
- it('skips patterns with internal path separators', () => {
98
- const { dirs } = parseGitignoreContent('src/generated\n.runwork/types\n.cache\n');
99
- expect(dirs.has('src/generated')).toBe(false);
100
- expect(dirs.has('.runwork/types')).toBe(false);
101
- expect(dirs.has('.cache')).toBe(true);
102
- });
103
- it('parses a realistic runwork-app .gitignore without throwing', () => {
104
- const content = [
105
- '# Logs',
106
- 'logs',
107
- '*.log',
108
- '',
109
- 'node_modules',
110
- 'dist',
111
- 'dist-ssr',
112
- '*.local',
113
- '.idea',
114
- '.DS_Store',
115
- '.wrangler',
116
- '.dev.vars*',
117
- '.env.*',
118
- 'data/',
119
- '.data/',
120
- '*.tsbuildinfo',
121
- '.eslintcache',
122
- '.runwork/types/',
123
- '.runwork/.credentials',
124
- '.runwork/logs.txt',
125
- 'SKILL.md',
126
- '.bun-cache/',
127
- ].join('\n');
128
- const { dirs } = parseGitignoreContent(content);
129
- expect(dirs.has('node_modules')).toBe(true);
130
- expect(dirs.has('dist')).toBe(true);
131
- expect(dirs.has('dist-ssr')).toBe(true);
132
- expect(dirs.has('.idea')).toBe(true);
133
- expect(dirs.has('.wrangler')).toBe(true);
134
- expect(dirs.has('.bun-cache')).toBe(true);
135
- expect(dirs.has('.eslintcache')).toBe(true);
136
- expect(dirs.has('SKILL.md')).toBe(true);
137
- // Patterns containing a slash, glob, or starting with `!` are not
138
- // representable as basename matches and must be silently skipped.
139
- expect(dirs.has('.runwork/types')).toBe(false);
140
- expect(dirs.has('*.log')).toBe(false);
141
- expect(dirs.has('.dev.vars*')).toBe(false);
142
- expect(dirs.has('.env.*')).toBe(false);
143
- });
144
- });
145
- describe('buildIgnoreSets()', () => {
146
- it('falls back to defaults when no .gitignore is present', () => {
147
- const dir = makeTempDir('no-gitignore');
148
- const sets = buildIgnoreSets(dir);
149
- expect(sets.dirs.has('.bun-cache')).toBe(true);
150
- expect(sets.dirs.has('node_modules')).toBe(true);
151
- // No project-specific entries get added.
152
- expect(sets.dirs.has('dist')).toBe(false);
153
- });
154
- it('merges defaults with patterns parsed from .gitignore', () => {
155
- const dir = makeTempDir('with-gitignore');
156
- writeFileSync(join(dir, '.gitignore'), 'dist/\n.next/\ncoverage\n');
157
- const sets = buildIgnoreSets(dir);
158
- // Defaults still present.
159
- expect(sets.dirs.has('.bun-cache')).toBe(true);
160
- // Project-specific entries added.
161
- expect(sets.dirs.has('dist')).toBe(true);
162
- expect(sets.dirs.has('.next')).toBe(true);
163
- expect(sets.dirs.has('coverage')).toBe(true);
164
- });
165
- it('returns defaults if .gitignore is unreadable', () => {
166
- const dir = makeTempDir('bad-gitignore');
167
- // Create a directory at the .gitignore path so readFileSync fails.
168
- // Easiest cross-platform way: pass a directory path. We just write
169
- // nothing here and skip — but verify no throw and defaults applied.
170
- // (The unreadable path is exercised by buildIgnoreSets's try/catch.)
171
- const sets = buildIgnoreSets(dir);
172
- expect(sets.dirs.has('.bun-cache')).toBe(true);
173
- });
174
- });
175
- describe('isPathIgnored()', () => {
176
- const sets = defaultIgnoreSets();
177
- it('ignores well-known cache directories by basename', () => {
178
- expect(isPathIgnored('.bun-cache', sets)).toBe(true);
179
- expect(isPathIgnored('/abs/path/.bun-cache', sets)).toBe(true);
180
- expect(isPathIgnored('./project/node_modules', sets)).toBe(true);
181
- });
182
- it('ignores .dev.vars and .env files exactly (not substrings)', () => {
183
- expect(isPathIgnored('.dev.vars', sets)).toBe(true);
184
- expect(isPathIgnored('.env', sets)).toBe(true);
185
- expect(isPathIgnored('.env.example', sets)).toBe(false);
186
- expect(isPathIgnored('.env.local', sets)).toBe(false);
187
- });
188
- it('ignores files whose extension is in the extension set', () => {
189
- expect(isPathIgnored('debug.log', sets)).toBe(true);
190
- expect(isPathIgnored('/var/log/app.log', sets)).toBe(true);
191
- expect(isPathIgnored('app.txt', sets)).toBe(false);
192
- });
193
- it('does not ignore ordinary source files', () => {
194
- expect(isPathIgnored('src/index.ts', sets)).toBe(false);
195
- expect(isPathIgnored('package.json', sets)).toBe(false);
196
- expect(isPathIgnored('Makefile', sets)).toBe(false);
197
- });
198
- it('honors merged sets from buildIgnoreSets', () => {
199
- const dir = makeTempDir('honors');
200
- writeFileSync(join(dir, '.gitignore'), 'dist/\n');
201
- const merged = buildIgnoreSets(dir);
202
- expect(isPathIgnored('/repo/dist', merged)).toBe(true);
203
- expect(isPathIgnored('/repo/src', merged)).toBe(false);
204
- });
205
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,38 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import { shouldOutputJson, jsonOut, jsonLine } from '../output.js';
3
- describe('shouldOutputJson', () => {
4
- it('returns true when json flag is true', () => {
5
- expect(shouldOutputJson(true)).toBe(true);
6
- });
7
- it('returns false when json flag is false (--no-json)', () => {
8
- expect(shouldOutputJson(false)).toBe(false);
9
- });
10
- it('returns false when undefined and stdout is TTY', () => {
11
- const original = process.stdout.isTTY;
12
- Object.defineProperty(process.stdout, 'isTTY', { value: true, writable: true });
13
- expect(shouldOutputJson(undefined)).toBe(false);
14
- Object.defineProperty(process.stdout, 'isTTY', { value: original, writable: true });
15
- });
16
- it('returns true when undefined and stdout is not TTY', () => {
17
- const original = process.stdout.isTTY;
18
- Object.defineProperty(process.stdout, 'isTTY', { value: false, writable: true });
19
- expect(shouldOutputJson(undefined)).toBe(true);
20
- Object.defineProperty(process.stdout, 'isTTY', { value: original, writable: true });
21
- });
22
- });
23
- describe('jsonOut', () => {
24
- it('writes JSON to stdout with newline', () => {
25
- const spy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
26
- jsonOut({ hello: 'world' });
27
- expect(spy).toHaveBeenCalledWith('{"hello":"world"}\n');
28
- spy.mockRestore();
29
- });
30
- });
31
- describe('jsonLine', () => {
32
- it('writes a single NDJSON line', () => {
33
- const spy = vi.spyOn(process.stdout, 'write').mockImplementation(() => true);
34
- jsonLine({ event: 'test', ts: 123 });
35
- expect(spy).toHaveBeenCalledWith('{"event":"test","ts":123}\n');
36
- spy.mockRestore();
37
- });
38
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,27 +0,0 @@
1
- import { describe, it, expect, vi } from 'vitest';
2
- import { promptSelect } from '../prompt.js';
3
- describe('promptSelect', () => {
4
- it('throws when no choices available', async () => {
5
- await expect(promptSelect('Pick:', [])).rejects.toThrow('No choices available');
6
- });
7
- it('returns single choice without prompting', async () => {
8
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
9
- const choice = { label: 'Only option', value: 'only' };
10
- const result = await promptSelect('Pick:', [choice]);
11
- expect(result).toBe(choice);
12
- consoleSpy.mockRestore();
13
- });
14
- it('auto-selects preserves all properties on single choice', async () => {
15
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
16
- const choice = { label: 'Test', id: 'abc', extra: true };
17
- const result = await promptSelect('Select', [choice]);
18
- expect(result).toBe(choice);
19
- consoleSpy.mockRestore();
20
- });
21
- it('logs message and choice label when single choice', async () => {
22
- const consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => { });
23
- await promptSelect('Pick one', [{ label: 'Only Option', value: 42 }]);
24
- expect(consoleSpy).toHaveBeenCalledWith('Pick one: Only Option');
25
- consoleSpy.mockRestore();
26
- });
27
- });
@@ -1 +0,0 @@
1
- export {};