@coldtea/abide 0.0.1

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 (370) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +10 -0
  3. package/dist/abide-hook.d.ts +2 -0
  4. package/dist/abide-hook.d.ts.map +1 -0
  5. package/dist/abide-hook.js +23 -0
  6. package/dist/abide-hook.js.map +1 -0
  7. package/dist/bin.d.ts +3 -0
  8. package/dist/bin.d.ts.map +1 -0
  9. package/dist/bin.js +64 -0
  10. package/dist/bin.js.map +1 -0
  11. package/dist/commands/audit.d.ts +3 -0
  12. package/dist/commands/audit.d.ts.map +1 -0
  13. package/dist/commands/audit.js +79 -0
  14. package/dist/commands/audit.js.map +1 -0
  15. package/dist/commands/bench.d.ts +3 -0
  16. package/dist/commands/bench.d.ts.map +1 -0
  17. package/dist/commands/bench.js +206 -0
  18. package/dist/commands/bench.js.map +1 -0
  19. package/dist/commands/calibrate.d.ts +3 -0
  20. package/dist/commands/calibrate.d.ts.map +1 -0
  21. package/dist/commands/calibrate.js +159 -0
  22. package/dist/commands/calibrate.js.map +1 -0
  23. package/dist/commands/check.d.ts +3 -0
  24. package/dist/commands/check.d.ts.map +1 -0
  25. package/dist/commands/check.js +106 -0
  26. package/dist/commands/check.js.map +1 -0
  27. package/dist/commands/compile.d.ts +3 -0
  28. package/dist/commands/compile.d.ts.map +1 -0
  29. package/dist/commands/compile.js +116 -0
  30. package/dist/commands/compile.js.map +1 -0
  31. package/dist/commands/init.d.ts +4 -0
  32. package/dist/commands/init.d.ts.map +1 -0
  33. package/dist/commands/init.js +93 -0
  34. package/dist/commands/init.js.map +1 -0
  35. package/dist/commands/login.d.ts +3 -0
  36. package/dist/commands/login.d.ts.map +1 -0
  37. package/dist/commands/login.js +58 -0
  38. package/dist/commands/login.js.map +1 -0
  39. package/dist/commands/replay.d.ts +4 -0
  40. package/dist/commands/replay.d.ts.map +1 -0
  41. package/dist/commands/replay.js +118 -0
  42. package/dist/commands/replay.js.map +1 -0
  43. package/dist/commands/report.d.ts +5 -0
  44. package/dist/commands/report.d.ts.map +1 -0
  45. package/dist/commands/report.js +78 -0
  46. package/dist/commands/report.js.map +1 -0
  47. package/dist/commands/rubric.d.ts +3 -0
  48. package/dist/commands/rubric.d.ts.map +1 -0
  49. package/dist/commands/rubric.js +40 -0
  50. package/dist/commands/rubric.js.map +1 -0
  51. package/dist/commands/uninstall.d.ts +2 -0
  52. package/dist/commands/uninstall.d.ts.map +1 -0
  53. package/dist/commands/uninstall.js +31 -0
  54. package/dist/commands/uninstall.js.map +1 -0
  55. package/dist/hooks/postToolUse.d.ts +3 -0
  56. package/dist/hooks/postToolUse.d.ts.map +1 -0
  57. package/dist/hooks/postToolUse.js +145 -0
  58. package/dist/hooks/postToolUse.js.map +1 -0
  59. package/dist/hooks/sessionStart.d.ts +11 -0
  60. package/dist/hooks/sessionStart.d.ts.map +1 -0
  61. package/dist/hooks/sessionStart.js +83 -0
  62. package/dist/hooks/sessionStart.js.map +1 -0
  63. package/dist/hooks/stop.d.ts +26 -0
  64. package/dist/hooks/stop.d.ts.map +1 -0
  65. package/dist/hooks/stop.js +227 -0
  66. package/dist/hooks/stop.js.map +1 -0
  67. package/dist/hooks/turnStart.d.ts +8 -0
  68. package/dist/hooks/turnStart.d.ts.map +1 -0
  69. package/dist/hooks/turnStart.js +40 -0
  70. package/dist/hooks/turnStart.js.map +1 -0
  71. package/dist/lib/applyPatch.d.ts +22 -0
  72. package/dist/lib/applyPatch.d.ts.map +1 -0
  73. package/dist/lib/applyPatch.js +63 -0
  74. package/dist/lib/applyPatch.js.map +1 -0
  75. package/dist/lib/audit.d.ts +40 -0
  76. package/dist/lib/audit.d.ts.map +1 -0
  77. package/dist/lib/audit.js +215 -0
  78. package/dist/lib/audit.js.map +1 -0
  79. package/dist/lib/band.d.ts +20 -0
  80. package/dist/lib/band.d.ts.map +1 -0
  81. package/dist/lib/band.js +40 -0
  82. package/dist/lib/band.js.map +1 -0
  83. package/dist/lib/calibration.d.ts +13 -0
  84. package/dist/lib/calibration.d.ts.map +1 -0
  85. package/dist/lib/calibration.js +25 -0
  86. package/dist/lib/calibration.js.map +1 -0
  87. package/dist/lib/checkRunner.d.ts +34 -0
  88. package/dist/lib/checkRunner.d.ts.map +1 -0
  89. package/dist/lib/checkRunner.js +76 -0
  90. package/dist/lib/checkRunner.js.map +1 -0
  91. package/dist/lib/claude.d.ts +4 -0
  92. package/dist/lib/claude.d.ts.map +1 -0
  93. package/dist/lib/claude.js +28 -0
  94. package/dist/lib/claude.js.map +1 -0
  95. package/dist/lib/compilePrompt.d.ts +22 -0
  96. package/dist/lib/compilePrompt.d.ts.map +1 -0
  97. package/dist/lib/compilePrompt.js +33 -0
  98. package/dist/lib/compilePrompt.js.map +1 -0
  99. package/dist/lib/constants.d.ts +33 -0
  100. package/dist/lib/constants.d.ts.map +1 -0
  101. package/dist/lib/constants.js +33 -0
  102. package/dist/lib/constants.js.map +1 -0
  103. package/dist/lib/coverage.d.ts +7 -0
  104. package/dist/lib/coverage.d.ts.map +1 -0
  105. package/dist/lib/coverage.js +17 -0
  106. package/dist/lib/coverage.js.map +1 -0
  107. package/dist/lib/credentials.d.ts +27 -0
  108. package/dist/lib/credentials.d.ts.map +1 -0
  109. package/dist/lib/credentials.js +89 -0
  110. package/dist/lib/credentials.js.map +1 -0
  111. package/dist/lib/diff.d.ts +30 -0
  112. package/dist/lib/diff.d.ts.map +1 -0
  113. package/dist/lib/diff.js +139 -0
  114. package/dist/lib/diff.js.map +1 -0
  115. package/dist/lib/events.d.ts +5 -0
  116. package/dist/lib/events.d.ts.map +1 -0
  117. package/dist/lib/events.js +38 -0
  118. package/dist/lib/events.js.map +1 -0
  119. package/dist/lib/git.d.ts +37 -0
  120. package/dist/lib/git.d.ts.map +1 -0
  121. package/dist/lib/git.js +163 -0
  122. package/dist/lib/git.js.map +1 -0
  123. package/dist/lib/hookRunner.d.ts +10 -0
  124. package/dist/lib/hookRunner.d.ts.map +1 -0
  125. package/dist/lib/hookRunner.js +52 -0
  126. package/dist/lib/hookRunner.js.map +1 -0
  127. package/dist/lib/hosts.d.ts +20 -0
  128. package/dist/lib/hosts.d.ts.map +1 -0
  129. package/dist/lib/hosts.js +101 -0
  130. package/dist/lib/hosts.js.map +1 -0
  131. package/dist/lib/jev.d.ts +24 -0
  132. package/dist/lib/jev.d.ts.map +1 -0
  133. package/dist/lib/jev.js +169 -0
  134. package/dist/lib/jev.js.map +1 -0
  135. package/dist/lib/lintConfig.d.ts +3 -0
  136. package/dist/lib/lintConfig.d.ts.map +1 -0
  137. package/dist/lib/lintConfig.js +55 -0
  138. package/dist/lib/lintConfig.js.map +1 -0
  139. package/dist/lib/loadRules.d.ts +12 -0
  140. package/dist/lib/loadRules.d.ts.map +1 -0
  141. package/dist/lib/loadRules.js +31 -0
  142. package/dist/lib/loadRules.js.map +1 -0
  143. package/dist/lib/opencodePlugin.d.ts +10 -0
  144. package/dist/lib/opencodePlugin.d.ts.map +1 -0
  145. package/dist/lib/opencodePlugin.js +36 -0
  146. package/dist/lib/opencodePlugin.js.map +1 -0
  147. package/dist/lib/output.d.ts +6 -0
  148. package/dist/lib/output.d.ts.map +1 -0
  149. package/dist/lib/output.js +35 -0
  150. package/dist/lib/output.js.map +1 -0
  151. package/dist/lib/packageRoot.d.ts +12 -0
  152. package/dist/lib/packageRoot.d.ts.map +1 -0
  153. package/dist/lib/packageRoot.js +50 -0
  154. package/dist/lib/packageRoot.js.map +1 -0
  155. package/dist/lib/paths.d.ts +24 -0
  156. package/dist/lib/paths.d.ts.map +1 -0
  157. package/dist/lib/paths.js +75 -0
  158. package/dist/lib/paths.js.map +1 -0
  159. package/dist/lib/reason.d.ts +11 -0
  160. package/dist/lib/reason.d.ts.map +1 -0
  161. package/dist/lib/reason.js +31 -0
  162. package/dist/lib/reason.js.map +1 -0
  163. package/dist/lib/regularFile.d.ts +26 -0
  164. package/dist/lib/regularFile.d.ts.map +1 -0
  165. package/dist/lib/regularFile.js +77 -0
  166. package/dist/lib/regularFile.js.map +1 -0
  167. package/dist/lib/replay.d.ts +74 -0
  168. package/dist/lib/replay.d.ts.map +1 -0
  169. package/dist/lib/replay.js +250 -0
  170. package/dist/lib/replay.js.map +1 -0
  171. package/dist/lib/replayCodex.d.ts +6 -0
  172. package/dist/lib/replayCodex.d.ts.map +1 -0
  173. package/dist/lib/replayCodex.js +132 -0
  174. package/dist/lib/replayCodex.js.map +1 -0
  175. package/dist/lib/replayOpencode.d.ts +15 -0
  176. package/dist/lib/replayOpencode.d.ts.map +1 -0
  177. package/dist/lib/replayOpencode.js +154 -0
  178. package/dist/lib/replayOpencode.js.map +1 -0
  179. package/dist/lib/rubricFile.d.ts +31 -0
  180. package/dist/lib/rubricFile.d.ts.map +1 -0
  181. package/dist/lib/rubricFile.js +75 -0
  182. package/dist/lib/rubricFile.js.map +1 -0
  183. package/dist/lib/scope.d.ts +4 -0
  184. package/dist/lib/scope.d.ts.map +1 -0
  185. package/dist/lib/scope.js +14 -0
  186. package/dist/lib/scope.js.map +1 -0
  187. package/dist/lib/session.d.ts +48 -0
  188. package/dist/lib/session.d.ts.map +1 -0
  189. package/dist/lib/session.js +182 -0
  190. package/dist/lib/session.js.map +1 -0
  191. package/dist/lib/settings.d.ts +26 -0
  192. package/dist/lib/settings.d.ts.map +1 -0
  193. package/dist/lib/settings.js +104 -0
  194. package/dist/lib/settings.js.map +1 -0
  195. package/dist/lib/sources.d.ts +28 -0
  196. package/dist/lib/sources.d.ts.map +1 -0
  197. package/dist/lib/sources.js +137 -0
  198. package/dist/lib/sources.js.map +1 -0
  199. package/dist/lib/stdin.d.ts +3 -0
  200. package/dist/lib/stdin.d.ts.map +1 -0
  201. package/dist/lib/stdin.js +24 -0
  202. package/dist/lib/stdin.js.map +1 -0
  203. package/dist/lib/transcript.d.ts +3 -0
  204. package/dist/lib/transcript.d.ts.map +1 -0
  205. package/dist/lib/transcript.js +57 -0
  206. package/dist/lib/transcript.js.map +1 -0
  207. package/dist/lib/ui.d.ts +8 -0
  208. package/dist/lib/ui.d.ts.map +1 -0
  209. package/dist/lib/ui.js +34 -0
  210. package/dist/lib/ui.js.map +1 -0
  211. package/dist/ui/components/Buckets.d.ts +6 -0
  212. package/dist/ui/components/Buckets.d.ts.map +1 -0
  213. package/dist/ui/components/Buckets.js +11 -0
  214. package/dist/ui/components/Buckets.js.map +1 -0
  215. package/dist/ui/components/Callout.d.ts +11 -0
  216. package/dist/ui/components/Callout.d.ts.map +1 -0
  217. package/dist/ui/components/Callout.js +10 -0
  218. package/dist/ui/components/Callout.js.map +1 -0
  219. package/dist/ui/components/Checklist.d.ts +10 -0
  220. package/dist/ui/components/Checklist.d.ts.map +1 -0
  221. package/dist/ui/components/Checklist.js +8 -0
  222. package/dist/ui/components/Checklist.js.map +1 -0
  223. package/dist/ui/components/Columns.d.ts +28 -0
  224. package/dist/ui/components/Columns.d.ts.map +1 -0
  225. package/dist/ui/components/Columns.js +20 -0
  226. package/dist/ui/components/Columns.js.map +1 -0
  227. package/dist/ui/components/Header.d.ts +9 -0
  228. package/dist/ui/components/Header.d.ts.map +1 -0
  229. package/dist/ui/components/Header.js +7 -0
  230. package/dist/ui/components/Header.js.map +1 -0
  231. package/dist/ui/components/Live.d.ts +16 -0
  232. package/dist/ui/components/Live.d.ts.map +1 -0
  233. package/dist/ui/components/Live.js +40 -0
  234. package/dist/ui/components/Live.js.map +1 -0
  235. package/dist/ui/components/RuleTable.d.ts +15 -0
  236. package/dist/ui/components/RuleTable.d.ts.map +1 -0
  237. package/dist/ui/components/RuleTable.js +81 -0
  238. package/dist/ui/components/RuleTable.js.map +1 -0
  239. package/dist/ui/components/Section.d.ts +10 -0
  240. package/dist/ui/components/Section.d.ts.map +1 -0
  241. package/dist/ui/components/Section.js +8 -0
  242. package/dist/ui/components/Section.js.map +1 -0
  243. package/dist/ui/components/Verdicts.d.ts +9 -0
  244. package/dist/ui/components/Verdicts.d.ts.map +1 -0
  245. package/dist/ui/components/Verdicts.js +12 -0
  246. package/dist/ui/components/Verdicts.js.map +1 -0
  247. package/dist/ui/render.d.ts +20 -0
  248. package/dist/ui/render.d.ts.map +1 -0
  249. package/dist/ui/render.js +32 -0
  250. package/dist/ui/render.js.map +1 -0
  251. package/dist/ui/theme.d.ts +37 -0
  252. package/dist/ui/theme.d.ts.map +1 -0
  253. package/dist/ui/theme.js +63 -0
  254. package/dist/ui/theme.js.map +1 -0
  255. package/dist/ui/views/AuditView.d.ts +18 -0
  256. package/dist/ui/views/AuditView.d.ts.map +1 -0
  257. package/dist/ui/views/AuditView.js +48 -0
  258. package/dist/ui/views/AuditView.js.map +1 -0
  259. package/dist/ui/views/BenchView.d.ts +33 -0
  260. package/dist/ui/views/BenchView.d.ts.map +1 -0
  261. package/dist/ui/views/BenchView.js +19 -0
  262. package/dist/ui/views/BenchView.js.map +1 -0
  263. package/dist/ui/views/CalibrateView.d.ts +26 -0
  264. package/dist/ui/views/CalibrateView.d.ts.map +1 -0
  265. package/dist/ui/views/CalibrateView.js +42 -0
  266. package/dist/ui/views/CalibrateView.js.map +1 -0
  267. package/dist/ui/views/CheckView.d.ts +19 -0
  268. package/dist/ui/views/CheckView.d.ts.map +1 -0
  269. package/dist/ui/views/CheckView.js +15 -0
  270. package/dist/ui/views/CheckView.js.map +1 -0
  271. package/dist/ui/views/ErrorView.d.ts +4 -0
  272. package/dist/ui/views/ErrorView.d.ts.map +1 -0
  273. package/dist/ui/views/ErrorView.js +26 -0
  274. package/dist/ui/views/ErrorView.js.map +1 -0
  275. package/dist/ui/views/HelpView.d.ts +2 -0
  276. package/dist/ui/views/HelpView.d.ts.map +1 -0
  277. package/dist/ui/views/HelpView.js +25 -0
  278. package/dist/ui/views/HelpView.js.map +1 -0
  279. package/dist/ui/views/InitView.d.ts +27 -0
  280. package/dist/ui/views/InitView.d.ts.map +1 -0
  281. package/dist/ui/views/InitView.js +24 -0
  282. package/dist/ui/views/InitView.js.map +1 -0
  283. package/dist/ui/views/ReplayView.d.ts +16 -0
  284. package/dist/ui/views/ReplayView.d.ts.map +1 -0
  285. package/dist/ui/views/ReplayView.js +44 -0
  286. package/dist/ui/views/ReplayView.js.map +1 -0
  287. package/dist/ui/views/ReportView.d.ts +14 -0
  288. package/dist/ui/views/ReportView.d.ts.map +1 -0
  289. package/dist/ui/views/ReportView.js +86 -0
  290. package/dist/ui/views/ReportView.js.map +1 -0
  291. package/dist/ui/views/RubricView.d.ts +18 -0
  292. package/dist/ui/views/RubricView.d.ts.map +1 -0
  293. package/dist/ui/views/RubricView.js +18 -0
  294. package/dist/ui/views/RubricView.js.map +1 -0
  295. package/opencode/abide.mjs +246 -0
  296. package/package.json +50 -0
  297. package/skills/abide-compile/SKILL.md +173 -0
  298. package/src/abide-hook.ts +23 -0
  299. package/src/bin.ts +64 -0
  300. package/src/commands/audit.ts +97 -0
  301. package/src/commands/bench.ts +226 -0
  302. package/src/commands/calibrate.ts +165 -0
  303. package/src/commands/check.ts +114 -0
  304. package/src/commands/compile.ts +127 -0
  305. package/src/commands/init.ts +109 -0
  306. package/src/commands/login.ts +61 -0
  307. package/src/commands/replay.ts +148 -0
  308. package/src/commands/report.ts +83 -0
  309. package/src/commands/rubric.ts +45 -0
  310. package/src/commands/uninstall.ts +33 -0
  311. package/src/hooks/postToolUse.ts +171 -0
  312. package/src/hooks/sessionStart.ts +100 -0
  313. package/src/hooks/stop.ts +275 -0
  314. package/src/hooks/turnStart.ts +36 -0
  315. package/src/lib/applyPatch.ts +75 -0
  316. package/src/lib/audit.ts +265 -0
  317. package/src/lib/band.ts +49 -0
  318. package/src/lib/calibration.ts +35 -0
  319. package/src/lib/checkRunner.ts +124 -0
  320. package/src/lib/claude.ts +35 -0
  321. package/src/lib/compilePrompt.ts +67 -0
  322. package/src/lib/constants.ts +39 -0
  323. package/src/lib/coverage.ts +21 -0
  324. package/src/lib/credentials.ts +104 -0
  325. package/src/lib/diff.ts +209 -0
  326. package/src/lib/events.ts +34 -0
  327. package/src/lib/git.ts +206 -0
  328. package/src/lib/hookRunner.ts +55 -0
  329. package/src/lib/hosts.ts +112 -0
  330. package/src/lib/jev.ts +223 -0
  331. package/src/lib/lintConfig.ts +53 -0
  332. package/src/lib/loadRules.ts +39 -0
  333. package/src/lib/opencodePlugin.ts +38 -0
  334. package/src/lib/output.ts +44 -0
  335. package/src/lib/packageRoot.ts +48 -0
  336. package/src/lib/paths.ts +96 -0
  337. package/src/lib/reason.ts +46 -0
  338. package/src/lib/regularFile.ts +96 -0
  339. package/src/lib/replay.ts +314 -0
  340. package/src/lib/replayCodex.ts +130 -0
  341. package/src/lib/replayOpencode.ts +186 -0
  342. package/src/lib/rubricFile.ts +99 -0
  343. package/src/lib/scope.ts +18 -0
  344. package/src/lib/session.ts +223 -0
  345. package/src/lib/settings.ts +112 -0
  346. package/src/lib/sources.ts +154 -0
  347. package/src/lib/stdin.ts +23 -0
  348. package/src/lib/transcript.ts +49 -0
  349. package/src/lib/ui.ts +38 -0
  350. package/src/ui/components/Buckets.tsx +30 -0
  351. package/src/ui/components/Callout.tsx +26 -0
  352. package/src/ui/components/Checklist.tsx +29 -0
  353. package/src/ui/components/Columns.tsx +62 -0
  354. package/src/ui/components/Header.tsx +35 -0
  355. package/src/ui/components/Live.tsx +73 -0
  356. package/src/ui/components/RuleTable.tsx +94 -0
  357. package/src/ui/components/Section.tsx +24 -0
  358. package/src/ui/components/Verdicts.tsx +40 -0
  359. package/src/ui/render.tsx +51 -0
  360. package/src/ui/theme.ts +65 -0
  361. package/src/ui/views/AuditView.tsx +140 -0
  362. package/src/ui/views/BenchView.tsx +87 -0
  363. package/src/ui/views/CalibrateView.tsx +108 -0
  364. package/src/ui/views/CheckView.tsx +56 -0
  365. package/src/ui/views/ErrorView.tsx +32 -0
  366. package/src/ui/views/HelpView.tsx +51 -0
  367. package/src/ui/views/InitView.tsx +103 -0
  368. package/src/ui/views/ReplayView.tsx +100 -0
  369. package/src/ui/views/ReportView.tsx +225 -0
  370. package/src/ui/views/RubricView.tsx +82 -0
@@ -0,0 +1,14 @@
1
+ import type { AbideEvent, Rule } from "@coldtea/abide-schema";
2
+ import { type RuleStats } from "../components/RuleTable.js";
3
+ export type ReportData = {
4
+ root: string;
5
+ rules: Rule[];
6
+ events: AbideEvent[];
7
+ stats: Map<string, RuleStats>;
8
+ dead: Rule[];
9
+ problems: string[];
10
+ };
11
+ export declare function ReportView({ data }: {
12
+ data: ReportData;
13
+ }): import("react").JSX.Element;
14
+ //# sourceMappingURL=ReportView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReportView.d.ts","sourceRoot":"","sources":["../../../src/ui/views/ReportView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAK9D,OAAO,EAAa,KAAK,SAAS,EAAE,MAAM,4BAA4B,CAAC;AAKvE,MAAM,MAAM,UAAU,GAAG;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC9B,IAAI,EAAE,IAAI,EAAE,CAAC;IACb,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAOF,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,+BAuMxD"}
@@ -0,0 +1,86 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { Buckets } from "../components/Buckets.js";
4
+ import { Callout } from "../components/Callout.js";
5
+ import { Columns } from "../components/Columns.js";
6
+ import { Header } from "../components/Header.js";
7
+ import { RuleTable } from "../components/RuleTable.js";
8
+ import { Section } from "../components/Section.js";
9
+ import { median, ms, usd } from "../../lib/ui.js";
10
+ import { glyph, palette } from "../theme.js";
11
+ const reasonOf = (rule) => rule.check.type === "deferred" || rule.check.type === "unenforceable" ? rule.check.reason : "";
12
+ export function ReportView({ data }) {
13
+ const checks = data.events.filter((e) => e.kind === "check");
14
+ const errors = data.events.filter((e) => e.kind === "error").length;
15
+ const edit = checks.filter((c) => c.phase === "edit");
16
+ const turn = checks.filter((c) => c.phase === "turn");
17
+ const spend = (list) => list.reduce((s, c) => s + (c.usage?.costUsd ?? 0), 0);
18
+ const stuck = data.rules.filter((r) => r.status === "weak" || r.status === "noisy");
19
+ const notRunning = [...stuck, ...data.dead];
20
+ const lintable = data.rules.flatMap((r) => r.check.type === "lint"
21
+ ? [
22
+ {
23
+ id: r.id,
24
+ how: r.check.how ?? `pattern: ${r.check.pattern ?? ""}`,
25
+ overlaps: r.check.overlaps,
26
+ },
27
+ ]
28
+ : []);
29
+ const deferred = data.rules.filter((r) => r.check.type === "deferred");
30
+ const unenforceable = data.rules.filter((r) => r.check.type === "unenforceable");
31
+ const quiet = data.rules.filter((r) => {
32
+ const s = data.stats.get(r.id);
33
+ return (r.status === "active" &&
34
+ r.check.type === "model" &&
35
+ s !== undefined &&
36
+ s.checks > 0 &&
37
+ s.fired === 0 &&
38
+ s.flagged === 0 &&
39
+ !data.dead.includes(r));
40
+ });
41
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { command: "report", where: data.root }), data.problems.map((p) => (_jsx(Callout, { tone: "warn", title: "A rubric could not be read and is being ignored", children: _jsx(Text, { color: palette.mist, children: p }) }, p))), _jsxs(Section, { title: "Rules", children: [_jsx(Buckets, { rules: data.rules }), _jsx(Box, { marginTop: 1, children: _jsx(RuleTable, { rules: data.rules, stats: checks.length > 0 ? data.stats : undefined, runnableOnly: true }) }), quiet.length > 0 ? (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: palette.ash, children: [quiet.length, " ", quiet.length === 1 ? "rule has" : "rules have", " answered no on every check so far, which is what a clear answer looks like."] }) })) : null] }), notRunning.length > 0 ? (_jsxs(Callout, { tone: "warn", title: `${notRunning.length} ${notRunning.length === 1 ? "rule is switched off or never answers" : "rules are switched off or never answer"}. Likely badly worded.`, children: [notRunning.map((r) => (_jsxs(Text, { color: palette.cloud, children: [r.id, _jsxs(Text, { color: palette.ash, children: [" ", r.status === "weak"
42
+ ? "weak, off"
43
+ : r.status === "noisy"
44
+ ? "noisy, off"
45
+ : "never fired or flagged", r.calibration ? ` ${glyph.dotSep} median ${r.calibration.median.toFixed(2)}` : ""] })] }, r.id))), _jsx(Text, { color: palette.mist, children: "Run abide tune to rewrite them." })] })) : null, lintable.length > 0 ? (_jsx(Section, { title: "For your linter", aside: `${lintable.length} ${lintable.length === 1 ? "rule" : "rules"} a linter enforces exactly. Abide does not run them.`, children: _jsx(Columns, { indent: 2, columns: [
46
+ { key: "id", label: "", width: 30 },
47
+ { key: "have", label: "", width: 16 },
48
+ { key: "how", label: "" },
49
+ ], rows: lintable.map((r) => ({
50
+ id: { text: r.id, color: palette.mist },
51
+ how: { text: r.how, color: palette.cloud },
52
+ have: r.overlaps
53
+ ? { text: `${glyph.check} configured`, color: palette.sage }
54
+ : { text: "not configured", color: palette.amber },
55
+ })) }) })) : null, deferred.length + unenforceable.length > 0 ? (_jsxs(Section, { title: "Not checked", aside: `${deferred.length} deferred ${glyph.dotSep} ${unenforceable.length} unenforceable`, children: [deferred.length > 0 ? (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: palette.ceramicWarm, children: "Need the rest of the repository, which a diff does not carry" }), _jsx(Columns, { indent: 2, columns: [
56
+ { key: "id", label: "", width: 30 },
57
+ { key: "why", label: "" },
58
+ ], rows: deferred.map((r) => ({
59
+ id: { text: r.id, color: palette.mist },
60
+ why: { text: reasonOf(r), color: palette.ash },
61
+ })) })] })) : null, unenforceable.length > 0 ? (_jsxs(Box, { flexDirection: "column", marginTop: deferred.length > 0 ? 1 : 0, children: [_jsx(Text, { color: palette.ash, children: "About the process or the conversation, not a change to a file" }), _jsxs(Text, { color: palette.ash, wrap: "wrap", children: [" ", unenforceable.map((r) => r.id).join(` ${glyph.dotSep} `)] })] })) : null] })) : null, _jsx(Section, { title: "Checks", aside: checks.length === 0 ? "none recorded yet" : `${checks.length} in .abide/events.jsonl`, children: checks.length === 0 ? (_jsx(Text, { color: palette.ash, children: "Every check the hooks run lands here: what fired, how long it took, what it cost." })) : (_jsxs(Box, { flexDirection: "column", children: [_jsx(Columns, { indent: 2, columns: [
62
+ { key: "phase", label: "", width: 6 },
63
+ { key: "checks", label: "checks", width: 7, align: "right" },
64
+ { key: "blocked", label: "blocked", width: 8, align: "right" },
65
+ { key: "latency", label: "median", width: 8, align: "right" },
66
+ { key: "spend", label: "spend", width: 10, align: "right" },
67
+ { key: "pad", label: "" },
68
+ ], rows: [edit, turn].map((list, i) => ({
69
+ phase: {
70
+ text: i === 0 ? "edit" : "turn",
71
+ color: i === 0 ? palette.mist : palette.plum,
72
+ },
73
+ checks: { text: String(list.length), color: palette.cloud },
74
+ blocked: {
75
+ text: String(list.filter((c) => c.blocked).length),
76
+ color: list.some((c) => c.blocked) ? palette.rose : palette.mist,
77
+ },
78
+ latency: {
79
+ text: list.length ? ms(median(list.map((c) => c.latencyMs)) ?? 0) : "",
80
+ color: palette.cloud,
81
+ },
82
+ spend: { text: usd(spend(list)), color: palette.ceramic },
83
+ pad: { text: "" },
84
+ })) }), errors > 0 ? (_jsx(Box, { marginTop: 1, children: _jsxs(Text, { color: palette.amber, children: [errors, " ", errors === 1 ? "check" : "checks", " failed or timed out. Those edits went unchecked."] }) })) : null] })) })] }));
85
+ }
86
+ //# sourceMappingURL=ReportView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReportView.js","sourceRoot":"","sources":["../../../src/ui/views/ReportView.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { Rule } from "@coldtea/abide-schema";
2
+ export type RubricData = {
3
+ kind: "invalid";
4
+ root: string;
5
+ file: string;
6
+ issues: string[];
7
+ } | {
8
+ kind: "ok";
9
+ root: string;
10
+ file: string;
11
+ rules: Rule[];
12
+ missing: string[];
13
+ orphaned: string[];
14
+ };
15
+ export declare function RubricView({ data }: {
16
+ data: RubricData;
17
+ }): import("react").JSX.Element;
18
+ //# sourceMappingURL=RubricView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RubricView.d.ts","sourceRoot":"","sources":["../../../src/ui/views/RubricView.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAQlD,MAAM,MAAM,UAAU,GAClB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,EAAE,CAAA;CAAE,GACjE;IACE,IAAI,EAAE,IAAI,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAAC;AAEN,wBAAgB,UAAU,CAAC,EAAE,IAAI,EAAE,EAAE;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,+BA6DxD"}
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import { Buckets } from "../components/Buckets.js";
4
+ import { Callout } from "../components/Callout.js";
5
+ import { Header } from "../components/Header.js";
6
+ import { RuleTable } from "../components/RuleTable.js";
7
+ import { Section } from "../components/Section.js";
8
+ import { glyph, palette } from "../theme.js";
9
+ export function RubricView({ data }) {
10
+ if (data.kind === "invalid") {
11
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { command: "rubric validate", where: data.root }), _jsx(Callout, { tone: "bad", title: `${data.file} is not a valid rubric`, children: data.issues.map((issue) => (_jsxs(Text, { color: palette.cloud, children: [glyph.dot, " ", issue] }, issue))) })] }));
12
+ }
13
+ const stuck = data.rules.filter((r) => r.status === "weak" || r.status === "noisy");
14
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Header, { command: "rubric validate", where: data.root }), _jsxs(Text, { color: palette.sage, children: [glyph.check, " wrote ", data.file, " with source hashes"] }), data.missing.length > 0 ? (_jsx(Callout, { tone: "bad", title: "Sources that could not be hashed. Fix the path.", children: _jsx(Text, { color: palette.cloud, children: data.missing.join(", ") }) })) : null, data.orphaned.length > 0 ? (_jsx(Callout, { tone: "bad", title: 'Rules whose source is not listed under "sources". Add it or fix the path.', children: _jsx(Text, { color: palette.cloud, children: data.orphaned.join(", ") }) })) : null, _jsx(Box, { marginTop: 1, children: _jsxs(Section, { title: "Rules", children: [_jsx(Buckets, { rules: data.rules }), _jsx(Box, { marginTop: 1, children: _jsx(RuleTable, { rules: data.rules }) })] }) }), stuck.length > 0 ? (_jsxs(Callout, { tone: "warn", title: `${stuck.length} ${stuck.length === 1 ? "rule" : "rules"} will not run until rewritten`, children: [_jsx(Text, { color: palette.cloud, children: stuck
15
+ .map((r) => `${r.id} (${r.status}${r.calibration ? `, median ${r.calibration.median.toFixed(2)}` : ""})`)
16
+ .join(", ") }), _jsx(Text, { color: palette.mist, children: "Run abide tune." })] })) : null] }));
17
+ }
18
+ //# sourceMappingURL=RubricView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"RubricView.js","sourceRoot":"","sources":["../../../src/ui/views/RubricView.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,KAAK,CAAC;AAEhC,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAa7C,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAwB;IACvD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC5B,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,MAAM,IAAC,OAAO,EAAC,iBAAiB,EAAC,KAAK,EAAE,IAAI,CAAC,IAAI,GAAI,EACtD,KAAC,OAAO,IAAC,IAAI,EAAC,KAAK,EAAC,KAAK,EAAE,GAAG,IAAI,CAAC,IAAI,wBAAwB,YAC5D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAC1B,MAAC,IAAI,IAAa,KAAK,EAAE,OAAO,CAAC,KAAK,aACnC,KAAK,CAAC,GAAG,OAAG,KAAK,KADT,KAAK,CAET,CACR,CAAC,GACM,IACN,CACP,CAAC;IACJ,CAAC;IACD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO,CAAC,CAAC;IACpF,OAAO,CACL,MAAC,GAAG,IAAC,aAAa,EAAC,QAAQ,aACzB,KAAC,MAAM,IAAC,OAAO,EAAC,iBAAiB,EAAC,KAAK,EAAE,IAAI,CAAC,IAAI,GAAI,EACtD,MAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,IAAI,aACtB,KAAK,CAAC,KAAK,aAAS,IAAI,CAAC,IAAI,2BACzB,EACN,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACzB,KAAC,OAAO,IAAC,IAAI,EAAC,KAAK,EAAC,KAAK,EAAC,iDAAiD,YACzE,KAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK,YAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAQ,GACpD,CACX,CAAC,CAAC,CAAC,IAAI,EACP,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC1B,KAAC,OAAO,IACN,IAAI,EAAC,KAAK,EACV,KAAK,EAAC,2EAA2E,YAEjF,KAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK,YAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,GAAQ,GACrD,CACX,CAAC,CAAC,CAAC,IAAI,EACR,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,MAAC,OAAO,IAAC,KAAK,EAAC,OAAO,aACpB,KAAC,OAAO,IAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAI,EAC9B,KAAC,GAAG,IAAC,SAAS,EAAE,CAAC,YACf,KAAC,SAAS,IAAC,KAAK,EAAE,IAAI,CAAC,KAAK,GAAI,GAC5B,IACE,GACN,EACL,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAClB,MAAC,OAAO,IACN,IAAI,EAAC,MAAM,EACX,KAAK,EAAE,GAAG,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,+BAA+B,aAE9F,KAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,KAAK,YACvB,KAAK;6BACH,GAAG,CACF,CAAC,CAAC,EAAE,EAAE,CACJ,GAAG,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,CAC/F;6BACA,IAAI,CAAC,IAAI,CAAC,GACR,EACP,KAAC,IAAI,IAAC,KAAK,EAAE,OAAO,CAAC,IAAI,gCAAwB,IACzC,CACX,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC"}
@@ -0,0 +1,246 @@
1
+ // Abide for OpenCode.
2
+ //
3
+ // OpenCode has no hook processes: it loads this module into its own server and
4
+ // calls the functions below. Each one turns the OpenCode event into the payload
5
+ // the abide hook script already understands, runs that script, and puts the
6
+ // answer where OpenCode will carry it to the model: an edit's repair request is
7
+ // appended to the tool result, a turn's repair request is sent as one follow-up
8
+ // message. The checks, the rubric and the messages are the same as on every
9
+ // other host.
10
+ //
11
+ // Nothing here may throw into OpenCode. Every path catches, and the script has
12
+ // its own deadline.
13
+
14
+ import { spawn } from "node:child_process";
15
+ import path from "node:path";
16
+ import { fileURLToPath } from "node:url";
17
+
18
+ const HOOK = fileURLToPath(new URL("../dist/abide-hook.js", import.meta.url));
19
+
20
+ const runHook = (name, payload, timeoutMs) =>
21
+ new Promise((resolve) => {
22
+ let settled = false;
23
+ const finish = (value) => {
24
+ if (settled) return;
25
+ settled = true;
26
+ resolve(value);
27
+ };
28
+ let child;
29
+ try {
30
+ child = spawn("node", [HOOK, name], { stdio: ["pipe", "pipe", "ignore"] });
31
+ } catch {
32
+ finish(undefined);
33
+ return;
34
+ }
35
+ const chunks = [];
36
+ const timer = setTimeout(() => {
37
+ try {
38
+ child.kill();
39
+ } catch {}
40
+ finish(undefined);
41
+ }, timeoutMs);
42
+ // EPIPE from a child that exited early arrives async; unheard it kills OpenCode.
43
+ child.stdin.on("error", () => {});
44
+ child.stdout.on("error", () => {});
45
+ child.stdout.on("data", (c) => chunks.push(c));
46
+ child.on("error", () => {
47
+ clearTimeout(timer);
48
+ finish(undefined);
49
+ });
50
+ child.on("close", () => {
51
+ clearTimeout(timer);
52
+ const text = Buffer.concat(chunks).toString("utf8").trim();
53
+ if (text === "") {
54
+ finish(undefined);
55
+ return;
56
+ }
57
+ try {
58
+ finish(JSON.parse(text));
59
+ } catch {
60
+ finish(undefined);
61
+ }
62
+ });
63
+ try {
64
+ child.stdin.end(JSON.stringify(payload));
65
+ } catch {
66
+ clearTimeout(timer);
67
+ finish(undefined);
68
+ }
69
+ });
70
+
71
+ /** Unified-diff hunks, as the Claude-style payload carries them, from OpenCode's own diff text. */
72
+ const hunksFrom = (diff) => {
73
+ if (typeof diff !== "string") return undefined;
74
+ const hunks = [];
75
+ let current;
76
+ for (const line of diff.split("\n")) {
77
+ const header = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/.exec(line);
78
+ if (header) {
79
+ current = {
80
+ oldStart: Number(header[1]),
81
+ oldLines: header[2] === undefined ? 1 : Number(header[2]),
82
+ newStart: Number(header[3]),
83
+ newLines: header[4] === undefined ? 1 : Number(header[4]),
84
+ lines: [],
85
+ };
86
+ hunks.push(current);
87
+ continue;
88
+ }
89
+ if (current && /^[ +-]/.test(line)) current.lines.push(line);
90
+ }
91
+ return hunks.length > 0 ? hunks : undefined;
92
+ };
93
+
94
+ const textOf = (parts) =>
95
+ (Array.isArray(parts) ? parts : [])
96
+ .filter((p) => p && p.type === "text" && typeof p.text === "string")
97
+ .map((p) => p.text)
98
+ .join("\n");
99
+
100
+ export default async ({ client, directory }) => {
101
+ const log = (message) => {
102
+ try {
103
+ // An unhandled rejection is as fatal to the host as a throw.
104
+ Promise.resolve(
105
+ client?.app?.log?.({ body: { service: "abide", level: "info", message } }),
106
+ ).catch(() => {});
107
+ } catch {}
108
+ };
109
+ /** Per session: the turn being checked, and whether abide's own follow-up is in flight. */
110
+ const sessions = new Map();
111
+ const absolute = (file) =>
112
+ typeof file !== "string" ? "" : path.isAbsolute(file) ? file : path.join(directory, file);
113
+
114
+ return {
115
+ "chat.message": async (input, output) => {
116
+ try {
117
+ const sessionID = input?.sessionID;
118
+ const message = output?.message;
119
+ if (!sessionID || !message?.id) return;
120
+ const text = textOf(output.parts);
121
+ let s = sessions.get(sessionID);
122
+ if (!s) {
123
+ s = { turnId: undefined, followups: 0, repairing: false };
124
+ sessions.set(sessionID, s);
125
+ const out = await runHook(
126
+ "session-start",
127
+ {
128
+ session_id: sessionID,
129
+ cwd: directory,
130
+ hook_event_name: "SessionStart",
131
+ source: "startup",
132
+ },
133
+ 10_000,
134
+ );
135
+ const context = out?.hookSpecificOutput?.additionalContext;
136
+ if (typeof context === "string" && context !== "") {
137
+ output.parts.push({
138
+ id: `prt_abide_${Date.now().toString(36)}`,
139
+ sessionID,
140
+ messageID: message.id,
141
+ type: "text",
142
+ text: context,
143
+ synthetic: true,
144
+ });
145
+ }
146
+ if (out?.systemMessage) log(out.systemMessage);
147
+ }
148
+ // Abide's own repair request continues the turn it was raised in.
149
+ if (s.repairing && text.startsWith("Abide:")) {
150
+ s.repairing = false;
151
+ return;
152
+ }
153
+ s.turnId = message.id;
154
+ s.followups = 0;
155
+ await runHook(
156
+ "turn-start",
157
+ {
158
+ session_id: sessionID,
159
+ prompt_id: message.id,
160
+ cwd: directory,
161
+ hook_event_name: "UserPromptSubmit",
162
+ prompt: text,
163
+ },
164
+ 10_000,
165
+ );
166
+ } catch {}
167
+ },
168
+
169
+ "tool.execute.after": async (input, output) => {
170
+ try {
171
+ if (input?.tool !== "edit" && input?.tool !== "write") return;
172
+ const s = sessions.get(input.sessionID);
173
+ if (!s) return;
174
+ const args = input.args ?? {};
175
+ const file_path = absolute(args.filePath);
176
+ if (file_path === "") return;
177
+ const hunks = hunksFrom(output?.metadata?.diff);
178
+ const payload =
179
+ input.tool === "edit"
180
+ ? {
181
+ tool_name: "Edit",
182
+ tool_input: {
183
+ file_path,
184
+ old_string: String(args.oldString ?? ""),
185
+ new_string: String(args.newString ?? ""),
186
+ replace_all: Boolean(args.replaceAll),
187
+ },
188
+ tool_response: hunks ? { filePath: file_path, structuredPatch: hunks } : {},
189
+ }
190
+ : {
191
+ tool_name: "Write",
192
+ tool_input: { file_path, content: String(args.content ?? "") },
193
+ // A diff from the host means the file existed; without one it is treated as new.
194
+ tool_response: hunks
195
+ ? { filePath: file_path, originalFile: "", structuredPatch: hunks }
196
+ : { filePath: file_path, originalFile: null },
197
+ };
198
+ const out = await runHook(
199
+ "post-tool-use",
200
+ {
201
+ ...payload,
202
+ session_id: input.sessionID,
203
+ prompt_id: s.turnId,
204
+ cwd: directory,
205
+ hook_event_name: "PostToolUse",
206
+ tool_use_id: input.callID,
207
+ },
208
+ 20_000,
209
+ );
210
+ if (out?.decision === "block" && typeof out.reason === "string") {
211
+ output.output = `${output.output ?? ""}\n\n${out.reason}`;
212
+ }
213
+ if (out?.systemMessage) log(out.systemMessage);
214
+ } catch {}
215
+ },
216
+
217
+ event: async ({ event }) => {
218
+ try {
219
+ if (event?.type !== "session.idle") return;
220
+ const sessionID = event.properties?.sessionID;
221
+ const s = sessions.get(sessionID);
222
+ if (!s || !s.turnId) return;
223
+ const out = await runHook(
224
+ "stop",
225
+ {
226
+ session_id: sessionID,
227
+ prompt_id: s.turnId,
228
+ cwd: directory,
229
+ hook_event_name: "Stop",
230
+ stop_hook_active: s.followups > 0,
231
+ },
232
+ 30_000,
233
+ );
234
+ if (out?.systemMessage) log(out.systemMessage);
235
+ if (out?.decision === "block" && typeof out.reason === "string" && s.followups < 1) {
236
+ s.followups += 1;
237
+ s.repairing = true;
238
+ await client.session.promptAsync({
239
+ path: { id: sessionID },
240
+ body: { parts: [{ type: "text", text: out.reason }] },
241
+ });
242
+ }
243
+ } catch {}
244
+ },
245
+ };
246
+ };
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@coldtea/abide",
3
+ "version": "0.0.1",
4
+ "description": "Enforce your own AGENTS.md rules on every edit a coding agent makes.",
5
+ "license": "MIT",
6
+ "author": "Coldtea AI",
7
+ "type": "module",
8
+ "bin": {
9
+ "abide": "./dist/bin.js"
10
+ },
11
+ "files": [
12
+ "dist",
13
+ "src",
14
+ "skills",
15
+ "opencode",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "engines": {
23
+ "node": ">=20.11"
24
+ },
25
+ "dependencies": {
26
+ "@ai-sdk/typesafe-ai": "3",
27
+ "ai": "^7.0.105",
28
+ "diff": "9.0.0",
29
+ "ink": "6.8.0",
30
+ "ink-spinner": "5.0.0",
31
+ "picomatch": "4.0.7",
32
+ "react": "19.3.0",
33
+ "zod": "^4.4.3",
34
+ "@coldtea/abide-schema": "0.0.1"
35
+ },
36
+ "devDependencies": {
37
+ "@types/diff": "8.0.0",
38
+ "@types/node": "^20.19.0",
39
+ "@types/picomatch": "4.0.3",
40
+ "@types/react": "19.3.0",
41
+ "ink-testing-library": "4.0.0",
42
+ "typescript": "7.0.2",
43
+ "vitest": "4.1.11"
44
+ },
45
+ "scripts": {
46
+ "build": "rm -rf dist skills && tsc -p tsconfig.build.json && mkdir -p skills/abide-compile && cp ../../skills/abide-compile/SKILL.md skills/abide-compile/SKILL.md",
47
+ "typecheck": "tsc -p tsconfig.json --noEmit",
48
+ "test": "vitest run"
49
+ }
50
+ }