@ainyc/canonry 2.0.0 → 2.2.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.
@@ -16,6 +16,7 @@ import { drizzle } from "drizzle-orm/better-sqlite3";
16
16
  // ../db/src/schema.ts
17
17
  var schema_exports = {};
18
18
  __export(schema_exports, {
19
+ agentMemory: () => agentMemory,
19
20
  agentSessions: () => agentSessions,
20
21
  apiKeys: () => apiKeys,
21
22
  auditLog: () => auditLog,
@@ -425,6 +426,18 @@ var agentSessions = sqliteTable("agent_sessions", {
425
426
  index("idx_agent_sessions_project").on(table.projectId),
426
427
  index("idx_agent_sessions_updated").on(table.updatedAt)
427
428
  ]);
429
+ var agentMemory = sqliteTable("agent_memory", {
430
+ id: text("id").primaryKey(),
431
+ projectId: text("project_id").notNull().references(() => projects.id, { onDelete: "cascade" }),
432
+ key: text("key").notNull(),
433
+ value: text("value").notNull(),
434
+ source: text("source").notNull(),
435
+ createdAt: text("created_at").notNull(),
436
+ updatedAt: text("updated_at").notNull()
437
+ }, (table) => [
438
+ uniqueIndex("uniq_agent_memory_project_key").on(table.projectId, table.key),
439
+ index("idx_agent_memory_project_updated").on(table.projectId, table.updatedAt)
440
+ ]);
428
441
 
429
442
  // ../db/src/client.ts
430
443
  function createClient(databasePath) {
@@ -894,7 +907,21 @@ var MIGRATIONS = [
894
907
  // registry no longer recognizes 'anthropic'/'google'. Safe to re-run: the
895
908
  // UPDATE is a no-op once the rename has been applied.
896
909
  `UPDATE agent_sessions SET model_provider = 'claude' WHERE model_provider = 'anthropic'`,
897
- `UPDATE agent_sessions SET model_provider = 'gemini' WHERE model_provider = 'google'`
910
+ `UPDATE agent_sessions SET model_provider = 'gemini' WHERE model_provider = 'google'`,
911
+ // v40: Aero durable memory — project-scoped notes + compaction summaries.
912
+ `CREATE TABLE IF NOT EXISTS agent_memory (
913
+ id TEXT PRIMARY KEY,
914
+ project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,
915
+ key TEXT NOT NULL,
916
+ value TEXT NOT NULL,
917
+ source TEXT NOT NULL,
918
+ created_at TEXT NOT NULL,
919
+ updated_at TEXT NOT NULL
920
+ )`,
921
+ `CREATE UNIQUE INDEX IF NOT EXISTS uniq_agent_memory_project_key
922
+ ON agent_memory(project_id, key)`,
923
+ `CREATE INDEX IF NOT EXISTS idx_agent_memory_project_updated
924
+ ON agent_memory(project_id, updated_at)`
898
925
  ];
899
926
  function isDuplicateColumnError(err) {
900
927
  if (!(err instanceof Error)) return false;
@@ -1425,6 +1452,7 @@ export {
1425
1452
  insights,
1426
1453
  healthSnapshots,
1427
1454
  agentSessions,
1455
+ agentMemory,
1428
1456
  createClient,
1429
1457
  parseJsonColumn,
1430
1458
  extractLegacyCredentials,
package/dist/cli.js CHANGED
@@ -35,7 +35,7 @@ import {
35
35
  showFirstRunNotice,
36
36
  trackEvent,
37
37
  usageError
38
- } from "./chunk-YZKLIUH4.js";
38
+ } from "./chunk-2QNWFP6R.js";
39
39
  import {
40
40
  apiKeys,
41
41
  competitors,
@@ -45,7 +45,7 @@ import {
45
45
  projects,
46
46
  querySnapshots,
47
47
  runs
48
- } from "./chunk-GH6WGN5B.js";
48
+ } from "./chunk-TAII35VC.js";
49
49
 
50
50
  // src/cli.ts
51
51
  import { pathToFileURL } from "url";
@@ -292,7 +292,7 @@ async function backfillAnswerVisibilityCommand(opts) {
292
292
  console.log(` Errors: ${providerErrors}`);
293
293
  }
294
294
  async function backfillInsightsCommand(project, opts) {
295
- const { IntelligenceService } = await import("./intelligence-service-LHWXONQJ.js");
295
+ const { IntelligenceService } = await import("./intelligence-service-C5LAYDFM.js");
296
296
  const config = loadConfig();
297
297
  const db = createClient(config.database);
298
298
  migrate(db);
@@ -7440,6 +7440,73 @@ async function agentTranscriptReset(opts) {
7440
7440
  }
7441
7441
  }
7442
7442
 
7443
+ // src/commands/agent-memory.ts
7444
+ function toFormat2(raw) {
7445
+ return raw === "json" ? "json" : "text";
7446
+ }
7447
+ async function agentMemoryList(opts) {
7448
+ const format = toFormat2(opts.format);
7449
+ try {
7450
+ const client = createApiClient();
7451
+ const result = await client.listAgentMemory(opts.project);
7452
+ if (format === "json") {
7453
+ console.log(JSON.stringify(result, null, 2));
7454
+ return;
7455
+ }
7456
+ if (result.entries.length === 0) {
7457
+ console.log(`No Aero memory notes for "${opts.project}".`);
7458
+ return;
7459
+ }
7460
+ console.log(`Aero memory for ${opts.project} \u2014 ${result.entries.length} note(s)
7461
+ `);
7462
+ for (const entry of result.entries) {
7463
+ console.log(`[${entry.source}] ${entry.key} (updated ${entry.updatedAt})`);
7464
+ console.log(` ${entry.value.replace(/\n/g, "\n ")}`);
7465
+ console.log();
7466
+ }
7467
+ } catch (err) {
7468
+ printCliError(err, format);
7469
+ process.exitCode = err instanceof CliError ? err.exitCode : 2;
7470
+ }
7471
+ }
7472
+ async function agentMemorySet(opts) {
7473
+ const format = toFormat2(opts.format);
7474
+ try {
7475
+ const client = createApiClient();
7476
+ const result = await client.setAgentMemory(opts.project, {
7477
+ key: opts.key,
7478
+ value: opts.value
7479
+ });
7480
+ if (format === "json") {
7481
+ console.log(JSON.stringify(result, null, 2));
7482
+ return;
7483
+ }
7484
+ console.log(`Stored note "${result.entry.key}" for "${opts.project}" (source=${result.entry.source}).`);
7485
+ } catch (err) {
7486
+ printCliError(err, format);
7487
+ process.exitCode = err instanceof CliError ? err.exitCode : 2;
7488
+ }
7489
+ }
7490
+ async function agentMemoryForget(opts) {
7491
+ const format = toFormat2(opts.format);
7492
+ try {
7493
+ const client = createApiClient();
7494
+ const result = await client.forgetAgentMemory(opts.project, opts.key);
7495
+ if (format === "json") {
7496
+ console.log(JSON.stringify(result, null, 2));
7497
+ return;
7498
+ }
7499
+ if (result.status === "forgotten") {
7500
+ console.log(`Forgot note "${opts.key}" for "${opts.project}".`);
7501
+ } else {
7502
+ console.log(`No note with key "${opts.key}" for "${opts.project}".`);
7503
+ }
7504
+ } catch (err) {
7505
+ printCliError(err, format);
7506
+ process.exitCode = err instanceof CliError ? err.exitCode : 2;
7507
+ }
7508
+ }
7509
+
7443
7510
  // src/cli-commands/agent.ts
7444
7511
  var AGENT_ASK_SCOPES = ["all", "read-only"];
7445
7512
  var AGENT_CLI_COMMANDS = [
@@ -7557,6 +7624,66 @@ var AGENT_CLI_COMMANDS = [
7557
7624
  }
7558
7625
  await agentTranscriptReset({ project, format: input.format });
7559
7626
  }
7627
+ },
7628
+ {
7629
+ path: ["agent", "memory", "list"],
7630
+ usage: "canonry agent memory list <project> [--format json]",
7631
+ options: {},
7632
+ run: async (input) => {
7633
+ const project = input.positionals[0];
7634
+ if (!project) {
7635
+ throw usageError("Usage: canonry agent memory list <project>", {
7636
+ message: "project name is required"
7637
+ });
7638
+ }
7639
+ await agentMemoryList({ project, format: input.format });
7640
+ }
7641
+ },
7642
+ {
7643
+ path: ["agent", "memory", "set"],
7644
+ usage: "canonry agent memory set <project> --key <k> --value <v> [--format json]",
7645
+ options: {
7646
+ key: stringOption(),
7647
+ value: stringOption()
7648
+ },
7649
+ run: async (input) => {
7650
+ const project = input.positionals[0];
7651
+ if (!project) {
7652
+ throw usageError("Usage: canonry agent memory set <project> --key <k> --value <v>", {
7653
+ message: "project name is required"
7654
+ });
7655
+ }
7656
+ const key = getString(input.values, "key");
7657
+ const value = getString(input.values, "value");
7658
+ if (!key || !value) {
7659
+ throw usageError("--key and --value are both required.", {
7660
+ message: "--key and --value are both required"
7661
+ });
7662
+ }
7663
+ await agentMemorySet({ project, key, value, format: input.format });
7664
+ }
7665
+ },
7666
+ {
7667
+ path: ["agent", "memory", "forget"],
7668
+ usage: "canonry agent memory forget <project> --key <k> [--format json]",
7669
+ options: {
7670
+ key: stringOption()
7671
+ },
7672
+ run: async (input) => {
7673
+ const project = input.positionals[0];
7674
+ if (!project) {
7675
+ throw usageError("Usage: canonry agent memory forget <project> --key <k>", {
7676
+ message: "project name is required"
7677
+ });
7678
+ }
7679
+ const key = getString(input.values, "key");
7680
+ if (!key) {
7681
+ throw usageError("--key is required.", {
7682
+ message: "--key is required"
7683
+ });
7684
+ }
7685
+ await agentMemoryForget({ project, key, format: input.format });
7686
+ }
7560
7687
  }
7561
7688
  ];
7562
7689
 
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  createServer,
3
3
  loadConfig
4
- } from "./chunk-YZKLIUH4.js";
5
- import "./chunk-GH6WGN5B.js";
4
+ } from "./chunk-2QNWFP6R.js";
5
+ import "./chunk-TAII35VC.js";
6
6
  export {
7
7
  createServer,
8
8
  loadConfig
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  IntelligenceService
3
- } from "./chunk-GH6WGN5B.js";
3
+ } from "./chunk-TAII35VC.js";
4
4
  export {
5
5
  IntelligenceService
6
6
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ainyc/canonry",
3
- "version": "2.0.0",
3
+ "version": "2.2.1",
4
4
  "type": "module",
5
5
  "description": "The ultimate open-source AEO monitoring tool - track how answer engines cite your domain",
6
6
  "license": "FSL-1.1-ALv2",
@@ -58,19 +58,19 @@
58
58
  "tsup": "^8.5.1",
59
59
  "tsx": "^4.19.0",
60
60
  "@ainyc/canonry-api-routes": "0.0.0",
61
- "@ainyc/canonry-contracts": "0.0.0",
62
61
  "@ainyc/canonry-config": "0.0.0",
62
+ "@ainyc/canonry-contracts": "0.0.0",
63
63
  "@ainyc/canonry-db": "0.0.0",
64
- "@ainyc/canonry-integration-google": "0.0.0",
65
64
  "@ainyc/canonry-intelligence": "0.0.0",
66
- "@ainyc/canonry-integration-bing": "0.0.0",
67
- "@ainyc/canonry-integration-wordpress": "0.0.0",
65
+ "@ainyc/canonry-integration-google": "0.0.0",
68
66
  "@ainyc/canonry-provider-cdp": "0.0.0",
67
+ "@ainyc/canonry-integration-wordpress": "0.0.0",
69
68
  "@ainyc/canonry-provider-claude": "0.0.0",
70
69
  "@ainyc/canonry-provider-gemini": "0.0.0",
70
+ "@ainyc/canonry-integration-bing": "0.0.0",
71
+ "@ainyc/canonry-provider-local": "0.0.0",
71
72
  "@ainyc/canonry-provider-openai": "0.0.0",
72
- "@ainyc/canonry-provider-perplexity": "0.0.0",
73
- "@ainyc/canonry-provider-local": "0.0.0"
73
+ "@ainyc/canonry-provider-perplexity": "0.0.0"
74
74
  },
75
75
  "scripts": {
76
76
  "build": "tsx scripts/copy-agent-assets.ts && tsup && tsx build-web.ts",