@sentry/warden 0.1.1 → 0.3.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 (589) hide show
  1. package/dist/cli/commands/init.d.ts.map +1 -1
  2. package/dist/cli/commands/init.js +36 -2
  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/diff-apply.d.ts +15 -0
  10. package/dist/cli/diff-apply.d.ts.map +1 -0
  11. package/dist/cli/diff-apply.js +69 -0
  12. package/dist/cli/diff-apply.js.map +1 -0
  13. package/dist/cli/files.d.ts +11 -1
  14. package/dist/cli/files.d.ts.map +1 -1
  15. package/dist/cli/files.js +145 -4
  16. package/dist/cli/files.js.map +1 -1
  17. package/dist/cli/fix.d.ts +1 -5
  18. package/dist/cli/fix.d.ts.map +1 -1
  19. package/dist/cli/fix.js +3 -62
  20. package/dist/cli/fix.js.map +1 -1
  21. package/dist/cli/git.d.ts.map +1 -1
  22. package/dist/cli/git.js +5 -9
  23. package/dist/cli/git.js.map +1 -1
  24. package/dist/cli/index.js +0 -0
  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 +7 -4
  36. package/dist/output/dedup.d.ts.map +1 -1
  37. package/dist/output/dedup.js +48 -12
  38. package/dist/output/dedup.js.map +1 -1
  39. package/dist/output/renderer.d.ts.map +1 -1
  40. package/dist/output/renderer.js +52 -7
  41. package/dist/output/renderer.js.map +1 -1
  42. package/dist/output/stale.d.ts.map +1 -1
  43. package/dist/output/stale.js +7 -0
  44. package/dist/output/stale.js.map +1 -1
  45. package/dist/output/types.d.ts +15 -1
  46. package/dist/output/types.d.ts.map +1 -1
  47. package/dist/sdk/analyze.d.ts +18 -0
  48. package/dist/sdk/analyze.d.ts.map +1 -0
  49. package/dist/sdk/analyze.js +421 -0
  50. package/dist/sdk/analyze.js.map +1 -0
  51. package/dist/sdk/errors.d.ts +23 -0
  52. package/dist/sdk/errors.d.ts.map +1 -0
  53. package/dist/sdk/errors.js +74 -0
  54. package/dist/sdk/errors.js.map +1 -0
  55. package/dist/sdk/extract.d.ts +44 -0
  56. package/dist/sdk/extract.d.ts.map +1 -0
  57. package/dist/sdk/extract.js +224 -0
  58. package/dist/sdk/extract.js.map +1 -0
  59. package/dist/sdk/prepare.d.ts +13 -0
  60. package/dist/sdk/prepare.d.ts.map +1 -0
  61. package/dist/sdk/prepare.js +73 -0
  62. package/dist/sdk/prepare.js.map +1 -0
  63. package/dist/sdk/prompt.d.ts +30 -0
  64. package/dist/sdk/prompt.d.ts.map +1 -0
  65. package/dist/sdk/prompt.js +109 -0
  66. package/dist/sdk/prompt.js.map +1 -0
  67. package/dist/sdk/retry.d.ts +12 -0
  68. package/dist/sdk/retry.d.ts.map +1 -0
  69. package/dist/sdk/retry.js +31 -0
  70. package/dist/sdk/retry.js.map +1 -0
  71. package/dist/sdk/runner.d.ts +22 -199
  72. package/dist/sdk/runner.d.ts.map +1 -1
  73. package/dist/sdk/runner.js +26 -884
  74. package/dist/sdk/runner.js.map +1 -1
  75. package/dist/sdk/types.d.ts +127 -0
  76. package/dist/sdk/types.d.ts.map +1 -0
  77. package/dist/sdk/types.js +5 -0
  78. package/dist/sdk/types.js.map +1 -0
  79. package/dist/sdk/usage.d.ts +20 -0
  80. package/dist/sdk/usage.d.ts.map +1 -0
  81. package/dist/sdk/usage.js +44 -0
  82. package/dist/sdk/usage.js.map +1 -0
  83. package/dist/skills/remote.d.ts.map +1 -1
  84. package/dist/skills/remote.js +3 -7
  85. package/dist/skills/remote.js.map +1 -1
  86. package/dist/types/index.d.ts +1 -0
  87. package/dist/types/index.d.ts.map +1 -1
  88. package/dist/types/index.js +2 -0
  89. package/dist/types/index.js.map +1 -1
  90. package/dist/utils/exec.d.ts +61 -0
  91. package/dist/utils/exec.d.ts.map +1 -0
  92. package/dist/utils/exec.js +111 -0
  93. package/dist/utils/exec.js.map +1 -0
  94. package/dist/utils/index.d.ts +2 -0
  95. package/dist/utils/index.d.ts.map +1 -1
  96. package/dist/utils/index.js +1 -0
  97. package/dist/utils/index.js.map +1 -1
  98. package/package.json +15 -16
  99. package/.agents/skills/find-bugs/SKILL.md +0 -75
  100. package/.agents/skills/vercel-react-best-practices/AGENTS.md +0 -2934
  101. package/.agents/skills/vercel-react-best-practices/SKILL.md +0 -136
  102. package/.agents/skills/vercel-react-best-practices/rules/advanced-event-handler-refs.md +0 -55
  103. package/.agents/skills/vercel-react-best-practices/rules/advanced-init-once.md +0 -42
  104. package/.agents/skills/vercel-react-best-practices/rules/advanced-use-latest.md +0 -39
  105. package/.agents/skills/vercel-react-best-practices/rules/async-api-routes.md +0 -38
  106. package/.agents/skills/vercel-react-best-practices/rules/async-defer-await.md +0 -80
  107. package/.agents/skills/vercel-react-best-practices/rules/async-dependencies.md +0 -51
  108. package/.agents/skills/vercel-react-best-practices/rules/async-parallel.md +0 -28
  109. package/.agents/skills/vercel-react-best-practices/rules/async-suspense-boundaries.md +0 -99
  110. package/.agents/skills/vercel-react-best-practices/rules/bundle-barrel-imports.md +0 -59
  111. package/.agents/skills/vercel-react-best-practices/rules/bundle-conditional.md +0 -31
  112. package/.agents/skills/vercel-react-best-practices/rules/bundle-defer-third-party.md +0 -49
  113. package/.agents/skills/vercel-react-best-practices/rules/bundle-dynamic-imports.md +0 -35
  114. package/.agents/skills/vercel-react-best-practices/rules/bundle-preload.md +0 -50
  115. package/.agents/skills/vercel-react-best-practices/rules/client-event-listeners.md +0 -74
  116. package/.agents/skills/vercel-react-best-practices/rules/client-localstorage-schema.md +0 -71
  117. package/.agents/skills/vercel-react-best-practices/rules/client-passive-event-listeners.md +0 -48
  118. package/.agents/skills/vercel-react-best-practices/rules/client-swr-dedup.md +0 -56
  119. package/.agents/skills/vercel-react-best-practices/rules/js-batch-dom-css.md +0 -107
  120. package/.agents/skills/vercel-react-best-practices/rules/js-cache-function-results.md +0 -80
  121. package/.agents/skills/vercel-react-best-practices/rules/js-cache-property-access.md +0 -28
  122. package/.agents/skills/vercel-react-best-practices/rules/js-cache-storage.md +0 -70
  123. package/.agents/skills/vercel-react-best-practices/rules/js-combine-iterations.md +0 -32
  124. package/.agents/skills/vercel-react-best-practices/rules/js-early-exit.md +0 -50
  125. package/.agents/skills/vercel-react-best-practices/rules/js-hoist-regexp.md +0 -45
  126. package/.agents/skills/vercel-react-best-practices/rules/js-index-maps.md +0 -37
  127. package/.agents/skills/vercel-react-best-practices/rules/js-length-check-first.md +0 -49
  128. package/.agents/skills/vercel-react-best-practices/rules/js-min-max-loop.md +0 -82
  129. package/.agents/skills/vercel-react-best-practices/rules/js-set-map-lookups.md +0 -24
  130. package/.agents/skills/vercel-react-best-practices/rules/js-tosorted-immutable.md +0 -57
  131. package/.agents/skills/vercel-react-best-practices/rules/rendering-activity.md +0 -26
  132. package/.agents/skills/vercel-react-best-practices/rules/rendering-animate-svg-wrapper.md +0 -47
  133. package/.agents/skills/vercel-react-best-practices/rules/rendering-conditional-render.md +0 -40
  134. package/.agents/skills/vercel-react-best-practices/rules/rendering-content-visibility.md +0 -38
  135. package/.agents/skills/vercel-react-best-practices/rules/rendering-hoist-jsx.md +0 -46
  136. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-no-flicker.md +0 -82
  137. package/.agents/skills/vercel-react-best-practices/rules/rendering-hydration-suppress-warning.md +0 -30
  138. package/.agents/skills/vercel-react-best-practices/rules/rendering-svg-precision.md +0 -28
  139. package/.agents/skills/vercel-react-best-practices/rules/rendering-usetransition-loading.md +0 -75
  140. package/.agents/skills/vercel-react-best-practices/rules/rerender-defer-reads.md +0 -39
  141. package/.agents/skills/vercel-react-best-practices/rules/rerender-dependencies.md +0 -45
  142. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state-no-effect.md +0 -40
  143. package/.agents/skills/vercel-react-best-practices/rules/rerender-derived-state.md +0 -29
  144. package/.agents/skills/vercel-react-best-practices/rules/rerender-functional-setstate.md +0 -74
  145. package/.agents/skills/vercel-react-best-practices/rules/rerender-lazy-state-init.md +0 -58
  146. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo-with-default-value.md +0 -38
  147. package/.agents/skills/vercel-react-best-practices/rules/rerender-memo.md +0 -44
  148. package/.agents/skills/vercel-react-best-practices/rules/rerender-move-effect-to-event.md +0 -45
  149. package/.agents/skills/vercel-react-best-practices/rules/rerender-simple-expression-in-memo.md +0 -35
  150. package/.agents/skills/vercel-react-best-practices/rules/rerender-transitions.md +0 -40
  151. package/.agents/skills/vercel-react-best-practices/rules/rerender-use-ref-transient-values.md +0 -73
  152. package/.agents/skills/vercel-react-best-practices/rules/server-after-nonblocking.md +0 -73
  153. package/.agents/skills/vercel-react-best-practices/rules/server-auth-actions.md +0 -96
  154. package/.agents/skills/vercel-react-best-practices/rules/server-cache-lru.md +0 -41
  155. package/.agents/skills/vercel-react-best-practices/rules/server-cache-react.md +0 -76
  156. package/.agents/skills/vercel-react-best-practices/rules/server-dedup-props.md +0 -65
  157. package/.agents/skills/vercel-react-best-practices/rules/server-parallel-fetching.md +0 -83
  158. package/.agents/skills/vercel-react-best-practices/rules/server-serialization.md +0 -38
  159. package/.claude/settings.json +0 -57
  160. package/.claude/skills/agent-prompt/SKILL.md +0 -54
  161. package/.claude/skills/agent-prompt/references/agentic-patterns.md +0 -94
  162. package/.claude/skills/agent-prompt/references/anti-patterns.md +0 -140
  163. package/.claude/skills/agent-prompt/references/context-design.md +0 -124
  164. package/.claude/skills/agent-prompt/references/core-principles.md +0 -75
  165. package/.claude/skills/agent-prompt/references/model-guidance.md +0 -118
  166. package/.claude/skills/agent-prompt/references/output-formats.md +0 -98
  167. package/.claude/skills/agent-prompt/references/skill-structure.md +0 -115
  168. package/.claude/skills/agent-prompt/references/system-prompts.md +0 -115
  169. package/.claude/skills/notseer/SKILL.md +0 -131
  170. package/.claude/skills/skill-writer/SKILL.md +0 -140
  171. package/.claude/skills/testing-guidelines/SKILL.md +0 -132
  172. package/.claude/skills/warden-skill/SKILL.md +0 -226
  173. package/.claude/skills/warden-skill/references/config-schema.md +0 -116
  174. package/.dex/config.toml +0 -2
  175. package/.github/workflows/ci.yml +0 -33
  176. package/.github/workflows/release.yml +0 -59
  177. package/.github/workflows/warden.yml +0 -40
  178. package/AGENTS.md +0 -89
  179. package/CONTRIBUTING.md +0 -60
  180. package/SPEC.md +0 -263
  181. package/action.yml +0 -87
  182. package/assets/favicon.png +0 -0
  183. package/assets/warden-icon-bw.svg +0 -5
  184. package/assets/warden-icon-purple.png +0 -0
  185. package/assets/warden-icon-purple.svg +0 -5
  186. package/dist/action/159.index.js +0 -523
  187. package/dist/action/159.index.js.map +0 -1
  188. package/dist/action/action/index.d.ts +0 -2
  189. package/dist/action/action/index.d.ts.map +0 -1
  190. package/dist/action/action/main.d.ts +0 -2
  191. package/dist/action/action/main.d.ts.map +0 -1
  192. package/dist/action/cli/args.d.ts +0 -74
  193. package/dist/action/cli/args.d.ts.map +0 -1
  194. package/dist/action/cli/args.test.d.ts +0 -2
  195. package/dist/action/cli/args.test.d.ts.map +0 -1
  196. package/dist/action/cli/commands/add.d.ts +0 -7
  197. package/dist/action/cli/commands/add.d.ts.map +0 -1
  198. package/dist/action/cli/commands/init.d.ts +0 -10
  199. package/dist/action/cli/commands/init.d.ts.map +0 -1
  200. package/dist/action/cli/commands/init.test.d.ts +0 -2
  201. package/dist/action/cli/commands/init.test.d.ts.map +0 -1
  202. package/dist/action/cli/commands/setup-app/browser.d.ts +0 -9
  203. package/dist/action/cli/commands/setup-app/browser.d.ts.map +0 -1
  204. package/dist/action/cli/commands/setup-app/credentials.d.ts +0 -15
  205. package/dist/action/cli/commands/setup-app/credentials.d.ts.map +0 -1
  206. package/dist/action/cli/commands/setup-app/manifest.d.ts +0 -24
  207. package/dist/action/cli/commands/setup-app/manifest.d.ts.map +0 -1
  208. package/dist/action/cli/commands/setup-app/server.d.ts +0 -28
  209. package/dist/action/cli/commands/setup-app/server.d.ts.map +0 -1
  210. package/dist/action/cli/commands/setup-app.d.ts +0 -11
  211. package/dist/action/cli/commands/setup-app.d.ts.map +0 -1
  212. package/dist/action/cli/commands/sync.d.ts +0 -9
  213. package/dist/action/cli/commands/sync.d.ts.map +0 -1
  214. package/dist/action/cli/context.d.ts +0 -27
  215. package/dist/action/cli/context.d.ts.map +0 -1
  216. package/dist/action/cli/files.d.ts +0 -22
  217. package/dist/action/cli/files.d.ts.map +0 -1
  218. package/dist/action/cli/files.test.d.ts +0 -2
  219. package/dist/action/cli/files.test.d.ts.map +0 -1
  220. package/dist/action/cli/fix.d.ts +0 -41
  221. package/dist/action/cli/fix.d.ts.map +0 -1
  222. package/dist/action/cli/fix.test.d.ts +0 -2
  223. package/dist/action/cli/fix.test.d.ts.map +0 -1
  224. package/dist/action/cli/git.d.ts +0 -73
  225. package/dist/action/cli/git.d.ts.map +0 -1
  226. package/dist/action/cli/git.test.d.ts +0 -2
  227. package/dist/action/cli/git.test.d.ts.map +0 -1
  228. package/dist/action/cli/index.d.ts +0 -3
  229. package/dist/action/cli/index.d.ts.map +0 -1
  230. package/dist/action/cli/main.d.ts +0 -7
  231. package/dist/action/cli/main.d.ts.map +0 -1
  232. package/dist/action/cli/output/box.d.ts +0 -75
  233. package/dist/action/cli/output/box.d.ts.map +0 -1
  234. package/dist/action/cli/output/formatters.d.ts +0 -90
  235. package/dist/action/cli/output/formatters.d.ts.map +0 -1
  236. package/dist/action/cli/output/formatters.test.d.ts +0 -2
  237. package/dist/action/cli/output/formatters.test.d.ts.map +0 -1
  238. package/dist/action/cli/output/icons.d.ts +0 -15
  239. package/dist/action/cli/output/icons.d.ts.map +0 -1
  240. package/dist/action/cli/output/index.d.ts +0 -10
  241. package/dist/action/cli/output/index.d.ts.map +0 -1
  242. package/dist/action/cli/output/ink-runner.d.ts +0 -29
  243. package/dist/action/cli/output/ink-runner.d.ts.map +0 -1
  244. package/dist/action/cli/output/jsonl.d.ts +0 -43
  245. package/dist/action/cli/output/jsonl.d.ts.map +0 -1
  246. package/dist/action/cli/output/jsonl.test.d.ts +0 -2
  247. package/dist/action/cli/output/jsonl.test.d.ts.map +0 -1
  248. package/dist/action/cli/output/reporter.d.ts +0 -108
  249. package/dist/action/cli/output/reporter.d.ts.map +0 -1
  250. package/dist/action/cli/output/tasks.d.ts +0 -89
  251. package/dist/action/cli/output/tasks.d.ts.map +0 -1
  252. package/dist/action/cli/output/tty.d.ts +0 -21
  253. package/dist/action/cli/output/tty.d.ts.map +0 -1
  254. package/dist/action/cli/output/tty.test.d.ts +0 -2
  255. package/dist/action/cli/output/tty.test.d.ts.map +0 -1
  256. package/dist/action/cli/output/verbosity.d.ts +0 -20
  257. package/dist/action/cli/output/verbosity.d.ts.map +0 -1
  258. package/dist/action/cli/output/verbosity.test.d.ts +0 -2
  259. package/dist/action/cli/output/verbosity.test.d.ts.map +0 -1
  260. package/dist/action/cli/terminal.d.ts +0 -19
  261. package/dist/action/cli/terminal.d.ts.map +0 -1
  262. package/dist/action/cli/terminal.test.d.ts +0 -2
  263. package/dist/action/cli/terminal.test.d.ts.map +0 -1
  264. package/dist/action/config/index.d.ts +0 -4
  265. package/dist/action/config/index.d.ts.map +0 -1
  266. package/dist/action/config/loader.d.ts +0 -27
  267. package/dist/action/config/loader.d.ts.map +0 -1
  268. package/dist/action/config/loader.test.d.ts +0 -2
  269. package/dist/action/config/loader.test.d.ts.map +0 -1
  270. package/dist/action/config/schema.d.ts +0 -318
  271. package/dist/action/config/schema.d.ts.map +0 -1
  272. package/dist/action/config/writer.d.ts +0 -11
  273. package/dist/action/config/writer.d.ts.map +0 -1
  274. package/dist/action/config/writer.test.d.ts +0 -2
  275. package/dist/action/config/writer.test.d.ts.map +0 -1
  276. package/dist/action/diff/classify.d.ts +0 -29
  277. package/dist/action/diff/classify.d.ts.map +0 -1
  278. package/dist/action/diff/classify.test.d.ts +0 -2
  279. package/dist/action/diff/classify.test.d.ts.map +0 -1
  280. package/dist/action/diff/coalesce.d.ts +0 -42
  281. package/dist/action/diff/coalesce.d.ts.map +0 -1
  282. package/dist/action/diff/coalesce.test.d.ts +0 -2
  283. package/dist/action/diff/coalesce.test.d.ts.map +0 -1
  284. package/dist/action/diff/context.d.ts +0 -30
  285. package/dist/action/diff/context.d.ts.map +0 -1
  286. package/dist/action/diff/context.test.d.ts +0 -2
  287. package/dist/action/diff/context.test.d.ts.map +0 -1
  288. package/dist/action/diff/index.d.ts +0 -5
  289. package/dist/action/diff/index.d.ts.map +0 -1
  290. package/dist/action/diff/parser.d.ts +0 -52
  291. package/dist/action/diff/parser.d.ts.map +0 -1
  292. package/dist/action/diff/parser.test.d.ts +0 -2
  293. package/dist/action/diff/parser.test.d.ts.map +0 -1
  294. package/dist/action/event/context.d.ts +0 -9
  295. package/dist/action/event/context.d.ts.map +0 -1
  296. package/dist/action/event/index.d.ts +0 -3
  297. package/dist/action/event/index.d.ts.map +0 -1
  298. package/dist/action/event/schedule-context.d.ts +0 -30
  299. package/dist/action/event/schedule-context.d.ts.map +0 -1
  300. package/dist/action/examples/examples.integration.test.d.ts +0 -2
  301. package/dist/action/examples/examples.integration.test.d.ts.map +0 -1
  302. package/dist/action/examples/index.d.ts +0 -50
  303. package/dist/action/examples/index.d.ts.map +0 -1
  304. package/dist/action/examples/index.test.d.ts +0 -2
  305. package/dist/action/examples/index.test.d.ts.map +0 -1
  306. package/dist/action/examples/setup.d.ts +0 -2
  307. package/dist/action/examples/setup.d.ts.map +0 -1
  308. package/dist/action/index.d.ts +0 -11
  309. package/dist/action/index.d.ts.map +0 -1
  310. package/dist/action/index.js +0 -38231
  311. package/dist/action/index.js.map +0 -1
  312. package/dist/action/licenses.txt +0 -992
  313. package/dist/action/main.d.ts +0 -2
  314. package/dist/action/main.d.ts.map +0 -1
  315. package/dist/action/main.js +0 -707
  316. package/dist/action/main.js.map +0 -1
  317. package/dist/action/output/dedup.d.ts +0 -153
  318. package/dist/action/output/dedup.d.ts.map +0 -1
  319. package/dist/action/output/dedup.test.d.ts +0 -2
  320. package/dist/action/output/dedup.test.d.ts.map +0 -1
  321. package/dist/action/output/github-checks.d.ts +0 -106
  322. package/dist/action/output/github-checks.d.ts.map +0 -1
  323. package/dist/action/output/github-checks.test.d.ts +0 -2
  324. package/dist/action/output/github-checks.test.d.ts.map +0 -1
  325. package/dist/action/output/github-issues.d.ts +0 -35
  326. package/dist/action/output/github-issues.d.ts.map +0 -1
  327. package/dist/action/output/index.d.ts +0 -6
  328. package/dist/action/output/index.d.ts.map +0 -1
  329. package/dist/action/output/issue-renderer.d.ts +0 -20
  330. package/dist/action/output/issue-renderer.d.ts.map +0 -1
  331. package/dist/action/output/renderer.d.ts +0 -4
  332. package/dist/action/output/renderer.d.ts.map +0 -1
  333. package/dist/action/output/renderer.test.d.ts +0 -2
  334. package/dist/action/output/renderer.test.d.ts.map +0 -1
  335. package/dist/action/output/stale.d.ts +0 -31
  336. package/dist/action/output/stale.d.ts.map +0 -1
  337. package/dist/action/output/stale.test.d.ts +0 -2
  338. package/dist/action/output/stale.test.d.ts.map +0 -1
  339. package/dist/action/output/types.d.ts +0 -31
  340. package/dist/action/output/types.d.ts.map +0 -1
  341. package/dist/action/package.json +0 -3
  342. package/dist/action/sdk/index.d.ts +0 -2
  343. package/dist/action/sdk/index.d.ts.map +0 -1
  344. package/dist/action/sdk/runner.d.ts +0 -202
  345. package/dist/action/sdk/runner.d.ts.map +0 -1
  346. package/dist/action/sdk/runner.test.d.ts +0 -2
  347. package/dist/action/sdk/runner.test.d.ts.map +0 -1
  348. package/dist/action/skills/index.d.ts +0 -5
  349. package/dist/action/skills/index.d.ts.map +0 -1
  350. package/dist/action/skills/loader.d.ts +0 -111
  351. package/dist/action/skills/loader.d.ts.map +0 -1
  352. package/dist/action/skills/loader.test.d.ts +0 -2
  353. package/dist/action/skills/loader.test.d.ts.map +0 -1
  354. package/dist/action/skills/remote.d.ts +0 -117
  355. package/dist/action/skills/remote.d.ts.map +0 -1
  356. package/dist/action/skills/remote.test.d.ts +0 -2
  357. package/dist/action/skills/remote.test.d.ts.map +0 -1
  358. package/dist/action/sourcemap-register.cjs +0 -1
  359. package/dist/action/triggers/matcher.d.ts +0 -30
  360. package/dist/action/triggers/matcher.d.ts.map +0 -1
  361. package/dist/action/triggers/matcher.test.d.ts +0 -2
  362. package/dist/action/triggers/matcher.test.d.ts.map +0 -1
  363. package/dist/action/types/index.d.ts +0 -269
  364. package/dist/action/types/index.d.ts.map +0 -1
  365. package/dist/action/utils/async.d.ts +0 -5
  366. package/dist/action/utils/async.d.ts.map +0 -1
  367. package/dist/action/utils/index.d.ts +0 -16
  368. package/dist/action/utils/index.d.ts.map +0 -1
  369. package/dist/action/utils/index.test.d.ts +0 -2
  370. package/dist/action/utils/index.test.d.ts.map +0 -1
  371. package/dist/action/utils/version.d.ts +0 -3
  372. package/dist/action/utils/version.d.ts.map +0 -1
  373. package/dist/cli/args.test.d.ts +0 -2
  374. package/dist/cli/args.test.d.ts.map +0 -1
  375. package/dist/cli/args.test.js +0 -392
  376. package/dist/cli/args.test.js.map +0 -1
  377. package/dist/cli/commands/init.test.d.ts +0 -2
  378. package/dist/cli/commands/init.test.d.ts.map +0 -1
  379. package/dist/cli/commands/init.test.js +0 -117
  380. package/dist/cli/commands/init.test.js.map +0 -1
  381. package/dist/cli/files.test.d.ts +0 -2
  382. package/dist/cli/files.test.d.ts.map +0 -1
  383. package/dist/cli/files.test.js +0 -117
  384. package/dist/cli/files.test.js.map +0 -1
  385. package/dist/cli/fix.test.d.ts +0 -2
  386. package/dist/cli/fix.test.d.ts.map +0 -1
  387. package/dist/cli/fix.test.js +0 -251
  388. package/dist/cli/fix.test.js.map +0 -1
  389. package/dist/cli/git.test.d.ts +0 -2
  390. package/dist/cli/git.test.d.ts.map +0 -1
  391. package/dist/cli/git.test.js +0 -96
  392. package/dist/cli/git.test.js.map +0 -1
  393. package/dist/cli/output/formatters.test.d.ts +0 -2
  394. package/dist/cli/output/formatters.test.d.ts.map +0 -1
  395. package/dist/cli/output/formatters.test.js +0 -152
  396. package/dist/cli/output/formatters.test.js.map +0 -1
  397. package/dist/cli/output/jsonl.test.d.ts +0 -2
  398. package/dist/cli/output/jsonl.test.d.ts.map +0 -1
  399. package/dist/cli/output/jsonl.test.js +0 -284
  400. package/dist/cli/output/jsonl.test.js.map +0 -1
  401. package/dist/cli/output/tty.test.d.ts +0 -2
  402. package/dist/cli/output/tty.test.d.ts.map +0 -1
  403. package/dist/cli/output/tty.test.js +0 -105
  404. package/dist/cli/output/tty.test.js.map +0 -1
  405. package/dist/cli/output/verbosity.test.d.ts +0 -2
  406. package/dist/cli/output/verbosity.test.d.ts.map +0 -1
  407. package/dist/cli/output/verbosity.test.js +0 -35
  408. package/dist/cli/output/verbosity.test.js.map +0 -1
  409. package/dist/cli/terminal.test.d.ts +0 -2
  410. package/dist/cli/terminal.test.d.ts.map +0 -1
  411. package/dist/cli/terminal.test.js +0 -123
  412. package/dist/cli/terminal.test.js.map +0 -1
  413. package/dist/config/loader.test.d.ts +0 -2
  414. package/dist/config/loader.test.d.ts.map +0 -1
  415. package/dist/config/loader.test.js +0 -263
  416. package/dist/config/loader.test.js.map +0 -1
  417. package/dist/config/writer.test.d.ts +0 -2
  418. package/dist/config/writer.test.d.ts.map +0 -1
  419. package/dist/config/writer.test.js +0 -98
  420. package/dist/config/writer.test.js.map +0 -1
  421. package/dist/diff/classify.test.d.ts +0 -2
  422. package/dist/diff/classify.test.d.ts.map +0 -1
  423. package/dist/diff/classify.test.js +0 -140
  424. package/dist/diff/classify.test.js.map +0 -1
  425. package/dist/diff/coalesce.test.d.ts +0 -2
  426. package/dist/diff/coalesce.test.d.ts.map +0 -1
  427. package/dist/diff/coalesce.test.js +0 -159
  428. package/dist/diff/coalesce.test.js.map +0 -1
  429. package/dist/diff/context.test.d.ts +0 -2
  430. package/dist/diff/context.test.d.ts.map +0 -1
  431. package/dist/diff/context.test.js +0 -190
  432. package/dist/diff/context.test.js.map +0 -1
  433. package/dist/diff/parser.test.d.ts +0 -2
  434. package/dist/diff/parser.test.d.ts.map +0 -1
  435. package/dist/diff/parser.test.js +0 -178
  436. package/dist/diff/parser.test.js.map +0 -1
  437. package/dist/examples/examples.integration.test.d.ts +0 -2
  438. package/dist/examples/examples.integration.test.d.ts.map +0 -1
  439. package/dist/examples/examples.integration.test.js +0 -55
  440. package/dist/examples/examples.integration.test.js.map +0 -1
  441. package/dist/examples/index.test.d.ts +0 -2
  442. package/dist/examples/index.test.d.ts.map +0 -1
  443. package/dist/examples/index.test.js +0 -88
  444. package/dist/examples/index.test.js.map +0 -1
  445. package/dist/output/dedup.test.d.ts +0 -2
  446. package/dist/output/dedup.test.d.ts.map +0 -1
  447. package/dist/output/dedup.test.js +0 -357
  448. package/dist/output/dedup.test.js.map +0 -1
  449. package/dist/output/github-checks.test.d.ts +0 -2
  450. package/dist/output/github-checks.test.d.ts.map +0 -1
  451. package/dist/output/github-checks.test.js +0 -255
  452. package/dist/output/github-checks.test.js.map +0 -1
  453. package/dist/output/renderer.test.d.ts +0 -2
  454. package/dist/output/renderer.test.d.ts.map +0 -1
  455. package/dist/output/renderer.test.js +0 -645
  456. package/dist/output/renderer.test.js.map +0 -1
  457. package/dist/output/stale.test.d.ts +0 -2
  458. package/dist/output/stale.test.d.ts.map +0 -1
  459. package/dist/output/stale.test.js +0 -330
  460. package/dist/output/stale.test.js.map +0 -1
  461. package/dist/sdk/runner.test.d.ts +0 -2
  462. package/dist/sdk/runner.test.d.ts.map +0 -1
  463. package/dist/sdk/runner.test.js +0 -677
  464. package/dist/sdk/runner.test.js.map +0 -1
  465. package/dist/skills/loader.test.d.ts +0 -2
  466. package/dist/skills/loader.test.d.ts.map +0 -1
  467. package/dist/skills/loader.test.js +0 -241
  468. package/dist/skills/loader.test.js.map +0 -1
  469. package/dist/skills/remote.test.d.ts +0 -2
  470. package/dist/skills/remote.test.d.ts.map +0 -1
  471. package/dist/skills/remote.test.js +0 -582
  472. package/dist/skills/remote.test.js.map +0 -1
  473. package/dist/triggers/matcher.test.d.ts +0 -2
  474. package/dist/triggers/matcher.test.d.ts.map +0 -1
  475. package/dist/triggers/matcher.test.js +0 -234
  476. package/dist/triggers/matcher.test.js.map +0 -1
  477. package/dist/utils/index.test.d.ts +0 -2
  478. package/dist/utils/index.test.d.ts.map +0 -1
  479. package/dist/utils/index.test.js +0 -68
  480. package/dist/utils/index.test.js.map +0 -1
  481. package/docs/astro.config.mjs +0 -43
  482. package/docs/package.json +0 -19
  483. package/docs/pnpm-lock.yaml +0 -4000
  484. package/docs/public/favicon.svg +0 -5
  485. package/docs/src/components/Code.astro +0 -141
  486. package/docs/src/components/PackageManagerTabs.astro +0 -183
  487. package/docs/src/components/Terminal.astro +0 -212
  488. package/docs/src/layouts/Base.astro +0 -380
  489. package/docs/src/pages/cli.astro +0 -167
  490. package/docs/src/pages/config.astro +0 -395
  491. package/docs/src/pages/guide.astro +0 -450
  492. package/docs/src/pages/index.astro +0 -490
  493. package/docs/src/styles/global.css +0 -551
  494. package/docs/src/utils/version.ts +0 -6
  495. package/docs/tsconfig.json +0 -3
  496. package/docs/vercel.json +0 -5
  497. package/eslint.config.js +0 -33
  498. package/src/action/index.ts +0 -1
  499. package/src/action/main.ts +0 -868
  500. package/src/cli/args.test.ts +0 -477
  501. package/src/cli/args.ts +0 -414
  502. package/src/cli/commands/add.ts +0 -447
  503. package/src/cli/commands/init.test.ts +0 -137
  504. package/src/cli/commands/init.ts +0 -134
  505. package/src/cli/commands/setup-app/browser.ts +0 -38
  506. package/src/cli/commands/setup-app/credentials.ts +0 -45
  507. package/src/cli/commands/setup-app/manifest.ts +0 -48
  508. package/src/cli/commands/setup-app/server.ts +0 -172
  509. package/src/cli/commands/setup-app.ts +0 -156
  510. package/src/cli/commands/sync.ts +0 -114
  511. package/src/cli/context.ts +0 -131
  512. package/src/cli/files.test.ts +0 -155
  513. package/src/cli/files.ts +0 -89
  514. package/src/cli/fix.test.ts +0 -310
  515. package/src/cli/fix.ts +0 -387
  516. package/src/cli/git.test.ts +0 -119
  517. package/src/cli/git.ts +0 -318
  518. package/src/cli/index.ts +0 -14
  519. package/src/cli/main.ts +0 -672
  520. package/src/cli/output/box.ts +0 -235
  521. package/src/cli/output/formatters.test.ts +0 -187
  522. package/src/cli/output/formatters.ts +0 -269
  523. package/src/cli/output/icons.ts +0 -19
  524. package/src/cli/output/index.ts +0 -44
  525. package/src/cli/output/ink-runner.tsx +0 -366
  526. package/src/cli/output/jsonl.test.ts +0 -347
  527. package/src/cli/output/jsonl.ts +0 -126
  528. package/src/cli/output/reporter.ts +0 -434
  529. package/src/cli/output/tasks.ts +0 -374
  530. package/src/cli/output/tty.test.ts +0 -117
  531. package/src/cli/output/tty.ts +0 -60
  532. package/src/cli/output/verbosity.test.ts +0 -40
  533. package/src/cli/output/verbosity.ts +0 -31
  534. package/src/cli/terminal.test.ts +0 -148
  535. package/src/cli/terminal.ts +0 -301
  536. package/src/config/index.ts +0 -3
  537. package/src/config/loader.test.ts +0 -313
  538. package/src/config/loader.ts +0 -103
  539. package/src/config/schema.ts +0 -168
  540. package/src/config/writer.test.ts +0 -119
  541. package/src/config/writer.ts +0 -84
  542. package/src/diff/classify.test.ts +0 -162
  543. package/src/diff/classify.ts +0 -92
  544. package/src/diff/coalesce.test.ts +0 -208
  545. package/src/diff/coalesce.ts +0 -133
  546. package/src/diff/context.test.ts +0 -226
  547. package/src/diff/context.ts +0 -201
  548. package/src/diff/index.ts +0 -4
  549. package/src/diff/parser.test.ts +0 -212
  550. package/src/diff/parser.ts +0 -149
  551. package/src/event/context.ts +0 -132
  552. package/src/event/index.ts +0 -2
  553. package/src/event/schedule-context.ts +0 -101
  554. package/src/examples/examples.integration.test.ts +0 -66
  555. package/src/examples/index.test.ts +0 -101
  556. package/src/examples/index.ts +0 -122
  557. package/src/examples/setup.ts +0 -25
  558. package/src/index.ts +0 -115
  559. package/src/output/dedup.test.ts +0 -419
  560. package/src/output/dedup.ts +0 -607
  561. package/src/output/github-checks.test.ts +0 -300
  562. package/src/output/github-checks.ts +0 -476
  563. package/src/output/github-issues.ts +0 -329
  564. package/src/output/index.ts +0 -5
  565. package/src/output/issue-renderer.ts +0 -197
  566. package/src/output/renderer.test.ts +0 -727
  567. package/src/output/renderer.ts +0 -217
  568. package/src/output/stale.test.ts +0 -375
  569. package/src/output/stale.ts +0 -155
  570. package/src/output/types.ts +0 -34
  571. package/src/sdk/index.ts +0 -1
  572. package/src/sdk/runner.test.ts +0 -806
  573. package/src/sdk/runner.ts +0 -1232
  574. package/src/skills/index.ts +0 -36
  575. package/src/skills/loader.test.ts +0 -300
  576. package/src/skills/loader.ts +0 -423
  577. package/src/skills/remote.test.ts +0 -704
  578. package/src/skills/remote.ts +0 -604
  579. package/src/triggers/matcher.test.ts +0 -277
  580. package/src/triggers/matcher.ts +0 -152
  581. package/src/types/index.ts +0 -194
  582. package/src/utils/async.ts +0 -18
  583. package/src/utils/index.test.ts +0 -84
  584. package/src/utils/index.ts +0 -51
  585. package/src/utils/version.ts +0 -17
  586. package/tsconfig.json +0 -25
  587. package/vitest.config.ts +0 -8
  588. package/vitest.integration.config.ts +0 -11
  589. package/warden.toml +0 -19
@@ -1,604 +0,0 @@
1
- import { existsSync, mkdirSync, readFileSync, writeFileSync, rmSync, renameSync, readdirSync, statSync } from 'node:fs';
2
- import { homedir } from 'node:os';
3
- import { dirname, join } from 'node:path';
4
- import { execFileSync } from 'node:child_process';
5
- import { z } from 'zod';
6
- import { loadSkillFromMarkdown, SkillLoaderError } from './loader.js';
7
- import type { SkillDefinition } from '../config/schema.js';
8
-
9
- /** Default TTL for unpinned remote skills: 24 hours */
10
- const DEFAULT_TTL_SECONDS = 86400;
11
-
12
- /** Schema for a single remote entry in state.json */
13
- const RemoteEntrySchema = z.object({
14
- sha: z.string(),
15
- fetchedAt: z.string().datetime(),
16
- });
17
-
18
- /** Schema for the entire state.json file */
19
- const RemoteStateSchema = z.object({
20
- remotes: z.record(z.string(), RemoteEntrySchema),
21
- });
22
-
23
- export type RemoteEntry = z.infer<typeof RemoteEntrySchema>;
24
- export type RemoteState = z.infer<typeof RemoteStateSchema>;
25
-
26
- /** Schema for a plugin in marketplace.json */
27
- const MarketplacePluginSchema = z.object({
28
- name: z.string(),
29
- source: z.string(),
30
- description: z.string().optional(),
31
- category: z.string().optional(),
32
- });
33
-
34
- /** Schema for .claude-plugin/marketplace.json */
35
- const MarketplaceConfigSchema = z.object({
36
- $schema: z.string().optional(),
37
- name: z.string(),
38
- description: z.string().optional(),
39
- plugins: z.array(MarketplacePluginSchema),
40
- });
41
-
42
- type MarketplaceConfig = z.infer<typeof MarketplaceConfigSchema>;
43
-
44
- /** Parsed remote reference */
45
- export interface ParsedRemoteRef {
46
- owner: string;
47
- repo: string;
48
- sha?: string;
49
- }
50
-
51
- /**
52
- * Normalize a GitHub URL to owner/repo format.
53
- * Returns null if the input is not a recognized GitHub URL.
54
- *
55
- * Supports:
56
- * - https://github.com/owner/repo
57
- * - https://github.com/owner/repo.git
58
- * - git@github.com:owner/repo.git
59
- */
60
- function normalizeGitHubUrl(input: string): string | null {
61
- // HTTPS URL: https://github.com/owner/repo or https://github.com/owner/repo.git
62
- const httpsMatch = input.match(/^https?:\/\/github\.com\/([^/]+)\/([^/@]+?)(?:\.git)?$/);
63
- if (httpsMatch) {
64
- return `${httpsMatch[1]}/${httpsMatch[2]}`;
65
- }
66
-
67
- // SSH URL: git@github.com:owner/repo.git
68
- const sshMatch = input.match(/^git@github\.com:([^/]+)\/([^/@]+?)(?:\.git)?$/);
69
- if (sshMatch) {
70
- return `${sshMatch[1]}/${sshMatch[2]}`;
71
- }
72
-
73
- return null;
74
- }
75
-
76
- /**
77
- * Parse a remote reference string into its components.
78
- * Supports formats:
79
- * - "owner/repo" or "owner/repo@sha"
80
- * - "https://github.com/owner/repo" or "https://github.com/owner/repo@sha"
81
- * - "https://github.com/owner/repo.git" or "https://github.com/owner/repo.git@sha"
82
- * - "git@github.com:owner/repo.git" or "git@github.com:owner/repo.git@sha"
83
- */
84
- export function parseRemoteRef(ref: string): ParsedRemoteRef {
85
- let inputRef = ref;
86
- let sha: string | undefined;
87
-
88
- // Extract SHA suffix from the input before URL normalization.
89
- // The SHA is always at the end, after a @ that follows the repo name.
90
- // For git@github.com URLs, we need to find the @ after the colon.
91
- if (ref.startsWith('git@')) {
92
- const colonIndex = ref.indexOf(':');
93
- if (colonIndex !== -1) {
94
- const afterColon = ref.slice(colonIndex + 1);
95
- const shaAtIndex = afterColon.lastIndexOf('@');
96
- if (shaAtIndex !== -1) {
97
- sha = afterColon.slice(shaAtIndex + 1);
98
- inputRef = ref.slice(0, colonIndex + 1 + shaAtIndex);
99
- }
100
- }
101
- } else {
102
- const lastAtIndex = ref.lastIndexOf('@');
103
- if (lastAtIndex !== -1) {
104
- const potentialSha = ref.slice(lastAtIndex + 1);
105
- // SHA should not contain : or / (those would indicate URL structure)
106
- if (!potentialSha.includes(':') && !potentialSha.includes('/')) {
107
- if (!potentialSha) {
108
- throw new SkillLoaderError(`Invalid remote ref: ${ref} (empty SHA after @)`);
109
- }
110
- sha = potentialSha;
111
- inputRef = ref.slice(0, lastAtIndex);
112
- }
113
- }
114
- }
115
-
116
- // Normalize GitHub URLs to owner/repo format
117
- const repoPath = normalizeGitHubUrl(inputRef) ?? inputRef;
118
-
119
- const slashIndex = repoPath.indexOf('/');
120
- if (slashIndex === -1) {
121
- throw new SkillLoaderError(`Invalid remote ref: ${ref} (expected owner/repo format)`);
122
- }
123
-
124
- const owner = repoPath.slice(0, slashIndex);
125
- const repo = repoPath.slice(slashIndex + 1);
126
-
127
- if (!owner || !repo) {
128
- throw new SkillLoaderError(`Invalid remote ref: ${ref} (empty owner or repo)`);
129
- }
130
-
131
- if (repo.includes('/')) {
132
- throw new SkillLoaderError(`Invalid remote ref: ${ref} (repo name cannot contain /)`);
133
- }
134
-
135
- // Security: Prevent git flag injection by rejecting values starting with '-'
136
- if (owner.startsWith('-')) {
137
- throw new SkillLoaderError(`Invalid remote ref: ${ref} (owner cannot start with -)`);
138
- }
139
- if (repo.startsWith('-')) {
140
- throw new SkillLoaderError(`Invalid remote ref: ${ref} (repo cannot start with -)`);
141
- }
142
- if (sha?.startsWith('-')) {
143
- throw new SkillLoaderError(`Invalid remote ref: ${ref} (SHA cannot start with -)`);
144
- }
145
-
146
- return { owner, repo, sha };
147
- }
148
-
149
- /**
150
- * Format a parsed remote ref back to string format.
151
- */
152
- export function formatRemoteRef(parsed: ParsedRemoteRef): string {
153
- const base = `${parsed.owner}/${parsed.repo}`;
154
- return parsed.sha ? `${base}@${parsed.sha}` : base;
155
- }
156
-
157
- /**
158
- * Get the base directory for caching remote skills.
159
- * Respects WARDEN_STATE_DIR environment variable.
160
- * Default: ~/.local/warden/skills/
161
- */
162
- export function getSkillsCacheDir(): string {
163
- const stateDir = process.env['WARDEN_STATE_DIR'];
164
- if (stateDir) {
165
- return join(stateDir, 'skills');
166
- }
167
- return join(homedir(), '.local', 'warden', 'skills');
168
- }
169
-
170
- /**
171
- * Get the cache path for a specific remote ref.
172
- * - Unpinned: ~/.local/warden/skills/owner/repo/
173
- * - Pinned: ~/.local/warden/skills/owner/repo@sha/
174
- */
175
- export function getRemotePath(ref: string): string {
176
- const parsed = parseRemoteRef(ref);
177
- const cacheDir = getSkillsCacheDir();
178
-
179
- if (parsed.sha) {
180
- return join(cacheDir, parsed.owner, `${parsed.repo}@${parsed.sha}`);
181
- }
182
- return join(cacheDir, parsed.owner, parsed.repo);
183
- }
184
-
185
- /**
186
- * Get the path to the state.json file.
187
- */
188
- export function getStatePath(): string {
189
- return join(getSkillsCacheDir(), 'state.json');
190
- }
191
-
192
- /**
193
- * Load the remote state from state.json.
194
- * Returns an empty state if the file doesn't exist.
195
- */
196
- export function loadState(): RemoteState {
197
- const statePath = getStatePath();
198
-
199
- if (!existsSync(statePath)) {
200
- return { remotes: {} };
201
- }
202
-
203
- try {
204
- const content = readFileSync(statePath, 'utf-8');
205
- const data = JSON.parse(content);
206
- return RemoteStateSchema.parse(data);
207
- } catch (error) {
208
- // If state is corrupted, start fresh
209
- const message = error instanceof Error ? error.message : String(error);
210
- console.warn(`Warning: Failed to load state.json, starting fresh: ${message}`);
211
- return { remotes: {} };
212
- }
213
- }
214
-
215
- /**
216
- * Save the remote state to state.json.
217
- * Uses atomic write (write to temp, then rename).
218
- */
219
- export function saveState(state: RemoteState): void {
220
- const statePath = getStatePath();
221
- const stateDir = dirname(statePath);
222
-
223
- // Ensure directory exists
224
- if (!existsSync(stateDir)) {
225
- mkdirSync(stateDir, { recursive: true });
226
- }
227
-
228
- // Write atomically
229
- const tempPath = `${statePath}.tmp`;
230
- writeFileSync(tempPath, JSON.stringify(state, null, 2), 'utf-8');
231
-
232
- // Rename is atomic on most filesystems
233
- renameSync(tempPath, statePath);
234
- }
235
-
236
- /**
237
- * Get the TTL for remote skill cache in seconds.
238
- * Respects WARDEN_SKILL_CACHE_TTL environment variable.
239
- */
240
- export function getCacheTtlSeconds(): number {
241
- const envTtl = process.env['WARDEN_SKILL_CACHE_TTL'];
242
- if (envTtl) {
243
- const parsed = parseInt(envTtl, 10);
244
- if (!isNaN(parsed) && parsed > 0) {
245
- return parsed;
246
- }
247
- }
248
- return DEFAULT_TTL_SECONDS;
249
- }
250
-
251
- /**
252
- * Check if an unpinned remote ref needs to be refreshed.
253
- * Pinned refs (with @sha) never need refresh.
254
- */
255
- export function shouldRefresh(ref: string, state: RemoteState): boolean {
256
- const parsed = parseRemoteRef(ref);
257
-
258
- // Pinned refs are immutable - never refresh
259
- if (parsed.sha) {
260
- return false;
261
- }
262
-
263
- const entry = state.remotes[ref];
264
- if (!entry) {
265
- return true; // Not cached, needs fetch
266
- }
267
-
268
- const fetchedAt = new Date(entry.fetchedAt).getTime();
269
- const now = Date.now();
270
- const ttl = getCacheTtlSeconds() * 1000;
271
-
272
- return now - fetchedAt > ttl;
273
- }
274
-
275
- export interface FetchRemoteOptions {
276
- /** Force refresh even if cache is valid */
277
- force?: boolean;
278
- /** Skip network operations - only use cache */
279
- offline?: boolean;
280
- /** Callback for progress messages */
281
- onProgress?: (message: string) => void;
282
- }
283
-
284
- /**
285
- * Execute a git command and return stdout.
286
- * Uses execFileSync to avoid shell injection vulnerabilities.
287
- * Throws SkillLoaderError on failure.
288
- */
289
- function execGit(args: string[], options?: { cwd?: string }): string {
290
- try {
291
- return execFileSync('git', args, {
292
- encoding: 'utf-8',
293
- cwd: options?.cwd,
294
- stdio: ['pipe', 'pipe', 'pipe'],
295
- }).trim();
296
- } catch (error) {
297
- const message = error instanceof Error ? error.message : String(error);
298
- throw new SkillLoaderError(`Git command failed: git ${args.join(' ')}: ${message}`);
299
- }
300
- }
301
-
302
- /**
303
- * Clone or update a remote repository to the cache.
304
- * Returns the SHA of the fetched commit.
305
- */
306
- export async function fetchRemote(ref: string, options: FetchRemoteOptions = {}): Promise<string> {
307
- const { force = false, offline = false, onProgress } = options;
308
- const parsed = parseRemoteRef(ref);
309
- const remotePath = getRemotePath(ref);
310
- const state = loadState();
311
-
312
- const isPinned = !!parsed.sha;
313
- const isCached = existsSync(remotePath);
314
- const needsRefresh = shouldRefresh(ref, state);
315
-
316
- // Check if we have a valid cache (directory exists AND state entry exists)
317
- const stateEntry = state.remotes[ref];
318
- const hasValidCache = isCached && !!stateEntry;
319
-
320
- // Handle offline mode
321
- if (offline) {
322
- if (hasValidCache) {
323
- return stateEntry.sha;
324
- }
325
- throw new SkillLoaderError(`Remote skill not cached and offline mode enabled: ${ref}`);
326
- }
327
-
328
- // Pinned + valid cache = use cache (SHA is immutable)
329
- if (isPinned && hasValidCache && !force && parsed.sha) {
330
- return parsed.sha;
331
- }
332
-
333
- // Unpinned + valid cache + fresh = use cache
334
- if (!isPinned && hasValidCache && !needsRefresh && !force) {
335
- return stateEntry.sha;
336
- }
337
-
338
- const repoUrl = `https://github.com/${parsed.owner}/${parsed.repo}.git`;
339
-
340
- // Clone or update
341
- if (!isCached) {
342
- onProgress?.(`Cloning ${ref}...`);
343
-
344
- // Ensure parent directory exists
345
- const parentDir = dirname(remotePath);
346
- if (!existsSync(parentDir)) {
347
- mkdirSync(parentDir, { recursive: true });
348
- }
349
-
350
- // Clone with minimal depth for unpinned refs
351
- // Note: '--' separates flags from positional args to prevent flag injection
352
- if (isPinned && parsed.sha) {
353
- // For pinned refs, we need full history to checkout the specific SHA
354
- // Use a shallow clone then deepen if needed
355
- execGit(['clone', '--depth=1', '--', repoUrl, remotePath]);
356
-
357
- try {
358
- // Try to checkout the pinned SHA
359
- // Note: 'checkout' without '--' treats arg as ref; with '--' it's a file path
360
- execGit(['fetch', '--depth=1', 'origin', '--', parsed.sha], { cwd: remotePath });
361
- execGit(['checkout', parsed.sha], { cwd: remotePath });
362
- } catch {
363
- // If SHA not found, do a full fetch and retry
364
- execGit(['fetch', '--unshallow'], { cwd: remotePath });
365
- execGit(['checkout', parsed.sha], { cwd: remotePath });
366
- }
367
- } else if (!isPinned) {
368
- // For unpinned refs, shallow clone of default branch
369
- execGit(['clone', '--depth=1', '--', repoUrl, remotePath]);
370
- }
371
- } else {
372
- // Update existing cache
373
- onProgress?.(`Updating ${ref}...`);
374
-
375
- if (!isPinned) {
376
- // For unpinned refs, pull latest
377
- execGit(['fetch', '--depth=1', 'origin'], { cwd: remotePath });
378
- execGit(['reset', '--hard', 'origin/HEAD'], { cwd: remotePath });
379
- }
380
- // Pinned refs don't need updates - SHA is immutable
381
- }
382
-
383
- // Get the current HEAD SHA
384
- const sha = execGit(['rev-parse', 'HEAD'], { cwd: remotePath });
385
-
386
- // Update state
387
- state.remotes[ref] = {
388
- sha,
389
- fetchedAt: new Date().toISOString(),
390
- };
391
- saveState(state);
392
-
393
- return sha;
394
- }
395
-
396
- export interface DiscoveredRemoteSkill {
397
- name: string;
398
- description: string;
399
- path: string;
400
- /** Plugin name for marketplace format skills */
401
- pluginName?: string;
402
- }
403
-
404
- /**
405
- * Parse marketplace.json from a remote repository if it exists.
406
- * Returns null if the file doesn't exist or is invalid.
407
- */
408
- function parseMarketplaceConfig(remotePath: string): MarketplaceConfig | null {
409
- const marketplacePath = join(remotePath, '.claude-plugin', 'marketplace.json');
410
-
411
- if (!existsSync(marketplacePath)) {
412
- return null;
413
- }
414
-
415
- try {
416
- const content = readFileSync(marketplacePath, 'utf-8');
417
- const data = JSON.parse(content);
418
- return MarketplaceConfigSchema.parse(data);
419
- } catch {
420
- // Invalid or malformed marketplace.json - fall back to traditional discovery
421
- return null;
422
- }
423
- }
424
-
425
- /** Directories to search for skills in remote repositories */
426
- const REMOTE_SKILL_DIRECTORIES = [
427
- '', // root level
428
- 'skills', // skills/ subdirectory
429
- '.warden/skills', // Warden-specific
430
- '.agents/skills', // General agent skills
431
- '.claude/skills', // Claude Code skills
432
- ];
433
-
434
- /**
435
- * Discover skills using traditional directory layout.
436
- * Searches root level, skills/, and conventional skill directories.
437
- */
438
- async function discoverTraditionalSkills(remotePath: string): Promise<DiscoveredRemoteSkill[]> {
439
- const skills: DiscoveredRemoteSkill[] = [];
440
- const seenNames = new Set<string>();
441
-
442
- for (const subdir of REMOTE_SKILL_DIRECTORIES) {
443
- const searchPath = subdir ? join(remotePath, subdir) : remotePath;
444
- if (!existsSync(searchPath)) continue;
445
-
446
- const entries = readdirSync(searchPath);
447
-
448
- for (const entry of entries) {
449
- if (entry.startsWith('.')) continue;
450
-
451
- const entryPath = join(searchPath, entry);
452
- const stat = statSync(entryPath);
453
-
454
- if (stat.isDirectory()) {
455
- const skillMdPath = join(entryPath, 'SKILL.md');
456
- if (existsSync(skillMdPath)) {
457
- try {
458
- const skill = await loadSkillFromMarkdown(skillMdPath);
459
- // First occurrence wins (root takes precedence over skills/)
460
- if (!seenNames.has(skill.name)) {
461
- seenNames.add(skill.name);
462
- skills.push({
463
- name: skill.name,
464
- description: skill.description,
465
- path: entryPath,
466
- });
467
- }
468
- } catch {
469
- // Skip invalid skill directories
470
- }
471
- }
472
- }
473
- }
474
- }
475
-
476
- return skills;
477
- }
478
-
479
- /**
480
- * Discover skills using marketplace format.
481
- * Searches plugins/{plugin}/skills/ for each plugin defined in marketplace.json.
482
- */
483
- async function discoverMarketplaceSkills(
484
- remotePath: string,
485
- config: MarketplaceConfig
486
- ): Promise<DiscoveredRemoteSkill[]> {
487
- const skills: DiscoveredRemoteSkill[] = [];
488
- const seenNames = new Set<string>();
489
-
490
- for (const plugin of config.plugins) {
491
- // Resolve plugin source path (e.g., "./plugins/sentry-skills" -> "plugins/sentry-skills")
492
- const pluginSource = plugin.source.replace(/^\.\//, '');
493
- const skillsPath = join(remotePath, pluginSource, 'skills');
494
-
495
- if (!existsSync(skillsPath)) continue;
496
-
497
- const entries = readdirSync(skillsPath);
498
-
499
- for (const entry of entries) {
500
- if (entry.startsWith('.')) continue;
501
-
502
- const entryPath = join(skillsPath, entry);
503
- const stat = statSync(entryPath);
504
-
505
- if (stat.isDirectory()) {
506
- const skillMdPath = join(entryPath, 'SKILL.md');
507
- if (existsSync(skillMdPath)) {
508
- try {
509
- const skill = await loadSkillFromMarkdown(skillMdPath);
510
- // First plugin wins for duplicate skill names
511
- if (!seenNames.has(skill.name)) {
512
- seenNames.add(skill.name);
513
- skills.push({
514
- name: skill.name,
515
- description: skill.description,
516
- path: entryPath,
517
- pluginName: plugin.name,
518
- });
519
- }
520
- } catch {
521
- // Skip invalid skill directories
522
- }
523
- }
524
- }
525
- }
526
- }
527
-
528
- return skills;
529
- }
530
-
531
- /**
532
- * Discover all skills in a cached remote repository.
533
- * Detects format and delegates to appropriate discovery function:
534
- * - If .claude-plugin/marketplace.json exists, uses marketplace discovery
535
- * - Otherwise, uses traditional discovery (root, skills/, .warden/skills, etc.)
536
- */
537
- export async function discoverRemoteSkills(ref: string): Promise<DiscoveredRemoteSkill[]> {
538
- const remotePath = getRemotePath(ref);
539
-
540
- if (!existsSync(remotePath)) {
541
- throw new SkillLoaderError(`Remote not cached: ${ref}. Run fetch first.`);
542
- }
543
-
544
- // Check for marketplace format
545
- const marketplaceConfig = parseMarketplaceConfig(remotePath);
546
- if (marketplaceConfig) {
547
- return discoverMarketplaceSkills(remotePath, marketplaceConfig);
548
- }
549
-
550
- // Fall back to traditional discovery
551
- return discoverTraditionalSkills(remotePath);
552
- }
553
-
554
- /**
555
- * Resolve a skill from a remote repository.
556
- * Ensures the remote is fetched/cached, then loads the skill.
557
- * Matches by skill name (from SKILL.md), not directory name.
558
- */
559
- export async function resolveRemoteSkill(
560
- ref: string,
561
- skillName: string,
562
- options: FetchRemoteOptions = {}
563
- ): Promise<SkillDefinition> {
564
- await fetchRemote(ref, options);
565
-
566
- const availableSkills = await discoverRemoteSkills(ref);
567
- const match = availableSkills.find((s) => s.name === skillName);
568
-
569
- if (match) {
570
- return loadSkillFromMarkdown(join(match.path, 'SKILL.md'));
571
- }
572
-
573
- if (availableSkills.length === 0) {
574
- throw new SkillLoaderError(`No skills found in remote: ${ref}`);
575
- }
576
-
577
- throw new SkillLoaderError(
578
- `Skill '${skillName}' not found in remote: ${ref}. Available skills: ${availableSkills.map((s) => s.name).join(', ')}`
579
- );
580
- }
581
-
582
- /**
583
- * Remove a remote from the cache.
584
- */
585
- export function removeRemote(ref: string): void {
586
- const remotePath = getRemotePath(ref);
587
-
588
- if (existsSync(remotePath)) {
589
- rmSync(remotePath, { recursive: true, force: true });
590
- }
591
-
592
- const state = loadState();
593
- const { [ref]: _removed, ...remainingRemotes } = state.remotes;
594
- state.remotes = remainingRemotes;
595
- saveState(state);
596
- }
597
-
598
- /**
599
- * List all cached remotes with their metadata.
600
- */
601
- export function listCachedRemotes(): { ref: string; entry: RemoteEntry }[] {
602
- const state = loadState();
603
- return Object.entries(state.remotes).map(([ref, entry]) => ({ ref, entry }));
604
- }