audrey 1.0.1 → 1.0.2

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 (227) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +5 -3
  3. package/benchmarks/adapter-self-test.mjs +6 -2
  4. package/benchmarks/adapters/example-allow.mjs +5 -2
  5. package/benchmarks/adapters/mem0-platform.mjs +19 -12
  6. package/benchmarks/adapters/zep-cloud.mjs +51 -27
  7. package/benchmarks/baselines.js +11 -6
  8. package/benchmarks/build-leaderboard.mjs +36 -23
  9. package/benchmarks/cases.js +24 -12
  10. package/benchmarks/create-conformance-card.mjs +12 -3
  11. package/benchmarks/create-submission-bundle.mjs +22 -8
  12. package/benchmarks/dry-run-external-adapters.mjs +24 -12
  13. package/benchmarks/guardbench.js +263 -123
  14. package/benchmarks/output/adapter-self-test/guardbench-adapter-self-test.json +4 -4
  15. package/benchmarks/output/external/guardbench-external-dry-run.json +1 -1
  16. package/benchmarks/output/external/guardbench-external-evidence.json +1 -1
  17. package/benchmarks/output/guardbench-conformance-card.json +11 -11
  18. package/benchmarks/output/guardbench-raw.json +107 -108
  19. package/benchmarks/output/guardbench-summary.json +170 -172
  20. package/benchmarks/output/leaderboard/guardbench-leaderboard.json +5 -5
  21. package/benchmarks/output/leaderboard/guardbench-leaderboard.md +2 -2
  22. package/benchmarks/output/submission-bundle/guardbench-conformance-card.json +11 -11
  23. package/benchmarks/output/submission-bundle/guardbench-raw.json +107 -108
  24. package/benchmarks/output/submission-bundle/guardbench-summary.json +170 -172
  25. package/benchmarks/output/submission-bundle/submission-manifest.json +11 -11
  26. package/benchmarks/output/submission-bundle/validation-report.json +1 -1
  27. package/benchmarks/output/summary.json +57 -57
  28. package/benchmarks/perf-snapshot.js +12 -9
  29. package/benchmarks/perf.bench.js +14 -6
  30. package/benchmarks/public-paths.mjs +11 -5
  31. package/benchmarks/reference-results.js +10 -5
  32. package/benchmarks/report.js +48 -27
  33. package/benchmarks/run-external-guardbench.mjs +47 -25
  34. package/benchmarks/run.js +112 -59
  35. package/benchmarks/validate-adapter-module.mjs +13 -10
  36. package/benchmarks/validate-adapter-registry.mjs +16 -5
  37. package/benchmarks/validate-guardbench-artifacts.mjs +76 -19
  38. package/benchmarks/verify-external-evidence.mjs +86 -31
  39. package/benchmarks/verify-publication-artifacts.mjs +34 -11
  40. package/benchmarks/verify-submission-bundle.mjs +9 -4
  41. package/dist/mcp-server/config.d.ts +1 -1
  42. package/dist/mcp-server/config.d.ts.map +1 -1
  43. package/dist/mcp-server/config.js +5 -3
  44. package/dist/mcp-server/config.js.map +1 -1
  45. package/dist/mcp-server/index.d.ts +4 -3
  46. package/dist/mcp-server/index.d.ts.map +1 -1
  47. package/dist/mcp-server/index.js +479 -172
  48. package/dist/mcp-server/index.js.map +1 -1
  49. package/dist/src/action-key.d.ts.map +1 -1
  50. package/dist/src/action-key.js +6 -2
  51. package/dist/src/action-key.js.map +1 -1
  52. package/dist/src/adaptive.d.ts.map +1 -1
  53. package/dist/src/adaptive.js +4 -2
  54. package/dist/src/adaptive.js.map +1 -1
  55. package/dist/src/affect.d.ts.map +1 -1
  56. package/dist/src/affect.js +8 -5
  57. package/dist/src/affect.js.map +1 -1
  58. package/dist/src/audrey.d.ts +1 -1
  59. package/dist/src/audrey.d.ts.map +1 -1
  60. package/dist/src/audrey.js +93 -49
  61. package/dist/src/audrey.js.map +1 -1
  62. package/dist/src/capsule.d.ts.map +1 -1
  63. package/dist/src/capsule.js +37 -15
  64. package/dist/src/capsule.js.map +1 -1
  65. package/dist/src/causal.d.ts +1 -1
  66. package/dist/src/causal.d.ts.map +1 -1
  67. package/dist/src/causal.js +4 -2
  68. package/dist/src/causal.js.map +1 -1
  69. package/dist/src/confidence.d.ts.map +1 -1
  70. package/dist/src/confidence.js +5 -5
  71. package/dist/src/confidence.js.map +1 -1
  72. package/dist/src/consolidate.d.ts.map +1 -1
  73. package/dist/src/consolidate.js +17 -9
  74. package/dist/src/consolidate.js.map +1 -1
  75. package/dist/src/context.js +1 -1
  76. package/dist/src/context.js.map +1 -1
  77. package/dist/src/controller.d.ts.map +1 -1
  78. package/dist/src/controller.js +24 -13
  79. package/dist/src/controller.js.map +1 -1
  80. package/dist/src/db.d.ts.map +1 -1
  81. package/dist/src/db.js +78 -27
  82. package/dist/src/db.js.map +1 -1
  83. package/dist/src/decay.d.ts +1 -1
  84. package/dist/src/decay.d.ts.map +1 -1
  85. package/dist/src/decay.js +1 -1
  86. package/dist/src/decay.js.map +1 -1
  87. package/dist/src/embedding.d.ts +12 -4
  88. package/dist/src/embedding.d.ts.map +1 -1
  89. package/dist/src/embedding.js +18 -16
  90. package/dist/src/embedding.js.map +1 -1
  91. package/dist/src/encode.d.ts.map +1 -1
  92. package/dist/src/encode.js +5 -4
  93. package/dist/src/encode.js.map +1 -1
  94. package/dist/src/events.d.ts +3 -2
  95. package/dist/src/events.d.ts.map +1 -1
  96. package/dist/src/events.js +7 -3
  97. package/dist/src/events.js.map +1 -1
  98. package/dist/src/export.d.ts.map +1 -1
  99. package/dist/src/export.js +21 -7
  100. package/dist/src/export.js.map +1 -1
  101. package/dist/src/feedback.d.ts.map +1 -1
  102. package/dist/src/feedback.js +1 -1
  103. package/dist/src/feedback.js.map +1 -1
  104. package/dist/src/forget.d.ts.map +1 -1
  105. package/dist/src/forget.js +12 -6
  106. package/dist/src/forget.js.map +1 -1
  107. package/dist/src/fts.d.ts.map +1 -1
  108. package/dist/src/fts.js +20 -8
  109. package/dist/src/fts.js.map +1 -1
  110. package/dist/src/hybrid-recall.d.ts.map +1 -1
  111. package/dist/src/hybrid-recall.js +12 -6
  112. package/dist/src/hybrid-recall.js.map +1 -1
  113. package/dist/src/impact.d.ts.map +1 -1
  114. package/dist/src/impact.js +26 -10
  115. package/dist/src/impact.js.map +1 -1
  116. package/dist/src/import.d.ts.map +1 -1
  117. package/dist/src/import.js +11 -6
  118. package/dist/src/import.js.map +1 -1
  119. package/dist/src/index.d.ts +3 -3
  120. package/dist/src/index.d.ts.map +1 -1
  121. package/dist/src/index.js +3 -3
  122. package/dist/src/index.js.map +1 -1
  123. package/dist/src/interference.d.ts.map +1 -1
  124. package/dist/src/interference.js +10 -5
  125. package/dist/src/interference.js.map +1 -1
  126. package/dist/src/introspect.d.ts.map +1 -1
  127. package/dist/src/introspect.js +12 -6
  128. package/dist/src/introspect.js.map +1 -1
  129. package/dist/src/llm.d.ts +2 -2
  130. package/dist/src/llm.d.ts.map +1 -1
  131. package/dist/src/llm.js +6 -6
  132. package/dist/src/llm.js.map +1 -1
  133. package/dist/src/migrate.d.ts.map +1 -1
  134. package/dist/src/migrate.js +10 -4
  135. package/dist/src/migrate.js.map +1 -1
  136. package/dist/src/preflight.d.ts.map +1 -1
  137. package/dist/src/preflight.js +6 -8
  138. package/dist/src/preflight.js.map +1 -1
  139. package/dist/src/profile.d.ts.map +1 -1
  140. package/dist/src/profile.js.map +1 -1
  141. package/dist/src/promote.d.ts.map +1 -1
  142. package/dist/src/promote.js +16 -7
  143. package/dist/src/promote.js.map +1 -1
  144. package/dist/src/prompts.d.ts.map +1 -1
  145. package/dist/src/prompts.js +1 -2
  146. package/dist/src/prompts.js.map +1 -1
  147. package/dist/src/recall.d.ts.map +1 -1
  148. package/dist/src/recall.js +85 -18
  149. package/dist/src/recall.js.map +1 -1
  150. package/dist/src/redact.d.ts.map +1 -1
  151. package/dist/src/redact.js +9 -4
  152. package/dist/src/redact.js.map +1 -1
  153. package/dist/src/reflexes.d.ts.map +1 -1
  154. package/dist/src/reflexes.js +1 -7
  155. package/dist/src/reflexes.js.map +1 -1
  156. package/dist/src/rollback.d.ts.map +1 -1
  157. package/dist/src/rollback.js +4 -2
  158. package/dist/src/rollback.js.map +1 -1
  159. package/dist/src/routes.d.ts.map +1 -1
  160. package/dist/src/routes.js +33 -13
  161. package/dist/src/routes.js.map +1 -1
  162. package/dist/src/rules-compiler.d.ts.map +1 -1
  163. package/dist/src/rules-compiler.js +24 -2
  164. package/dist/src/rules-compiler.js.map +1 -1
  165. package/dist/src/server.js +2 -2
  166. package/dist/src/server.js.map +1 -1
  167. package/dist/src/tool-trace.d.ts +2 -2
  168. package/dist/src/tool-trace.d.ts.map +1 -1
  169. package/dist/src/tool-trace.js +12 -4
  170. package/dist/src/tool-trace.js.map +1 -1
  171. package/dist/src/types.d.ts.map +1 -1
  172. package/dist/src/ulid.js +1 -1
  173. package/dist/src/ulid.js.map +1 -1
  174. package/dist/src/utils.d.ts.map +1 -1
  175. package/dist/src/utils.js.map +1 -1
  176. package/dist/src/validate.d.ts.map +1 -1
  177. package/dist/src/validate.js +20 -10
  178. package/dist/src/validate.js.map +1 -1
  179. package/docs/paper/07-evaluation.md +5 -5
  180. package/docs/paper/audrey-paper-v1.md +5 -5
  181. package/docs/paper/evidence-ledger.md +1 -1
  182. package/docs/paper/output/arxiv/arxiv-manifest.json +4 -4
  183. package/docs/paper/output/arxiv/main.tex +5 -5
  184. package/docs/paper/output/arxiv-compile-report.json +3 -3
  185. package/docs/paper/output/submission-bundle/README.md +5 -3
  186. package/docs/paper/output/submission-bundle/benchmarks/output/adapter-self-test/guardbench-adapter-self-test.json +4 -4
  187. package/docs/paper/output/submission-bundle/benchmarks/output/external/guardbench-external-dry-run.json +1 -1
  188. package/docs/paper/output/submission-bundle/benchmarks/output/external/guardbench-external-evidence.json +1 -1
  189. package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-conformance-card.json +11 -11
  190. package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-raw.json +107 -108
  191. package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-summary.json +170 -172
  192. package/docs/paper/output/submission-bundle/benchmarks/output/leaderboard/guardbench-leaderboard.json +5 -5
  193. package/docs/paper/output/submission-bundle/benchmarks/output/leaderboard/guardbench-leaderboard.md +2 -2
  194. package/docs/paper/output/submission-bundle/benchmarks/output/submission-bundle/submission-manifest.json +11 -11
  195. package/docs/paper/output/submission-bundle/benchmarks/output/submission-bundle/validation-report.json +1 -1
  196. package/docs/paper/output/submission-bundle/benchmarks/output/summary.json +58 -58
  197. package/docs/paper/output/submission-bundle/docs/paper/07-evaluation.md +5 -5
  198. package/docs/paper/output/submission-bundle/docs/paper/audrey-paper-v1.md +5 -5
  199. package/docs/paper/output/submission-bundle/docs/paper/evidence-ledger.md +1 -1
  200. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/arxiv-manifest.json +4 -4
  201. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/main.tex +5 -5
  202. package/docs/paper/output/submission-bundle/docs/paper/output/arxiv-compile-report.json +3 -3
  203. package/docs/paper/output/submission-bundle/package.json +17 -4
  204. package/docs/paper/output/submission-bundle/paper-submission-manifest.json +36 -36
  205. package/examples/fintech-ops-demo.js +12 -5
  206. package/examples/healthcare-ops-demo.js +8 -4
  207. package/examples/ollama-memory-agent.js +41 -13
  208. package/examples/stripe-demo.js +12 -5
  209. package/package.json +17 -4
  210. package/scripts/audit-release-completion.mjs +179 -101
  211. package/scripts/create-arxiv-source.mjs +20 -14
  212. package/scripts/create-paper-submission-bundle.mjs +6 -2
  213. package/scripts/finalize-release.mjs +111 -36
  214. package/scripts/prepare-release-cut.mjs +14 -6
  215. package/scripts/publish-release-bundle.mjs +62 -23
  216. package/scripts/publish-release-github-api.mjs +89 -24
  217. package/scripts/smoke-cli.js +9 -9
  218. package/scripts/sync-paper-artifacts.mjs +5 -1
  219. package/scripts/verify-arxiv-compile.mjs +52 -16
  220. package/scripts/verify-arxiv-source.mjs +45 -15
  221. package/scripts/verify-browser-launch-plan.mjs +28 -11
  222. package/scripts/verify-browser-launch-results.mjs +32 -14
  223. package/scripts/verify-paper-artifacts.mjs +539 -79
  224. package/scripts/verify-paper-claims.mjs +48 -20
  225. package/scripts/verify-paper-submission-bundle.mjs +22 -11
  226. package/scripts/verify-publication-pack.mjs +23 -9
  227. package/scripts/verify-release-readiness.mjs +211 -76
@@ -67,7 +67,8 @@ function safeRepoRelativePath(value, label) {
67
67
  function normalizeArgs(args) {
68
68
  args.version = safeVersion(args.version);
69
69
  args.artifactDir = safeRepoRelativePath(args.artifactDir, '--artifact-dir');
70
- if (args.commitMessage !== null) args.commitMessage = safeString(args.commitMessage, '--commit-message');
70
+ if (args.commitMessage !== null)
71
+ args.commitMessage = safeString(args.commitMessage, '--commit-message');
71
72
  if (args.npmOtp !== null) args.npmOtp = safeString(args.npmOtp, '--npm-otp');
72
73
  return args;
73
74
  }
@@ -109,7 +110,8 @@ function parseArgs(argv = process.argv.slice(2)) {
109
110
 
110
111
  for (let i = 0; i < argv.length; i++) {
111
112
  const token = argv[i];
112
- if ((token === '--version' || token === '--target-version') && argv[i + 1]) args.version = argv[++i];
113
+ if ((token === '--version' || token === '--target-version') && argv[i + 1])
114
+ args.version = argv[++i];
113
115
  else if (token === '--artifact-dir' && argv[i + 1]) args.artifactDir = argv[++i];
114
116
  else if (token === '--commit-message' && argv[i + 1]) args.commitMessage = argv[++i];
115
117
  else if (token === '--npm-otp' && argv[i + 1]) args.npmOtp = argv[++i];
@@ -162,7 +164,9 @@ function commandFor(command, args) {
162
164
  if (!RELEASE_COMMANDS.has(command)) {
163
165
  throw new Error(`Unsupported release command: ${command}`);
164
166
  }
165
- const safeArgs = args.map((arg, index) => safeString(String(arg), `${command} argument ${index + 1}`));
167
+ const safeArgs = args.map((arg, index) =>
168
+ safeString(String(arg), `${command} argument ${index + 1}`),
169
+ );
166
170
  if (process.platform === 'win32' && command === 'npm') {
167
171
  return { command: 'cmd.exe', args: ['/d', '/c', 'npm', ...safeArgs] };
168
172
  }
@@ -218,7 +222,9 @@ function listArtifacts(artifactDir, version) {
218
222
  }
219
223
 
220
224
  return files.map(path => ({
221
- path: path.startsWith(ROOT) ? path.slice(ROOT.length + 1).replaceAll('\\', '/') : path.replaceAll('\\', '/'),
225
+ path: path.startsWith(ROOT)
226
+ ? path.slice(ROOT.length + 1).replaceAll('\\', '/')
227
+ : path.replaceAll('\\', '/'),
222
228
  sha256: sha256(path),
223
229
  bytes: readFileSync(path).byteLength,
224
230
  }));
@@ -280,15 +286,23 @@ function buildPlan(args) {
280
286
  if (args.tag) commands.push(`git tag -a ${tagName} -m "Audrey ${args.version}"`);
281
287
  if (args.push) commands.push(`git push origin HEAD:master --follow-tags`);
282
288
  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}`);
289
+ if (args.sourceBundle)
290
+ commands.push(
291
+ `git bundle create ${args.artifactDir}/audrey-${args.version}.git.bundle refs/heads/master refs/tags/v${args.version}`,
292
+ );
284
293
  if (args.publishNpm) {
285
294
  const otp = args.npmOtp ? ' --otp <provided>' : '';
286
- commands.push(`npm publish ${args.artifactDir}/audrey-${args.version}.tgz --access public --registry ${NPM_REGISTRY}${otp}`);
295
+ commands.push(
296
+ `npm publish ${args.artifactDir}/audrey-${args.version}.tgz --access public --registry ${NPM_REGISTRY}${otp}`,
297
+ );
287
298
  }
288
- if (args.publishPypi) commands.push(`python -m twine upload python/dist/audrey_memory-${args.version}*`);
299
+ if (args.publishPypi)
300
+ commands.push(`python -m twine upload python/dist/audrey_memory-${args.version}*`);
289
301
 
290
302
  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');
303
+ blockers.push(
304
+ 'Select at least one action such as --pack, --source-bundle, --commit, --tag, --push, --publish-npm, or --publish-pypi',
305
+ );
292
306
  }
293
307
  if (args.publishPypi && !pypiCredentialEnv()) {
294
308
  blockers.push('Set TWINE_PASSWORD, PYPI_API_TOKEN, or UV_PUBLISH_TOKEN before --publish-pypi');
@@ -312,12 +326,18 @@ function buildPlan(args) {
312
326
  }
313
327
 
314
328
  function runReadiness(plan) {
315
- const readiness = run('node', ['scripts/verify-release-readiness.mjs', '--allow-pending', '--json'], { timeout: 180_000 });
329
+ const readiness = run(
330
+ 'node',
331
+ ['scripts/verify-release-readiness.mjs', '--allow-pending', '--json'],
332
+ { timeout: 180_000 },
333
+ );
316
334
  plan.results.push(readiness);
317
335
  assertOk(readiness);
318
336
  const report = JSON.parse(readiness.stdout);
319
337
  if (!report.ok) {
320
- throw new Error(`release readiness failed: ${report.failures?.join('; ') || 'unknown failure'}`);
338
+ throw new Error(
339
+ `release readiness failed: ${report.failures?.join('; ') || 'unknown failure'}`,
340
+ );
321
341
  }
322
342
  plan.readiness = {
323
343
  ok: report.ok,
@@ -367,7 +387,20 @@ function createSourceBundle(args, plan) {
367
387
  }
368
388
 
369
389
  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;
390
+ const commit = assertOk(
391
+ run(
392
+ 'git',
393
+ [
394
+ 'commit-tree',
395
+ tree,
396
+ '-p',
397
+ 'HEAD',
398
+ '-m',
399
+ args.commitMessage ?? `Release Audrey ${args.version}`,
400
+ ],
401
+ { env },
402
+ ),
403
+ ).stdout;
371
404
  const tagContent = [
372
405
  `object ${commit}`,
373
406
  'type commit',
@@ -384,17 +417,33 @@ function createSourceBundle(args, plan) {
384
417
  mkdirSync(join(gitDir, 'refs', 'heads'), { recursive: true });
385
418
  mkdirSync(join(gitDir, 'refs', 'tags'), { recursive: true });
386
419
  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');
420
+ writeFileSync(
421
+ join(gitDir, 'config'),
422
+ '[core]\n\trepositoryformatversion = 0\n\tfilemode = false\n\tbare = true\n',
423
+ 'utf-8',
424
+ );
388
425
  writeFileSync(join(gitDir, 'refs', 'heads', 'master'), `${commit}\n`, 'utf-8');
389
426
  writeFileSync(join(gitDir, 'refs', 'tags', `v${args.version}`), `${tag}\n`, 'utf-8');
390
427
 
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'),
428
+ const bundle = run(
429
+ 'git',
430
+ [
431
+ '--git-dir',
432
+ gitDir,
433
+ 'bundle',
434
+ 'create',
435
+ bundlePath,
436
+ 'refs/heads/master',
437
+ `refs/tags/v${args.version}`,
438
+ ],
439
+ {
440
+ env: {
441
+ GIT_OBJECT_DIRECTORY: objectDir,
442
+ GIT_ALTERNATE_OBJECT_DIRECTORIES: fromRoot('.git/objects'),
443
+ },
444
+ timeout: 180_000,
395
445
  },
396
- timeout: 180_000,
397
- });
446
+ );
398
447
  plan.results.push(bundle);
399
448
  assertOk(bundle);
400
449
 
@@ -410,7 +459,11 @@ function createSourceBundle(args, plan) {
410
459
  indexFile: '.tmp/release.index',
411
460
  bundle: args.artifactDir.replaceAll('\\', '/') + `/audrey-${args.version}.git.bundle`,
412
461
  };
413
- writeFileSync(fromRoot('.tmp/release-git-object-report.json'), `${JSON.stringify(objectReport, null, 2)}\n`, 'utf-8');
462
+ writeFileSync(
463
+ fromRoot('.tmp/release-git-object-report.json'),
464
+ `${JSON.stringify(objectReport, null, 2)}\n`,
465
+ 'utf-8',
466
+ );
414
467
  plan.sourceControl = objectReport;
415
468
  }
416
469
 
@@ -434,18 +487,22 @@ function execute(args, plan) {
434
487
  }
435
488
 
436
489
  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 });
490
+ const push = run(
491
+ 'git',
492
+ [
493
+ '-c',
494
+ 'http.sslBackend=openssl',
495
+ '-c',
496
+ 'credential.helper=',
497
+ '-c',
498
+ 'core.askPass=',
499
+ 'push',
500
+ 'origin',
501
+ 'HEAD:master',
502
+ '--follow-tags',
503
+ ],
504
+ { timeout: 45_000 },
505
+ );
449
506
  plan.results.push(push);
450
507
  assertOk(push);
451
508
  }
@@ -464,7 +521,14 @@ function execute(args, plan) {
464
521
  const whoami = run('npm', ['whoami', '--registry', NPM_REGISTRY]);
465
522
  plan.results.push(whoami);
466
523
  assertOk(whoami);
467
- const publishArgs = ['publish', npmTarballPath(args.artifactDir, args.version), '--access', 'public', '--registry', NPM_REGISTRY];
524
+ const publishArgs = [
525
+ 'publish',
526
+ npmTarballPath(args.artifactDir, args.version),
527
+ '--access',
528
+ 'public',
529
+ '--registry',
530
+ NPM_REGISTRY,
531
+ ];
468
532
  if (args.npmOtp) publishArgs.push('--otp', args.npmOtp);
469
533
  const publish = run('npm', publishArgs, { timeout: 180_000 });
470
534
  plan.results.push(publish);
@@ -473,19 +537,29 @@ function execute(args, plan) {
473
537
 
474
538
  if (args.publishPypi) {
475
539
  const uploadEnv = pypiCredentialEnv();
476
- if (!uploadEnv) throw new Error('Missing PyPI credentials: set TWINE_PASSWORD, PYPI_API_TOKEN, or UV_PUBLISH_TOKEN');
540
+ if (!uploadEnv)
541
+ throw new Error(
542
+ 'Missing PyPI credentials: set TWINE_PASSWORD, PYPI_API_TOKEN, or UV_PUBLISH_TOKEN',
543
+ );
477
544
  const build = run('npm', ['run', 'python:release:check'], { timeout: 180_000 });
478
545
  plan.results.push(build);
479
546
  assertOk(build);
480
547
  const artifacts = pythonArtifactPaths(args.version);
481
548
  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 });
549
+ const upload = run('python', ['-m', 'twine', 'upload', ...artifacts], {
550
+ timeout: 180_000,
551
+ env: uploadEnv,
552
+ });
483
553
  plan.results.push(upload);
484
554
  assertOk(upload);
485
555
  }
486
556
 
487
557
  plan.artifacts = listArtifacts(artifactDir, args.version);
488
- writeFileSync(join(artifactDir, 'release-finalize-report.json'), `${JSON.stringify(plan, null, 2)}\n`, 'utf-8');
558
+ writeFileSync(
559
+ join(artifactDir, 'release-finalize-report.json'),
560
+ `${JSON.stringify(plan, null, 2)}\n`,
561
+ 'utf-8',
562
+ );
489
563
  }
490
564
 
491
565
  function printPlan(plan, json) {
@@ -503,7 +577,8 @@ function printPlan(plan, json) {
503
577
  }
504
578
  if (plan.artifacts.length) {
505
579
  console.log('Artifacts:');
506
- for (const artifact of plan.artifacts) console.log(`- ${artifact.path} sha256=${artifact.sha256}`);
580
+ for (const artifact of plan.artifacts)
581
+ console.log(`- ${artifact.path} sha256=${artifact.sha256}`);
507
582
  }
508
583
  }
509
584
 
@@ -4,7 +4,8 @@ import { fileURLToPath } from 'node:url';
4
4
 
5
5
  const ROOT = process.cwd();
6
6
  const DEFAULT_TARGET_VERSION = '1.0.0';
7
- const VERSION_RE = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
7
+ const VERSION_RE =
8
+ /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z.-]+)?(?:\+[0-9A-Za-z.-]+)?$/;
8
9
 
9
10
  function fromRoot(path) {
10
11
  return resolve(ROOT, path);
@@ -34,7 +35,8 @@ function parseArgs(argv = process.argv.slice(2)) {
34
35
 
35
36
  for (let i = 0; i < argv.length; i++) {
36
37
  const token = argv[i];
37
- if ((token === '--target-version' || token === '--version') && argv[i + 1]) args.targetVersion = argv[++i];
38
+ if ((token === '--target-version' || token === '--version') && argv[i + 1])
39
+ args.targetVersion = argv[++i];
38
40
  else if (token === '--date' && argv[i + 1]) args.date = argv[++i];
39
41
  else if (token === '--apply') args.apply = true;
40
42
  else if (token === '--json') args.json = true;
@@ -203,10 +205,14 @@ export function prepareReleaseCut(options = {}) {
203
205
  const versions = currentVersionSnapshot();
204
206
  const versionValues = Object.values(versions);
205
207
  const failures = [];
206
- if (versionValues.some(value => !value)) failures.push('One or more release version surfaces are missing');
207
- if (new Set(versionValues).size !== 1) failures.push(`Release version surfaces are not aligned: ${JSON.stringify(versions)}`);
208
+ if (versionValues.some(value => !value))
209
+ failures.push('One or more release version surfaces are missing');
210
+ if (new Set(versionValues).size !== 1)
211
+ failures.push(`Release version surfaces are not aligned: ${JSON.stringify(versions)}`);
208
212
  if (versions.packageJson && compareCoreVersions(targetVersion, versions.packageJson) < 0) {
209
- failures.push(`Target version ${targetVersion} is lower than current package version ${versions.packageJson}`);
213
+ failures.push(
214
+ `Target version ${targetVersion} is lower than current package version ${versions.packageJson}`,
215
+ );
210
216
  }
211
217
 
212
218
  const files = plannedFiles(targetVersion, date).map(([path, after]) => {
@@ -251,7 +257,9 @@ async function main() {
251
257
  console.log(JSON.stringify(report, null, 2));
252
258
  } else if (report.ok) {
253
259
  const changed = report.files.filter(file => file.changed).map(file => file.path);
254
- console.log(`${report.apply ? 'Applied' : 'Planned'} Audrey ${report.targetVersion} release cut: ${changed.length} file(s)`);
260
+ console.log(
261
+ `${report.apply ? 'Applied' : 'Planned'} Audrey ${report.targetVersion} release cut: ${changed.length} file(s)`,
262
+ );
255
263
  for (const file of changed) console.log(`- ${file}`);
256
264
  } else {
257
265
  console.error('Release cut preparation failed:');
@@ -22,7 +22,8 @@ function parseArgs(argv = process.argv.slice(2)) {
22
22
 
23
23
  for (let i = 0; i < argv.length; i++) {
24
24
  const token = argv[i];
25
- if ((token === '--version' || token === '--target-version') && argv[i + 1]) args.version = argv[++i];
25
+ if ((token === '--version' || token === '--target-version') && argv[i + 1])
26
+ args.version = argv[++i];
26
27
  else if (token === '--bundle' && argv[i + 1]) args.bundle = argv[++i];
27
28
  else if (token === '--remote' && argv[i + 1]) args.remote = argv[++i];
28
29
  else if (token === '--apply') args.apply = true;
@@ -72,7 +73,12 @@ function run(command, args, options = {}) {
72
73
  }
73
74
 
74
75
  function firstLine(result) {
75
- return `${result.stderr}\n${result.stdout}`.split(/\r?\n/).map(line => line.trim()).find(Boolean) ?? '';
76
+ return (
77
+ `${result.stderr}\n${result.stdout}`
78
+ .split(/\r?\n/)
79
+ .map(line => line.trim())
80
+ .find(Boolean) ?? ''
81
+ );
76
82
  }
77
83
 
78
84
  function parseBundleRefs(output, version) {
@@ -101,9 +107,27 @@ function parseRemoteRefs(output, version) {
101
107
  }
102
108
 
103
109
  function remoteHead(args) {
104
- let result = run('git', ['ls-remote', args.remote, 'refs/heads/master', `refs/tags/v${args.version}`], { timeout: 60_000 });
105
- if (!result.ok && /schannel|AcquireCredentialsHandle|SEC_E_NO_CREDENTIALS/i.test(firstLine(result))) {
106
- result = run('git', ['-c', 'http.sslBackend=openssl', 'ls-remote', args.remote, 'refs/heads/master', `refs/tags/v${args.version}`], { timeout: 60_000 });
110
+ let result = run(
111
+ 'git',
112
+ ['ls-remote', args.remote, 'refs/heads/master', `refs/tags/v${args.version}`],
113
+ { timeout: 60_000 },
114
+ );
115
+ if (
116
+ !result.ok &&
117
+ /schannel|AcquireCredentialsHandle|SEC_E_NO_CREDENTIALS/i.test(firstLine(result))
118
+ ) {
119
+ result = run(
120
+ 'git',
121
+ [
122
+ '-c',
123
+ 'http.sslBackend=openssl',
124
+ 'ls-remote',
125
+ args.remote,
126
+ 'refs/heads/master',
127
+ `refs/tags/v${args.version}`,
128
+ ],
129
+ { timeout: 60_000 },
130
+ );
107
131
  result.fallback = 'openssl';
108
132
  }
109
133
  return result;
@@ -112,20 +136,26 @@ function remoteHead(args) {
112
136
  function publishFromBundle(args, refs) {
113
137
  const temp = mkdtempSync(join(tmpdir(), 'audrey-release-push-'));
114
138
  try {
115
- const clone = run('git', ['clone', '--bare', resolve(ROOT, args.bundle), temp], { timeout: 120_000 });
139
+ const clone = run('git', ['clone', '--bare', resolve(ROOT, args.bundle), temp], {
140
+ timeout: 120_000,
141
+ });
116
142
  if (!clone.ok) return [clone];
117
- const push = run('git', [
118
- '-c',
119
- 'http.sslBackend=openssl',
120
- '-c',
121
- 'credential.helper=',
122
- '-c',
123
- 'core.askPass=',
124
- 'push',
125
- args.remote,
126
- `${refs.master}:refs/heads/master`,
127
- `${refs.tag}:refs/tags/v${args.version}`,
128
- ], { cwd: temp, timeout: 45_000 });
143
+ const push = run(
144
+ 'git',
145
+ [
146
+ '-c',
147
+ 'http.sslBackend=openssl',
148
+ '-c',
149
+ 'credential.helper=',
150
+ '-c',
151
+ 'core.askPass=',
152
+ 'push',
153
+ args.remote,
154
+ `${refs.master}:refs/heads/master`,
155
+ `${refs.tag}:refs/tags/v${args.version}`,
156
+ ],
157
+ { cwd: temp, timeout: 45_000 },
158
+ );
129
159
  return [clone, push];
130
160
  } finally {
131
161
  rmSync(temp, { recursive: true, force: true });
@@ -135,16 +165,22 @@ function publishFromBundle(args, refs) {
135
165
  export function planPublish(args) {
136
166
  const verify = run('git', ['bundle', 'verify', args.bundle], { timeout: 60_000 });
137
167
  const remote = remoteHead(args);
138
- const bundleRefs = verify.ok ? parseBundleRefs(verify.stdout, args.version) : { master: null, tag: null };
139
- const remoteRefs = remote.ok ? parseRemoteRefs(remote.stdout, args.version) : { master: null, tag: null };
168
+ const bundleRefs = verify.ok
169
+ ? parseBundleRefs(verify.stdout, args.version)
170
+ : { master: null, tag: null };
171
+ const remoteRefs = remote.ok
172
+ ? parseRemoteRefs(remote.stdout, args.version)
173
+ : { master: null, tag: null };
140
174
  const blockers = [];
141
175
 
142
176
  if (!verify.ok) blockers.push(`Bundle verification failed: ${firstLine(verify)}`);
143
177
  if (!bundleRefs.master) blockers.push('Bundle is missing refs/heads/master');
144
178
  if (!bundleRefs.tag) blockers.push(`Bundle is missing refs/tags/v${args.version}`);
145
179
  if (!remote.ok) blockers.push(`Remote check failed: ${firstLine(remote)}`);
146
- if (remoteRefs.tag && remoteRefs.tag !== bundleRefs.tag) blockers.push(`Remote v${args.version} already points at ${remoteRefs.tag}`);
147
- if (remoteRefs.master === bundleRefs.master && remoteRefs.tag === bundleRefs.tag) blockers.push('Remote already matches the release bundle');
180
+ if (remoteRefs.tag && remoteRefs.tag !== bundleRefs.tag)
181
+ blockers.push(`Remote v${args.version} already points at ${remoteRefs.tag}`);
182
+ if (remoteRefs.master === bundleRefs.master && remoteRefs.tag === bundleRefs.tag)
183
+ blockers.push('Remote already matches the release bundle');
148
184
 
149
185
  return {
150
186
  schemaVersion: '1.0.0',
@@ -198,7 +234,10 @@ async function main() {
198
234
  }
199
235
 
200
236
  function isDirectRun() {
201
- return Boolean(process.argv[1]) && resolve(process.argv[1]).toLowerCase() === fileURLToPath(import.meta.url).toLowerCase();
237
+ return (
238
+ Boolean(process.argv[1]) &&
239
+ resolve(process.argv[1]).toLowerCase() === fileURLToPath(import.meta.url).toLowerCase()
240
+ );
202
241
  }
203
242
 
204
243
  if (isDirectRun()) {
@@ -27,11 +27,14 @@ function parseArgs(argv = process.argv.slice(2)) {
27
27
 
28
28
  for (let i = 0; i < argv.length; i++) {
29
29
  const token = argv[i];
30
- if ((token === '--repository' || token === '--repo') && argv[i + 1]) args.repository = argv[++i];
30
+ if ((token === '--repository' || token === '--repo') && argv[i + 1])
31
+ args.repository = argv[++i];
31
32
  else if (token === '--branch' && argv[i + 1]) args.branch = argv[++i];
32
- else if ((token === '--version' || token === '--target-version') && argv[i + 1]) args.version = argv[++i];
33
+ else if ((token === '--version' || token === '--target-version') && argv[i + 1])
34
+ args.version = argv[++i];
33
35
  else if (token === '--token-env' && argv[i + 1]) args.tokenEnv = argv[++i];
34
- else if (token === '--concurrency' && argv[i + 1]) args.concurrency = Number.parseInt(argv[++i], 10);
36
+ else if (token === '--concurrency' && argv[i + 1])
37
+ args.concurrency = Number.parseInt(argv[++i], 10);
35
38
  else if (token === '--apply') args.apply = true;
36
39
  else if (token === '--json') args.json = true;
37
40
  else if (token === '--force') args.force = true;
@@ -84,7 +87,10 @@ function run(command, args, options = {}) {
84
87
  }
85
88
 
86
89
  function assertOk(result) {
87
- if (!result.ok) throw new Error(`${result.command} failed: ${result.stderr || result.stdout || result.error || result.status}`);
90
+ if (!result.ok)
91
+ throw new Error(
92
+ `${result.command} failed: ${result.stderr || result.stdout || result.error || result.status}`,
93
+ );
88
94
  return result.stdout;
89
95
  }
90
96
 
@@ -97,7 +103,9 @@ function normalized(path) {
97
103
  }
98
104
 
99
105
  function sha256(path) {
100
- return createHash('sha256').update(readFileSync(resolve(ROOT, path))).digest('hex');
106
+ return createHash('sha256')
107
+ .update(readFileSync(resolve(ROOT, path)))
108
+ .digest('hex');
101
109
  }
102
110
 
103
111
  function readJsonIfExists(path) {
@@ -106,9 +114,24 @@ function readJsonIfExists(path) {
106
114
  }
107
115
 
108
116
  function collectChangedPaths() {
109
- const changed = splitZ(assertOk(run('git', ['-c', 'core.quotepath=false', 'diff', '--name-only', '-z', 'HEAD', '--'])));
110
- const untracked = splitZ(assertOk(run('git', ['-c', 'core.quotepath=false', 'ls-files', '--others', '--exclude-standard', '-z'])));
111
- return [...new Set([...changed, ...untracked].map(normalized))].sort((a, b) => a.localeCompare(b));
117
+ const changed = splitZ(
118
+ assertOk(run('git', ['-c', 'core.quotepath=false', 'diff', '--name-only', '-z', 'HEAD', '--'])),
119
+ );
120
+ const untracked = splitZ(
121
+ assertOk(
122
+ run('git', [
123
+ '-c',
124
+ 'core.quotepath=false',
125
+ 'ls-files',
126
+ '--others',
127
+ '--exclude-standard',
128
+ '-z',
129
+ ]),
130
+ ),
131
+ );
132
+ return [...new Set([...changed, ...untracked].map(normalized))].sort((a, b) =>
133
+ a.localeCompare(b),
134
+ );
112
135
  }
113
136
 
114
137
  function fileMode(path) {
@@ -136,9 +159,34 @@ function changedEntries() {
136
159
  }
137
160
 
138
161
  function remoteRefs(repository, branch, version) {
139
- let result = run('git', ['ls-remote', `https://github.com/${repository}.git`, `refs/heads/${branch}`, `refs/tags/v${version}`], { timeout: 60_000 });
140
- if (!result.ok && /schannel|AcquireCredentialsHandle|SEC_E_NO_CREDENTIALS/i.test(`${result.stderr}\n${result.stdout}`)) {
141
- result = run('git', ['-c', 'http.sslBackend=openssl', 'ls-remote', `https://github.com/${repository}.git`, `refs/heads/${branch}`, `refs/tags/v${version}`], { timeout: 60_000 });
162
+ let result = run(
163
+ 'git',
164
+ [
165
+ 'ls-remote',
166
+ `https://github.com/${repository}.git`,
167
+ `refs/heads/${branch}`,
168
+ `refs/tags/v${version}`,
169
+ ],
170
+ { timeout: 60_000 },
171
+ );
172
+ if (
173
+ !result.ok &&
174
+ /schannel|AcquireCredentialsHandle|SEC_E_NO_CREDENTIALS/i.test(
175
+ `${result.stderr}\n${result.stdout}`,
176
+ )
177
+ ) {
178
+ result = run(
179
+ 'git',
180
+ [
181
+ '-c',
182
+ 'http.sslBackend=openssl',
183
+ 'ls-remote',
184
+ `https://github.com/${repository}.git`,
185
+ `refs/heads/${branch}`,
186
+ `refs/tags/v${version}`,
187
+ ],
188
+ { timeout: 60_000 },
189
+ );
142
190
  result.fallback = 'openssl';
143
191
  }
144
192
 
@@ -155,7 +203,10 @@ function remoteRefs(repository, branch, version) {
155
203
  }
156
204
 
157
205
  function releaseDates() {
158
- const headTime = Number.parseInt(assertOk(run('git', ['show', '-s', '--format=%ct', 'HEAD'])), 10);
206
+ const headTime = Number.parseInt(
207
+ assertOk(run('git', ['show', '-s', '--format=%ct', 'HEAD'])),
208
+ 10,
209
+ );
159
210
  const commitEpoch = headTime + 1;
160
211
  return {
161
212
  commitEpoch,
@@ -191,7 +242,9 @@ async function githubJson(token, repository, path, options = {}) {
191
242
  const payload = text ? JSON.parse(text) : null;
192
243
  if (!response.ok) {
193
244
  const message = payload?.message ?? text.slice(0, 500) ?? response.statusText;
194
- throw new Error(`GitHub API ${options.method ?? 'GET'} ${path} failed (${response.status}): ${message}`);
245
+ throw new Error(
246
+ `GitHub API ${options.method ?? 'GET'} ${path} failed (${response.status}): ${message}`,
247
+ );
195
248
  }
196
249
  return payload;
197
250
  }
@@ -238,12 +291,18 @@ function localState(args) {
238
291
  const bytes = entries.reduce((total, entry) => total + entry.bytes, 0);
239
292
  const blockers = [];
240
293
 
241
- if (!refs.result.ok) blockers.push(`Remote ref check failed: ${refs.result.stderr || refs.result.stdout || refs.result.error}`);
294
+ if (!refs.result.ok)
295
+ blockers.push(
296
+ `Remote ref check failed: ${refs.result.stderr || refs.result.stdout || refs.result.error}`,
297
+ );
242
298
  if (refs.branch && refs.branch !== localHead && !args.force) {
243
299
  blockers.push(`Remote ${args.branch} is ${refs.branch}, but local HEAD is ${localHead}`);
244
300
  }
245
301
  if (refs.tag) blockers.push(`Remote tag v${args.version} already exists at ${refs.tag}`);
246
- if (!objectReport?.commit || !objectReport?.tree) blockers.push('Missing .tmp/release-git-object-report.json; run npm run release:artifacts first');
302
+ if (!objectReport?.commit || !objectReport?.tree)
303
+ blockers.push(
304
+ 'Missing .tmp/release-git-object-report.json; run npm run release:artifacts first',
305
+ );
247
306
 
248
307
  return {
249
308
  localHead,
@@ -283,7 +342,9 @@ async function publishWithGitHubApi(args, state, token) {
283
342
  });
284
343
 
285
344
  if (state.expectedReleaseTree && tree.sha !== state.expectedReleaseTree) {
286
- throw new Error(`GitHub release tree ${tree.sha} does not match local source-bundle tree ${state.expectedReleaseTree}`);
345
+ throw new Error(
346
+ `GitHub release tree ${tree.sha} does not match local source-bundle tree ${state.expectedReleaseTree}`,
347
+ );
287
348
  }
288
349
 
289
350
  const dates = releaseDates();
@@ -300,7 +361,9 @@ async function publishWithGitHubApi(args, state, token) {
300
361
  });
301
362
 
302
363
  if (state.expectedReleaseCommit && commit.sha !== state.expectedReleaseCommit) {
303
- throw new Error(`GitHub release commit ${commit.sha} does not match local source-bundle commit ${state.expectedReleaseCommit}`);
364
+ throw new Error(
365
+ `GitHub release commit ${commit.sha} does not match local source-bundle commit ${state.expectedReleaseCommit}`,
366
+ );
304
367
  }
305
368
 
306
369
  const branchUpdate = await githubJson(token, args.repository, `/git/refs/heads/${args.branch}`, {
@@ -398,12 +461,12 @@ async function main() {
398
461
  })),
399
462
  changedEntries: args.includeEntries
400
463
  ? state.entries.map(entry => ({
401
- path: entry.path,
402
- deleted: entry.deleted,
403
- mode: entry.mode,
404
- bytes: entry.bytes,
405
- sha256: entry.sha256,
406
- }))
464
+ path: entry.path,
465
+ deleted: entry.deleted,
466
+ mode: entry.mode,
467
+ bytes: entry.bytes,
468
+ sha256: entry.sha256,
469
+ }))
407
470
  : undefined,
408
471
  finalizeArtifacts: state.finalizeArtifacts,
409
472
  blockers: [...state.blockers],
@@ -413,7 +476,9 @@ async function main() {
413
476
  if (args.apply) {
414
477
  const token = process.env[args.tokenEnv];
415
478
  if (!token) {
416
- report.blockers.push(`Set ${args.tokenEnv} to a GitHub token with contents:write before applying`);
479
+ report.blockers.push(
480
+ `Set ${args.tokenEnv} to a GitHub token with contents:write before applying`,
481
+ );
417
482
  } else if (report.blockers.length === 0) {
418
483
  report.publish = await publishWithGitHubApi(args, state, token);
419
484
  }
@@ -24,11 +24,9 @@ if (!existsSync(cli)) {
24
24
  }
25
25
 
26
26
  function createTempRoot() {
27
- const candidates = [
28
- process.env.AUDREY_SMOKE_TMPDIR,
29
- tmpdir(),
30
- join(root, '.tmp'),
31
- ].filter(Boolean);
27
+ const candidates = [process.env.AUDREY_SMOKE_TMPDIR, tmpdir(), join(root, '.tmp')].filter(
28
+ Boolean,
29
+ );
32
30
  const failures = [];
33
31
 
34
32
  for (const candidate of candidates) {
@@ -75,10 +73,12 @@ try {
75
73
 
76
74
  const doctor = JSON.parse(run('doctor --json', ['doctor', '--json']));
77
75
  if (doctor.version !== pkg.version || doctor.ok !== true) {
78
- fail(`doctor --json returned unexpected release status: ${JSON.stringify({
79
- version: doctor.version,
80
- ok: doctor.ok,
81
- })}`);
76
+ fail(
77
+ `doctor --json returned unexpected release status: ${JSON.stringify({
78
+ version: doctor.version,
79
+ ok: doctor.ok,
80
+ })}`,
81
+ );
82
82
  }
83
83
 
84
84
  const demo = run('demo', ['demo']);