@sentry/warden 0.1.0 → 0.2.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 (588) hide show
  1. package/dist/cli/commands/init.d.ts.map +1 -1
  2. package/dist/cli/commands/init.js +3 -1
  3. package/dist/cli/commands/init.js.map +1 -1
  4. package/dist/cli/commands/setup-app/manifest.d.ts.map +1 -1
  5. package/dist/cli/commands/setup-app/manifest.js +3 -1
  6. package/dist/cli/commands/setup-app/manifest.js.map +1 -1
  7. package/dist/cli/commands/setup-app.js +1 -1
  8. package/dist/cli/commands/setup-app.js.map +1 -1
  9. package/dist/cli/files.d.ts +11 -1
  10. package/dist/cli/files.d.ts.map +1 -1
  11. package/dist/cli/files.js +145 -4
  12. package/dist/cli/files.js.map +1 -1
  13. package/dist/cli/git.d.ts.map +1 -1
  14. package/dist/cli/git.js +5 -9
  15. package/dist/cli/git.js.map +1 -1
  16. package/dist/cli/index.js +0 -0
  17. package/dist/cli/output/icons.d.ts +4 -0
  18. package/dist/cli/output/icons.d.ts.map +1 -1
  19. package/dist/cli/output/icons.js +4 -0
  20. package/dist/cli/output/icons.js.map +1 -1
  21. package/dist/cli/output/ink-runner.d.ts +20 -0
  22. package/dist/cli/output/ink-runner.d.ts.map +1 -1
  23. package/dist/cli/output/ink-runner.js +53 -19
  24. package/dist/cli/output/ink-runner.js.map +1 -1
  25. package/dist/cli/output/tasks.d.ts.map +1 -1
  26. package/dist/cli/output/tasks.js +5 -1
  27. package/dist/cli/output/tasks.js.map +1 -1
  28. package/dist/config/schema.d.ts.map +1 -1
  29. package/dist/config/schema.js +15 -1
  30. package/dist/config/schema.js.map +1 -1
  31. package/dist/diff/coalesce.d.ts +32 -2
  32. package/dist/diff/coalesce.d.ts.map +1 -1
  33. package/dist/diff/coalesce.js +174 -2
  34. package/dist/diff/coalesce.js.map +1 -1
  35. package/dist/output/dedup.d.ts.map +1 -1
  36. package/dist/output/dedup.js +8 -3
  37. package/dist/output/dedup.js.map +1 -1
  38. package/dist/output/renderer.d.ts.map +1 -1
  39. package/dist/output/renderer.js +49 -5
  40. package/dist/output/renderer.js.map +1 -1
  41. package/dist/output/stale.d.ts.map +1 -1
  42. package/dist/output/stale.js +7 -0
  43. package/dist/output/stale.js.map +1 -1
  44. package/dist/output/types.d.ts +15 -1
  45. package/dist/output/types.d.ts.map +1 -1
  46. package/dist/sdk/analyze.d.ts +18 -0
  47. package/dist/sdk/analyze.d.ts.map +1 -0
  48. package/dist/sdk/analyze.js +425 -0
  49. package/dist/sdk/analyze.js.map +1 -0
  50. package/dist/sdk/errors.d.ts +23 -0
  51. package/dist/sdk/errors.d.ts.map +1 -0
  52. package/dist/sdk/errors.js +72 -0
  53. package/dist/sdk/errors.js.map +1 -0
  54. package/dist/sdk/extract.d.ts +44 -0
  55. package/dist/sdk/extract.d.ts.map +1 -0
  56. package/dist/sdk/extract.js +224 -0
  57. package/dist/sdk/extract.js.map +1 -0
  58. package/dist/sdk/prepare.d.ts +13 -0
  59. package/dist/sdk/prepare.d.ts.map +1 -0
  60. package/dist/sdk/prepare.js +73 -0
  61. package/dist/sdk/prepare.js.map +1 -0
  62. package/dist/sdk/prompt.d.ts +30 -0
  63. package/dist/sdk/prompt.d.ts.map +1 -0
  64. package/dist/sdk/prompt.js +109 -0
  65. package/dist/sdk/prompt.js.map +1 -0
  66. package/dist/sdk/retry.d.ts +12 -0
  67. package/dist/sdk/retry.d.ts.map +1 -0
  68. package/dist/sdk/retry.js +31 -0
  69. package/dist/sdk/retry.js.map +1 -0
  70. package/dist/sdk/runner.d.ts +22 -199
  71. package/dist/sdk/runner.d.ts.map +1 -1
  72. package/dist/sdk/runner.js +26 -884
  73. package/dist/sdk/runner.js.map +1 -1
  74. package/dist/sdk/types.d.ts +127 -0
  75. package/dist/sdk/types.d.ts.map +1 -0
  76. package/dist/sdk/types.js +5 -0
  77. package/dist/sdk/types.js.map +1 -0
  78. package/dist/sdk/usage.d.ts +20 -0
  79. package/dist/sdk/usage.d.ts.map +1 -0
  80. package/dist/sdk/usage.js +44 -0
  81. package/dist/sdk/usage.js.map +1 -0
  82. package/dist/skills/remote.d.ts.map +1 -1
  83. package/dist/skills/remote.js +3 -7
  84. package/dist/skills/remote.js.map +1 -1
  85. package/dist/types/index.d.ts +1 -0
  86. package/dist/types/index.d.ts.map +1 -1
  87. package/dist/types/index.js +2 -0
  88. package/dist/types/index.js.map +1 -1
  89. package/dist/utils/exec.d.ts +61 -0
  90. package/dist/utils/exec.d.ts.map +1 -0
  91. package/dist/utils/exec.js +111 -0
  92. package/dist/utils/exec.js.map +1 -0
  93. package/dist/utils/index.d.ts +2 -0
  94. package/dist/utils/index.d.ts.map +1 -1
  95. package/dist/utils/index.js +1 -0
  96. package/dist/utils/index.js.map +1 -1
  97. package/package.json +15 -16
  98. package/.agents/skills/find-bugs/SKILL.md +0 -75
  99. package/.agents/skills/vercel-react-best-practices/AGENTS.md +0 -2934
  100. package/.agents/skills/vercel-react-best-practices/SKILL.md +0 -136
  101. package/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  102. package/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  103. package/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  104. package/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  105. package/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
  106. package/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  107. package/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
  108. package/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  109. package/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
  110. package/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  111. package/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  112. package/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  113. package/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  114. package/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  115. package/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  116. package/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  117. package/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  118. package/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  119. package/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  120. package/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  121. package/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  122. package/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  123. package/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  124. package/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  125. package/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  126. package/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  127. package/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  128. package/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  129. package/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  130. package/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  131. package/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  132. package/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  133. package/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  134. package/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  135. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  136. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  137. package/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  138. package/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  139. package/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  140. package/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  141. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  142. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  143. package/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  144. package/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  145. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  146. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  147. package/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  148. package/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  149. package/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  150. package/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  151. package/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  152. package/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  153. package/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  154. package/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  155. package/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  156. package/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  157. package/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
  158. package/.claude/settings.json +0 -57
  159. package/.claude/skills/agent-prompt/SKILL.md +0 -54
  160. package/.claude/skills/agent-prompt/references/agentic-patterns.md +0 -94
  161. package/.claude/skills/agent-prompt/references/anti-patterns.md +0 -140
  162. package/.claude/skills/agent-prompt/references/context-design.md +0 -124
  163. package/.claude/skills/agent-prompt/references/core-principles.md +0 -75
  164. package/.claude/skills/agent-prompt/references/model-guidance.md +0 -118
  165. package/.claude/skills/agent-prompt/references/output-formats.md +0 -98
  166. package/.claude/skills/agent-prompt/references/skill-structure.md +0 -115
  167. package/.claude/skills/agent-prompt/references/system-prompts.md +0 -115
  168. package/.claude/skills/notseer/SKILL.md +0 -131
  169. package/.claude/skills/skill-writer/SKILL.md +0 -140
  170. package/.claude/skills/testing-guidelines/SKILL.md +0 -132
  171. package/.claude/skills/warden-skill/SKILL.md +0 -250
  172. package/.claude/skills/warden-skill/references/config-schema.md +0 -133
  173. package/.dex/config.toml +0 -2
  174. package/.github/workflows/ci.yml +0 -33
  175. package/.github/workflows/release.yml +0 -59
  176. package/.github/workflows/warden.yml +0 -40
  177. package/AGENTS.md +0 -89
  178. package/CONTRIBUTING.md +0 -60
  179. package/SPEC.md +0 -263
  180. package/action.yml +0 -87
  181. package/assets/favicon.png +0 -0
  182. package/assets/warden-icon-bw.svg +0 -5
  183. package/assets/warden-icon-purple.png +0 -0
  184. package/assets/warden-icon-purple.svg +0 -5
  185. package/dist/action/159.index.js +0 -523
  186. package/dist/action/159.index.js.map +0 -1
  187. package/dist/action/action/index.d.ts +0 -2
  188. package/dist/action/action/index.d.ts.map +0 -1
  189. package/dist/action/action/main.d.ts +0 -2
  190. package/dist/action/action/main.d.ts.map +0 -1
  191. package/dist/action/cli/args.d.ts +0 -74
  192. package/dist/action/cli/args.d.ts.map +0 -1
  193. package/dist/action/cli/args.test.d.ts +0 -2
  194. package/dist/action/cli/args.test.d.ts.map +0 -1
  195. package/dist/action/cli/commands/add.d.ts +0 -7
  196. package/dist/action/cli/commands/add.d.ts.map +0 -1
  197. package/dist/action/cli/commands/init.d.ts +0 -10
  198. package/dist/action/cli/commands/init.d.ts.map +0 -1
  199. package/dist/action/cli/commands/init.test.d.ts +0 -2
  200. package/dist/action/cli/commands/init.test.d.ts.map +0 -1
  201. package/dist/action/cli/commands/setup-app/browser.d.ts +0 -9
  202. package/dist/action/cli/commands/setup-app/browser.d.ts.map +0 -1
  203. package/dist/action/cli/commands/setup-app/credentials.d.ts +0 -15
  204. package/dist/action/cli/commands/setup-app/credentials.d.ts.map +0 -1
  205. package/dist/action/cli/commands/setup-app/manifest.d.ts +0 -24
  206. package/dist/action/cli/commands/setup-app/manifest.d.ts.map +0 -1
  207. package/dist/action/cli/commands/setup-app/server.d.ts +0 -28
  208. package/dist/action/cli/commands/setup-app/server.d.ts.map +0 -1
  209. package/dist/action/cli/commands/setup-app.d.ts +0 -11
  210. package/dist/action/cli/commands/setup-app.d.ts.map +0 -1
  211. package/dist/action/cli/commands/sync.d.ts +0 -9
  212. package/dist/action/cli/commands/sync.d.ts.map +0 -1
  213. package/dist/action/cli/context.d.ts +0 -27
  214. package/dist/action/cli/context.d.ts.map +0 -1
  215. package/dist/action/cli/files.d.ts +0 -22
  216. package/dist/action/cli/files.d.ts.map +0 -1
  217. package/dist/action/cli/files.test.d.ts +0 -2
  218. package/dist/action/cli/files.test.d.ts.map +0 -1
  219. package/dist/action/cli/fix.d.ts +0 -41
  220. package/dist/action/cli/fix.d.ts.map +0 -1
  221. package/dist/action/cli/fix.test.d.ts +0 -2
  222. package/dist/action/cli/fix.test.d.ts.map +0 -1
  223. package/dist/action/cli/git.d.ts +0 -73
  224. package/dist/action/cli/git.d.ts.map +0 -1
  225. package/dist/action/cli/git.test.d.ts +0 -2
  226. package/dist/action/cli/git.test.d.ts.map +0 -1
  227. package/dist/action/cli/index.d.ts +0 -3
  228. package/dist/action/cli/index.d.ts.map +0 -1
  229. package/dist/action/cli/main.d.ts +0 -7
  230. package/dist/action/cli/main.d.ts.map +0 -1
  231. package/dist/action/cli/output/box.d.ts +0 -75
  232. package/dist/action/cli/output/box.d.ts.map +0 -1
  233. package/dist/action/cli/output/formatters.d.ts +0 -90
  234. package/dist/action/cli/output/formatters.d.ts.map +0 -1
  235. package/dist/action/cli/output/formatters.test.d.ts +0 -2
  236. package/dist/action/cli/output/formatters.test.d.ts.map +0 -1
  237. package/dist/action/cli/output/icons.d.ts +0 -11
  238. package/dist/action/cli/output/icons.d.ts.map +0 -1
  239. package/dist/action/cli/output/index.d.ts +0 -10
  240. package/dist/action/cli/output/index.d.ts.map +0 -1
  241. package/dist/action/cli/output/ink-runner.d.ts +0 -9
  242. package/dist/action/cli/output/ink-runner.d.ts.map +0 -1
  243. package/dist/action/cli/output/jsonl.d.ts +0 -43
  244. package/dist/action/cli/output/jsonl.d.ts.map +0 -1
  245. package/dist/action/cli/output/jsonl.test.d.ts +0 -2
  246. package/dist/action/cli/output/jsonl.test.d.ts.map +0 -1
  247. package/dist/action/cli/output/reporter.d.ts +0 -108
  248. package/dist/action/cli/output/reporter.d.ts.map +0 -1
  249. package/dist/action/cli/output/tasks.d.ts +0 -89
  250. package/dist/action/cli/output/tasks.d.ts.map +0 -1
  251. package/dist/action/cli/output/tty.d.ts +0 -21
  252. package/dist/action/cli/output/tty.d.ts.map +0 -1
  253. package/dist/action/cli/output/tty.test.d.ts +0 -2
  254. package/dist/action/cli/output/tty.test.d.ts.map +0 -1
  255. package/dist/action/cli/output/verbosity.d.ts +0 -20
  256. package/dist/action/cli/output/verbosity.d.ts.map +0 -1
  257. package/dist/action/cli/output/verbosity.test.d.ts +0 -2
  258. package/dist/action/cli/output/verbosity.test.d.ts.map +0 -1
  259. package/dist/action/cli/terminal.d.ts +0 -19
  260. package/dist/action/cli/terminal.d.ts.map +0 -1
  261. package/dist/action/cli/terminal.test.d.ts +0 -2
  262. package/dist/action/cli/terminal.test.d.ts.map +0 -1
  263. package/dist/action/config/index.d.ts +0 -4
  264. package/dist/action/config/index.d.ts.map +0 -1
  265. package/dist/action/config/loader.d.ts +0 -27
  266. package/dist/action/config/loader.d.ts.map +0 -1
  267. package/dist/action/config/loader.test.d.ts +0 -2
  268. package/dist/action/config/loader.test.d.ts.map +0 -1
  269. package/dist/action/config/schema.d.ts +0 -318
  270. package/dist/action/config/schema.d.ts.map +0 -1
  271. package/dist/action/config/writer.d.ts +0 -11
  272. package/dist/action/config/writer.d.ts.map +0 -1
  273. package/dist/action/config/writer.test.d.ts +0 -2
  274. package/dist/action/config/writer.test.d.ts.map +0 -1
  275. package/dist/action/diff/classify.d.ts +0 -29
  276. package/dist/action/diff/classify.d.ts.map +0 -1
  277. package/dist/action/diff/classify.test.d.ts +0 -2
  278. package/dist/action/diff/classify.test.d.ts.map +0 -1
  279. package/dist/action/diff/coalesce.d.ts +0 -42
  280. package/dist/action/diff/coalesce.d.ts.map +0 -1
  281. package/dist/action/diff/coalesce.test.d.ts +0 -2
  282. package/dist/action/diff/coalesce.test.d.ts.map +0 -1
  283. package/dist/action/diff/context.d.ts +0 -30
  284. package/dist/action/diff/context.d.ts.map +0 -1
  285. package/dist/action/diff/context.test.d.ts +0 -2
  286. package/dist/action/diff/context.test.d.ts.map +0 -1
  287. package/dist/action/diff/index.d.ts +0 -5
  288. package/dist/action/diff/index.d.ts.map +0 -1
  289. package/dist/action/diff/parser.d.ts +0 -52
  290. package/dist/action/diff/parser.d.ts.map +0 -1
  291. package/dist/action/diff/parser.test.d.ts +0 -2
  292. package/dist/action/diff/parser.test.d.ts.map +0 -1
  293. package/dist/action/event/context.d.ts +0 -9
  294. package/dist/action/event/context.d.ts.map +0 -1
  295. package/dist/action/event/index.d.ts +0 -3
  296. package/dist/action/event/index.d.ts.map +0 -1
  297. package/dist/action/event/schedule-context.d.ts +0 -30
  298. package/dist/action/event/schedule-context.d.ts.map +0 -1
  299. package/dist/action/examples/examples.integration.test.d.ts +0 -2
  300. package/dist/action/examples/examples.integration.test.d.ts.map +0 -1
  301. package/dist/action/examples/index.d.ts +0 -50
  302. package/dist/action/examples/index.d.ts.map +0 -1
  303. package/dist/action/examples/index.test.d.ts +0 -2
  304. package/dist/action/examples/index.test.d.ts.map +0 -1
  305. package/dist/action/examples/setup.d.ts +0 -2
  306. package/dist/action/examples/setup.d.ts.map +0 -1
  307. package/dist/action/index.d.ts +0 -11
  308. package/dist/action/index.d.ts.map +0 -1
  309. package/dist/action/index.js +0 -38231
  310. package/dist/action/index.js.map +0 -1
  311. package/dist/action/licenses.txt +0 -992
  312. package/dist/action/main.d.ts +0 -2
  313. package/dist/action/main.d.ts.map +0 -1
  314. package/dist/action/main.js +0 -707
  315. package/dist/action/main.js.map +0 -1
  316. package/dist/action/output/dedup.d.ts +0 -153
  317. package/dist/action/output/dedup.d.ts.map +0 -1
  318. package/dist/action/output/dedup.test.d.ts +0 -2
  319. package/dist/action/output/dedup.test.d.ts.map +0 -1
  320. package/dist/action/output/github-checks.d.ts +0 -106
  321. package/dist/action/output/github-checks.d.ts.map +0 -1
  322. package/dist/action/output/github-checks.test.d.ts +0 -2
  323. package/dist/action/output/github-checks.test.d.ts.map +0 -1
  324. package/dist/action/output/github-issues.d.ts +0 -35
  325. package/dist/action/output/github-issues.d.ts.map +0 -1
  326. package/dist/action/output/index.d.ts +0 -6
  327. package/dist/action/output/index.d.ts.map +0 -1
  328. package/dist/action/output/issue-renderer.d.ts +0 -20
  329. package/dist/action/output/issue-renderer.d.ts.map +0 -1
  330. package/dist/action/output/renderer.d.ts +0 -4
  331. package/dist/action/output/renderer.d.ts.map +0 -1
  332. package/dist/action/output/renderer.test.d.ts +0 -2
  333. package/dist/action/output/renderer.test.d.ts.map +0 -1
  334. package/dist/action/output/stale.d.ts +0 -31
  335. package/dist/action/output/stale.d.ts.map +0 -1
  336. package/dist/action/output/stale.test.d.ts +0 -2
  337. package/dist/action/output/stale.test.d.ts.map +0 -1
  338. package/dist/action/output/types.d.ts +0 -31
  339. package/dist/action/output/types.d.ts.map +0 -1
  340. package/dist/action/package.json +0 -3
  341. package/dist/action/sdk/index.d.ts +0 -2
  342. package/dist/action/sdk/index.d.ts.map +0 -1
  343. package/dist/action/sdk/runner.d.ts +0 -202
  344. package/dist/action/sdk/runner.d.ts.map +0 -1
  345. package/dist/action/sdk/runner.test.d.ts +0 -2
  346. package/dist/action/sdk/runner.test.d.ts.map +0 -1
  347. package/dist/action/skills/index.d.ts +0 -5
  348. package/dist/action/skills/index.d.ts.map +0 -1
  349. package/dist/action/skills/loader.d.ts +0 -111
  350. package/dist/action/skills/loader.d.ts.map +0 -1
  351. package/dist/action/skills/loader.test.d.ts +0 -2
  352. package/dist/action/skills/loader.test.d.ts.map +0 -1
  353. package/dist/action/skills/remote.d.ts +0 -117
  354. package/dist/action/skills/remote.d.ts.map +0 -1
  355. package/dist/action/skills/remote.test.d.ts +0 -2
  356. package/dist/action/skills/remote.test.d.ts.map +0 -1
  357. package/dist/action/sourcemap-register.cjs +0 -1
  358. package/dist/action/triggers/matcher.d.ts +0 -30
  359. package/dist/action/triggers/matcher.d.ts.map +0 -1
  360. package/dist/action/triggers/matcher.test.d.ts +0 -2
  361. package/dist/action/triggers/matcher.test.d.ts.map +0 -1
  362. package/dist/action/types/index.d.ts +0 -269
  363. package/dist/action/types/index.d.ts.map +0 -1
  364. package/dist/action/utils/async.d.ts +0 -5
  365. package/dist/action/utils/async.d.ts.map +0 -1
  366. package/dist/action/utils/index.d.ts +0 -16
  367. package/dist/action/utils/index.d.ts.map +0 -1
  368. package/dist/action/utils/index.test.d.ts +0 -2
  369. package/dist/action/utils/index.test.d.ts.map +0 -1
  370. package/dist/action/utils/version.d.ts +0 -3
  371. package/dist/action/utils/version.d.ts.map +0 -1
  372. package/dist/cli/args.test.d.ts +0 -2
  373. package/dist/cli/args.test.d.ts.map +0 -1
  374. package/dist/cli/args.test.js +0 -392
  375. package/dist/cli/args.test.js.map +0 -1
  376. package/dist/cli/commands/init.test.d.ts +0 -2
  377. package/dist/cli/commands/init.test.d.ts.map +0 -1
  378. package/dist/cli/commands/init.test.js +0 -117
  379. package/dist/cli/commands/init.test.js.map +0 -1
  380. package/dist/cli/files.test.d.ts +0 -2
  381. package/dist/cli/files.test.d.ts.map +0 -1
  382. package/dist/cli/files.test.js +0 -117
  383. package/dist/cli/files.test.js.map +0 -1
  384. package/dist/cli/fix.test.d.ts +0 -2
  385. package/dist/cli/fix.test.d.ts.map +0 -1
  386. package/dist/cli/fix.test.js +0 -251
  387. package/dist/cli/fix.test.js.map +0 -1
  388. package/dist/cli/git.test.d.ts +0 -2
  389. package/dist/cli/git.test.d.ts.map +0 -1
  390. package/dist/cli/git.test.js +0 -96
  391. package/dist/cli/git.test.js.map +0 -1
  392. package/dist/cli/output/formatters.test.d.ts +0 -2
  393. package/dist/cli/output/formatters.test.d.ts.map +0 -1
  394. package/dist/cli/output/formatters.test.js +0 -152
  395. package/dist/cli/output/formatters.test.js.map +0 -1
  396. package/dist/cli/output/jsonl.test.d.ts +0 -2
  397. package/dist/cli/output/jsonl.test.d.ts.map +0 -1
  398. package/dist/cli/output/jsonl.test.js +0 -284
  399. package/dist/cli/output/jsonl.test.js.map +0 -1
  400. package/dist/cli/output/tty.test.d.ts +0 -2
  401. package/dist/cli/output/tty.test.d.ts.map +0 -1
  402. package/dist/cli/output/tty.test.js +0 -105
  403. package/dist/cli/output/tty.test.js.map +0 -1
  404. package/dist/cli/output/verbosity.test.d.ts +0 -2
  405. package/dist/cli/output/verbosity.test.d.ts.map +0 -1
  406. package/dist/cli/output/verbosity.test.js +0 -35
  407. package/dist/cli/output/verbosity.test.js.map +0 -1
  408. package/dist/cli/terminal.test.d.ts +0 -2
  409. package/dist/cli/terminal.test.d.ts.map +0 -1
  410. package/dist/cli/terminal.test.js +0 -123
  411. package/dist/cli/terminal.test.js.map +0 -1
  412. package/dist/config/loader.test.d.ts +0 -2
  413. package/dist/config/loader.test.d.ts.map +0 -1
  414. package/dist/config/loader.test.js +0 -263
  415. package/dist/config/loader.test.js.map +0 -1
  416. package/dist/config/writer.test.d.ts +0 -2
  417. package/dist/config/writer.test.d.ts.map +0 -1
  418. package/dist/config/writer.test.js +0 -98
  419. package/dist/config/writer.test.js.map +0 -1
  420. package/dist/diff/classify.test.d.ts +0 -2
  421. package/dist/diff/classify.test.d.ts.map +0 -1
  422. package/dist/diff/classify.test.js +0 -140
  423. package/dist/diff/classify.test.js.map +0 -1
  424. package/dist/diff/coalesce.test.d.ts +0 -2
  425. package/dist/diff/coalesce.test.d.ts.map +0 -1
  426. package/dist/diff/coalesce.test.js +0 -159
  427. package/dist/diff/coalesce.test.js.map +0 -1
  428. package/dist/diff/context.test.d.ts +0 -2
  429. package/dist/diff/context.test.d.ts.map +0 -1
  430. package/dist/diff/context.test.js +0 -190
  431. package/dist/diff/context.test.js.map +0 -1
  432. package/dist/diff/parser.test.d.ts +0 -2
  433. package/dist/diff/parser.test.d.ts.map +0 -1
  434. package/dist/diff/parser.test.js +0 -178
  435. package/dist/diff/parser.test.js.map +0 -1
  436. package/dist/examples/examples.integration.test.d.ts +0 -2
  437. package/dist/examples/examples.integration.test.d.ts.map +0 -1
  438. package/dist/examples/examples.integration.test.js +0 -55
  439. package/dist/examples/examples.integration.test.js.map +0 -1
  440. package/dist/examples/index.test.d.ts +0 -2
  441. package/dist/examples/index.test.d.ts.map +0 -1
  442. package/dist/examples/index.test.js +0 -88
  443. package/dist/examples/index.test.js.map +0 -1
  444. package/dist/output/dedup.test.d.ts +0 -2
  445. package/dist/output/dedup.test.d.ts.map +0 -1
  446. package/dist/output/dedup.test.js +0 -357
  447. package/dist/output/dedup.test.js.map +0 -1
  448. package/dist/output/github-checks.test.d.ts +0 -2
  449. package/dist/output/github-checks.test.d.ts.map +0 -1
  450. package/dist/output/github-checks.test.js +0 -255
  451. package/dist/output/github-checks.test.js.map +0 -1
  452. package/dist/output/renderer.test.d.ts +0 -2
  453. package/dist/output/renderer.test.d.ts.map +0 -1
  454. package/dist/output/renderer.test.js +0 -645
  455. package/dist/output/renderer.test.js.map +0 -1
  456. package/dist/output/stale.test.d.ts +0 -2
  457. package/dist/output/stale.test.d.ts.map +0 -1
  458. package/dist/output/stale.test.js +0 -330
  459. package/dist/output/stale.test.js.map +0 -1
  460. package/dist/sdk/runner.test.d.ts +0 -2
  461. package/dist/sdk/runner.test.d.ts.map +0 -1
  462. package/dist/sdk/runner.test.js +0 -677
  463. package/dist/sdk/runner.test.js.map +0 -1
  464. package/dist/skills/loader.test.d.ts +0 -2
  465. package/dist/skills/loader.test.d.ts.map +0 -1
  466. package/dist/skills/loader.test.js +0 -241
  467. package/dist/skills/loader.test.js.map +0 -1
  468. package/dist/skills/remote.test.d.ts +0 -2
  469. package/dist/skills/remote.test.d.ts.map +0 -1
  470. package/dist/skills/remote.test.js +0 -582
  471. package/dist/skills/remote.test.js.map +0 -1
  472. package/dist/triggers/matcher.test.d.ts +0 -2
  473. package/dist/triggers/matcher.test.d.ts.map +0 -1
  474. package/dist/triggers/matcher.test.js +0 -234
  475. package/dist/triggers/matcher.test.js.map +0 -1
  476. package/dist/utils/index.test.d.ts +0 -2
  477. package/dist/utils/index.test.d.ts.map +0 -1
  478. package/dist/utils/index.test.js +0 -68
  479. package/dist/utils/index.test.js.map +0 -1
  480. package/docs/astro.config.mjs +0 -43
  481. package/docs/package.json +0 -19
  482. package/docs/pnpm-lock.yaml +0 -4000
  483. package/docs/public/favicon.svg +0 -5
  484. package/docs/src/components/Code.astro +0 -141
  485. package/docs/src/components/PackageManagerTabs.astro +0 -183
  486. package/docs/src/components/Terminal.astro +0 -212
  487. package/docs/src/layouts/Base.astro +0 -380
  488. package/docs/src/pages/cli.astro +0 -167
  489. package/docs/src/pages/config.astro +0 -395
  490. package/docs/src/pages/guide.astro +0 -450
  491. package/docs/src/pages/index.astro +0 -490
  492. package/docs/src/styles/global.css +0 -551
  493. package/docs/src/utils/version.ts +0 -6
  494. package/docs/tsconfig.json +0 -3
  495. package/docs/vercel.json +0 -5
  496. package/eslint.config.js +0 -33
  497. package/src/action/index.ts +0 -1
  498. package/src/action/main.ts +0 -868
  499. package/src/cli/args.test.ts +0 -477
  500. package/src/cli/args.ts +0 -414
  501. package/src/cli/commands/add.ts +0 -447
  502. package/src/cli/commands/init.test.ts +0 -137
  503. package/src/cli/commands/init.ts +0 -134
  504. package/src/cli/commands/setup-app/browser.ts +0 -38
  505. package/src/cli/commands/setup-app/credentials.ts +0 -45
  506. package/src/cli/commands/setup-app/manifest.ts +0 -48
  507. package/src/cli/commands/setup-app/server.ts +0 -172
  508. package/src/cli/commands/setup-app.ts +0 -156
  509. package/src/cli/commands/sync.ts +0 -114
  510. package/src/cli/context.ts +0 -131
  511. package/src/cli/files.test.ts +0 -155
  512. package/src/cli/files.ts +0 -89
  513. package/src/cli/fix.test.ts +0 -310
  514. package/src/cli/fix.ts +0 -387
  515. package/src/cli/git.test.ts +0 -119
  516. package/src/cli/git.ts +0 -318
  517. package/src/cli/index.ts +0 -14
  518. package/src/cli/main.ts +0 -672
  519. package/src/cli/output/box.ts +0 -235
  520. package/src/cli/output/formatters.test.ts +0 -187
  521. package/src/cli/output/formatters.ts +0 -269
  522. package/src/cli/output/icons.ts +0 -13
  523. package/src/cli/output/index.ts +0 -44
  524. package/src/cli/output/ink-runner.tsx +0 -337
  525. package/src/cli/output/jsonl.test.ts +0 -347
  526. package/src/cli/output/jsonl.ts +0 -126
  527. package/src/cli/output/reporter.ts +0 -434
  528. package/src/cli/output/tasks.ts +0 -374
  529. package/src/cli/output/tty.test.ts +0 -117
  530. package/src/cli/output/tty.ts +0 -60
  531. package/src/cli/output/verbosity.test.ts +0 -40
  532. package/src/cli/output/verbosity.ts +0 -31
  533. package/src/cli/terminal.test.ts +0 -148
  534. package/src/cli/terminal.ts +0 -301
  535. package/src/config/index.ts +0 -3
  536. package/src/config/loader.test.ts +0 -313
  537. package/src/config/loader.ts +0 -103
  538. package/src/config/schema.ts +0 -168
  539. package/src/config/writer.test.ts +0 -119
  540. package/src/config/writer.ts +0 -84
  541. package/src/diff/classify.test.ts +0 -162
  542. package/src/diff/classify.ts +0 -92
  543. package/src/diff/coalesce.test.ts +0 -208
  544. package/src/diff/coalesce.ts +0 -133
  545. package/src/diff/context.test.ts +0 -226
  546. package/src/diff/context.ts +0 -201
  547. package/src/diff/index.ts +0 -4
  548. package/src/diff/parser.test.ts +0 -212
  549. package/src/diff/parser.ts +0 -149
  550. package/src/event/context.ts +0 -132
  551. package/src/event/index.ts +0 -2
  552. package/src/event/schedule-context.ts +0 -101
  553. package/src/examples/examples.integration.test.ts +0 -66
  554. package/src/examples/index.test.ts +0 -101
  555. package/src/examples/index.ts +0 -122
  556. package/src/examples/setup.ts +0 -25
  557. package/src/index.ts +0 -115
  558. package/src/output/dedup.test.ts +0 -419
  559. package/src/output/dedup.ts +0 -607
  560. package/src/output/github-checks.test.ts +0 -300
  561. package/src/output/github-checks.ts +0 -476
  562. package/src/output/github-issues.ts +0 -329
  563. package/src/output/index.ts +0 -5
  564. package/src/output/issue-renderer.ts +0 -197
  565. package/src/output/renderer.test.ts +0 -727
  566. package/src/output/renderer.ts +0 -217
  567. package/src/output/stale.test.ts +0 -375
  568. package/src/output/stale.ts +0 -155
  569. package/src/output/types.ts +0 -34
  570. package/src/sdk/index.ts +0 -1
  571. package/src/sdk/runner.test.ts +0 -806
  572. package/src/sdk/runner.ts +0 -1232
  573. package/src/skills/index.ts +0 -36
  574. package/src/skills/loader.test.ts +0 -300
  575. package/src/skills/loader.ts +0 -423
  576. package/src/skills/remote.test.ts +0 -704
  577. package/src/skills/remote.ts +0 -604
  578. package/src/triggers/matcher.test.ts +0 -277
  579. package/src/triggers/matcher.ts +0 -152
  580. package/src/types/index.ts +0 -194
  581. package/src/utils/async.ts +0 -18
  582. package/src/utils/index.test.ts +0 -84
  583. package/src/utils/index.ts +0 -51
  584. package/src/utils/version.ts +0 -17
  585. package/tsconfig.json +0 -25
  586. package/vitest.config.ts +0 -8
  587. package/vitest.integration.config.ts +0 -11
  588. package/warden.toml +0 -19
@@ -1,704 +0,0 @@
1
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
- import { dirname, join } from 'node:path';
3
- import { mkdirSync, writeFileSync, rmSync } from 'node:fs';
4
- import { tmpdir } from 'node:os';
5
- import {
6
- parseRemoteRef,
7
- formatRemoteRef,
8
- getSkillsCacheDir,
9
- getRemotePath,
10
- getStatePath,
11
- loadState,
12
- saveState,
13
- getCacheTtlSeconds,
14
- shouldRefresh,
15
- discoverRemoteSkills,
16
- resolveRemoteSkill,
17
- type RemoteState,
18
- } from './remote.js';
19
- import { SkillLoaderError } from './loader.js';
20
-
21
- /** Standard SKILL.md content for testing */
22
- function skillMd(name: string, description: string): string {
23
- return `---
24
- name: ${name}
25
- description: ${description}
26
- ---
27
- Prompt for ${name}.
28
- `;
29
- }
30
-
31
- /**
32
- * Create a file tree from a declarative structure.
33
- * Keys are relative paths, values are file contents.
34
- */
35
- function createFileTree(basePath: string, files: Record<string, string>): void {
36
- for (const [relativePath, content] of Object.entries(files)) {
37
- const fullPath = join(basePath, relativePath);
38
- mkdirSync(dirname(fullPath), { recursive: true });
39
- writeFileSync(fullPath, content);
40
- }
41
- }
42
-
43
- describe('parseRemoteRef', () => {
44
- it('parses owner/repo format', () => {
45
- const result = parseRemoteRef('getsentry/skills');
46
- expect(result).toEqual({
47
- owner: 'getsentry',
48
- repo: 'skills',
49
- sha: undefined,
50
- });
51
- });
52
-
53
- it('parses owner/repo@sha format', () => {
54
- const result = parseRemoteRef('getsentry/skills@abc123def');
55
- expect(result).toEqual({
56
- owner: 'getsentry',
57
- repo: 'skills',
58
- sha: 'abc123def',
59
- });
60
- });
61
-
62
- it('handles full commit SHA', () => {
63
- const fullSha = 'abc123def456789012345678901234567890abcd';
64
- const result = parseRemoteRef(`getsentry/skills@${fullSha}`);
65
- expect(result).toEqual({
66
- owner: 'getsentry',
67
- repo: 'skills',
68
- sha: fullSha,
69
- });
70
- });
71
-
72
- it('throws for missing owner', () => {
73
- expect(() => parseRemoteRef('/repo')).toThrow(SkillLoaderError);
74
- expect(() => parseRemoteRef('/repo')).toThrow('empty owner or repo');
75
- });
76
-
77
- it('throws for missing repo', () => {
78
- expect(() => parseRemoteRef('owner/')).toThrow(SkillLoaderError);
79
- expect(() => parseRemoteRef('owner/')).toThrow('empty owner or repo');
80
- });
81
-
82
- it('throws for missing slash', () => {
83
- expect(() => parseRemoteRef('noslash')).toThrow(SkillLoaderError);
84
- expect(() => parseRemoteRef('noslash')).toThrow('expected owner/repo format');
85
- });
86
-
87
- it('throws for empty SHA after @', () => {
88
- expect(() => parseRemoteRef('owner/repo@')).toThrow(SkillLoaderError);
89
- expect(() => parseRemoteRef('owner/repo@')).toThrow('empty SHA after @');
90
- });
91
-
92
- it('throws for nested paths in repo', () => {
93
- expect(() => parseRemoteRef('owner/repo/nested')).toThrow(SkillLoaderError);
94
- expect(() => parseRemoteRef('owner/repo/nested')).toThrow('repo name cannot contain /');
95
- });
96
-
97
- it('throws for owner starting with dash (flag injection)', () => {
98
- expect(() => parseRemoteRef('-malicious/repo')).toThrow(SkillLoaderError);
99
- expect(() => parseRemoteRef('-malicious/repo')).toThrow('owner cannot start with -');
100
- });
101
-
102
- it('throws for repo starting with dash (flag injection)', () => {
103
- expect(() => parseRemoteRef('owner/-malicious')).toThrow(SkillLoaderError);
104
- expect(() => parseRemoteRef('owner/-malicious')).toThrow('repo cannot start with -');
105
- });
106
-
107
- it('throws for SHA starting with dash (flag injection)', () => {
108
- expect(() => parseRemoteRef('owner/repo@--upload-pack=evil')).toThrow(SkillLoaderError);
109
- expect(() => parseRemoteRef('owner/repo@--upload-pack=evil')).toThrow('SHA cannot start with -');
110
- });
111
-
112
- // GitHub URL support
113
- it('parses HTTPS GitHub URL', () => {
114
- const result = parseRemoteRef('https://github.com/getsentry/skills');
115
- expect(result).toEqual({
116
- owner: 'getsentry',
117
- repo: 'skills',
118
- sha: undefined,
119
- });
120
- });
121
-
122
- it('parses HTTPS GitHub URL with .git suffix', () => {
123
- const result = parseRemoteRef('https://github.com/getsentry/skills.git');
124
- expect(result).toEqual({
125
- owner: 'getsentry',
126
- repo: 'skills',
127
- sha: undefined,
128
- });
129
- });
130
-
131
- it('parses HTTPS GitHub URL with SHA', () => {
132
- const result = parseRemoteRef('https://github.com/getsentry/skills@abc123');
133
- expect(result).toEqual({
134
- owner: 'getsentry',
135
- repo: 'skills',
136
- sha: 'abc123',
137
- });
138
- });
139
-
140
- it('parses HTTPS GitHub URL with .git and SHA', () => {
141
- const result = parseRemoteRef('https://github.com/getsentry/skills.git@abc123');
142
- expect(result).toEqual({
143
- owner: 'getsentry',
144
- repo: 'skills',
145
- sha: 'abc123',
146
- });
147
- });
148
-
149
- it('parses SSH GitHub URL', () => {
150
- const result = parseRemoteRef('git@github.com:getsentry/skills.git');
151
- expect(result).toEqual({
152
- owner: 'getsentry',
153
- repo: 'skills',
154
- sha: undefined,
155
- });
156
- });
157
-
158
- it('parses SSH GitHub URL with SHA', () => {
159
- const result = parseRemoteRef('git@github.com:getsentry/skills.git@abc123');
160
- expect(result).toEqual({
161
- owner: 'getsentry',
162
- repo: 'skills',
163
- sha: 'abc123',
164
- });
165
- });
166
-
167
- it('parses HTTP GitHub URL (upgrades to HTTPS)', () => {
168
- const result = parseRemoteRef('http://github.com/getsentry/skills');
169
- expect(result).toEqual({
170
- owner: 'getsentry',
171
- repo: 'skills',
172
- sha: undefined,
173
- });
174
- });
175
- });
176
-
177
- describe('formatRemoteRef', () => {
178
- it('formats unpinned ref', () => {
179
- const result = formatRemoteRef({ owner: 'getsentry', repo: 'skills' });
180
- expect(result).toBe('getsentry/skills');
181
- });
182
-
183
- it('formats pinned ref', () => {
184
- const result = formatRemoteRef({ owner: 'getsentry', repo: 'skills', sha: 'abc123' });
185
- expect(result).toBe('getsentry/skills@abc123');
186
- });
187
- });
188
-
189
- describe('getSkillsCacheDir', () => {
190
- const originalEnv = process.env['WARDEN_STATE_DIR'];
191
-
192
- afterEach(() => {
193
- if (originalEnv === undefined) {
194
- delete process.env['WARDEN_STATE_DIR'];
195
- } else {
196
- process.env['WARDEN_STATE_DIR'] = originalEnv;
197
- }
198
- });
199
-
200
- it('returns default path when WARDEN_STATE_DIR not set', () => {
201
- delete process.env['WARDEN_STATE_DIR'];
202
- const result = getSkillsCacheDir();
203
- expect(result).toContain('.local');
204
- expect(result).toContain('warden');
205
- expect(result).toContain('skills');
206
- });
207
-
208
- it('respects WARDEN_STATE_DIR', () => {
209
- process.env['WARDEN_STATE_DIR'] = '/custom/state';
210
- const result = getSkillsCacheDir();
211
- expect(result).toBe('/custom/state/skills');
212
- });
213
- });
214
-
215
- describe('getRemotePath', () => {
216
- const originalEnv = process.env['WARDEN_STATE_DIR'];
217
-
218
- beforeEach(() => {
219
- process.env['WARDEN_STATE_DIR'] = '/test/state';
220
- });
221
-
222
- afterEach(() => {
223
- if (originalEnv === undefined) {
224
- delete process.env['WARDEN_STATE_DIR'];
225
- } else {
226
- process.env['WARDEN_STATE_DIR'] = originalEnv;
227
- }
228
- });
229
-
230
- it('returns path for unpinned ref', () => {
231
- const result = getRemotePath('getsentry/skills');
232
- expect(result).toBe('/test/state/skills/getsentry/skills');
233
- });
234
-
235
- it('returns path for pinned ref', () => {
236
- const result = getRemotePath('getsentry/skills@abc123');
237
- expect(result).toBe('/test/state/skills/getsentry/skills@abc123');
238
- });
239
- });
240
-
241
- describe('state management', () => {
242
- const testDir = join(tmpdir(), `warden-remote-test-${Date.now()}`);
243
- const originalEnv = process.env['WARDEN_STATE_DIR'];
244
-
245
- beforeEach(() => {
246
- process.env['WARDEN_STATE_DIR'] = testDir;
247
- mkdirSync(testDir, { recursive: true });
248
- });
249
-
250
- afterEach(() => {
251
- if (originalEnv === undefined) {
252
- delete process.env['WARDEN_STATE_DIR'];
253
- } else {
254
- process.env['WARDEN_STATE_DIR'] = originalEnv;
255
- }
256
- rmSync(testDir, { recursive: true, force: true });
257
- });
258
-
259
- it('loadState returns empty state when file does not exist', () => {
260
- const state = loadState();
261
- expect(state).toEqual({ remotes: {} });
262
- });
263
-
264
- it('saveState creates state file', () => {
265
- const state: RemoteState = {
266
- remotes: {
267
- 'getsentry/skills': {
268
- sha: 'abc123',
269
- fetchedAt: new Date().toISOString(),
270
- },
271
- },
272
- };
273
-
274
- saveState(state);
275
-
276
- const loaded = loadState();
277
- expect(loaded.remotes['getsentry/skills']?.sha).toBe('abc123');
278
- });
279
-
280
- it('saveState updates existing state', () => {
281
- const state1: RemoteState = {
282
- remotes: {
283
- 'getsentry/skills': {
284
- sha: 'abc123',
285
- fetchedAt: new Date().toISOString(),
286
- },
287
- },
288
- };
289
- saveState(state1);
290
-
291
- const state2: RemoteState = {
292
- remotes: {
293
- 'getsentry/skills': {
294
- sha: 'def456',
295
- fetchedAt: new Date().toISOString(),
296
- },
297
- 'other/repo': {
298
- sha: 'ghi789',
299
- fetchedAt: new Date().toISOString(),
300
- },
301
- },
302
- };
303
- saveState(state2);
304
-
305
- const loaded = loadState();
306
- expect(loaded.remotes['getsentry/skills']?.sha).toBe('def456');
307
- expect(loaded.remotes['other/repo']?.sha).toBe('ghi789');
308
- });
309
-
310
- it('loadState handles corrupted state file gracefully', () => {
311
- const statePath = getStatePath();
312
- mkdirSync(join(testDir, 'skills'), { recursive: true });
313
- writeFileSync(statePath, 'invalid json {{{', 'utf-8');
314
-
315
- // Should return empty state without throwing
316
- const state = loadState();
317
- expect(state).toEqual({ remotes: {} });
318
- });
319
- });
320
-
321
- describe('getCacheTtlSeconds', () => {
322
- const originalEnv = process.env['WARDEN_SKILL_CACHE_TTL'];
323
-
324
- afterEach(() => {
325
- if (originalEnv === undefined) {
326
- delete process.env['WARDEN_SKILL_CACHE_TTL'];
327
- } else {
328
- process.env['WARDEN_SKILL_CACHE_TTL'] = originalEnv;
329
- }
330
- });
331
-
332
- it('returns default 24 hours when not set', () => {
333
- delete process.env['WARDEN_SKILL_CACHE_TTL'];
334
- expect(getCacheTtlSeconds()).toBe(86400);
335
- });
336
-
337
- it('respects WARDEN_SKILL_CACHE_TTL', () => {
338
- process.env['WARDEN_SKILL_CACHE_TTL'] = '3600';
339
- expect(getCacheTtlSeconds()).toBe(3600);
340
- });
341
-
342
- it('ignores invalid TTL values', () => {
343
- process.env['WARDEN_SKILL_CACHE_TTL'] = 'invalid';
344
- expect(getCacheTtlSeconds()).toBe(86400);
345
-
346
- process.env['WARDEN_SKILL_CACHE_TTL'] = '-100';
347
- expect(getCacheTtlSeconds()).toBe(86400);
348
-
349
- process.env['WARDEN_SKILL_CACHE_TTL'] = '0';
350
- expect(getCacheTtlSeconds()).toBe(86400);
351
- });
352
- });
353
-
354
- describe('shouldRefresh', () => {
355
- const originalEnv = process.env['WARDEN_SKILL_CACHE_TTL'];
356
-
357
- beforeEach(() => {
358
- // Set short TTL for testing
359
- process.env['WARDEN_SKILL_CACHE_TTL'] = '60';
360
- });
361
-
362
- afterEach(() => {
363
- if (originalEnv === undefined) {
364
- delete process.env['WARDEN_SKILL_CACHE_TTL'];
365
- } else {
366
- process.env['WARDEN_SKILL_CACHE_TTL'] = originalEnv;
367
- }
368
- });
369
-
370
- it('returns true when ref is not cached', () => {
371
- const state: RemoteState = { remotes: {} };
372
- expect(shouldRefresh('getsentry/skills', state)).toBe(true);
373
- });
374
-
375
- it('returns false for pinned refs', () => {
376
- const state: RemoteState = { remotes: {} };
377
- // Even if not cached, pinned refs never need refresh
378
- expect(shouldRefresh('getsentry/skills@abc123', state)).toBe(false);
379
- });
380
-
381
- it('returns false when cache is fresh', () => {
382
- const state: RemoteState = {
383
- remotes: {
384
- 'getsentry/skills': {
385
- sha: 'abc123',
386
- fetchedAt: new Date().toISOString(), // Just now
387
- },
388
- },
389
- };
390
- expect(shouldRefresh('getsentry/skills', state)).toBe(false);
391
- });
392
-
393
- it('returns true when cache is stale', () => {
394
- const staleTime = new Date(Date.now() - 120000); // 2 minutes ago (TTL is 60 seconds)
395
- const state: RemoteState = {
396
- remotes: {
397
- 'getsentry/skills': {
398
- sha: 'abc123',
399
- fetchedAt: staleTime.toISOString(),
400
- },
401
- },
402
- };
403
- expect(shouldRefresh('getsentry/skills', state)).toBe(true);
404
- });
405
- });
406
-
407
- describe('discoverRemoteSkills', () => {
408
- let testDir: string;
409
- const originalEnv = process.env['WARDEN_STATE_DIR'];
410
-
411
- beforeEach(() => {
412
- testDir = join(tmpdir(), `warden-remote-discover-${Date.now()}-${Math.random().toString(36).slice(2)}`);
413
- process.env['WARDEN_STATE_DIR'] = testDir;
414
- mkdirSync(testDir, { recursive: true });
415
- });
416
-
417
- afterEach(() => {
418
- if (originalEnv === undefined) {
419
- delete process.env['WARDEN_STATE_DIR'];
420
- } else {
421
- process.env['WARDEN_STATE_DIR'] = originalEnv;
422
- }
423
- rmSync(testDir, { recursive: true, force: true });
424
- });
425
-
426
- it('throws when remote is not cached', async () => {
427
- await expect(discoverRemoteSkills('getsentry/skills')).rejects.toThrow('Remote not cached');
428
- });
429
-
430
- it('discovers skills at root level', async () => {
431
- const remotePath = getRemotePath('test/repo');
432
- createFileTree(remotePath, {
433
- 'skill-a/SKILL.md': skillMd('skill-a', 'Skill A'),
434
- 'skill-b/SKILL.md': skillMd('skill-b', 'Skill B'),
435
- });
436
-
437
- const skills = await discoverRemoteSkills('test/repo');
438
-
439
- expect(skills.map((s) => s.name).sort()).toEqual(['skill-a', 'skill-b']);
440
- });
441
-
442
- it('skips directories without SKILL.md and hidden directories', async () => {
443
- const remotePath = getRemotePath('test/repo');
444
- createFileTree(remotePath, {
445
- 'valid-skill/SKILL.md': skillMd('valid', 'Valid skill'),
446
- 'empty-dir/README.md': '# Empty',
447
- '.git/config': '# Git config',
448
- });
449
-
450
- const skills = await discoverRemoteSkills('test/repo');
451
-
452
- expect(skills.length).toBe(1);
453
- expect(skills[0]?.name).toBe('valid');
454
- });
455
-
456
- it('skips invalid SKILL.md files', async () => {
457
- const remotePath = getRemotePath('test/repo');
458
- createFileTree(remotePath, {
459
- 'valid/SKILL.md': skillMd('valid', 'Valid skill'),
460
- 'invalid/SKILL.md': '---\ndescription: Missing name\n---\nPrompt.',
461
- });
462
-
463
- const skills = await discoverRemoteSkills('test/repo');
464
-
465
- expect(skills.length).toBe(1);
466
- expect(skills[0]?.name).toBe('valid');
467
- });
468
-
469
- // Test all 5 discovery directories with precedence
470
- describe('directory discovery', () => {
471
- const directories = [
472
- { path: '', label: 'root' },
473
- { path: 'skills', label: 'skills/' },
474
- { path: '.warden/skills', label: '.warden/skills' },
475
- { path: '.agents/skills', label: '.agents/skills' },
476
- { path: '.claude/skills', label: '.claude/skills' },
477
- ];
478
-
479
- it.each(directories)('discovers skills in $label directory', async ({ path }) => {
480
- const remotePath = getRemotePath('test/repo');
481
- const skillDir = path ? `${path}/my-skill` : 'my-skill';
482
- createFileTree(remotePath, {
483
- [`${skillDir}/SKILL.md`]: skillMd('my-skill', `From ${path || 'root'}`),
484
- });
485
-
486
- const skills = await discoverRemoteSkills('test/repo');
487
-
488
- expect(skills.length).toBe(1);
489
- expect(skills[0]?.name).toBe('my-skill');
490
- expect(skills[0]?.path).toBe(join(remotePath, skillDir));
491
- });
492
-
493
- it('respects precedence order: root > skills/ > .warden > .agents > .claude', async () => {
494
- const remotePath = getRemotePath('test/repo');
495
- createFileTree(remotePath, {
496
- 'my-skill/SKILL.md': skillMd('my-skill', 'From root'),
497
- 'skills/my-skill/SKILL.md': skillMd('my-skill', 'From skills/'),
498
- '.warden/skills/my-skill/SKILL.md': skillMd('my-skill', 'From .warden'),
499
- '.agents/skills/my-skill/SKILL.md': skillMd('my-skill', 'From .agents'),
500
- '.claude/skills/my-skill/SKILL.md': skillMd('my-skill', 'From .claude'),
501
- });
502
-
503
- const skills = await discoverRemoteSkills('test/repo');
504
-
505
- expect(skills.length).toBe(1);
506
- expect(skills[0]?.description).toBe('From root');
507
- expect(skills[0]?.path).toBe(join(remotePath, 'my-skill'));
508
- });
509
-
510
- it('.warden takes precedence when root and skills/ are absent', async () => {
511
- const remotePath = getRemotePath('test/repo');
512
- createFileTree(remotePath, {
513
- '.warden/skills/my-skill/SKILL.md': skillMd('my-skill', 'From .warden'),
514
- '.agents/skills/my-skill/SKILL.md': skillMd('my-skill', 'From .agents'),
515
- '.claude/skills/my-skill/SKILL.md': skillMd('my-skill', 'From .claude'),
516
- });
517
-
518
- const skills = await discoverRemoteSkills('test/repo');
519
-
520
- expect(skills[0]?.description).toBe('From .warden');
521
- });
522
- });
523
-
524
- // Marketplace format tests
525
- describe('marketplace format', () => {
526
- function marketplaceJson(plugins: { name: string; source: string }[]): string {
527
- return JSON.stringify({ name: 'test', plugins });
528
- }
529
-
530
- it('discovers skills from marketplace.json plugins', async () => {
531
- const remotePath = getRemotePath('test/repo');
532
- createFileTree(remotePath, {
533
- '.claude-plugin/marketplace.json': marketplaceJson([
534
- { name: 'my-plugin', source: './plugins/my-plugin' },
535
- ]),
536
- 'plugins/my-plugin/skills/commit/SKILL.md': skillMd('commit', 'Commit skill'),
537
- 'plugins/my-plugin/skills/review/SKILL.md': skillMd('review', 'Review skill'),
538
- });
539
-
540
- const skills = await discoverRemoteSkills('test/repo');
541
-
542
- expect(skills.map((s) => s.name).sort()).toEqual(['commit', 'review']);
543
- expect(skills.every((s) => s.pluginName === 'my-plugin')).toBe(true);
544
- });
545
-
546
- it('ignores traditional directories when marketplace.json exists', async () => {
547
- const remotePath = getRemotePath('test/repo');
548
- createFileTree(remotePath, {
549
- '.claude-plugin/marketplace.json': marketplaceJson([
550
- { name: 'plugin', source: './plugins/p' },
551
- ]),
552
- 'plugins/p/skills/marketplace-skill/SKILL.md': skillMd('marketplace-skill', 'From marketplace'),
553
- 'root-skill/SKILL.md': skillMd('root-skill', 'From root'),
554
- });
555
-
556
- const skills = await discoverRemoteSkills('test/repo');
557
-
558
- expect(skills.length).toBe(1);
559
- expect(skills[0]?.name).toBe('marketplace-skill');
560
- });
561
-
562
- it('handles multiple plugins', async () => {
563
- const remotePath = getRemotePath('test/repo');
564
- createFileTree(remotePath, {
565
- '.claude-plugin/marketplace.json': marketplaceJson([
566
- { name: 'plugin-a', source: './plugins/a' },
567
- { name: 'plugin-b', source: './plugins/b' },
568
- ]),
569
- 'plugins/a/skills/skill-a/SKILL.md': skillMd('skill-a', 'From A'),
570
- 'plugins/b/skills/skill-b/SKILL.md': skillMd('skill-b', 'From B'),
571
- });
572
-
573
- const skills = await discoverRemoteSkills('test/repo');
574
-
575
- expect(skills.find((s) => s.name === 'skill-a')?.pluginName).toBe('plugin-a');
576
- expect(skills.find((s) => s.name === 'skill-b')?.pluginName).toBe('plugin-b');
577
- });
578
-
579
- it('first plugin wins for duplicate skill names', async () => {
580
- const remotePath = getRemotePath('test/repo');
581
- createFileTree(remotePath, {
582
- '.claude-plugin/marketplace.json': marketplaceJson([
583
- { name: 'plugin-a', source: './plugins/a' },
584
- { name: 'plugin-b', source: './plugins/b' },
585
- ]),
586
- 'plugins/a/skills/shared/SKILL.md': skillMd('shared', 'From A'),
587
- 'plugins/b/skills/shared/SKILL.md': skillMd('shared', 'From B'),
588
- });
589
-
590
- const skills = await discoverRemoteSkills('test/repo');
591
-
592
- expect(skills.length).toBe(1);
593
- expect(skills[0]?.description).toBe('From A');
594
- expect(skills[0]?.pluginName).toBe('plugin-a');
595
- });
596
-
597
- it('returns correct path for marketplace skills', async () => {
598
- const remotePath = getRemotePath('test/repo');
599
- createFileTree(remotePath, {
600
- '.claude-plugin/marketplace.json': marketplaceJson([
601
- { name: 'plugin', source: './plugins/p' },
602
- ]),
603
- 'plugins/p/skills/my-skill/SKILL.md': skillMd('my-skill', 'Test'),
604
- });
605
-
606
- const skills = await discoverRemoteSkills('test/repo');
607
-
608
- expect(skills[0]?.path).toBe(join(remotePath, 'plugins', 'p', 'skills', 'my-skill'));
609
- });
610
-
611
- it('falls back to traditional when marketplace.json is invalid', async () => {
612
- const remotePath = getRemotePath('test/repo');
613
- createFileTree(remotePath, {
614
- '.claude-plugin/marketplace.json': 'invalid json {{{',
615
- 'my-skill/SKILL.md': skillMd('my-skill', 'Traditional'),
616
- });
617
-
618
- const skills = await discoverRemoteSkills('test/repo');
619
-
620
- expect(skills[0]?.name).toBe('my-skill');
621
- expect(skills[0]?.pluginName).toBeUndefined();
622
- });
623
- });
624
- });
625
-
626
- describe('resolveRemoteSkill', () => {
627
- const testDir = join(tmpdir(), `warden-remote-resolve-${Date.now()}`);
628
- const originalEnv = process.env['WARDEN_STATE_DIR'];
629
-
630
- beforeEach(() => {
631
- process.env['WARDEN_STATE_DIR'] = testDir;
632
- mkdirSync(testDir, { recursive: true });
633
- });
634
-
635
- afterEach(() => {
636
- if (originalEnv === undefined) {
637
- delete process.env['WARDEN_STATE_DIR'];
638
- } else {
639
- process.env['WARDEN_STATE_DIR'] = originalEnv;
640
- }
641
- rmSync(testDir, { recursive: true, force: true });
642
- });
643
-
644
- it('resolves skill when directory name differs from skill name', async () => {
645
- // Simulate vercel-labs/agent-skills structure: directory is "react-best-practices"
646
- // but skill name in SKILL.md is "vercel-react-best-practices"
647
- const remotePath = getRemotePath('vercel/skills');
648
- mkdirSync(join(remotePath, 'skills', 'react-best-practices'), { recursive: true });
649
-
650
- writeFileSync(
651
- join(remotePath, 'skills', 'react-best-practices', 'SKILL.md'),
652
- `---
653
- name: vercel-react-best-practices
654
- description: React best practices from Vercel
655
- ---
656
- React review prompt.
657
- `
658
- );
659
-
660
- // Create state entry so fetchRemote doesn't try to clone
661
- saveState({
662
- remotes: {
663
- 'vercel/skills': {
664
- sha: 'abc123',
665
- fetchedAt: new Date().toISOString(),
666
- },
667
- },
668
- });
669
-
670
- const skill = await resolveRemoteSkill('vercel/skills', 'vercel-react-best-practices', { offline: true });
671
-
672
- expect(skill.name).toBe('vercel-react-best-practices');
673
- expect(skill.description).toBe('React best practices from Vercel');
674
- });
675
-
676
- it('throws helpful error when skill not found', async () => {
677
- const remotePath = getRemotePath('getsentry/skills');
678
- mkdirSync(join(remotePath, 'security-review'), { recursive: true });
679
-
680
- writeFileSync(
681
- join(remotePath, 'security-review', 'SKILL.md'),
682
- `---
683
- name: security-review
684
- description: Security review skill
685
- ---
686
- Prompt.
687
- `
688
- );
689
-
690
- saveState({
691
- remotes: {
692
- 'getsentry/skills': {
693
- sha: 'abc123',
694
- fetchedAt: new Date().toISOString(),
695
- },
696
- },
697
- });
698
-
699
- await expect(resolveRemoteSkill('getsentry/skills', 'nonexistent', { offline: true }))
700
- .rejects.toThrow("Skill 'nonexistent' not found");
701
- await expect(resolveRemoteSkill('getsentry/skills', 'nonexistent', { offline: true }))
702
- .rejects.toThrow('Available skills: security-review');
703
- });
704
- });