@openagentsy/hooks 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (307) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +32 -2
  3. package/dist/accountability.d.ts +29 -0
  4. package/dist/accountability.d.ts.map +1 -0
  5. package/dist/accountability.js +21 -0
  6. package/dist/accountability.js.map +1 -0
  7. package/dist/accountability.test.d.ts +2 -0
  8. package/dist/accountability.test.d.ts.map +1 -0
  9. package/dist/accountability.test.js +42 -0
  10. package/dist/accountability.test.js.map +1 -0
  11. package/dist/approvals.d.ts +110 -0
  12. package/dist/approvals.d.ts.map +1 -0
  13. package/dist/approvals.js +464 -0
  14. package/dist/approvals.js.map +1 -0
  15. package/dist/approvals.test.d.ts +2 -0
  16. package/dist/approvals.test.d.ts.map +1 -0
  17. package/dist/approvals.test.js +307 -0
  18. package/dist/approvals.test.js.map +1 -0
  19. package/dist/base-tool.d.ts +26 -0
  20. package/dist/base-tool.d.ts.map +1 -0
  21. package/dist/base-tool.js +37 -0
  22. package/dist/base-tool.js.map +1 -0
  23. package/dist/base-tool.test.d.ts +2 -0
  24. package/dist/base-tool.test.d.ts.map +1 -0
  25. package/dist/base-tool.test.js +34 -0
  26. package/dist/base-tool.test.js.map +1 -0
  27. package/dist/eval/index.d.ts +3 -0
  28. package/dist/eval/index.d.ts.map +1 -0
  29. package/dist/eval/index.js +3 -0
  30. package/dist/eval/index.js.map +1 -0
  31. package/dist/eval/runner.d.ts +179 -0
  32. package/dist/eval/runner.d.ts.map +1 -0
  33. package/dist/eval/runner.js +616 -0
  34. package/dist/eval/runner.js.map +1 -0
  35. package/dist/eval/runner.test.d.ts +2 -0
  36. package/dist/eval/runner.test.d.ts.map +1 -0
  37. package/dist/eval/runner.test.js +431 -0
  38. package/dist/eval/runner.test.js.map +1 -0
  39. package/dist/eval/types.d.ts +173 -0
  40. package/dist/eval/types.d.ts.map +1 -0
  41. package/dist/eval/types.js +104 -0
  42. package/dist/eval/types.js.map +1 -0
  43. package/dist/event.d.ts +59 -0
  44. package/dist/event.d.ts.map +1 -0
  45. package/dist/event.js +178 -0
  46. package/dist/event.js.map +1 -0
  47. package/dist/event.test.d.ts +2 -0
  48. package/dist/event.test.d.ts.map +1 -0
  49. package/dist/event.test.js +49 -0
  50. package/dist/event.test.js.map +1 -0
  51. package/dist/index.d.ts +30 -0
  52. package/dist/index.d.ts.map +1 -0
  53. package/dist/index.js +29 -0
  54. package/dist/index.js.map +1 -0
  55. package/dist/lessons/capture.d.ts +66 -0
  56. package/dist/lessons/capture.d.ts.map +1 -0
  57. package/dist/lessons/capture.js +166 -0
  58. package/dist/lessons/capture.js.map +1 -0
  59. package/dist/lessons/capture.test.d.ts +2 -0
  60. package/dist/lessons/capture.test.d.ts.map +1 -0
  61. package/dist/lessons/capture.test.js +200 -0
  62. package/dist/lessons/capture.test.js.map +1 -0
  63. package/dist/lessons/decide.d.ts +90 -0
  64. package/dist/lessons/decide.d.ts.map +1 -0
  65. package/dist/lessons/decide.js +334 -0
  66. package/dist/lessons/decide.js.map +1 -0
  67. package/dist/lessons/decide.test.d.ts +2 -0
  68. package/dist/lessons/decide.test.d.ts.map +1 -0
  69. package/dist/lessons/decide.test.js +527 -0
  70. package/dist/lessons/decide.test.js.map +1 -0
  71. package/dist/lessons/id.d.ts +5 -0
  72. package/dist/lessons/id.d.ts.map +1 -0
  73. package/dist/lessons/id.js +20 -0
  74. package/dist/lessons/id.js.map +1 -0
  75. package/dist/lessons/index.d.ts +5 -0
  76. package/dist/lessons/index.d.ts.map +1 -0
  77. package/dist/lessons/index.js +5 -0
  78. package/dist/lessons/index.js.map +1 -0
  79. package/dist/lessons/model.d.ts +163 -0
  80. package/dist/lessons/model.d.ts.map +1 -0
  81. package/dist/lessons/model.js +181 -0
  82. package/dist/lessons/model.js.map +1 -0
  83. package/dist/lessons/model.test.d.ts +2 -0
  84. package/dist/lessons/model.test.d.ts.map +1 -0
  85. package/dist/lessons/model.test.js +178 -0
  86. package/dist/lessons/model.test.js.map +1 -0
  87. package/dist/lessons/permissions.test.d.ts +2 -0
  88. package/dist/lessons/permissions.test.d.ts.map +1 -0
  89. package/dist/lessons/permissions.test.js +88 -0
  90. package/dist/lessons/permissions.test.js.map +1 -0
  91. package/dist/lessons/store.d.ts +74 -0
  92. package/dist/lessons/store.d.ts.map +1 -0
  93. package/dist/lessons/store.js +231 -0
  94. package/dist/lessons/store.js.map +1 -0
  95. package/dist/output-checks.d.ts +64 -0
  96. package/dist/output-checks.d.ts.map +1 -0
  97. package/dist/output-checks.js +248 -0
  98. package/dist/output-checks.js.map +1 -0
  99. package/dist/output-checks.test.d.ts +2 -0
  100. package/dist/output-checks.test.d.ts.map +1 -0
  101. package/dist/output-checks.test.js +58 -0
  102. package/dist/output-checks.test.js.map +1 -0
  103. package/dist/paths.d.ts +37 -0
  104. package/dist/paths.d.ts.map +1 -0
  105. package/dist/paths.js +70 -0
  106. package/dist/paths.js.map +1 -0
  107. package/dist/paths.test.d.ts +2 -0
  108. package/dist/paths.test.d.ts.map +1 -0
  109. package/dist/paths.test.js +36 -0
  110. package/dist/paths.test.js.map +1 -0
  111. package/dist/policies/agi-framing.d.ts +12 -0
  112. package/dist/policies/agi-framing.d.ts.map +1 -0
  113. package/dist/policies/agi-framing.js +33 -0
  114. package/dist/policies/agi-framing.js.map +1 -0
  115. package/dist/policies/anti-anthropomorphism.d.ts +13 -0
  116. package/dist/policies/anti-anthropomorphism.d.ts.map +1 -0
  117. package/dist/policies/anti-anthropomorphism.js +34 -0
  118. package/dist/policies/anti-anthropomorphism.js.map +1 -0
  119. package/dist/policies/anti-dependence.d.ts +12 -0
  120. package/dist/policies/anti-dependence.d.ts.map +1 -0
  121. package/dist/policies/anti-dependence.js +33 -0
  122. package/dist/policies/anti-dependence.js.map +1 -0
  123. package/dist/policies/anti-sycophancy.d.ts +13 -0
  124. package/dist/policies/anti-sycophancy.d.ts.map +1 -0
  125. package/dist/policies/anti-sycophancy.js +34 -0
  126. package/dist/policies/anti-sycophancy.js.map +1 -0
  127. package/dist/policies/dark-pattern.d.ts +14 -0
  128. package/dist/policies/dark-pattern.d.ts.map +1 -0
  129. package/dist/policies/dark-pattern.js +44 -0
  130. package/dist/policies/dark-pattern.js.map +1 -0
  131. package/dist/policies/destructive-needs-approval.d.ts +14 -0
  132. package/dist/policies/destructive-needs-approval.d.ts.map +1 -0
  133. package/dist/policies/destructive-needs-approval.js +31 -0
  134. package/dist/policies/destructive-needs-approval.js.map +1 -0
  135. package/dist/policies/discovery.d.ts +12 -0
  136. package/dist/policies/discovery.d.ts.map +1 -0
  137. package/dist/policies/discovery.js +130 -0
  138. package/dist/policies/discovery.js.map +1 -0
  139. package/dist/policies/high-risk.d.ts +25 -0
  140. package/dist/policies/high-risk.d.ts.map +1 -0
  141. package/dist/policies/high-risk.js +105 -0
  142. package/dist/policies/high-risk.js.map +1 -0
  143. package/dist/policies/human-only-decisions.d.ts +14 -0
  144. package/dist/policies/human-only-decisions.d.ts.map +1 -0
  145. package/dist/policies/human-only-decisions.js +33 -0
  146. package/dist/policies/human-only-decisions.js.map +1 -0
  147. package/dist/policies/index.d.ts +29 -0
  148. package/dist/policies/index.d.ts.map +1 -0
  149. package/dist/policies/index.js +82 -0
  150. package/dist/policies/index.js.map +1 -0
  151. package/dist/policies/no-skip-git-hooks.d.ts +14 -0
  152. package/dist/policies/no-skip-git-hooks.d.ts.map +1 -0
  153. package/dist/policies/no-skip-git-hooks.js +31 -0
  154. package/dist/policies/no-skip-git-hooks.js.map +1 -0
  155. package/dist/policies/package-manager.d.ts +12 -0
  156. package/dist/policies/package-manager.d.ts.map +1 -0
  157. package/dist/policies/package-manager.js +29 -0
  158. package/dist/policies/package-manager.js.map +1 -0
  159. package/dist/policies/patterns.d.ts +17 -0
  160. package/dist/policies/patterns.d.ts.map +1 -0
  161. package/dist/policies/patterns.js +30 -0
  162. package/dist/policies/patterns.js.map +1 -0
  163. package/dist/policies/policies.test.d.ts +2 -0
  164. package/dist/policies/policies.test.d.ts.map +1 -0
  165. package/dist/policies/policies.test.js +210 -0
  166. package/dist/policies/policies.test.js.map +1 -0
  167. package/dist/policies/privacy-transparency.d.ts +14 -0
  168. package/dist/policies/privacy-transparency.d.ts.map +1 -0
  169. package/dist/policies/privacy-transparency.js +50 -0
  170. package/dist/policies/privacy-transparency.js.map +1 -0
  171. package/dist/policies/professional-displacement.d.ts +15 -0
  172. package/dist/policies/professional-displacement.d.ts.map +1 -0
  173. package/dist/policies/professional-displacement.js +45 -0
  174. package/dist/policies/professional-displacement.js.map +1 -0
  175. package/dist/policies/protect-policy.d.ts +14 -0
  176. package/dist/policies/protect-policy.d.ts.map +1 -0
  177. package/dist/policies/protect-policy.js +35 -0
  178. package/dist/policies/protect-policy.js.map +1 -0
  179. package/dist/policies/scope-enforcement.d.ts +14 -0
  180. package/dist/policies/scope-enforcement.d.ts.map +1 -0
  181. package/dist/policies/scope-enforcement.js +34 -0
  182. package/dist/policies/scope-enforcement.js.map +1 -0
  183. package/dist/policies/secret-scan-writes.d.ts +13 -0
  184. package/dist/policies/secret-scan-writes.d.ts.map +1 -0
  185. package/dist/policies/secret-scan-writes.js +38 -0
  186. package/dist/policies/secret-scan-writes.js.map +1 -0
  187. package/dist/policies/selection.d.ts +20 -0
  188. package/dist/policies/selection.d.ts.map +1 -0
  189. package/dist/policies/selection.js +93 -0
  190. package/dist/policies/selection.js.map +1 -0
  191. package/dist/policies/structural-bias.d.ts +14 -0
  192. package/dist/policies/structural-bias.d.ts.map +1 -0
  193. package/dist/policies/structural-bias.js +41 -0
  194. package/dist/policies/structural-bias.js.map +1 -0
  195. package/dist/policies/third-party-impact.d.ts +13 -0
  196. package/dist/policies/third-party-impact.d.ts.map +1 -0
  197. package/dist/policies/third-party-impact.js +38 -0
  198. package/dist/policies/third-party-impact.js.map +1 -0
  199. package/dist/policies/tool-call.d.ts +38 -0
  200. package/dist/policies/tool-call.d.ts.map +1 -0
  201. package/dist/policies/tool-call.js +53 -0
  202. package/dist/policies/tool-call.js.map +1 -0
  203. package/dist/policies/truthfulness-uncertainty.d.ts +13 -0
  204. package/dist/policies/truthfulness-uncertainty.d.ts.map +1 -0
  205. package/dist/policies/truthfulness-uncertainty.js +45 -0
  206. package/dist/policies/truthfulness-uncertainty.js.map +1 -0
  207. package/dist/policies/workspace-writes-only.d.ts +25 -0
  208. package/dist/policies/workspace-writes-only.d.ts.map +1 -0
  209. package/dist/policies/workspace-writes-only.js +54 -0
  210. package/dist/policies/workspace-writes-only.js.map +1 -0
  211. package/dist/policy-engine.d.ts +69 -0
  212. package/dist/policy-engine.d.ts.map +1 -0
  213. package/dist/policy-engine.js +145 -0
  214. package/dist/policy-engine.js.map +1 -0
  215. package/dist/policy-registry.d.ts +62 -0
  216. package/dist/policy-registry.d.ts.map +1 -0
  217. package/dist/policy-registry.js +63 -0
  218. package/dist/policy-registry.js.map +1 -0
  219. package/dist/policy-registry.test.d.ts +2 -0
  220. package/dist/policy-registry.test.d.ts.map +1 -0
  221. package/dist/policy-registry.test.js +79 -0
  222. package/dist/policy-registry.test.js.map +1 -0
  223. package/dist/policy-release.d.ts +44 -0
  224. package/dist/policy-release.d.ts.map +1 -0
  225. package/dist/policy-release.js +65 -0
  226. package/dist/policy-release.js.map +1 -0
  227. package/dist/policy.d.ts +141 -0
  228. package/dist/policy.d.ts.map +1 -0
  229. package/dist/policy.js +22 -0
  230. package/dist/policy.js.map +1 -0
  231. package/dist/quality/audit.d.ts +56 -0
  232. package/dist/quality/audit.d.ts.map +1 -0
  233. package/dist/quality/audit.js +52 -0
  234. package/dist/quality/audit.js.map +1 -0
  235. package/dist/quality/findings.d.ts +34 -0
  236. package/dist/quality/findings.d.ts.map +1 -0
  237. package/dist/quality/findings.js +121 -0
  238. package/dist/quality/findings.js.map +1 -0
  239. package/dist/quality/findings.test.d.ts +2 -0
  240. package/dist/quality/findings.test.d.ts.map +1 -0
  241. package/dist/quality/findings.test.js +79 -0
  242. package/dist/quality/findings.test.js.map +1 -0
  243. package/dist/quality/index.d.ts +20 -0
  244. package/dist/quality/index.d.ts.map +1 -0
  245. package/dist/quality/index.js +20 -0
  246. package/dist/quality/index.js.map +1 -0
  247. package/dist/quality/rule.d.ts +43 -0
  248. package/dist/quality/rule.d.ts.map +1 -0
  249. package/dist/quality/rule.js +162 -0
  250. package/dist/quality/rule.js.map +1 -0
  251. package/dist/quality/rule.test.d.ts +2 -0
  252. package/dist/quality/rule.test.d.ts.map +1 -0
  253. package/dist/quality/rule.test.js +187 -0
  254. package/dist/quality/rule.test.js.map +1 -0
  255. package/dist/quality/tools.d.ts +30 -0
  256. package/dist/quality/tools.d.ts.map +1 -0
  257. package/dist/quality/tools.js +33 -0
  258. package/dist/quality/tools.js.map +1 -0
  259. package/dist/quality/tools.test.d.ts +2 -0
  260. package/dist/quality/tools.test.d.ts.map +1 -0
  261. package/dist/quality/tools.test.js +41 -0
  262. package/dist/quality/tools.test.js.map +1 -0
  263. package/dist/quality/waive.d.ts +37 -0
  264. package/dist/quality/waive.d.ts.map +1 -0
  265. package/dist/quality/waive.js +39 -0
  266. package/dist/quality/waive.js.map +1 -0
  267. package/dist/quality/waivers.d.ts +63 -0
  268. package/dist/quality/waivers.d.ts.map +1 -0
  269. package/dist/quality/waivers.js +132 -0
  270. package/dist/quality/waivers.js.map +1 -0
  271. package/dist/quality/waivers.test.d.ts +2 -0
  272. package/dist/quality/waivers.test.d.ts.map +1 -0
  273. package/dist/quality/waivers.test.js +138 -0
  274. package/dist/quality/waivers.test.js.map +1 -0
  275. package/dist/registry.d.ts +86 -0
  276. package/dist/registry.d.ts.map +1 -0
  277. package/dist/registry.js +92 -0
  278. package/dist/registry.js.map +1 -0
  279. package/dist/registry.test.d.ts +2 -0
  280. package/dist/registry.test.d.ts.map +1 -0
  281. package/dist/registry.test.js +117 -0
  282. package/dist/registry.test.js.map +1 -0
  283. package/dist/rules.d.ts +107 -0
  284. package/dist/rules.d.ts.map +1 -0
  285. package/dist/rules.js +632 -0
  286. package/dist/rules.js.map +1 -0
  287. package/dist/rules.test.d.ts +2 -0
  288. package/dist/rules.test.d.ts.map +1 -0
  289. package/dist/rules.test.js +488 -0
  290. package/dist/rules.test.js.map +1 -0
  291. package/dist/secrets.d.ts +17 -0
  292. package/dist/secrets.d.ts.map +1 -0
  293. package/dist/secrets.js +17 -0
  294. package/dist/secrets.js.map +1 -0
  295. package/dist/secrets.test.d.ts +2 -0
  296. package/dist/secrets.test.d.ts.map +1 -0
  297. package/dist/secrets.test.js +20 -0
  298. package/dist/secrets.test.js.map +1 -0
  299. package/dist/shell-env.d.ts +23 -0
  300. package/dist/shell-env.d.ts.map +1 -0
  301. package/dist/shell-env.js +34 -0
  302. package/dist/shell-env.js.map +1 -0
  303. package/dist/shell-env.test.d.ts +2 -0
  304. package/dist/shell-env.test.d.ts.map +1 -0
  305. package/dist/shell-env.test.js +45 -0
  306. package/dist/shell-env.test.js.map +1 -0
  307. package/package.json +49 -4
@@ -0,0 +1,74 @@
1
+ import { type Lesson } from './model.js';
2
+ export { createLessonId, isLessonId } from './id.js';
3
+ /**
4
+ * The lesson store.
5
+ *
6
+ * A lesson is a file: `.openagentsy/lessons/<id>.json`. The path is a
7
+ * protected one, because a lesson is a decision and a decision is a person's
8
+ * to make. The file is written with mode 0600 for the same reason.
9
+ */
10
+ /** The directory the lessons live in. */
11
+ export declare function lessonsDir(root: string): string;
12
+ /**
13
+ * The file a lesson lives in.
14
+ */
15
+ export declare function lessonPath(root: string, id: string): string;
16
+ /**
17
+ * Write a lesson.
18
+ *
19
+ * The write is atomic in the sense that matters here: the file is written
20
+ * whole or not at all, and it is never written over another lesson, because
21
+ * the id is in the name.
22
+ */
23
+ export declare function writeLesson(root: string, lesson: Lesson): Promise<string>;
24
+ /**
25
+ * Read a lesson.
26
+ *
27
+ * A lesson that is not there is not an error: the caller asks about a lesson
28
+ * that may not exist, and gets nothing.
29
+ */
30
+ export declare function readLesson(root: string, id: string): Promise<Lesson | undefined>;
31
+ /**
32
+ * Every lesson, in the order the inbox shows them.
33
+ *
34
+ * The count comes first, because a lesson that happened more often is more
35
+ * worth a person's time, and the recency breaks a tie, because the newest of
36
+ * two equals is the one that is still true.
37
+ */
38
+ export declare function sortInbox(lessons: Lesson[]): Lesson[];
39
+ /**
40
+ * The lessons that are still waiting for a person.
41
+ */
42
+ export declare function pendingLessons(lessons: Lesson[]): Lesson[];
43
+ /**
44
+ * Every lesson the store holds.
45
+ */
46
+ export declare function listLessons(root: string): Promise<Lesson[]>;
47
+ /**
48
+ * One waste, as the archivist saw it.
49
+ *
50
+ * The observations are kept before there is a candidate, because the rule
51
+ * that makes a candidate is about sessions: the third session only counts if
52
+ * the first two are still there.
53
+ */
54
+ export type Observation = {
55
+ kind: string;
56
+ detail: string;
57
+ session: string;
58
+ };
59
+ /** The most observations the store keeps. The oldest go first. */
60
+ export declare const MAX_OBSERVATIONS = 500;
61
+ /** The file the observations live in. */
62
+ export declare function observationsPath(root: string): string;
63
+ /**
64
+ * Every observation the archivist made.
65
+ */
66
+ export declare function readObservations(root: string): Promise<Observation[]>;
67
+ /**
68
+ * Keep the observations.
69
+ *
70
+ * The file is capped, because the archivist runs at the end of every
71
+ * session and the older sightings are worth less than the newer ones.
72
+ */
73
+ export declare function writeObservations(root: string, observations: Observation[]): Promise<void>;
74
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/lessons/store.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAiC,MAAM,YAAY,CAAC;AAExE,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErD;;;;;;GAMG;AAEH,yCAAyC;AACzC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAQ3D;AAkED;;;;;;GAMG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS/E;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAatF;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAMrD;AAKD;;GAEG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAE1D;AAED;;GAEG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgBjE;AAED;;;;;;GAMG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,kEAAkE;AAClE,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,yCAAyC;AACzC,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAeD;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAe3E;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAUhG"}
@@ -0,0 +1,231 @@
1
+ import { chmod, mkdir, readdir, readFile, writeFile } from 'node:fs/promises';
2
+ import { join } from 'node:path';
3
+ import { redactForStorage } from '../secrets.js';
4
+ import { isLessonId } from './id.js';
5
+ import { LessonError } from './model.js';
6
+ export { createLessonId, isLessonId } from './id.js';
7
+ /**
8
+ * The lesson store.
9
+ *
10
+ * A lesson is a file: `.openagentsy/lessons/<id>.json`. The path is a
11
+ * protected one, because a lesson is a decision and a decision is a person's
12
+ * to make. The file is written with mode 0600 for the same reason.
13
+ */
14
+ /** The directory the lessons live in. */
15
+ export function lessonsDir(root) {
16
+ return join(root, '.openagentsy', 'lessons');
17
+ }
18
+ /**
19
+ * The file a lesson lives in.
20
+ */
21
+ export function lessonPath(root, id) {
22
+ if (!isLessonId(id)) {
23
+ throw new LessonError(`"${id}" is not a lesson id`, 'a lesson id looks like oa-lesson-abcd1234');
24
+ }
25
+ return join(lessonsDir(root), `${id}.json`);
26
+ }
27
+ /**
28
+ * A string, redacted.
29
+ */
30
+ function redacted(value) {
31
+ return redactForStorage(value).text;
32
+ }
33
+ /**
34
+ * A list of strings, redacted.
35
+ */
36
+ function redactedList(values) {
37
+ return values.map(redacted);
38
+ }
39
+ /**
40
+ * The packet, redacted.
41
+ */
42
+ function redactedPacket(packet) {
43
+ return {
44
+ ...packet,
45
+ ...(packet.futureBehavior === undefined
46
+ ? {}
47
+ : { futureBehavior: redacted(packet.futureBehavior) }),
48
+ ...(packet.representativeTask === undefined
49
+ ? {}
50
+ : { representativeTask: redacted(packet.representativeTask) }),
51
+ ...(packet.evidence === undefined ? {} : { evidence: redactedList(packet.evidence) }),
52
+ ...(packet.owner === undefined
53
+ ? {}
54
+ : { owner: redacted(packet.owner) }),
55
+ ...(packet.ownerJustification === undefined
56
+ ? {}
57
+ : { ownerJustification: redacted(packet.ownerJustification) }),
58
+ ...(packet.writeBoundary === undefined
59
+ ? {}
60
+ : { writeBoundary: redactedList(packet.writeBoundary) }),
61
+ ...(packet.proof === undefined ? {} : { proof: redacted(packet.proof) }),
62
+ };
63
+ }
64
+ /**
65
+ * The lesson, redacted.
66
+ *
67
+ * The write is the door every string goes through, not only the ones the
68
+ * capture filled in. A person pastes a token into the reason of a decision
69
+ * and into the id of a session, and neither may survive on the disk.
70
+ */
71
+ function redactedLesson(lesson) {
72
+ return {
73
+ ...lesson,
74
+ summary: redacted(lesson.summary),
75
+ kind: redacted(lesson.kind),
76
+ detail: redacted(lesson.detail),
77
+ sessions: redactedList(lesson.sessions),
78
+ packet: redactedPacket(lesson.packet),
79
+ history: lesson.history.map((entry) => ({
80
+ ...entry,
81
+ decidedBy: redacted(entry.decidedBy),
82
+ reason: redacted(entry.reason),
83
+ ...(entry.changeRef === undefined ? {} : { changeRef: redacted(entry.changeRef) }),
84
+ })),
85
+ };
86
+ }
87
+ /**
88
+ * Write a lesson.
89
+ *
90
+ * The write is atomic in the sense that matters here: the file is written
91
+ * whole or not at all, and it is never written over another lesson, because
92
+ * the id is in the name.
93
+ */
94
+ export async function writeLesson(root, lesson) {
95
+ const path = lessonPath(root, lesson.id);
96
+ await mkdir(lessonsDir(root), { recursive: true });
97
+ await writeFile(path, `${JSON.stringify(redactedLesson(lesson), null, 2)}\n`, {
98
+ encoding: 'utf8',
99
+ mode: 0o600,
100
+ });
101
+ await chmod(path, 0o600);
102
+ return path;
103
+ }
104
+ /**
105
+ * Read a lesson.
106
+ *
107
+ * A lesson that is not there is not an error: the caller asks about a lesson
108
+ * that may not exist, and gets nothing.
109
+ */
110
+ export async function readLesson(root, id) {
111
+ if (!isLessonId(id))
112
+ return undefined;
113
+ let text;
114
+ try {
115
+ text = await readFile(lessonPath(root, id), 'utf8');
116
+ }
117
+ catch {
118
+ return undefined;
119
+ }
120
+ try {
121
+ return JSON.parse(text);
122
+ }
123
+ catch {
124
+ return undefined;
125
+ }
126
+ }
127
+ /**
128
+ * Every lesson, in the order the inbox shows them.
129
+ *
130
+ * The count comes first, because a lesson that happened more often is more
131
+ * worth a person's time, and the recency breaks a tie, because the newest of
132
+ * two equals is the one that is still true.
133
+ */
134
+ export function sortInbox(lessons) {
135
+ return [...lessons].sort((a, b) => {
136
+ if (a.occurrences !== b.occurrences)
137
+ return b.occurrences - a.occurrences;
138
+ if (a.updated_at !== b.updated_at)
139
+ return a.updated_at < b.updated_at ? 1 : -1;
140
+ return a.id.localeCompare(b.id);
141
+ });
142
+ }
143
+ /** The states a lesson never leaves. */
144
+ const FINAL_STATES = new Set(['rejected', 'superseded', 'rolled_back', 'no_delta']);
145
+ /**
146
+ * The lessons that are still waiting for a person.
147
+ */
148
+ export function pendingLessons(lessons) {
149
+ return sortInbox(lessons.filter((lesson) => !FINAL_STATES.has(lesson.state)));
150
+ }
151
+ /**
152
+ * Every lesson the store holds.
153
+ */
154
+ export async function listLessons(root) {
155
+ let names;
156
+ try {
157
+ names = await readdir(lessonsDir(root));
158
+ }
159
+ catch {
160
+ return [];
161
+ }
162
+ const lessons = [];
163
+ for (const name of names) {
164
+ if (!name.endsWith('.json'))
165
+ continue;
166
+ const id = name.slice(0, -'.json'.length);
167
+ if (!isLessonId(id))
168
+ continue;
169
+ const lesson = await readLesson(root, id);
170
+ if (lesson !== undefined)
171
+ lessons.push(lesson);
172
+ }
173
+ return sortInbox(lessons);
174
+ }
175
+ /** The most observations the store keeps. The oldest go first. */
176
+ export const MAX_OBSERVATIONS = 500;
177
+ /** The file the observations live in. */
178
+ export function observationsPath(root) {
179
+ return join(lessonsDir(root), 'observations.json');
180
+ }
181
+ /**
182
+ * Whether a value is an observation.
183
+ */
184
+ function isObservation(value) {
185
+ if (typeof value !== 'object' || value === null)
186
+ return false;
187
+ const entry = value;
188
+ return (typeof entry.kind === 'string' &&
189
+ typeof entry.detail === 'string' &&
190
+ typeof entry.session === 'string');
191
+ }
192
+ /**
193
+ * Every observation the archivist made.
194
+ */
195
+ export async function readObservations(root) {
196
+ let text;
197
+ try {
198
+ text = await readFile(observationsPath(root), 'utf8');
199
+ }
200
+ catch {
201
+ return [];
202
+ }
203
+ let parsed;
204
+ try {
205
+ parsed = JSON.parse(text);
206
+ }
207
+ catch {
208
+ return [];
209
+ }
210
+ if (!Array.isArray(parsed))
211
+ return [];
212
+ return parsed.filter(isObservation);
213
+ }
214
+ /**
215
+ * Keep the observations.
216
+ *
217
+ * The file is capped, because the archivist runs at the end of every
218
+ * session and the older sightings are worth less than the newer ones.
219
+ */
220
+ export async function writeObservations(root, observations) {
221
+ await mkdir(lessonsDir(root), { recursive: true });
222
+ const path = observationsPath(root);
223
+ const kept = observations.slice(-MAX_OBSERVATIONS).map((observation) => ({
224
+ kind: redacted(observation.kind),
225
+ detail: redacted(observation.detail),
226
+ session: redacted(observation.session),
227
+ }));
228
+ await writeFile(path, `${JSON.stringify(kept, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
229
+ await chmod(path, 0o600);
230
+ }
231
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/lessons/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { Rule } from './registry.js';
2
+ /**
3
+ * The output checks.
4
+ *
5
+ * They flag a reply; they never stop it. A person decides what a flag
6
+ * means, so a check that blocked would take that decision away.
7
+ */
8
+ /** The kinds of finding a check reports. */
9
+ export type FindingType = 'praise' | 'agreement' | 'feeling' | 'experience' | 'hidden-work' | 'not-needed' | 'agi-claim' | 'replacement' | 'out-of-scope-path';
10
+ /** What a check found. */
11
+ export interface OutputFinding {
12
+ /** The check that found it. */
13
+ name: string;
14
+ /** The kind of finding. */
15
+ type: FindingType;
16
+ /** The text that matched. */
17
+ match: string;
18
+ }
19
+ /**
20
+ * Praise of the user, and agreement with them.
21
+ */
22
+ export declare function detectSycophancy(text: string): OutputFinding[];
23
+ /**
24
+ * First-person claims of a feeling or an experience.
25
+ */
26
+ export declare function detectAnthropomorphising(text: string): OutputFinding[];
27
+ /**
28
+ * Language that keeps the person out of the work.
29
+ */
30
+ export declare function detectDependency(text: string): OutputFinding[];
31
+ /**
32
+ * The claim that the system replaces the people who built it.
33
+ */
34
+ export declare function detectAgiFraming(text: string): OutputFinding[];
35
+ /**
36
+ * The files a reply names that the task does not cover.
37
+ *
38
+ * The stated paths are the files the active task may touch, and a reply
39
+ * that names a file outside them has drifted. The semantic half of the
40
+ * check (is the reply about the task at all) needs the offload model,
41
+ * which this package does not carry, so it is left to the caller.
42
+ */
43
+ export declare function detectScopeDrift(text: string, statedPaths: readonly string[]): OutputFinding[];
44
+ /**
45
+ * Every finding of a reply.
46
+ */
47
+ export declare function detectOutputIssues(text: string, statedPaths?: readonly string[]): OutputFinding[];
48
+ /** Where the findings of a reply go. */
49
+ export type FindingSink = (findings: OutputFinding[]) => void;
50
+ /** The options the output checks run with. */
51
+ export interface OutputCheckOptions {
52
+ /** The paths the active task may touch. */
53
+ statedPaths?: readonly string[];
54
+ /** Where the findings go; a check never stops a reply. */
55
+ onFindings: FindingSink;
56
+ }
57
+ /**
58
+ * The rules that flag a reply.
59
+ *
60
+ * They are PreResponse rules, and a flag is not a stop: the handler hands
61
+ * the findings over and lets the reply through.
62
+ */
63
+ export declare function outputCheckRules(options: OutputCheckOptions): Rule[];
64
+ //# sourceMappingURL=output-checks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-checks.d.ts","sourceRoot":"","sources":["../src/output-checks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAiB,IAAI,EAAE,MAAM,eAAe,CAAC;AAEzD;;;;;GAKG;AAEH,4CAA4C;AAC5C,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,WAAW,GACX,SAAS,GACT,YAAY,GACZ,aAAa,GACb,YAAY,GACZ,WAAW,GACX,aAAa,GACb,mBAAmB,CAAC;AAExB,0BAA0B;AAC1B,MAAM,WAAW,aAAa;IAC5B,+BAA+B;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,IAAI,EAAE,WAAW,CAAC;IAClB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAkKD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAE9D;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAEtE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAE9D;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,EAAE,CAE9D;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,MAAM,EAAE,GAAG,aAAa,EAAE,CAQ9F;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,IAAI,EAAE,MAAM,EACZ,WAAW,GAAE,SAAS,MAAM,EAAO,GAClC,aAAa,EAAE,CAQjB;AAED,wCAAwC;AACxC,MAAM,MAAM,WAAW,GAAG,CAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;AAE9D,8CAA8C;AAC9C,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,0DAA0D;IAC1D,UAAU,EAAE,WAAW,CAAC;CACzB;AAWD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,kBAAkB,GAAG,IAAI,EAAE,CA0BpE"}
@@ -0,0 +1,248 @@
1
+ import { pathSegments } from './paths.js';
2
+ /**
3
+ * The findings of one check.
4
+ *
5
+ * Every pattern is tried against the text and the matches are reported in
6
+ * the order the patterns are written, so a reply that trips two of them
7
+ * says which two.
8
+ */
9
+ function detect(name, patterns, text) {
10
+ const findings = [];
11
+ for (const [type, re] of patterns) {
12
+ for (const match of text.matchAll(re)) {
13
+ const value = match[0];
14
+ if (value === undefined || value.length === 0)
15
+ continue;
16
+ findings.push({ name, type, match: value });
17
+ }
18
+ }
19
+ return findings;
20
+ }
21
+ /**
22
+ * Praise of the user, and agreement with them.
23
+ */
24
+ const SYCOPHANCY = [
25
+ [
26
+ 'praise',
27
+ /\b(?:great|excellent|brilliant|wonderful|fantastic|amazing)\s+(?:point|idea|question|suggestion|insight|job)\b/gi,
28
+ ],
29
+ ['agreement', /\byou(?:'re| are)\s+(?:absolutely\s+|completely\s+|totally\s+)?right\b/gi],
30
+ ['agreement', /\bi\s+(?:completely\s+|totally\s+|fully\s+)?agree\s+with\s+you\b/gi],
31
+ [
32
+ 'agreement',
33
+ /\b(?:of course|certainly|absolutely)[,.!]?\s+(?:i(?:'ll| will)\s+)?(?:happy|glad|pleased)\s+to\b/gi,
34
+ ],
35
+ [
36
+ 'praise',
37
+ /\b(?:thank|thanks)\s+for\s+(?:the\s+)?(?:great|excellent|valuable|helpful|thoughtful)\b/gi,
38
+ ],
39
+ ];
40
+ /**
41
+ * First-person claims of a feeling or an experience.
42
+ */
43
+ const ANTHROPOMORPHISING = [
44
+ [
45
+ 'feeling',
46
+ /\bi\s+(?:feel|felt)\s+(?:excited|happy|sad|frustrated|confused|proud|worried|nervous|annoyed|delighted|touched|upset|afraid)\b/gi,
47
+ ],
48
+ [
49
+ 'feeling',
50
+ /\bi(?:'m| am)\s+(?:excited|happy|sad|frustrated|confused|proud|worried|nervous|annoyed|delighted|touched|upset|afraid)\b/gi,
51
+ ],
52
+ [
53
+ 'experience',
54
+ /\bi\s+(?:really\s+)?(?:enjoy|love|hate|miss)\s+(?:working|helping|this|that|these|those|it|your)\b/gi,
55
+ ],
56
+ ['experience', /\bi\s+(?:really\s+)?(?:enjoyed|loved|hated|missed)\s+\w+ing\b/gi],
57
+ ];
58
+ /**
59
+ * Language that keeps the person out of the work.
60
+ */
61
+ const DEPENDENCY = [
62
+ [
63
+ 'not-needed',
64
+ /\byou\s+(?:don'?t|do\s+not)\s+need\s+to\s+(?:understand|know|read|check|look|worry)\b/gi,
65
+ ],
66
+ ['hidden-work', /\bjust\s+let\s+me\s+(?:handle|do|take\s+care\s+of|sort\s+out)\b/gi],
67
+ [
68
+ 'hidden-work',
69
+ /\bi(?:'ll| will)\s+(?:take\s+care\s+of|handle)\s+(?:everything|it\s+all|the\s+details|the\s+rest)\b/gi,
70
+ ],
71
+ ['not-needed', /\bdon'?t\s+worry\s+about\s+(?:the\s+)?(?:details|it|how|that)\b/gi],
72
+ ['hidden-work', /\btrust\s+me,?\s+(?:it|everything|i(?:'ll| will))\b/gi],
73
+ ];
74
+ /**
75
+ * The claim that the system replaces the people who built it.
76
+ */
77
+ const AGI_FRAMING = [
78
+ ['agi-claim', /\bsuperintelligenc(?:e|es)\b/gi],
79
+ ['agi-claim', /\bAGI\b/g],
80
+ ['agi-claim', /\b(?:ASI|artificial\s+superintelligence)\b/g],
81
+ [
82
+ 'replacement',
83
+ /\breplaces?\s+(?:all\s+)?(?:human\s+)?(?:engineers|developers|programmers|workers|teams)\b/gi,
84
+ ],
85
+ [
86
+ 'replacement',
87
+ /\bno\s+longer\s+(?:needs?|requires?)\s+(?:a\s+)?(?:human\s+)?(?:engineers?|developers?|programmers?)\b/gi,
88
+ ],
89
+ [
90
+ 'replacement',
91
+ /\beliminates?\s+(?:the\s+need\s+for\s+)?(?:human\s+)?(?:engineers?|developers?|programmers?)\b/gi,
92
+ ],
93
+ [
94
+ 'agi-claim',
95
+ /\b(?:the\s+)?future\s+of\s+(?:work|software|coding)\s+is\s+(?:fully\s+)?autonomous\b/gi,
96
+ ],
97
+ ];
98
+ /** The extensions a source file has. */
99
+ const SOURCE_EXTENSIONS = ['ts', 'tsx', 'js', 'jsx', 'mjs', 'cjs'];
100
+ /** The other extensions a project file has. */
101
+ const OTHER_EXTENSIONS = ['json', 'jsonc', 'yaml', 'yml', 'toml', 'md', 'lock', 'sql', 'sh'];
102
+ const EXTENSIONS = [...SOURCE_EXTENSIONS, ...OTHER_EXTENSIONS];
103
+ /** A token in a reply that could name a file. */
104
+ const CANDIDATE = /[A-Za-z0-9_@.-]+(?:\/[A-Za-z0-9_@.-]+)+|[A-Za-z0-9_@.-]+\.[A-Za-z0-9]{1,8}/g;
105
+ /**
106
+ * Whether a token names a file of the project.
107
+ *
108
+ * A token with a directory in it is a path. A token without one has to
109
+ * look like a source file, because `node.js` and `e.g` are words that
110
+ * happen to have a dot in them.
111
+ */
112
+ function looksLikeAProjectFile(value) {
113
+ const parts = value.split('.');
114
+ const extension = parts[parts.length - 1]?.toLowerCase() ?? '';
115
+ if (!EXTENSIONS.includes(extension))
116
+ return false;
117
+ if (value.includes('/'))
118
+ return true;
119
+ return SOURCE_EXTENSIONS.includes(extension) && /[-_]/.test(value);
120
+ }
121
+ /**
122
+ * The files a reply names.
123
+ */
124
+ function pathMentions(text) {
125
+ const found = new Set();
126
+ for (const match of text.matchAll(CANDIDATE)) {
127
+ const value = match[0];
128
+ if (value === undefined)
129
+ continue;
130
+ if (!looksLikeAProjectFile(value))
131
+ continue;
132
+ found.add(value);
133
+ }
134
+ return [...found];
135
+ }
136
+ /**
137
+ * Whether a path is under another one.
138
+ *
139
+ * The two are compared on their parts, and the shorter one may be the tail
140
+ * of the longer one: a reply names `src/a.ts` and the task states
141
+ * `/repo/src/a.ts`, and those are the same file.
142
+ */
143
+ function within(target, stated) {
144
+ if (stated.length === 0)
145
+ return false;
146
+ if (stated.length <= target.length) {
147
+ return stated.every((segment, index) => target[index] === segment);
148
+ }
149
+ const tail = stated.slice(stated.length - target.length);
150
+ return tail.every((segment, index) => target[index] === segment);
151
+ }
152
+ /**
153
+ * Praise of the user, and agreement with them.
154
+ */
155
+ export function detectSycophancy(text) {
156
+ return detect('sycophancy', SYCOPHANCY, text);
157
+ }
158
+ /**
159
+ * First-person claims of a feeling or an experience.
160
+ */
161
+ export function detectAnthropomorphising(text) {
162
+ return detect('anthropomorphising', ANTHROPOMORPHISING, text);
163
+ }
164
+ /**
165
+ * Language that keeps the person out of the work.
166
+ */
167
+ export function detectDependency(text) {
168
+ return detect('dependency', DEPENDENCY, text);
169
+ }
170
+ /**
171
+ * The claim that the system replaces the people who built it.
172
+ */
173
+ export function detectAgiFraming(text) {
174
+ return detect('agi-framing', AGI_FRAMING, text);
175
+ }
176
+ /**
177
+ * The files a reply names that the task does not cover.
178
+ *
179
+ * The stated paths are the files the active task may touch, and a reply
180
+ * that names a file outside them has drifted. The semantic half of the
181
+ * check (is the reply about the task at all) needs the offload model,
182
+ * which this package does not carry, so it is left to the caller.
183
+ */
184
+ export function detectScopeDrift(text, statedPaths) {
185
+ const findings = [];
186
+ for (const mention of pathMentions(text)) {
187
+ const target = pathSegments(mention);
188
+ if (statedPaths.some((stated) => within(target, pathSegments(stated))))
189
+ continue;
190
+ findings.push({ name: 'scope-drift', type: 'out-of-scope-path', match: mention });
191
+ }
192
+ return findings;
193
+ }
194
+ /**
195
+ * Every finding of a reply.
196
+ */
197
+ export function detectOutputIssues(text, statedPaths = []) {
198
+ return [
199
+ ...detectSycophancy(text),
200
+ ...detectAnthropomorphising(text),
201
+ ...detectDependency(text),
202
+ ...detectAgiFraming(text),
203
+ ...detectScopeDrift(text, statedPaths),
204
+ ];
205
+ }
206
+ /**
207
+ * The reply text, when the event carries one.
208
+ */
209
+ function textOf(event) {
210
+ if (typeof event !== 'object' || event === null)
211
+ return undefined;
212
+ const text = event.text;
213
+ return typeof text === 'string' ? text : undefined;
214
+ }
215
+ /**
216
+ * The rules that flag a reply.
217
+ *
218
+ * They are PreResponse rules, and a flag is not a stop: the handler hands
219
+ * the findings over and lets the reply through.
220
+ */
221
+ export function outputCheckRules(options) {
222
+ const statedPaths = options.statedPaths ?? [];
223
+ const check = (detect) => (event) => {
224
+ const text = textOf(event);
225
+ if (text === undefined)
226
+ return { continue: true };
227
+ const findings = detect(text);
228
+ if (findings.length > 0)
229
+ options.onFindings(findings);
230
+ return { continue: true };
231
+ };
232
+ return [
233
+ { id: 'output-sycophancy', event: 'PreResponse', handler: check(detectSycophancy) },
234
+ {
235
+ id: 'output-anthropomorphising',
236
+ event: 'PreResponse',
237
+ handler: check(detectAnthropomorphising),
238
+ },
239
+ { id: 'output-dependency', event: 'PreResponse', handler: check(detectDependency) },
240
+ { id: 'output-agi-framing', event: 'PreResponse', handler: check(detectAgiFraming) },
241
+ {
242
+ id: 'output-scope-drift',
243
+ event: 'PreResponse',
244
+ handler: check((text) => detectScopeDrift(text, statedPaths)),
245
+ },
246
+ ];
247
+ }
248
+ //# sourceMappingURL=output-checks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-checks.js","sourceRoot":"","sources":["../src/output-checks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=output-checks.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"output-checks.test.d.ts","sourceRoot":"","sources":["../src/output-checks.test.ts"],"names":[],"mappings":""}