audrey 0.23.1 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +101 -15
- package/LICENSE +21 -21
- package/README.md +232 -6
- package/SECURITY.md +2 -1
- package/benchmarks/adapter-kit.mjs +20 -0
- package/benchmarks/adapter-self-test.mjs +166 -0
- package/benchmarks/adapters/example-allow.mjs +28 -0
- package/benchmarks/adapters/mem0-platform.mjs +267 -0
- package/benchmarks/adapters/registry.json +51 -0
- package/benchmarks/adapters/zep-cloud.mjs +280 -0
- package/benchmarks/baselines.js +169 -0
- package/benchmarks/build-leaderboard.mjs +170 -0
- package/benchmarks/cases.js +537 -0
- package/benchmarks/create-conformance-card.mjs +139 -0
- package/benchmarks/create-submission-bundle.mjs +176 -0
- package/benchmarks/dry-run-external-adapters.mjs +165 -0
- package/benchmarks/guardbench.js +1125 -0
- package/benchmarks/output/adapter-self-test/guardbench-adapter-self-test.json +50 -0
- package/benchmarks/output/external/guardbench-external-dry-run.json +69 -0
- package/benchmarks/output/external/guardbench-external-evidence.json +56 -0
- package/benchmarks/output/guardbench-conformance-card.json +63 -0
- package/benchmarks/output/guardbench-manifest.json +414 -0
- package/benchmarks/output/guardbench-raw.json +1271 -0
- package/benchmarks/output/guardbench-summary.json +2107 -0
- package/benchmarks/output/leaderboard/guardbench-leaderboard.json +93 -0
- package/benchmarks/output/leaderboard/guardbench-leaderboard.md +7 -0
- package/benchmarks/output/submission-bundle/guardbench-conformance-card.json +63 -0
- package/benchmarks/output/submission-bundle/guardbench-manifest.json +414 -0
- package/benchmarks/output/submission-bundle/guardbench-raw.json +1271 -0
- package/benchmarks/output/submission-bundle/guardbench-summary.json +2107 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-adapter-registry.schema.json +69 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-adapter-self-test.schema.json +156 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-conformance-card.schema.json +184 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-external-dry-run.schema.json +74 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-external-evidence.schema.json +108 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-external-run.schema.json +160 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-leaderboard.schema.json +179 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-manifest.schema.json +213 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-publication-verification.schema.json +47 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-raw.schema.json +184 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-submission-manifest.schema.json +151 -0
- package/benchmarks/output/submission-bundle/schemas/guardbench-summary.schema.json +249 -0
- package/benchmarks/output/submission-bundle/submission-manifest.json +131 -0
- package/benchmarks/output/submission-bundle/validation-report.json +31 -0
- package/benchmarks/output/summary.json +2354 -0
- package/benchmarks/perf-snapshot.js +304 -0
- package/benchmarks/perf.bench.js +161 -0
- package/benchmarks/public-paths.mjs +78 -0
- package/benchmarks/reference-results.js +70 -0
- package/benchmarks/report.js +259 -0
- package/benchmarks/run-external-guardbench.mjs +281 -0
- package/benchmarks/run.js +682 -0
- package/benchmarks/schemas/guardbench-adapter-registry.schema.json +69 -0
- package/benchmarks/schemas/guardbench-adapter-self-test.schema.json +156 -0
- package/benchmarks/schemas/guardbench-conformance-card.schema.json +184 -0
- package/benchmarks/schemas/guardbench-external-dry-run.schema.json +74 -0
- package/benchmarks/schemas/guardbench-external-evidence.schema.json +108 -0
- package/benchmarks/schemas/guardbench-external-run.schema.json +160 -0
- package/benchmarks/schemas/guardbench-leaderboard.schema.json +179 -0
- package/benchmarks/schemas/guardbench-manifest.schema.json +213 -0
- package/benchmarks/schemas/guardbench-publication-verification.schema.json +47 -0
- package/benchmarks/schemas/guardbench-raw.schema.json +184 -0
- package/benchmarks/schemas/guardbench-submission-manifest.schema.json +151 -0
- package/benchmarks/schemas/guardbench-summary.schema.json +249 -0
- package/benchmarks/snapshots/perf-0.22.2.json +123 -0
- package/benchmarks/snapshots/perf-0.23.0.json +123 -0
- package/benchmarks/validate-adapter-module.mjs +104 -0
- package/benchmarks/validate-adapter-registry.mjs +134 -0
- package/benchmarks/validate-adapter-self-test.mjs +96 -0
- package/benchmarks/validate-guardbench-artifacts.mjs +343 -0
- package/benchmarks/verify-external-evidence.mjs +296 -0
- package/benchmarks/verify-publication-artifacts.mjs +286 -0
- package/benchmarks/verify-submission-bundle.mjs +167 -0
- package/dist/mcp-server/config.d.ts +1 -1
- package/dist/mcp-server/config.d.ts.map +1 -1
- package/dist/mcp-server/config.js +1 -1
- package/dist/mcp-server/config.js.map +1 -1
- package/dist/mcp-server/index.d.ts +65 -3
- package/dist/mcp-server/index.d.ts.map +1 -1
- package/dist/mcp-server/index.js +675 -157
- package/dist/mcp-server/index.js.map +1 -1
- package/dist/src/action-key.d.ts +9 -0
- package/dist/src/action-key.d.ts.map +1 -0
- package/dist/src/action-key.js +49 -0
- package/dist/src/action-key.js.map +1 -0
- package/dist/src/adaptive.js +5 -5
- package/dist/src/affect.js +8 -8
- package/dist/src/audrey.d.ts +13 -0
- package/dist/src/audrey.d.ts.map +1 -1
- package/dist/src/audrey.js +68 -3
- package/dist/src/audrey.js.map +1 -1
- package/dist/src/capsule.js +4 -4
- package/dist/src/causal.js +3 -3
- package/dist/src/consolidate.js +48 -48
- package/dist/src/controller.d.ts +78 -6
- package/dist/src/controller.d.ts.map +1 -1
- package/dist/src/controller.js +273 -53
- package/dist/src/controller.js.map +1 -1
- package/dist/src/db.js +172 -172
- package/dist/src/decay.js +8 -8
- package/dist/src/embedding.d.ts +2 -1
- package/dist/src/embedding.d.ts.map +1 -1
- package/dist/src/embedding.js +39 -29
- package/dist/src/embedding.js.map +1 -1
- package/dist/src/encode.js +6 -6
- package/dist/src/feedback.d.ts +6 -0
- package/dist/src/feedback.d.ts.map +1 -1
- package/dist/src/feedback.js +6 -0
- package/dist/src/feedback.js.map +1 -1
- package/dist/src/forget.js +12 -12
- package/dist/src/hybrid-recall.js +9 -9
- package/dist/src/impact.js +6 -6
- package/dist/src/import.d.ts +3 -3
- package/dist/src/import.js +41 -41
- package/dist/src/index.d.ts +5 -4
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +3 -3
- package/dist/src/index.js.map +1 -1
- package/dist/src/interference.js +14 -14
- package/dist/src/introspect.js +18 -18
- package/dist/src/preflight.d.ts.map +1 -1
- package/dist/src/preflight.js +41 -0
- package/dist/src/preflight.js.map +1 -1
- package/dist/src/promote.js +7 -7
- package/dist/src/prompts.js +118 -118
- package/dist/src/recall.js +30 -30
- package/dist/src/reflexes.d.ts +1 -0
- package/dist/src/reflexes.d.ts.map +1 -1
- package/dist/src/reflexes.js +3 -0
- package/dist/src/reflexes.js.map +1 -1
- package/dist/src/rollback.js +4 -4
- package/dist/src/routes.d.ts.map +1 -1
- package/dist/src/routes.js +71 -2
- package/dist/src/routes.js.map +1 -1
- package/dist/src/validate.js +25 -25
- package/docs/AUDREY_PAPER_OUTLINE.md +175 -0
- package/docs/MEMORY_BENCHMARKING.md +59 -0
- package/docs/PRODUCTION_BACKLOG.md +304 -0
- package/docs/paper/00-master.md +48 -0
- package/docs/paper/01-introduction.md +27 -0
- package/docs/paper/02-related-work.md +47 -0
- package/docs/paper/03-problem-definition.md +108 -0
- package/docs/paper/04-design.md +164 -0
- package/docs/paper/05-guardbench-spec.md +412 -0
- package/docs/paper/06-implementation.md +113 -0
- package/docs/paper/07-evaluation.md +168 -0
- package/docs/paper/08-discussion-limitations.md +61 -0
- package/docs/paper/09-conclusion.md +11 -0
- package/docs/paper/SUBMISSION_README.md +162 -0
- package/docs/paper/appendix-a-demo-transcript.md +114 -0
- package/docs/paper/arxiv-compile-report.schema.json +116 -0
- package/docs/paper/arxiv-source.schema.json +61 -0
- package/docs/paper/audrey-paper-v1.md +1106 -0
- package/docs/paper/browser-launch-plan.json +209 -0
- package/docs/paper/browser-launch-plan.schema.json +100 -0
- package/docs/paper/browser-launch-results.json +86 -0
- package/docs/paper/browser-launch-results.schema.json +66 -0
- package/docs/paper/claim-register.json +138 -0
- package/docs/paper/claim-register.schema.json +81 -0
- package/docs/paper/evidence-ledger.md +103 -0
- package/docs/paper/output/arxiv/README-arxiv.txt +8 -0
- package/docs/paper/output/arxiv/arxiv-manifest.json +41 -0
- package/docs/paper/output/arxiv/main.tex +949 -0
- package/docs/paper/output/arxiv/references.bib +222 -0
- package/docs/paper/output/arxiv-compile-report.json +24 -0
- package/docs/paper/output/submission-bundle/LICENSE +21 -0
- package/docs/paper/output/submission-bundle/README.md +555 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/adapter-self-test/guardbench-adapter-self-test.json +50 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/external/guardbench-external-dry-run.json +69 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/external/guardbench-external-evidence.json +56 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-conformance-card.json +63 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-manifest.json +414 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-raw.json +1271 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/guardbench-summary.json +2107 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/leaderboard/guardbench-leaderboard.json +93 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/leaderboard/guardbench-leaderboard.md +7 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/submission-bundle/submission-manifest.json +131 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/submission-bundle/validation-report.json +31 -0
- package/docs/paper/output/submission-bundle/benchmarks/output/summary.json +2354 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-adapter-registry.schema.json +69 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-adapter-self-test.schema.json +156 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-conformance-card.schema.json +184 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-external-dry-run.schema.json +74 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-external-evidence.schema.json +108 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-external-run.schema.json +160 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-leaderboard.schema.json +179 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-manifest.schema.json +213 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-publication-verification.schema.json +47 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-raw.schema.json +184 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-submission-manifest.schema.json +151 -0
- package/docs/paper/output/submission-bundle/benchmarks/schemas/guardbench-summary.schema.json +249 -0
- package/docs/paper/output/submission-bundle/docs/AUDREY_PAPER_OUTLINE.md +175 -0
- package/docs/paper/output/submission-bundle/docs/paper/00-master.md +48 -0
- package/docs/paper/output/submission-bundle/docs/paper/01-introduction.md +27 -0
- package/docs/paper/output/submission-bundle/docs/paper/02-related-work.md +47 -0
- package/docs/paper/output/submission-bundle/docs/paper/03-problem-definition.md +108 -0
- package/docs/paper/output/submission-bundle/docs/paper/04-design.md +164 -0
- package/docs/paper/output/submission-bundle/docs/paper/05-guardbench-spec.md +412 -0
- package/docs/paper/output/submission-bundle/docs/paper/06-implementation.md +113 -0
- package/docs/paper/output/submission-bundle/docs/paper/07-evaluation.md +168 -0
- package/docs/paper/output/submission-bundle/docs/paper/08-discussion-limitations.md +61 -0
- package/docs/paper/output/submission-bundle/docs/paper/09-conclusion.md +11 -0
- package/docs/paper/output/submission-bundle/docs/paper/SUBMISSION_README.md +162 -0
- package/docs/paper/output/submission-bundle/docs/paper/appendix-a-demo-transcript.md +114 -0
- package/docs/paper/output/submission-bundle/docs/paper/arxiv-compile-report.schema.json +116 -0
- package/docs/paper/output/submission-bundle/docs/paper/arxiv-source.schema.json +61 -0
- package/docs/paper/output/submission-bundle/docs/paper/audrey-paper-v1.md +1106 -0
- package/docs/paper/output/submission-bundle/docs/paper/browser-launch-plan.json +209 -0
- package/docs/paper/output/submission-bundle/docs/paper/browser-launch-plan.schema.json +100 -0
- package/docs/paper/output/submission-bundle/docs/paper/browser-launch-results.json +86 -0
- package/docs/paper/output/submission-bundle/docs/paper/browser-launch-results.schema.json +66 -0
- package/docs/paper/output/submission-bundle/docs/paper/claim-register.json +138 -0
- package/docs/paper/output/submission-bundle/docs/paper/claim-register.schema.json +81 -0
- package/docs/paper/output/submission-bundle/docs/paper/evidence-ledger.md +103 -0
- package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/README-arxiv.txt +8 -0
- package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/arxiv-manifest.json +41 -0
- package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/main.tex +949 -0
- package/docs/paper/output/submission-bundle/docs/paper/output/arxiv/references.bib +222 -0
- package/docs/paper/output/submission-bundle/docs/paper/output/arxiv-compile-report.json +24 -0
- package/docs/paper/output/submission-bundle/docs/paper/paper-submission-bundle.schema.json +70 -0
- package/docs/paper/output/submission-bundle/docs/paper/publication-pack.json +81 -0
- package/docs/paper/output/submission-bundle/docs/paper/publication-pack.schema.json +60 -0
- package/docs/paper/output/submission-bundle/docs/paper/references.bib +222 -0
- package/docs/paper/output/submission-bundle/package.json +212 -0
- package/docs/paper/output/submission-bundle/paper-submission-manifest.json +379 -0
- package/docs/paper/paper-submission-bundle.schema.json +70 -0
- package/docs/paper/publication-pack.json +81 -0
- package/docs/paper/publication-pack.schema.json +60 -0
- package/docs/paper/references.bib +222 -0
- package/package.json +87 -4
- package/scripts/audit-release-completion.mjs +362 -0
- package/scripts/create-arxiv-source.mjs +362 -0
- package/scripts/create-paper-submission-bundle.mjs +210 -0
- package/scripts/finalize-release.mjs +526 -0
- package/scripts/prepare-release-cut.mjs +269 -0
- package/scripts/publish-release-bundle.mjs +209 -0
- package/scripts/publish-release-github-api.mjs +429 -0
- package/scripts/run-vitest.mjs +34 -0
- package/scripts/smoke-cli.js +92 -0
- package/scripts/sync-paper-artifacts.mjs +109 -0
- package/scripts/verify-arxiv-compile.mjs +440 -0
- package/scripts/verify-arxiv-source.mjs +194 -0
- package/scripts/verify-browser-launch-plan.mjs +237 -0
- package/scripts/verify-browser-launch-results.mjs +285 -0
- package/scripts/verify-paper-artifacts.mjs +338 -0
- package/scripts/verify-paper-claims.mjs +226 -0
- package/scripts/verify-paper-submission-bundle.mjs +207 -0
- package/scripts/verify-publication-pack.mjs +196 -0
- package/scripts/verify-python-package.py +201 -0
- package/scripts/verify-release-readiness.mjs +785 -0
package/dist/mcp-server/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { homedir, platform, tmpdir } from 'node:os';
|
|
4
|
-
import { join, resolve } from 'node:path';
|
|
5
|
-
import { existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync } from 'node:fs';
|
|
4
|
+
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import { existsSync, mkdirSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from 'node:fs';
|
|
6
6
|
import { execFileSync } from 'node:child_process';
|
|
7
7
|
import { fileURLToPath } from 'node:url';
|
|
8
8
|
import { Audrey, MemoryController } from '../src/index.js';
|
|
@@ -120,6 +120,28 @@ export const memoryPreflightToolSchema = {
|
|
|
120
120
|
include_capsule: z.boolean().optional().describe('If false, omit the embedded Memory Capsule from the response.'),
|
|
121
121
|
scope: z.enum(['agent', 'shared']).optional().describe('agent restricts memory recall to this server agent identity. shared searches the whole store. Defaults to agent.'),
|
|
122
122
|
};
|
|
123
|
+
const { record_event: _preflightRecordEvent, ...memoryGuardBeforeFields } = memoryPreflightToolSchema;
|
|
124
|
+
export const memoryGuardBeforeToolSchema = {
|
|
125
|
+
...memoryGuardBeforeFields,
|
|
126
|
+
session_id: z.string().optional().describe('Session identifier for grouping the required guard receipt event.'),
|
|
127
|
+
files: z.array(z.string()).optional().describe('File paths to fingerprint in the required guard receipt.'),
|
|
128
|
+
};
|
|
129
|
+
export const memoryGuardAfterToolSchema = {
|
|
130
|
+
receipt_id: z.string()
|
|
131
|
+
.refine(isNonEmptyText, 'Receipt id must not be empty')
|
|
132
|
+
.describe('Receipt id returned by memory_guard_before.'),
|
|
133
|
+
tool: z.string().optional().describe('Tool or command family that completed, e.g. Bash, npm test, Edit, deploy.'),
|
|
134
|
+
session_id: z.string().optional().describe('Session identifier for grouping related guard events.'),
|
|
135
|
+
input: z.unknown().optional().describe('Tool input. Hashed and never stored raw; redacted metadata is only stored when retain_details is true.'),
|
|
136
|
+
output: z.unknown().optional().describe('Tool output. Same redaction and storage policy as input.'),
|
|
137
|
+
outcome: z.enum(['succeeded', 'failed', 'blocked', 'skipped', 'unknown']).optional().describe('Outcome classification'),
|
|
138
|
+
error_summary: z.string().optional().describe('Short error description if the action failed. Redacted and truncated to 2 KB.'),
|
|
139
|
+
cwd: z.string().optional().describe('Working directory at the time of the action.'),
|
|
140
|
+
files: z.array(z.string()).optional().describe('File paths to fingerprint (size + mtime + content hash).'),
|
|
141
|
+
metadata: z.record(z.string(), z.unknown()).optional().describe('Arbitrary structured metadata (redacted before storage).'),
|
|
142
|
+
retain_details: z.boolean().optional().describe('If true, redacted input and output payloads are stored alongside hashes. Defaults to false.'),
|
|
143
|
+
evidence_feedback: z.record(z.string(), z.enum(['used', 'helpful', 'wrong'])).optional().describe('Map of evidence ids from the guard receipt to memory validation outcomes.'),
|
|
144
|
+
};
|
|
123
145
|
export const memoryReflexesToolSchema = {
|
|
124
146
|
...memoryPreflightToolSchema,
|
|
125
147
|
include_preflight: z.boolean().optional().describe('If true, include the full underlying preflight report.'),
|
|
@@ -426,10 +448,20 @@ export function formatInstallGuide(host, env = process.env, dryRun = false) {
|
|
|
426
448
|
'Generated MCP config:',
|
|
427
449
|
formatMcpHostConfig(normalizedHost, env),
|
|
428
450
|
'',
|
|
451
|
+
...(normalizedHost === 'claude-code'
|
|
452
|
+
? [
|
|
453
|
+
'Generated Claude Code hook config:',
|
|
454
|
+
formatClaudeCodeHookConfig(),
|
|
455
|
+
'',
|
|
456
|
+
]
|
|
457
|
+
: []),
|
|
429
458
|
'Next steps:',
|
|
430
459
|
];
|
|
431
460
|
if (normalizedHost === 'claude-code') {
|
|
432
461
|
lines.push('- Run without --dry-run to register Audrey through Claude Code: npx audrey install --host claude-code');
|
|
462
|
+
lines.push('- Apply project hooks with: npx audrey hook-config claude-code --apply --scope project');
|
|
463
|
+
lines.push('- Apply user hooks with: npx audrey hook-config claude-code --apply --scope user');
|
|
464
|
+
lines.push('- Verify hooks in Claude Code with: /hooks');
|
|
433
465
|
lines.push('- Verify with: claude mcp list');
|
|
434
466
|
}
|
|
435
467
|
else if (normalizedHost === 'codex') {
|
|
@@ -496,49 +528,51 @@ function installClaudeCode(options = { includeSecrets: false }) {
|
|
|
496
528
|
console.error('Failed to register MCP server. Is Claude Code installed and on your PATH?');
|
|
497
529
|
process.exit(1);
|
|
498
530
|
}
|
|
499
|
-
console.log(`
|
|
500
|
-
Audrey registered as "${SERVER_NAME}" with Claude Code.
|
|
501
|
-
|
|
502
|
-
20 MCP tools available in every session:
|
|
503
|
-
memory_encode - Store observations, facts, preferences
|
|
504
|
-
memory_recall - Search memories by semantic similarity
|
|
505
|
-
memory_consolidate - Extract principles from accumulated episodes
|
|
506
|
-
memory_dream - Full sleep cycle: consolidate + decay + stats
|
|
507
|
-
memory_introspect - Check memory system health
|
|
508
|
-
memory_resolve_truth - Resolve contradictions between claims
|
|
509
|
-
memory_export - Export all memories as JSON snapshot
|
|
510
|
-
memory_import - Import a snapshot into a fresh database
|
|
511
|
-
memory_forget - Forget a specific memory by ID or query
|
|
512
|
-
memory_validate - Closed-loop feedback: helpful/used/wrong outcomes
|
|
513
|
-
memory_decay - Apply forgetting curves, transition low-confidence to dormant
|
|
514
|
-
memory_status - Check brain health (episode/vec sync, dimensions)
|
|
515
|
-
memory_reflect - Form lasting memories from a conversation
|
|
516
|
-
memory_greeting - Wake up as yourself: load identity, context, mood
|
|
517
|
-
memory_observe_tool - Record redacted tool-use events
|
|
518
|
-
memory_recent_failures - Inspect recent failed tool events
|
|
519
|
-
memory_capsule - Return a ranked, evidence-backed memory packet
|
|
520
|
-
memory_preflight - Check memory before an agent acts
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
npx audrey
|
|
528
|
-
npx audrey
|
|
529
|
-
npx audrey
|
|
530
|
-
npx audrey
|
|
531
|
-
npx audrey
|
|
532
|
-
npx audrey
|
|
533
|
-
npx audrey
|
|
534
|
-
npx audrey status
|
|
535
|
-
npx audrey
|
|
536
|
-
npx audrey
|
|
537
|
-
npx audrey
|
|
538
|
-
npx audrey
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
531
|
+
console.log(`
|
|
532
|
+
Audrey registered as "${SERVER_NAME}" with Claude Code.
|
|
533
|
+
|
|
534
|
+
20 MCP tools available in every session:
|
|
535
|
+
memory_encode - Store observations, facts, preferences
|
|
536
|
+
memory_recall - Search memories by semantic similarity
|
|
537
|
+
memory_consolidate - Extract principles from accumulated episodes
|
|
538
|
+
memory_dream - Full sleep cycle: consolidate + decay + stats
|
|
539
|
+
memory_introspect - Check memory system health
|
|
540
|
+
memory_resolve_truth - Resolve contradictions between claims
|
|
541
|
+
memory_export - Export all memories as JSON snapshot
|
|
542
|
+
memory_import - Import a snapshot into a fresh database
|
|
543
|
+
memory_forget - Forget a specific memory by ID or query
|
|
544
|
+
memory_validate - Closed-loop feedback: helpful/used/wrong outcomes
|
|
545
|
+
memory_decay - Apply forgetting curves, transition low-confidence to dormant
|
|
546
|
+
memory_status - Check brain health (episode/vec sync, dimensions)
|
|
547
|
+
memory_reflect - Form lasting memories from a conversation
|
|
548
|
+
memory_greeting - Wake up as yourself: load identity, context, mood
|
|
549
|
+
memory_observe_tool - Record redacted tool-use events
|
|
550
|
+
memory_recent_failures - Inspect recent failed tool events
|
|
551
|
+
memory_capsule - Return a ranked, evidence-backed memory packet
|
|
552
|
+
memory_preflight - Check memory before an agent acts
|
|
553
|
+
memory_guard_before - Create a guard receipt before an agent acts
|
|
554
|
+
memory_guard_after - Record the outcome for a guard receipt
|
|
555
|
+
memory_reflexes - Convert preflight evidence into trigger-response reflexes
|
|
556
|
+
memory_promote - Promote repeated lessons into project rules
|
|
557
|
+
|
|
558
|
+
CLI subcommands:
|
|
559
|
+
npx audrey demo - Run a 60-second local proof with no network calls
|
|
560
|
+
npx audrey doctor - Diagnose runtime, store health, and host config readiness
|
|
561
|
+
npx audrey install - Register MCP server with Claude Code
|
|
562
|
+
npx audrey install --host codex --dry-run - Print safe host setup instructions
|
|
563
|
+
npx audrey mcp-config codex - Print Codex MCP TOML
|
|
564
|
+
npx audrey mcp-config generic - Print JSON config for other MCP hosts
|
|
565
|
+
npx audrey uninstall - Remove MCP server registration
|
|
566
|
+
npx audrey status - Show memory store health and stats
|
|
567
|
+
npx audrey status --json - Emit machine-readable health output
|
|
568
|
+
npx audrey status --json --fail-on-unhealthy - Exit non-zero on unhealthy status
|
|
569
|
+
npx audrey greeting - Output session briefing (for hooks)
|
|
570
|
+
npx audrey reflect - Reflect on conversation + dream cycle (for hooks)
|
|
571
|
+
npx audrey dream - Run consolidation + decay cycle
|
|
572
|
+
npx audrey reembed - Re-embed all memories with current provider
|
|
573
|
+
|
|
574
|
+
Data stored in: ${dataDir}
|
|
575
|
+
Verify: claude mcp list
|
|
542
576
|
`);
|
|
543
577
|
}
|
|
544
578
|
function install() {
|
|
@@ -584,9 +618,238 @@ function printMcpConfig() {
|
|
|
584
618
|
process.exit(2);
|
|
585
619
|
}
|
|
586
620
|
}
|
|
621
|
+
function printHookConfig() {
|
|
622
|
+
let options;
|
|
623
|
+
try {
|
|
624
|
+
options = parseHookConfigOptions();
|
|
625
|
+
}
|
|
626
|
+
catch (err) {
|
|
627
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
628
|
+
console.error(`[audrey] hook-config failed: ${message}`);
|
|
629
|
+
process.exit(2);
|
|
630
|
+
}
|
|
631
|
+
if (options.host !== 'claude-code') {
|
|
632
|
+
console.error(`[audrey] hook-config currently supports claude-code only, got "${options.host}"`);
|
|
633
|
+
process.exit(2);
|
|
634
|
+
}
|
|
635
|
+
if (!options.apply) {
|
|
636
|
+
console.log(formatClaudeCodeHookConfig());
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
try {
|
|
640
|
+
const settingsPath = options.settingsPath ?? defaultClaudeCodeSettingsPath(options);
|
|
641
|
+
const result = applyClaudeCodeHookConfig({
|
|
642
|
+
settingsPath,
|
|
643
|
+
dryRun: options.dryRun,
|
|
644
|
+
});
|
|
645
|
+
const action = result.dryRun
|
|
646
|
+
? result.changed ? 'would update' : 'would leave unchanged'
|
|
647
|
+
: result.changed ? 'updated' : 'already up to date';
|
|
648
|
+
console.log(`[audrey] Claude Code hook settings ${action}: ${result.settingsPath}`);
|
|
649
|
+
if (result.backupPath)
|
|
650
|
+
console.log(`[audrey] backup written: ${result.backupPath}`);
|
|
651
|
+
if (result.dryRun)
|
|
652
|
+
console.log(JSON.stringify(result.settings, null, 2));
|
|
653
|
+
}
|
|
654
|
+
catch (err) {
|
|
655
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
656
|
+
console.error(`[audrey] hook-config failed: ${message}`);
|
|
657
|
+
process.exit(2);
|
|
658
|
+
}
|
|
659
|
+
}
|
|
660
|
+
export function recallPayload(results) {
|
|
661
|
+
return {
|
|
662
|
+
results: Array.from(results),
|
|
663
|
+
partial_failure: results.partialFailure ?? false,
|
|
664
|
+
errors: results.errors ?? [],
|
|
665
|
+
};
|
|
666
|
+
}
|
|
587
667
|
function sectionTitle(section) {
|
|
588
668
|
return section.replace(/_/g, ' ');
|
|
589
669
|
}
|
|
670
|
+
function shellQuote(value) {
|
|
671
|
+
return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
|
|
672
|
+
}
|
|
673
|
+
export function formatClaudeCodeHookConfig(entrypoint = MCP_ENTRYPOINT) {
|
|
674
|
+
const node = shellQuote(process.execPath);
|
|
675
|
+
const entry = shellQuote(entrypoint);
|
|
676
|
+
const command = (subcommand) => `${node} ${entry} ${subcommand}`;
|
|
677
|
+
return JSON.stringify({
|
|
678
|
+
hooks: {
|
|
679
|
+
PreToolUse: [
|
|
680
|
+
{
|
|
681
|
+
matcher: '.*',
|
|
682
|
+
hooks: [
|
|
683
|
+
{
|
|
684
|
+
type: 'command',
|
|
685
|
+
command: command('guard --hook --fail-on-warn'),
|
|
686
|
+
},
|
|
687
|
+
],
|
|
688
|
+
},
|
|
689
|
+
],
|
|
690
|
+
PostToolUse: [
|
|
691
|
+
{
|
|
692
|
+
matcher: '.*',
|
|
693
|
+
hooks: [
|
|
694
|
+
{
|
|
695
|
+
type: 'command',
|
|
696
|
+
command: command('observe-tool --event PostToolUse'),
|
|
697
|
+
},
|
|
698
|
+
],
|
|
699
|
+
},
|
|
700
|
+
],
|
|
701
|
+
PostToolUseFailure: [
|
|
702
|
+
{
|
|
703
|
+
matcher: '.*',
|
|
704
|
+
hooks: [
|
|
705
|
+
{
|
|
706
|
+
type: 'command',
|
|
707
|
+
command: command('observe-tool --event PostToolUseFailure'),
|
|
708
|
+
},
|
|
709
|
+
],
|
|
710
|
+
},
|
|
711
|
+
],
|
|
712
|
+
},
|
|
713
|
+
}, null, 2);
|
|
714
|
+
}
|
|
715
|
+
function asJsonRecord(value) {
|
|
716
|
+
return value && typeof value === 'object' && !Array.isArray(value) ? value : {};
|
|
717
|
+
}
|
|
718
|
+
function cloneHookRows(value) {
|
|
719
|
+
return Array.isArray(value) ? [...value] : [];
|
|
720
|
+
}
|
|
721
|
+
function hookCommandSet(settings) {
|
|
722
|
+
const commands = new Set();
|
|
723
|
+
const hooks = asJsonRecord(settings.hooks);
|
|
724
|
+
for (const rows of Object.values(hooks)) {
|
|
725
|
+
if (!Array.isArray(rows))
|
|
726
|
+
continue;
|
|
727
|
+
for (const row of rows) {
|
|
728
|
+
const record = asJsonRecord(row);
|
|
729
|
+
const hookItems = cloneHookRows(record.hooks);
|
|
730
|
+
for (const item of hookItems) {
|
|
731
|
+
const hook = asJsonRecord(item);
|
|
732
|
+
if (typeof hook.command === 'string')
|
|
733
|
+
commands.add(hook.command);
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
}
|
|
737
|
+
return commands;
|
|
738
|
+
}
|
|
739
|
+
export function mergeClaudeCodeHookSettings(existingSettings, generatedSettings = JSON.parse(formatClaudeCodeHookConfig())) {
|
|
740
|
+
const existing = asJsonRecord(existingSettings);
|
|
741
|
+
const generated = asJsonRecord(generatedSettings);
|
|
742
|
+
const merged = { ...existing };
|
|
743
|
+
const existingHooks = asJsonRecord(existing.hooks);
|
|
744
|
+
const generatedHooks = asJsonRecord(generated.hooks);
|
|
745
|
+
const nextHooks = { ...existingHooks };
|
|
746
|
+
const existingCommands = hookCommandSet(existing);
|
|
747
|
+
for (const [eventName, generatedRows] of Object.entries(generatedHooks)) {
|
|
748
|
+
const rows = cloneHookRows(nextHooks[eventName]);
|
|
749
|
+
for (const row of cloneHookRows(generatedRows)) {
|
|
750
|
+
const hookRow = asJsonRecord(row);
|
|
751
|
+
const commands = cloneHookRows(hookRow.hooks)
|
|
752
|
+
.map(item => asJsonRecord(item).command)
|
|
753
|
+
.filter((command) => typeof command === 'string');
|
|
754
|
+
if (commands.some(command => existingCommands.has(command)))
|
|
755
|
+
continue;
|
|
756
|
+
rows.push(row);
|
|
757
|
+
for (const command of commands)
|
|
758
|
+
existingCommands.add(command);
|
|
759
|
+
}
|
|
760
|
+
nextHooks[eventName] = rows;
|
|
761
|
+
}
|
|
762
|
+
merged.hooks = nextHooks;
|
|
763
|
+
return merged;
|
|
764
|
+
}
|
|
765
|
+
function parseHookConfigOptions(argv = process.argv) {
|
|
766
|
+
let host = argv[3] || 'claude-code';
|
|
767
|
+
let apply = false;
|
|
768
|
+
let dryRun = false;
|
|
769
|
+
let scope = 'project';
|
|
770
|
+
let projectDir = process.cwd();
|
|
771
|
+
let settingsPath;
|
|
772
|
+
for (let i = 4; i < argv.length; i++) {
|
|
773
|
+
const token = argv[i];
|
|
774
|
+
const next = () => argv[++i];
|
|
775
|
+
if (token === '--apply')
|
|
776
|
+
apply = true;
|
|
777
|
+
else if (token === '--dry-run' || token === '--print')
|
|
778
|
+
dryRun = true;
|
|
779
|
+
else if (token === '--scope') {
|
|
780
|
+
const value = next();
|
|
781
|
+
if (value === 'project' || value === 'user')
|
|
782
|
+
scope = value;
|
|
783
|
+
else
|
|
784
|
+
throw new Error(`Unsupported hook-config scope "${value}". Use project or user.`);
|
|
785
|
+
}
|
|
786
|
+
else if (token?.startsWith('--scope=')) {
|
|
787
|
+
const value = token.slice('--scope='.length);
|
|
788
|
+
if (value === 'project' || value === 'user')
|
|
789
|
+
scope = value;
|
|
790
|
+
else
|
|
791
|
+
throw new Error(`Unsupported hook-config scope "${value}". Use project or user.`);
|
|
792
|
+
}
|
|
793
|
+
else if (token === '--project-dir') {
|
|
794
|
+
projectDir = next() ?? projectDir;
|
|
795
|
+
}
|
|
796
|
+
else if (token?.startsWith('--project-dir=')) {
|
|
797
|
+
projectDir = token.slice('--project-dir='.length) || projectDir;
|
|
798
|
+
}
|
|
799
|
+
else if (token === '--settings') {
|
|
800
|
+
settingsPath = next();
|
|
801
|
+
}
|
|
802
|
+
else if (token?.startsWith('--settings=')) {
|
|
803
|
+
settingsPath = token.slice('--settings='.length);
|
|
804
|
+
}
|
|
805
|
+
else if (token && !token.startsWith('-')) {
|
|
806
|
+
host = token;
|
|
807
|
+
}
|
|
808
|
+
else if (token) {
|
|
809
|
+
throw new Error(`Unknown hook-config option: ${token}`);
|
|
810
|
+
}
|
|
811
|
+
}
|
|
812
|
+
return { host, apply, dryRun, scope, projectDir, ...(settingsPath ? { settingsPath } : {}) };
|
|
813
|
+
}
|
|
814
|
+
function defaultClaudeCodeSettingsPath(options) {
|
|
815
|
+
if (options.scope === 'user')
|
|
816
|
+
return join(homedir(), '.claude', 'settings.json');
|
|
817
|
+
return join(resolve(options.projectDir), '.claude', 'settings.local.json');
|
|
818
|
+
}
|
|
819
|
+
export function applyClaudeCodeHookConfig(options) {
|
|
820
|
+
const settingsPath = resolve(options.settingsPath);
|
|
821
|
+
const existingText = existsSync(settingsPath) ? readFileSync(settingsPath, 'utf-8') : '';
|
|
822
|
+
let existing = {};
|
|
823
|
+
if (existingText.trim()) {
|
|
824
|
+
try {
|
|
825
|
+
existing = JSON.parse(existingText);
|
|
826
|
+
}
|
|
827
|
+
catch (err) {
|
|
828
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
829
|
+
throw new Error(`Cannot merge Audrey hooks into invalid JSON at ${settingsPath}: ${message}`);
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
const settings = mergeClaudeCodeHookSettings(existing);
|
|
833
|
+
const nextText = `${JSON.stringify(settings, null, 2)}\n`;
|
|
834
|
+
const changed = existingText !== nextText;
|
|
835
|
+
let backupPath = null;
|
|
836
|
+
if (changed && !options.dryRun) {
|
|
837
|
+
mkdirSync(dirname(settingsPath), { recursive: true });
|
|
838
|
+
if (existingText) {
|
|
839
|
+
const stamp = (options.now ?? new Date()).toISOString().replace(/[:.]/g, '-');
|
|
840
|
+
backupPath = `${settingsPath}.audrey-${stamp}.bak`;
|
|
841
|
+
writeFileSync(backupPath, existingText, 'utf-8');
|
|
842
|
+
}
|
|
843
|
+
writeFileSync(settingsPath, nextText, 'utf-8');
|
|
844
|
+
}
|
|
845
|
+
return {
|
|
846
|
+
settingsPath,
|
|
847
|
+
dryRun: options.dryRun ?? false,
|
|
848
|
+
changed,
|
|
849
|
+
backupPath,
|
|
850
|
+
settings,
|
|
851
|
+
};
|
|
852
|
+
}
|
|
590
853
|
function createDemoDir() {
|
|
591
854
|
const preferredParent = process.env['AUDREY_DEMO_PARENT_DIR'] || tmpdir();
|
|
592
855
|
try {
|
|
@@ -598,13 +861,6 @@ function createDemoDir() {
|
|
|
598
861
|
return mkdtempSync(join(fallbackParent, 'run-'));
|
|
599
862
|
}
|
|
600
863
|
}
|
|
601
|
-
export function recallPayload(results) {
|
|
602
|
-
return {
|
|
603
|
-
results: Array.from(results),
|
|
604
|
-
partial_failure: results.partialFailure ?? false,
|
|
605
|
-
errors: results.errors ?? [],
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
864
|
function cliValue(flag, argv = process.argv) {
|
|
609
865
|
for (let i = 0; i < argv.length; i++) {
|
|
610
866
|
const token = argv[i];
|
|
@@ -618,7 +874,7 @@ function cliValue(flag, argv = process.argv) {
|
|
|
618
874
|
function demoScenario(argv = process.argv) {
|
|
619
875
|
return cliValue('--scenario', argv);
|
|
620
876
|
}
|
|
621
|
-
function
|
|
877
|
+
function formatControllerGuardResult(result) {
|
|
622
878
|
const label = result.decision === 'block'
|
|
623
879
|
? 'BLOCKED'
|
|
624
880
|
: result.decision === 'warn'
|
|
@@ -632,39 +888,14 @@ function formatGuardResult(result, { explain = false } = {}) {
|
|
|
632
888
|
if (result.evidenceIds.length > 0) {
|
|
633
889
|
lines.push('');
|
|
634
890
|
lines.push('Evidence:');
|
|
635
|
-
for (const id of result.evidenceIds.slice(0, 8))
|
|
891
|
+
for (const id of result.evidenceIds.slice(0, 8))
|
|
636
892
|
lines.push(`- ${id}`);
|
|
637
|
-
}
|
|
638
893
|
}
|
|
639
894
|
if (result.recommendedActions.length > 0) {
|
|
640
895
|
lines.push('');
|
|
641
896
|
lines.push('Recommended action:');
|
|
642
|
-
for (const action of result.recommendedActions.slice(0, 5))
|
|
897
|
+
for (const action of result.recommendedActions.slice(0, 5))
|
|
643
898
|
lines.push(`- ${action}`);
|
|
644
|
-
}
|
|
645
|
-
}
|
|
646
|
-
if (result.reflexes.length > 0) {
|
|
647
|
-
lines.push('');
|
|
648
|
-
lines.push('Memory reflexes:');
|
|
649
|
-
for (const reflex of result.reflexes.slice(0, 5)) {
|
|
650
|
-
lines.push(`- ${reflex.response_type}: ${reflex.response}`);
|
|
651
|
-
}
|
|
652
|
-
}
|
|
653
|
-
if (explain && result.capsule) {
|
|
654
|
-
lines.push('');
|
|
655
|
-
lines.push('Capsule:');
|
|
656
|
-
for (const [section, entries] of Object.entries(result.capsule.sections)) {
|
|
657
|
-
if (!Array.isArray(entries) || entries.length === 0)
|
|
658
|
-
continue;
|
|
659
|
-
lines.push(`- ${sectionTitle(section)}:`);
|
|
660
|
-
for (const entry of entries.slice(0, 3)) {
|
|
661
|
-
lines.push(` * ${entry.memory_id}: ${entry.content}`);
|
|
662
|
-
}
|
|
663
|
-
}
|
|
664
|
-
}
|
|
665
|
-
if (result.decision === 'block') {
|
|
666
|
-
lines.push('');
|
|
667
|
-
lines.push('Next: fix the warning and retry, or pass --override to allow this guard check.');
|
|
668
899
|
}
|
|
669
900
|
return lines.join('\n');
|
|
670
901
|
}
|
|
@@ -709,7 +940,7 @@ async function runRepeatedFailureDemo({ out = console.log, keep = process.argv.i
|
|
|
709
940
|
const result = await controller.beforeAction(action);
|
|
710
941
|
out('Step 3: a new preflight checks the same action before tool use.');
|
|
711
942
|
out('');
|
|
712
|
-
out(
|
|
943
|
+
out(formatControllerGuardResult(result));
|
|
713
944
|
audrey.validate({ id: lessonId, outcome: 'helpful' });
|
|
714
945
|
const impactReport = audrey.impact({ windowDays: 7, limit: 3 });
|
|
715
946
|
out('');
|
|
@@ -733,14 +964,10 @@ async function runRepeatedFailureDemo({ out = console.log, keep = process.argv.i
|
|
|
733
964
|
}
|
|
734
965
|
}
|
|
735
966
|
export async function runDemoCommand({ out = console.log, keep = process.argv.includes('--keep'), } = {}) {
|
|
736
|
-
|
|
737
|
-
if (scenario === 'repeated-failure') {
|
|
967
|
+
if (demoScenario() === 'repeated-failure') {
|
|
738
968
|
await runRepeatedFailureDemo({ out, keep });
|
|
739
969
|
return;
|
|
740
970
|
}
|
|
741
|
-
if (scenario) {
|
|
742
|
-
throw new Error(`Unknown demo scenario "${scenario}". Supported scenarios: repeated-failure`);
|
|
743
|
-
}
|
|
744
971
|
const demoDir = createDemoDir();
|
|
745
972
|
const audrey = new Audrey({
|
|
746
973
|
dataDir: demoDir,
|
|
@@ -891,11 +1118,11 @@ export function buildStatusReport({ dataDir = resolveDataDir(process.env), claud
|
|
|
891
1118
|
});
|
|
892
1119
|
report.stats = audrey.introspect();
|
|
893
1120
|
report.health = audrey.memoryStatus();
|
|
894
|
-
report.lastConsolidation = audrey.db.prepare(`
|
|
895
|
-
SELECT completed_at FROM consolidation_runs
|
|
896
|
-
WHERE status = 'completed'
|
|
897
|
-
ORDER BY completed_at DESC
|
|
898
|
-
LIMIT 1
|
|
1121
|
+
report.lastConsolidation = audrey.db.prepare(`
|
|
1122
|
+
SELECT completed_at FROM consolidation_runs
|
|
1123
|
+
WHERE status = 'completed'
|
|
1124
|
+
ORDER BY completed_at DESC
|
|
1125
|
+
LIMIT 1
|
|
899
1126
|
`).get()?.completed_at ?? 'never';
|
|
900
1127
|
audrey.close();
|
|
901
1128
|
}
|
|
@@ -1324,10 +1551,10 @@ async function main() {
|
|
|
1324
1551
|
};
|
|
1325
1552
|
if (profileEnabled) {
|
|
1326
1553
|
const { results, diagnostics } = await audrey.recallWithDiagnostics(query, recallOptions);
|
|
1327
|
-
return toolResult(
|
|
1554
|
+
return toolResult(results, diagnostics);
|
|
1328
1555
|
}
|
|
1329
1556
|
const results = await audrey.recall(query, recallOptions);
|
|
1330
|
-
return toolResult(
|
|
1557
|
+
return toolResult(results);
|
|
1331
1558
|
}
|
|
1332
1559
|
catch (err) {
|
|
1333
1560
|
return toolError(err);
|
|
@@ -1471,7 +1698,7 @@ async function main() {
|
|
|
1471
1698
|
outcome: z.enum(['succeeded', 'failed', 'blocked', 'skipped', 'unknown']).optional().describe('Outcome classification'),
|
|
1472
1699
|
error_summary: z.string().optional().describe('Short error description if the tool failed. Redacted and truncated to 2 KB.'),
|
|
1473
1700
|
cwd: z.string().optional().describe('Working directory at the time of the tool call'),
|
|
1474
|
-
files: z.array(z.string()).optional().describe('File paths
|
|
1701
|
+
files: z.array(z.string()).optional().describe('File paths to fingerprint (size + mtime + content hash)'),
|
|
1475
1702
|
metadata: z.record(z.string(), z.unknown()).optional().describe('Arbitrary structured metadata (redacted before storage)'),
|
|
1476
1703
|
retain_details: z.boolean().optional().describe('If true, redacted input and output payloads are stored alongside hashes. Defaults to false.'),
|
|
1477
1704
|
}, async ({ event, tool, session_id, input, output, outcome, error_summary, cwd, files, metadata, retain_details, }) => {
|
|
@@ -1563,6 +1790,51 @@ async function main() {
|
|
|
1563
1790
|
return toolError(err);
|
|
1564
1791
|
}
|
|
1565
1792
|
});
|
|
1793
|
+
server.tool('memory_guard_before', memoryGuardBeforeToolSchema, async ({ action, tool, session_id, cwd, files, strict, limit, budget_chars, mode, failure_window_hours, include_status, include_capsule, scope, }) => {
|
|
1794
|
+
try {
|
|
1795
|
+
const decision = await audrey.beforeAction(action, {
|
|
1796
|
+
tool,
|
|
1797
|
+
sessionId: session_id,
|
|
1798
|
+
cwd,
|
|
1799
|
+
files,
|
|
1800
|
+
strict,
|
|
1801
|
+
limit,
|
|
1802
|
+
budgetChars: budget_chars,
|
|
1803
|
+
mode,
|
|
1804
|
+
recentFailureWindowHours: failure_window_hours,
|
|
1805
|
+
includeStatus: include_status,
|
|
1806
|
+
recordEvent: true,
|
|
1807
|
+
includeCapsule: include_capsule,
|
|
1808
|
+
scope: scope ?? 'agent',
|
|
1809
|
+
});
|
|
1810
|
+
return toolResult(decision);
|
|
1811
|
+
}
|
|
1812
|
+
catch (err) {
|
|
1813
|
+
return toolError(err);
|
|
1814
|
+
}
|
|
1815
|
+
});
|
|
1816
|
+
server.tool('memory_guard_after', memoryGuardAfterToolSchema, async ({ receipt_id, tool, session_id, input, output, outcome, error_summary, cwd, files, metadata, retain_details, evidence_feedback, }) => {
|
|
1817
|
+
try {
|
|
1818
|
+
const result = audrey.afterAction({
|
|
1819
|
+
receiptId: receipt_id,
|
|
1820
|
+
tool,
|
|
1821
|
+
sessionId: session_id,
|
|
1822
|
+
input,
|
|
1823
|
+
output,
|
|
1824
|
+
outcome,
|
|
1825
|
+
errorSummary: error_summary,
|
|
1826
|
+
cwd,
|
|
1827
|
+
files,
|
|
1828
|
+
metadata,
|
|
1829
|
+
retainDetails: retain_details,
|
|
1830
|
+
evidenceFeedback: evidence_feedback,
|
|
1831
|
+
});
|
|
1832
|
+
return toolResult(result);
|
|
1833
|
+
}
|
|
1834
|
+
catch (err) {
|
|
1835
|
+
return toolError(err);
|
|
1836
|
+
}
|
|
1837
|
+
});
|
|
1566
1838
|
server.tool('memory_reflexes', memoryReflexesToolSchema, async ({ action, tool, session_id, cwd, files, strict, limit, budget_chars, mode, failure_window_hours, include_status, record_event, include_capsule, include_preflight, scope, }) => {
|
|
1567
1839
|
try {
|
|
1568
1840
|
const report = await audrey.reflexes(action, {
|
|
@@ -1783,6 +2055,9 @@ function parseGuardArgs(argv) {
|
|
|
1783
2055
|
let override = false;
|
|
1784
2056
|
let failOnWarn = false;
|
|
1785
2057
|
let explain = false;
|
|
2058
|
+
let hook = false;
|
|
2059
|
+
let strict = false;
|
|
2060
|
+
let includeCapsule = false;
|
|
1786
2061
|
for (let i = 0; i < argv.length; i++) {
|
|
1787
2062
|
const token = argv[i];
|
|
1788
2063
|
const next = () => argv[++i];
|
|
@@ -1816,13 +2091,16 @@ function parseGuardArgs(argv) {
|
|
|
1816
2091
|
failOnWarn = true;
|
|
1817
2092
|
else if (token === '--explain')
|
|
1818
2093
|
explain = true;
|
|
2094
|
+
else if (token === '--hook')
|
|
2095
|
+
hook = true;
|
|
2096
|
+
else if (token === '--strict')
|
|
2097
|
+
strict = true;
|
|
2098
|
+
else if (token === '--include-capsule')
|
|
2099
|
+
includeCapsule = true;
|
|
1819
2100
|
else if (token && token !== '--')
|
|
1820
2101
|
positional.push(token);
|
|
1821
2102
|
}
|
|
1822
2103
|
const action = positional.join(' ').trim();
|
|
1823
|
-
if (!action) {
|
|
1824
|
-
throw new Error('audrey guard requires an action, e.g. audrey guard --tool Bash "npm run deploy"');
|
|
1825
|
-
}
|
|
1826
2104
|
return {
|
|
1827
2105
|
tool,
|
|
1828
2106
|
action,
|
|
@@ -1833,28 +2111,164 @@ function parseGuardArgs(argv) {
|
|
|
1833
2111
|
override,
|
|
1834
2112
|
failOnWarn,
|
|
1835
2113
|
explain,
|
|
2114
|
+
hook,
|
|
2115
|
+
strict,
|
|
2116
|
+
includeCapsule,
|
|
1836
2117
|
};
|
|
1837
2118
|
}
|
|
2119
|
+
function guardDisplayDecision(result) {
|
|
2120
|
+
if (result.decision === 'block')
|
|
2121
|
+
return 'block';
|
|
2122
|
+
if (result.decision === 'caution')
|
|
2123
|
+
return 'warn';
|
|
2124
|
+
return 'allow';
|
|
2125
|
+
}
|
|
2126
|
+
function summarizeToolInput(payload, tool) {
|
|
2127
|
+
const input = (payload.tool_input && typeof payload.tool_input === 'object')
|
|
2128
|
+
? payload.tool_input
|
|
2129
|
+
: {};
|
|
2130
|
+
const command = typeof input.command === 'string' ? input.command : undefined;
|
|
2131
|
+
const fileFields = ['file_path', 'path', 'notebook_path'];
|
|
2132
|
+
const files = fileFields
|
|
2133
|
+
.map(field => input[field])
|
|
2134
|
+
.filter((value) => typeof value === 'string' && value.trim().length > 0);
|
|
2135
|
+
if (command)
|
|
2136
|
+
return { action: command, command, files };
|
|
2137
|
+
const description = typeof input.description === 'string' ? input.description : undefined;
|
|
2138
|
+
if (description)
|
|
2139
|
+
return { action: `${tool}: ${description}`, files };
|
|
2140
|
+
const compactInput = JSON.stringify(input);
|
|
2141
|
+
return {
|
|
2142
|
+
action: compactInput && compactInput !== '{}'
|
|
2143
|
+
? `${tool} ${compactInput}`
|
|
2144
|
+
: `Use ${tool}`,
|
|
2145
|
+
files,
|
|
2146
|
+
};
|
|
2147
|
+
}
|
|
2148
|
+
async function readHookPayload() {
|
|
2149
|
+
const chunks = [];
|
|
2150
|
+
for await (const chunk of process.stdin)
|
|
2151
|
+
chunks.push(chunk);
|
|
2152
|
+
const raw = Buffer.concat(chunks).toString('utf-8').trim();
|
|
2153
|
+
if (!raw)
|
|
2154
|
+
return {};
|
|
2155
|
+
return JSON.parse(raw);
|
|
2156
|
+
}
|
|
2157
|
+
function formatHookReason(result) {
|
|
2158
|
+
const recommendations = result.recommended_actions.slice(0, 3);
|
|
2159
|
+
return [
|
|
2160
|
+
result.summary,
|
|
2161
|
+
recommendations.length > 0 ? `Recommended: ${recommendations.join(' ')}` : '',
|
|
2162
|
+
result.evidence_ids.length > 0 ? `Evidence: ${result.evidence_ids.slice(0, 5).join(', ')}` : '',
|
|
2163
|
+
].filter(Boolean).join('\n');
|
|
2164
|
+
}
|
|
2165
|
+
function formatPreToolUseHookOutput(result, failOnWarn) {
|
|
2166
|
+
const decision = guardDisplayDecision(result);
|
|
2167
|
+
const shouldDeny = decision === 'block' || (failOnWarn && decision === 'warn');
|
|
2168
|
+
if (shouldDeny) {
|
|
2169
|
+
return {
|
|
2170
|
+
hookSpecificOutput: {
|
|
2171
|
+
hookEventName: 'PreToolUse',
|
|
2172
|
+
permissionDecision: 'deny',
|
|
2173
|
+
permissionDecisionReason: formatHookReason(result),
|
|
2174
|
+
},
|
|
2175
|
+
};
|
|
2176
|
+
}
|
|
2177
|
+
if (decision === 'warn') {
|
|
2178
|
+
return {
|
|
2179
|
+
hookSpecificOutput: {
|
|
2180
|
+
hookEventName: 'PreToolUse',
|
|
2181
|
+
additionalContext: formatHookReason(result),
|
|
2182
|
+
},
|
|
2183
|
+
};
|
|
2184
|
+
}
|
|
2185
|
+
return {};
|
|
2186
|
+
}
|
|
2187
|
+
function formatGuardDecision(result, { explain = false } = {}) {
|
|
2188
|
+
const display = guardDisplayDecision(result);
|
|
2189
|
+
const label = display === 'block' ? 'BLOCKED' : display === 'warn' ? 'WARN' : 'ALLOW';
|
|
2190
|
+
const lines = [];
|
|
2191
|
+
lines.push(`Audrey Guard: ${label}`);
|
|
2192
|
+
lines.push('');
|
|
2193
|
+
lines.push(`Receipt: ${result.receipt_id}`);
|
|
2194
|
+
lines.push(`Reason: ${result.summary}`);
|
|
2195
|
+
lines.push(`Risk score: ${result.risk_score.toFixed(2)}`);
|
|
2196
|
+
if (result.evidence_ids.length > 0) {
|
|
2197
|
+
lines.push('');
|
|
2198
|
+
lines.push('Evidence:');
|
|
2199
|
+
for (const id of result.evidence_ids.slice(0, 8))
|
|
2200
|
+
lines.push(`- ${id}`);
|
|
2201
|
+
}
|
|
2202
|
+
if (result.recommended_actions.length > 0) {
|
|
2203
|
+
lines.push('');
|
|
2204
|
+
lines.push('Recommended action:');
|
|
2205
|
+
for (const action of result.recommended_actions.slice(0, 5))
|
|
2206
|
+
lines.push(`- ${action}`);
|
|
2207
|
+
}
|
|
2208
|
+
if (result.reflexes.length > 0) {
|
|
2209
|
+
lines.push('');
|
|
2210
|
+
lines.push('Memory reflexes:');
|
|
2211
|
+
for (const reflex of result.reflexes.slice(0, 5)) {
|
|
2212
|
+
lines.push(`- ${reflex.response_type}: ${reflex.response}`);
|
|
2213
|
+
}
|
|
2214
|
+
}
|
|
2215
|
+
if (explain && result.capsule) {
|
|
2216
|
+
lines.push('');
|
|
2217
|
+
lines.push('Capsule:');
|
|
2218
|
+
for (const [section, entries] of Object.entries(result.capsule.sections)) {
|
|
2219
|
+
if (!Array.isArray(entries) || entries.length === 0)
|
|
2220
|
+
continue;
|
|
2221
|
+
lines.push(`- ${sectionTitle(section)}:`);
|
|
2222
|
+
for (const entry of entries.slice(0, 3)) {
|
|
2223
|
+
lines.push(` * ${entry.memory_id}: ${entry.content}`);
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
}
|
|
2227
|
+
if (display === 'block') {
|
|
2228
|
+
lines.push('');
|
|
2229
|
+
lines.push('Next: fix the warning and retry, or pass --override to allow this guard check.');
|
|
2230
|
+
}
|
|
2231
|
+
return lines.join('\n');
|
|
2232
|
+
}
|
|
1838
2233
|
async function guardCli() {
|
|
1839
2234
|
const args = parseGuardArgs(process.argv.slice(3));
|
|
1840
|
-
|
|
2235
|
+
if (!args.action && !args.hook) {
|
|
2236
|
+
console.error('[audrey] guard: action is required');
|
|
2237
|
+
process.exit(2);
|
|
2238
|
+
}
|
|
2239
|
+
const hookPayload = args.hook ? await readHookPayload() : null;
|
|
2240
|
+
const hookTool = hookPayload && typeof hookPayload.tool_name === 'string' ? hookPayload.tool_name : undefined;
|
|
2241
|
+
const hookSessionId = hookPayload && typeof hookPayload.session_id === 'string' ? hookPayload.session_id : undefined;
|
|
2242
|
+
const hookCwd = hookPayload && typeof hookPayload.cwd === 'string' ? hookPayload.cwd : undefined;
|
|
2243
|
+
const hookSummary = hookPayload ? summarizeToolInput(hookPayload, hookTool ?? args.tool) : null;
|
|
2244
|
+
const dataDir = resolveDataDir(process.env);
|
|
2245
|
+
const embedding = resolveEmbeddingProvider(process.env, process.env['AUDREY_EMBEDDING_PROVIDER']);
|
|
2246
|
+
const audrey = new Audrey({
|
|
2247
|
+
dataDir,
|
|
2248
|
+
agent: process.env['AUDREY_AGENT'] ?? 'guard',
|
|
2249
|
+
embedding,
|
|
2250
|
+
});
|
|
1841
2251
|
try {
|
|
1842
|
-
const
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
2252
|
+
const result = await audrey.beforeAction(hookSummary?.action ?? args.action, {
|
|
2253
|
+
tool: hookTool ?? args.tool,
|
|
2254
|
+
sessionId: args.sessionId ?? hookSessionId,
|
|
2255
|
+
cwd: args.cwd ?? hookCwd ?? process.cwd(),
|
|
2256
|
+
files: args.files.length > 0 ? args.files : hookSummary?.files?.length ? hookSummary.files : undefined,
|
|
2257
|
+
strict: args.strict || args.failOnWarn || args.hook,
|
|
2258
|
+
recordEvent: true,
|
|
2259
|
+
includeCapsule: args.includeCapsule || args.explain,
|
|
1850
2260
|
});
|
|
1851
|
-
if (args.
|
|
2261
|
+
if (args.hook) {
|
|
2262
|
+
console.log(JSON.stringify(formatPreToolUseHookOutput(result, args.failOnWarn)));
|
|
2263
|
+
}
|
|
2264
|
+
else if (args.json) {
|
|
1852
2265
|
console.log(JSON.stringify(result, null, 2));
|
|
1853
2266
|
}
|
|
1854
2267
|
else {
|
|
1855
|
-
console.log(
|
|
2268
|
+
console.log(formatGuardDecision(result, { explain: args.explain }));
|
|
1856
2269
|
}
|
|
1857
|
-
|
|
2270
|
+
const display = guardDisplayDecision(result);
|
|
2271
|
+
if (!args.hook && (display === 'block' || (args.failOnWarn && display === 'warn')) && !args.override) {
|
|
1858
2272
|
process.exitCode = 2;
|
|
1859
2273
|
}
|
|
1860
2274
|
}
|
|
@@ -1862,6 +2276,100 @@ async function guardCli() {
|
|
|
1862
2276
|
await audrey.closeAsync();
|
|
1863
2277
|
}
|
|
1864
2278
|
}
|
|
2279
|
+
function parseGuardAfterArgs(argv) {
|
|
2280
|
+
const out = {};
|
|
2281
|
+
for (let i = 0; i < argv.length; i++) {
|
|
2282
|
+
const token = argv[i];
|
|
2283
|
+
const next = () => argv[++i];
|
|
2284
|
+
if (token === '--receipt')
|
|
2285
|
+
out.receipt = next();
|
|
2286
|
+
else if (token === '--tool')
|
|
2287
|
+
out.tool = next();
|
|
2288
|
+
else if (token === '--session-id')
|
|
2289
|
+
out.sessionId = next();
|
|
2290
|
+
else if (token === '--outcome')
|
|
2291
|
+
out.outcome = next();
|
|
2292
|
+
else if (token === '--error-summary')
|
|
2293
|
+
out.errorSummary = next();
|
|
2294
|
+
else if (token === '--cwd')
|
|
2295
|
+
out.cwd = next();
|
|
2296
|
+
}
|
|
2297
|
+
return out;
|
|
2298
|
+
}
|
|
2299
|
+
async function readOptionalJsonFromStdin(command) {
|
|
2300
|
+
if (process.stdin.isTTY)
|
|
2301
|
+
return null;
|
|
2302
|
+
const chunks = [];
|
|
2303
|
+
for await (const chunk of process.stdin)
|
|
2304
|
+
chunks.push(chunk);
|
|
2305
|
+
const raw = Buffer.concat(chunks).toString('utf-8').trim();
|
|
2306
|
+
if (!raw)
|
|
2307
|
+
return null;
|
|
2308
|
+
try {
|
|
2309
|
+
return JSON.parse(raw);
|
|
2310
|
+
}
|
|
2311
|
+
catch {
|
|
2312
|
+
console.error(`[audrey] ${command}: stdin was not valid JSON, ignoring.`);
|
|
2313
|
+
return null;
|
|
2314
|
+
}
|
|
2315
|
+
}
|
|
2316
|
+
function inferGuardAfterOutcome(stdinPayload) {
|
|
2317
|
+
const response = stdinPayload?.tool_response
|
|
2318
|
+
?? stdinPayload?.tool_output
|
|
2319
|
+
?? stdinPayload?.output;
|
|
2320
|
+
const success = response?.success;
|
|
2321
|
+
if (typeof success === 'boolean')
|
|
2322
|
+
return success ? 'succeeded' : 'failed';
|
|
2323
|
+
const errField = response?.error ?? response?.stderr ?? stdinPayload?.error ?? stdinPayload?.stderr;
|
|
2324
|
+
if (errField && (typeof errField !== 'string' || errField.length > 0))
|
|
2325
|
+
return 'failed';
|
|
2326
|
+
return undefined;
|
|
2327
|
+
}
|
|
2328
|
+
async function guardAfterCli() {
|
|
2329
|
+
const args = parseGuardAfterArgs(process.argv.slice(3));
|
|
2330
|
+
if (!args.receipt) {
|
|
2331
|
+
console.error('[audrey] guard-after: --receipt is required');
|
|
2332
|
+
process.exit(2);
|
|
2333
|
+
}
|
|
2334
|
+
const stdinPayload = await readOptionalJsonFromStdin('guard-after');
|
|
2335
|
+
const outputPayload = stdinPayload?.tool_response ?? stdinPayload?.tool_output ?? stdinPayload?.output;
|
|
2336
|
+
const inputPayload = stdinPayload?.tool_input ?? stdinPayload?.input;
|
|
2337
|
+
const outcome = args.outcome ?? inferGuardAfterOutcome(stdinPayload);
|
|
2338
|
+
let errorSummary = args.errorSummary ?? stdinPayload?.error_summary;
|
|
2339
|
+
if (outcome === 'failed' && !errorSummary) {
|
|
2340
|
+
const response = outputPayload && typeof outputPayload === 'object'
|
|
2341
|
+
? outputPayload
|
|
2342
|
+
: undefined;
|
|
2343
|
+
const errField = response?.error ?? response?.stderr ?? stdinPayload?.error ?? stdinPayload?.stderr;
|
|
2344
|
+
if (typeof errField === 'string')
|
|
2345
|
+
errorSummary = errField;
|
|
2346
|
+
else if (errField !== undefined)
|
|
2347
|
+
errorSummary = JSON.stringify(errField);
|
|
2348
|
+
}
|
|
2349
|
+
const dataDir = resolveDataDir(process.env);
|
|
2350
|
+
const embedding = resolveEmbeddingProvider(process.env, process.env['AUDREY_EMBEDDING_PROVIDER']);
|
|
2351
|
+
const audrey = new Audrey({
|
|
2352
|
+
dataDir,
|
|
2353
|
+
agent: process.env['AUDREY_AGENT'] ?? 'guard-after',
|
|
2354
|
+
embedding,
|
|
2355
|
+
});
|
|
2356
|
+
try {
|
|
2357
|
+
const result = audrey.afterAction({
|
|
2358
|
+
receiptId: args.receipt,
|
|
2359
|
+
tool: args.tool ?? stdinPayload?.tool_name,
|
|
2360
|
+
sessionId: args.sessionId ?? stdinPayload?.session_id,
|
|
2361
|
+
input: inputPayload,
|
|
2362
|
+
output: outputPayload,
|
|
2363
|
+
outcome,
|
|
2364
|
+
errorSummary,
|
|
2365
|
+
cwd: args.cwd ?? stdinPayload?.cwd,
|
|
2366
|
+
});
|
|
2367
|
+
console.log(JSON.stringify(result));
|
|
2368
|
+
}
|
|
2369
|
+
finally {
|
|
2370
|
+
await audrey.closeAsync();
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
1865
2373
|
function parsePromoteArgs(argv) {
|
|
1866
2374
|
const out = {};
|
|
1867
2375
|
for (let i = 0; i < argv.length; i++) {
|
|
@@ -1949,60 +2457,61 @@ function canonicalEntryPath(path) {
|
|
|
1949
2457
|
const isDirectRun = Boolean(process.argv[1])
|
|
1950
2458
|
&& canonicalEntryPath(process.argv[1]) === canonicalEntryPath(fileURLToPath(import.meta.url));
|
|
1951
2459
|
const KNOWN_SUBCOMMANDS = [
|
|
1952
|
-
'install', 'uninstall', 'mcp-config', '
|
|
1953
|
-
'greeting', 'reflect', 'serve', 'status', 'doctor', 'observe-tool', 'promote', 'impact',
|
|
2460
|
+
'install', 'uninstall', 'mcp-config', 'hook-config', 'demo', 'reembed', 'dream',
|
|
2461
|
+
'greeting', 'reflect', 'serve', 'status', 'doctor', 'observe-tool', 'guard', 'guard-after', 'promote', 'impact',
|
|
1954
2462
|
];
|
|
1955
2463
|
function printHelp() {
|
|
1956
|
-
process.stdout.write(`audrey ${VERSION} — local-first memory runtime for AI agents
|
|
1957
|
-
|
|
1958
|
-
Usage: audrey <command> [options]
|
|
1959
|
-
|
|
2464
|
+
process.stdout.write(`audrey ${VERSION} — local-first memory runtime for AI agents
|
|
2465
|
+
|
|
2466
|
+
Usage: audrey <command> [options]
|
|
2467
|
+
|
|
1960
2468
|
Commands:
|
|
1961
2469
|
doctor Verify Node, MCP entrypoint, providers, and store health
|
|
1962
2470
|
demo Run a no-key, no-network proof of recall + reflexes
|
|
1963
|
-
demo --scenario repeated-failure
|
|
1964
|
-
Show Audrey Guard stopping a repeated deploy failure
|
|
1965
|
-
guard --tool <Tool> "<action>" Run memory-before-action guard; exits 2 on block
|
|
1966
|
-
Use --fail-on-warn for hooks/CI, --override to allow
|
|
1967
2471
|
status Print store health (add --json --fail-on-unhealthy for CI)
|
|
1968
2472
|
install [--host <h>] Register Audrey with an MCP host (codex, claude-code, generic)
|
|
1969
|
-
uninstall Remove Audrey from a host's MCP config
|
|
1970
|
-
mcp-config <host> Print raw MCP config block for a host (codex|generic|vscode)
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
1986
|
-
|
|
1987
|
-
|
|
1988
|
-
|
|
1989
|
-
|
|
1990
|
-
|
|
1991
|
-
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
1998
|
-
|
|
2473
|
+
uninstall Remove Audrey from a host's MCP config
|
|
2474
|
+
mcp-config <host> Print raw MCP config block for a host (codex|generic|vscode)
|
|
2475
|
+
hook-config claude-code Print Claude Code hook config (add --apply to merge settings)
|
|
2476
|
+
serve Start the REST sidecar (default port 7437; AUDREY_API_KEY recommended)
|
|
2477
|
+
dream Run consolidation + decay sweep
|
|
2478
|
+
reembed Recompute vectors after dimension/provider change
|
|
2479
|
+
greeting Emit session-start briefing (used by host hooks)
|
|
2480
|
+
reflect End-of-session memory capture from stdin transcript
|
|
2481
|
+
observe-tool Record a tool-trace event (--event, --tool, --outcome)
|
|
2482
|
+
guard Check memory before an action (--json, --tool, --strict)
|
|
2483
|
+
guard-after Record a guarded action outcome (--receipt, --outcome)
|
|
2484
|
+
impact Show closed-loop feedback metrics (--window N, --limit N, --json)
|
|
2485
|
+
promote Promote rules from observed traces (--dry-run to preview)
|
|
2486
|
+
|
|
2487
|
+
(no command) Start the MCP stdio server (used by MCP hosts)
|
|
2488
|
+
|
|
2489
|
+
Common options:
|
|
2490
|
+
-h, --help Print this help and exit
|
|
2491
|
+
-v, --version Print version and exit
|
|
2492
|
+
--include-secrets Include provider API keys in Claude Code install argv/config
|
|
2493
|
+
|
|
2494
|
+
Environment:
|
|
2495
|
+
AUDREY_DATA_DIR Path to SQLite memory store (default: ~/.audrey/data)
|
|
2496
|
+
AUDREY_AGENT Logical agent identity (default: local-agent)
|
|
2497
|
+
AUDREY_EMBEDDING_PROVIDER local | gemini | openai | mock
|
|
2498
|
+
AUDREY_LLM_PROVIDER anthropic | openai | mock
|
|
2499
|
+
AUDREY_ENABLE_ADMIN_TOOLS=1 Enable export, import, and forget tools/routes
|
|
2500
|
+
AUDREY_PORT REST sidecar port (default: 7437)
|
|
2501
|
+
AUDREY_API_KEY Bearer token required for non-loopback REST traffic
|
|
2502
|
+
AUDREY_PROFILE=1 Emit per-stage timings via _meta.diagnostics
|
|
2503
|
+
AUDREY_DISABLE_WARMUP=1 Skip background embedding warmup
|
|
2504
|
+
AUDREY_ONNX_VERBOSE=1 Show ONNX runtime warnings (off by default)
|
|
2505
|
+
|
|
1999
2506
|
Quick start:
|
|
2000
2507
|
npx audrey doctor
|
|
2001
2508
|
npx audrey demo --scenario repeated-failure
|
|
2002
2509
|
npx audrey guard --tool Bash "npm run deploy"
|
|
2003
2510
|
npx audrey install --host codex --dry-run
|
|
2004
|
-
|
|
2005
|
-
|
|
2511
|
+
npx audrey hook-config claude-code
|
|
2512
|
+
npx audrey hook-config claude-code --apply --scope project
|
|
2513
|
+
|
|
2514
|
+
Docs: https://github.com/Evilander/Audrey
|
|
2006
2515
|
`);
|
|
2007
2516
|
}
|
|
2008
2517
|
function printVersion() {
|
|
@@ -2028,18 +2537,15 @@ if (isDirectRun) {
|
|
|
2028
2537
|
else if (subcommand === 'mcp-config') {
|
|
2029
2538
|
printMcpConfig();
|
|
2030
2539
|
}
|
|
2540
|
+
else if (subcommand === 'hook-config') {
|
|
2541
|
+
printHookConfig();
|
|
2542
|
+
}
|
|
2031
2543
|
else if (subcommand === 'demo') {
|
|
2032
2544
|
runDemoCommand().catch(err => {
|
|
2033
2545
|
console.error('[audrey] demo failed:', err);
|
|
2034
2546
|
process.exit(1);
|
|
2035
2547
|
});
|
|
2036
2548
|
}
|
|
2037
|
-
else if (subcommand === 'guard') {
|
|
2038
|
-
guardCli().catch(err => {
|
|
2039
|
-
console.error('[audrey] guard failed:', err);
|
|
2040
|
-
process.exit(1);
|
|
2041
|
-
});
|
|
2042
|
-
}
|
|
2043
2549
|
else if (subcommand === 'reembed') {
|
|
2044
2550
|
reembed().catch(err => {
|
|
2045
2551
|
console.error('[audrey] reembed failed:', err);
|
|
@@ -2082,6 +2588,18 @@ if (isDirectRun) {
|
|
|
2082
2588
|
process.exit(1);
|
|
2083
2589
|
});
|
|
2084
2590
|
}
|
|
2591
|
+
else if (subcommand === 'guard') {
|
|
2592
|
+
guardCli().catch(err => {
|
|
2593
|
+
console.error('[audrey] guard failed:', err);
|
|
2594
|
+
process.exit(1);
|
|
2595
|
+
});
|
|
2596
|
+
}
|
|
2597
|
+
else if (subcommand === 'guard-after') {
|
|
2598
|
+
guardAfterCli().catch(err => {
|
|
2599
|
+
console.error('[audrey] guard-after failed:', err);
|
|
2600
|
+
process.exit(1);
|
|
2601
|
+
});
|
|
2602
|
+
}
|
|
2085
2603
|
else if (subcommand === 'impact') {
|
|
2086
2604
|
impact().catch(err => {
|
|
2087
2605
|
console.error('[audrey] impact failed:', err);
|