audrey 0.21.0 → 1.0.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 (346) hide show
  1. package/CHANGELOG.md +238 -0
  2. package/LICENSE +21 -21
  3. package/README.md +281 -33
  4. package/SECURITY.md +30 -0
  5. package/benchmarks/adapter-kit.mjs +20 -0
  6. package/benchmarks/adapter-self-test.mjs +166 -0
  7. package/benchmarks/adapters/example-allow.mjs +28 -0
  8. package/benchmarks/adapters/mem0-platform.mjs +267 -0
  9. package/benchmarks/adapters/registry.json +51 -0
  10. package/benchmarks/adapters/zep-cloud.mjs +280 -0
  11. package/benchmarks/baselines.js +169 -0
  12. package/benchmarks/build-leaderboard.mjs +170 -0
  13. package/benchmarks/cases.js +537 -0
  14. package/benchmarks/create-conformance-card.mjs +139 -0
  15. package/benchmarks/create-submission-bundle.mjs +176 -0
  16. package/benchmarks/dry-run-external-adapters.mjs +165 -0
  17. package/benchmarks/guardbench.js +1035 -0
  18. package/benchmarks/output/adapter-self-test/guardbench-adapter-self-test.json +50 -0
  19. package/benchmarks/output/external/guardbench-external-dry-run.json +69 -0
  20. package/benchmarks/output/external/guardbench-external-evidence.json +56 -0
  21. package/benchmarks/output/guardbench-conformance-card.json +63 -0
  22. package/benchmarks/output/guardbench-manifest.json +414 -0
  23. package/benchmarks/output/guardbench-raw.json +1171 -0
  24. package/benchmarks/output/guardbench-summary.json +1981 -0
  25. package/benchmarks/output/leaderboard/guardbench-leaderboard.json +93 -0
  26. package/benchmarks/output/leaderboard/guardbench-leaderboard.md +7 -0
  27. package/benchmarks/output/submission-bundle/guardbench-conformance-card.json +63 -0
  28. package/benchmarks/output/submission-bundle/guardbench-manifest.json +414 -0
  29. package/benchmarks/output/submission-bundle/guardbench-raw.json +1171 -0
  30. package/benchmarks/output/submission-bundle/guardbench-summary.json +1981 -0
  31. package/benchmarks/output/submission-bundle/schemas/guardbench-adapter-registry.schema.json +69 -0
  32. package/benchmarks/output/submission-bundle/schemas/guardbench-adapter-self-test.schema.json +156 -0
  33. package/benchmarks/output/submission-bundle/schemas/guardbench-conformance-card.schema.json +184 -0
  34. package/benchmarks/output/submission-bundle/schemas/guardbench-external-dry-run.schema.json +74 -0
  35. package/benchmarks/output/submission-bundle/schemas/guardbench-external-evidence.schema.json +108 -0
  36. package/benchmarks/output/submission-bundle/schemas/guardbench-external-run.schema.json +160 -0
  37. package/benchmarks/output/submission-bundle/schemas/guardbench-leaderboard.schema.json +179 -0
  38. package/benchmarks/output/submission-bundle/schemas/guardbench-manifest.schema.json +213 -0
  39. package/benchmarks/output/submission-bundle/schemas/guardbench-publication-verification.schema.json +47 -0
  40. package/benchmarks/output/submission-bundle/schemas/guardbench-raw.schema.json +164 -0
  41. package/benchmarks/output/submission-bundle/schemas/guardbench-submission-manifest.schema.json +151 -0
  42. package/benchmarks/output/submission-bundle/schemas/guardbench-summary.schema.json +228 -0
  43. package/benchmarks/output/submission-bundle/submission-manifest.json +131 -0
  44. package/benchmarks/output/submission-bundle/validation-report.json +31 -0
  45. package/benchmarks/output/summary.json +2354 -0
  46. package/benchmarks/perf-snapshot.js +304 -0
  47. package/benchmarks/perf.bench.js +161 -0
  48. package/benchmarks/public-paths.mjs +78 -0
  49. package/benchmarks/reference-results.js +70 -0
  50. package/benchmarks/report.js +259 -0
  51. package/benchmarks/run-external-guardbench.mjs +281 -0
  52. package/benchmarks/run.js +682 -0
  53. package/benchmarks/schemas/guardbench-adapter-registry.schema.json +69 -0
  54. package/benchmarks/schemas/guardbench-adapter-self-test.schema.json +156 -0
  55. package/benchmarks/schemas/guardbench-conformance-card.schema.json +184 -0
  56. package/benchmarks/schemas/guardbench-external-dry-run.schema.json +74 -0
  57. package/benchmarks/schemas/guardbench-external-evidence.schema.json +108 -0
  58. package/benchmarks/schemas/guardbench-external-run.schema.json +160 -0
  59. package/benchmarks/schemas/guardbench-leaderboard.schema.json +179 -0
  60. package/benchmarks/schemas/guardbench-manifest.schema.json +213 -0
  61. package/benchmarks/schemas/guardbench-publication-verification.schema.json +47 -0
  62. package/benchmarks/schemas/guardbench-raw.schema.json +164 -0
  63. package/benchmarks/schemas/guardbench-submission-manifest.schema.json +151 -0
  64. package/benchmarks/schemas/guardbench-summary.schema.json +228 -0
  65. package/benchmarks/snapshots/perf-0.22.2.json +123 -0
  66. package/benchmarks/snapshots/perf-0.23.0.json +123 -0
  67. package/benchmarks/validate-adapter-module.mjs +104 -0
  68. package/benchmarks/validate-adapter-registry.mjs +134 -0
  69. package/benchmarks/validate-adapter-self-test.mjs +96 -0
  70. package/benchmarks/validate-guardbench-artifacts.mjs +343 -0
  71. package/benchmarks/verify-external-evidence.mjs +296 -0
  72. package/benchmarks/verify-publication-artifacts.mjs +286 -0
  73. package/benchmarks/verify-submission-bundle.mjs +167 -0
  74. package/dist/mcp-server/config.d.ts +5 -4
  75. package/dist/mcp-server/config.d.ts.map +1 -1
  76. package/dist/mcp-server/config.js +6 -8
  77. package/dist/mcp-server/config.js.map +1 -1
  78. package/dist/mcp-server/index.d.ts +281 -23
  79. package/dist/mcp-server/index.d.ts.map +1 -1
  80. package/dist/mcp-server/index.js +1186 -82
  81. package/dist/mcp-server/index.js.map +1 -1
  82. package/dist/src/action-key.d.ts +9 -0
  83. package/dist/src/action-key.d.ts.map +1 -0
  84. package/dist/src/action-key.js +49 -0
  85. package/dist/src/action-key.js.map +1 -0
  86. package/dist/src/adaptive.d.ts.map +1 -1
  87. package/dist/src/adaptive.js +8 -6
  88. package/dist/src/adaptive.js.map +1 -1
  89. package/dist/src/affect.d.ts +4 -1
  90. package/dist/src/affect.d.ts.map +1 -1
  91. package/dist/src/affect.js +14 -12
  92. package/dist/src/affect.js.map +1 -1
  93. package/dist/src/audrey.d.ts +57 -4
  94. package/dist/src/audrey.d.ts.map +1 -1
  95. package/dist/src/audrey.js +512 -65
  96. package/dist/src/audrey.js.map +1 -1
  97. package/dist/src/capsule.d.ts +2 -1
  98. package/dist/src/capsule.d.ts.map +1 -1
  99. package/dist/src/capsule.js +18 -8
  100. package/dist/src/capsule.js.map +1 -1
  101. package/dist/src/causal.d.ts.map +1 -1
  102. package/dist/src/causal.js +23 -5
  103. package/dist/src/causal.js.map +1 -1
  104. package/dist/src/confidence.d.ts.map +1 -1
  105. package/dist/src/confidence.js +3 -0
  106. package/dist/src/confidence.js.map +1 -1
  107. package/dist/src/consolidate.d.ts +1 -0
  108. package/dist/src/consolidate.d.ts.map +1 -1
  109. package/dist/src/consolidate.js +70 -54
  110. package/dist/src/consolidate.js.map +1 -1
  111. package/dist/src/controller.d.ts +94 -0
  112. package/dist/src/controller.d.ts.map +1 -0
  113. package/dist/src/controller.js +350 -0
  114. package/dist/src/controller.js.map +1 -0
  115. package/dist/src/db.d.ts.map +1 -1
  116. package/dist/src/db.js +181 -169
  117. package/dist/src/db.js.map +1 -1
  118. package/dist/src/decay.d.ts.map +1 -1
  119. package/dist/src/decay.js +62 -55
  120. package/dist/src/decay.js.map +1 -1
  121. package/dist/src/embedding.d.ts +2 -1
  122. package/dist/src/embedding.d.ts.map +1 -1
  123. package/dist/src/embedding.js +60 -22
  124. package/dist/src/embedding.js.map +1 -1
  125. package/dist/src/encode.d.ts +9 -2
  126. package/dist/src/encode.d.ts.map +1 -1
  127. package/dist/src/encode.js +25 -12
  128. package/dist/src/encode.js.map +1 -1
  129. package/dist/src/export.d.ts.map +1 -1
  130. package/dist/src/export.js +5 -3
  131. package/dist/src/export.js.map +1 -1
  132. package/dist/src/feedback.d.ts +35 -0
  133. package/dist/src/feedback.d.ts.map +1 -0
  134. package/dist/src/feedback.js +129 -0
  135. package/dist/src/feedback.js.map +1 -0
  136. package/dist/src/forget.d.ts.map +1 -1
  137. package/dist/src/forget.js +68 -60
  138. package/dist/src/forget.js.map +1 -1
  139. package/dist/src/fts.js +1 -1
  140. package/dist/src/fts.js.map +1 -1
  141. package/dist/src/hybrid-recall.d.ts +2 -1
  142. package/dist/src/hybrid-recall.d.ts.map +1 -1
  143. package/dist/src/hybrid-recall.js +41 -32
  144. package/dist/src/hybrid-recall.js.map +1 -1
  145. package/dist/src/impact.d.ts +47 -0
  146. package/dist/src/impact.d.ts.map +1 -0
  147. package/dist/src/impact.js +146 -0
  148. package/dist/src/impact.js.map +1 -0
  149. package/dist/src/import.d.ts +177 -1
  150. package/dist/src/import.d.ts.map +1 -1
  151. package/dist/src/import.js +235 -46
  152. package/dist/src/import.js.map +1 -1
  153. package/dist/src/index.d.ts +5 -1
  154. package/dist/src/index.d.ts.map +1 -1
  155. package/dist/src/index.js +3 -1
  156. package/dist/src/index.js.map +1 -1
  157. package/dist/src/interference.d.ts +5 -2
  158. package/dist/src/interference.d.ts.map +1 -1
  159. package/dist/src/interference.js +39 -32
  160. package/dist/src/interference.js.map +1 -1
  161. package/dist/src/introspect.js +18 -18
  162. package/dist/src/llm.d.ts.map +1 -1
  163. package/dist/src/llm.js +1 -0
  164. package/dist/src/llm.js.map +1 -1
  165. package/dist/src/migrate.d.ts.map +1 -1
  166. package/dist/src/migrate.js +21 -9
  167. package/dist/src/migrate.js.map +1 -1
  168. package/dist/src/preflight.d.ts +2 -1
  169. package/dist/src/preflight.d.ts.map +1 -1
  170. package/dist/src/preflight.js +66 -5
  171. package/dist/src/preflight.js.map +1 -1
  172. package/dist/src/profile.d.ts +23 -0
  173. package/dist/src/profile.d.ts.map +1 -0
  174. package/dist/src/profile.js +51 -0
  175. package/dist/src/profile.js.map +1 -0
  176. package/dist/src/promote.d.ts.map +1 -1
  177. package/dist/src/promote.js +8 -9
  178. package/dist/src/promote.js.map +1 -1
  179. package/dist/src/prompts.d.ts.map +1 -1
  180. package/dist/src/prompts.js +165 -136
  181. package/dist/src/prompts.js.map +1 -1
  182. package/dist/src/recall.d.ts +9 -6
  183. package/dist/src/recall.d.ts.map +1 -1
  184. package/dist/src/recall.js +204 -62
  185. package/dist/src/recall.js.map +1 -1
  186. package/dist/src/redact.d.ts +7 -1
  187. package/dist/src/redact.d.ts.map +1 -1
  188. package/dist/src/redact.js +94 -11
  189. package/dist/src/redact.js.map +1 -1
  190. package/dist/src/reflexes.d.ts +1 -0
  191. package/dist/src/reflexes.d.ts.map +1 -1
  192. package/dist/src/reflexes.js +3 -0
  193. package/dist/src/reflexes.js.map +1 -1
  194. package/dist/src/rollback.d.ts.map +1 -1
  195. package/dist/src/rollback.js +13 -8
  196. package/dist/src/rollback.js.map +1 -1
  197. package/dist/src/routes.d.ts +1 -0
  198. package/dist/src/routes.d.ts.map +1 -1
  199. package/dist/src/routes.js +251 -6
  200. package/dist/src/routes.js.map +1 -1
  201. package/dist/src/rules-compiler.d.ts.map +1 -1
  202. package/dist/src/rules-compiler.js +36 -6
  203. package/dist/src/rules-compiler.js.map +1 -1
  204. package/dist/src/server.d.ts +2 -1
  205. package/dist/src/server.d.ts.map +1 -1
  206. package/dist/src/server.js +42 -4
  207. package/dist/src/server.js.map +1 -1
  208. package/dist/src/tool-trace.d.ts.map +1 -1
  209. package/dist/src/tool-trace.js +42 -29
  210. package/dist/src/tool-trace.js.map +1 -1
  211. package/dist/src/types.d.ts +28 -1
  212. package/dist/src/types.d.ts.map +1 -1
  213. package/dist/src/ulid.d.ts.map +1 -1
  214. package/dist/src/ulid.js +52 -2
  215. package/dist/src/ulid.js.map +1 -1
  216. package/dist/src/utils.d.ts.map +1 -1
  217. package/dist/src/utils.js +8 -1
  218. package/dist/src/utils.js.map +1 -1
  219. package/dist/src/validate.d.ts +2 -0
  220. package/dist/src/validate.d.ts.map +1 -1
  221. package/dist/src/validate.js +77 -46
  222. package/dist/src/validate.js.map +1 -1
  223. package/docs/AUDREY_PAPER_OUTLINE.md +175 -0
  224. package/docs/MEMORY_BENCHMARKING.md +59 -0
  225. package/docs/PRODUCTION_BACKLOG.md +304 -0
  226. package/docs/paper/00-master.md +48 -0
  227. package/docs/paper/01-introduction.md +27 -0
  228. package/docs/paper/02-related-work.md +47 -0
  229. package/docs/paper/03-problem-definition.md +108 -0
  230. package/docs/paper/04-design.md +164 -0
  231. package/docs/paper/05-guardbench-spec.md +412 -0
  232. package/docs/paper/06-implementation.md +113 -0
  233. package/docs/paper/07-evaluation.md +168 -0
  234. package/docs/paper/08-discussion-limitations.md +61 -0
  235. package/docs/paper/09-conclusion.md +11 -0
  236. package/docs/paper/SUBMISSION_README.md +162 -0
  237. package/docs/paper/appendix-a-demo-transcript.md +114 -0
  238. package/docs/paper/arxiv-compile-report.schema.json +116 -0
  239. package/docs/paper/arxiv-source.schema.json +61 -0
  240. package/docs/paper/audrey-paper-v1.md +1106 -0
  241. package/docs/paper/browser-launch-plan.json +209 -0
  242. package/docs/paper/browser-launch-plan.schema.json +100 -0
  243. package/docs/paper/browser-launch-results.json +86 -0
  244. package/docs/paper/browser-launch-results.schema.json +66 -0
  245. package/docs/paper/claim-register.json +138 -0
  246. package/docs/paper/claim-register.schema.json +81 -0
  247. package/docs/paper/evidence-ledger.md +103 -0
  248. package/docs/paper/output/arxiv/README-arxiv.txt +8 -0
  249. package/docs/paper/output/arxiv/arxiv-manifest.json +41 -0
  250. package/docs/paper/output/arxiv/main.tex +949 -0
  251. package/docs/paper/output/arxiv/references.bib +222 -0
  252. package/docs/paper/output/arxiv-compile-report.json +24 -0
  253. package/docs/paper/output/submission-bundle/LICENSE +21 -0
  254. package/docs/paper/output/submission-bundle/README.md +533 -0
  255. package/docs/paper/output/submission-bundle/benchmarks/output/adapter-self-test/guardbench-adapter-self-test.json +50 -0
  256. package/docs/paper/output/submission-bundle/benchmarks/output/external/guardbench-external-dry-run.json +69 -0
  257. package/docs/paper/output/submission-bundle/benchmarks/output/external/guardbench-external-evidence.json +56 -0
  258. package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-conformance-card.json +63 -0
  259. package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-manifest.json +414 -0
  260. package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-raw.json +1171 -0
  261. package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-summary.json +1981 -0
  262. package/docs/paper/output/submission-bundle/benchmarks/output/leaderboard/guardbench-leaderboard.json +93 -0
  263. package/docs/paper/output/submission-bundle/benchmarks/output/leaderboard/guardbench-leaderboard.md +7 -0
  264. package/docs/paper/output/submission-bundle/benchmarks/output/submission-bundle/submission-manifest.json +131 -0
  265. package/docs/paper/output/submission-bundle/benchmarks/output/submission-bundle/validation-report.json +31 -0
  266. package/docs/paper/output/submission-bundle/benchmarks/output/summary.json +2354 -0
  267. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-adapter-registry.schema.json +69 -0
  268. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-adapter-self-test.schema.json +156 -0
  269. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-conformance-card.schema.json +184 -0
  270. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-external-dry-run.schema.json +74 -0
  271. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-external-evidence.schema.json +108 -0
  272. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-external-run.schema.json +160 -0
  273. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-leaderboard.schema.json +179 -0
  274. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-manifest.schema.json +213 -0
  275. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-publication-verification.schema.json +47 -0
  276. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-raw.schema.json +164 -0
  277. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-submission-manifest.schema.json +151 -0
  278. package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-summary.schema.json +228 -0
  279. package/docs/paper/output/submission-bundle/docs/AUDREY_PAPER_OUTLINE.md +175 -0
  280. package/docs/paper/output/submission-bundle/docs/paper/00-master.md +48 -0
  281. package/docs/paper/output/submission-bundle/docs/paper/01-introduction.md +27 -0
  282. package/docs/paper/output/submission-bundle/docs/paper/02-related-work.md +47 -0
  283. package/docs/paper/output/submission-bundle/docs/paper/03-problem-definition.md +108 -0
  284. package/docs/paper/output/submission-bundle/docs/paper/04-design.md +164 -0
  285. package/docs/paper/output/submission-bundle/docs/paper/05-guardbench-spec.md +412 -0
  286. package/docs/paper/output/submission-bundle/docs/paper/06-implementation.md +113 -0
  287. package/docs/paper/output/submission-bundle/docs/paper/07-evaluation.md +168 -0
  288. package/docs/paper/output/submission-bundle/docs/paper/08-discussion-limitations.md +61 -0
  289. package/docs/paper/output/submission-bundle/docs/paper/09-conclusion.md +11 -0
  290. package/docs/paper/output/submission-bundle/docs/paper/SUBMISSION_README.md +162 -0
  291. package/docs/paper/output/submission-bundle/docs/paper/appendix-a-demo-transcript.md +114 -0
  292. package/docs/paper/output/submission-bundle/docs/paper/arxiv-compile-report.schema.json +116 -0
  293. package/docs/paper/output/submission-bundle/docs/paper/arxiv-source.schema.json +61 -0
  294. package/docs/paper/output/submission-bundle/docs/paper/audrey-paper-v1.md +1106 -0
  295. package/docs/paper/output/submission-bundle/docs/paper/browser-launch-plan.json +209 -0
  296. package/docs/paper/output/submission-bundle/docs/paper/browser-launch-plan.schema.json +100 -0
  297. package/docs/paper/output/submission-bundle/docs/paper/browser-launch-results.json +86 -0
  298. package/docs/paper/output/submission-bundle/docs/paper/browser-launch-results.schema.json +66 -0
  299. package/docs/paper/output/submission-bundle/docs/paper/claim-register.json +138 -0
  300. package/docs/paper/output/submission-bundle/docs/paper/claim-register.schema.json +81 -0
  301. package/docs/paper/output/submission-bundle/docs/paper/evidence-ledger.md +103 -0
  302. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/README-arxiv.txt +8 -0
  303. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/arxiv-manifest.json +41 -0
  304. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/main.tex +949 -0
  305. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/references.bib +222 -0
  306. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv-compile-report.json +24 -0
  307. package/docs/paper/output/submission-bundle/docs/paper/paper-submission-bundle.schema.json +70 -0
  308. package/docs/paper/output/submission-bundle/docs/paper/publication-pack.json +81 -0
  309. package/docs/paper/output/submission-bundle/docs/paper/publication-pack.schema.json +60 -0
  310. package/docs/paper/output/submission-bundle/docs/paper/references.bib +222 -0
  311. package/docs/paper/output/submission-bundle/package.json +212 -0
  312. package/docs/paper/output/submission-bundle/paper-submission-manifest.json +379 -0
  313. package/docs/paper/paper-submission-bundle.schema.json +70 -0
  314. package/docs/paper/publication-pack.json +81 -0
  315. package/docs/paper/publication-pack.schema.json +60 -0
  316. package/docs/paper/references.bib +222 -0
  317. package/package.json +103 -26
  318. package/scripts/audit-release-completion.mjs +362 -0
  319. package/scripts/create-arxiv-source.mjs +362 -0
  320. package/scripts/create-paper-submission-bundle.mjs +210 -0
  321. package/scripts/finalize-release.mjs +526 -0
  322. package/scripts/prepare-release-cut.mjs +269 -0
  323. package/scripts/publish-release-bundle.mjs +209 -0
  324. package/scripts/publish-release-github-api.mjs +429 -0
  325. package/scripts/run-vitest.mjs +34 -0
  326. package/scripts/smoke-cli.js +72 -0
  327. package/scripts/sync-paper-artifacts.mjs +109 -0
  328. package/scripts/verify-arxiv-compile.mjs +440 -0
  329. package/scripts/verify-arxiv-source.mjs +194 -0
  330. package/scripts/verify-browser-launch-plan.mjs +237 -0
  331. package/scripts/verify-browser-launch-results.mjs +285 -0
  332. package/scripts/verify-paper-artifacts.mjs +338 -0
  333. package/scripts/verify-paper-claims.mjs +226 -0
  334. package/scripts/verify-paper-submission-bundle.mjs +207 -0
  335. package/scripts/verify-publication-pack.mjs +196 -0
  336. package/scripts/verify-python-package.py +201 -0
  337. package/scripts/verify-release-readiness.mjs +741 -0
  338. package/docs/assets/benchmarks/local-benchmark.svg +0 -45
  339. package/docs/assets/benchmarks/operations-benchmark.svg +0 -45
  340. package/docs/assets/benchmarks/published-memory-standards.svg +0 -50
  341. package/docs/audrey-for-dummies.md +0 -670
  342. package/docs/benchmarking.md +0 -151
  343. package/docs/future-of-llm-memory.md +0 -452
  344. package/docs/mcp-hosts.md +0 -206
  345. package/docs/ollama-local-agents.md +0 -128
  346. package/docs/production-readiness.md +0 -128
@@ -0,0 +1,526 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawnSync } from 'node:child_process';
4
+ import { createHash } from 'node:crypto';
5
+ import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
6
+ import { dirname, isAbsolute, join, relative, resolve } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
+
9
+ const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
10
+ const DEFAULT_VERSION = '1.0.0';
11
+ const DEFAULT_ARTIFACT_DIR = '.tmp/release-artifacts';
12
+ const NPM_REGISTRY = 'https://registry.npmjs.org/';
13
+ const RELEASE_COMMANDS = new Set(['git', 'node', 'npm', 'python']);
14
+ const RELEASE_VERSION_PATTERN = /^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/;
15
+ const INHERITED_ENV_KEYS = [
16
+ 'PATH',
17
+ 'Path',
18
+ 'PATHEXT',
19
+ 'SystemRoot',
20
+ 'SYSTEMROOT',
21
+ 'WINDIR',
22
+ 'HOME',
23
+ 'USERPROFILE',
24
+ 'APPDATA',
25
+ 'LOCALAPPDATA',
26
+ 'TEMP',
27
+ 'TMP',
28
+ 'NPM_CONFIG_USERCONFIG',
29
+ 'NPM_TOKEN',
30
+ 'TWINE_USERNAME',
31
+ 'TWINE_PASSWORD',
32
+ ];
33
+
34
+ function fromRoot(path) {
35
+ return resolve(ROOT, path);
36
+ }
37
+
38
+ function readJson(path) {
39
+ return JSON.parse(readFileSync(fromRoot(path), 'utf-8'));
40
+ }
41
+
42
+ function safeString(value, label) {
43
+ if (typeof value !== 'string' || value.length === 0 || value.includes('\0')) {
44
+ throw new Error(`${label} must be a non-empty string without NUL bytes`);
45
+ }
46
+ return value;
47
+ }
48
+
49
+ function safeVersion(value) {
50
+ const version = safeString(value, '--version');
51
+ if (!RELEASE_VERSION_PATTERN.test(version)) {
52
+ throw new Error(`Invalid release version: ${version}`);
53
+ }
54
+ return version;
55
+ }
56
+
57
+ function safeRepoRelativePath(value, label) {
58
+ const raw = safeString(value, label);
59
+ const resolved = fromRoot(raw);
60
+ const rel = relative(ROOT, resolved);
61
+ if (!rel || rel.startsWith('..') || isAbsolute(rel)) {
62
+ throw new Error(`${label} must stay inside the Audrey repository`);
63
+ }
64
+ return rel.replaceAll('\\', '/');
65
+ }
66
+
67
+ function normalizeArgs(args) {
68
+ args.version = safeVersion(args.version);
69
+ args.artifactDir = safeRepoRelativePath(args.artifactDir, '--artifact-dir');
70
+ if (args.commitMessage !== null) args.commitMessage = safeString(args.commitMessage, '--commit-message');
71
+ if (args.npmOtp !== null) args.npmOtp = safeString(args.npmOtp, '--npm-otp');
72
+ return args;
73
+ }
74
+
75
+ function releaseEnv(extra = {}) {
76
+ const env = {};
77
+ for (const key of INHERITED_ENV_KEYS) {
78
+ if (process.env[key]) env[key] = process.env[key];
79
+ }
80
+ for (const [key, value] of Object.entries(extra)) {
81
+ env[key] = safeString(String(value), `environment ${key}`);
82
+ }
83
+ return {
84
+ ...env,
85
+ GIT_TERMINAL_PROMPT: '0',
86
+ GCM_INTERACTIVE: 'never',
87
+ GIT_ASKPASS: '',
88
+ SSH_ASKPASS: '',
89
+ TWINE_NON_INTERACTIVE: '1',
90
+ };
91
+ }
92
+
93
+ function parseArgs(argv = process.argv.slice(2)) {
94
+ const args = {
95
+ version: DEFAULT_VERSION,
96
+ artifactDir: DEFAULT_ARTIFACT_DIR,
97
+ apply: false,
98
+ json: false,
99
+ commit: false,
100
+ tag: false,
101
+ push: false,
102
+ pack: false,
103
+ sourceBundle: false,
104
+ publishNpm: false,
105
+ publishPypi: false,
106
+ npmOtp: null,
107
+ commitMessage: null,
108
+ };
109
+
110
+ for (let i = 0; i < argv.length; i++) {
111
+ const token = argv[i];
112
+ if ((token === '--version' || token === '--target-version') && argv[i + 1]) args.version = argv[++i];
113
+ else if (token === '--artifact-dir' && argv[i + 1]) args.artifactDir = argv[++i];
114
+ else if (token === '--commit-message' && argv[i + 1]) args.commitMessage = argv[++i];
115
+ else if (token === '--npm-otp' && argv[i + 1]) args.npmOtp = argv[++i];
116
+ else if (token === '--apply') args.apply = true;
117
+ else if (token === '--json') args.json = true;
118
+ else if (token === '--commit') args.commit = true;
119
+ else if (token === '--tag') args.tag = true;
120
+ else if (token === '--push') args.push = true;
121
+ else if (token === '--pack') args.pack = true;
122
+ else if (token === '--source-bundle') args.sourceBundle = true;
123
+ else if (token === '--publish-npm') args.publishNpm = true;
124
+ else if (token === '--publish-pypi') args.publishPypi = true;
125
+ else if (token === '--all') {
126
+ args.commit = true;
127
+ args.tag = true;
128
+ args.push = true;
129
+ args.pack = true;
130
+ args.sourceBundle = true;
131
+ args.publishNpm = true;
132
+ args.publishPypi = true;
133
+ } else if (token === '--help' || token === '-h') args.help = true;
134
+ else throw new Error(`Unknown argument: ${token}`);
135
+ }
136
+
137
+ return normalizeArgs(args);
138
+ }
139
+
140
+ function usage() {
141
+ return `Usage: node scripts/finalize-release.mjs [options]
142
+
143
+ Options:
144
+ --apply Execute selected release actions. Dry-run by default.
145
+ --version <version> Release version. Default: ${DEFAULT_VERSION}.
146
+ --artifact-dir <path> Local ignored artifact directory. Default: ${DEFAULT_ARTIFACT_DIR}.
147
+ --commit git add + commit the release candidate.
148
+ --tag Create annotated v<version> tag.
149
+ --push Push HEAD and tags to origin/master.
150
+ --pack Create npm tarball and artifact manifest.
151
+ --source-bundle Create ignored Git bundle for external source publication.
152
+ --publish-npm Publish the packaged npm tarball.
153
+ --publish-pypi Upload Python wheel/sdist with twine.
154
+ --npm-otp <code> Optional npm one-time password.
155
+ --commit-message <message> Override the default release commit message.
156
+ --all Commit, tag, push, pack, and publish npm/PyPI.
157
+ --json Print the machine-readable plan/report.
158
+ `;
159
+ }
160
+
161
+ function commandFor(command, args) {
162
+ if (!RELEASE_COMMANDS.has(command)) {
163
+ throw new Error(`Unsupported release command: ${command}`);
164
+ }
165
+ const safeArgs = args.map((arg, index) => safeString(String(arg), `${command} argument ${index + 1}`));
166
+ if (process.platform === 'win32' && command === 'npm') {
167
+ return { command: 'cmd.exe', args: ['/d', '/c', 'npm', ...safeArgs] };
168
+ }
169
+ return { command, args: safeArgs };
170
+ }
171
+
172
+ function run(command, args, options = {}) {
173
+ const prepared = commandFor(command, args);
174
+ const result = spawnSync(prepared.command, prepared.args, {
175
+ cwd: ROOT,
176
+ encoding: 'utf-8',
177
+ stdio: options.stdio ?? 'pipe',
178
+ timeout: options.timeout ?? 120_000,
179
+ env: releaseEnv(options.env),
180
+ });
181
+ return {
182
+ command: [command, ...args].join(' '),
183
+ ok: result.status === 0,
184
+ status: result.status,
185
+ stdout: result.stdout?.trim() ?? '',
186
+ stderr: result.stderr?.trim() ?? '',
187
+ error: result.error?.message ?? null,
188
+ };
189
+ }
190
+
191
+ function commandFailure(result) {
192
+ return result.error || result.stderr || result.stdout || `exited ${result.status}`;
193
+ }
194
+
195
+ function assertOk(result) {
196
+ if (!result.ok) throw new Error(`${result.command} failed: ${commandFailure(result)}`);
197
+ return result;
198
+ }
199
+
200
+ function sha256(path) {
201
+ return createHash('sha256').update(readFileSync(path)).digest('hex');
202
+ }
203
+
204
+ function listArtifacts(artifactDir, version) {
205
+ const files = [];
206
+ const npmTarball = join(artifactDir, `audrey-${version}.tgz`);
207
+ const gitBundle = join(artifactDir, `audrey-${version}.git.bundle`);
208
+ if (existsSync(npmTarball)) files.push(npmTarball);
209
+ if (existsSync(gitBundle)) files.push(gitBundle);
210
+
211
+ const pythonDist = fromRoot('python/dist');
212
+ if (existsSync(pythonDist)) {
213
+ for (const name of readdirSync(pythonDist)) {
214
+ if (name.includes(version) && (name.endsWith('.whl') || name.endsWith('.tar.gz'))) {
215
+ files.push(join(pythonDist, name));
216
+ }
217
+ }
218
+ }
219
+
220
+ return files.map(path => ({
221
+ path: path.startsWith(ROOT) ? path.slice(ROOT.length + 1).replaceAll('\\', '/') : path.replaceAll('\\', '/'),
222
+ sha256: sha256(path),
223
+ bytes: readFileSync(path).byteLength,
224
+ }));
225
+ }
226
+
227
+ function npmTarballPath(artifactDir, version) {
228
+ return join(artifactDir, `audrey-${version}.tgz`);
229
+ }
230
+
231
+ function pythonArtifactPaths(version) {
232
+ const dist = fromRoot('python/dist');
233
+ if (!existsSync(dist)) return [];
234
+ return readdirSync(dist)
235
+ .filter(name => name.includes(version) && (name.endsWith('.whl') || name.endsWith('.tar.gz')))
236
+ .map(name => join('python/dist', name));
237
+ }
238
+
239
+ function pypiCredentialEnv() {
240
+ if (process.env.TWINE_PASSWORD) return {};
241
+ const token = process.env.PYPI_API_TOKEN ?? process.env.UV_PUBLISH_TOKEN;
242
+ if (!token) return null;
243
+ return {
244
+ TWINE_USERNAME: process.env.TWINE_USERNAME ?? '__token__',
245
+ TWINE_PASSWORD: token,
246
+ };
247
+ }
248
+
249
+ function selectedActions(args) {
250
+ return [
251
+ args.commit && 'commit',
252
+ args.tag && 'tag',
253
+ args.push && 'push',
254
+ args.pack && 'pack',
255
+ args.sourceBundle && 'source-bundle',
256
+ args.publishNpm && 'publish-npm',
257
+ args.publishPypi && 'publish-pypi',
258
+ ].filter(Boolean);
259
+ }
260
+
261
+ function ensurePackageVersion(version) {
262
+ const pkg = readJson('package.json');
263
+ if (pkg.version !== version) {
264
+ throw new Error(`package.json version is ${pkg.version}, expected ${version}`);
265
+ }
266
+ return pkg;
267
+ }
268
+
269
+ function buildPlan(args) {
270
+ const pkg = ensurePackageVersion(args.version);
271
+ const tagName = `v${args.version}`;
272
+ const artifactDir = fromRoot(args.artifactDir);
273
+ const commitMessage = args.commitMessage ?? `Release Audrey ${args.version}`;
274
+ const actions = selectedActions(args);
275
+ const commands = [];
276
+ const blockers = [];
277
+
278
+ commands.push('node scripts/verify-release-readiness.mjs --allow-pending --json');
279
+ if (args.commit) commands.push('git add --all', `git commit -m "${commitMessage}"`);
280
+ if (args.tag) commands.push(`git tag -a ${tagName} -m "Audrey ${args.version}"`);
281
+ if (args.push) commands.push(`git push origin HEAD:master --follow-tags`);
282
+ if (args.pack) commands.push(`npm pack --pack-destination ${args.artifactDir}`);
283
+ if (args.sourceBundle) commands.push(`git bundle create ${args.artifactDir}/audrey-${args.version}.git.bundle refs/heads/master refs/tags/v${args.version}`);
284
+ if (args.publishNpm) {
285
+ const otp = args.npmOtp ? ' --otp <provided>' : '';
286
+ commands.push(`npm publish ${args.artifactDir}/audrey-${args.version}.tgz --access public --registry ${NPM_REGISTRY}${otp}`);
287
+ }
288
+ if (args.publishPypi) commands.push(`python -m twine upload python/dist/audrey_memory-${args.version}*`);
289
+
290
+ if (actions.length === 0) {
291
+ blockers.push('Select at least one action such as --pack, --source-bundle, --commit, --tag, --push, --publish-npm, or --publish-pypi');
292
+ }
293
+ if (args.publishPypi && !pypiCredentialEnv()) {
294
+ blockers.push('Set TWINE_PASSWORD, PYPI_API_TOKEN, or UV_PUBLISH_TOKEN before --publish-pypi');
295
+ }
296
+
297
+ return {
298
+ schemaVersion: '1.0.0',
299
+ suite: 'Audrey release finalization',
300
+ generatedAt: new Date().toISOString(),
301
+ apply: args.apply,
302
+ version: args.version,
303
+ packageName: pkg.name,
304
+ tagName,
305
+ artifactDir: args.artifactDir,
306
+ actions,
307
+ commands,
308
+ blockers,
309
+ results: [],
310
+ artifacts: listArtifacts(artifactDir, args.version),
311
+ };
312
+ }
313
+
314
+ function runReadiness(plan) {
315
+ const readiness = run('node', ['scripts/verify-release-readiness.mjs', '--allow-pending', '--json'], { timeout: 180_000 });
316
+ plan.results.push(readiness);
317
+ assertOk(readiness);
318
+ const report = JSON.parse(readiness.stdout);
319
+ if (!report.ok) {
320
+ throw new Error(`release readiness failed: ${report.failures?.join('; ') || 'unknown failure'}`);
321
+ }
322
+ plan.readiness = {
323
+ ok: report.ok,
324
+ ready: report.ready,
325
+ blockers: report.blockers ?? [],
326
+ };
327
+ }
328
+
329
+ function gitObjectEnv(timestamp) {
330
+ const objectDir = fromRoot('.tmp/git-object-store');
331
+ const indexFile = fromRoot('.tmp/release.index');
332
+ return {
333
+ GIT_OBJECT_DIRECTORY: objectDir,
334
+ GIT_ALTERNATE_OBJECT_DIRECTORIES: fromRoot('.git/objects'),
335
+ GIT_INDEX_FILE: indexFile,
336
+ GIT_AUTHOR_NAME: 'Tyler Eveland',
337
+ GIT_AUTHOR_EMAIL: 'j.tyler.eveland@gmail.com',
338
+ GIT_COMMITTER_NAME: 'Tyler Eveland',
339
+ GIT_COMMITTER_EMAIL: 'j.tyler.eveland@gmail.com',
340
+ GIT_AUTHOR_DATE: `${timestamp} -0500`,
341
+ GIT_COMMITTER_DATE: `${timestamp} -0500`,
342
+ };
343
+ }
344
+
345
+ function createSourceBundle(args, plan) {
346
+ const objectDir = fromRoot('.tmp/git-object-store');
347
+ const indexFile = fromRoot('.tmp/release.index');
348
+ const gitDir = fromRoot('.tmp/release-gitdir');
349
+ const artifactDir = fromRoot(args.artifactDir);
350
+ const bundlePath = join(artifactDir, `audrey-${args.version}.git.bundle`);
351
+ const headTime = assertOk(run('git', ['show', '-s', '--format=%ct', 'HEAD'])).stdout;
352
+ const timestamp = Number.parseInt(headTime, 10) + 1;
353
+ const env = gitObjectEnv(timestamp);
354
+
355
+ rmSync(objectDir, { recursive: true, force: true });
356
+ rmSync(indexFile, { force: true });
357
+ rmSync(gitDir, { recursive: true, force: true });
358
+ mkdirSync(objectDir, { recursive: true });
359
+ mkdirSync(artifactDir, { recursive: true });
360
+
361
+ for (const result of [
362
+ run('git', ['read-tree', 'HEAD'], { env }),
363
+ run('git', ['add', '--all'], { env }),
364
+ ]) {
365
+ plan.results.push(result);
366
+ assertOk(result);
367
+ }
368
+
369
+ const tree = assertOk(run('git', ['write-tree'], { env })).stdout;
370
+ const commit = assertOk(run('git', ['commit-tree', tree, '-p', 'HEAD', '-m', args.commitMessage ?? `Release Audrey ${args.version}`], { env })).stdout;
371
+ const tagContent = [
372
+ `object ${commit}`,
373
+ 'type commit',
374
+ `tag v${args.version}`,
375
+ `tagger Tyler Eveland <j.tyler.eveland@gmail.com> ${timestamp + 1} -0500`,
376
+ '',
377
+ `Audrey ${args.version}`,
378
+ '',
379
+ ].join('\n');
380
+ const tagFile = fromRoot('.tmp/release-tag.txt');
381
+ writeFileSync(tagFile, tagContent, 'utf-8');
382
+ const tag = assertOk(run('git', ['hash-object', '-t', 'tag', '-w', tagFile], { env })).stdout;
383
+
384
+ mkdirSync(join(gitDir, 'refs', 'heads'), { recursive: true });
385
+ mkdirSync(join(gitDir, 'refs', 'tags'), { recursive: true });
386
+ writeFileSync(join(gitDir, 'HEAD'), 'ref: refs/heads/master\n', 'utf-8');
387
+ writeFileSync(join(gitDir, 'config'), '[core]\n\trepositoryformatversion = 0\n\tfilemode = false\n\tbare = true\n', 'utf-8');
388
+ writeFileSync(join(gitDir, 'refs', 'heads', 'master'), `${commit}\n`, 'utf-8');
389
+ writeFileSync(join(gitDir, 'refs', 'tags', `v${args.version}`), `${tag}\n`, 'utf-8');
390
+
391
+ const bundle = run('git', ['--git-dir', gitDir, 'bundle', 'create', bundlePath, 'refs/heads/master', `refs/tags/v${args.version}`], {
392
+ env: {
393
+ GIT_OBJECT_DIRECTORY: objectDir,
394
+ GIT_ALTERNATE_OBJECT_DIRECTORIES: fromRoot('.git/objects'),
395
+ },
396
+ timeout: 180_000,
397
+ });
398
+ plan.results.push(bundle);
399
+ assertOk(bundle);
400
+
401
+ const verify = run('git', ['bundle', 'verify', bundlePath], { timeout: 60_000 });
402
+ plan.results.push(verify);
403
+ assertOk(verify);
404
+
405
+ const objectReport = {
406
+ tree,
407
+ commit,
408
+ tag,
409
+ objectDir: '.tmp/git-object-store',
410
+ indexFile: '.tmp/release.index',
411
+ bundle: args.artifactDir.replaceAll('\\', '/') + `/audrey-${args.version}.git.bundle`,
412
+ };
413
+ writeFileSync(fromRoot('.tmp/release-git-object-report.json'), `${JSON.stringify(objectReport, null, 2)}\n`, 'utf-8');
414
+ plan.sourceControl = objectReport;
415
+ }
416
+
417
+ function execute(args, plan) {
418
+ const artifactDir = fromRoot(args.artifactDir);
419
+ mkdirSync(artifactDir, { recursive: true });
420
+ runReadiness(plan);
421
+
422
+ if (args.commit) {
423
+ assertOk(run('git', ['add', '--all']));
424
+ const commitMessage = args.commitMessage ?? `Release Audrey ${args.version}`;
425
+ const commit = run('git', ['commit', '-m', commitMessage]);
426
+ plan.results.push(commit);
427
+ assertOk(commit);
428
+ }
429
+
430
+ if (args.tag) {
431
+ const tag = run('git', ['tag', '-a', `v${args.version}`, '-m', `Audrey ${args.version}`]);
432
+ plan.results.push(tag);
433
+ assertOk(tag);
434
+ }
435
+
436
+ if (args.push) {
437
+ const push = run('git', [
438
+ '-c',
439
+ 'http.sslBackend=openssl',
440
+ '-c',
441
+ 'credential.helper=',
442
+ '-c',
443
+ 'core.askPass=',
444
+ 'push',
445
+ 'origin',
446
+ 'HEAD:master',
447
+ '--follow-tags',
448
+ ], { timeout: 45_000 });
449
+ plan.results.push(push);
450
+ assertOk(push);
451
+ }
452
+
453
+ if (args.pack || args.publishNpm) {
454
+ const pack = run('npm', ['pack', '--pack-destination', args.artifactDir], { timeout: 180_000 });
455
+ plan.results.push(pack);
456
+ assertOk(pack);
457
+ }
458
+
459
+ if (args.sourceBundle) {
460
+ createSourceBundle(args, plan);
461
+ }
462
+
463
+ if (args.publishNpm) {
464
+ const whoami = run('npm', ['whoami', '--registry', NPM_REGISTRY]);
465
+ plan.results.push(whoami);
466
+ assertOk(whoami);
467
+ const publishArgs = ['publish', npmTarballPath(args.artifactDir, args.version), '--access', 'public', '--registry', NPM_REGISTRY];
468
+ if (args.npmOtp) publishArgs.push('--otp', args.npmOtp);
469
+ const publish = run('npm', publishArgs, { timeout: 180_000 });
470
+ plan.results.push(publish);
471
+ assertOk(publish);
472
+ }
473
+
474
+ if (args.publishPypi) {
475
+ const uploadEnv = pypiCredentialEnv();
476
+ if (!uploadEnv) throw new Error('Missing PyPI credentials: set TWINE_PASSWORD, PYPI_API_TOKEN, or UV_PUBLISH_TOKEN');
477
+ const build = run('npm', ['run', 'python:release:check'], { timeout: 180_000 });
478
+ plan.results.push(build);
479
+ assertOk(build);
480
+ const artifacts = pythonArtifactPaths(args.version);
481
+ if (artifacts.length === 0) throw new Error(`No Python artifacts found for ${args.version}`);
482
+ const upload = run('python', ['-m', 'twine', 'upload', ...artifacts], { timeout: 180_000, env: uploadEnv });
483
+ plan.results.push(upload);
484
+ assertOk(upload);
485
+ }
486
+
487
+ plan.artifacts = listArtifacts(artifactDir, args.version);
488
+ writeFileSync(join(artifactDir, 'release-finalize-report.json'), `${JSON.stringify(plan, null, 2)}\n`, 'utf-8');
489
+ }
490
+
491
+ function printPlan(plan, json) {
492
+ if (json) {
493
+ console.log(JSON.stringify(plan, null, 2));
494
+ return;
495
+ }
496
+
497
+ console.log(`${plan.apply ? 'Ran' : 'Planned'} Audrey ${plan.version} release finalization`);
498
+ console.log(`Actions: ${plan.actions.length ? plan.actions.join(', ') : 'none selected'}`);
499
+ for (const command of plan.commands) console.log(`- ${command}`);
500
+ if (plan.blockers.length) {
501
+ console.log('Blockers:');
502
+ for (const blocker of plan.blockers) console.log(`- ${blocker}`);
503
+ }
504
+ if (plan.artifacts.length) {
505
+ console.log('Artifacts:');
506
+ for (const artifact of plan.artifacts) console.log(`- ${artifact.path} sha256=${artifact.sha256}`);
507
+ }
508
+ }
509
+
510
+ async function main() {
511
+ const args = parseArgs();
512
+ if (args.help) {
513
+ console.log(usage());
514
+ return;
515
+ }
516
+
517
+ const plan = buildPlan(args);
518
+ if (args.apply && plan.blockers.length === 0) execute(args, plan);
519
+ printPlan(plan, args.json);
520
+ if (plan.blockers.length) process.exit(1);
521
+ }
522
+
523
+ main().catch(error => {
524
+ console.error(error.message);
525
+ process.exit(1);
526
+ });