agentix-cli 0.14.0 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (100) hide show
  1. package/README.md +70 -34
  2. package/dist/agent-BCDPSPKU.js +2 -0
  3. package/dist/board-dashboard-LA7WW56M.js +5668 -0
  4. package/dist/board-dashboard-LA7WW56M.js.map +1 -0
  5. package/dist/chunk-5F3J55LG.js +2 -0
  6. package/dist/chunk-5F3J55LG.js.map +1 -0
  7. package/dist/chunk-64P4QHSZ.js +2 -0
  8. package/dist/chunk-64P4QHSZ.js.map +1 -0
  9. package/dist/chunk-7FJQGD6U.js +6 -0
  10. package/dist/chunk-7FJQGD6U.js.map +1 -0
  11. package/dist/{chunk-ZRYBSI5G.js → chunk-7MBTMCKY.js} +2 -2
  12. package/dist/chunk-ABDP7TDL.js +71 -0
  13. package/dist/chunk-ABDP7TDL.js.map +1 -0
  14. package/dist/chunk-BFZUG66X.js +45 -0
  15. package/dist/chunk-BFZUG66X.js.map +1 -0
  16. package/dist/chunk-CXY2RYNI.js +11 -0
  17. package/dist/chunk-CXY2RYNI.js.map +1 -0
  18. package/dist/chunk-FIOB3MEX.js +2 -0
  19. package/dist/chunk-FLOGK2U7.js +7 -0
  20. package/dist/chunk-FLOGK2U7.js.map +1 -0
  21. package/dist/{chunk-XVYMZ4M7.js → chunk-HVC6FJNP.js} +5 -5
  22. package/dist/chunk-K7BE4E35.js +138 -0
  23. package/dist/chunk-K7BE4E35.js.map +1 -0
  24. package/dist/chunk-KXJSLLSQ.js +199 -0
  25. package/dist/chunk-KXJSLLSQ.js.map +1 -0
  26. package/dist/chunk-LEIYC3BF.js +104 -0
  27. package/dist/chunk-LEIYC3BF.js.map +1 -0
  28. package/dist/{chunk-O72LPMBR.js → chunk-RB7265LO.js} +2 -2
  29. package/dist/chunk-WZEYII2S.js +6 -0
  30. package/dist/chunk-WZEYII2S.js.map +1 -0
  31. package/dist/chunk-YI2T5QYB.js +5 -0
  32. package/dist/{chunk-NJR5WF5E.js.map → chunk-YI2T5QYB.js.map} +1 -1
  33. package/dist/cli.js +209 -181
  34. package/dist/cli.js.map +1 -1
  35. package/dist/{compaction-7I3E5QUO.js → compaction-JBZZ7I7Y.js} +4 -4
  36. package/dist/config-LN6JEHMF.js +2 -0
  37. package/dist/config-mutator-24TH7PHM.js +2 -0
  38. package/dist/debug-3MEUO2P2.js +2 -0
  39. package/dist/{heal-OTGT5HHJ.js → heal-WKY5I4KB.js} +2 -2
  40. package/dist/index.d.ts +1078 -13
  41. package/dist/index.js +47 -44
  42. package/dist/index.js.map +1 -1
  43. package/dist/loader-PTCXLJEX.js +2 -0
  44. package/dist/memory-extract-AD7KMRPC.js +2 -0
  45. package/dist/{providers-G3WZ4RVJ.js → providers-VUIWO3ZK.js} +2 -2
  46. package/dist/query-PKGYE5HR.js +2 -0
  47. package/dist/registry-ASC2QS5K.js +2 -0
  48. package/dist/scheduler-A3TQOCKT.js +2 -0
  49. package/dist/scheduler-A3TQOCKT.js.map +1 -0
  50. package/dist/{subagent-WV7QKQ3L.js → subagent-2SJHSSJS.js} +2 -2
  51. package/dist/types-OIFU3KSQ.js +2 -0
  52. package/dist/types-OIFU3KSQ.js.map +1 -0
  53. package/dist/{usage-dashboard-M7AFIGMJ.js → usage-dashboard-QX3CF6KK.js} +8 -8
  54. package/dist/usage-dashboard-QX3CF6KK.js.map +1 -0
  55. package/dist/whatsapp-state-6D6FHHD2.js +2 -0
  56. package/dist/whatsapp-state-6D6FHHD2.js.map +1 -0
  57. package/dist/wiki-UDPYFJBL.js +2 -0
  58. package/dist/wiki-UDPYFJBL.js.map +1 -0
  59. package/dist/workspace-setup-ZWTT42XT.js +2 -0
  60. package/dist/workspace-setup-ZWTT42XT.js.map +1 -0
  61. package/package.json +3 -2
  62. package/dist/agent-DW3NYIIL.js +0 -2
  63. package/dist/board-dashboard-6TKE6NMV.js +0 -1435
  64. package/dist/board-dashboard-6TKE6NMV.js.map +0 -1
  65. package/dist/chunk-4YCH6IZV.js +0 -2
  66. package/dist/chunk-DYOBFJLX.js +0 -11
  67. package/dist/chunk-DYOBFJLX.js.map +0 -1
  68. package/dist/chunk-ITZEVXZ4.js +0 -2
  69. package/dist/chunk-ITZEVXZ4.js.map +0 -1
  70. package/dist/chunk-M33CB2H4.js +0 -6
  71. package/dist/chunk-M33CB2H4.js.map +0 -1
  72. package/dist/chunk-NJR5WF5E.js +0 -5
  73. package/dist/chunk-RB73FZXJ.js +0 -133
  74. package/dist/chunk-RB73FZXJ.js.map +0 -1
  75. package/dist/chunk-UPT2UMF6.js +0 -159
  76. package/dist/chunk-UPT2UMF6.js.map +0 -1
  77. package/dist/config-7QJ2QJIC.js +0 -2
  78. package/dist/config-mutator-GAEVGHDD.js +0 -2
  79. package/dist/debug-N3B5NVJU.js +0 -2
  80. package/dist/loader-YQE6XJBT.js +0 -2
  81. package/dist/memory-extract-RGPUPMKU.js +0 -2
  82. package/dist/registry-YVAG4EO5.js +0 -2
  83. package/dist/usage-dashboard-M7AFIGMJ.js.map +0 -1
  84. package/dist/workspace-setup-QQTCJY4B.js +0 -2
  85. /package/dist/{agent-DW3NYIIL.js.map → agent-BCDPSPKU.js.map} +0 -0
  86. /package/dist/{chunk-ZRYBSI5G.js.map → chunk-7MBTMCKY.js.map} +0 -0
  87. /package/dist/{chunk-4YCH6IZV.js.map → chunk-FIOB3MEX.js.map} +0 -0
  88. /package/dist/{chunk-XVYMZ4M7.js.map → chunk-HVC6FJNP.js.map} +0 -0
  89. /package/dist/{chunk-O72LPMBR.js.map → chunk-RB7265LO.js.map} +0 -0
  90. /package/dist/{compaction-7I3E5QUO.js.map → compaction-JBZZ7I7Y.js.map} +0 -0
  91. /package/dist/{config-7QJ2QJIC.js.map → config-LN6JEHMF.js.map} +0 -0
  92. /package/dist/{config-mutator-GAEVGHDD.js.map → config-mutator-24TH7PHM.js.map} +0 -0
  93. /package/dist/{debug-N3B5NVJU.js.map → debug-3MEUO2P2.js.map} +0 -0
  94. /package/dist/{heal-OTGT5HHJ.js.map → heal-WKY5I4KB.js.map} +0 -0
  95. /package/dist/{loader-YQE6XJBT.js.map → loader-PTCXLJEX.js.map} +0 -0
  96. /package/dist/{memory-extract-RGPUPMKU.js.map → memory-extract-AD7KMRPC.js.map} +0 -0
  97. /package/dist/{providers-G3WZ4RVJ.js.map → providers-VUIWO3ZK.js.map} +0 -0
  98. /package/dist/{registry-YVAG4EO5.js.map → query-PKGYE5HR.js.map} +0 -0
  99. /package/dist/{workspace-setup-QQTCJY4B.js.map → registry-ASC2QS5K.js.map} +0 -0
  100. /package/dist/{subagent-WV7QKQ3L.js.map → subagent-2SJHSSJS.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -1311,6 +1311,11 @@ declare const agentConfigSchema: z.ZodObject<{
1311
1311
  channel?: string | undefined;
1312
1312
  intervalMinutes?: number | undefined;
1313
1313
  }>>;
1314
+ /** Reachability via the external public API.
1315
+ * - "private" (default): this agent is daemon-internal + channel-bound only.
1316
+ * - "public": external apps can POST /api/public/agents/<id>/messages
1317
+ * with a scoped token (agent:<id> or agent:*). */
1318
+ access: z.ZodDefault<z.ZodEnum<["private", "public"]>>;
1314
1319
  }, "strip", z.ZodTypeAny, {
1315
1320
  name: string;
1316
1321
  workspace: string;
@@ -1326,6 +1331,7 @@ declare const agentConfigSchema: z.ZodObject<{
1326
1331
  channel: string;
1327
1332
  intervalMinutes: number;
1328
1333
  };
1334
+ access: "private" | "public";
1329
1335
  provider?: string | undefined;
1330
1336
  model?: string | undefined;
1331
1337
  systemPrompt?: string | undefined;
@@ -1347,6 +1353,7 @@ declare const agentConfigSchema: z.ZodObject<{
1347
1353
  channel?: string | undefined;
1348
1354
  intervalMinutes?: number | undefined;
1349
1355
  } | undefined;
1356
+ access?: "private" | "public" | undefined;
1350
1357
  }>;
1351
1358
  declare const cronJobSchema: z.ZodObject<{
1352
1359
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -1480,6 +1487,11 @@ declare const daemonConfigSchema: z.ZodObject<{
1480
1487
  channel?: string | undefined;
1481
1488
  intervalMinutes?: number | undefined;
1482
1489
  }>>;
1490
+ /** Reachability via the external public API.
1491
+ * - "private" (default): this agent is daemon-internal + channel-bound only.
1492
+ * - "public": external apps can POST /api/public/agents/<id>/messages
1493
+ * with a scoped token (agent:<id> or agent:*). */
1494
+ access: z.ZodDefault<z.ZodEnum<["private", "public"]>>;
1483
1495
  }, "strip", z.ZodTypeAny, {
1484
1496
  name: string;
1485
1497
  workspace: string;
@@ -1495,6 +1507,7 @@ declare const daemonConfigSchema: z.ZodObject<{
1495
1507
  channel: string;
1496
1508
  intervalMinutes: number;
1497
1509
  };
1510
+ access: "private" | "public";
1498
1511
  provider?: string | undefined;
1499
1512
  model?: string | undefined;
1500
1513
  systemPrompt?: string | undefined;
@@ -1516,6 +1529,7 @@ declare const daemonConfigSchema: z.ZodObject<{
1516
1529
  channel?: string | undefined;
1517
1530
  intervalMinutes?: number | undefined;
1518
1531
  } | undefined;
1532
+ access?: "private" | "public" | undefined;
1519
1533
  }>>>;
1520
1534
  channels: z.ZodDefault<z.ZodObject<{
1521
1535
  telegram: z.ZodDefault<z.ZodObject<{
@@ -1523,20 +1537,36 @@ declare const daemonConfigSchema: z.ZodObject<{
1523
1537
  accounts: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1524
1538
  token: z.ZodString;
1525
1539
  agentBinding: z.ZodString;
1540
+ /** Per-account sender allowlist. When set, OVERRIDES the global
1541
+ * `policy.allowFrom`. Entries accept:
1542
+ * - numeric user id ("1816212449") — matches sender (from.id)
1543
+ * - numeric chat id ("-1003861455814") — matches chat (chat.id)
1544
+ * - "@username" — matches sender username
1545
+ * A message is dispatched iff at least one entry matches. */
1546
+ allowFrom: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1526
1547
  }, "strip", z.ZodTypeAny, {
1527
1548
  token: string;
1528
1549
  agentBinding: string;
1550
+ allowFrom?: string[] | undefined;
1529
1551
  }, {
1530
1552
  token: string;
1531
1553
  agentBinding: string;
1554
+ allowFrom?: string[] | undefined;
1532
1555
  }>>>;
1533
1556
  policy: z.ZodDefault<z.ZodObject<{
1534
1557
  dm: z.ZodDefault<z.ZodEnum<["pair", "block"]>>;
1535
1558
  group: z.ZodDefault<z.ZodEnum<["mention-required", "all"]>>;
1559
+ /** Global sender allowlist applied to every account that doesn't set
1560
+ * its own `allowFrom`. When neither is configured, every incoming
1561
+ * message is dropped — closed by default. Same entry forms as the
1562
+ * per-account list (user id, chat id, @username). */
1563
+ allowFrom: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1536
1564
  }, "strip", z.ZodTypeAny, {
1537
1565
  dm: "block" | "pair";
1538
1566
  group: "all" | "mention-required";
1567
+ allowFrom?: string[] | undefined;
1539
1568
  }, {
1569
+ allowFrom?: string[] | undefined;
1540
1570
  dm?: "block" | "pair" | undefined;
1541
1571
  group?: "all" | "mention-required" | undefined;
1542
1572
  }>>;
@@ -1545,18 +1575,22 @@ declare const daemonConfigSchema: z.ZodObject<{
1545
1575
  accounts: Record<string, {
1546
1576
  token: string;
1547
1577
  agentBinding: string;
1578
+ allowFrom?: string[] | undefined;
1548
1579
  }>;
1549
1580
  policy: {
1550
1581
  dm: "block" | "pair";
1551
1582
  group: "all" | "mention-required";
1583
+ allowFrom?: string[] | undefined;
1552
1584
  };
1553
1585
  }, {
1554
1586
  enabled?: boolean | undefined;
1555
1587
  accounts?: Record<string, {
1556
1588
  token: string;
1557
1589
  agentBinding: string;
1590
+ allowFrom?: string[] | undefined;
1558
1591
  }> | undefined;
1559
1592
  policy?: {
1593
+ allowFrom?: string[] | undefined;
1560
1594
  dm?: "block" | "pair" | undefined;
1561
1595
  group?: "all" | "mention-required" | undefined;
1562
1596
  } | undefined;
@@ -1587,13 +1621,13 @@ declare const daemonConfigSchema: z.ZodObject<{
1587
1621
  group?: string | undefined;
1588
1622
  contact?: string | undefined;
1589
1623
  }[];
1590
- defaultAgent?: string | undefined;
1591
1624
  allowFrom?: string[] | undefined;
1625
+ defaultAgent?: string | undefined;
1592
1626
  }, {
1593
1627
  enabled?: boolean | undefined;
1628
+ allowFrom?: string[] | undefined;
1594
1629
  sessionDir?: string | undefined;
1595
1630
  defaultAgent?: string | undefined;
1596
- allowFrom?: string[] | undefined;
1597
1631
  routes?: {
1598
1632
  agent: string;
1599
1633
  group?: string | undefined;
@@ -1613,6 +1647,24 @@ declare const daemonConfigSchema: z.ZodObject<{
1613
1647
  token?: string | undefined;
1614
1648
  agentBinding?: string | undefined;
1615
1649
  }>>;
1650
+ slack: z.ZodDefault<z.ZodObject<{
1651
+ enabled: z.ZodDefault<z.ZodBoolean>;
1652
+ /** xoxb-... — bot user OAuth token from the Slack app's "OAuth & Permissions" tab. */
1653
+ botToken: z.ZodOptional<z.ZodString>;
1654
+ /** xapp-... — app-level token with connections:write scope (for Socket Mode). */
1655
+ appToken: z.ZodOptional<z.ZodString>;
1656
+ agentBinding: z.ZodOptional<z.ZodString>;
1657
+ }, "strip", z.ZodTypeAny, {
1658
+ enabled: boolean;
1659
+ agentBinding?: string | undefined;
1660
+ botToken?: string | undefined;
1661
+ appToken?: string | undefined;
1662
+ }, {
1663
+ enabled?: boolean | undefined;
1664
+ agentBinding?: string | undefined;
1665
+ botToken?: string | undefined;
1666
+ appToken?: string | undefined;
1667
+ }>>;
1616
1668
  gitlab: z.ZodDefault<z.ZodObject<{
1617
1669
  enabled: z.ZodDefault<z.ZodBoolean>;
1618
1670
  webhookPort: z.ZodDefault<z.ZodNumber>;
@@ -1711,10 +1763,12 @@ declare const daemonConfigSchema: z.ZodObject<{
1711
1763
  accounts: Record<string, {
1712
1764
  token: string;
1713
1765
  agentBinding: string;
1766
+ allowFrom?: string[] | undefined;
1714
1767
  }>;
1715
1768
  policy: {
1716
1769
  dm: "block" | "pair";
1717
1770
  group: "all" | "mention-required";
1771
+ allowFrom?: string[] | undefined;
1718
1772
  };
1719
1773
  };
1720
1774
  whatsapp: {
@@ -1725,14 +1779,20 @@ declare const daemonConfigSchema: z.ZodObject<{
1725
1779
  group?: string | undefined;
1726
1780
  contact?: string | undefined;
1727
1781
  }[];
1728
- defaultAgent?: string | undefined;
1729
1782
  allowFrom?: string[] | undefined;
1783
+ defaultAgent?: string | undefined;
1730
1784
  };
1731
1785
  discord: {
1732
1786
  enabled: boolean;
1733
1787
  token?: string | undefined;
1734
1788
  agentBinding?: string | undefined;
1735
1789
  };
1790
+ slack: {
1791
+ enabled: boolean;
1792
+ agentBinding?: string | undefined;
1793
+ botToken?: string | undefined;
1794
+ appToken?: string | undefined;
1795
+ };
1736
1796
  }, {
1737
1797
  gitlab?: {
1738
1798
  enabled?: boolean | undefined;
@@ -1757,17 +1817,19 @@ declare const daemonConfigSchema: z.ZodObject<{
1757
1817
  accounts?: Record<string, {
1758
1818
  token: string;
1759
1819
  agentBinding: string;
1820
+ allowFrom?: string[] | undefined;
1760
1821
  }> | undefined;
1761
1822
  policy?: {
1823
+ allowFrom?: string[] | undefined;
1762
1824
  dm?: "block" | "pair" | undefined;
1763
1825
  group?: "all" | "mention-required" | undefined;
1764
1826
  } | undefined;
1765
1827
  } | undefined;
1766
1828
  whatsapp?: {
1767
1829
  enabled?: boolean | undefined;
1830
+ allowFrom?: string[] | undefined;
1768
1831
  sessionDir?: string | undefined;
1769
1832
  defaultAgent?: string | undefined;
1770
- allowFrom?: string[] | undefined;
1771
1833
  routes?: {
1772
1834
  agent: string;
1773
1835
  group?: string | undefined;
@@ -1779,6 +1841,12 @@ declare const daemonConfigSchema: z.ZodObject<{
1779
1841
  token?: string | undefined;
1780
1842
  agentBinding?: string | undefined;
1781
1843
  } | undefined;
1844
+ slack?: {
1845
+ enabled?: boolean | undefined;
1846
+ agentBinding?: string | undefined;
1847
+ botToken?: string | undefined;
1848
+ appToken?: string | undefined;
1849
+ } | undefined;
1782
1850
  }>>;
1783
1851
  crons: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1784
1852
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -2359,18 +2427,27 @@ declare const daemonConfigSchema: z.ZodObject<{
2359
2427
  bind: z.ZodDefault<z.ZodString>;
2360
2428
  token: z.ZodOptional<z.ZodString>;
2361
2429
  daemonUrl: z.ZodDefault<z.ZodString>;
2430
+ /** Soft cap on output length. Claude Code CLI has no hard flag for this,
2431
+ * but appending an instruction to the prompt is reliably honored. Use
2432
+ * 1500 for briefs, 500 for status pings, 300 for pure classifiers. */
2362
2433
  daemons: z.ZodDefault<z.ZodArray<z.ZodObject<{
2363
2434
  name: z.ZodString;
2364
2435
  url: z.ZodString;
2436
+ dashboardUrl: z.ZodOptional<z.ZodString>;
2365
2437
  token: z.ZodOptional<z.ZodString>;
2438
+ dashboardToken: z.ZodOptional<z.ZodString>;
2366
2439
  }, "strip", z.ZodTypeAny, {
2367
2440
  name: string;
2368
2441
  url: string;
2369
2442
  token?: string | undefined;
2443
+ dashboardUrl?: string | undefined;
2444
+ dashboardToken?: string | undefined;
2370
2445
  }, {
2371
2446
  name: string;
2372
2447
  url: string;
2373
2448
  token?: string | undefined;
2449
+ dashboardUrl?: string | undefined;
2450
+ dashboardToken?: string | undefined;
2374
2451
  }>, "many">>;
2375
2452
  draftAgent: z.ZodOptional<z.ZodString>;
2376
2453
  }, "strip", z.ZodTypeAny, {
@@ -2382,6 +2459,8 @@ declare const daemonConfigSchema: z.ZodObject<{
2382
2459
  name: string;
2383
2460
  url: string;
2384
2461
  token?: string | undefined;
2462
+ dashboardUrl?: string | undefined;
2463
+ dashboardToken?: string | undefined;
2385
2464
  }[];
2386
2465
  token?: string | undefined;
2387
2466
  draftAgent?: string | undefined;
@@ -2395,9 +2474,100 @@ declare const daemonConfigSchema: z.ZodObject<{
2395
2474
  name: string;
2396
2475
  url: string;
2397
2476
  token?: string | undefined;
2477
+ dashboardUrl?: string | undefined;
2478
+ dashboardToken?: string | undefined;
2398
2479
  }[] | undefined;
2399
2480
  draftAgent?: string | undefined;
2400
2481
  }>>;
2482
+ graph: z.ZodDefault<z.ZodObject<{
2483
+ enabled: z.ZodDefault<z.ZodBoolean>;
2484
+ /** Where the schema/nodes/classifications live. Relative to cwd. */
2485
+ baseDir: z.ZodDefault<z.ZodString>;
2486
+ /** Which agent makes LLM classification proposals. Falls back to
2487
+ * `dashboard.draftAgent` at call sites if unset. */
2488
+ draftAgent: z.ZodOptional<z.ZodString>;
2489
+ /** Agent used by `agentx graph review` to triage pending classifications.
2490
+ * Should be an agent with the wiki skill so it can call `wiki query` for
2491
+ * context before deciding approve/reject. Falls back to draftAgent. */
2492
+ reviewAgent: z.ZodOptional<z.ZodString>;
2493
+ /** Structural auto-approval policy. Evaluated against each classification
2494
+ * independently of `autoApproveConfidence`; either triggers approval.
2495
+ * - "strict" : never approve via structure — every classification
2496
+ * waits for human review
2497
+ * - "extend-leaves" : auto-approve when the proposed path (a) reuses only
2498
+ * existing nodes, or (b) adds exactly one NEW node at
2499
+ * the deepest level. Structural changes (new mid-path
2500
+ * node, new root) still queue for review. Default.
2501
+ * - "any" : auto-approve every classification regardless of
2502
+ * structural change
2503
+ */
2504
+ autoApproveStructure: z.ZodDefault<z.ZodEnum<["strict", "extend-leaves", "any"]>>;
2505
+ /** Minimum classifier confidence (0..1) to auto-approve. OR'd with the
2506
+ * structural policy — either hitting the threshold lets the classification
2507
+ * bypass the pending queue. 1.0 (default) disables this knob, so approval
2508
+ * is driven by `autoApproveStructure` alone. Lower it to e.g. 0.7 if you
2509
+ * also want high-confidence structural changes auto-approved. */
2510
+ autoApproveConfidence: z.ZodDefault<z.ZodNumber>;
2511
+ /** Weights for the wiki hybrid retrieval score. Path-ancestry match vs
2512
+ * BM25 over article text. Sum need not be 1. */
2513
+ retrievalWeights: z.ZodDefault<z.ZodObject<{
2514
+ graph: z.ZodDefault<z.ZodNumber>;
2515
+ bm25: z.ZodDefault<z.ZodNumber>;
2516
+ }, "strip", z.ZodTypeAny, {
2517
+ graph: number;
2518
+ bm25: number;
2519
+ }, {
2520
+ graph?: number | undefined;
2521
+ bm25?: number | undefined;
2522
+ }>>;
2523
+ }, "strip", z.ZodTypeAny, {
2524
+ enabled: boolean;
2525
+ baseDir: string;
2526
+ autoApproveStructure: "any" | "strict" | "extend-leaves";
2527
+ autoApproveConfidence: number;
2528
+ retrievalWeights: {
2529
+ graph: number;
2530
+ bm25: number;
2531
+ };
2532
+ draftAgent?: string | undefined;
2533
+ reviewAgent?: string | undefined;
2534
+ }, {
2535
+ enabled?: boolean | undefined;
2536
+ draftAgent?: string | undefined;
2537
+ baseDir?: string | undefined;
2538
+ reviewAgent?: string | undefined;
2539
+ autoApproveStructure?: "any" | "strict" | "extend-leaves" | undefined;
2540
+ autoApproveConfidence?: number | undefined;
2541
+ retrievalWeights?: {
2542
+ graph?: number | undefined;
2543
+ bm25?: number | undefined;
2544
+ } | undefined;
2545
+ }>>;
2546
+ /** Registered inbound webhooks — an inventory the dashboard manages. Each
2547
+ * entry binds an (agent, source) pair to an optional signing secret. The
2548
+ * actual inbound URL is always POST /webhook/<agentId>/<source>. */
2549
+ webhooks: z.ZodDefault<z.ZodArray<z.ZodObject<{
2550
+ id: z.ZodString;
2551
+ source: z.ZodEnum<["gitlab", "github", "sentry", "stripe", "discord", "slack", "custom"]>;
2552
+ agentId: z.ZodString;
2553
+ secretEnv: z.ZodOptional<z.ZodString>;
2554
+ description: z.ZodOptional<z.ZodString>;
2555
+ enabled: z.ZodDefault<z.ZodBoolean>;
2556
+ }, "strip", z.ZodTypeAny, {
2557
+ enabled: boolean;
2558
+ id: string;
2559
+ source: "custom" | "gitlab" | "discord" | "slack" | "github" | "sentry" | "stripe";
2560
+ agentId: string;
2561
+ description?: string | undefined;
2562
+ secretEnv?: string | undefined;
2563
+ }, {
2564
+ id: string;
2565
+ source: "custom" | "gitlab" | "discord" | "slack" | "github" | "sentry" | "stripe";
2566
+ agentId: string;
2567
+ enabled?: boolean | undefined;
2568
+ description?: string | undefined;
2569
+ secretEnv?: string | undefined;
2570
+ }>, "many">>;
2401
2571
  /** Session cache-reuse policy. `staleMinutes` controls how long a Claude
2402
2572
  * session can idle before we rebuild the prompt from scratch (paying the
2403
2573
  * full cache-create tax again). Longer is cheaper at Opus rates but means
@@ -2425,6 +2595,7 @@ declare const daemonConfigSchema: z.ZodObject<{
2425
2595
  channel: string;
2426
2596
  intervalMinutes: number;
2427
2597
  };
2598
+ access: "private" | "public";
2428
2599
  provider?: string | undefined;
2429
2600
  model?: string | undefined;
2430
2601
  systemPrompt?: string | undefined;
@@ -2448,6 +2619,18 @@ declare const daemonConfigSchema: z.ZodObject<{
2448
2619
  bind: string;
2449
2620
  defaultAgent?: string | undefined;
2450
2621
  };
2622
+ graph: {
2623
+ enabled: boolean;
2624
+ baseDir: string;
2625
+ autoApproveStructure: "any" | "strict" | "extend-leaves";
2626
+ autoApproveConfidence: number;
2627
+ retrievalWeights: {
2628
+ graph: number;
2629
+ bm25: number;
2630
+ };
2631
+ draftAgent?: string | undefined;
2632
+ reviewAgent?: string | undefined;
2633
+ };
2451
2634
  providers: Record<string, {
2452
2635
  apiKey?: string | undefined;
2453
2636
  defaultModel?: string | undefined;
@@ -2477,10 +2660,12 @@ declare const daemonConfigSchema: z.ZodObject<{
2477
2660
  accounts: Record<string, {
2478
2661
  token: string;
2479
2662
  agentBinding: string;
2663
+ allowFrom?: string[] | undefined;
2480
2664
  }>;
2481
2665
  policy: {
2482
2666
  dm: "block" | "pair";
2483
2667
  group: "all" | "mention-required";
2668
+ allowFrom?: string[] | undefined;
2484
2669
  };
2485
2670
  };
2486
2671
  whatsapp: {
@@ -2491,14 +2676,20 @@ declare const daemonConfigSchema: z.ZodObject<{
2491
2676
  group?: string | undefined;
2492
2677
  contact?: string | undefined;
2493
2678
  }[];
2494
- defaultAgent?: string | undefined;
2495
2679
  allowFrom?: string[] | undefined;
2680
+ defaultAgent?: string | undefined;
2496
2681
  };
2497
2682
  discord: {
2498
2683
  enabled: boolean;
2499
2684
  token?: string | undefined;
2500
2685
  agentBinding?: string | undefined;
2501
2686
  };
2687
+ slack: {
2688
+ enabled: boolean;
2689
+ agentBinding?: string | undefined;
2690
+ botToken?: string | undefined;
2691
+ appToken?: string | undefined;
2692
+ };
2502
2693
  };
2503
2694
  crons: Record<string, {
2504
2695
  enabled: boolean;
@@ -2587,10 +2778,20 @@ declare const daemonConfigSchema: z.ZodObject<{
2587
2778
  name: string;
2588
2779
  url: string;
2589
2780
  token?: string | undefined;
2781
+ dashboardUrl?: string | undefined;
2782
+ dashboardToken?: string | undefined;
2590
2783
  }[];
2591
2784
  token?: string | undefined;
2592
2785
  draftAgent?: string | undefined;
2593
2786
  };
2787
+ webhooks: {
2788
+ enabled: boolean;
2789
+ id: string;
2790
+ source: "custom" | "gitlab" | "discord" | "slack" | "github" | "sentry" | "stripe";
2791
+ agentId: string;
2792
+ description?: string | undefined;
2793
+ secretEnv?: string | undefined;
2794
+ }[];
2594
2795
  session: {
2595
2796
  staleMinutes: number;
2596
2797
  };
@@ -2661,6 +2862,7 @@ declare const daemonConfigSchema: z.ZodObject<{
2661
2862
  channel?: string | undefined;
2662
2863
  intervalMinutes?: number | undefined;
2663
2864
  } | undefined;
2865
+ access?: "private" | "public" | undefined;
2664
2866
  }> | undefined;
2665
2867
  mesh?: {
2666
2868
  enabled?: boolean | undefined;
@@ -2675,6 +2877,18 @@ declare const daemonConfigSchema: z.ZodObject<{
2675
2877
  interval?: number | undefined;
2676
2878
  } | undefined;
2677
2879
  } | undefined;
2880
+ graph?: {
2881
+ enabled?: boolean | undefined;
2882
+ draftAgent?: string | undefined;
2883
+ baseDir?: string | undefined;
2884
+ reviewAgent?: string | undefined;
2885
+ autoApproveStructure?: "any" | "strict" | "extend-leaves" | undefined;
2886
+ autoApproveConfidence?: number | undefined;
2887
+ retrievalWeights?: {
2888
+ graph?: number | undefined;
2889
+ bm25?: number | undefined;
2890
+ } | undefined;
2891
+ } | undefined;
2678
2892
  providers?: Record<string, {
2679
2893
  apiKey?: string | undefined;
2680
2894
  defaultModel?: string | undefined;
@@ -2704,17 +2918,19 @@ declare const daemonConfigSchema: z.ZodObject<{
2704
2918
  accounts?: Record<string, {
2705
2919
  token: string;
2706
2920
  agentBinding: string;
2921
+ allowFrom?: string[] | undefined;
2707
2922
  }> | undefined;
2708
2923
  policy?: {
2924
+ allowFrom?: string[] | undefined;
2709
2925
  dm?: "block" | "pair" | undefined;
2710
2926
  group?: "all" | "mention-required" | undefined;
2711
2927
  } | undefined;
2712
2928
  } | undefined;
2713
2929
  whatsapp?: {
2714
2930
  enabled?: boolean | undefined;
2931
+ allowFrom?: string[] | undefined;
2715
2932
  sessionDir?: string | undefined;
2716
2933
  defaultAgent?: string | undefined;
2717
- allowFrom?: string[] | undefined;
2718
2934
  routes?: {
2719
2935
  agent: string;
2720
2936
  group?: string | undefined;
@@ -2726,6 +2942,12 @@ declare const daemonConfigSchema: z.ZodObject<{
2726
2942
  token?: string | undefined;
2727
2943
  agentBinding?: string | undefined;
2728
2944
  } | undefined;
2945
+ slack?: {
2946
+ enabled?: boolean | undefined;
2947
+ agentBinding?: string | undefined;
2948
+ botToken?: string | undefined;
2949
+ appToken?: string | undefined;
2950
+ } | undefined;
2729
2951
  } | undefined;
2730
2952
  crons?: Record<string, {
2731
2953
  agent: string;
@@ -2857,9 +3079,19 @@ declare const daemonConfigSchema: z.ZodObject<{
2857
3079
  name: string;
2858
3080
  url: string;
2859
3081
  token?: string | undefined;
3082
+ dashboardUrl?: string | undefined;
3083
+ dashboardToken?: string | undefined;
2860
3084
  }[] | undefined;
2861
3085
  draftAgent?: string | undefined;
2862
3086
  } | undefined;
3087
+ webhooks?: {
3088
+ id: string;
3089
+ source: "custom" | "gitlab" | "discord" | "slack" | "github" | "sentry" | "stripe";
3090
+ agentId: string;
3091
+ enabled?: boolean | undefined;
3092
+ description?: string | undefined;
3093
+ secretEnv?: string | undefined;
3094
+ }[] | undefined;
2863
3095
  session?: {
2864
3096
  staleMinutes?: number | undefined;
2865
3097
  } | undefined;
@@ -2974,6 +3206,12 @@ declare class AgentXDaemon {
2974
3206
  * GET /events — streams daemon logs in real-time.
2975
3207
  */
2976
3208
  private handleSSE;
3209
+ /**
3210
+ * Stream a single running task's live output as SSE.
3211
+ * Sends a `start` event with the existing buffer (so a late opener catches up),
3212
+ * then `chunk` events for every new delta, and `end` when the task finishes.
3213
+ */
3214
+ private handleTaskStream;
2977
3215
  private handleHttp;
2978
3216
  /**
2979
3217
  * OpenAI-compatible chat completions endpoint.
@@ -3245,14 +3483,27 @@ declare function executeOrchestrator(agent: AgentDef, task: AgentTask, apiKey?:
3245
3483
  */
3246
3484
  declare function executeTask(agent: AgentDef, task: AgentTask, providers: Record<string, {
3247
3485
  apiKey?: string;
3248
- }>, onDelta?: StreamCallback, historyContext?: string, resumeSessionId?: string): Promise<AgentResponse>;
3486
+ }>, onDelta?: StreamCallback, historyContext?: string, resumeSessionId?: string, onEvent?: (event: any) => void): Promise<AgentResponse>;
3249
3487
 
3250
3488
  type WikiAccess = "private" | "shared" | "public";
3251
3489
  /**
3252
- * Article metadata. Intentionally minimal — tags do the heavy lifting.
3490
+ * Article type — the organizational spine. Matches Farzapedia's
3491
+ * `type: person | project | place | concept | event`, extended with
3492
+ * `decision` and `pattern` for workflow-heavy corpora.
3493
+ * Optional on legacy articles; Phase 2 migration backfills it.
3494
+ */
3495
+ type WikiArticleType = "person" | "project" | "place" | "concept" | "event" | "decision" | "pattern";
3496
+ /**
3497
+ * Article metadata. `type` + `related` are the primary retrieval surface;
3498
+ * tags remain as a secondary hint but are no longer central.
3253
3499
  */
3254
3500
  interface WikiArticleMeta {
3255
3501
  title: string;
3502
+ /** Organizational spine — Phase 2 migration backfills any missing values. */
3503
+ type?: WikiArticleType;
3504
+ /** Wikilink targets (by title) — persisted from `[[wikilinks]]` in body. */
3505
+ related?: string[];
3506
+ /** Secondary hint, no longer the retrieval spine. */
3256
3507
  tags: string[];
3257
3508
  owner: string;
3258
3509
  access: WikiAccess;
@@ -3260,6 +3511,10 @@ interface WikiArticleMeta {
3260
3511
  created: string;
3261
3512
  lastUpdated: string;
3262
3513
  sources: string[];
3514
+ /** Intent graph path (root → leaf node ids) when the article was authored
3515
+ * under an active intent graph. Empty for legacy articles — retrieval
3516
+ * falls back to pure BM25 for those. */
3517
+ graphPath?: string[];
3263
3518
  }
3264
3519
  interface WikiArticle {
3265
3520
  meta: WikiArticleMeta;
@@ -3279,6 +3534,8 @@ interface WikiIndex {
3279
3534
  articles: Array<{
3280
3535
  path: string;
3281
3536
  title: string;
3537
+ type?: WikiArticleType;
3538
+ related?: string[];
3282
3539
  tags: string[];
3283
3540
  owner: string;
3284
3541
  access: WikiAccess;
@@ -3292,7 +3549,7 @@ interface WikiIndex {
3292
3549
  }
3293
3550
 
3294
3551
  declare class WikiStore {
3295
- private baseDir;
3552
+ readonly baseDir: string;
3296
3553
  private rawDir;
3297
3554
  private log;
3298
3555
  constructor(baseDir?: string, log?: (...args: unknown[]) => void);
@@ -3356,9 +3613,19 @@ declare class WikiStore {
3356
3613
  search(query: string, agentId: string, maxResults?: number): WikiArticle[];
3357
3614
  /**
3358
3615
  * Find articles relevant to a message (for context injection).
3359
- * Extracts keywords from the message and searches the wiki.
3616
+ *
3617
+ * Scoring:
3618
+ * - BM25 over title+tags+content (always)
3619
+ * - + ancestry bonus if the caller classified the message through the
3620
+ * intent graph and articles carry `graphPath` from a previous classification
3621
+ *
3622
+ * `weights.graph` is scaled against `weights.bm25`. When the caller omits
3623
+ * `messagePath`, retrieval collapses to pure BM25 and matches legacy behavior.
3360
3624
  */
3361
- findRelevant(message: string, agentId?: string, maxArticles?: number): WikiArticle[];
3625
+ findRelevant(message: string, agentId?: string, maxArticles?: number, messagePath?: string[], weights?: {
3626
+ graph: number;
3627
+ bm25: number;
3628
+ }): WikiArticle[];
3362
3629
  /**
3363
3630
  * Build context string from relevant wiki articles for prompt injection.
3364
3631
  * Token-efficient: includes title + first ~500 chars of each article.
@@ -3368,6 +3635,15 @@ declare class WikiStore {
3368
3635
  * Rebuild the master index.
3369
3636
  */
3370
3637
  rebuildIndex(): WikiIndex;
3638
+ /**
3639
+ * Write `_index.md` — the Farzapedia-style content catalog grouped by
3640
+ * article `type`. This is the one file the agentic query (Phase 3) reads
3641
+ * to pick candidate articles before walking the wikilink subgraph.
3642
+ *
3643
+ * Articles without a `type` land in "Untyped" at the bottom; the Phase 2
3644
+ * migration backfills those.
3645
+ */
3646
+ private writeCatalog;
3371
3647
  /**
3372
3648
  * Get wiki stats.
3373
3649
  */
@@ -3555,6 +3831,25 @@ interface RunningTask {
3555
3831
  /** Wall-clock start. */
3556
3832
  startedAt: Date;
3557
3833
  }
3834
+ type TaskOutputSubscriber = (chunk: string) => void;
3835
+ /** Persisted record of a finished task, written to .agentx/task-history. */
3836
+ interface TaskRecord {
3837
+ id: string;
3838
+ agentId: string;
3839
+ channel: string;
3840
+ chatId?: string;
3841
+ sender?: string;
3842
+ message: string;
3843
+ startedAt: string;
3844
+ endedAt: string;
3845
+ durationMs: number;
3846
+ ok: boolean;
3847
+ error?: string;
3848
+ /** Final agent text (one-shot, may be empty if streaming captured it). */
3849
+ responseText: string;
3850
+ /** Terminal-style transcript captured from stream-json events. */
3851
+ transcript: string;
3852
+ }
3558
3853
  declare class AgentRegistry {
3559
3854
  private agents;
3560
3855
  private config;
@@ -3567,14 +3862,31 @@ declare class AgentRegistry {
3567
3862
  private tokenTracker;
3568
3863
  private landscape?;
3569
3864
  private messageQueue;
3865
+ /** Intent Knowledge Graph classifier. Null when graph.enabled=false. */
3866
+ private classifier?;
3867
+ private graphStore?;
3868
+ /** Runtime handover store — shared with MessageRouter via file on disk. */
3869
+ private handoverStore;
3570
3870
  /** Active soul profile per agent+chat session: "agentId:channel:chatId" → profile name */
3571
3871
  private activeSouls;
3872
+ /** Live output captured per running task id — drives the dashboard streaming modal. */
3873
+ private taskOutputs;
3874
+ /** Last completed task summary per agent — single-line blurb for the dashboard card. */
3875
+ private lastSummaries;
3876
+ /** 24-hour sparkline cache per agent — recomputed from disk at most once a minute. */
3877
+ private sparklineCache;
3572
3878
  private log;
3573
3879
  constructor(config: DaemonConfig, log?: (...args: unknown[]) => void);
3574
3880
  /**
3575
3881
  * Set landscape builder (called after mesh init).
3576
3882
  */
3577
3883
  setLandscape(builder: LandscapeBuilder): void;
3884
+ /**
3885
+ * If there's an active handover routing TO this agent for this (channel,
3886
+ * chatId) pair AND the operator's summary hasn't been consumed yet, pull
3887
+ * + clear it so the target agent sees the note exactly once.
3888
+ */
3889
+ private buildHandoverNote;
3578
3890
  /**
3579
3891
  * Get agent definition by ID.
3580
3892
  */
@@ -3625,7 +3937,57 @@ declare class AgentRegistry {
3625
3937
  errors: number;
3626
3938
  lastActive?: Date;
3627
3939
  runningTasks: RunningTask[];
3940
+ lastSummary?: {
3941
+ text: string;
3942
+ at: string;
3943
+ ok: boolean;
3944
+ };
3945
+ hourlyTasks?: number[];
3628
3946
  }>;
3947
+ /**
3948
+ * Write a finished task record to disk under .agentx/task-history/<agent>/<yyyy-mm-dd>/.
3949
+ * Side-effects only — call sites should treat failure as best-effort.
3950
+ */
3951
+ private persistTaskRecord;
3952
+ /**
3953
+ * Compute a 24-hour hourly task-count sparkline for an agent from persisted
3954
+ * history. Returns an array of 24 numbers: buckets[0] = 23-24h ago,
3955
+ * buckets[23] = now-hour. Cached per-agent for 60s to keep snapshot load
3956
+ * reasonable when the dashboard polls every 2s.
3957
+ */
3958
+ getHourlySparkline(agentId: string, hours?: number): number[];
3959
+ /**
3960
+ * Rebuild the in-memory lastSummaries cache from disk so dashboard cards
3961
+ * show the most recent "what did they do" line even right after a restart.
3962
+ * Called once on daemon startup — one file read per agent.
3963
+ */
3964
+ hydrateLastSummariesFromDisk(): number;
3965
+ /**
3966
+ * Drop history folders older than retention window. Cheap startup-time
3967
+ * sweep — once a day is plenty, but doing it on every daemon boot is fine.
3968
+ */
3969
+ pruneTaskHistory(retentionDays?: number): number;
3970
+ /**
3971
+ * Newest-first list of task records for one agent, capped at `limit`.
3972
+ * Walks at most the last few day folders so this is O(limit), not O(history).
3973
+ */
3974
+ listTaskHistory(agentId: string, limit?: number): Array<Omit<TaskRecord, "transcript" | "responseText">>;
3975
+ /**
3976
+ * Look up one task's full record (transcript included) across the retention window.
3977
+ */
3978
+ getTaskRecord(agentId: string, taskId: string): TaskRecord | null;
3979
+ private safe;
3980
+ /**
3981
+ * Subscribe to live output for a running task. Returns the buffer that has
3982
+ * accumulated so far plus an unsubscribe handle. If the task is unknown,
3983
+ * returns null. If the task already finished, the subscriber is given the
3984
+ * tail buffer and immediately ended.
3985
+ */
3986
+ subscribeToTaskOutput(taskId: string, sub: TaskOutputSubscriber): {
3987
+ initial: string;
3988
+ done: boolean;
3989
+ unsubscribe: () => void;
3990
+ } | null;
3629
3991
  /**
3630
3992
  * Get token usage summary.
3631
3993
  */
@@ -3751,6 +4113,58 @@ interface ChannelAdapter {
3751
4113
  getChannelMeta?(chatId: string): Promise<ChannelMeta | undefined>;
3752
4114
  }
3753
4115
 
4116
+ interface HandoverOverride {
4117
+ channel: string;
4118
+ chatId: string;
4119
+ accountId?: string;
4120
+ fromAgent: string;
4121
+ toAgent: string;
4122
+ summary?: string;
4123
+ createdAt: string;
4124
+ createdBy?: string;
4125
+ /** When set, overrides past this time are treated as expired (ignored on
4126
+ * read, optionally pruned on access). null = indefinite. */
4127
+ expiresAt?: string | null;
4128
+ /** Set after the summary has been injected once. Route stays active. */
4129
+ summaryConsumedAt?: string;
4130
+ }
4131
+ interface HandoverFile {
4132
+ version: number;
4133
+ overrides: Record<string, HandoverOverride>;
4134
+ }
4135
+ declare class HandoverStore {
4136
+ readonly filePath: string;
4137
+ private log;
4138
+ constructor(opts?: {
4139
+ baseDir?: string;
4140
+ log?: (...args: unknown[]) => void;
4141
+ });
4142
+ /** Canonical key for an override. Using "-" for missing accountId keeps
4143
+ * the key shape uniform across channels. */
4144
+ key(channel: string, chatId: string, accountId?: string): string;
4145
+ load(): HandoverFile;
4146
+ private save;
4147
+ /** Return the active override for a chat, or undefined. Skips expired. */
4148
+ get(channel: string, chatId: string, accountId?: string): HandoverOverride | undefined;
4149
+ /** Create or replace an override. If `fromAgent` isn't supplied the caller
4150
+ * can pass "" and the router will fill it in from current routing. */
4151
+ set(o: Omit<HandoverOverride, "createdAt"> & {
4152
+ createdAt?: string;
4153
+ }): HandoverOverride;
4154
+ /** Remove an override (release the handover). Idempotent. */
4155
+ remove(channel: string, chatId: string, accountId?: string): boolean;
4156
+ /** Mark the summary as consumed (after it's been injected once). Route
4157
+ * stays active; subsequent messages just skip the note. */
4158
+ consumeSummary(channel: string, chatId: string, accountId?: string): string | undefined;
4159
+ /** List all non-expired overrides. Used by the admin UI. */
4160
+ listActive(): HandoverOverride[];
4161
+ /** Overrides pointing at this agent (incoming) or away from it (outgoing). */
4162
+ listByAgent(agentId: string): {
4163
+ incoming: HandoverOverride[];
4164
+ outgoing: HandoverOverride[];
4165
+ };
4166
+ }
4167
+
3754
4168
  interface ServiceTrigger {
3755
4169
  pattern: string;
3756
4170
  channel?: string;
@@ -4332,7 +4746,13 @@ declare class MessageRouter {
4332
4746
  private serviceMatcher?;
4333
4747
  private business?;
4334
4748
  private groupLog;
4749
+ /** Runtime per-chat routing overrides (handovers). Consulted at the top
4750
+ * of resolveAgent; config routes + mention matching only run when no
4751
+ * override applies. */
4752
+ private handoverStore;
4335
4753
  private log;
4754
+ /** Exposed so the admin panel + registry can share the same store. */
4755
+ getHandoverStore(): HandoverStore;
4336
4756
  /**
4337
4757
  * Short-TTL cache of recently processed incoming message IDs, keyed by
4338
4758
  * `<channel>:<accountId>:<id>`. Prevents duplicate replies from:
@@ -4359,6 +4779,8 @@ declare class MessageRouter {
4359
4779
  private readonly DEDUP_STORE_PATH;
4360
4780
  private dedupDirtyCount;
4361
4781
  private dedupSaveTimer?;
4782
+ /** Crash-safe inflight log (see InflightLog class above). */
4783
+ private inflight;
4362
4784
  constructor(registry: AgentRegistry, config: DaemonConfig, hooks?: HookRegistry, log?: (...args: unknown[]) => void);
4363
4785
  private loadDedupFromDisk;
4364
4786
  private scheduleDedupSave;
@@ -4381,6 +4803,12 @@ declare class MessageRouter {
4381
4803
  /** List registered channel names. */
4382
4804
  getChannelNames(): string[];
4383
4805
  startAll(): Promise<void>;
4806
+ /**
4807
+ * On startup, re-run any incoming message that was recorded as `start` but
4808
+ * never got a matching `done` in the inflight log. Those are tasks the
4809
+ * previous process committed to handling but crashed before completing.
4810
+ */
4811
+ private replayInflight;
4384
4812
  stopAll(): Promise<void>;
4385
4813
  /**
4386
4814
  * Returns true if this message id was processed within MESSAGE_ID_TTL_MS.
@@ -4388,6 +4816,9 @@ declare class MessageRouter {
4388
4816
  */
4389
4817
  private isDuplicateMessage;
4390
4818
  private handleMessage;
4819
+ /** The actual processing body — split out so handleMessage can wrap it in
4820
+ * the inflight try/finally without drowning the happy path in indentation. */
4821
+ private processResolvedMessage;
4391
4822
  private static readonly MAX_BOT_CHAIN_DEPTH;
4392
4823
  /**
4393
4824
  * Bot-to-bot conversation chain.
@@ -4423,6 +4854,7 @@ declare class MessageRouter {
4423
4854
  interface TelegramAccountConfig {
4424
4855
  token: string;
4425
4856
  agentBinding: string;
4857
+ allowFrom?: string[];
4426
4858
  }
4427
4859
  declare class TelegramAdapter implements ChannelAdapter {
4428
4860
  readonly name = "telegram";
@@ -4431,7 +4863,22 @@ declare class TelegramAdapter implements ChannelAdapter {
4431
4863
  private handler?;
4432
4864
  private polling;
4433
4865
  private log;
4434
- constructor(accounts: Record<string, TelegramAccountConfig>, log?: (...args: unknown[]) => void);
4866
+ /** Global allowlist fallback. When a per-account allowFrom is unset,
4867
+ * this list applies. When BOTH are unset, everything is rejected
4868
+ * (closed by default). */
4869
+ private globalAllowFrom?;
4870
+ constructor(accounts: Record<string, TelegramAccountConfig>, opts?: {
4871
+ policy?: {
4872
+ allowFrom?: string[];
4873
+ };
4874
+ }, log?: (...args: unknown[]) => void);
4875
+ /** Effective sender allowlist for an account. Returns undefined when the
4876
+ * account has no explicit config AND the global policy is unset — the
4877
+ * caller treats undefined as "closed, drop everything". */
4878
+ private effectiveAllowFrom;
4879
+ /** Accept a message only when at least one allowlist entry matches the
4880
+ * sender's user id, the chat id, or the sender's @username. */
4881
+ private isAllowed;
4435
4882
  onMessage(handler: (msg: IncomingMessage) => Promise<void>): void;
4436
4883
  start(): Promise<void>;
4437
4884
  stop(): Promise<void>;
@@ -4502,11 +4949,18 @@ declare class WhatsAppAdapter implements ChannelAdapter {
4502
4949
  private generation;
4503
4950
  private sentMessageIds;
4504
4951
  private log;
4952
+ /** Fires whenever the underlying WhatsApp socket emits a new QR or clears it.
4953
+ * Passing null means the session is now connected. */
4954
+ private onQR?;
4955
+ /** Fires whenever the connection state changes (connecting / open / close). */
4956
+ private onStatus?;
4505
4957
  constructor(config: {
4506
4958
  sessionDir: string;
4507
4959
  defaultAgent?: string;
4508
4960
  allowFrom?: string[];
4509
4961
  routes?: WhatsAppRoute[];
4962
+ onQR?: (qr: string | null) => void;
4963
+ onStatus?: (status: "connecting" | "open" | "close", detail?: string) => void;
4510
4964
  }, log?: (...args: unknown[]) => void);
4511
4965
  /**
4512
4966
  * Resolve which agent handles a message based on routes.
@@ -4617,6 +5071,606 @@ declare class CronScheduler {
4617
5071
  };
4618
5072
  }
4619
5073
 
5074
+ declare const axisTypeSchema: z.ZodEnum<["enum", "free", "ref"]>;
5075
+ type AxisType = z.infer<typeof axisTypeSchema>;
5076
+ declare const axisDefSchema: z.ZodObject<{
5077
+ name: z.ZodString;
5078
+ type: z.ZodEnum<["enum", "free", "ref"]>;
5079
+ /** For type="enum": closed set of allowed values. */
5080
+ values: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
5081
+ /** For type="ref": which level's nodes may be referenced. */
5082
+ refLevel: z.ZodOptional<z.ZodString>;
5083
+ /** If true, this axis may be absent from a node without failing validation.
5084
+ * Use for axes that apply conditionally (e.g. a department's "lead" ref
5085
+ * doesn't apply to a person-kind unit). Absent/false = required. */
5086
+ optional: z.ZodOptional<z.ZodBoolean>;
5087
+ /** Optional human-readable help, shown as tooltip in the admin UI. */
5088
+ description: z.ZodOptional<z.ZodString>;
5089
+ }, "strip", z.ZodTypeAny, {
5090
+ type: "enum" | "free" | "ref";
5091
+ name: string;
5092
+ values?: string[] | undefined;
5093
+ description?: string | undefined;
5094
+ refLevel?: string | undefined;
5095
+ optional?: boolean | undefined;
5096
+ }, {
5097
+ type: "enum" | "free" | "ref";
5098
+ name: string;
5099
+ values?: string[] | undefined;
5100
+ description?: string | undefined;
5101
+ refLevel?: string | undefined;
5102
+ optional?: boolean | undefined;
5103
+ }>;
5104
+ type AxisDef = z.infer<typeof axisDefSchema>;
5105
+ declare const levelDefSchema: z.ZodObject<{
5106
+ id: z.ZodString;
5107
+ /** Axes every node at this level MUST carry. Order matters for UI rendering. */
5108
+ axes: z.ZodArray<z.ZodObject<{
5109
+ name: z.ZodString;
5110
+ type: z.ZodEnum<["enum", "free", "ref"]>;
5111
+ /** For type="enum": closed set of allowed values. */
5112
+ values: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
5113
+ /** For type="ref": which level's nodes may be referenced. */
5114
+ refLevel: z.ZodOptional<z.ZodString>;
5115
+ /** If true, this axis may be absent from a node without failing validation.
5116
+ * Use for axes that apply conditionally (e.g. a department's "lead" ref
5117
+ * doesn't apply to a person-kind unit). Absent/false = required. */
5118
+ optional: z.ZodOptional<z.ZodBoolean>;
5119
+ /** Optional human-readable help, shown as tooltip in the admin UI. */
5120
+ description: z.ZodOptional<z.ZodString>;
5121
+ }, "strip", z.ZodTypeAny, {
5122
+ type: "enum" | "free" | "ref";
5123
+ name: string;
5124
+ values?: string[] | undefined;
5125
+ description?: string | undefined;
5126
+ refLevel?: string | undefined;
5127
+ optional?: boolean | undefined;
5128
+ }, {
5129
+ type: "enum" | "free" | "ref";
5130
+ name: string;
5131
+ values?: string[] | undefined;
5132
+ description?: string | undefined;
5133
+ refLevel?: string | undefined;
5134
+ optional?: boolean | undefined;
5135
+ }>, "many">;
5136
+ description: z.ZodOptional<z.ZodString>;
5137
+ }, "strip", z.ZodTypeAny, {
5138
+ id: string;
5139
+ axes: {
5140
+ type: "enum" | "free" | "ref";
5141
+ name: string;
5142
+ values?: string[] | undefined;
5143
+ description?: string | undefined;
5144
+ refLevel?: string | undefined;
5145
+ optional?: boolean | undefined;
5146
+ }[];
5147
+ description?: string | undefined;
5148
+ }, {
5149
+ id: string;
5150
+ axes: {
5151
+ type: "enum" | "free" | "ref";
5152
+ name: string;
5153
+ values?: string[] | undefined;
5154
+ description?: string | undefined;
5155
+ refLevel?: string | undefined;
5156
+ optional?: boolean | undefined;
5157
+ }[];
5158
+ description?: string | undefined;
5159
+ }>;
5160
+ type LevelDef = z.infer<typeof levelDefSchema>;
5161
+ declare const graphSchemaSchema: z.ZodObject<{
5162
+ version: z.ZodDefault<z.ZodNumber>;
5163
+ /** Ordered from root to leaf. Max 5 to keep the taxonomy scannable. */
5164
+ levels: z.ZodArray<z.ZodObject<{
5165
+ id: z.ZodString;
5166
+ /** Axes every node at this level MUST carry. Order matters for UI rendering. */
5167
+ axes: z.ZodArray<z.ZodObject<{
5168
+ name: z.ZodString;
5169
+ type: z.ZodEnum<["enum", "free", "ref"]>;
5170
+ /** For type="enum": closed set of allowed values. */
5171
+ values: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
5172
+ /** For type="ref": which level's nodes may be referenced. */
5173
+ refLevel: z.ZodOptional<z.ZodString>;
5174
+ /** If true, this axis may be absent from a node without failing validation.
5175
+ * Use for axes that apply conditionally (e.g. a department's "lead" ref
5176
+ * doesn't apply to a person-kind unit). Absent/false = required. */
5177
+ optional: z.ZodOptional<z.ZodBoolean>;
5178
+ /** Optional human-readable help, shown as tooltip in the admin UI. */
5179
+ description: z.ZodOptional<z.ZodString>;
5180
+ }, "strip", z.ZodTypeAny, {
5181
+ type: "enum" | "free" | "ref";
5182
+ name: string;
5183
+ values?: string[] | undefined;
5184
+ description?: string | undefined;
5185
+ refLevel?: string | undefined;
5186
+ optional?: boolean | undefined;
5187
+ }, {
5188
+ type: "enum" | "free" | "ref";
5189
+ name: string;
5190
+ values?: string[] | undefined;
5191
+ description?: string | undefined;
5192
+ refLevel?: string | undefined;
5193
+ optional?: boolean | undefined;
5194
+ }>, "many">;
5195
+ description: z.ZodOptional<z.ZodString>;
5196
+ }, "strip", z.ZodTypeAny, {
5197
+ id: string;
5198
+ axes: {
5199
+ type: "enum" | "free" | "ref";
5200
+ name: string;
5201
+ values?: string[] | undefined;
5202
+ description?: string | undefined;
5203
+ refLevel?: string | undefined;
5204
+ optional?: boolean | undefined;
5205
+ }[];
5206
+ description?: string | undefined;
5207
+ }, {
5208
+ id: string;
5209
+ axes: {
5210
+ type: "enum" | "free" | "ref";
5211
+ name: string;
5212
+ values?: string[] | undefined;
5213
+ description?: string | undefined;
5214
+ refLevel?: string | undefined;
5215
+ optional?: boolean | undefined;
5216
+ }[];
5217
+ description?: string | undefined;
5218
+ }>, "many">;
5219
+ /** Axis describing where a leaf classification came from (channel, cron, etc.). */
5220
+ leafInput: z.ZodOptional<z.ZodObject<{
5221
+ name: z.ZodString;
5222
+ type: z.ZodEnum<["enum", "free", "ref"]>;
5223
+ /** For type="enum": closed set of allowed values. */
5224
+ values: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
5225
+ /** For type="ref": which level's nodes may be referenced. */
5226
+ refLevel: z.ZodOptional<z.ZodString>;
5227
+ /** If true, this axis may be absent from a node without failing validation.
5228
+ * Use for axes that apply conditionally (e.g. a department's "lead" ref
5229
+ * doesn't apply to a person-kind unit). Absent/false = required. */
5230
+ optional: z.ZodOptional<z.ZodBoolean>;
5231
+ /** Optional human-readable help, shown as tooltip in the admin UI. */
5232
+ description: z.ZodOptional<z.ZodString>;
5233
+ }, "strip", z.ZodTypeAny, {
5234
+ type: "enum" | "free" | "ref";
5235
+ name: string;
5236
+ values?: string[] | undefined;
5237
+ description?: string | undefined;
5238
+ refLevel?: string | undefined;
5239
+ optional?: boolean | undefined;
5240
+ }, {
5241
+ type: "enum" | "free" | "ref";
5242
+ name: string;
5243
+ values?: string[] | undefined;
5244
+ description?: string | undefined;
5245
+ refLevel?: string | undefined;
5246
+ optional?: boolean | undefined;
5247
+ }>>;
5248
+ /** Free-form description of the expected result of a leaf classification. */
5249
+ leafOutput: z.ZodOptional<z.ZodObject<{
5250
+ name: z.ZodString;
5251
+ type: z.ZodEnum<["enum", "free", "ref"]>;
5252
+ /** For type="enum": closed set of allowed values. */
5253
+ values: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
5254
+ /** For type="ref": which level's nodes may be referenced. */
5255
+ refLevel: z.ZodOptional<z.ZodString>;
5256
+ /** If true, this axis may be absent from a node without failing validation.
5257
+ * Use for axes that apply conditionally (e.g. a department's "lead" ref
5258
+ * doesn't apply to a person-kind unit). Absent/false = required. */
5259
+ optional: z.ZodOptional<z.ZodBoolean>;
5260
+ /** Optional human-readable help, shown as tooltip in the admin UI. */
5261
+ description: z.ZodOptional<z.ZodString>;
5262
+ }, "strip", z.ZodTypeAny, {
5263
+ type: "enum" | "free" | "ref";
5264
+ name: string;
5265
+ values?: string[] | undefined;
5266
+ description?: string | undefined;
5267
+ refLevel?: string | undefined;
5268
+ optional?: boolean | undefined;
5269
+ }, {
5270
+ type: "enum" | "free" | "ref";
5271
+ name: string;
5272
+ values?: string[] | undefined;
5273
+ description?: string | undefined;
5274
+ refLevel?: string | undefined;
5275
+ optional?: boolean | undefined;
5276
+ }>>;
5277
+ }, "strip", z.ZodTypeAny, {
5278
+ version: number;
5279
+ levels: {
5280
+ id: string;
5281
+ axes: {
5282
+ type: "enum" | "free" | "ref";
5283
+ name: string;
5284
+ values?: string[] | undefined;
5285
+ description?: string | undefined;
5286
+ refLevel?: string | undefined;
5287
+ optional?: boolean | undefined;
5288
+ }[];
5289
+ description?: string | undefined;
5290
+ }[];
5291
+ leafInput?: {
5292
+ type: "enum" | "free" | "ref";
5293
+ name: string;
5294
+ values?: string[] | undefined;
5295
+ description?: string | undefined;
5296
+ refLevel?: string | undefined;
5297
+ optional?: boolean | undefined;
5298
+ } | undefined;
5299
+ leafOutput?: {
5300
+ type: "enum" | "free" | "ref";
5301
+ name: string;
5302
+ values?: string[] | undefined;
5303
+ description?: string | undefined;
5304
+ refLevel?: string | undefined;
5305
+ optional?: boolean | undefined;
5306
+ } | undefined;
5307
+ }, {
5308
+ levels: {
5309
+ id: string;
5310
+ axes: {
5311
+ type: "enum" | "free" | "ref";
5312
+ name: string;
5313
+ values?: string[] | undefined;
5314
+ description?: string | undefined;
5315
+ refLevel?: string | undefined;
5316
+ optional?: boolean | undefined;
5317
+ }[];
5318
+ description?: string | undefined;
5319
+ }[];
5320
+ version?: number | undefined;
5321
+ leafInput?: {
5322
+ type: "enum" | "free" | "ref";
5323
+ name: string;
5324
+ values?: string[] | undefined;
5325
+ description?: string | undefined;
5326
+ refLevel?: string | undefined;
5327
+ optional?: boolean | undefined;
5328
+ } | undefined;
5329
+ leafOutput?: {
5330
+ type: "enum" | "free" | "ref";
5331
+ name: string;
5332
+ values?: string[] | undefined;
5333
+ description?: string | undefined;
5334
+ refLevel?: string | undefined;
5335
+ optional?: boolean | undefined;
5336
+ } | undefined;
5337
+ }>;
5338
+ type GraphSchema = z.infer<typeof graphSchemaSchema>;
5339
+ declare const graphNodeSchema: z.ZodObject<{
5340
+ id: z.ZodString;
5341
+ /** Matches a `levels[*].id` from the schema. */
5342
+ level: z.ZodString;
5343
+ /** null for root-level nodes (level[0]); otherwise the id of a node at level-1. */
5344
+ parentId: z.ZodNullable<z.ZodString>;
5345
+ /** Values for every axis declared at this level's schema entry. `ref` axes
5346
+ * hold the id of another node; `enum` axes hold one of the declared values;
5347
+ * `free` axes hold any string. */
5348
+ axes: z.ZodRecord<z.ZodString, z.ZodString>;
5349
+ createdAt: z.ZodString;
5350
+ createdBy: z.ZodOptional<z.ZodString>;
5351
+ }, "strip", z.ZodTypeAny, {
5352
+ id: string;
5353
+ createdAt: string;
5354
+ axes: Record<string, string>;
5355
+ level: string;
5356
+ parentId: string | null;
5357
+ createdBy?: string | undefined;
5358
+ }, {
5359
+ id: string;
5360
+ createdAt: string;
5361
+ axes: Record<string, string>;
5362
+ level: string;
5363
+ parentId: string | null;
5364
+ createdBy?: string | undefined;
5365
+ }>;
5366
+ type GraphNode = z.infer<typeof graphNodeSchema>;
5367
+ declare const classificationSourceSchema: z.ZodEnum<["llm", "user", "cache"]>;
5368
+ type ClassificationSource = z.infer<typeof classificationSourceSchema>;
5369
+ declare const classificationStatusSchema: z.ZodEnum<["pending", "approved", "rejected"]>;
5370
+ type ClassificationStatus = z.infer<typeof classificationStatusSchema>;
5371
+ declare const classificationSchema: z.ZodObject<{
5372
+ ts: z.ZodString;
5373
+ msgHash: z.ZodString;
5374
+ agentId: z.ZodOptional<z.ZodString>;
5375
+ channel: z.ZodOptional<z.ZodString>;
5376
+ sender: z.ZodOptional<z.ZodString>;
5377
+ /** Node ids from root to leaf, one per level. Shorter-than-full paths are
5378
+ * allowed if the classifier was only confident down to a certain depth. */
5379
+ path: z.ZodArray<z.ZodString, "many">;
5380
+ /** Axis values asserted by the classifier for new nodes it proposed along
5381
+ * the path. Keyed by node id. */
5382
+ proposedAxes: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodString>>>;
5383
+ /** Leaf-level extras. */
5384
+ leaf: z.ZodDefault<z.ZodObject<{
5385
+ input: z.ZodOptional<z.ZodOptional<z.ZodString>>;
5386
+ output: z.ZodOptional<z.ZodOptional<z.ZodString>>;
5387
+ }, "strip", z.ZodTypeAny, {
5388
+ output?: string | undefined;
5389
+ input?: string | undefined;
5390
+ }, {
5391
+ output?: string | undefined;
5392
+ input?: string | undefined;
5393
+ }>>;
5394
+ source: z.ZodEnum<["llm", "user", "cache"]>;
5395
+ status: z.ZodEnum<["pending", "approved", "rejected"]>;
5396
+ confidence: z.ZodOptional<z.ZodNumber>;
5397
+ /** Redacted first ~200 chars of the message, for the approval UI. */
5398
+ preview: z.ZodOptional<z.ZodString>;
5399
+ }, "strip", z.ZodTypeAny, {
5400
+ path: string[];
5401
+ status: "pending" | "approved" | "rejected";
5402
+ source: "user" | "llm" | "cache";
5403
+ ts: string;
5404
+ msgHash: string;
5405
+ proposedAxes: Record<string, Record<string, string>>;
5406
+ leaf: {
5407
+ output?: string | undefined;
5408
+ input?: string | undefined;
5409
+ };
5410
+ channel?: string | undefined;
5411
+ agentId?: string | undefined;
5412
+ sender?: string | undefined;
5413
+ confidence?: number | undefined;
5414
+ preview?: string | undefined;
5415
+ }, {
5416
+ path: string[];
5417
+ status: "pending" | "approved" | "rejected";
5418
+ source: "user" | "llm" | "cache";
5419
+ ts: string;
5420
+ msgHash: string;
5421
+ channel?: string | undefined;
5422
+ agentId?: string | undefined;
5423
+ sender?: string | undefined;
5424
+ proposedAxes?: Record<string, Record<string, string>> | undefined;
5425
+ leaf?: {
5426
+ output?: string | undefined;
5427
+ input?: string | undefined;
5428
+ } | undefined;
5429
+ confidence?: number | undefined;
5430
+ preview?: string | undefined;
5431
+ }>;
5432
+ type Classification = z.infer<typeof classificationSchema>;
5433
+ /** Row in the fingerprint → path snap cache. */
5434
+ declare const fingerprintEntrySchema: z.ZodObject<{
5435
+ fingerprint: z.ZodString;
5436
+ path: z.ZodArray<z.ZodString, "many">;
5437
+ leaf: z.ZodDefault<z.ZodObject<{
5438
+ input: z.ZodOptional<z.ZodOptional<z.ZodString>>;
5439
+ output: z.ZodOptional<z.ZodOptional<z.ZodString>>;
5440
+ }, "strip", z.ZodTypeAny, {
5441
+ output?: string | undefined;
5442
+ input?: string | undefined;
5443
+ }, {
5444
+ output?: string | undefined;
5445
+ input?: string | undefined;
5446
+ }>>;
5447
+ updatedAt: z.ZodString;
5448
+ }, "strip", z.ZodTypeAny, {
5449
+ path: string[];
5450
+ leaf: {
5451
+ output?: string | undefined;
5452
+ input?: string | undefined;
5453
+ };
5454
+ fingerprint: string;
5455
+ updatedAt: string;
5456
+ }, {
5457
+ path: string[];
5458
+ fingerprint: string;
5459
+ updatedAt: string;
5460
+ leaf?: {
5461
+ output?: string | undefined;
5462
+ input?: string | undefined;
5463
+ } | undefined;
5464
+ }>;
5465
+ type FingerprintEntry = z.infer<typeof fingerprintEntrySchema>;
5466
+ /** Nodes file is a plain list, not a nested tree — lookups are by id. */
5467
+ declare const nodesFileSchema: z.ZodObject<{
5468
+ version: z.ZodDefault<z.ZodNumber>;
5469
+ nodes: z.ZodDefault<z.ZodArray<z.ZodObject<{
5470
+ id: z.ZodString;
5471
+ /** Matches a `levels[*].id` from the schema. */
5472
+ level: z.ZodString;
5473
+ /** null for root-level nodes (level[0]); otherwise the id of a node at level-1. */
5474
+ parentId: z.ZodNullable<z.ZodString>;
5475
+ /** Values for every axis declared at this level's schema entry. `ref` axes
5476
+ * hold the id of another node; `enum` axes hold one of the declared values;
5477
+ * `free` axes hold any string. */
5478
+ axes: z.ZodRecord<z.ZodString, z.ZodString>;
5479
+ createdAt: z.ZodString;
5480
+ createdBy: z.ZodOptional<z.ZodString>;
5481
+ }, "strip", z.ZodTypeAny, {
5482
+ id: string;
5483
+ createdAt: string;
5484
+ axes: Record<string, string>;
5485
+ level: string;
5486
+ parentId: string | null;
5487
+ createdBy?: string | undefined;
5488
+ }, {
5489
+ id: string;
5490
+ createdAt: string;
5491
+ axes: Record<string, string>;
5492
+ level: string;
5493
+ parentId: string | null;
5494
+ createdBy?: string | undefined;
5495
+ }>, "many">>;
5496
+ }, "strip", z.ZodTypeAny, {
5497
+ version: number;
5498
+ nodes: {
5499
+ id: string;
5500
+ createdAt: string;
5501
+ axes: Record<string, string>;
5502
+ level: string;
5503
+ parentId: string | null;
5504
+ createdBy?: string | undefined;
5505
+ }[];
5506
+ }, {
5507
+ version?: number | undefined;
5508
+ nodes?: {
5509
+ id: string;
5510
+ createdAt: string;
5511
+ axes: Record<string, string>;
5512
+ level: string;
5513
+ parentId: string | null;
5514
+ createdBy?: string | undefined;
5515
+ }[] | undefined;
5516
+ }>;
5517
+ type NodesFile = z.infer<typeof nodesFileSchema>;
5518
+ /** Index file — record of fingerprints. Hot path; kept as a map on disk. */
5519
+ declare const indexFileSchema: z.ZodObject<{
5520
+ version: z.ZodDefault<z.ZodNumber>;
5521
+ entries: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
5522
+ fingerprint: z.ZodString;
5523
+ path: z.ZodArray<z.ZodString, "many">;
5524
+ leaf: z.ZodDefault<z.ZodObject<{
5525
+ input: z.ZodOptional<z.ZodOptional<z.ZodString>>;
5526
+ output: z.ZodOptional<z.ZodOptional<z.ZodString>>;
5527
+ }, "strip", z.ZodTypeAny, {
5528
+ output?: string | undefined;
5529
+ input?: string | undefined;
5530
+ }, {
5531
+ output?: string | undefined;
5532
+ input?: string | undefined;
5533
+ }>>;
5534
+ updatedAt: z.ZodString;
5535
+ }, "strip", z.ZodTypeAny, {
5536
+ path: string[];
5537
+ leaf: {
5538
+ output?: string | undefined;
5539
+ input?: string | undefined;
5540
+ };
5541
+ fingerprint: string;
5542
+ updatedAt: string;
5543
+ }, {
5544
+ path: string[];
5545
+ fingerprint: string;
5546
+ updatedAt: string;
5547
+ leaf?: {
5548
+ output?: string | undefined;
5549
+ input?: string | undefined;
5550
+ } | undefined;
5551
+ }>>>;
5552
+ }, "strip", z.ZodTypeAny, {
5553
+ entries: Record<string, {
5554
+ path: string[];
5555
+ leaf: {
5556
+ output?: string | undefined;
5557
+ input?: string | undefined;
5558
+ };
5559
+ fingerprint: string;
5560
+ updatedAt: string;
5561
+ }>;
5562
+ version: number;
5563
+ }, {
5564
+ entries?: Record<string, {
5565
+ path: string[];
5566
+ fingerprint: string;
5567
+ updatedAt: string;
5568
+ leaf?: {
5569
+ output?: string | undefined;
5570
+ input?: string | undefined;
5571
+ } | undefined;
5572
+ }> | undefined;
5573
+ version?: number | undefined;
5574
+ }>;
5575
+ type IndexFile = z.infer<typeof indexFileSchema>;
5576
+
5577
+ /**
5578
+ * Ships with the install. When .agentx/graph/schema.json is missing, the
5579
+ * store seeds this so a fresh daemon has something to classify against.
5580
+ *
5581
+ * Five levels, three primaries at the leaf (who / what / where) — matches
5582
+ * the "primary colors per level" design from the plan.
5583
+ */
5584
+ declare const STARTER_SCHEMA: GraphSchema;
5585
+
5586
+ interface GraphStoreOptions {
5587
+ baseDir?: string;
5588
+ log?: (...args: unknown[]) => void;
5589
+ }
5590
+ declare class GraphStore {
5591
+ readonly baseDir: string;
5592
+ private log;
5593
+ constructor(opts?: GraphStoreOptions);
5594
+ schemaPath(): string;
5595
+ nodesPath(): string;
5596
+ indexPath(): string;
5597
+ classificationsPath(): string;
5598
+ /** Load the graph schema, seeding STARTER_SCHEMA if the file is missing. */
5599
+ loadSchema(): GraphSchema;
5600
+ saveSchema(schema: GraphSchema): void;
5601
+ loadNodes(): NodesFile;
5602
+ saveNodes(file: NodesFile): void;
5603
+ /** Validate a node against the schema AND uniqueness within the nodes file. */
5604
+ validateNode(node: GraphNode, schema: GraphSchema, all: GraphNode[]): void;
5605
+ /**
5606
+ * Commit a full classification path: for each path element that doesn't
5607
+ * yet exist, infer its schema level by matching the proposed axes against
5608
+ * the level's required axes (first match ≥ cursor wins — this handles
5609
+ * paths that skip levels, like business → noqta where location is
5610
+ * absent). Refreshes the node list between adds so callers in a loop
5611
+ * don't hit "Node id already exists" on the second iteration.
5612
+ */
5613
+ commitNodesAlongPath(path: string[], proposedAxes: Record<string, Record<string, string>>, schema: GraphSchema, createdBy?: string): {
5614
+ added: GraphNode[];
5615
+ skipped: string[];
5616
+ };
5617
+ /** Append a node. Caller is responsible for id uniqueness; we check and throw. */
5618
+ addNode(node: GraphNode): GraphNode;
5619
+ appendClassification(c: Classification): boolean;
5620
+ /**
5621
+ * All pending classifications, newest first. Collapses the append-only
5622
+ * ledger by msgHash — the most recent entry per message wins (so if an
5623
+ * entry was updated via updateClassificationStatus, we see the current
5624
+ * state, not the original).
5625
+ */
5626
+ listPendingClassifications(limit?: number): Classification[];
5627
+ /** Same contract as listPendingClassifications but filtered to any status. */
5628
+ listByStatus(status: Classification["status"], limit?: number): Classification[];
5629
+ /**
5630
+ * Read every classification, collapse by msgHash keeping the newest entry
5631
+ * per message. Used by listByStatus + the review loop to see current state.
5632
+ * Returns newest-first order.
5633
+ */
5634
+ private readAllCollapsed;
5635
+ /**
5636
+ * Append a status-update entry for an existing classification. The ledger
5637
+ * stays append-only; readers collapse by msgHash. Returns the updated
5638
+ * classification, or null if no prior entry for msgHash exists.
5639
+ */
5640
+ updateClassificationStatus(msgHash: string, update: {
5641
+ status: Classification["status"];
5642
+ reviewer?: string;
5643
+ reviewReason?: string;
5644
+ }): Classification | null;
5645
+ /** Read the last N classifications, newest first. Cheap enough for the admin UI. */
5646
+ readRecentClassifications(limit?: number): Classification[];
5647
+ /**
5648
+ * Hash that represents "this kind of message" for snap-to-path caching.
5649
+ * Normalizes casing + whitespace; includes channel + sender so two people
5650
+ * writing the same words can still land on different paths if they should.
5651
+ */
5652
+ fingerprint(msg: {
5653
+ text: string;
5654
+ channel?: string;
5655
+ sender?: string;
5656
+ }): string;
5657
+ loadIndex(): IndexFile;
5658
+ saveIndex(file: IndexFile): void;
5659
+ getFingerprint(fp: string): FingerprintEntry | undefined;
5660
+ setFingerprint(fp: string, entry: Omit<FingerprintEntry, "fingerprint" | "updatedAt">): void;
5661
+ /** Update the axes on an existing node. Schema-validates the result. */
5662
+ updateNodeAxes(id: string, axes: Record<string, string>): GraphNode;
5663
+ /** Remove a node. Refuses to delete if any other node still references it
5664
+ * (child via parentId, or axis ref). */
5665
+ deleteNode(id: string): void;
5666
+ /** Approve a pending classification. Commits any new nodes along its path,
5667
+ * stamps the fingerprint index so future similar messages hit the cache,
5668
+ * and appends an audit entry. Idempotent — no-op if already cached. */
5669
+ approveClassification(c: Classification): void;
5670
+ /** Record rejection — no nodes committed, no fingerprint set. */
5671
+ rejectClassification(c: Classification): void;
5672
+ }
5673
+
4620
5674
  interface ProviderCapabilities {
4621
5675
  streaming: boolean;
4622
5676
  tools: boolean;
@@ -4666,6 +5720,17 @@ declare const logger: {
4666
5720
 
4667
5721
  declare function handleError(error: unknown): void;
4668
5722
 
5723
+ /**
5724
+ * Read the agentx-cli package.json so commands like --version work.
5725
+ *
5726
+ * Looks in three places, in order:
5727
+ * 1. A package.json beside the compiled entry (dist/cli.js → ../package.json),
5728
+ * which is how npm-installed usage finds it.
5729
+ * 2. A package.json in the CWD, which is what `pnpm dev` / `tsx src/cli.ts`
5730
+ * implicitly relies on.
5731
+ * 3. A safe fallback so the CLI never crashes on a truly bare environment
5732
+ * (e.g. a fresh user running `agentx setup` from an empty temp dir).
5733
+ */
4669
5734
  declare function getPackageInfo(): PackageJson;
4670
5735
 
4671
- export { A2AClient, A2AMesh, A2AServer, A2AServerConfig, ALL_TOOL_NAMES, AgentCard, AgentConfig, AgentContext, AgentDef, AgentProvider, AgentRegistry, AgentResponse, AgentTask, AgentXDaemon, AgentXRuntime, AnthropicMessage, AuthConfig, BLOCKING_EVENTS, ChannelAdapter, ClaudeCodeProvider, ClaudeProvider, ContentBlock, ContextBuilder, CronJobDef, CronJobState, CronRunResult, CronScheduler, DaemonConfig, EnhanceConfig, EnhanceEngine, EnhanceResult, GenerateOptions, GenerateResult, GenerateStreamEvent, GeneratedFile, GenerationMessage, GenerationResult, GitCommitResult, GitDiffFile, GitLogEntry, GitManager, GitStatus, HOOK_EVENTS, HealConfig, HealEngine, HealResult, HookContext, HookDefinition, HookEvent, HookHandler, HookRegistry, HookResult, IncomingMessage, Memory, MemoryEntry, MemoryHierarchy, MemoryStore, MeshPeer, MessageRouter, MiddlewareFn, ModelUsage, OUTPUT_CONFIGS, OUTPUT_TYPES, OutgoingMessage, OutputConfig, OutputType, PERMISSION_MODES, PROVIDER_CAPABILITIES, PermissionAction, PermissionConfig, PermissionManager, PermissionMode, PermissionRule, Pipeline, PipelineRequest, PipelineResponse, ProjectSchemas, ProviderCapabilities, ProviderName, ProviderOptions, RawGenerationResult, ReplEngine, ReplOptions, RuntimeConfig, Session, StepUsage, StreamEvent, Task, TaskArtifact, TaskMessage, TaskState, TaskStatusUpdate, TechStack, TelegramAdapter, ToolCallInput, ToolExecutor, ToolExecutorOptions, ToolResult, UsageSummary, UsageTracker, WhatsAppAdapter, WikiAccess, WikiArticle, WikiArticleMeta, WikiEntry, WikiIndex, WikiStore, agentConfigSchema$1 as agentConfigSchema, checkCapabilities, createAgentContext, createProvider, createSession, daemonConfigSchema, debug, detectSchemas, detectTechStack, ensureCredentials, executeClaudeCode, executeOrchestrator, executeSdk, executeTask, exportSession, formatSchemas, formatTechStack, formatToolsForSystemPrompt, gatherContext7Docs, generate, generateSkill, generateSkillMd, generateStream, getAnthropicTools, getCommand, getLegacyTools, getPackageInfo, globalHooks, globalPermissions, globalTracker, handleError, installSkillPackage, isCommand, isDebug, listInstalledSkills, listSessions, loadAuthConfig, loadDaemonConfig, loadHooks, loadLatestSession, loadLocalSkills, loadProjectInstructions, loadSession, logger, matchSkillsToTask, outputTypeDescriptions, parseCommand, parseSkillContent, parseSkillFile, permissionConfigSchema, permissionModeSchema, registerCommand, resolveAtImports, resolveOutputType, resolveToken, runModelSetup, saveAuthConfig, saveSession, setDebug, startMcpServer, validateWorkspaces };
5736
+ export { A2AClient, A2AMesh, A2AServer, A2AServerConfig, ALL_TOOL_NAMES, AgentCard, AgentConfig, AgentContext, AgentDef, AgentProvider, AgentRegistry, AgentResponse, AgentTask, AgentXDaemon, AgentXRuntime, AnthropicMessage, AuthConfig, AxisDef, AxisType, BLOCKING_EVENTS, ChannelAdapter, Classification, ClassificationSource, ClassificationStatus, ClaudeCodeProvider, ClaudeProvider, ContentBlock, ContextBuilder, CronJobDef, CronJobState, CronRunResult, CronScheduler, DaemonConfig, EnhanceConfig, EnhanceEngine, EnhanceResult, FingerprintEntry, GenerateOptions, GenerateResult, GenerateStreamEvent, GeneratedFile, GenerationMessage, GenerationResult, GitCommitResult, GitDiffFile, GitLogEntry, GitManager, GitStatus, GraphNode, GraphSchema, GraphStore, GraphStoreOptions, HOOK_EVENTS, HealConfig, HealEngine, HealResult, HookContext, HookDefinition, HookEvent, HookHandler, HookRegistry, HookResult, IncomingMessage, IndexFile, LevelDef, Memory, MemoryEntry, MemoryHierarchy, MemoryStore, MeshPeer, MessageRouter, MiddlewareFn, ModelUsage, NodesFile, OUTPUT_CONFIGS, OUTPUT_TYPES, OutgoingMessage, OutputConfig, OutputType, PERMISSION_MODES, PROVIDER_CAPABILITIES, PermissionAction, PermissionConfig, PermissionManager, PermissionMode, PermissionRule, Pipeline, PipelineRequest, PipelineResponse, ProjectSchemas, ProviderCapabilities, ProviderName, ProviderOptions, RawGenerationResult, ReplEngine, ReplOptions, RuntimeConfig, STARTER_SCHEMA, Session, StepUsage, StreamEvent, Task, TaskArtifact, TaskMessage, TaskState, TaskStatusUpdate, TechStack, TelegramAdapter, ToolCallInput, ToolExecutor, ToolExecutorOptions, ToolResult, UsageSummary, UsageTracker, WhatsAppAdapter, WikiAccess, WikiArticle, WikiArticleMeta, WikiEntry, WikiIndex, WikiStore, agentConfigSchema$1 as agentConfigSchema, checkCapabilities, createAgentContext, createProvider, createSession, daemonConfigSchema, debug, detectSchemas, detectTechStack, ensureCredentials, executeClaudeCode, executeOrchestrator, executeSdk, executeTask, exportSession, formatSchemas, formatTechStack, formatToolsForSystemPrompt, gatherContext7Docs, generate, generateSkill, generateSkillMd, generateStream, getAnthropicTools, getCommand, getLegacyTools, getPackageInfo, globalHooks, globalPermissions, globalTracker, handleError, installSkillPackage, isCommand, isDebug, listInstalledSkills, listSessions, loadAuthConfig, loadDaemonConfig, loadHooks, loadLatestSession, loadLocalSkills, loadProjectInstructions, loadSession, logger, matchSkillsToTask, outputTypeDescriptions, parseCommand, parseSkillContent, parseSkillFile, permissionConfigSchema, permissionModeSchema, registerCommand, resolveAtImports, resolveOutputType, resolveToken, runModelSetup, saveAuthConfig, saveSession, setDebug, startMcpServer, validateWorkspaces };