@prism-d1/cli 1.1.2 → 1.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 (255) hide show
  1. package/dist/assets/github-workflows/prism-agent-eval.yml +2 -1
  2. package/dist/assets/github-workflows/prism-eval-gate-kiro.yml +12 -2
  3. package/dist/assets/gitlab-workflows/prism-eval-gate.yml +8 -0
  4. package/dist/assets/infra/bin/app.ts +61 -37
  5. package/dist/assets/infra/lib/constructs/otel-collector-construct.ts +96 -0
  6. package/dist/assets/infra/lib/constructs/security-agent-construct.ts +35 -30
  7. package/dist/assets/infra/lib/dashboard-stack.ts +27 -0
  8. package/dist/assets/infra/lib/lambda/otel-receiver.ts +278 -8
  9. package/dist/assets/infra/lib/lambda/pricing/litellm-snapshot.json +3769 -0
  10. package/dist/assets/infra/lib/lambda/pricing/price-source.ts +56 -0
  11. package/dist/assets/infra/lib/lambda/pricing/price-table.ts +240 -0
  12. package/dist/assets/infra/lib/lambda/pricing/prices-key.ts +6 -0
  13. package/dist/assets/infra/lib/lambda/pricing/reprice.ts +108 -0
  14. package/dist/assets/infra/lib/lambda/pricing-refresh.ts +352 -0
  15. package/dist/assets/infra/lib/lambda/velocity-widget.ts +124 -1
  16. package/dist/assets/infra/lib/metrics-pipeline-stack.ts +2 -110
  17. package/dist/assets/infra/lib/security-agent-resources.ts +136 -0
  18. package/dist/assets/infra/lib/security-agent-stack.ts +69 -0
  19. package/dist/assets/infra/package.json +4 -1
  20. package/dist/assets/metric-hooks/prepare-commit-msg +3 -1
  21. package/dist/assets/pentest-cdk/bin/app.ts +12 -0
  22. package/dist/assets/pentest-cdk/cdk.json +7 -0
  23. package/dist/assets/pentest-cdk/lib/pentest-target-stack.ts +206 -0
  24. package/dist/assets/pentest-cdk/package.json +18 -0
  25. package/dist/assets/pentest-cdk/tsconfig.json +12 -0
  26. package/dist/src/codewatch/config.d.ts +17 -0
  27. package/dist/src/codewatch/config.d.ts.map +1 -0
  28. package/dist/src/codewatch/config.js +40 -0
  29. package/dist/src/codewatch/config.js.map +1 -0
  30. package/dist/src/codewatch/gitleaks.d.ts +49 -0
  31. package/dist/src/codewatch/gitleaks.d.ts.map +1 -0
  32. package/dist/src/codewatch/gitleaks.js +160 -0
  33. package/dist/src/codewatch/gitleaks.js.map +1 -0
  34. package/dist/src/codewatch/globalHooks.d.ts +52 -0
  35. package/dist/src/codewatch/globalHooks.d.ts.map +1 -0
  36. package/dist/src/codewatch/globalHooks.js +235 -0
  37. package/dist/src/codewatch/globalHooks.js.map +1 -0
  38. package/dist/src/codewatch/hooks.d.ts +38 -0
  39. package/dist/src/codewatch/hooks.d.ts.map +1 -0
  40. package/dist/src/codewatch/hooks.js +176 -0
  41. package/dist/src/codewatch/hooks.js.map +1 -0
  42. package/dist/src/codewatch/prepush.d.ts +37 -0
  43. package/dist/src/codewatch/prepush.d.ts.map +1 -0
  44. package/dist/src/codewatch/prepush.js +231 -0
  45. package/dist/src/codewatch/prepush.js.map +1 -0
  46. package/dist/src/codewatch/results.d.ts +210 -0
  47. package/dist/src/codewatch/results.d.ts.map +1 -0
  48. package/dist/src/codewatch/results.js +127 -0
  49. package/dist/src/codewatch/results.js.map +1 -0
  50. package/dist/src/codewatch/reviewers/claude.d.ts +9 -0
  51. package/dist/src/codewatch/reviewers/claude.d.ts.map +1 -0
  52. package/dist/src/codewatch/reviewers/claude.js +48 -0
  53. package/dist/src/codewatch/reviewers/claude.js.map +1 -0
  54. package/dist/src/codewatch/reviewers/index.d.ts +39 -0
  55. package/dist/src/codewatch/reviewers/index.d.ts.map +1 -0
  56. package/dist/src/codewatch/reviewers/index.js +97 -0
  57. package/dist/src/codewatch/reviewers/index.js.map +1 -0
  58. package/dist/src/codewatch/reviewers/kiro.d.ts +14 -0
  59. package/dist/src/codewatch/reviewers/kiro.d.ts.map +1 -0
  60. package/dist/src/codewatch/reviewers/kiro.js +32 -0
  61. package/dist/src/codewatch/reviewers/kiro.js.map +1 -0
  62. package/dist/src/codewatch/reviewers/types.d.ts +56 -0
  63. package/dist/src/codewatch/reviewers/types.d.ts.map +1 -0
  64. package/dist/src/codewatch/reviewers/types.js +91 -0
  65. package/dist/src/codewatch/reviewers/types.js.map +1 -0
  66. package/dist/src/codewatch/rules.d.ts +12 -0
  67. package/dist/src/codewatch/rules.d.ts.map +1 -0
  68. package/dist/src/codewatch/rules.js +27 -0
  69. package/dist/src/codewatch/rules.js.map +1 -0
  70. package/dist/src/commands/_top/dashboard.d.ts +17 -0
  71. package/dist/src/commands/_top/dashboard.d.ts.map +1 -0
  72. package/dist/src/commands/_top/dashboard.js +76 -0
  73. package/dist/src/commands/_top/dashboard.js.map +1 -0
  74. package/dist/src/commands/_top/version.d.ts +62 -0
  75. package/dist/src/commands/_top/version.d.ts.map +1 -0
  76. package/dist/src/commands/_top/version.js +175 -0
  77. package/dist/src/commands/_top/version.js.map +1 -0
  78. package/dist/src/commands/bedrock-protection/scan-account.d.ts.map +1 -1
  79. package/dist/src/commands/bedrock-protection/scan-account.js +2 -1
  80. package/dist/src/commands/bedrock-protection/scan-account.js.map +1 -1
  81. package/dist/src/commands/bedrock-protection/scan-org.d.ts.map +1 -1
  82. package/dist/src/commands/bedrock-protection/scan-org.js +16 -4
  83. package/dist/src/commands/bedrock-protection/scan-org.js.map +1 -1
  84. package/dist/src/commands/bootstrapper/install-eval-harness.d.ts.map +1 -1
  85. package/dist/src/commands/bootstrapper/install-eval-harness.js +15 -48
  86. package/dist/src/commands/bootstrapper/install-eval-harness.js.map +1 -1
  87. package/dist/src/commands/bootstrapper/install-git-hooks.d.ts +13 -0
  88. package/dist/src/commands/bootstrapper/install-git-hooks.d.ts.map +1 -1
  89. package/dist/src/commands/bootstrapper/install-git-hooks.js +28 -147
  90. package/dist/src/commands/bootstrapper/install-git-hooks.js.map +1 -1
  91. package/dist/src/commands/bootstrapper/setup-otel-sync.d.ts +12 -6
  92. package/dist/src/commands/bootstrapper/setup-otel-sync.d.ts.map +1 -1
  93. package/dist/src/commands/bootstrapper/setup-otel-sync.js +18 -443
  94. package/dist/src/commands/bootstrapper/setup-otel-sync.js.map +1 -1
  95. package/dist/src/commands/codewatch/pre-commit.d.ts +7 -0
  96. package/dist/src/commands/codewatch/pre-commit.d.ts.map +1 -0
  97. package/dist/src/commands/codewatch/pre-commit.js +30 -0
  98. package/dist/src/commands/codewatch/pre-commit.js.map +1 -0
  99. package/dist/src/commands/codewatch/pre-push.d.ts +16 -0
  100. package/dist/src/commands/codewatch/pre-push.d.ts.map +1 -0
  101. package/dist/src/commands/codewatch/pre-push.js +32 -0
  102. package/dist/src/commands/codewatch/pre-push.js.map +1 -0
  103. package/dist/src/commands/codewatch/report.d.ts +22 -0
  104. package/dist/src/commands/codewatch/report.d.ts.map +1 -0
  105. package/dist/src/commands/codewatch/report.js +64 -0
  106. package/dist/src/commands/codewatch/report.js.map +1 -0
  107. package/dist/src/commands/enable/codeburn.d.ts +59 -0
  108. package/dist/src/commands/enable/codeburn.d.ts.map +1 -0
  109. package/dist/src/commands/enable/codeburn.js +531 -0
  110. package/dist/src/commands/enable/codeburn.js.map +1 -0
  111. package/dist/src/commands/enable/codewatch.d.ts +15 -0
  112. package/dist/src/commands/enable/codewatch.d.ts.map +1 -0
  113. package/dist/src/commands/enable/codewatch.js +186 -0
  114. package/dist/src/commands/enable/codewatch.js.map +1 -0
  115. package/dist/src/commands/enable/security.d.ts +41 -0
  116. package/dist/src/commands/enable/security.d.ts.map +1 -0
  117. package/dist/src/commands/enable/security.js +130 -0
  118. package/dist/src/commands/enable/security.js.map +1 -0
  119. package/dist/src/commands/export/otel.d.ts +31 -0
  120. package/dist/src/commands/export/otel.d.ts.map +1 -0
  121. package/dist/src/commands/export/otel.js +52 -0
  122. package/dist/src/commands/export/otel.js.map +1 -0
  123. package/dist/src/commands/git/claude-session-context.d.ts.map +1 -1
  124. package/dist/src/commands/git/claude-session-context.js +2 -1
  125. package/dist/src/commands/git/claude-session-context.js.map +1 -1
  126. package/dist/src/commands/git/commit-trailers.js +1 -1
  127. package/dist/src/commands/git/commit-trailers.js.map +1 -1
  128. package/dist/src/commands/security/code-review.d.ts +22 -0
  129. package/dist/src/commands/security/code-review.d.ts.map +1 -0
  130. package/dist/src/commands/security/code-review.js +43 -0
  131. package/dist/src/commands/security/code-review.js.map +1 -0
  132. package/dist/src/commands/security/findings.d.ts +15 -0
  133. package/dist/src/commands/security/findings.d.ts.map +1 -0
  134. package/dist/src/commands/security/findings.js +31 -0
  135. package/dist/src/commands/security/findings.js.map +1 -0
  136. package/dist/src/commands/security/pentest.d.ts +18 -0
  137. package/dist/src/commands/security/pentest.d.ts.map +1 -0
  138. package/dist/src/commands/security/pentest.js +32 -0
  139. package/dist/src/commands/security/pentest.js.map +1 -0
  140. package/dist/src/commands/security/threat-model.d.ts +16 -0
  141. package/dist/src/commands/security/threat-model.d.ts.map +1 -0
  142. package/dist/src/commands/security/threat-model.js +24 -0
  143. package/dist/src/commands/security/threat-model.js.map +1 -0
  144. package/dist/src/commands/security/threats.d.ts +12 -0
  145. package/dist/src/commands/security/threats.d.ts.map +1 -0
  146. package/dist/src/commands/security/threats.js +23 -0
  147. package/dist/src/commands/security/threats.js.map +1 -0
  148. package/dist/src/commands/securityagent/setup.d.ts +19 -5
  149. package/dist/src/commands/securityagent/setup.d.ts.map +1 -1
  150. package/dist/src/commands/securityagent/setup.js +25 -189
  151. package/dist/src/commands/securityagent/setup.js.map +1 -1
  152. package/dist/src/commands/workshop/verify-setup.d.ts.map +1 -1
  153. package/dist/src/commands/workshop/verify-setup.js +5 -3
  154. package/dist/src/commands/workshop/verify-setup.js.map +1 -1
  155. package/dist/src/dashboard/codewatch.d.ts +106 -0
  156. package/dist/src/dashboard/codewatch.d.ts.map +1 -0
  157. package/dist/src/dashboard/codewatch.js +120 -0
  158. package/dist/src/dashboard/codewatch.js.map +1 -0
  159. package/dist/src/dashboard/commits.d.ts +96 -0
  160. package/dist/src/dashboard/commits.d.ts.map +1 -0
  161. package/dist/src/dashboard/commits.js +207 -0
  162. package/dist/src/dashboard/commits.js.map +1 -0
  163. package/dist/src/dashboard/page.d.ts +10 -0
  164. package/dist/src/dashboard/page.d.ts.map +1 -0
  165. package/dist/src/dashboard/page.js +470 -0
  166. package/dist/src/dashboard/page.js.map +1 -0
  167. package/dist/src/dashboard/payload.d.ts +114 -0
  168. package/dist/src/dashboard/payload.d.ts.map +1 -0
  169. package/dist/src/dashboard/payload.js +96 -0
  170. package/dist/src/dashboard/payload.js.map +1 -0
  171. package/dist/src/dashboard/report.d.ts +99 -0
  172. package/dist/src/dashboard/report.d.ts.map +1 -0
  173. package/dist/src/dashboard/report.js +300 -0
  174. package/dist/src/dashboard/report.js.map +1 -0
  175. package/dist/src/dashboard/repos.d.ts +58 -0
  176. package/dist/src/dashboard/repos.d.ts.map +1 -0
  177. package/dist/src/dashboard/repos.js +111 -0
  178. package/dist/src/dashboard/repos.js.map +1 -0
  179. package/dist/src/dashboard/security.d.ts +130 -0
  180. package/dist/src/dashboard/security.d.ts.map +1 -0
  181. package/dist/src/dashboard/security.js +144 -0
  182. package/dist/src/dashboard/security.js.map +1 -0
  183. package/dist/src/dashboard/server.d.ts +52 -0
  184. package/dist/src/dashboard/server.d.ts.map +1 -0
  185. package/dist/src/dashboard/server.js +163 -0
  186. package/dist/src/dashboard/server.js.map +1 -0
  187. package/dist/src/dashboard/setup.d.ts +67 -0
  188. package/dist/src/dashboard/setup.d.ts.map +1 -0
  189. package/dist/src/dashboard/setup.js +146 -0
  190. package/dist/src/dashboard/setup.js.map +1 -0
  191. package/dist/src/dashboard/usage.d.ts +43 -0
  192. package/dist/src/dashboard/usage.d.ts.map +1 -0
  193. package/dist/src/dashboard/usage.js +88 -0
  194. package/dist/src/dashboard/usage.js.map +1 -0
  195. package/dist/src/index.d.ts +1 -0
  196. package/dist/src/index.d.ts.map +1 -1
  197. package/dist/src/index.js +48 -2
  198. package/dist/src/index.js.map +1 -1
  199. package/dist/src/security/cfn-diff.d.ts +57 -0
  200. package/dist/src/security/cfn-diff.d.ts.map +1 -0
  201. package/dist/src/security/cfn-diff.js +112 -0
  202. package/dist/src/security/cfn-diff.js.map +1 -0
  203. package/dist/src/security/errors.d.ts +45 -0
  204. package/dist/src/security/errors.d.ts.map +1 -0
  205. package/dist/src/security/errors.js +116 -0
  206. package/dist/src/security/errors.js.map +1 -0
  207. package/dist/src/security/marker.d.ts +46 -0
  208. package/dist/src/security/marker.d.ts.map +1 -0
  209. package/dist/src/security/marker.js +120 -0
  210. package/dist/src/security/marker.js.map +1 -0
  211. package/dist/src/security/pentest-dockerfile.d.ts +8 -0
  212. package/dist/src/security/pentest-dockerfile.d.ts.map +1 -0
  213. package/dist/src/security/pentest-dockerfile.js +163 -0
  214. package/dist/src/security/pentest-dockerfile.js.map +1 -0
  215. package/dist/src/security/pentest.d.ts +233 -0
  216. package/dist/src/security/pentest.d.ts.map +1 -0
  217. package/dist/src/security/pentest.js +1057 -0
  218. package/dist/src/security/pentest.js.map +1 -0
  219. package/dist/src/security/repo.d.ts +25 -0
  220. package/dist/src/security/repo.d.ts.map +1 -0
  221. package/dist/src/security/repo.js +38 -0
  222. package/dist/src/security/repo.js.map +1 -0
  223. package/dist/src/security/review.d.ts +202 -0
  224. package/dist/src/security/review.d.ts.map +1 -0
  225. package/dist/src/security/review.js +706 -0
  226. package/dist/src/security/review.js.map +1 -0
  227. package/dist/src/security/setup.d.ts +193 -0
  228. package/dist/src/security/setup.d.ts.map +1 -0
  229. package/dist/src/security/setup.js +728 -0
  230. package/dist/src/security/setup.js.map +1 -0
  231. package/dist/src/security/threat-model.d.ts +133 -0
  232. package/dist/src/security/threat-model.d.ts.map +1 -0
  233. package/dist/src/security/threat-model.js +653 -0
  234. package/dist/src/security/threat-model.js.map +1 -0
  235. package/dist/src/utils/audit-bedrock.d.ts +1 -0
  236. package/dist/src/utils/audit-bedrock.d.ts.map +1 -1
  237. package/dist/src/utils/audit-bedrock.js +133 -0
  238. package/dist/src/utils/audit-bedrock.js.map +1 -1
  239. package/dist/src/utils/audit-org.d.ts +1 -0
  240. package/dist/src/utils/audit-org.d.ts.map +1 -1
  241. package/dist/src/utils/audit-org.js +155 -0
  242. package/dist/src/utils/audit-org.js.map +1 -1
  243. package/dist/src/utils/exec.d.ts +6 -0
  244. package/dist/src/utils/exec.d.ts.map +1 -1
  245. package/dist/src/utils/exec.js +12 -1
  246. package/dist/src/utils/exec.js.map +1 -1
  247. package/dist/src/utils/otel-sync-schedule.d.ts +41 -0
  248. package/dist/src/utils/otel-sync-schedule.d.ts.map +1 -0
  249. package/dist/src/utils/otel-sync-schedule.js +90 -0
  250. package/dist/src/utils/otel-sync-schedule.js.map +1 -0
  251. package/dist/src/utils/tool-check.d.ts +14 -0
  252. package/dist/src/utils/tool-check.d.ts.map +1 -0
  253. package/dist/src/utils/tool-check.js +42 -0
  254. package/dist/src/utils/tool-check.js.map +1 -0
  255. package/package.json +3 -2
@@ -0,0 +1,210 @@
1
+ export declare const RESULT_SCHEMA_VERSION = 1;
2
+ export declare const RESULTS_DIR = ".prism/results";
3
+ /** Pre-commit ran with no gitleaks on PATH: the commit was allowed but not secret-scanned. */
4
+ export declare const REASON_GITLEAKS_MISSING = "gitleaks-missing";
5
+ export type Severity = 'high' | 'medium' | 'low';
6
+ export type FindingCategory = 'quality' | 'security';
7
+ export interface Finding {
8
+ severity: Severity;
9
+ category: FindingCategory;
10
+ /** Rule that fired: a gitleaks RuleID, or the review rule the reviewer named. */
11
+ rule: string;
12
+ file: string;
13
+ line: number | null;
14
+ message: string;
15
+ /** security-review / security-pentest: the Security Agent risk level (CRITICAL ... UNKNOWN), finding title, CWE and id. */
16
+ risk_level?: string;
17
+ title?: string;
18
+ cwe?: string | null;
19
+ finding_id?: string;
20
+ /** security-review only: the path exactly as the service reported it (file is repo-relative). */
21
+ raw_file?: string;
22
+ /** security-threat-model only: the threat's id, STRIDE categories, mitigation and every evidence path (repo-relative). */
23
+ threat_id?: string;
24
+ stride?: string[];
25
+ recommendation?: string;
26
+ evidence?: string[];
27
+ /** security-pentest only: the agent's confidence (HIGH | MEDIUM | LOW | FALSE_POSITIVE). */
28
+ confidence?: string;
29
+ }
30
+ /**
31
+ * `secrets` = gitleaks; `review` = the reviewer (kiro-cli / Claude Code);
32
+ * `security-review` = an AWS Security Agent code review job;
33
+ * `security-threat-model` = an AWS Security Agent threat model job;
34
+ * `security-pentest` = an AWS Security Agent penetration test job.
35
+ */
36
+ export type ResultKind = 'secrets' | 'review' | 'security-review' | 'security-threat-model' | 'security-pentest';
37
+ /** security-threat-model only: the job behind the result. */
38
+ export interface ThreatModelInfo {
39
+ job_id: string;
40
+ threat_model_id: string;
41
+ agent_space_id: string;
42
+ region: string;
43
+ account?: string;
44
+ job_status: string;
45
+ /** Threats per severity (CRITICAL ... INFO). */
46
+ counts: Record<string, number>;
47
+ /** Threats per STRIDE category. */
48
+ stride_counts: Record<string, number>;
49
+ /** Repo paths of the scope docs, as read from the commit. */
50
+ scope_docs: string[];
51
+ /** The agent's system overview, in full; null until the job completes. */
52
+ system_overview: string | null;
53
+ service_created_at?: string | null;
54
+ service_updated_at?: string | null;
55
+ }
56
+ /** security-review only: the job behind the result. */
57
+ export interface SecurityReviewInfo {
58
+ job_id: string;
59
+ code_review_id: string;
60
+ agent_space_id: string;
61
+ region: string;
62
+ /** The AWS account the job ran in, so `security findings` only completes its own account's pending records. */
63
+ account?: string;
64
+ /** diff: the branch diff base...tip. full: the whole repo at tip. unknown: fetched later by `security findings`. */
65
+ scope: 'diff' | 'full' | 'unknown';
66
+ /**
67
+ * The commit the code review's source asset (repo/<slug>/latest.zip) held
68
+ * when the job started: the code a diff job reads around the patch. null
69
+ * when unknown (a job `security findings` fetched with no pending record).
70
+ */
71
+ context_commit?: string | null;
72
+ job_status: string;
73
+ /** Findings per Security Agent risk level. */
74
+ counts: Record<string, number>;
75
+ /** The service's job timestamps, and updatedAt - createdAt (queue plus run time), when it reported them. */
76
+ service_created_at?: string | null;
77
+ service_updated_at?: string | null;
78
+ service_duration_s?: number | null;
79
+ /** Our wall time from starting the job to seeing it finish (code-review only; includes polling). */
80
+ wall_s?: number | null;
81
+ }
82
+ /**
83
+ * security-pentest only: the penetration-test job behind the result, and the
84
+ * temporary environment it ran against. Mirrors SecurityReviewInfo; a pentest
85
+ * finding has no file/line, carries a `confidence`, and the environment handle
86
+ * is what `security pentest --cleanup` tears down.
87
+ */
88
+ export interface PentestInfo {
89
+ job_id: string;
90
+ pentest_id: string;
91
+ agent_space_id: string;
92
+ /** True when this run created a dedicated agent space (teardown deletes it); false when it reused a shared one. */
93
+ agent_space_dedicated: boolean;
94
+ region: string;
95
+ /** The AWS account the job ran in, so findings only completes its own account's pending records. */
96
+ account?: string;
97
+ /** The verified target domain the pentest ran against (app.<zone>). */
98
+ target_host: string;
99
+ job_status: string;
100
+ /** Findings per Security Agent risk level, after dropping FALSE_POSITIVE confidence (unless --include-false-positives). */
101
+ counts: Record<string, number>;
102
+ /** First paragraph of the job's `overview` text, when the service reported one. */
103
+ overview?: string | null;
104
+ /** The CloudFormation stack and run slug of the temporary environment, for --cleanup. */
105
+ stack?: string | null;
106
+ slug?: string | null;
107
+ /** When the environment is set to auto-expire (the prism:expires-at tag), ISO. */
108
+ expires_at?: string | null;
109
+ /** The agent ENIs' security group id: teardown waits for its ENIs to drain before destroying the stack. */
110
+ agent_security_group_id?: string | null;
111
+ /** The app container's log group, for debugging hints. */
112
+ app_log_group?: string | null;
113
+ /** The PRIVATE_VPC target domain this run created; teardown deletes it. */
114
+ target_domain_id?: string | null;
115
+ /** Set when the last teardown left the stack up (destroy failed twice); --cleanup retries it. */
116
+ teardown_failed?: {
117
+ at: string;
118
+ reason: string;
119
+ } | null;
120
+ service_created_at?: string | null;
121
+ service_updated_at?: string | null;
122
+ service_duration_s?: number | null;
123
+ wall_s?: number | null;
124
+ }
125
+ export type ResultHook = 'pre-commit' | 'pre-push' | 'ci' | 'manual';
126
+ /**
127
+ * ok ran, nothing found
128
+ * findings ran, found something
129
+ * error could not produce a verdict (tool missing, crashed, unparseable output)
130
+ * skipped did not run: no changes to review, or the hook was bypassed (`--no-verify`)
131
+ * pending security-review / security-pentest: the job was started and has no
132
+ * verdict yet. finished_at equals started_at until the record is
133
+ * completed in place.
134
+ */
135
+ export type ResultStatus = 'ok' | 'findings' | 'error' | 'skipped' | 'pending';
136
+ export interface PrismResult {
137
+ schema_version: typeof RESULT_SCHEMA_VERSION;
138
+ kind: ResultKind;
139
+ hook: ResultHook;
140
+ status: ResultStatus;
141
+ /** Tool that produced the verdict: 'gitleaks', 'kiro', 'claude', or 'none'. */
142
+ tool: string;
143
+ tool_version: string | null;
144
+ /** Model the reviewer reported, or the one requested if it reported none. null when unknown. */
145
+ model: string | null;
146
+ /** Commit reviewed. null for pre-commit, where the commit does not exist yet. */
147
+ commit: string | null;
148
+ /**
149
+ * Tree object of the change. For pre-commit this is the staged tree, which
150
+ * equals the tree of the commit that follows -- how a later pre-push links a
151
+ * pushed commit back to its secret scan, and so detects `--no-verify`.
152
+ */
153
+ tree: string | null;
154
+ branch: string | null;
155
+ upstream: string | null;
156
+ /** Base commit of the reviewed range (pre-push). */
157
+ base: string | null;
158
+ started_at: string;
159
+ finished_at: string;
160
+ findings: Finding[];
161
+ summary: string | null;
162
+ score: number | null;
163
+ /**
164
+ * Why the run errored or was skipped. Free text, except these codes, which
165
+ * consumers (the dashboard, CI) match on exactly: see REASON_*.
166
+ */
167
+ reason: string | null;
168
+ /** Present on kind security-review. */
169
+ security?: SecurityReviewInfo;
170
+ /** Present on kind security-threat-model. */
171
+ threat_model?: ThreatModelInfo;
172
+ /** Present on kind security-pentest. */
173
+ pentest?: PentestInfo;
174
+ }
175
+ export type ResultInit = Omit<PrismResult, 'schema_version' | 'tool_version' | 'model' | 'commit' | 'tree' | 'branch' | 'upstream' | 'base' | 'summary' | 'score' | 'reason' | 'findings'> & Partial<Pick<PrismResult, 'tool_version' | 'model' | 'commit' | 'tree' | 'branch' | 'upstream' | 'base' | 'summary' | 'score' | 'reason' | 'findings'>>;
176
+ export declare function makeResult(init: ResultInit): PrismResult;
177
+ /** `20261104T202000123Z` -- sortable, colon-free. */
178
+ export declare function compactTimestamp(iso: string): string;
179
+ /**
180
+ * `<commit12>-<time>-<hook>-<kind>.json`, or `tree-<tree12>-...` when there is
181
+ * no commit yet (pre-commit).
182
+ */
183
+ export declare function resultFileName(r: PrismResult): string;
184
+ /**
185
+ * Writes a result atomically (temp file + rename), so a dashboard reading the
186
+ * directory never sees a half-written file. Returns the absolute path.
187
+ */
188
+ /**
189
+ * Makes sure `.prism/results/` is ignored in this clone. Under the global
190
+ * hooks a repo may never have had codewatch installed, so it has no .gitignore
191
+ * entry; `.git/info/exclude` is local to the clone and keeps the working tree
192
+ * clean without touching any tracked file. Outside a git repo it does nothing.
193
+ */
194
+ export declare function ensureResultsExcluded(repoRoot: string): boolean;
195
+ /**
196
+ * `id` (a ResultEntry id) rewrites that existing file in place instead of
197
+ * naming a new one: how a pending security-review record is completed.
198
+ */
199
+ export declare function writeResult(repoRoot: string, r: PrismResult, id?: string): string;
200
+ export interface ResultEntry {
201
+ /** File name without `.json`: the result's stable id (used by report links). */
202
+ id: string;
203
+ result: PrismResult;
204
+ }
205
+ /** Every parseable result with its id. Ids come from the directory listing, never from input. */
206
+ export declare function readResultEntries(repoRoot: string): ResultEntry[];
207
+ /** Reads every parseable result file. Unparseable files are ignored, not fatal. */
208
+ export declare function readResults(repoRoot: string): PrismResult[];
209
+ export declare function countBySeverity(findings: Finding[]): Record<Severity, number>;
210
+ //# sourceMappingURL=results.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"results.d.ts","sourceRoot":"","sources":["../../../src/codewatch/results.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Codewatch result schema and writer (local git-hook gate runs).
3
+ *
4
+ * Every local gate run (the pre-commit secret scan, the pre-push review, and a
5
+ * detected skip of either) is written as one JSON file under `.prism/results/`.
6
+ * The schema lives here, not in the hook code, so `prism-cli dashboard` and CI
7
+ * can read the same files without re-deriving the shape.
8
+ *
9
+ * Results are local developer evidence, never committed: the installer adds
10
+ * `.prism/results/` to .gitignore.
11
+ */
12
+ import { mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
13
+ import { dirname, join, resolve } from 'node:path';
14
+ import { appendFileSync, existsSync as fileExists } from 'node:fs';
15
+ import { run } from '../utils/exec.js';
16
+ export const RESULT_SCHEMA_VERSION = 1;
17
+ export const RESULTS_DIR = '.prism/results';
18
+ /** Pre-commit ran with no gitleaks on PATH: the commit was allowed but not secret-scanned. */
19
+ export const REASON_GITLEAKS_MISSING = 'gitleaks-missing';
20
+ export function makeResult(init) {
21
+ return {
22
+ schema_version: RESULT_SCHEMA_VERSION,
23
+ tool_version: null,
24
+ model: null,
25
+ commit: null,
26
+ tree: null,
27
+ branch: null,
28
+ upstream: null,
29
+ base: null,
30
+ summary: null,
31
+ score: null,
32
+ reason: null,
33
+ findings: [],
34
+ ...init,
35
+ };
36
+ }
37
+ /** Keeps only characters safe in a file name, so no value can escape the results dir. */
38
+ function safePart(s) {
39
+ return s.replace(/[^A-Za-z0-9_-]/g, '').slice(0, 40) || 'x';
40
+ }
41
+ /** `20261104T202000123Z` -- sortable, colon-free. */
42
+ export function compactTimestamp(iso) {
43
+ return iso.replace(/[-:]/g, '').replace('.', '');
44
+ }
45
+ /**
46
+ * `<commit12>-<time>-<hook>-<kind>.json`, or `tree-<tree12>-...` when there is
47
+ * no commit yet (pre-commit).
48
+ */
49
+ export function resultFileName(r) {
50
+ const id = r.commit ? safePart(r.commit.slice(0, 12)) : r.tree ? `tree-${safePart(r.tree.slice(0, 12))}` : 'nocommit';
51
+ return `${id}-${compactTimestamp(r.started_at)}-${safePart(r.hook)}-${safePart(r.kind)}.json`;
52
+ }
53
+ /**
54
+ * Writes a result atomically (temp file + rename), so a dashboard reading the
55
+ * directory never sees a half-written file. Returns the absolute path.
56
+ */
57
+ /**
58
+ * Makes sure `.prism/results/` is ignored in this clone. Under the global
59
+ * hooks a repo may never have had codewatch installed, so it has no .gitignore
60
+ * entry; `.git/info/exclude` is local to the clone and keeps the working tree
61
+ * clean without touching any tracked file. Outside a git repo it does nothing.
62
+ */
63
+ export function ensureResultsExcluded(repoRoot) {
64
+ const probe = run('git', ['-C', repoRoot, 'check-ignore', '-q', `${RESULTS_DIR}/probe.json`]);
65
+ if (probe.ok)
66
+ return false;
67
+ const p = run('git', ['-C', repoRoot, 'rev-parse', '--path-format=absolute', '--git-path', 'info/exclude']);
68
+ if (!p.ok || !p.stdout)
69
+ return false;
70
+ mkdirSync(dirname(p.stdout), { recursive: true });
71
+ const prefix = fileExists(p.stdout) && !readFileSync(p.stdout, 'utf8').endsWith('\n') ? '\n' : '';
72
+ appendFileSync(p.stdout, `${prefix}# prism-cli codewatch results (local)\n/${RESULTS_DIR}/\n`);
73
+ return true;
74
+ }
75
+ /**
76
+ * `id` (a ResultEntry id) rewrites that existing file in place instead of
77
+ * naming a new one: how a pending security-review record is completed.
78
+ */
79
+ export function writeResult(repoRoot, r, id) {
80
+ if (id !== undefined && !/^[A-Za-z0-9_-]{1,200}$/.test(id))
81
+ throw new Error(`invalid result id: ${id}`);
82
+ const dir = resolve(repoRoot, RESULTS_DIR);
83
+ if (!fileExists(dir)) {
84
+ try {
85
+ ensureResultsExcluded(repoRoot);
86
+ }
87
+ catch { /* never fail a write over this */ }
88
+ }
89
+ mkdirSync(dir, { recursive: true });
90
+ const dest = join(dir, id !== undefined ? `${id}.json` : resultFileName(r));
91
+ const tmp = `${dest}.${process.pid}.tmp`;
92
+ writeFileSync(tmp, JSON.stringify(r, null, 2) + '\n', { mode: 0o600 });
93
+ renameSync(tmp, dest);
94
+ return dest;
95
+ }
96
+ /** Every parseable result with its id. Ids come from the directory listing, never from input. */
97
+ export function readResultEntries(repoRoot) {
98
+ const dir = resolve(repoRoot, RESULTS_DIR);
99
+ let files;
100
+ try {
101
+ files = readdirSync(dir).filter((f) => f.endsWith('.json'));
102
+ }
103
+ catch {
104
+ return [];
105
+ }
106
+ const out = [];
107
+ for (const f of files) {
108
+ try {
109
+ const r = JSON.parse(readFileSync(join(dir, f), 'utf8'));
110
+ if (r && r.schema_version === RESULT_SCHEMA_VERSION)
111
+ out.push({ id: f.slice(0, -'.json'.length), result: r });
112
+ }
113
+ catch { /* skip */ }
114
+ }
115
+ return out;
116
+ }
117
+ /** Reads every parseable result file. Unparseable files are ignored, not fatal. */
118
+ export function readResults(repoRoot) {
119
+ return readResultEntries(repoRoot).map((e) => e.result);
120
+ }
121
+ export function countBySeverity(findings) {
122
+ const c = { high: 0, medium: 0, low: 0 };
123
+ for (const f of findings)
124
+ c[f.severity]++;
125
+ return c;
126
+ }
127
+ //# sourceMappingURL=results.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"results.js","sourceRoot":"","sources":["../../../src/codewatch/results.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type ReviewerAdapter } from './types.js';
2
+ /**
3
+ * Claude Code headless review (`claude -p --output-format json`).
4
+ *
5
+ * The rules and the diff go in the prompt on stdin (no argv length limit, no
6
+ * file outside the working dir to grant access to). Needs no kiro-cli.
7
+ */
8
+ export declare const claudeAdapter: ReviewerAdapter;
9
+ //# sourceMappingURL=claude.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../../../../src/codewatch/reviewers/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuD,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAMvG;;;;;GAKG;AACH,eAAO,MAAM,aAAa,EAAE,eAiC3B,CAAC"}
@@ -0,0 +1,48 @@
1
+ import { extractReviewJson, normalizeReview, OUTPUT_CONTRACT } from './types.js';
2
+ /** Read-only tools: the reviewer may look at surrounding code, never change it or run anything. */
3
+ const ALLOWED_TOOLS = ['Read', 'Grep', 'Glob'];
4
+ const DISALLOWED_TOOLS = ['Bash', 'Edit', 'Write', 'NotebookEdit', 'WebFetch', 'WebSearch', 'Task'];
5
+ /**
6
+ * Claude Code headless review (`claude -p --output-format json`).
7
+ *
8
+ * The rules and the diff go in the prompt on stdin (no argv length limit, no
9
+ * file outside the working dir to grant access to). Needs no kiro-cli.
10
+ */
11
+ export const claudeAdapter = {
12
+ id: 'claude',
13
+ binary: 'claude',
14
+ displayName: 'Claude Code',
15
+ invocation(req) {
16
+ const args = [
17
+ '-p',
18
+ '--output-format', 'json',
19
+ '--allowed-tools', ALLOWED_TOOLS.join(','),
20
+ '--disallowed-tools', DISALLOWED_TOOLS.join(','),
21
+ ];
22
+ if (req.model)
23
+ args.push('--model', req.model);
24
+ const input = 'You are a code reviewer. Review ONLY the changes in the diff below, for code quality and security, ' +
25
+ 'against these rules. You may read files in the repository for context but must not modify anything.\n\n' +
26
+ `<rules>\n${req.rulesText}\n</rules>\n\n<diff>\n${req.diff}\n</diff>\n\n${OUTPUT_CONTRACT}`;
27
+ return { args, input };
28
+ },
29
+ parse(stdout) {
30
+ // Envelope: {"type":"result","is_error":false,"result":"<text>","modelUsage":{"<model>":{...}},...}
31
+ let env;
32
+ try {
33
+ env = JSON.parse(stdout.trim());
34
+ }
35
+ catch {
36
+ throw new Error('Claude Code output is not JSON (expected --output-format json)');
37
+ }
38
+ if (env?.is_error)
39
+ throw new Error(`Claude Code reported an error: ${String(env.result ?? env.subtype ?? 'unknown').slice(0, 300)}`);
40
+ if (typeof env?.result !== 'string')
41
+ throw new Error('Claude Code JSON has no "result" text');
42
+ const models = env.modelUsage && typeof env.modelUsage === 'object' ? Object.keys(env.modelUsage) : [];
43
+ // modelUsage can list a small helper model too; the one with the most output tokens did the review.
44
+ models.sort((a, b) => (env.modelUsage[b]?.outputTokens ?? 0) - (env.modelUsage[a]?.outputTokens ?? 0));
45
+ return normalizeReview(extractReviewJson(env.result), models[0] ?? null);
46
+ },
47
+ };
48
+ //# sourceMappingURL=claude.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude.js","sourceRoot":"","sources":["../../../../src/codewatch/reviewers/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAwB,MAAM,YAAY,CAAC;AAEvG,mGAAmG;AACnG,MAAM,aAAa,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC/C,MAAM,gBAAgB,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;AAEpG;;;;;GAKG;AACH,MAAM,CAAC,MAAM,aAAa,GAAoB;IAC5C,EAAE,EAAE,QAAQ;IACZ,MAAM,EAAE,QAAQ;IAChB,WAAW,EAAE,aAAa;IAC1B,UAAU,CAAC,GAAG;QACZ,MAAM,IAAI,GAAG;YACX,IAAI;YACJ,iBAAiB,EAAE,MAAM;YACzB,iBAAiB,EAAE,aAAa,CAAC,IAAI,CAAC,GAAG,CAAC;YAC1C,oBAAoB,EAAE,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC;SACjD,CAAC;QACF,IAAI,GAAG,CAAC,KAAK;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/C,MAAM,KAAK,GACT,qGAAqG;YACrG,yGAAyG;YACzG,YAAY,GAAG,CAAC,SAAS,yBAAyB,GAAG,CAAC,IAAI,gBAAgB,eAAe,EAAE,CAAC;QAC9F,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC;IACD,KAAK,CAAC,MAAM;QACV,oGAAoG;QACpG,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,KAAK,CAAC,gEAAgE,CAAC,CAAC;QACpF,CAAC;QACD,IAAI,GAAG,EAAE,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,MAAM,CAAC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,SAAS,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACrI,IAAI,OAAO,GAAG,EAAE,MAAM,KAAK,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC9F,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,IAAI,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACvG,oGAAoG;QACpG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,YAAY,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC;QACvG,OAAO,eAAe,CAAC,iBAAiB,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;IAC3E,CAAC;CACF,CAAC"}
@@ -0,0 +1,39 @@
1
+ import { type ParsedReview, type ReviewerAdapter, type ReviewerId, type ReviewRequest } from './types.js';
2
+ export * from './types.js';
3
+ export declare const ADAPTERS: Record<ReviewerId, ReviewerAdapter>;
4
+ export { findOnPath, toolVersion } from '../../utils/tool-check.js';
5
+ /** Reviewer tools present on PATH, in REVIEWER_IDS order. */
6
+ export declare function detectReviewers(pathEnv?: string | undefined): ReviewerId[];
7
+ export interface ReviewerChoice {
8
+ /** The reviewer to run, or null when none is available. */
9
+ id: ReviewerId | null;
10
+ /** Where the choice came from. */
11
+ source: 'git-config' | 'prism-config' | 'detected' | 'fallback' | 'none';
12
+ /** Set when the configured reviewer was not available and another was used. */
13
+ note: string | null;
14
+ }
15
+ /**
16
+ * Precedence: `git config prism.reviewer` (per-clone developer override), then
17
+ * `.prism/config.json` eval.reviewer (team default), then whatever is on PATH.
18
+ *
19
+ * If the chosen tool is not installed, another installed one is used and the
20
+ * substitution is noted, so a Claude Code user on a team that defaults to kiro
21
+ * still gets a review without installing kiro-cli.
22
+ */
23
+ export declare function resolveReviewer(opts: {
24
+ gitConfigValue: string | null;
25
+ prismConfigValue: string | null | undefined;
26
+ available: ReviewerId[];
27
+ }): ReviewerChoice;
28
+ export interface ReviewRun {
29
+ ok: boolean;
30
+ review: ParsedReview | null;
31
+ error: string | null;
32
+ rawStdout: string;
33
+ }
34
+ /**
35
+ * Runs one adapter and parses its output. Never throws: a missing binary, a
36
+ * timeout, a non-zero exit and unparseable output all come back as ok:false.
37
+ */
38
+ export declare function runReview(adapter: ReviewerAdapter, req: ReviewRequest, timeoutMs: number, binaryPath?: string): ReviewRun;
39
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/codewatch/reviewers/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAA8B,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,KAAK,UAAU,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAEtI,cAAc,YAAY,CAAC;AAE3B,eAAO,MAAM,QAAQ,EAAE,MAAM,CAAC,UAAU,EAAE,eAAe,CAGxD,CAAC;AAEF,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAEpE,6DAA6D;AAC7D,wBAAgB,eAAe,CAAC,OAAO,GAAE,MAAM,GAAG,SAA4B,GAAG,UAAU,EAAE,CAE5F;AAED,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,EAAE,EAAE,UAAU,GAAG,IAAI,CAAC;IACtB,kCAAkC;IAClC,MAAM,EAAE,YAAY,GAAG,cAAc,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;IACzE,+EAA+E;IAC/E,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE;IACpC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC5C,SAAS,EAAE,UAAU,EAAE,CAAC;CACzB,GAAG,cAAc,CAuBjB;AAKD,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,OAAO,CAAC;IACZ,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,eAAe,EAAE,GAAG,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAgCzH"}
@@ -0,0 +1,97 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { findOnPath } from '../../utils/tool-check.js';
3
+ import { claudeAdapter } from './claude.js';
4
+ import { kiroAdapter } from './kiro.js';
5
+ import { isReviewerId, REVIEWER_IDS } from './types.js';
6
+ export * from './types.js';
7
+ export const ADAPTERS = {
8
+ kiro: kiroAdapter,
9
+ claude: claudeAdapter,
10
+ };
11
+ export { findOnPath, toolVersion } from '../../utils/tool-check.js';
12
+ /** Reviewer tools present on PATH, in REVIEWER_IDS order. */
13
+ export function detectReviewers(pathEnv = process.env.PATH) {
14
+ return REVIEWER_IDS.filter((id) => findOnPath(ADAPTERS[id].binary, pathEnv) !== null);
15
+ }
16
+ /**
17
+ * Precedence: `git config prism.reviewer` (per-clone developer override), then
18
+ * `.prism/config.json` eval.reviewer (team default), then whatever is on PATH.
19
+ *
20
+ * If the chosen tool is not installed, another installed one is used and the
21
+ * substitution is noted, so a Claude Code user on a team that defaults to kiro
22
+ * still gets a review without installing kiro-cli.
23
+ */
24
+ export function resolveReviewer(opts) {
25
+ const { gitConfigValue, prismConfigValue, available } = opts;
26
+ let wanted = null;
27
+ let source = 'detected';
28
+ let note = null;
29
+ if (gitConfigValue) {
30
+ if (isReviewerId(gitConfigValue)) {
31
+ wanted = gitConfigValue;
32
+ source = 'git-config';
33
+ }
34
+ else
35
+ note = `ignored git config prism.reviewer="${gitConfigValue}" (expected ${REVIEWER_IDS.join(' or ')})`;
36
+ }
37
+ if (!wanted && prismConfigValue) {
38
+ if (isReviewerId(prismConfigValue)) {
39
+ wanted = prismConfigValue;
40
+ source = 'prism-config';
41
+ }
42
+ else
43
+ note = `ignored eval.reviewer="${prismConfigValue}" in .prism/config.json`;
44
+ }
45
+ if (wanted && available.includes(wanted))
46
+ return { id: wanted, source, note };
47
+ if (available.length === 0) {
48
+ return { id: null, source: 'none', note: wanted ? `${ADAPTERS[wanted].binary} is not on PATH` : 'neither kiro-cli nor claude is on PATH' };
49
+ }
50
+ if (wanted) {
51
+ return { id: available[0], source: 'fallback', note: `${ADAPTERS[wanted].binary} is not on PATH; used ${ADAPTERS[available[0]].binary} instead` };
52
+ }
53
+ return { id: available[0], source: 'detected', note };
54
+ }
55
+ /** Git sets these for hooks; a reviewer that shells out to git must not inherit them. */
56
+ const GIT_HOOK_ENV = ['GIT_DIR', 'GIT_INDEX_FILE', 'GIT_WORK_TREE', 'GIT_PREFIX', 'GIT_OBJECT_DIRECTORY', 'GIT_ALTERNATE_OBJECT_DIRECTORIES'];
57
+ /**
58
+ * Runs one adapter and parses its output. Never throws: a missing binary, a
59
+ * timeout, a non-zero exit and unparseable output all come back as ok:false.
60
+ */
61
+ export function runReview(adapter, req, timeoutMs, binaryPath) {
62
+ const env = { ...process.env };
63
+ for (const k of GIT_HOOK_ENV)
64
+ delete env[k];
65
+ let inv;
66
+ try {
67
+ inv = adapter.invocation(req);
68
+ }
69
+ catch (e) {
70
+ return { ok: false, review: null, error: `could not build invocation: ${e.message}`, rawStdout: '' };
71
+ }
72
+ const res = spawnSync(binaryPath || adapter.binary, inv.args, {
73
+ cwd: req.repoRoot,
74
+ input: inv.input ?? '',
75
+ encoding: 'utf8',
76
+ env,
77
+ timeout: timeoutMs,
78
+ maxBuffer: 32 * 1024 * 1024,
79
+ stdio: ['pipe', 'pipe', 'pipe'],
80
+ });
81
+ const stdout = res.stdout || '';
82
+ if (res.error) {
83
+ const msg = res.error.code === 'ETIMEDOUT'
84
+ ? `${adapter.binary} timed out after ${Math.round(timeoutMs / 1000)}s`
85
+ : `${adapter.binary} failed to start: ${res.error.message}`;
86
+ return { ok: false, review: null, error: msg, rawStdout: stdout };
87
+ }
88
+ try {
89
+ const review = adapter.parse(stdout);
90
+ return { ok: true, review, error: null, rawStdout: stdout };
91
+ }
92
+ catch (e) {
93
+ const exit = res.status !== 0 ? ` (exit ${res.status}${res.stderr ? `: ${res.stderr.trim().slice(0, 200)}` : ''})` : '';
94
+ return { ok: false, review: null, error: `${e.message}${exit}`, rawStdout: stdout };
95
+ }
96
+ }
97
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/codewatch/reviewers/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type ReviewerAdapter } from './types.js';
2
+ /**
3
+ * kiro-cli headless review.
4
+ *
5
+ * Same shape as the CI gate (prism-eval-gate.yml): a short argv prompt that
6
+ * points kiro at files on disk, because kiro-cli has had a bug putting long
7
+ * stdin into HTTP headers. The rule set is passed as context by path -- kiro
8
+ * reads it with fs_read before reviewing.
9
+ *
10
+ * Only fs_read is trusted (`--trust-tools=fs_read`), so in --no-interactive
11
+ * mode any write or shell tool call is refused rather than run.
12
+ */
13
+ export declare const kiroAdapter: ReviewerAdapter;
14
+ //# sourceMappingURL=kiro.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kiro.d.ts","sourceRoot":"","sources":["../../../../src/codewatch/reviewers/kiro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAkE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AAElH;;;;;;;;;;GAUG;AACH,eAAO,MAAM,WAAW,EAAE,eAmBzB,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { extractReviewJson, normalizeReview, OUTPUT_CONTRACT, stripAnsi } from './types.js';
2
+ /**
3
+ * kiro-cli headless review.
4
+ *
5
+ * Same shape as the CI gate (prism-eval-gate.yml): a short argv prompt that
6
+ * points kiro at files on disk, because kiro-cli has had a bug putting long
7
+ * stdin into HTTP headers. The rule set is passed as context by path -- kiro
8
+ * reads it with fs_read before reviewing.
9
+ *
10
+ * Only fs_read is trusted (`--trust-tools=fs_read`), so in --no-interactive
11
+ * mode any write or shell tool call is refused rather than run.
12
+ */
13
+ export const kiroAdapter = {
14
+ id: 'kiro',
15
+ binary: 'kiro-cli',
16
+ displayName: 'kiro-cli',
17
+ invocation(req) {
18
+ const prompt = `You are a code reviewer. First read the review rules in ${req.rulesPath} and follow them. ` +
19
+ `Then read the diff at ${req.diffPath} and review only the changes it introduces, for code quality and security. ` +
20
+ OUTPUT_CONTRACT;
21
+ return {
22
+ args: ['chat', '--no-interactive', '--trust-tools=fs_read', '--model', req.model || 'auto', prompt],
23
+ };
24
+ },
25
+ parse(stdout) {
26
+ const text = stripAnsi(stdout);
27
+ // kiro-cli prints no machine-readable model; leave it to the caller's
28
+ // requested model.
29
+ return normalizeReview(extractReviewJson(text), null);
30
+ },
31
+ };
32
+ //# sourceMappingURL=kiro.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kiro.js","sourceRoot":"","sources":["../../../../src/codewatch/reviewers/kiro.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,eAAe,EAAE,SAAS,EAAwB,MAAM,YAAY,CAAC;AAElH;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,WAAW,GAAoB;IAC1C,EAAE,EAAE,MAAM;IACV,MAAM,EAAE,UAAU;IAClB,WAAW,EAAE,UAAU;IACvB,UAAU,CAAC,GAAG;QACZ,MAAM,MAAM,GACV,2DAA2D,GAAG,CAAC,SAAS,oBAAoB;YAC5F,yBAAyB,GAAG,CAAC,QAAQ,6EAA6E;YAClH,eAAe,CAAC;QAClB,OAAO;YACL,IAAI,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,SAAS,EAAE,GAAG,CAAC,KAAK,IAAI,MAAM,EAAE,MAAM,CAAC;SACpG,CAAC;IACJ,CAAC;IACD,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC;QAC/B,sEAAsE;QACtE,mBAAmB;QACnB,OAAO,eAAe,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC;IACxD,CAAC;CACF,CAAC"}