runwork 0.15.1 → 0.16.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 (404) hide show
  1. package/bundled-types/task-delegation/task-delegation/types.d.ts +6 -0
  2. package/dist/index.js +20237 -116
  3. package/package.json +4 -4
  4. package/dist/__tests__/curl-parser.test.d.ts +0 -1
  5. package/dist/__tests__/curl-parser.test.js +0 -250
  6. package/dist/__tests__/install-scripts.test.d.ts +0 -1
  7. package/dist/__tests__/install-scripts.test.js +0 -280
  8. package/dist/__tests__/types-manager.test.d.ts +0 -1
  9. package/dist/__tests__/types-manager.test.js +0 -89
  10. package/dist/agents/__tests__/chatgpt-registry.test.d.ts +0 -1
  11. package/dist/agents/__tests__/chatgpt-registry.test.js +0 -61
  12. package/dist/agents/__tests__/claude-code-managed-block.test.d.ts +0 -1
  13. package/dist/agents/__tests__/claude-code-managed-block.test.js +0 -105
  14. package/dist/agents/__tests__/claude-code-plugin.test.d.ts +0 -1
  15. package/dist/agents/__tests__/claude-code-plugin.test.js +0 -47
  16. package/dist/agents/__tests__/claude-code-stats.test.d.ts +0 -1
  17. package/dist/agents/__tests__/claude-code-stats.test.js +0 -390
  18. package/dist/agents/__tests__/claude-desktop-memory.test.d.ts +0 -1
  19. package/dist/agents/__tests__/claude-desktop-memory.test.js +0 -154
  20. package/dist/agents/__tests__/claude-desktop-plugin-tree.test.d.ts +0 -1
  21. package/dist/agents/__tests__/claude-desktop-plugin-tree.test.js +0 -161
  22. package/dist/agents/__tests__/claude-desktop-plugin.test.d.ts +0 -1
  23. package/dist/agents/__tests__/claude-desktop-plugin.test.js +0 -117
  24. package/dist/agents/__tests__/claude-desktop-rpm.test.d.ts +0 -1
  25. package/dist/agents/__tests__/claude-desktop-rpm.test.js +0 -126
  26. package/dist/agents/__tests__/claude-desktop-stats.test.d.ts +0 -1
  27. package/dist/agents/__tests__/claude-desktop-stats.test.js +0 -280
  28. package/dist/agents/__tests__/codex-instructions.test.d.ts +0 -1
  29. package/dist/agents/__tests__/codex-instructions.test.js +0 -57
  30. package/dist/agents/__tests__/codex-minimum-permissions.test.d.ts +0 -1
  31. package/dist/agents/__tests__/codex-minimum-permissions.test.js +0 -82
  32. package/dist/agents/__tests__/codex-stats.test.d.ts +0 -1
  33. package/dist/agents/__tests__/codex-stats.test.js +0 -370
  34. package/dist/agents/__tests__/cursor-merge.test.d.ts +0 -1
  35. package/dist/agents/__tests__/cursor-merge.test.js +0 -66
  36. package/dist/agents/__tests__/cursor-stats.test.d.ts +0 -1
  37. package/dist/agents/__tests__/cursor-stats.test.js +0 -183
  38. package/dist/agents/__tests__/defaults-merge.test.d.ts +0 -1
  39. package/dist/agents/__tests__/defaults-merge.test.js +0 -268
  40. package/dist/agents/__tests__/detection.test.d.ts +0 -1
  41. package/dist/agents/__tests__/detection.test.js +0 -89
  42. package/dist/agents/__tests__/graceful-degradation.test.d.ts +0 -1
  43. package/dist/agents/__tests__/graceful-degradation.test.js +0 -129
  44. package/dist/agents/__tests__/instruction-hint.test.d.ts +0 -1
  45. package/dist/agents/__tests__/instruction-hint.test.js +0 -69
  46. package/dist/agents/__tests__/intro-skill.test.d.ts +0 -1
  47. package/dist/agents/__tests__/intro-skill.test.js +0 -193
  48. package/dist/agents/__tests__/schema-validation.test.d.ts +0 -1
  49. package/dist/agents/__tests__/schema-validation.test.js +0 -212
  50. package/dist/agents/__tests__/skill-slug.test.d.ts +0 -1
  51. package/dist/agents/__tests__/skill-slug.test.js +0 -77
  52. package/dist/agents/claude-code.d.ts +0 -59
  53. package/dist/agents/claude-code.js +0 -753
  54. package/dist/agents/claude-desktop-plugin-tree.d.ts +0 -59
  55. package/dist/agents/claude-desktop-plugin-tree.js +0 -143
  56. package/dist/agents/claude-desktop.d.ts +0 -47
  57. package/dist/agents/claude-desktop.js +0 -684
  58. package/dist/agents/cline.d.ts +0 -15
  59. package/dist/agents/cline.js +0 -130
  60. package/dist/agents/codex.d.ts +0 -44
  61. package/dist/agents/codex.js +0 -453
  62. package/dist/agents/conversation-skills.d.ts +0 -18
  63. package/dist/agents/conversation-skills.js +0 -229
  64. package/dist/agents/cursor.d.ts +0 -35
  65. package/dist/agents/cursor.js +0 -294
  66. package/dist/agents/default-config.d.ts +0 -30
  67. package/dist/agents/default-config.js +0 -67
  68. package/dist/agents/defaults-merge.d.ts +0 -87
  69. package/dist/agents/defaults-merge.js +0 -150
  70. package/dist/agents/detect.d.ts +0 -4
  71. package/dist/agents/detect.js +0 -67
  72. package/dist/agents/detection.d.ts +0 -18
  73. package/dist/agents/detection.js +0 -94
  74. package/dist/agents/gemini.d.ts +0 -15
  75. package/dist/agents/gemini.js +0 -122
  76. package/dist/agents/generic-adapter.d.ts +0 -25
  77. package/dist/agents/generic-adapter.js +0 -151
  78. package/dist/agents/intro-skill.d.ts +0 -45
  79. package/dist/agents/intro-skill.js +0 -447
  80. package/dist/agents/registry-data.d.ts +0 -192
  81. package/dist/agents/registry-data.js +0 -669
  82. package/dist/agents/registry.d.ts +0 -13
  83. package/dist/agents/registry.js +0 -36
  84. package/dist/agents/runtime-detection.d.ts +0 -82
  85. package/dist/agents/runtime-detection.js +0 -271
  86. package/dist/agents/session-start-hook.d.ts +0 -37
  87. package/dist/agents/session-start-hook.js +0 -159
  88. package/dist/agents/types.d.ts +0 -171
  89. package/dist/agents/types.js +0 -75
  90. package/dist/agents/utils/instruction-hint.d.ts +0 -21
  91. package/dist/agents/utils/instruction-hint.js +0 -108
  92. package/dist/agents/utils/json-config.d.ts +0 -19
  93. package/dist/agents/utils/json-config.js +0 -69
  94. package/dist/agents/utils/toml-config.d.ts +0 -8
  95. package/dist/agents/utils/toml-config.js +0 -27
  96. package/dist/agents/windsurf.d.ts +0 -14
  97. package/dist/agents/windsurf.js +0 -102
  98. package/dist/api/__tests__/client.test.d.ts +0 -1
  99. package/dist/api/__tests__/client.test.js +0 -272
  100. package/dist/api/client.d.ts +0 -326
  101. package/dist/api/client.js +0 -427
  102. package/dist/auth/__tests__/login-flow.test.d.ts +0 -1
  103. package/dist/auth/__tests__/login-flow.test.js +0 -101
  104. package/dist/auth/__tests__/store.test.d.ts +0 -1
  105. package/dist/auth/__tests__/store.test.js +0 -132
  106. package/dist/auth/login-flow.d.ts +0 -26
  107. package/dist/auth/login-flow.js +0 -137
  108. package/dist/auth/store.d.ts +0 -5
  109. package/dist/auth/store.js +0 -62
  110. package/dist/commands/__tests__/clone-args.test.d.ts +0 -1
  111. package/dist/commands/__tests__/clone-args.test.js +0 -51
  112. package/dist/commands/__tests__/clone-source-result.test.d.ts +0 -1
  113. package/dist/commands/__tests__/clone-source-result.test.js +0 -45
  114. package/dist/commands/__tests__/info-merge.test.d.ts +0 -1
  115. package/dist/commands/__tests__/info-merge.test.js +0 -55
  116. package/dist/commands/__tests__/mcp-entries.test.d.ts +0 -1
  117. package/dist/commands/__tests__/mcp-entries.test.js +0 -48
  118. package/dist/commands/__tests__/setup-persona.test.d.ts +0 -1
  119. package/dist/commands/__tests__/setup-persona.test.js +0 -31
  120. package/dist/commands/__tests__/setup.test.d.ts +0 -1
  121. package/dist/commands/__tests__/setup.test.js +0 -81
  122. package/dist/commands/__tests__/sync-redetect.test.d.ts +0 -1
  123. package/dist/commands/__tests__/sync-redetect.test.js +0 -96
  124. package/dist/commands/__tests__/sync-telemetry.test.d.ts +0 -1
  125. package/dist/commands/__tests__/sync-telemetry.test.js +0 -281
  126. package/dist/commands/__tests__/upgrade.test.d.ts +0 -1
  127. package/dist/commands/__tests__/upgrade.test.js +0 -157
  128. package/dist/commands/agents.d.ts +0 -2
  129. package/dist/commands/agents.js +0 -160
  130. package/dist/commands/api-keys.d.ts +0 -2
  131. package/dist/commands/api-keys.js +0 -95
  132. package/dist/commands/apps.d.ts +0 -2
  133. package/dist/commands/apps.js +0 -82
  134. package/dist/commands/build-plugin.d.ts +0 -2
  135. package/dist/commands/build-plugin.js +0 -135
  136. package/dist/commands/clone.d.ts +0 -60
  137. package/dist/commands/clone.js +0 -271
  138. package/dist/commands/components.d.ts +0 -2
  139. package/dist/commands/components.js +0 -43
  140. package/dist/commands/deploy.d.ts +0 -2
  141. package/dist/commands/deploy.js +0 -279
  142. package/dist/commands/dev.d.ts +0 -11
  143. package/dist/commands/dev.js +0 -1011
  144. package/dist/commands/doctor.d.ts +0 -2
  145. package/dist/commands/doctor.js +0 -230
  146. package/dist/commands/endpoints.d.ts +0 -2
  147. package/dist/commands/endpoints.js +0 -189
  148. package/dist/commands/entities.d.ts +0 -2
  149. package/dist/commands/entities.js +0 -198
  150. package/dist/commands/files.d.ts +0 -2
  151. package/dist/commands/files.js +0 -193
  152. package/dist/commands/inbox.d.ts +0 -11
  153. package/dist/commands/inbox.js +0 -60
  154. package/dist/commands/info.d.ts +0 -178
  155. package/dist/commands/info.js +0 -455
  156. package/dist/commands/init.d.ts +0 -21
  157. package/dist/commands/init.js +0 -185
  158. package/dist/commands/integrations.d.ts +0 -2
  159. package/dist/commands/integrations.js +0 -233
  160. package/dist/commands/login.d.ts +0 -2
  161. package/dist/commands/login.js +0 -44
  162. package/dist/commands/logout.d.ts +0 -2
  163. package/dist/commands/logout.js +0 -13
  164. package/dist/commands/logs.d.ts +0 -2
  165. package/dist/commands/logs.js +0 -232
  166. package/dist/commands/mcp-entries.d.ts +0 -13
  167. package/dist/commands/mcp-entries.js +0 -26
  168. package/dist/commands/mcp.d.ts +0 -2
  169. package/dist/commands/mcp.js +0 -245
  170. package/dist/commands/open.d.ts +0 -2
  171. package/dist/commands/open.js +0 -53
  172. package/dist/commands/resume.d.ts +0 -2
  173. package/dist/commands/resume.js +0 -289
  174. package/dist/commands/save-convo.d.ts +0 -8
  175. package/dist/commands/save-convo.js +0 -20
  176. package/dist/commands/schedules.d.ts +0 -2
  177. package/dist/commands/schedules.js +0 -221
  178. package/dist/commands/setup.d.ts +0 -27
  179. package/dist/commands/setup.js +0 -177
  180. package/dist/commands/share-convo.d.ts +0 -24
  181. package/dist/commands/share-convo.js +0 -167
  182. package/dist/commands/skills.d.ts +0 -2
  183. package/dist/commands/skills.js +0 -352
  184. package/dist/commands/sync-telemetry.d.ts +0 -33
  185. package/dist/commands/sync-telemetry.js +0 -186
  186. package/dist/commands/sync.d.ts +0 -37
  187. package/dist/commands/sync.js +0 -702
  188. package/dist/commands/uninstall.d.ts +0 -2
  189. package/dist/commands/uninstall.js +0 -145
  190. package/dist/commands/upgrade.d.ts +0 -14
  191. package/dist/commands/upgrade.js +0 -217
  192. package/dist/commands/validate.d.ts +0 -2
  193. package/dist/commands/validate.js +0 -89
  194. package/dist/commands/welcome.d.ts +0 -1
  195. package/dist/commands/welcome.js +0 -86
  196. package/dist/commands/workflows.d.ts +0 -2
  197. package/dist/commands/workflows.js +0 -187
  198. package/dist/deploy/__tests__/deploy-state.test.d.ts +0 -1
  199. package/dist/deploy/__tests__/deploy-state.test.js +0 -80
  200. package/dist/deploy/__tests__/deploy-status.test.d.ts +0 -1
  201. package/dist/deploy/__tests__/deploy-status.test.js +0 -41
  202. package/dist/deploy/__tests__/detach-args.test.d.ts +0 -1
  203. package/dist/deploy/__tests__/detach-args.test.js +0 -30
  204. package/dist/deploy/deploy-state.d.ts +0 -36
  205. package/dist/deploy/deploy-state.js +0 -63
  206. package/dist/deploy/deploy-status.d.ts +0 -21
  207. package/dist/deploy/deploy-status.js +0 -36
  208. package/dist/deploy/detach.d.ts +0 -32
  209. package/dist/deploy/detach.js +0 -71
  210. package/dist/dev/__tests__/attach.test.d.ts +0 -1
  211. package/dist/dev/__tests__/attach.test.js +0 -296
  212. package/dist/dev/__tests__/detach.test.d.ts +0 -1
  213. package/dist/dev/__tests__/detach.test.js +0 -404
  214. package/dist/dev/__tests__/preview-url-poller.test.d.ts +0 -1
  215. package/dist/dev/__tests__/preview-url-poller.test.js +0 -149
  216. package/dist/dev/__tests__/session.test.d.ts +0 -1
  217. package/dist/dev/__tests__/session.test.js +0 -446
  218. package/dist/dev/__tests__/startup-sync.test.d.ts +0 -1
  219. package/dist/dev/__tests__/startup-sync.test.js +0 -32
  220. package/dist/dev/__tests__/stop.test.d.ts +0 -1
  221. package/dist/dev/__tests__/stop.test.js +0 -172
  222. package/dist/dev/attach.d.ts +0 -120
  223. package/dist/dev/attach.js +0 -269
  224. package/dist/dev/detach.d.ts +0 -187
  225. package/dist/dev/detach.js +0 -292
  226. package/dist/dev/preview-url-poller.d.ts +0 -35
  227. package/dist/dev/preview-url-poller.js +0 -50
  228. package/dist/dev/session.d.ts +0 -175
  229. package/dist/dev/session.js +0 -258
  230. package/dist/dev/startup-sync.d.ts +0 -23
  231. package/dist/dev/startup-sync.js +0 -14
  232. package/dist/dev/stop.d.ts +0 -52
  233. package/dist/dev/stop.js +0 -101
  234. package/dist/devtools/registry-data.d.ts +0 -46
  235. package/dist/devtools/registry-data.js +0 -40
  236. package/dist/generated/bundled-types.d.ts +0 -1
  237. package/dist/generated/bundled-types.js +0 -46
  238. package/dist/generated/version.d.ts +0 -1
  239. package/dist/generated/version.js +0 -2
  240. package/dist/git/__tests__/auto-commit.test.d.ts +0 -1
  241. package/dist/git/__tests__/auto-commit.test.js +0 -431
  242. package/dist/git/__tests__/classify-sync-error.test.d.ts +0 -1
  243. package/dist/git/__tests__/classify-sync-error.test.js +0 -57
  244. package/dist/git/__tests__/credential-helper-e2e.test.d.ts +0 -21
  245. package/dist/git/__tests__/credential-helper-e2e.test.js +0 -195
  246. package/dist/git/__tests__/credentials.test.d.ts +0 -1
  247. package/dist/git/__tests__/credentials.test.js +0 -141
  248. package/dist/git/__tests__/deploy-guard.test.d.ts +0 -1
  249. package/dist/git/__tests__/deploy-guard.test.js +0 -61
  250. package/dist/git/__tests__/ensure-git-credential-helper.test.d.ts +0 -1
  251. package/dist/git/__tests__/ensure-git-credential-helper.test.js +0 -133
  252. package/dist/git/__tests__/ensure-runwork-remote.test.d.ts +0 -1
  253. package/dist/git/__tests__/ensure-runwork-remote.test.js +0 -109
  254. package/dist/git/__tests__/identity.test.d.ts +0 -1
  255. package/dist/git/__tests__/identity.test.js +0 -146
  256. package/dist/git/__tests__/manifest.test.d.ts +0 -1
  257. package/dist/git/__tests__/manifest.test.js +0 -446
  258. package/dist/git/__tests__/preflight-resolution.test.d.ts +0 -1
  259. package/dist/git/__tests__/preflight-resolution.test.js +0 -366
  260. package/dist/git/__tests__/preflight.test.d.ts +0 -1
  261. package/dist/git/__tests__/preflight.test.js +0 -36
  262. package/dist/git/__tests__/repo-config.test.d.ts +0 -1
  263. package/dist/git/__tests__/repo-config.test.js +0 -26
  264. package/dist/git/__tests__/sync.test.d.ts +0 -1
  265. package/dist/git/__tests__/sync.test.js +0 -405
  266. package/dist/git/auto-commit.d.ts +0 -35
  267. package/dist/git/auto-commit.js +0 -293
  268. package/dist/git/classify-sync-error.d.ts +0 -21
  269. package/dist/git/classify-sync-error.js +0 -111
  270. package/dist/git/credentials.d.ts +0 -75
  271. package/dist/git/credentials.js +0 -164
  272. package/dist/git/critical-files.d.ts +0 -20
  273. package/dist/git/critical-files.js +0 -68
  274. package/dist/git/deploy-guard.d.ts +0 -53
  275. package/dist/git/deploy-guard.js +0 -78
  276. package/dist/git/identity.d.ts +0 -44
  277. package/dist/git/identity.js +0 -133
  278. package/dist/git/preflight.d.ts +0 -57
  279. package/dist/git/preflight.js +0 -276
  280. package/dist/git/remote.d.ts +0 -37
  281. package/dist/git/remote.js +0 -75
  282. package/dist/git/repo-config.d.ts +0 -8
  283. package/dist/git/repo-config.js +0 -29
  284. package/dist/git/sync.d.ts +0 -15
  285. package/dist/git/sync.js +0 -159
  286. package/dist/health/__tests__/checks.test.d.ts +0 -1
  287. package/dist/health/__tests__/checks.test.js +0 -357
  288. package/dist/health/__tests__/cli-distribution-checks.test.d.ts +0 -1
  289. package/dist/health/__tests__/cli-distribution-checks.test.js +0 -196
  290. package/dist/health/__tests__/fix.test.d.ts +0 -1
  291. package/dist/health/__tests__/fix.test.js +0 -72
  292. package/dist/health/__tests__/runner-filter.test.d.ts +0 -1
  293. package/dist/health/__tests__/runner-filter.test.js +0 -61
  294. package/dist/health/checks.d.ts +0 -42
  295. package/dist/health/checks.js +0 -636
  296. package/dist/health/fix.d.ts +0 -22
  297. package/dist/health/fix.js +0 -62
  298. package/dist/health/runner.d.ts +0 -8
  299. package/dist/health/runner.js +0 -47
  300. package/dist/health/types.d.ts +0 -12
  301. package/dist/health/types.js +0 -1
  302. package/dist/index.d.ts +0 -1
  303. package/dist/logs/__tests__/tailer-format.test.d.ts +0 -1
  304. package/dist/logs/__tests__/tailer-format.test.js +0 -43
  305. package/dist/logs/tailer.d.ts +0 -17
  306. package/dist/logs/tailer.js +0 -217
  307. package/dist/sync/__tests__/change-detect.test.d.ts +0 -1
  308. package/dist/sync/__tests__/change-detect.test.js +0 -123
  309. package/dist/sync/__tests__/hash.test.d.ts +0 -1
  310. package/dist/sync/__tests__/hash.test.js +0 -18
  311. package/dist/sync/change-detect.d.ts +0 -19
  312. package/dist/sync/change-detect.js +0 -136
  313. package/dist/sync/conflict-ui.d.ts +0 -5
  314. package/dist/sync/conflict-ui.js +0 -78
  315. package/dist/sync/executor.d.ts +0 -23
  316. package/dist/sync/executor.js +0 -102
  317. package/dist/sync/hash.d.ts +0 -1
  318. package/dist/sync/hash.js +0 -4
  319. package/dist/sync/types.d.ts +0 -24
  320. package/dist/sync/types.js +0 -1
  321. package/dist/template/manifest.d.ts +0 -17
  322. package/dist/template/manifest.js +0 -145
  323. package/dist/tools/types.d.ts +0 -52
  324. package/dist/tools/types.js +0 -8
  325. package/dist/types-manager.d.ts +0 -1
  326. package/dist/types-manager.js +0 -35
  327. package/dist/types.d.ts +0 -349
  328. package/dist/types.js +0 -1
  329. package/dist/ui/__tests__/banner.test.d.ts +0 -1
  330. package/dist/ui/__tests__/banner.test.js +0 -98
  331. package/dist/ui/__tests__/colors.test.d.ts +0 -1
  332. package/dist/ui/__tests__/colors.test.js +0 -22
  333. package/dist/ui/__tests__/keyboard.test.d.ts +0 -1
  334. package/dist/ui/__tests__/keyboard.test.js +0 -34
  335. package/dist/ui/__tests__/status-line.test.d.ts +0 -1
  336. package/dist/ui/__tests__/status-line.test.js +0 -54
  337. package/dist/ui/banner.d.ts +0 -29
  338. package/dist/ui/banner.js +0 -153
  339. package/dist/ui/colors.d.ts +0 -4
  340. package/dist/ui/colors.js +0 -7
  341. package/dist/ui/keyboard.d.ts +0 -12
  342. package/dist/ui/keyboard.js +0 -61
  343. package/dist/ui/status-line.d.ts +0 -6
  344. package/dist/ui/status-line.js +0 -53
  345. package/dist/utils/__tests__/format-error.test.d.ts +0 -1
  346. package/dist/utils/__tests__/format-error.test.js +0 -43
  347. package/dist/utils/__tests__/help-json.test.d.ts +0 -1
  348. package/dist/utils/__tests__/help-json.test.js +0 -39
  349. package/dist/utils/__tests__/http.test.d.ts +0 -1
  350. package/dist/utils/__tests__/http.test.js +0 -381
  351. package/dist/utils/__tests__/ignore-matcher.test.d.ts +0 -1
  352. package/dist/utils/__tests__/ignore-matcher.test.js +0 -205
  353. package/dist/utils/__tests__/output.test.d.ts +0 -1
  354. package/dist/utils/__tests__/output.test.js +0 -38
  355. package/dist/utils/__tests__/prompt.test.d.ts +0 -1
  356. package/dist/utils/__tests__/prompt.test.js +0 -27
  357. package/dist/utils/__tests__/resolve.test.d.ts +0 -1
  358. package/dist/utils/__tests__/resolve.test.js +0 -95
  359. package/dist/utils/__tests__/sqlite.test.d.ts +0 -1
  360. package/dist/utils/__tests__/sqlite.test.js +0 -89
  361. package/dist/utils/agent-guidance.d.ts +0 -47
  362. package/dist/utils/agent-guidance.js +0 -128
  363. package/dist/utils/app-info.d.ts +0 -70
  364. package/dist/utils/app-info.js +0 -167
  365. package/dist/utils/curl-parser.d.ts +0 -12
  366. package/dist/utils/curl-parser.js +0 -162
  367. package/dist/utils/data-input.d.ts +0 -1
  368. package/dist/utils/data-input.js +0 -38
  369. package/dist/utils/format-error.d.ts +0 -10
  370. package/dist/utils/format-error.js +0 -38
  371. package/dist/utils/fs.d.ts +0 -5
  372. package/dist/utils/fs.js +0 -23
  373. package/dist/utils/help-json.d.ts +0 -70
  374. package/dist/utils/help-json.js +0 -88
  375. package/dist/utils/http.d.ts +0 -46
  376. package/dist/utils/http.js +0 -421
  377. package/dist/utils/ignore-matcher.d.ts +0 -47
  378. package/dist/utils/ignore-matcher.js +0 -132
  379. package/dist/utils/output.d.ts +0 -17
  380. package/dist/utils/output.js +0 -27
  381. package/dist/utils/prompt.d.ts +0 -5
  382. package/dist/utils/prompt.js +0 -42
  383. package/dist/utils/resolve.d.ts +0 -12
  384. package/dist/utils/resolve.js +0 -52
  385. package/dist/utils/setup-state.d.ts +0 -3
  386. package/dist/utils/setup-state.js +0 -19
  387. package/dist/utils/sqlite-adapter.d.ts +0 -48
  388. package/dist/utils/sqlite-adapter.js +0 -147
  389. package/dist/utils/sqlite.d.ts +0 -14
  390. package/dist/utils/sqlite.js +0 -14
  391. package/dist/utils/subprocess.d.ts +0 -19
  392. package/dist/utils/subprocess.js +0 -27
  393. package/dist/utils/which.d.ts +0 -14
  394. package/dist/utils/which.js +0 -47
  395. package/dist/utils/zip.d.ts +0 -7
  396. package/dist/utils/zip.js +0 -42
  397. package/dist/validate/__tests__/validate.test.d.ts +0 -1
  398. package/dist/validate/__tests__/validate.test.js +0 -42
  399. package/dist/validate/freshness.d.ts +0 -28
  400. package/dist/validate/freshness.js +0 -48
  401. package/dist/validate/preview.d.ts +0 -21
  402. package/dist/validate/preview.js +0 -39
  403. package/dist/workspace/resolve.d.ts +0 -19
  404. 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 {};