@sentry/warden 0.22.0 → 0.24.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 (310) hide show
  1. package/.oxlintrc.json +169 -0
  2. package/CHANGELOG.md +427 -0
  3. package/README.md +4 -1
  4. package/dist/cli/args.d.ts +6 -2
  5. package/dist/cli/args.d.ts.map +1 -1
  6. package/dist/cli/args.js +175 -207
  7. package/dist/cli/args.js.map +1 -1
  8. package/dist/cli/commands/add.d.ts.map +1 -1
  9. package/dist/cli/commands/add.js +16 -5
  10. package/dist/cli/commands/add.js.map +1 -1
  11. package/dist/cli/commands/build.d.ts +13 -0
  12. package/dist/cli/commands/build.d.ts.map +1 -0
  13. package/dist/cli/commands/build.js +384 -0
  14. package/dist/cli/commands/build.js.map +1 -0
  15. package/dist/cli/commands/init.d.ts.map +1 -1
  16. package/dist/cli/commands/init.js +13 -5
  17. package/dist/cli/commands/init.js.map +1 -1
  18. package/dist/cli/commands/runs.d.ts.map +1 -1
  19. package/dist/cli/commands/runs.js +12 -6
  20. package/dist/cli/commands/runs.js.map +1 -1
  21. package/dist/cli/commands/sync.d.ts.map +1 -1
  22. package/dist/cli/commands/sync.js +4 -1
  23. package/dist/cli/commands/sync.js.map +1 -1
  24. package/dist/cli/context.d.ts.map +1 -1
  25. package/dist/cli/context.js +8 -1
  26. package/dist/cli/context.js.map +1 -1
  27. package/dist/cli/files.d.ts.map +1 -1
  28. package/dist/cli/files.js +27 -9
  29. package/dist/cli/files.js.map +1 -1
  30. package/dist/cli/help.d.ts +4 -0
  31. package/dist/cli/help.d.ts.map +1 -0
  32. package/dist/cli/help.js +448 -0
  33. package/dist/cli/help.js.map +1 -0
  34. package/dist/cli/index.js +2 -13
  35. package/dist/cli/index.js.map +1 -1
  36. package/dist/cli/input.d.ts +12 -0
  37. package/dist/cli/input.d.ts.map +1 -1
  38. package/dist/cli/input.js +60 -0
  39. package/dist/cli/input.js.map +1 -1
  40. package/dist/cli/main.d.ts +41 -2
  41. package/dist/cli/main.d.ts.map +1 -1
  42. package/dist/cli/main.js +294 -75
  43. package/dist/cli/main.js.map +1 -1
  44. package/dist/cli/output/box.js +1 -1
  45. package/dist/cli/output/formatters.d.ts +10 -2
  46. package/dist/cli/output/formatters.d.ts.map +1 -1
  47. package/dist/cli/output/formatters.js +32 -9
  48. package/dist/cli/output/formatters.js.map +1 -1
  49. package/dist/cli/output/index.d.ts +1 -1
  50. package/dist/cli/output/index.d.ts.map +1 -1
  51. package/dist/cli/output/index.js +1 -1
  52. package/dist/cli/output/index.js.map +1 -1
  53. package/dist/cli/output/ink-runner.d.ts +3 -1
  54. package/dist/cli/output/ink-runner.d.ts.map +1 -1
  55. package/dist/cli/output/ink-runner.js +64 -28
  56. package/dist/cli/output/ink-runner.js.map +1 -1
  57. package/dist/cli/output/jsonl.d.ts +37 -0
  58. package/dist/cli/output/jsonl.d.ts.map +1 -1
  59. package/dist/cli/output/jsonl.js +6 -0
  60. package/dist/cli/output/jsonl.js.map +1 -1
  61. package/dist/cli/output/live-status.d.ts +48 -0
  62. package/dist/cli/output/live-status.d.ts.map +1 -0
  63. package/dist/cli/output/live-status.js +173 -0
  64. package/dist/cli/output/live-status.js.map +1 -0
  65. package/dist/cli/output/reporter.d.ts +4 -0
  66. package/dist/cli/output/reporter.d.ts.map +1 -1
  67. package/dist/cli/output/reporter.js +20 -3
  68. package/dist/cli/output/reporter.js.map +1 -1
  69. package/dist/cli/output/tasks.d.ts +8 -5
  70. package/dist/cli/output/tasks.d.ts.map +1 -1
  71. package/dist/cli/output/tasks.js +113 -71
  72. package/dist/cli/output/tasks.js.map +1 -1
  73. package/dist/cli/signals.d.ts +15 -0
  74. package/dist/cli/signals.d.ts.map +1 -0
  75. package/dist/cli/signals.js +26 -0
  76. package/dist/cli/signals.js.map +1 -0
  77. package/dist/config/loader.d.ts +48 -7
  78. package/dist/config/loader.d.ts.map +1 -1
  79. package/dist/config/loader.js +228 -32
  80. package/dist/config/loader.js.map +1 -1
  81. package/dist/config/schema.d.ts +55 -0
  82. package/dist/config/schema.d.ts.map +1 -1
  83. package/dist/config/schema.js +34 -2
  84. package/dist/config/schema.js.map +1 -1
  85. package/dist/diff/context.d.ts +9 -2
  86. package/dist/diff/context.d.ts.map +1 -1
  87. package/dist/diff/context.js +65 -17
  88. package/dist/diff/context.js.map +1 -1
  89. package/dist/evals/runner.d.ts.map +1 -1
  90. package/dist/evals/runner.js +16 -0
  91. package/dist/evals/runner.js.map +1 -1
  92. package/dist/event/context.d.ts.map +1 -1
  93. package/dist/event/context.js +1 -0
  94. package/dist/event/context.js.map +1 -1
  95. package/dist/event/schedule-context.d.ts.map +1 -1
  96. package/dist/event/schedule-context.js +1 -0
  97. package/dist/event/schedule-context.js.map +1 -1
  98. package/dist/index.d.ts +6 -6
  99. package/dist/index.d.ts.map +1 -1
  100. package/dist/index.js +3 -3
  101. package/dist/index.js.map +1 -1
  102. package/dist/output/dedup.d.ts +8 -11
  103. package/dist/output/dedup.d.ts.map +1 -1
  104. package/dist/output/dedup.js +39 -37
  105. package/dist/output/dedup.js.map +1 -1
  106. package/dist/output/github-checks.d.ts +1 -0
  107. package/dist/output/github-checks.d.ts.map +1 -1
  108. package/dist/output/github-checks.js +9 -7
  109. package/dist/output/github-checks.js.map +1 -1
  110. package/dist/sdk/analyze.d.ts.map +1 -1
  111. package/dist/sdk/analyze.js +147 -277
  112. package/dist/sdk/analyze.js.map +1 -1
  113. package/dist/sdk/circuit-breaker.d.ts +26 -0
  114. package/dist/sdk/circuit-breaker.d.ts.map +1 -0
  115. package/dist/sdk/circuit-breaker.js +53 -0
  116. package/dist/sdk/circuit-breaker.js.map +1 -0
  117. package/dist/sdk/errors.d.ts +5 -0
  118. package/dist/sdk/errors.d.ts.map +1 -1
  119. package/dist/sdk/errors.js +27 -0
  120. package/dist/sdk/errors.js.map +1 -1
  121. package/dist/sdk/extract.d.ts +18 -9
  122. package/dist/sdk/extract.d.ts.map +1 -1
  123. package/dist/sdk/extract.js +95 -87
  124. package/dist/sdk/extract.js.map +1 -1
  125. package/dist/sdk/fix-quality.d.ts +5 -0
  126. package/dist/sdk/fix-quality.d.ts.map +1 -1
  127. package/dist/sdk/fix-quality.js +42 -23
  128. package/dist/sdk/fix-quality.js.map +1 -1
  129. package/dist/sdk/haiku.d.ts +6 -0
  130. package/dist/sdk/haiku.d.ts.map +1 -1
  131. package/dist/sdk/haiku.js +75 -49
  132. package/dist/sdk/haiku.js.map +1 -1
  133. package/dist/sdk/json-output.d.ts +31 -0
  134. package/dist/sdk/json-output.d.ts.map +1 -0
  135. package/dist/sdk/json-output.js +98 -0
  136. package/dist/sdk/json-output.js.map +1 -0
  137. package/dist/sdk/model-pricing.json +56 -16
  138. package/dist/sdk/post-process.d.ts +29 -0
  139. package/dist/sdk/post-process.d.ts.map +1 -0
  140. package/dist/sdk/post-process.js +65 -0
  141. package/dist/sdk/post-process.js.map +1 -0
  142. package/dist/sdk/prepare.d.ts.map +1 -1
  143. package/dist/sdk/prepare.js +4 -1
  144. package/dist/sdk/prepare.js.map +1 -1
  145. package/dist/sdk/pricing.d.ts +18 -0
  146. package/dist/sdk/pricing.d.ts.map +1 -1
  147. package/dist/sdk/pricing.js +108 -3
  148. package/dist/sdk/pricing.js.map +1 -1
  149. package/dist/sdk/prompt-sections.d.ts +56 -0
  150. package/dist/sdk/prompt-sections.d.ts.map +1 -0
  151. package/dist/sdk/prompt-sections.js +118 -0
  152. package/dist/sdk/prompt-sections.js.map +1 -0
  153. package/dist/sdk/prompt.d.ts +2 -17
  154. package/dist/sdk/prompt.d.ts.map +1 -1
  155. package/dist/sdk/prompt.js +15 -37
  156. package/dist/sdk/prompt.js.map +1 -1
  157. package/dist/sdk/report-files.d.ts +15 -0
  158. package/dist/sdk/report-files.d.ts.map +1 -0
  159. package/dist/sdk/report-files.js +20 -0
  160. package/dist/sdk/report-files.js.map +1 -0
  161. package/dist/sdk/runner.d.ts +9 -1
  162. package/dist/sdk/runner.d.ts.map +1 -1
  163. package/dist/sdk/runner.js +6 -0
  164. package/dist/sdk/runner.js.map +1 -1
  165. package/dist/sdk/runtimes/claude.d.ts +3 -0
  166. package/dist/sdk/runtimes/claude.d.ts.map +1 -0
  167. package/dist/sdk/runtimes/claude.js +376 -0
  168. package/dist/sdk/runtimes/claude.js.map +1 -0
  169. package/dist/sdk/runtimes/index.d.ts +12 -0
  170. package/dist/sdk/runtimes/index.d.ts.map +1 -0
  171. package/dist/sdk/runtimes/index.js +22 -0
  172. package/dist/sdk/runtimes/index.js.map +1 -0
  173. package/dist/sdk/runtimes/types.d.ts +116 -0
  174. package/dist/sdk/runtimes/types.d.ts.map +1 -0
  175. package/dist/sdk/runtimes/types.js +17 -0
  176. package/dist/sdk/runtimes/types.js.map +1 -0
  177. package/dist/sdk/types.d.ts +23 -2
  178. package/dist/sdk/types.d.ts.map +1 -1
  179. package/dist/sdk/types.js.map +1 -1
  180. package/dist/sdk/usage.d.ts +21 -6
  181. package/dist/sdk/usage.d.ts.map +1 -1
  182. package/dist/sdk/usage.js +36 -23
  183. package/dist/sdk/usage.js.map +1 -1
  184. package/dist/sdk/verify.d.ts +25 -0
  185. package/dist/sdk/verify.d.ts.map +1 -0
  186. package/dist/sdk/verify.js +226 -0
  187. package/dist/sdk/verify.js.map +1 -0
  188. package/dist/skill-builder/agentic.d.ts +33 -0
  189. package/dist/skill-builder/agentic.d.ts.map +1 -0
  190. package/dist/skill-builder/agentic.js +240 -0
  191. package/dist/skill-builder/agentic.js.map +1 -0
  192. package/dist/skill-builder/authoring-provider.d.ts +5 -0
  193. package/dist/skill-builder/authoring-provider.d.ts.map +1 -0
  194. package/dist/skill-builder/authoring-provider.js +70 -0
  195. package/dist/skill-builder/authoring-provider.js.map +1 -0
  196. package/dist/skill-builder/definition.d.ts +46 -0
  197. package/dist/skill-builder/definition.d.ts.map +1 -0
  198. package/dist/skill-builder/definition.js +171 -0
  199. package/dist/skill-builder/definition.js.map +1 -0
  200. package/dist/skill-builder/outline-contract.d.ts +113 -0
  201. package/dist/skill-builder/outline-contract.d.ts.map +1 -0
  202. package/dist/skill-builder/outline-contract.js +73 -0
  203. package/dist/skill-builder/outline-contract.js.map +1 -0
  204. package/dist/skill-builder/outline-state.d.ts +158 -0
  205. package/dist/skill-builder/outline-state.d.ts.map +1 -0
  206. package/dist/skill-builder/outline-state.js +87 -0
  207. package/dist/skill-builder/outline-state.js.map +1 -0
  208. package/dist/skill-builder/outline.d.ts +36 -0
  209. package/dist/skill-builder/outline.d.ts.map +1 -0
  210. package/dist/skill-builder/outline.js +345 -0
  211. package/dist/skill-builder/outline.js.map +1 -0
  212. package/dist/skill-builder/skill-contract.d.ts +97 -0
  213. package/dist/skill-builder/skill-contract.d.ts.map +1 -0
  214. package/dist/skill-builder/skill-contract.js +58 -0
  215. package/dist/skill-builder/skill-contract.js.map +1 -0
  216. package/dist/skill-builder/skill-prompts.d.ts +61 -0
  217. package/dist/skill-builder/skill-prompts.d.ts.map +1 -0
  218. package/dist/skill-builder/skill-prompts.js +285 -0
  219. package/dist/skill-builder/skill-prompts.js.map +1 -0
  220. package/dist/skill-builder/skill.d.ts +23 -0
  221. package/dist/skill-builder/skill.d.ts.map +1 -0
  222. package/dist/skill-builder/skill.js +563 -0
  223. package/dist/skill-builder/skill.js.map +1 -0
  224. package/dist/skills/index.d.ts +2 -2
  225. package/dist/skills/index.d.ts.map +1 -1
  226. package/dist/skills/index.js +1 -1
  227. package/dist/skills/index.js.map +1 -1
  228. package/dist/skills/loader.d.ts +20 -6
  229. package/dist/skills/loader.d.ts.map +1 -1
  230. package/dist/skills/loader.js +88 -141
  231. package/dist/skills/loader.js.map +1 -1
  232. package/dist/skills/remote.d.ts +11 -7
  233. package/dist/skills/remote.d.ts.map +1 -1
  234. package/dist/skills/remote.js +62 -162
  235. package/dist/skills/remote.js.map +1 -1
  236. package/dist/triggers/matcher.d.ts.map +1 -1
  237. package/dist/triggers/matcher.js +28 -15
  238. package/dist/triggers/matcher.js.map +1 -1
  239. package/dist/types/index.d.ts +40 -0
  240. package/dist/types/index.d.ts.map +1 -1
  241. package/dist/types/index.js +11 -0
  242. package/dist/types/index.js.map +1 -1
  243. package/dist/utils/index.d.ts +1 -0
  244. package/dist/utils/index.d.ts.map +1 -1
  245. package/dist/utils/index.js +1 -0
  246. package/dist/utils/index.js.map +1 -1
  247. package/dist/utils/path.d.ts +17 -0
  248. package/dist/utils/path.d.ts.map +1 -0
  249. package/dist/utils/path.js +36 -0
  250. package/dist/utils/path.js.map +1 -0
  251. package/package.json +8 -8
  252. package/policies/README.md +22 -0
  253. package/policies/code-comments.md +20 -0
  254. package/policies/policy-template.md +14 -0
  255. package/skills/warden/SPEC.md +112 -0
  256. package/skills/warden/references/cli-reference.md +2 -2
  257. package/skills/warden/references/config-schema.md +29 -13
  258. package/skills/warden/references/configuration.md +20 -8
  259. package/skills/warden/references/creating-skills.md +3 -0
  260. package/skills/warden-sweep/SPEC.md +126 -0
  261. package/src/builtin-skills/security-review/SKILL.md +81 -0
  262. package/src/builtin-skills/security-review/SPEC.md +77 -0
  263. package/src/builtin-skills/security-review/references/github-workflows.md +186 -0
  264. package/src/builtin-skills/security-review/references/javascript-typescript.md +69 -0
  265. package/src/builtin-skills/security-review/references/python.md +70 -0
  266. package/src/internal-skills/skill-writer/EVAL.md +124 -0
  267. package/src/internal-skills/skill-writer/SKILL.md +159 -0
  268. package/src/internal-skills/skill-writer/SOURCES.md +94 -0
  269. package/src/internal-skills/skill-writer/SPEC.md +153 -0
  270. package/src/internal-skills/skill-writer/references/artifact-layouts/argument-driven-skill-layout.md +32 -0
  271. package/src/internal-skills/skill-writer/references/artifact-layouts/asset-template-skill-layout.md +30 -0
  272. package/src/internal-skills/skill-writer/references/artifact-layouts/inline-skill-layout.md +28 -0
  273. package/src/internal-skills/skill-writer/references/artifact-layouts/reference-backed-skill-layout.md +35 -0
  274. package/src/internal-skills/skill-writer/references/artifact-layouts/script-backed-skill-layout.md +31 -0
  275. package/src/internal-skills/skill-writer/references/authoring-path.md +91 -0
  276. package/src/internal-skills/skill-writer/references/claude-code/argument-substitutions.md +20 -0
  277. package/src/internal-skills/skill-writer/references/claude-code/dynamic-context.md +16 -0
  278. package/src/internal-skills/skill-writer/references/claude-code/frontmatter-and-invocation.md +33 -0
  279. package/src/internal-skills/skill-writer/references/claude-code/hook-backed-skills.md +28 -0
  280. package/src/internal-skills/skill-writer/references/claude-code/subagent-fork-skills.md +22 -0
  281. package/src/internal-skills/skill-writer/references/description-optimization.md +28 -0
  282. package/src/internal-skills/skill-writer/references/design-principles.md +74 -0
  283. package/src/internal-skills/skill-writer/references/evaluation-path.md +73 -0
  284. package/src/internal-skills/skill-writer/references/examples/documentation-skill.md +70 -0
  285. package/src/internal-skills/skill-writer/references/examples/evaluator-loop-skill.md +38 -0
  286. package/src/internal-skills/skill-writer/references/examples/hook-backed-skill.md +39 -0
  287. package/src/internal-skills/skill-writer/references/examples/router-skill.md +41 -0
  288. package/src/internal-skills/skill-writer/references/examples/security-review-skill.md +69 -0
  289. package/src/internal-skills/skill-writer/references/examples/subagent-fork-skill.md +39 -0
  290. package/src/internal-skills/skill-writer/references/examples/workflow-process-skill.md +65 -0
  291. package/src/internal-skills/skill-writer/references/execution-shapes.md +68 -0
  292. package/src/internal-skills/skill-writer/references/iteration-evidence.md +82 -0
  293. package/src/internal-skills/skill-writer/references/iteration-path.md +40 -0
  294. package/src/internal-skills/skill-writer/references/mode-selection.md +67 -0
  295. package/src/internal-skills/skill-writer/references/output-contracts.md +68 -0
  296. package/src/internal-skills/skill-writer/references/reference-architecture.md +71 -0
  297. package/src/internal-skills/skill-writer/references/registration-validation.md +67 -0
  298. package/src/internal-skills/skill-writer/references/source-discovery.md +60 -0
  299. package/src/internal-skills/skill-writer/references/spec-template.md +118 -0
  300. package/src/internal-skills/skill-writer/references/structure-troubleshooting.md +111 -0
  301. package/src/internal-skills/skill-writer/references/synthesis-path.md +119 -0
  302. package/src/internal-skills/skill-writer/references/workflow-mechanics/evaluator-loops.md +25 -0
  303. package/src/internal-skills/skill-writer/references/workflow-mechanics/orchestrator-workers.md +25 -0
  304. package/src/internal-skills/skill-writer/references/workflow-mechanics/parallel-workflows.md +21 -0
  305. package/src/internal-skills/skill-writer/references/workflow-mechanics/plan-validate-execute.md +26 -0
  306. package/src/internal-skills/skill-writer/references/workflow-mechanics/prompt-chaining.md +24 -0
  307. package/src/internal-skills/skill-writer/references/workflow-mechanics/routing-workflows.md +28 -0
  308. package/src/internal-skills/skill-writer/references/workflow-mechanics/validation-loops.md +26 -0
  309. package/src/internal-skills/skill-writer/scripts/quick_validate.py +158 -0
  310. package/src/internal-skills/skill-writer/scripts/quick_validate_test.py +79 -0
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAE,mBAAmB,EAAuB,MAAM,mBAAmB,CAAC;AAG/F,OAAO,EAAwD,KAAK,UAAU,EAAE,MAAM,WAAW,CAAC;AAIlG,OAAO,EAKL,aAAa,EAed,MAAM,mBAAmB,CAAC;AAe3B;;;GAGG;AACH,eAAO,MAAM,eAAe,iBAAwB,CAAC;AAErD;;;GAGG;AACH,eAAO,MAAM,WAAW;;CAAmB,CAAC;AAkZ5C,UAAU,gBAAgB;IACxB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC,EAClD,QAAQ,EAAE,UAAU,CAAC,UAAU,CAAC,EAChC,aAAa,CAAC,EAAE,mBAAmB,GAClC,gBAAgB,CA8BlB;AA4qBD,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CA4F1C"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"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"}
package/dist/cli/main.js CHANGED
@@ -1,18 +1,20 @@
1
1
  import { existsSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
2
- import { dirname, join, resolve } from 'node:path';
2
+ import { dirname, join, relative, resolve } from 'node:path';
3
3
  import { config as dotenvConfig } from 'dotenv';
4
4
  import { Sentry, flushSentry, setGlobalAttributes, emitRunMetric, getTraceId } from '../sentry.js';
5
- import { loadWardenConfig, resolveSkillConfigs } from '../config/loader.js';
5
+ import { emptyToUndefined, loadWardenConfig, resolveSkillConfigs } from '../config/loader.js';
6
6
  import { verifyAuth } from '../sdk/runner.js';
7
7
  import { mapExtractionErrorCode } from '../sdk/errors.js';
8
8
  import { mergeAuxiliaryUsage } from '../sdk/usage.js';
9
- import { resolveSkillAsync } from '../skills/loader.js';
9
+ import { resolveSkillAsync, SkillLoaderError } from '../skills/loader.js';
10
10
  import { matchTrigger, filterContextByPaths, shouldFail, countFindingsAtOrAbove } from '../triggers/matcher.js';
11
11
  import { filterFindings } from '../types/index.js';
12
12
  import { DEFAULT_CONCURRENCY, getAnthropicApiKey } from '../utils/index.js';
13
- import { parseCliArgs, showHelp, showVersion, classifyTargets } from './args.js';
13
+ import { isRepoRelativePath, normalizePath } from '../utils/path.js';
14
+ import { parseCliArgs, showVersion, classifyTargets } from './args.js';
15
+ import { showHelp } from './help.js';
14
16
  import { buildLocalEventContext, buildFileEventContext } from './context.js';
15
- import { getRepoRoot, getHeadSha, refExists, hasUncommittedChanges } from './git.js';
17
+ import { getRepoRoot, getHeadSha, refExists, getDefaultBranch } from './git.js';
16
18
  import { renderTerminalReport, filterReports } from './terminal.js';
17
19
  import { Reporter, detectOutputMode, parseVerbosity, Verbosity, runSkillTasks, runSkillTasksWithInk, pluralize, MODEL_DEFAULT_SENTINEL, writeJsonlContent, renderJsonlString, renderJsonlChunkLine, renderJsonlChunkRecords, initJsonlFile, appendJsonlLine, getRepoLogPath, generateRunId, } from './output/index.js';
18
20
  import { cleanupArtifacts } from './log-cleanup.js';
@@ -23,6 +25,8 @@ import { runAdd } from './commands/add.js';
23
25
  import { runSetupApp } from './commands/setup-app.js';
24
26
  import { runSync } from './commands/sync.js';
25
27
  import { runRuns } from './commands/runs.js';
28
+ import { runBuild, runImprove } from './commands/build.js';
29
+ import { generatedSkillDefinitionRootExists, resolveGeneratedSkillTarget, } from '../skill-builder/definition.js';
26
30
  /**
27
31
  * Global abort controller for graceful shutdown on SIGINT.
28
32
  * Used to cancel in-progress SDK queries.
@@ -54,22 +58,31 @@ function loadEnvFiles(dir) {
54
58
  dotenvConfig({ path: envLocalPath, override: true, quiet: true });
55
59
  }
56
60
  }
57
- /**
58
- * Create a Reporter instance from CLI options.
59
- */
60
61
  function createReporter(options) {
61
62
  const detected = detectOutputMode(options.color);
62
63
  const outputMode = options.log ? { ...detected, isTTY: false } : detected;
63
64
  const verbosity = parseVerbosity(options.quiet, options.verbose, options.debug);
64
65
  return new Reporter(outputMode, verbosity);
65
66
  }
66
- /**
67
- * Resolve the config file path based on CLI options and repo root.
68
- */
67
+ /** Resolve the directory Warden should treat as the invocation root. */
68
+ export function resolveInvocationCwd(baseCwd, cliCwd) {
69
+ return cliCwd ? resolve(baseCwd, cliCwd) : baseCwd;
70
+ }
69
71
  function resolveConfigPath(options, repoPath) {
70
72
  const cwd = process.cwd();
71
73
  return options.config ? resolve(cwd, options.config) : resolve(repoPath, 'warden.toml');
72
74
  }
75
+ function resolveLocalReviewBase(configDefaultBranch, repoPath) {
76
+ const defaultBranch = configDefaultBranch ?? getDefaultBranch(repoPath);
77
+ if (defaultBranch.includes('/')) {
78
+ return { defaultBranch, base: defaultBranch };
79
+ }
80
+ const remoteTrackingRef = `origin/${defaultBranch}`;
81
+ return {
82
+ defaultBranch,
83
+ base: refExists(remoteTrackingRef, repoPath) ? remoteTrackingRef : defaultBranch,
84
+ };
85
+ }
73
86
  /**
74
87
  * Emit a minimal JSONL log (summary-only, 0 findings) for early-exit paths.
75
88
  *
@@ -376,6 +389,138 @@ function finalizeRunLog(log, reports, totalDurationMs, error) {
376
389
  }
377
390
  return wrote;
378
391
  }
392
+ const BUILTIN_SKILL_SOURCE = 'built-in (@sentry/warden)';
393
+ function isBuiltinSkillRoot(rootDir, repoPath) {
394
+ const normalizedRoot = normalizePath(rootDir);
395
+ if (normalizedRoot.includes('/node_modules/@sentry/warden/src/builtin-skills/')
396
+ || normalizedRoot.includes('/node_modules/@sentry/warden/dist/builtin-skills/')) {
397
+ return true;
398
+ }
399
+ if (!repoPath) {
400
+ return false;
401
+ }
402
+ const relativeRoot = normalizePath(relative(repoPath, rootDir));
403
+ return (relativeRoot === 'src/builtin-skills'
404
+ || relativeRoot.startsWith('src/builtin-skills/')
405
+ || relativeRoot === 'dist/builtin-skills'
406
+ || relativeRoot.startsWith('dist/builtin-skills/'));
407
+ }
408
+ /** Format a skill source path for the CLI run header. */
409
+ export function formatSkillSource(skill, repoPath) {
410
+ if (!skill.rootDir) {
411
+ return undefined;
412
+ }
413
+ if (isBuiltinSkillRoot(skill.rootDir, repoPath)) {
414
+ return BUILTIN_SKILL_SOURCE;
415
+ }
416
+ if (!repoPath) {
417
+ return skill.rootDir;
418
+ }
419
+ const relativeRoot = normalizePath(relative(repoPath, skill.rootDir));
420
+ return isRepoRelativePath(relativeRoot) ? relativeRoot : skill.rootDir;
421
+ }
422
+ /** Apply per-skill runner overrides on top of the shared execution defaults. */
423
+ export function mergeSkillRunnerOptions(base, overrides) {
424
+ const merged = { ...base };
425
+ if (overrides.model !== undefined)
426
+ merged.model = overrides.model;
427
+ if (overrides.maxTurns !== undefined)
428
+ merged.maxTurns = overrides.maxTurns;
429
+ if (overrides.runtime !== undefined)
430
+ merged.runtime = overrides.runtime;
431
+ if (overrides.auxiliaryModel !== undefined)
432
+ merged.auxiliaryModel = overrides.auxiliaryModel;
433
+ if (overrides.synthesisModel !== undefined)
434
+ merged.synthesisModel = overrides.synthesisModel;
435
+ if (overrides.auxiliaryMaxRetries !== undefined) {
436
+ merged.auxiliaryMaxRetries = overrides.auxiliaryMaxRetries;
437
+ }
438
+ if (overrides.verifyFindings !== undefined)
439
+ merged.verifyFindings = overrides.verifyFindings;
440
+ return merged;
441
+ }
442
+ function renderSkillRunHeader(args) {
443
+ const { reporter, skill, repoPath, runtimeName, model } = args;
444
+ const source = formatSkillSource(skill, repoPath);
445
+ reporter.blank();
446
+ reporter.text(` Skill ${skill.name}`);
447
+ if (source) {
448
+ reporter.text(` Source ${source}`);
449
+ }
450
+ reporter.text(` Model ${model ?? 'default'} [${runtimeName}]`);
451
+ reporter.blank();
452
+ }
453
+ async function createDirectSkillTask(args) {
454
+ const { spec, repoPath, options, reporter, renderHeader } = args;
455
+ let skill;
456
+ try {
457
+ skill = await resolveSkillAsync(spec.skill, repoPath, {
458
+ remote: spec.remote,
459
+ offline: options.offline,
460
+ });
461
+ }
462
+ catch (error) {
463
+ if (error instanceof SkillLoaderError &&
464
+ repoPath &&
465
+ generatedSkillDefinitionRootExists(resolveGeneratedSkillTarget(repoPath, spec.skill).rootDir)) {
466
+ throw new Error(`Generated skill ${spec.skill} is missing generated artifacts. Run "warden build ${spec.skill}" first.`);
467
+ }
468
+ throw error;
469
+ }
470
+ if (renderHeader && !options.json) {
471
+ renderSkillRunHeader({
472
+ reporter,
473
+ skill,
474
+ repoPath,
475
+ runtimeName: spec.runnerOptions.runtime ?? 'claude',
476
+ model: spec.runnerOptions.model,
477
+ });
478
+ }
479
+ return {
480
+ name: spec.name,
481
+ displayName: spec.displayName,
482
+ failOn: spec.failOn,
483
+ minConfidence: spec.minConfidence,
484
+ resolveSkill: async () => skill,
485
+ context: spec.context,
486
+ runnerOptions: spec.runnerOptions,
487
+ };
488
+ }
489
+ /** Expand configured skills into runnable direct tasks. */
490
+ export async function createSkillTasks(args) {
491
+ const tasks = [];
492
+ const singleDirectSkill = args.specs.length === 1;
493
+ for (const spec of args.specs) {
494
+ tasks.push(await createDirectSkillTask({
495
+ spec,
496
+ repoPath: args.repoPath,
497
+ options: args.options,
498
+ reporter: args.reporter,
499
+ renderHeader: singleDirectSkill,
500
+ }));
501
+ }
502
+ return tasks;
503
+ }
504
+ /** Resolve the default analysis model from config, CLI overrides, or environment. */
505
+ export function resolveCliDefaultModel(config, cliModel) {
506
+ return (emptyToUndefined(config?.defaults?.agent?.model) ??
507
+ emptyToUndefined(config?.defaults?.model) ??
508
+ emptyToUndefined(cliModel) ??
509
+ emptyToUndefined(process.env['WARDEN_MODEL']));
510
+ }
511
+ /** Resolve the default auxiliary model used for helper and repair passes. */
512
+ export function resolveCliDefaultAuxiliaryModel(config) {
513
+ return emptyToUndefined(config?.defaults?.auxiliary?.model);
514
+ }
515
+ /** Resolve the default synthesis model, falling back to the auxiliary lane when unset. */
516
+ export function resolveCliDefaultSynthesisModel(config) {
517
+ return (emptyToUndefined(config?.defaults?.synthesis?.model) ??
518
+ resolveCliDefaultAuxiliaryModel(config));
519
+ }
520
+ /** Resolve the model label recorded in JSONL output, including the default sentinel. */
521
+ export function resolveCliLogModel(config, cliModel) {
522
+ return resolveCliDefaultModel(config, cliModel) ?? MODEL_DEFAULT_SENTINEL;
523
+ }
379
524
  /**
380
525
  * Process skill task results into reports and check for failures.
381
526
  * Exported for testing; callers inside main.ts use it directly.
@@ -408,9 +553,6 @@ export function processTaskResults(results, reportOn, minConfidence) {
408
553
  const filteredReports = filterReports(reports, reportOn, minConfidence);
409
554
  return { reports, filteredReports, hasFailure, failureReasons };
410
555
  }
411
- /**
412
- * Output results and handle fixes. Returns exit code.
413
- */
414
556
  async function outputResultsAndHandleFixes(processed, options, reporter, runLog, totalDuration, failFastAborted) {
415
557
  const { reports, filteredReports, hasFailure, failureReasons } = processed;
416
558
  const traceId = runLog.baseRun.traceId;
@@ -500,12 +642,8 @@ async function outputResultsAndHandleFixes(processed, options, reporter, runLog,
500
642
  }
501
643
  return 0;
502
644
  }
503
- /**
504
- * Run skills on a context and output results.
505
- * If skillName is provided, runs only that skill.
506
- * Otherwise, runs skills from matched triggers in warden.toml.
507
- */
508
- async function runSkills(context, options, reporter) {
645
+ /** Run one or more skills against an already constructed review context. */
646
+ export async function runSkills(context, options, reporter) {
509
647
  const cwd = process.cwd();
510
648
  const startTime = Date.now();
511
649
  // Get API key (optional - SDK can use Claude Code subscription auth)
@@ -547,6 +685,9 @@ async function runSkills(context, options, reporter) {
547
685
  const config = configPath && existsSync(configPath)
548
686
  ? loadWardenConfig(dirname(configPath))
549
687
  : null;
688
+ const defaultModel = resolveCliDefaultModel(config, options.model);
689
+ const defaultAuxiliaryModel = resolveCliDefaultAuxiliaryModel(config);
690
+ const defaultSynthesisModel = resolveCliDefaultSynthesisModel(config);
550
691
  // Determine which triggers/skills to run
551
692
  let skillsToRun;
552
693
  if (options.skill) {
@@ -559,7 +700,20 @@ async function runSkills(context, options, reporter) {
559
700
  const fallbackFilters = defaultIgnorePaths?.length
560
701
  ? { ignorePaths: defaultIgnorePaths }
561
702
  : {};
562
- skillsToRun = [{ skill: options.skill, remote: match?.remote, filters: match?.filters ?? fallbackFilters }];
703
+ skillsToRun = [{
704
+ skill: options.skill,
705
+ remote: match?.remote,
706
+ filters: match?.filters ?? fallbackFilters,
707
+ model: match?.model ?? defaultModel,
708
+ maxTurns: match?.maxTurns ?? config?.defaults?.agent?.maxTurns ?? config?.defaults?.maxTurns,
709
+ runtime: match?.runtime ?? config?.defaults?.runtime ?? 'claude',
710
+ auxiliaryModel: match?.auxiliaryModel ?? defaultAuxiliaryModel,
711
+ synthesisModel: match?.synthesisModel ?? defaultSynthesisModel,
712
+ auxiliaryMaxRetries: match?.auxiliaryMaxRetries ??
713
+ config?.defaults?.auxiliary?.maxRetries ??
714
+ config?.defaults?.auxiliaryMaxRetries,
715
+ verifyFindings: match?.verifyFindings ?? (config?.defaults?.verification?.enabled !== false),
716
+ }];
563
717
  }
564
718
  else if (config) {
565
719
  // Get skills from matched triggers, preserving remote property and filters
@@ -574,7 +728,18 @@ async function runSkills(context, options, reporter) {
574
728
  seen.add(t.skill);
575
729
  return true;
576
730
  })
577
- .map((t) => ({ skill: t.skill, remote: t.remote, filters: t.filters }));
731
+ .map((t) => ({
732
+ skill: t.skill,
733
+ remote: t.remote,
734
+ filters: t.filters,
735
+ model: t.model,
736
+ maxTurns: t.maxTurns,
737
+ runtime: t.runtime,
738
+ auxiliaryModel: t.auxiliaryModel,
739
+ synthesisModel: t.synthesisModel,
740
+ auxiliaryMaxRetries: t.auxiliaryMaxRetries,
741
+ verifyFindings: t.verifyFindings,
742
+ }));
578
743
  }
579
744
  else {
580
745
  skillsToRun = [];
@@ -592,30 +757,54 @@ async function runSkills(context, options, reporter) {
592
757
  return 0;
593
758
  }
594
759
  // Build skill tasks
595
- // Model precedence: defaults.model > CLI flag > WARDEN_MODEL env var > SDK default
760
+ // Model precedence: defaults.agent.model > defaults.model > CLI flag > WARDEN_MODEL env var > SDK default
596
761
  // sdkModel is undefined when no model is explicitly configured (lets SDK use its default).
597
762
  // logModel records what was used for JSONL logs (sentinel when no explicit model).
598
- const sdkModel = config?.defaults?.model ?? options.model ?? process.env['WARDEN_MODEL'];
599
- const logModel = sdkModel ?? MODEL_DEFAULT_SENTINEL;
763
+ const sdkModel = defaultModel;
764
+ const logModel = resolveCliLogModel(config, options.model);
600
765
  const runnerOptions = {
601
766
  apiKey,
602
767
  model: sdkModel,
768
+ runtime: config?.defaults?.runtime ?? 'claude',
769
+ auxiliaryModel: defaultAuxiliaryModel,
770
+ synthesisModel: defaultSynthesisModel,
603
771
  abortController,
604
- maxTurns: config?.defaults?.maxTurns,
772
+ maxTurns: config?.defaults?.agent?.maxTurns ?? config?.defaults?.maxTurns,
605
773
  batchDelayMs: config?.defaults?.batchDelayMs,
606
774
  maxContextFiles: config?.defaults?.chunking?.maxContextFiles,
607
- auxiliaryMaxRetries: config?.defaults?.auxiliaryMaxRetries,
775
+ auxiliaryMaxRetries: config?.defaults?.auxiliary?.maxRetries ??
776
+ config?.defaults?.auxiliaryMaxRetries,
777
+ verifyFindings: config?.defaults?.verification?.enabled !== false,
608
778
  };
609
- const tasks = skillsToRun.map(({ skill, remote, filters }) => ({
779
+ const specs = skillsToRun.map(({ skill, remote, filters, ...skillOptions }) => ({
610
780
  name: skill,
781
+ skill,
782
+ remote,
611
783
  failOn: options.failOn,
612
- resolveSkill: () => resolveSkillAsync(skill, repoPath, {
613
- remote,
614
- offline: options.offline,
615
- }),
616
784
  context: filterContextByPaths(context, filters),
617
- runnerOptions,
785
+ runnerOptions: mergeSkillRunnerOptions(runnerOptions, skillOptions),
618
786
  }));
787
+ let tasks;
788
+ const concurrency = options.parallel ?? DEFAULT_CONCURRENCY;
789
+ try {
790
+ tasks = await createSkillTasks({
791
+ specs,
792
+ repoPath,
793
+ options,
794
+ parallel: concurrency,
795
+ reporter,
796
+ });
797
+ }
798
+ catch (error) {
799
+ const message = error instanceof Error ? error.message : String(error);
800
+ reporter.error(message);
801
+ emitEmptyRunLog(repoPath ?? cwd, options, {
802
+ code: 'unknown',
803
+ message,
804
+ timestamp: new Date().toISOString(),
805
+ });
806
+ return 1;
807
+ }
619
808
  // Open the run's JSONL log before launching skills so `warden runs
620
809
  // follow <runId>` works from a second terminal while the run is live.
621
810
  const runId = generateRunId();
@@ -640,7 +829,6 @@ async function runSkills(context, options, reporter) {
640
829
  startTime,
641
830
  });
642
831
  // Run skills with Ink UI (TTY) or simple console output (non-TTY)
643
- const concurrency = options.parallel ?? DEFAULT_CONCURRENCY;
644
832
  failFastController = options.failFast ? new AbortController() : undefined;
645
833
  const taskOptions = {
646
834
  mode: reporter.mode,
@@ -659,9 +847,6 @@ async function runSkills(context, options, reporter) {
659
847
  const processed = processTaskResults(results, options.reportOn, effectiveMinConfidence);
660
848
  return outputResultsAndHandleFixes(processed, options, reporter, runLog, totalDuration, failFastController?.signal.aborted);
661
849
  }
662
- /**
663
- * Run in file mode: analyze specific files.
664
- */
665
850
  async function runFileMode(filePatterns, options, reporter) {
666
851
  const cwd = process.cwd();
667
852
  // Build context from files
@@ -704,9 +889,6 @@ function parseGitRef(ref) {
704
889
  }
705
890
  return { base: ref, head: 'HEAD' };
706
891
  }
707
- /**
708
- * Run in git ref mode: analyze changes from a git ref.
709
- */
710
892
  async function runGitRefMode(gitRef, options, reporter) {
711
893
  const cwd = process.cwd();
712
894
  let repoPath;
@@ -756,9 +938,6 @@ async function runGitRefMode(gitRef, options, reporter) {
756
938
  reporter.contextFiles(pullRequest.files);
757
939
  return runSkills(context, options, reporter);
758
940
  }
759
- /**
760
- * Run in config mode: use warden.toml triggers.
761
- */
762
941
  async function runConfigMode(options, reporter) {
763
942
  const cwd = process.cwd();
764
943
  let repoPath;
@@ -780,13 +959,18 @@ async function runConfigMode(options, reporter) {
780
959
  }
781
960
  // Load config
782
961
  const config = loadWardenConfig(dirname(configPath));
783
- // Build context from local git default to HEAD so only uncommitted changes are analyzed
784
- const statusMessage = options.staged ? 'Analyzing staged changes...' : 'Analyzing uncommitted changes...';
962
+ // Build context from local git. By default, mirror PR-style analysis:
963
+ // compare the configured/default branch merge base to HEAD.
964
+ const localReviewBase = resolveLocalReviewBase(config.defaults?.defaultBranch, repoPath);
965
+ const statusMessage = options.staged
966
+ ? 'Analyzing staged changes...'
967
+ : `Analyzing changes from ${localReviewBase.base} to HEAD...`;
785
968
  reporter.startContext(statusMessage);
786
969
  const context = buildLocalEventContext({
787
- base: 'HEAD',
970
+ base: options.staged ? 'HEAD' : localReviewBase.base,
971
+ head: options.staged ? undefined : 'HEAD',
788
972
  cwd: repoPath,
789
- defaultBranch: config.defaults?.defaultBranch,
973
+ defaultBranch: localReviewBase.defaultBranch,
790
974
  staged: options.staged,
791
975
  });
792
976
  const pullRequest = context.pullRequest;
@@ -801,10 +985,7 @@ async function runConfigMode(options, reporter) {
801
985
  reporter.renderEmptyState('No staged changes found');
802
986
  }
803
987
  else {
804
- const tip = !hasUncommittedChanges(repoPath)
805
- ? 'Specify a git ref: warden HEAD~3 --skill <name>'
806
- : undefined;
807
- reporter.renderEmptyState('No uncommitted changes found', tip);
988
+ reporter.renderEmptyState(`No changes found from ${pullRequest.baseBranch} to HEAD`, 'Use --staged to analyze staged changes');
808
989
  }
809
990
  reporter.blank();
810
991
  }
@@ -850,7 +1031,6 @@ async function runConfigMode(options, reporter) {
850
1031
  if (!apiKey) {
851
1032
  reporter.debug('No API key found. Using Claude Code subscription auth.');
852
1033
  }
853
- // Pre-flight: verify auth will work before starting analysis
854
1034
  try {
855
1035
  verifyAuth({ apiKey });
856
1036
  }
@@ -866,31 +1046,54 @@ async function runConfigMode(options, reporter) {
866
1046
  }
867
1047
  // Build trigger tasks
868
1048
  const effectiveMinConfidence = options.minConfidence ?? config.defaults?.minConfidence ?? 'medium';
869
- const tasks = triggersToRun.map((trigger) => ({
1049
+ const specs = triggersToRun.map((trigger) => ({
870
1050
  name: trigger.name,
871
1051
  displayName: trigger.skill,
1052
+ skill: trigger.skill,
1053
+ remote: trigger.remote,
872
1054
  failOn: trigger.failOn ?? options.failOn,
873
1055
  minConfidence: trigger.minConfidence ?? effectiveMinConfidence,
874
- resolveSkill: () => resolveSkillAsync(trigger.skill, repoPath, {
875
- remote: trigger.remote,
876
- offline: options.offline,
877
- }),
878
1056
  context: filterContextByPaths(context, trigger.filters),
879
1057
  runnerOptions: {
880
1058
  apiKey,
881
1059
  model: trigger.model,
1060
+ runtime: trigger.runtime,
1061
+ auxiliaryModel: trigger.auxiliaryModel,
1062
+ synthesisModel: trigger.synthesisModel,
882
1063
  abortController,
883
1064
  maxTurns: trigger.maxTurns,
884
1065
  maxContextFiles: config.defaults?.chunking?.maxContextFiles,
885
- auxiliaryMaxRetries: config.defaults?.auxiliaryMaxRetries,
1066
+ auxiliaryMaxRetries: trigger.auxiliaryMaxRetries,
1067
+ verifyFindings: trigger.verifyFindings,
886
1068
  },
887
1069
  }));
1070
+ let tasks;
1071
+ const concurrency = options.parallel ?? config.runner?.concurrency ?? DEFAULT_CONCURRENCY;
1072
+ try {
1073
+ tasks = await createSkillTasks({
1074
+ specs,
1075
+ repoPath,
1076
+ options,
1077
+ parallel: concurrency,
1078
+ reporter,
1079
+ });
1080
+ }
1081
+ catch (error) {
1082
+ const message = error instanceof Error ? error.message : String(error);
1083
+ reporter.error(message);
1084
+ emitEmptyRunLog(repoPath, options, {
1085
+ code: 'unknown',
1086
+ message,
1087
+ timestamp: new Date().toISOString(),
1088
+ });
1089
+ return 1;
1090
+ }
888
1091
  // Initialize the run's JSONL log up front so a second terminal can
889
1092
  // `warden runs follow <runId>` while skills are still running.
890
1093
  // Skill records are appended on each completion; the trailing summary
891
1094
  // is appended in `outputResultsAndHandleFixes`.
892
1095
  // Run-level model is the default (ignoring per-trigger overrides); per-skill models are on each report.
893
- const defaultModel = config.defaults?.model ?? options.model ?? process.env['WARDEN_MODEL'] ?? MODEL_DEFAULT_SENTINEL;
1096
+ const defaultModel = resolveCliLogModel(config, options.model);
894
1097
  const runId = generateRunId();
895
1098
  const timestamp = new Date();
896
1099
  const traceId = getTraceId();
@@ -913,7 +1116,6 @@ async function runConfigMode(options, reporter) {
913
1116
  startTime,
914
1117
  });
915
1118
  // Run triggers with Ink UI (TTY) or simple console output (non-TTY)
916
- const concurrency = options.parallel ?? config.runner?.concurrency ?? DEFAULT_CONCURRENCY;
917
1119
  failFastController = options.failFast ? new AbortController() : undefined;
918
1120
  const taskOptions = {
919
1121
  mode: reporter.mode,
@@ -931,10 +1133,6 @@ async function runConfigMode(options, reporter) {
931
1133
  const processed = processTaskResults(results, options.reportOn, effectiveMinConfidence);
932
1134
  return outputResultsAndHandleFixes(processed, options, reporter, runLog, totalDuration, failFastController?.signal.aborted);
933
1135
  }
934
- /**
935
- * Run in direct skill mode: run a specific skill on uncommitted changes.
936
- * Used when --skill is specified without targets.
937
- */
938
1136
  async function runDirectSkillMode(options, reporter) {
939
1137
  const cwd = process.cwd();
940
1138
  let repoPath;
@@ -949,13 +1147,18 @@ async function runDirectSkillMode(options, reporter) {
949
1147
  // Load config to get defaultBranch if available
950
1148
  const configPath = resolveConfigPath(options, repoPath);
951
1149
  const config = existsSync(configPath) ? loadWardenConfig(dirname(configPath)) : null;
952
- // Build context from local git - compare against HEAD for true uncommitted changes
953
- const statusMessage = options.staged ? 'Analyzing staged changes...' : 'Analyzing uncommitted changes...';
1150
+ // Build context from local git. By default, mirror PR-style analysis:
1151
+ // compare the configured/default branch merge base to HEAD.
1152
+ const localReviewBase = resolveLocalReviewBase(config?.defaults?.defaultBranch, repoPath);
1153
+ const statusMessage = options.staged
1154
+ ? 'Analyzing staged changes...'
1155
+ : `Analyzing changes from ${localReviewBase.base} to HEAD...`;
954
1156
  reporter.startContext(statusMessage);
955
1157
  const context = buildLocalEventContext({
956
- base: 'HEAD',
1158
+ base: options.staged ? 'HEAD' : localReviewBase.base,
1159
+ head: options.staged ? undefined : 'HEAD',
957
1160
  cwd: repoPath,
958
- defaultBranch: config?.defaults?.defaultBranch,
1161
+ defaultBranch: localReviewBase.defaultBranch,
959
1162
  staged: options.staged,
960
1163
  });
961
1164
  const pullRequest = context.pullRequest;
@@ -970,8 +1173,7 @@ async function runDirectSkillMode(options, reporter) {
970
1173
  reporter.renderEmptyState('No staged changes found');
971
1174
  }
972
1175
  else {
973
- const tip = 'Specify a git ref to analyze committed changes: warden main --skill <name>';
974
- reporter.renderEmptyState('No uncommitted changes found', tip);
1176
+ reporter.renderEmptyState(`No changes found from ${pullRequest.baseBranch} to HEAD`, 'Use --staged to analyze staged changes');
975
1177
  }
976
1178
  reporter.blank();
977
1179
  }
@@ -986,7 +1188,7 @@ async function runCommand(options, reporter) {
986
1188
  if (options.staged && targets.length > 0) {
987
1189
  reporter.warning('--staged is ignored when targets are specified');
988
1190
  }
989
- // No targets with --skill → run skill directly on uncommitted changes
1191
+ // No targets with --skill → run skill directly on current branch changes
990
1192
  if (targets.length === 0 && options.skill) {
991
1193
  return runDirectSkillMode(options, reporter);
992
1194
  }
@@ -1016,16 +1218,31 @@ async function runCommand(options, reporter) {
1016
1218
  // File mode
1017
1219
  return runFileMode(filePatterns, options, reporter);
1018
1220
  }
1221
+ /** Parse CLI input, dispatch the selected command, and perform shutdown cleanup. */
1019
1222
  export async function main() {
1020
- const { command, options, setupAppOptions, runsOptions } = parseCliArgs();
1223
+ const { command, options, helpTarget, setupAppOptions, runsOptions } = parseCliArgs();
1021
1224
  if (command === 'help') {
1022
- showHelp();
1225
+ showHelp(helpTarget);
1023
1226
  process.exit(0);
1024
1227
  }
1025
1228
  if (command === 'version') {
1026
1229
  showVersion();
1027
1230
  process.exit(0);
1028
1231
  }
1232
+ const reporter = createReporter(options);
1233
+ const originalCwd = process.cwd();
1234
+ const invocationCwd = resolveInvocationCwd(originalCwd, options.cwd);
1235
+ if (invocationCwd !== originalCwd) {
1236
+ try {
1237
+ process.chdir(invocationCwd);
1238
+ }
1239
+ catch (error) {
1240
+ const message = error instanceof Error ? error.message : String(error);
1241
+ reporter.error(`Unable to change to ${invocationCwd}: ${message}`);
1242
+ process.exit(1);
1243
+ return;
1244
+ }
1245
+ }
1029
1246
  // Load environment variables from .env files at CLI entry point.
1030
1247
  // Try repo root first, fall back to cwd if not in a git repo.
1031
1248
  const cwd = process.cwd();
@@ -1037,8 +1254,6 @@ export async function main() {
1037
1254
  // Not in a git repo - use cwd
1038
1255
  }
1039
1256
  loadEnvFiles(envDir);
1040
- // Create reporter based on options
1041
- const reporter = createReporter(options);
1042
1257
  // Show header (unless JSON output or quiet)
1043
1258
  if (!options.json) {
1044
1259
  reporter.header();
@@ -1068,6 +1283,10 @@ export async function main() {
1068
1283
  process.exit(1);
1069
1284
  }
1070
1285
  return runRuns(runsOptions, options, reporter);
1286
+ case 'build':
1287
+ return runBuild(options, reporter, { abortController, interrupted });
1288
+ case 'improve':
1289
+ return runImprove(options, reporter, { abortController, interrupted });
1071
1290
  default:
1072
1291
  return runCommand(options, reporter);
1073
1292
  }