@sentry/warden 0.1.1 → 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 (580) 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/tasks.d.ts.map +1 -1
  18. package/dist/cli/output/tasks.js +5 -1
  19. package/dist/cli/output/tasks.js.map +1 -1
  20. package/dist/config/schema.d.ts.map +1 -1
  21. package/dist/config/schema.js +15 -1
  22. package/dist/config/schema.js.map +1 -1
  23. package/dist/diff/coalesce.d.ts +32 -2
  24. package/dist/diff/coalesce.d.ts.map +1 -1
  25. package/dist/diff/coalesce.js +174 -2
  26. package/dist/diff/coalesce.js.map +1 -1
  27. package/dist/output/dedup.d.ts.map +1 -1
  28. package/dist/output/dedup.js +8 -3
  29. package/dist/output/dedup.js.map +1 -1
  30. package/dist/output/renderer.d.ts.map +1 -1
  31. package/dist/output/renderer.js +49 -5
  32. package/dist/output/renderer.js.map +1 -1
  33. package/dist/output/stale.d.ts.map +1 -1
  34. package/dist/output/stale.js +7 -0
  35. package/dist/output/stale.js.map +1 -1
  36. package/dist/output/types.d.ts +15 -1
  37. package/dist/output/types.d.ts.map +1 -1
  38. package/dist/sdk/analyze.d.ts +18 -0
  39. package/dist/sdk/analyze.d.ts.map +1 -0
  40. package/dist/sdk/analyze.js +425 -0
  41. package/dist/sdk/analyze.js.map +1 -0
  42. package/dist/sdk/errors.d.ts +23 -0
  43. package/dist/sdk/errors.d.ts.map +1 -0
  44. package/dist/sdk/errors.js +72 -0
  45. package/dist/sdk/errors.js.map +1 -0
  46. package/dist/sdk/extract.d.ts +44 -0
  47. package/dist/sdk/extract.d.ts.map +1 -0
  48. package/dist/sdk/extract.js +224 -0
  49. package/dist/sdk/extract.js.map +1 -0
  50. package/dist/sdk/prepare.d.ts +13 -0
  51. package/dist/sdk/prepare.d.ts.map +1 -0
  52. package/dist/sdk/prepare.js +73 -0
  53. package/dist/sdk/prepare.js.map +1 -0
  54. package/dist/sdk/prompt.d.ts +30 -0
  55. package/dist/sdk/prompt.d.ts.map +1 -0
  56. package/dist/sdk/prompt.js +109 -0
  57. package/dist/sdk/prompt.js.map +1 -0
  58. package/dist/sdk/retry.d.ts +12 -0
  59. package/dist/sdk/retry.d.ts.map +1 -0
  60. package/dist/sdk/retry.js +31 -0
  61. package/dist/sdk/retry.js.map +1 -0
  62. package/dist/sdk/runner.d.ts +22 -199
  63. package/dist/sdk/runner.d.ts.map +1 -1
  64. package/dist/sdk/runner.js +26 -884
  65. package/dist/sdk/runner.js.map +1 -1
  66. package/dist/sdk/types.d.ts +127 -0
  67. package/dist/sdk/types.d.ts.map +1 -0
  68. package/dist/sdk/types.js +5 -0
  69. package/dist/sdk/types.js.map +1 -0
  70. package/dist/sdk/usage.d.ts +20 -0
  71. package/dist/sdk/usage.d.ts.map +1 -0
  72. package/dist/sdk/usage.js +44 -0
  73. package/dist/sdk/usage.js.map +1 -0
  74. package/dist/skills/remote.d.ts.map +1 -1
  75. package/dist/skills/remote.js +3 -7
  76. package/dist/skills/remote.js.map +1 -1
  77. package/dist/types/index.d.ts +1 -0
  78. package/dist/types/index.d.ts.map +1 -1
  79. package/dist/types/index.js +2 -0
  80. package/dist/types/index.js.map +1 -1
  81. package/dist/utils/exec.d.ts +61 -0
  82. package/dist/utils/exec.d.ts.map +1 -0
  83. package/dist/utils/exec.js +111 -0
  84. package/dist/utils/exec.js.map +1 -0
  85. package/dist/utils/index.d.ts +2 -0
  86. package/dist/utils/index.d.ts.map +1 -1
  87. package/dist/utils/index.js +1 -0
  88. package/dist/utils/index.js.map +1 -1
  89. package/package.json +15 -16
  90. package/.agents/skills/find-bugs/SKILL.md +0 -75
  91. package/.agents/skills/vercel-react-best-practices/AGENTS.md +0 -2934
  92. package/.agents/skills/vercel-react-best-practices/SKILL.md +0 -136
  93. package/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  94. package/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  95. package/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  96. package/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  97. package/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
  98. package/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  99. package/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
  100. package/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  101. package/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
  102. package/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  103. package/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  104. package/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  105. package/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  106. package/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  107. package/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  108. package/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  109. package/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  110. package/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  111. package/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  112. package/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  113. package/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  114. package/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  115. package/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  116. package/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  117. package/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  118. package/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  119. package/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  120. package/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  121. package/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  122. package/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  123. package/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  124. package/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  125. package/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  126. package/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  127. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  128. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  129. package/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  130. package/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  131. package/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  132. package/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  133. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  134. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  135. package/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  136. package/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  137. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  138. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  139. package/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  140. package/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  141. package/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  142. package/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  143. package/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  144. package/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  145. package/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  146. package/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  147. package/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  148. package/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  149. package/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
  150. package/.claude/settings.json +0 -57
  151. package/.claude/skills/agent-prompt/SKILL.md +0 -54
  152. package/.claude/skills/agent-prompt/references/agentic-patterns.md +0 -94
  153. package/.claude/skills/agent-prompt/references/anti-patterns.md +0 -140
  154. package/.claude/skills/agent-prompt/references/context-design.md +0 -124
  155. package/.claude/skills/agent-prompt/references/core-principles.md +0 -75
  156. package/.claude/skills/agent-prompt/references/model-guidance.md +0 -118
  157. package/.claude/skills/agent-prompt/references/output-formats.md +0 -98
  158. package/.claude/skills/agent-prompt/references/skill-structure.md +0 -115
  159. package/.claude/skills/agent-prompt/references/system-prompts.md +0 -115
  160. package/.claude/skills/notseer/SKILL.md +0 -131
  161. package/.claude/skills/skill-writer/SKILL.md +0 -140
  162. package/.claude/skills/testing-guidelines/SKILL.md +0 -132
  163. package/.claude/skills/warden-skill/SKILL.md +0 -226
  164. package/.claude/skills/warden-skill/references/config-schema.md +0 -116
  165. package/.dex/config.toml +0 -2
  166. package/.github/workflows/ci.yml +0 -33
  167. package/.github/workflows/release.yml +0 -59
  168. package/.github/workflows/warden.yml +0 -40
  169. package/AGENTS.md +0 -89
  170. package/CONTRIBUTING.md +0 -60
  171. package/SPEC.md +0 -263
  172. package/action.yml +0 -87
  173. package/assets/favicon.png +0 -0
  174. package/assets/warden-icon-bw.svg +0 -5
  175. package/assets/warden-icon-purple.png +0 -0
  176. package/assets/warden-icon-purple.svg +0 -5
  177. package/dist/action/159.index.js +0 -523
  178. package/dist/action/159.index.js.map +0 -1
  179. package/dist/action/action/index.d.ts +0 -2
  180. package/dist/action/action/index.d.ts.map +0 -1
  181. package/dist/action/action/main.d.ts +0 -2
  182. package/dist/action/action/main.d.ts.map +0 -1
  183. package/dist/action/cli/args.d.ts +0 -74
  184. package/dist/action/cli/args.d.ts.map +0 -1
  185. package/dist/action/cli/args.test.d.ts +0 -2
  186. package/dist/action/cli/args.test.d.ts.map +0 -1
  187. package/dist/action/cli/commands/add.d.ts +0 -7
  188. package/dist/action/cli/commands/add.d.ts.map +0 -1
  189. package/dist/action/cli/commands/init.d.ts +0 -10
  190. package/dist/action/cli/commands/init.d.ts.map +0 -1
  191. package/dist/action/cli/commands/init.test.d.ts +0 -2
  192. package/dist/action/cli/commands/init.test.d.ts.map +0 -1
  193. package/dist/action/cli/commands/setup-app/browser.d.ts +0 -9
  194. package/dist/action/cli/commands/setup-app/browser.d.ts.map +0 -1
  195. package/dist/action/cli/commands/setup-app/credentials.d.ts +0 -15
  196. package/dist/action/cli/commands/setup-app/credentials.d.ts.map +0 -1
  197. package/dist/action/cli/commands/setup-app/manifest.d.ts +0 -24
  198. package/dist/action/cli/commands/setup-app/manifest.d.ts.map +0 -1
  199. package/dist/action/cli/commands/setup-app/server.d.ts +0 -28
  200. package/dist/action/cli/commands/setup-app/server.d.ts.map +0 -1
  201. package/dist/action/cli/commands/setup-app.d.ts +0 -11
  202. package/dist/action/cli/commands/setup-app.d.ts.map +0 -1
  203. package/dist/action/cli/commands/sync.d.ts +0 -9
  204. package/dist/action/cli/commands/sync.d.ts.map +0 -1
  205. package/dist/action/cli/context.d.ts +0 -27
  206. package/dist/action/cli/context.d.ts.map +0 -1
  207. package/dist/action/cli/files.d.ts +0 -22
  208. package/dist/action/cli/files.d.ts.map +0 -1
  209. package/dist/action/cli/files.test.d.ts +0 -2
  210. package/dist/action/cli/files.test.d.ts.map +0 -1
  211. package/dist/action/cli/fix.d.ts +0 -41
  212. package/dist/action/cli/fix.d.ts.map +0 -1
  213. package/dist/action/cli/fix.test.d.ts +0 -2
  214. package/dist/action/cli/fix.test.d.ts.map +0 -1
  215. package/dist/action/cli/git.d.ts +0 -73
  216. package/dist/action/cli/git.d.ts.map +0 -1
  217. package/dist/action/cli/git.test.d.ts +0 -2
  218. package/dist/action/cli/git.test.d.ts.map +0 -1
  219. package/dist/action/cli/index.d.ts +0 -3
  220. package/dist/action/cli/index.d.ts.map +0 -1
  221. package/dist/action/cli/main.d.ts +0 -7
  222. package/dist/action/cli/main.d.ts.map +0 -1
  223. package/dist/action/cli/output/box.d.ts +0 -75
  224. package/dist/action/cli/output/box.d.ts.map +0 -1
  225. package/dist/action/cli/output/formatters.d.ts +0 -90
  226. package/dist/action/cli/output/formatters.d.ts.map +0 -1
  227. package/dist/action/cli/output/formatters.test.d.ts +0 -2
  228. package/dist/action/cli/output/formatters.test.d.ts.map +0 -1
  229. package/dist/action/cli/output/icons.d.ts +0 -15
  230. package/dist/action/cli/output/icons.d.ts.map +0 -1
  231. package/dist/action/cli/output/index.d.ts +0 -10
  232. package/dist/action/cli/output/index.d.ts.map +0 -1
  233. package/dist/action/cli/output/ink-runner.d.ts +0 -29
  234. package/dist/action/cli/output/ink-runner.d.ts.map +0 -1
  235. package/dist/action/cli/output/jsonl.d.ts +0 -43
  236. package/dist/action/cli/output/jsonl.d.ts.map +0 -1
  237. package/dist/action/cli/output/jsonl.test.d.ts +0 -2
  238. package/dist/action/cli/output/jsonl.test.d.ts.map +0 -1
  239. package/dist/action/cli/output/reporter.d.ts +0 -108
  240. package/dist/action/cli/output/reporter.d.ts.map +0 -1
  241. package/dist/action/cli/output/tasks.d.ts +0 -89
  242. package/dist/action/cli/output/tasks.d.ts.map +0 -1
  243. package/dist/action/cli/output/tty.d.ts +0 -21
  244. package/dist/action/cli/output/tty.d.ts.map +0 -1
  245. package/dist/action/cli/output/tty.test.d.ts +0 -2
  246. package/dist/action/cli/output/tty.test.d.ts.map +0 -1
  247. package/dist/action/cli/output/verbosity.d.ts +0 -20
  248. package/dist/action/cli/output/verbosity.d.ts.map +0 -1
  249. package/dist/action/cli/output/verbosity.test.d.ts +0 -2
  250. package/dist/action/cli/output/verbosity.test.d.ts.map +0 -1
  251. package/dist/action/cli/terminal.d.ts +0 -19
  252. package/dist/action/cli/terminal.d.ts.map +0 -1
  253. package/dist/action/cli/terminal.test.d.ts +0 -2
  254. package/dist/action/cli/terminal.test.d.ts.map +0 -1
  255. package/dist/action/config/index.d.ts +0 -4
  256. package/dist/action/config/index.d.ts.map +0 -1
  257. package/dist/action/config/loader.d.ts +0 -27
  258. package/dist/action/config/loader.d.ts.map +0 -1
  259. package/dist/action/config/loader.test.d.ts +0 -2
  260. package/dist/action/config/loader.test.d.ts.map +0 -1
  261. package/dist/action/config/schema.d.ts +0 -318
  262. package/dist/action/config/schema.d.ts.map +0 -1
  263. package/dist/action/config/writer.d.ts +0 -11
  264. package/dist/action/config/writer.d.ts.map +0 -1
  265. package/dist/action/config/writer.test.d.ts +0 -2
  266. package/dist/action/config/writer.test.d.ts.map +0 -1
  267. package/dist/action/diff/classify.d.ts +0 -29
  268. package/dist/action/diff/classify.d.ts.map +0 -1
  269. package/dist/action/diff/classify.test.d.ts +0 -2
  270. package/dist/action/diff/classify.test.d.ts.map +0 -1
  271. package/dist/action/diff/coalesce.d.ts +0 -42
  272. package/dist/action/diff/coalesce.d.ts.map +0 -1
  273. package/dist/action/diff/coalesce.test.d.ts +0 -2
  274. package/dist/action/diff/coalesce.test.d.ts.map +0 -1
  275. package/dist/action/diff/context.d.ts +0 -30
  276. package/dist/action/diff/context.d.ts.map +0 -1
  277. package/dist/action/diff/context.test.d.ts +0 -2
  278. package/dist/action/diff/context.test.d.ts.map +0 -1
  279. package/dist/action/diff/index.d.ts +0 -5
  280. package/dist/action/diff/index.d.ts.map +0 -1
  281. package/dist/action/diff/parser.d.ts +0 -52
  282. package/dist/action/diff/parser.d.ts.map +0 -1
  283. package/dist/action/diff/parser.test.d.ts +0 -2
  284. package/dist/action/diff/parser.test.d.ts.map +0 -1
  285. package/dist/action/event/context.d.ts +0 -9
  286. package/dist/action/event/context.d.ts.map +0 -1
  287. package/dist/action/event/index.d.ts +0 -3
  288. package/dist/action/event/index.d.ts.map +0 -1
  289. package/dist/action/event/schedule-context.d.ts +0 -30
  290. package/dist/action/event/schedule-context.d.ts.map +0 -1
  291. package/dist/action/examples/examples.integration.test.d.ts +0 -2
  292. package/dist/action/examples/examples.integration.test.d.ts.map +0 -1
  293. package/dist/action/examples/index.d.ts +0 -50
  294. package/dist/action/examples/index.d.ts.map +0 -1
  295. package/dist/action/examples/index.test.d.ts +0 -2
  296. package/dist/action/examples/index.test.d.ts.map +0 -1
  297. package/dist/action/examples/setup.d.ts +0 -2
  298. package/dist/action/examples/setup.d.ts.map +0 -1
  299. package/dist/action/index.d.ts +0 -11
  300. package/dist/action/index.d.ts.map +0 -1
  301. package/dist/action/index.js +0 -38231
  302. package/dist/action/index.js.map +0 -1
  303. package/dist/action/licenses.txt +0 -992
  304. package/dist/action/main.d.ts +0 -2
  305. package/dist/action/main.d.ts.map +0 -1
  306. package/dist/action/main.js +0 -707
  307. package/dist/action/main.js.map +0 -1
  308. package/dist/action/output/dedup.d.ts +0 -153
  309. package/dist/action/output/dedup.d.ts.map +0 -1
  310. package/dist/action/output/dedup.test.d.ts +0 -2
  311. package/dist/action/output/dedup.test.d.ts.map +0 -1
  312. package/dist/action/output/github-checks.d.ts +0 -106
  313. package/dist/action/output/github-checks.d.ts.map +0 -1
  314. package/dist/action/output/github-checks.test.d.ts +0 -2
  315. package/dist/action/output/github-checks.test.d.ts.map +0 -1
  316. package/dist/action/output/github-issues.d.ts +0 -35
  317. package/dist/action/output/github-issues.d.ts.map +0 -1
  318. package/dist/action/output/index.d.ts +0 -6
  319. package/dist/action/output/index.d.ts.map +0 -1
  320. package/dist/action/output/issue-renderer.d.ts +0 -20
  321. package/dist/action/output/issue-renderer.d.ts.map +0 -1
  322. package/dist/action/output/renderer.d.ts +0 -4
  323. package/dist/action/output/renderer.d.ts.map +0 -1
  324. package/dist/action/output/renderer.test.d.ts +0 -2
  325. package/dist/action/output/renderer.test.d.ts.map +0 -1
  326. package/dist/action/output/stale.d.ts +0 -31
  327. package/dist/action/output/stale.d.ts.map +0 -1
  328. package/dist/action/output/stale.test.d.ts +0 -2
  329. package/dist/action/output/stale.test.d.ts.map +0 -1
  330. package/dist/action/output/types.d.ts +0 -31
  331. package/dist/action/output/types.d.ts.map +0 -1
  332. package/dist/action/package.json +0 -3
  333. package/dist/action/sdk/index.d.ts +0 -2
  334. package/dist/action/sdk/index.d.ts.map +0 -1
  335. package/dist/action/sdk/runner.d.ts +0 -202
  336. package/dist/action/sdk/runner.d.ts.map +0 -1
  337. package/dist/action/sdk/runner.test.d.ts +0 -2
  338. package/dist/action/sdk/runner.test.d.ts.map +0 -1
  339. package/dist/action/skills/index.d.ts +0 -5
  340. package/dist/action/skills/index.d.ts.map +0 -1
  341. package/dist/action/skills/loader.d.ts +0 -111
  342. package/dist/action/skills/loader.d.ts.map +0 -1
  343. package/dist/action/skills/loader.test.d.ts +0 -2
  344. package/dist/action/skills/loader.test.d.ts.map +0 -1
  345. package/dist/action/skills/remote.d.ts +0 -117
  346. package/dist/action/skills/remote.d.ts.map +0 -1
  347. package/dist/action/skills/remote.test.d.ts +0 -2
  348. package/dist/action/skills/remote.test.d.ts.map +0 -1
  349. package/dist/action/sourcemap-register.cjs +0 -1
  350. package/dist/action/triggers/matcher.d.ts +0 -30
  351. package/dist/action/triggers/matcher.d.ts.map +0 -1
  352. package/dist/action/triggers/matcher.test.d.ts +0 -2
  353. package/dist/action/triggers/matcher.test.d.ts.map +0 -1
  354. package/dist/action/types/index.d.ts +0 -269
  355. package/dist/action/types/index.d.ts.map +0 -1
  356. package/dist/action/utils/async.d.ts +0 -5
  357. package/dist/action/utils/async.d.ts.map +0 -1
  358. package/dist/action/utils/index.d.ts +0 -16
  359. package/dist/action/utils/index.d.ts.map +0 -1
  360. package/dist/action/utils/index.test.d.ts +0 -2
  361. package/dist/action/utils/index.test.d.ts.map +0 -1
  362. package/dist/action/utils/version.d.ts +0 -3
  363. package/dist/action/utils/version.d.ts.map +0 -1
  364. package/dist/cli/args.test.d.ts +0 -2
  365. package/dist/cli/args.test.d.ts.map +0 -1
  366. package/dist/cli/args.test.js +0 -392
  367. package/dist/cli/args.test.js.map +0 -1
  368. package/dist/cli/commands/init.test.d.ts +0 -2
  369. package/dist/cli/commands/init.test.d.ts.map +0 -1
  370. package/dist/cli/commands/init.test.js +0 -117
  371. package/dist/cli/commands/init.test.js.map +0 -1
  372. package/dist/cli/files.test.d.ts +0 -2
  373. package/dist/cli/files.test.d.ts.map +0 -1
  374. package/dist/cli/files.test.js +0 -117
  375. package/dist/cli/files.test.js.map +0 -1
  376. package/dist/cli/fix.test.d.ts +0 -2
  377. package/dist/cli/fix.test.d.ts.map +0 -1
  378. package/dist/cli/fix.test.js +0 -251
  379. package/dist/cli/fix.test.js.map +0 -1
  380. package/dist/cli/git.test.d.ts +0 -2
  381. package/dist/cli/git.test.d.ts.map +0 -1
  382. package/dist/cli/git.test.js +0 -96
  383. package/dist/cli/git.test.js.map +0 -1
  384. package/dist/cli/output/formatters.test.d.ts +0 -2
  385. package/dist/cli/output/formatters.test.d.ts.map +0 -1
  386. package/dist/cli/output/formatters.test.js +0 -152
  387. package/dist/cli/output/formatters.test.js.map +0 -1
  388. package/dist/cli/output/jsonl.test.d.ts +0 -2
  389. package/dist/cli/output/jsonl.test.d.ts.map +0 -1
  390. package/dist/cli/output/jsonl.test.js +0 -284
  391. package/dist/cli/output/jsonl.test.js.map +0 -1
  392. package/dist/cli/output/tty.test.d.ts +0 -2
  393. package/dist/cli/output/tty.test.d.ts.map +0 -1
  394. package/dist/cli/output/tty.test.js +0 -105
  395. package/dist/cli/output/tty.test.js.map +0 -1
  396. package/dist/cli/output/verbosity.test.d.ts +0 -2
  397. package/dist/cli/output/verbosity.test.d.ts.map +0 -1
  398. package/dist/cli/output/verbosity.test.js +0 -35
  399. package/dist/cli/output/verbosity.test.js.map +0 -1
  400. package/dist/cli/terminal.test.d.ts +0 -2
  401. package/dist/cli/terminal.test.d.ts.map +0 -1
  402. package/dist/cli/terminal.test.js +0 -123
  403. package/dist/cli/terminal.test.js.map +0 -1
  404. package/dist/config/loader.test.d.ts +0 -2
  405. package/dist/config/loader.test.d.ts.map +0 -1
  406. package/dist/config/loader.test.js +0 -263
  407. package/dist/config/loader.test.js.map +0 -1
  408. package/dist/config/writer.test.d.ts +0 -2
  409. package/dist/config/writer.test.d.ts.map +0 -1
  410. package/dist/config/writer.test.js +0 -98
  411. package/dist/config/writer.test.js.map +0 -1
  412. package/dist/diff/classify.test.d.ts +0 -2
  413. package/dist/diff/classify.test.d.ts.map +0 -1
  414. package/dist/diff/classify.test.js +0 -140
  415. package/dist/diff/classify.test.js.map +0 -1
  416. package/dist/diff/coalesce.test.d.ts +0 -2
  417. package/dist/diff/coalesce.test.d.ts.map +0 -1
  418. package/dist/diff/coalesce.test.js +0 -159
  419. package/dist/diff/coalesce.test.js.map +0 -1
  420. package/dist/diff/context.test.d.ts +0 -2
  421. package/dist/diff/context.test.d.ts.map +0 -1
  422. package/dist/diff/context.test.js +0 -190
  423. package/dist/diff/context.test.js.map +0 -1
  424. package/dist/diff/parser.test.d.ts +0 -2
  425. package/dist/diff/parser.test.d.ts.map +0 -1
  426. package/dist/diff/parser.test.js +0 -178
  427. package/dist/diff/parser.test.js.map +0 -1
  428. package/dist/examples/examples.integration.test.d.ts +0 -2
  429. package/dist/examples/examples.integration.test.d.ts.map +0 -1
  430. package/dist/examples/examples.integration.test.js +0 -55
  431. package/dist/examples/examples.integration.test.js.map +0 -1
  432. package/dist/examples/index.test.d.ts +0 -2
  433. package/dist/examples/index.test.d.ts.map +0 -1
  434. package/dist/examples/index.test.js +0 -88
  435. package/dist/examples/index.test.js.map +0 -1
  436. package/dist/output/dedup.test.d.ts +0 -2
  437. package/dist/output/dedup.test.d.ts.map +0 -1
  438. package/dist/output/dedup.test.js +0 -357
  439. package/dist/output/dedup.test.js.map +0 -1
  440. package/dist/output/github-checks.test.d.ts +0 -2
  441. package/dist/output/github-checks.test.d.ts.map +0 -1
  442. package/dist/output/github-checks.test.js +0 -255
  443. package/dist/output/github-checks.test.js.map +0 -1
  444. package/dist/output/renderer.test.d.ts +0 -2
  445. package/dist/output/renderer.test.d.ts.map +0 -1
  446. package/dist/output/renderer.test.js +0 -645
  447. package/dist/output/renderer.test.js.map +0 -1
  448. package/dist/output/stale.test.d.ts +0 -2
  449. package/dist/output/stale.test.d.ts.map +0 -1
  450. package/dist/output/stale.test.js +0 -330
  451. package/dist/output/stale.test.js.map +0 -1
  452. package/dist/sdk/runner.test.d.ts +0 -2
  453. package/dist/sdk/runner.test.d.ts.map +0 -1
  454. package/dist/sdk/runner.test.js +0 -677
  455. package/dist/sdk/runner.test.js.map +0 -1
  456. package/dist/skills/loader.test.d.ts +0 -2
  457. package/dist/skills/loader.test.d.ts.map +0 -1
  458. package/dist/skills/loader.test.js +0 -241
  459. package/dist/skills/loader.test.js.map +0 -1
  460. package/dist/skills/remote.test.d.ts +0 -2
  461. package/dist/skills/remote.test.d.ts.map +0 -1
  462. package/dist/skills/remote.test.js +0 -582
  463. package/dist/skills/remote.test.js.map +0 -1
  464. package/dist/triggers/matcher.test.d.ts +0 -2
  465. package/dist/triggers/matcher.test.d.ts.map +0 -1
  466. package/dist/triggers/matcher.test.js +0 -234
  467. package/dist/triggers/matcher.test.js.map +0 -1
  468. package/dist/utils/index.test.d.ts +0 -2
  469. package/dist/utils/index.test.d.ts.map +0 -1
  470. package/dist/utils/index.test.js +0 -68
  471. package/dist/utils/index.test.js.map +0 -1
  472. package/docs/astro.config.mjs +0 -43
  473. package/docs/package.json +0 -19
  474. package/docs/pnpm-lock.yaml +0 -4000
  475. package/docs/public/favicon.svg +0 -5
  476. package/docs/src/components/Code.astro +0 -141
  477. package/docs/src/components/PackageManagerTabs.astro +0 -183
  478. package/docs/src/components/Terminal.astro +0 -212
  479. package/docs/src/layouts/Base.astro +0 -380
  480. package/docs/src/pages/cli.astro +0 -167
  481. package/docs/src/pages/config.astro +0 -395
  482. package/docs/src/pages/guide.astro +0 -450
  483. package/docs/src/pages/index.astro +0 -490
  484. package/docs/src/styles/global.css +0 -551
  485. package/docs/src/utils/version.ts +0 -6
  486. package/docs/tsconfig.json +0 -3
  487. package/docs/vercel.json +0 -5
  488. package/eslint.config.js +0 -33
  489. package/src/action/index.ts +0 -1
  490. package/src/action/main.ts +0 -868
  491. package/src/cli/args.test.ts +0 -477
  492. package/src/cli/args.ts +0 -414
  493. package/src/cli/commands/add.ts +0 -447
  494. package/src/cli/commands/init.test.ts +0 -137
  495. package/src/cli/commands/init.ts +0 -134
  496. package/src/cli/commands/setup-app/browser.ts +0 -38
  497. package/src/cli/commands/setup-app/credentials.ts +0 -45
  498. package/src/cli/commands/setup-app/manifest.ts +0 -48
  499. package/src/cli/commands/setup-app/server.ts +0 -172
  500. package/src/cli/commands/setup-app.ts +0 -156
  501. package/src/cli/commands/sync.ts +0 -114
  502. package/src/cli/context.ts +0 -131
  503. package/src/cli/files.test.ts +0 -155
  504. package/src/cli/files.ts +0 -89
  505. package/src/cli/fix.test.ts +0 -310
  506. package/src/cli/fix.ts +0 -387
  507. package/src/cli/git.test.ts +0 -119
  508. package/src/cli/git.ts +0 -318
  509. package/src/cli/index.ts +0 -14
  510. package/src/cli/main.ts +0 -672
  511. package/src/cli/output/box.ts +0 -235
  512. package/src/cli/output/formatters.test.ts +0 -187
  513. package/src/cli/output/formatters.ts +0 -269
  514. package/src/cli/output/icons.ts +0 -19
  515. package/src/cli/output/index.ts +0 -44
  516. package/src/cli/output/ink-runner.tsx +0 -366
  517. package/src/cli/output/jsonl.test.ts +0 -347
  518. package/src/cli/output/jsonl.ts +0 -126
  519. package/src/cli/output/reporter.ts +0 -434
  520. package/src/cli/output/tasks.ts +0 -374
  521. package/src/cli/output/tty.test.ts +0 -117
  522. package/src/cli/output/tty.ts +0 -60
  523. package/src/cli/output/verbosity.test.ts +0 -40
  524. package/src/cli/output/verbosity.ts +0 -31
  525. package/src/cli/terminal.test.ts +0 -148
  526. package/src/cli/terminal.ts +0 -301
  527. package/src/config/index.ts +0 -3
  528. package/src/config/loader.test.ts +0 -313
  529. package/src/config/loader.ts +0 -103
  530. package/src/config/schema.ts +0 -168
  531. package/src/config/writer.test.ts +0 -119
  532. package/src/config/writer.ts +0 -84
  533. package/src/diff/classify.test.ts +0 -162
  534. package/src/diff/classify.ts +0 -92
  535. package/src/diff/coalesce.test.ts +0 -208
  536. package/src/diff/coalesce.ts +0 -133
  537. package/src/diff/context.test.ts +0 -226
  538. package/src/diff/context.ts +0 -201
  539. package/src/diff/index.ts +0 -4
  540. package/src/diff/parser.test.ts +0 -212
  541. package/src/diff/parser.ts +0 -149
  542. package/src/event/context.ts +0 -132
  543. package/src/event/index.ts +0 -2
  544. package/src/event/schedule-context.ts +0 -101
  545. package/src/examples/examples.integration.test.ts +0 -66
  546. package/src/examples/index.test.ts +0 -101
  547. package/src/examples/index.ts +0 -122
  548. package/src/examples/setup.ts +0 -25
  549. package/src/index.ts +0 -115
  550. package/src/output/dedup.test.ts +0 -419
  551. package/src/output/dedup.ts +0 -607
  552. package/src/output/github-checks.test.ts +0 -300
  553. package/src/output/github-checks.ts +0 -476
  554. package/src/output/github-issues.ts +0 -329
  555. package/src/output/index.ts +0 -5
  556. package/src/output/issue-renderer.ts +0 -197
  557. package/src/output/renderer.test.ts +0 -727
  558. package/src/output/renderer.ts +0 -217
  559. package/src/output/stale.test.ts +0 -375
  560. package/src/output/stale.ts +0 -155
  561. package/src/output/types.ts +0 -34
  562. package/src/sdk/index.ts +0 -1
  563. package/src/sdk/runner.test.ts +0 -806
  564. package/src/sdk/runner.ts +0 -1232
  565. package/src/skills/index.ts +0 -36
  566. package/src/skills/loader.test.ts +0 -300
  567. package/src/skills/loader.ts +0 -423
  568. package/src/skills/remote.test.ts +0 -704
  569. package/src/skills/remote.ts +0 -604
  570. package/src/triggers/matcher.test.ts +0 -277
  571. package/src/triggers/matcher.ts +0 -152
  572. package/src/types/index.ts +0 -194
  573. package/src/utils/async.ts +0 -18
  574. package/src/utils/index.test.ts +0 -84
  575. package/src/utils/index.ts +0 -51
  576. package/src/utils/version.ts +0 -17
  577. package/tsconfig.json +0 -25
  578. package/vitest.config.ts +0 -8
  579. package/vitest.integration.config.ts +0 -11
  580. 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
- });