agentix-cli 0.9.0 → 0.14.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 (71) hide show
  1. package/README.md +50 -443
  2. package/dist/agent-DW3NYIIL.js +2 -0
  3. package/dist/board-dashboard-6TKE6NMV.js +1435 -0
  4. package/dist/board-dashboard-6TKE6NMV.js.map +1 -0
  5. package/dist/chunk-6U2XOQHU.js +7 -0
  6. package/dist/chunk-6U2XOQHU.js.map +1 -0
  7. package/dist/chunk-DYOBFJLX.js +11 -0
  8. package/dist/chunk-DYOBFJLX.js.map +1 -0
  9. package/dist/chunk-HI24KAEY.js +54 -0
  10. package/dist/chunk-HI24KAEY.js.map +1 -0
  11. package/dist/chunk-ITZEVXZ4.js +2 -0
  12. package/dist/chunk-ITZEVXZ4.js.map +1 -0
  13. package/dist/chunk-M33CB2H4.js +6 -0
  14. package/dist/chunk-M33CB2H4.js.map +1 -0
  15. package/dist/chunk-MCJUAE6V.js +6 -0
  16. package/dist/chunk-MCJUAE6V.js.map +1 -0
  17. package/dist/chunk-NJR5WF5E.js +5 -0
  18. package/dist/chunk-NJR5WF5E.js.map +1 -0
  19. package/dist/chunk-O72LPMBR.js +12 -0
  20. package/dist/chunk-O72LPMBR.js.map +1 -0
  21. package/dist/chunk-QOYAX2FT.js +2 -0
  22. package/dist/chunk-QOYAX2FT.js.map +1 -0
  23. package/dist/chunk-QZP65I2H.js +45 -0
  24. package/dist/chunk-QZP65I2H.js.map +1 -0
  25. package/dist/chunk-RB73FZXJ.js +133 -0
  26. package/dist/chunk-RB73FZXJ.js.map +1 -0
  27. package/dist/chunk-UPT2UMF6.js +159 -0
  28. package/dist/chunk-UPT2UMF6.js.map +1 -0
  29. package/dist/{chunk-SBUX74OU.js → chunk-XVYMZ4M7.js} +5 -5
  30. package/dist/cli.js +53 -50
  31. package/dist/cli.js.map +1 -1
  32. package/dist/compaction-7I3E5QUO.js +28 -0
  33. package/dist/compaction-7I3E5QUO.js.map +1 -0
  34. package/dist/config-7QJ2QJIC.js +2 -0
  35. package/dist/config-mutator-GAEVGHDD.js +2 -0
  36. package/dist/index.d.ts +1715 -106
  37. package/dist/index.js +39 -35
  38. package/dist/index.js.map +1 -1
  39. package/dist/loader-YQE6XJBT.js +2 -0
  40. package/dist/registry-YVAG4EO5.js +2 -0
  41. package/dist/registry-YVAG4EO5.js.map +1 -0
  42. package/dist/{usage-dashboard-2TJQBFSH.js → usage-dashboard-M7AFIGMJ.js} +2 -2
  43. package/dist/workspace-setup-QQTCJY4B.js +2 -0
  44. package/dist/workspace-setup-QQTCJY4B.js.map +1 -0
  45. package/package.json +9 -1
  46. package/dist/agent-QYQVGKLM.js +0 -2
  47. package/dist/chunk-34UAFPK4.js +0 -10
  48. package/dist/chunk-34UAFPK4.js.map +0 -1
  49. package/dist/chunk-BAIQJHQF.js +0 -64
  50. package/dist/chunk-BAIQJHQF.js.map +0 -1
  51. package/dist/chunk-BHDLKX3G.js +0 -6
  52. package/dist/chunk-BHDLKX3G.js.map +0 -1
  53. package/dist/chunk-CJ45Y2IR.js +0 -12
  54. package/dist/chunk-CJ45Y2IR.js.map +0 -1
  55. package/dist/chunk-FRFR27IN.js +0 -3
  56. package/dist/chunk-FRFR27IN.js.map +0 -1
  57. package/dist/chunk-IVVVYXPH.js +0 -136
  58. package/dist/chunk-IVVVYXPH.js.map +0 -1
  59. package/dist/chunk-X32247GM.js +0 -2
  60. package/dist/chunk-X32247GM.js.map +0 -1
  61. package/dist/compaction-E3MQRLTL.js +0 -28
  62. package/dist/compaction-E3MQRLTL.js.map +0 -1
  63. package/dist/config-MSWKC466.js +0 -2
  64. package/dist/loader-6VSM6FSY.js +0 -2
  65. package/dist/registry-FP6FUOXF.js +0 -2
  66. /package/dist/{agent-QYQVGKLM.js.map → agent-DW3NYIIL.js.map} +0 -0
  67. /package/dist/{chunk-SBUX74OU.js.map → chunk-XVYMZ4M7.js.map} +0 -0
  68. /package/dist/{config-MSWKC466.js.map → config-7QJ2QJIC.js.map} +0 -0
  69. /package/dist/{loader-6VSM6FSY.js.map → config-mutator-GAEVGHDD.js.map} +0 -0
  70. /package/dist/{registry-FP6FUOXF.js.map → loader-YQE6XJBT.js.map} +0 -0
  71. /package/dist/{usage-dashboard-2TJQBFSH.js.map → usage-dashboard-M7AFIGMJ.js.map} +0 -0
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ import { IncomingMessage as IncomingMessage$1, ServerResponse } from 'http';
2
3
  import { PackageJson } from 'type-fest';
3
4
 
4
5
  interface GenerationMessage {
@@ -410,6 +411,8 @@ declare const skillFrontmatterSchema: z.ZodObject<{
410
411
  pattern: string;
411
412
  description?: string | undefined;
412
413
  }>, "many">>;
414
+ /** If true, skill is auto-injected into context when triggers match (per-turn) */
415
+ autoInject: z.ZodOptional<z.ZodBoolean>;
413
416
  }, "strip", z.ZodTypeAny, {
414
417
  name: string;
415
418
  description: string;
@@ -421,6 +424,7 @@ declare const skillFrontmatterSchema: z.ZodObject<{
421
424
  pattern: string;
422
425
  description?: string | undefined;
423
426
  }[] | undefined;
427
+ autoInject?: boolean | undefined;
424
428
  }, {
425
429
  name: string;
426
430
  description: string;
@@ -432,6 +436,7 @@ declare const skillFrontmatterSchema: z.ZodObject<{
432
436
  pattern: string;
433
437
  description?: string | undefined;
434
438
  }[] | undefined;
439
+ autoInject?: boolean | undefined;
435
440
  }>;
436
441
  type SkillFrontmatter = z.infer<typeof skillFrontmatterSchema>;
437
442
  interface Skill {
@@ -908,7 +913,7 @@ declare class PermissionManager {
908
913
  }
909
914
  declare const globalPermissions: PermissionManager;
910
915
 
911
- declare const HOOK_EVENTS: readonly ["pre:generate", "post:generate", "pre:file-write", "post:file-write", "pre:prompt", "post:response", "pre:command", "on:error", "pre:tool-call", "post:tool-call", "pre:channel-message", "post:channel-message", "pre:a2a-task", "pre:cron-run", "post:cron-run"];
916
+ declare const HOOK_EVENTS: readonly ["pre:generate", "post:generate", "pre:file-write", "post:file-write", "pre:prompt", "post:response", "pre:command", "on:error", "pre:tool-call", "post:tool-call", "pre:channel-message", "post:channel-message", "pre:a2a-task", "pre:cron-run", "post:cron-run", "on:gitlab-pipeline", "on:gitlab-issue"];
912
917
  type HookEvent = (typeof HOOK_EVENTS)[number];
913
918
  declare const BLOCKING_EVENTS: HookEvent[];
914
919
  declare const hookDefinitionSchema: z.ZodObject<{
@@ -1284,6 +1289,10 @@ declare const agentConfigSchema: z.ZodObject<{
1284
1289
  systemPrompt: z.ZodOptional<z.ZodString>;
1285
1290
  mentions: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
1286
1291
  maxConcurrent: z.ZodDefault<z.ZodNumber>;
1292
+ /** Hard wall-clock cap on a single Claude Code invocation. Exceeding the
1293
+ * cap sends SIGTERM (exit 143). Default 20 min — bump for devops/coder
1294
+ * agents that do long investigations or multi-file refactors. */
1295
+ maxExecutionMinutes: z.ZodDefault<z.ZodNumber>;
1287
1296
  permissionMode: z.ZodDefault<z.ZodString>;
1288
1297
  queueMode: z.ZodDefault<z.ZodEnum<["collect", "followup", "drop"]>>;
1289
1298
  heartbeat: z.ZodDefault<z.ZodObject<{
@@ -1308,6 +1317,7 @@ declare const agentConfigSchema: z.ZodObject<{
1308
1317
  tier: "claude-code" | "sdk" | "orchestrator";
1309
1318
  mentions: string[];
1310
1319
  maxConcurrent: number;
1320
+ maxExecutionMinutes: number;
1311
1321
  permissionMode: string;
1312
1322
  queueMode: "collect" | "followup" | "drop";
1313
1323
  heartbeat: {
@@ -1328,6 +1338,7 @@ declare const agentConfigSchema: z.ZodObject<{
1328
1338
  systemPrompt?: string | undefined;
1329
1339
  mentions?: string[] | undefined;
1330
1340
  maxConcurrent?: number | undefined;
1341
+ maxExecutionMinutes?: number | undefined;
1331
1342
  permissionMode?: string | undefined;
1332
1343
  queueMode?: "collect" | "followup" | "drop" | undefined;
1333
1344
  heartbeat?: {
@@ -1345,7 +1356,11 @@ declare const cronJobSchema: z.ZodObject<{
1345
1356
  prompt: z.ZodString;
1346
1357
  timeout: z.ZodDefault<z.ZodNumber>;
1347
1358
  model: z.ZodOptional<z.ZodString>;
1348
- onError: z.ZodDefault<z.ZodEnum<["log", "notify", "disable"]>>;
1359
+ /** Soft cap on output length. Claude Code CLI has no hard flag for this,
1360
+ * but appending an instruction to the prompt is reliably honored. Use
1361
+ * 1500 for briefs, 500 for status pings, 300 for pure classifiers. */
1362
+ maxOutputTokens: z.ZodOptional<z.ZodNumber>;
1363
+ onError: z.ZodEffects<z.ZodDefault<z.ZodUnion<[z.ZodEnum<["log", "notify", "disable"]>, z.ZodArray<z.ZodEnum<["log", "notify", "disable"]>, "many">]>>, ("notify" | "log" | "disable")[], "notify" | "log" | "disable" | ("notify" | "log" | "disable")[] | undefined>;
1349
1364
  notify: z.ZodOptional<z.ZodObject<{
1350
1365
  channel: z.ZodString;
1351
1366
  chatId: z.ZodString;
@@ -1366,13 +1381,14 @@ declare const cronJobSchema: z.ZodObject<{
1366
1381
  timeout: number;
1367
1382
  schedule: string;
1368
1383
  timezone: string;
1369
- onError: "log" | "notify" | "disable";
1384
+ onError: ("notify" | "log" | "disable")[];
1370
1385
  model?: string | undefined;
1371
1386
  notify?: {
1372
1387
  channel: string;
1373
1388
  chatId: string;
1374
1389
  accountId?: string | undefined;
1375
1390
  } | undefined;
1391
+ maxOutputTokens?: number | undefined;
1376
1392
  }, {
1377
1393
  agent: string;
1378
1394
  prompt: string;
@@ -1386,7 +1402,8 @@ declare const cronJobSchema: z.ZodObject<{
1386
1402
  chatId: string;
1387
1403
  accountId?: string | undefined;
1388
1404
  } | undefined;
1389
- onError?: "log" | "notify" | "disable" | undefined;
1405
+ maxOutputTokens?: number | undefined;
1406
+ onError?: "notify" | "log" | "disable" | ("notify" | "log" | "disable")[] | undefined;
1390
1407
  }>;
1391
1408
  declare const meshPeerSchema: z.ZodObject<{
1392
1409
  url: z.ZodString;
@@ -1406,14 +1423,18 @@ declare const daemonConfigSchema: z.ZodObject<{
1406
1423
  id: z.ZodString;
1407
1424
  name: z.ZodString;
1408
1425
  bind: z.ZodDefault<z.ZodString>;
1426
+ /** Default agent for voice/API calls that don't specify one (e.g. Siri) */
1427
+ defaultAgent: z.ZodOptional<z.ZodString>;
1409
1428
  }, "strip", z.ZodTypeAny, {
1410
1429
  id: string;
1411
1430
  name: string;
1412
1431
  bind: string;
1432
+ defaultAgent?: string | undefined;
1413
1433
  }, {
1414
1434
  id: string;
1415
1435
  name: string;
1416
1436
  bind?: string | undefined;
1437
+ defaultAgent?: string | undefined;
1417
1438
  }>;
1418
1439
  providers: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1419
1440
  apiKey: z.ZodOptional<z.ZodString>;
@@ -1437,6 +1458,10 @@ declare const daemonConfigSchema: z.ZodObject<{
1437
1458
  systemPrompt: z.ZodOptional<z.ZodString>;
1438
1459
  mentions: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
1439
1460
  maxConcurrent: z.ZodDefault<z.ZodNumber>;
1461
+ /** Hard wall-clock cap on a single Claude Code invocation. Exceeding the
1462
+ * cap sends SIGTERM (exit 143). Default 20 min — bump for devops/coder
1463
+ * agents that do long investigations or multi-file refactors. */
1464
+ maxExecutionMinutes: z.ZodDefault<z.ZodNumber>;
1440
1465
  permissionMode: z.ZodDefault<z.ZodString>;
1441
1466
  queueMode: z.ZodDefault<z.ZodEnum<["collect", "followup", "drop"]>>;
1442
1467
  heartbeat: z.ZodDefault<z.ZodObject<{
@@ -1461,6 +1486,7 @@ declare const daemonConfigSchema: z.ZodObject<{
1461
1486
  tier: "claude-code" | "sdk" | "orchestrator";
1462
1487
  mentions: string[];
1463
1488
  maxConcurrent: number;
1489
+ maxExecutionMinutes: number;
1464
1490
  permissionMode: string;
1465
1491
  queueMode: "collect" | "followup" | "drop";
1466
1492
  heartbeat: {
@@ -1481,6 +1507,7 @@ declare const daemonConfigSchema: z.ZodObject<{
1481
1507
  systemPrompt?: string | undefined;
1482
1508
  mentions?: string[] | undefined;
1483
1509
  maxConcurrent?: number | undefined;
1510
+ maxExecutionMinutes?: number | undefined;
1484
1511
  permissionMode?: string | undefined;
1485
1512
  queueMode?: "collect" | "followup" | "drop" | undefined;
1486
1513
  heartbeat?: {
@@ -1607,16 +1634,23 @@ declare const daemonConfigSchema: z.ZodObject<{
1607
1634
  gitlabUsernames: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
1608
1635
  keywords: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
1609
1636
  token: z.ZodOptional<z.ZodString>;
1637
+ /** If set, the agent lives on a remote mesh peer (node id). Forces the
1638
+ * username→agent map to resolve to this mapping even when a local
1639
+ * agent's token resolves to the same GitLab user — prevents collisions
1640
+ * like two agents both claiming @devops-noqta. */
1641
+ node: z.ZodOptional<z.ZodString>;
1610
1642
  }, "strip", z.ZodTypeAny, {
1611
1643
  agentId: string;
1612
1644
  gitlabUsernames: string[];
1613
1645
  keywords: string[];
1614
1646
  token?: string | undefined;
1647
+ node?: string | undefined;
1615
1648
  }, {
1616
1649
  agentId: string;
1617
1650
  token?: string | undefined;
1618
1651
  gitlabUsernames?: string[] | undefined;
1619
1652
  keywords?: string[] | undefined;
1653
+ node?: string | undefined;
1620
1654
  }>, "many">>;
1621
1655
  }, "strip", z.ZodTypeAny, {
1622
1656
  enabled: boolean;
@@ -1631,6 +1665,7 @@ declare const daemonConfigSchema: z.ZodObject<{
1631
1665
  gitlabUsernames: string[];
1632
1666
  keywords: string[];
1633
1667
  token?: string | undefined;
1668
+ node?: string | undefined;
1634
1669
  }[];
1635
1670
  token?: string | undefined;
1636
1671
  webhookSecret?: string | undefined;
@@ -1649,9 +1684,28 @@ declare const daemonConfigSchema: z.ZodObject<{
1649
1684
  token?: string | undefined;
1650
1685
  gitlabUsernames?: string[] | undefined;
1651
1686
  keywords?: string[] | undefined;
1687
+ node?: string | undefined;
1652
1688
  }[] | undefined;
1653
1689
  }>>;
1654
1690
  }, "strip", z.ZodTypeAny, {
1691
+ gitlab: {
1692
+ enabled: boolean;
1693
+ routes: {
1694
+ agent: string;
1695
+ project: string;
1696
+ }[];
1697
+ webhookPort: number;
1698
+ host: string;
1699
+ agentMappings: {
1700
+ agentId: string;
1701
+ gitlabUsernames: string[];
1702
+ keywords: string[];
1703
+ token?: string | undefined;
1704
+ node?: string | undefined;
1705
+ }[];
1706
+ token?: string | undefined;
1707
+ webhookSecret?: string | undefined;
1708
+ };
1655
1709
  telegram: {
1656
1710
  enabled: boolean;
1657
1711
  accounts: Record<string, {
@@ -1679,24 +1733,25 @@ declare const daemonConfigSchema: z.ZodObject<{
1679
1733
  token?: string | undefined;
1680
1734
  agentBinding?: string | undefined;
1681
1735
  };
1682
- gitlab: {
1683
- enabled: boolean;
1684
- routes: {
1736
+ }, {
1737
+ gitlab?: {
1738
+ enabled?: boolean | undefined;
1739
+ token?: string | undefined;
1740
+ routes?: {
1685
1741
  agent: string;
1686
1742
  project: string;
1687
- }[];
1688
- webhookPort: number;
1689
- host: string;
1690
- agentMappings: {
1743
+ }[] | undefined;
1744
+ webhookPort?: number | undefined;
1745
+ webhookSecret?: string | undefined;
1746
+ host?: string | undefined;
1747
+ agentMappings?: {
1691
1748
  agentId: string;
1692
- gitlabUsernames: string[];
1693
- keywords: string[];
1694
1749
  token?: string | undefined;
1695
- }[];
1696
- token?: string | undefined;
1697
- webhookSecret?: string | undefined;
1698
- };
1699
- }, {
1750
+ gitlabUsernames?: string[] | undefined;
1751
+ keywords?: string[] | undefined;
1752
+ node?: string | undefined;
1753
+ }[] | undefined;
1754
+ } | undefined;
1700
1755
  telegram?: {
1701
1756
  enabled?: boolean | undefined;
1702
1757
  accounts?: Record<string, {
@@ -1724,23 +1779,6 @@ declare const daemonConfigSchema: z.ZodObject<{
1724
1779
  token?: string | undefined;
1725
1780
  agentBinding?: string | undefined;
1726
1781
  } | undefined;
1727
- gitlab?: {
1728
- enabled?: boolean | undefined;
1729
- token?: string | undefined;
1730
- routes?: {
1731
- agent: string;
1732
- project: string;
1733
- }[] | undefined;
1734
- webhookPort?: number | undefined;
1735
- webhookSecret?: string | undefined;
1736
- host?: string | undefined;
1737
- agentMappings?: {
1738
- agentId: string;
1739
- token?: string | undefined;
1740
- gitlabUsernames?: string[] | undefined;
1741
- keywords?: string[] | undefined;
1742
- }[] | undefined;
1743
- } | undefined;
1744
1782
  }>>;
1745
1783
  crons: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1746
1784
  enabled: z.ZodDefault<z.ZodBoolean>;
@@ -1750,7 +1788,11 @@ declare const daemonConfigSchema: z.ZodObject<{
1750
1788
  prompt: z.ZodString;
1751
1789
  timeout: z.ZodDefault<z.ZodNumber>;
1752
1790
  model: z.ZodOptional<z.ZodString>;
1753
- onError: z.ZodDefault<z.ZodEnum<["log", "notify", "disable"]>>;
1791
+ /** Soft cap on output length. Claude Code CLI has no hard flag for this,
1792
+ * but appending an instruction to the prompt is reliably honored. Use
1793
+ * 1500 for briefs, 500 for status pings, 300 for pure classifiers. */
1794
+ maxOutputTokens: z.ZodOptional<z.ZodNumber>;
1795
+ onError: z.ZodEffects<z.ZodDefault<z.ZodUnion<[z.ZodEnum<["log", "notify", "disable"]>, z.ZodArray<z.ZodEnum<["log", "notify", "disable"]>, "many">]>>, ("notify" | "log" | "disable")[], "notify" | "log" | "disable" | ("notify" | "log" | "disable")[] | undefined>;
1754
1796
  notify: z.ZodOptional<z.ZodObject<{
1755
1797
  channel: z.ZodString;
1756
1798
  chatId: z.ZodString;
@@ -1771,13 +1813,14 @@ declare const daemonConfigSchema: z.ZodObject<{
1771
1813
  timeout: number;
1772
1814
  schedule: string;
1773
1815
  timezone: string;
1774
- onError: "log" | "notify" | "disable";
1816
+ onError: ("notify" | "log" | "disable")[];
1775
1817
  model?: string | undefined;
1776
1818
  notify?: {
1777
1819
  channel: string;
1778
1820
  chatId: string;
1779
1821
  accountId?: string | undefined;
1780
1822
  } | undefined;
1823
+ maxOutputTokens?: number | undefined;
1781
1824
  }, {
1782
1825
  agent: string;
1783
1826
  prompt: string;
@@ -1791,8 +1834,128 @@ declare const daemonConfigSchema: z.ZodObject<{
1791
1834
  chatId: string;
1792
1835
  accountId?: string | undefined;
1793
1836
  } | undefined;
1794
- onError?: "log" | "notify" | "disable" | undefined;
1837
+ maxOutputTokens?: number | undefined;
1838
+ onError?: "notify" | "log" | "disable" | ("notify" | "log" | "disable")[] | undefined;
1839
+ }>>>;
1840
+ services: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
1841
+ name: z.ZodString;
1842
+ triggers: z.ZodArray<z.ZodObject<{
1843
+ pattern: z.ZodString;
1844
+ channel: z.ZodOptional<z.ZodString>;
1845
+ }, "strip", z.ZodTypeAny, {
1846
+ pattern: string;
1847
+ channel?: string | undefined;
1848
+ }, {
1849
+ pattern: string;
1850
+ channel?: string | undefined;
1851
+ }>, "many">;
1852
+ allowedContacts: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
1853
+ agent: z.ZodString;
1854
+ prompt: z.ZodString;
1855
+ schedule: z.ZodOptional<z.ZodString>;
1856
+ timezone: z.ZodDefault<z.ZodString>;
1857
+ notify: z.ZodOptional<z.ZodObject<{
1858
+ channel: z.ZodString;
1859
+ chatId: z.ZodString;
1860
+ accountId: z.ZodOptional<z.ZodString>;
1861
+ }, "strip", z.ZodTypeAny, {
1862
+ channel: string;
1863
+ chatId: string;
1864
+ accountId?: string | undefined;
1865
+ }, {
1866
+ channel: string;
1867
+ chatId: string;
1868
+ accountId?: string | undefined;
1869
+ }>>;
1870
+ }, "strip", z.ZodTypeAny, {
1871
+ agent: string;
1872
+ name: string;
1873
+ prompt: string;
1874
+ triggers: {
1875
+ pattern: string;
1876
+ channel?: string | undefined;
1877
+ }[];
1878
+ timezone: string;
1879
+ schedule?: string | undefined;
1880
+ notify?: {
1881
+ channel: string;
1882
+ chatId: string;
1883
+ accountId?: string | undefined;
1884
+ } | undefined;
1885
+ allowedContacts?: string[] | undefined;
1886
+ }, {
1887
+ agent: string;
1888
+ name: string;
1889
+ prompt: string;
1890
+ triggers: {
1891
+ pattern: string;
1892
+ channel?: string | undefined;
1893
+ }[];
1894
+ schedule?: string | undefined;
1895
+ timezone?: string | undefined;
1896
+ notify?: {
1897
+ channel: string;
1898
+ chatId: string;
1899
+ accountId?: string | undefined;
1900
+ } | undefined;
1901
+ allowedContacts?: string[] | undefined;
1795
1902
  }>>>;
1903
+ notifications: z.ZodDefault<z.ZodObject<{
1904
+ /** Send notification when task takes longer than this (seconds). 0 = disabled. */
1905
+ longTaskThreshold: z.ZodDefault<z.ZodNumber>;
1906
+ /** Where to send notifications */
1907
+ destination: z.ZodOptional<z.ZodObject<{
1908
+ channel: z.ZodString;
1909
+ chatId: z.ZodString;
1910
+ accountId: z.ZodOptional<z.ZodString>;
1911
+ }, "strip", z.ZodTypeAny, {
1912
+ channel: string;
1913
+ chatId: string;
1914
+ accountId?: string | undefined;
1915
+ }, {
1916
+ channel: string;
1917
+ chatId: string;
1918
+ accountId?: string | undefined;
1919
+ }>>;
1920
+ /** Notify on these events */
1921
+ on: z.ZodDefault<z.ZodObject<{
1922
+ taskComplete: z.ZodDefault<z.ZodBoolean>;
1923
+ taskError: z.ZodDefault<z.ZodBoolean>;
1924
+ taskQueued: z.ZodDefault<z.ZodBoolean>;
1925
+ }, "strip", z.ZodTypeAny, {
1926
+ taskComplete: boolean;
1927
+ taskError: boolean;
1928
+ taskQueued: boolean;
1929
+ }, {
1930
+ taskComplete?: boolean | undefined;
1931
+ taskError?: boolean | undefined;
1932
+ taskQueued?: boolean | undefined;
1933
+ }>>;
1934
+ }, "strip", z.ZodTypeAny, {
1935
+ on: {
1936
+ taskComplete: boolean;
1937
+ taskError: boolean;
1938
+ taskQueued: boolean;
1939
+ };
1940
+ longTaskThreshold: number;
1941
+ destination?: {
1942
+ channel: string;
1943
+ chatId: string;
1944
+ accountId?: string | undefined;
1945
+ } | undefined;
1946
+ }, {
1947
+ on?: {
1948
+ taskComplete?: boolean | undefined;
1949
+ taskError?: boolean | undefined;
1950
+ taskQueued?: boolean | undefined;
1951
+ } | undefined;
1952
+ longTaskThreshold?: number | undefined;
1953
+ destination?: {
1954
+ channel: string;
1955
+ chatId: string;
1956
+ accountId?: string | undefined;
1957
+ } | undefined;
1958
+ }>>;
1796
1959
  mesh: z.ZodDefault<z.ZodObject<{
1797
1960
  enabled: z.ZodDefault<z.ZodBoolean>;
1798
1961
  peers: z.ZodDefault<z.ZodArray<z.ZodObject<{
@@ -1844,6 +2007,408 @@ declare const daemonConfigSchema: z.ZodObject<{
1844
2007
  interval?: number | undefined;
1845
2008
  } | undefined;
1846
2009
  }>>;
2010
+ business: z.ZodOptional<z.ZodObject<{
2011
+ enabled: z.ZodDefault<z.ZodBoolean>;
2012
+ timezone: z.ZodDefault<z.ZodString>;
2013
+ mainChannel: z.ZodObject<{
2014
+ channel: z.ZodString;
2015
+ chatId: z.ZodString;
2016
+ accountId: z.ZodOptional<z.ZodString>;
2017
+ }, "strip", z.ZodTypeAny, {
2018
+ channel: string;
2019
+ chatId: string;
2020
+ accountId?: string | undefined;
2021
+ }, {
2022
+ channel: string;
2023
+ chatId: string;
2024
+ accountId?: string | undefined;
2025
+ }>;
2026
+ workSource: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2027
+ type: z.ZodLiteral<"backlog">;
2028
+ path: z.ZodDefault<z.ZodString>;
2029
+ }, "strip", z.ZodTypeAny, {
2030
+ path: string;
2031
+ type: "backlog";
2032
+ }, {
2033
+ type: "backlog";
2034
+ path?: string | undefined;
2035
+ }>, z.ZodObject<{
2036
+ type: z.ZodLiteral<"gitlab">;
2037
+ projects: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
2038
+ }, "strip", z.ZodTypeAny, {
2039
+ type: "gitlab";
2040
+ projects: string[];
2041
+ }, {
2042
+ type: "gitlab";
2043
+ projects?: string[] | undefined;
2044
+ }>, z.ZodObject<{
2045
+ type: z.ZodLiteral<"wiki">;
2046
+ path: z.ZodString;
2047
+ glob: z.ZodDefault<z.ZodString>;
2048
+ }, "strip", z.ZodTypeAny, {
2049
+ path: string;
2050
+ type: "wiki";
2051
+ glob: string;
2052
+ }, {
2053
+ path: string;
2054
+ type: "wiki";
2055
+ glob?: string | undefined;
2056
+ }>]>;
2057
+ roles: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
2058
+ title: z.ZodString;
2059
+ responsibilities: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
2060
+ sopPath: z.ZodOptional<z.ZodString>;
2061
+ kpis: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
2062
+ }, "strip", z.ZodTypeAny, {
2063
+ title: string;
2064
+ responsibilities: string[];
2065
+ kpis: string[];
2066
+ sopPath?: string | undefined;
2067
+ }, {
2068
+ title: string;
2069
+ responsibilities?: string[] | undefined;
2070
+ sopPath?: string | undefined;
2071
+ kpis?: string[] | undefined;
2072
+ }>>>;
2073
+ orgChart: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
2074
+ role: z.ZodString;
2075
+ reportsTo: z.ZodOptional<z.ZodString>;
2076
+ schedule: z.ZodObject<{
2077
+ days: z.ZodDefault<z.ZodArray<z.ZodEnum<["mon", "tue", "wed", "thu", "fri", "sat", "sun"]>, "many">>;
2078
+ start: z.ZodString;
2079
+ end: z.ZodString;
2080
+ lunch: z.ZodOptional<z.ZodObject<{
2081
+ start: z.ZodString;
2082
+ end: z.ZodString;
2083
+ }, "strip", z.ZodTypeAny, {
2084
+ end: string;
2085
+ start: string;
2086
+ }, {
2087
+ end: string;
2088
+ start: string;
2089
+ }>>;
2090
+ }, "strip", z.ZodTypeAny, {
2091
+ end: string;
2092
+ days: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[];
2093
+ start: string;
2094
+ lunch?: {
2095
+ end: string;
2096
+ start: string;
2097
+ } | undefined;
2098
+ }, {
2099
+ end: string;
2100
+ start: string;
2101
+ days?: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[] | undefined;
2102
+ lunch?: {
2103
+ end: string;
2104
+ start: string;
2105
+ } | undefined;
2106
+ }>;
2107
+ utilizationTarget: z.ZodDefault<z.ZodNumber>;
2108
+ }, "strip", z.ZodTypeAny, {
2109
+ role: string;
2110
+ schedule: {
2111
+ end: string;
2112
+ days: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[];
2113
+ start: string;
2114
+ lunch?: {
2115
+ end: string;
2116
+ start: string;
2117
+ } | undefined;
2118
+ };
2119
+ utilizationTarget: number;
2120
+ reportsTo?: string | undefined;
2121
+ }, {
2122
+ role: string;
2123
+ schedule: {
2124
+ end: string;
2125
+ start: string;
2126
+ days?: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[] | undefined;
2127
+ lunch?: {
2128
+ end: string;
2129
+ start: string;
2130
+ } | undefined;
2131
+ };
2132
+ reportsTo?: string | undefined;
2133
+ utilizationTarget?: number | undefined;
2134
+ }>>>;
2135
+ workTickMinutes: z.ZodDefault<z.ZodNumber>;
2136
+ idleQueueThreshold: z.ZodDefault<z.ZodNumber>;
2137
+ }, "strip", z.ZodTypeAny, {
2138
+ enabled: boolean;
2139
+ timezone: string;
2140
+ mainChannel: {
2141
+ channel: string;
2142
+ chatId: string;
2143
+ accountId?: string | undefined;
2144
+ };
2145
+ workSource: {
2146
+ path: string;
2147
+ type: "backlog";
2148
+ } | {
2149
+ type: "gitlab";
2150
+ projects: string[];
2151
+ } | {
2152
+ path: string;
2153
+ type: "wiki";
2154
+ glob: string;
2155
+ };
2156
+ roles: Record<string, {
2157
+ title: string;
2158
+ responsibilities: string[];
2159
+ kpis: string[];
2160
+ sopPath?: string | undefined;
2161
+ }>;
2162
+ orgChart: Record<string, {
2163
+ role: string;
2164
+ schedule: {
2165
+ end: string;
2166
+ days: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[];
2167
+ start: string;
2168
+ lunch?: {
2169
+ end: string;
2170
+ start: string;
2171
+ } | undefined;
2172
+ };
2173
+ utilizationTarget: number;
2174
+ reportsTo?: string | undefined;
2175
+ }>;
2176
+ workTickMinutes: number;
2177
+ idleQueueThreshold: number;
2178
+ }, {
2179
+ mainChannel: {
2180
+ channel: string;
2181
+ chatId: string;
2182
+ accountId?: string | undefined;
2183
+ };
2184
+ workSource: {
2185
+ type: "backlog";
2186
+ path?: string | undefined;
2187
+ } | {
2188
+ type: "gitlab";
2189
+ projects?: string[] | undefined;
2190
+ } | {
2191
+ path: string;
2192
+ type: "wiki";
2193
+ glob?: string | undefined;
2194
+ };
2195
+ enabled?: boolean | undefined;
2196
+ timezone?: string | undefined;
2197
+ roles?: Record<string, {
2198
+ title: string;
2199
+ responsibilities?: string[] | undefined;
2200
+ sopPath?: string | undefined;
2201
+ kpis?: string[] | undefined;
2202
+ }> | undefined;
2203
+ orgChart?: Record<string, {
2204
+ role: string;
2205
+ schedule: {
2206
+ end: string;
2207
+ start: string;
2208
+ days?: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[] | undefined;
2209
+ lunch?: {
2210
+ end: string;
2211
+ start: string;
2212
+ } | undefined;
2213
+ };
2214
+ reportsTo?: string | undefined;
2215
+ utilizationTarget?: number | undefined;
2216
+ }> | undefined;
2217
+ workTickMinutes?: number | undefined;
2218
+ idleQueueThreshold?: number | undefined;
2219
+ }>>;
2220
+ boards: z.ZodDefault<z.ZodArray<z.ZodObject<{
2221
+ id: z.ZodString;
2222
+ name: z.ZodString;
2223
+ source: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
2224
+ type: z.ZodLiteral<"gitlab">;
2225
+ projects: z.ZodArray<z.ZodString, "many">;
2226
+ }, "strip", z.ZodTypeAny, {
2227
+ type: "gitlab";
2228
+ projects: string[];
2229
+ }, {
2230
+ type: "gitlab";
2231
+ projects: string[];
2232
+ }>]>;
2233
+ primaryToolLabel: z.ZodOptional<z.ZodString>;
2234
+ labels: z.ZodDefault<z.ZodArray<z.ZodObject<{
2235
+ name: z.ZodString;
2236
+ color: z.ZodDefault<z.ZodString>;
2237
+ description: z.ZodOptional<z.ZodString>;
2238
+ }, "strip", z.ZodTypeAny, {
2239
+ name: string;
2240
+ color: string;
2241
+ description?: string | undefined;
2242
+ }, {
2243
+ name: string;
2244
+ description?: string | undefined;
2245
+ color?: string | undefined;
2246
+ }>, "many">>;
2247
+ columns: z.ZodDefault<z.ZodArray<z.ZodObject<{
2248
+ id: z.ZodString;
2249
+ title: z.ZodString;
2250
+ kind: z.ZodDefault<z.ZodEnum<["open-backlog", "scoped-label", "closed", "label"]>>;
2251
+ mapsToLabel: z.ZodOptional<z.ZodString>;
2252
+ scopedLabel: z.ZodOptional<z.ZodString>;
2253
+ scopedPrefix: z.ZodDefault<z.ZodString>;
2254
+ accent: z.ZodOptional<z.ZodString>;
2255
+ }, "strip", z.ZodTypeAny, {
2256
+ id: string;
2257
+ title: string;
2258
+ kind: "open-backlog" | "scoped-label" | "closed" | "label";
2259
+ scopedPrefix: string;
2260
+ mapsToLabel?: string | undefined;
2261
+ scopedLabel?: string | undefined;
2262
+ accent?: string | undefined;
2263
+ }, {
2264
+ id: string;
2265
+ title: string;
2266
+ kind?: "open-backlog" | "scoped-label" | "closed" | "label" | undefined;
2267
+ mapsToLabel?: string | undefined;
2268
+ scopedLabel?: string | undefined;
2269
+ scopedPrefix?: string | undefined;
2270
+ accent?: string | undefined;
2271
+ }>, "many">>;
2272
+ timeRangeDays: z.ZodDefault<z.ZodNumber>;
2273
+ closedWindowDays: z.ZodDefault<z.ZodNumber>;
2274
+ reconciliation: z.ZodDefault<z.ZodObject<{
2275
+ enabled: z.ZodDefault<z.ZodBoolean>;
2276
+ staleDoingMinutes: z.ZodDefault<z.ZodNumber>;
2277
+ respectLunchBreak: z.ZodDefault<z.ZodBoolean>;
2278
+ respectSchedule: z.ZodDefault<z.ZodBoolean>;
2279
+ action: z.ZodDefault<z.ZodEnum<["badge", "notify"]>>;
2280
+ }, "strip", z.ZodTypeAny, {
2281
+ enabled: boolean;
2282
+ action: "badge" | "notify";
2283
+ staleDoingMinutes: number;
2284
+ respectLunchBreak: boolean;
2285
+ respectSchedule: boolean;
2286
+ }, {
2287
+ enabled?: boolean | undefined;
2288
+ action?: "badge" | "notify" | undefined;
2289
+ staleDoingMinutes?: number | undefined;
2290
+ respectLunchBreak?: boolean | undefined;
2291
+ respectSchedule?: boolean | undefined;
2292
+ }>>;
2293
+ }, "strip", z.ZodTypeAny, {
2294
+ id: string;
2295
+ name: string;
2296
+ source: {
2297
+ type: "gitlab";
2298
+ projects: string[];
2299
+ };
2300
+ labels: {
2301
+ name: string;
2302
+ color: string;
2303
+ description?: string | undefined;
2304
+ }[];
2305
+ columns: {
2306
+ id: string;
2307
+ title: string;
2308
+ kind: "open-backlog" | "scoped-label" | "closed" | "label";
2309
+ scopedPrefix: string;
2310
+ mapsToLabel?: string | undefined;
2311
+ scopedLabel?: string | undefined;
2312
+ accent?: string | undefined;
2313
+ }[];
2314
+ timeRangeDays: number;
2315
+ closedWindowDays: number;
2316
+ reconciliation: {
2317
+ enabled: boolean;
2318
+ action: "badge" | "notify";
2319
+ staleDoingMinutes: number;
2320
+ respectLunchBreak: boolean;
2321
+ respectSchedule: boolean;
2322
+ };
2323
+ primaryToolLabel?: string | undefined;
2324
+ }, {
2325
+ id: string;
2326
+ name: string;
2327
+ source: {
2328
+ type: "gitlab";
2329
+ projects: string[];
2330
+ };
2331
+ primaryToolLabel?: string | undefined;
2332
+ labels?: {
2333
+ name: string;
2334
+ description?: string | undefined;
2335
+ color?: string | undefined;
2336
+ }[] | undefined;
2337
+ columns?: {
2338
+ id: string;
2339
+ title: string;
2340
+ kind?: "open-backlog" | "scoped-label" | "closed" | "label" | undefined;
2341
+ mapsToLabel?: string | undefined;
2342
+ scopedLabel?: string | undefined;
2343
+ scopedPrefix?: string | undefined;
2344
+ accent?: string | undefined;
2345
+ }[] | undefined;
2346
+ timeRangeDays?: number | undefined;
2347
+ closedWindowDays?: number | undefined;
2348
+ reconciliation?: {
2349
+ enabled?: boolean | undefined;
2350
+ action?: "badge" | "notify" | undefined;
2351
+ staleDoingMinutes?: number | undefined;
2352
+ respectLunchBreak?: boolean | undefined;
2353
+ respectSchedule?: boolean | undefined;
2354
+ } | undefined;
2355
+ }>, "many">>;
2356
+ dashboard: z.ZodDefault<z.ZodObject<{
2357
+ enabled: z.ZodDefault<z.ZodBoolean>;
2358
+ port: z.ZodDefault<z.ZodNumber>;
2359
+ bind: z.ZodDefault<z.ZodString>;
2360
+ token: z.ZodOptional<z.ZodString>;
2361
+ daemonUrl: z.ZodDefault<z.ZodString>;
2362
+ daemons: z.ZodDefault<z.ZodArray<z.ZodObject<{
2363
+ name: z.ZodString;
2364
+ url: z.ZodString;
2365
+ token: z.ZodOptional<z.ZodString>;
2366
+ }, "strip", z.ZodTypeAny, {
2367
+ name: string;
2368
+ url: string;
2369
+ token?: string | undefined;
2370
+ }, {
2371
+ name: string;
2372
+ url: string;
2373
+ token?: string | undefined;
2374
+ }>, "many">>;
2375
+ draftAgent: z.ZodOptional<z.ZodString>;
2376
+ }, "strip", z.ZodTypeAny, {
2377
+ enabled: boolean;
2378
+ port: number;
2379
+ bind: string;
2380
+ daemonUrl: string;
2381
+ daemons: {
2382
+ name: string;
2383
+ url: string;
2384
+ token?: string | undefined;
2385
+ }[];
2386
+ token?: string | undefined;
2387
+ draftAgent?: string | undefined;
2388
+ }, {
2389
+ enabled?: boolean | undefined;
2390
+ token?: string | undefined;
2391
+ port?: number | undefined;
2392
+ bind?: string | undefined;
2393
+ daemonUrl?: string | undefined;
2394
+ daemons?: {
2395
+ name: string;
2396
+ url: string;
2397
+ token?: string | undefined;
2398
+ }[] | undefined;
2399
+ draftAgent?: string | undefined;
2400
+ }>>;
2401
+ /** Session cache-reuse policy. `staleMinutes` controls how long a Claude
2402
+ * session can idle before we rebuild the prompt from scratch (paying the
2403
+ * full cache-create tax again). Longer is cheaper at Opus rates but means
2404
+ * an agent may resume with mildly outdated context. */
2405
+ session: z.ZodDefault<z.ZodObject<{
2406
+ staleMinutes: z.ZodDefault<z.ZodNumber>;
2407
+ }, "strip", z.ZodTypeAny, {
2408
+ staleMinutes: number;
2409
+ }, {
2410
+ staleMinutes?: number | undefined;
2411
+ }>>;
1847
2412
  }, "strip", z.ZodTypeAny, {
1848
2413
  agents: Record<string, {
1849
2414
  name: string;
@@ -1851,6 +2416,7 @@ declare const daemonConfigSchema: z.ZodObject<{
1851
2416
  tier: "claude-code" | "sdk" | "orchestrator";
1852
2417
  mentions: string[];
1853
2418
  maxConcurrent: number;
2419
+ maxExecutionMinutes: number;
1854
2420
  permissionMode: string;
1855
2421
  queueMode: "collect" | "followup" | "drop";
1856
2422
  heartbeat: {
@@ -1880,6 +2446,7 @@ declare const daemonConfigSchema: z.ZodObject<{
1880
2446
  id: string;
1881
2447
  name: string;
1882
2448
  bind: string;
2449
+ defaultAgent?: string | undefined;
1883
2450
  };
1884
2451
  providers: Record<string, {
1885
2452
  apiKey?: string | undefined;
@@ -1887,6 +2454,24 @@ declare const daemonConfigSchema: z.ZodObject<{
1887
2454
  baseUrl?: string | undefined;
1888
2455
  }>;
1889
2456
  channels: {
2457
+ gitlab: {
2458
+ enabled: boolean;
2459
+ routes: {
2460
+ agent: string;
2461
+ project: string;
2462
+ }[];
2463
+ webhookPort: number;
2464
+ host: string;
2465
+ agentMappings: {
2466
+ agentId: string;
2467
+ gitlabUsernames: string[];
2468
+ keywords: string[];
2469
+ token?: string | undefined;
2470
+ node?: string | undefined;
2471
+ }[];
2472
+ token?: string | undefined;
2473
+ webhookSecret?: string | undefined;
2474
+ };
1890
2475
  telegram: {
1891
2476
  enabled: boolean;
1892
2477
  accounts: Record<string, {
@@ -1914,23 +2499,6 @@ declare const daemonConfigSchema: z.ZodObject<{
1914
2499
  token?: string | undefined;
1915
2500
  agentBinding?: string | undefined;
1916
2501
  };
1917
- gitlab: {
1918
- enabled: boolean;
1919
- routes: {
1920
- agent: string;
1921
- project: string;
1922
- }[];
1923
- webhookPort: number;
1924
- host: string;
1925
- agentMappings: {
1926
- agentId: string;
1927
- gitlabUsernames: string[];
1928
- keywords: string[];
1929
- token?: string | undefined;
1930
- }[];
1931
- token?: string | undefined;
1932
- webhookSecret?: string | undefined;
1933
- };
1934
2502
  };
1935
2503
  crons: Record<string, {
1936
2504
  enabled: boolean;
@@ -1939,19 +2507,141 @@ declare const daemonConfigSchema: z.ZodObject<{
1939
2507
  timeout: number;
1940
2508
  schedule: string;
1941
2509
  timezone: string;
1942
- onError: "log" | "notify" | "disable";
2510
+ onError: ("notify" | "log" | "disable")[];
1943
2511
  model?: string | undefined;
1944
2512
  notify?: {
1945
2513
  channel: string;
1946
2514
  chatId: string;
1947
2515
  accountId?: string | undefined;
1948
2516
  } | undefined;
2517
+ maxOutputTokens?: number | undefined;
2518
+ }>;
2519
+ services: Record<string, {
2520
+ agent: string;
2521
+ name: string;
2522
+ prompt: string;
2523
+ triggers: {
2524
+ pattern: string;
2525
+ channel?: string | undefined;
2526
+ }[];
2527
+ timezone: string;
2528
+ schedule?: string | undefined;
2529
+ notify?: {
2530
+ channel: string;
2531
+ chatId: string;
2532
+ accountId?: string | undefined;
2533
+ } | undefined;
2534
+ allowedContacts?: string[] | undefined;
1949
2535
  }>;
2536
+ notifications: {
2537
+ on: {
2538
+ taskComplete: boolean;
2539
+ taskError: boolean;
2540
+ taskQueued: boolean;
2541
+ };
2542
+ longTaskThreshold: number;
2543
+ destination?: {
2544
+ channel: string;
2545
+ chatId: string;
2546
+ accountId?: string | undefined;
2547
+ } | undefined;
2548
+ };
2549
+ boards: {
2550
+ id: string;
2551
+ name: string;
2552
+ source: {
2553
+ type: "gitlab";
2554
+ projects: string[];
2555
+ };
2556
+ labels: {
2557
+ name: string;
2558
+ color: string;
2559
+ description?: string | undefined;
2560
+ }[];
2561
+ columns: {
2562
+ id: string;
2563
+ title: string;
2564
+ kind: "open-backlog" | "scoped-label" | "closed" | "label";
2565
+ scopedPrefix: string;
2566
+ mapsToLabel?: string | undefined;
2567
+ scopedLabel?: string | undefined;
2568
+ accent?: string | undefined;
2569
+ }[];
2570
+ timeRangeDays: number;
2571
+ closedWindowDays: number;
2572
+ reconciliation: {
2573
+ enabled: boolean;
2574
+ action: "badge" | "notify";
2575
+ staleDoingMinutes: number;
2576
+ respectLunchBreak: boolean;
2577
+ respectSchedule: boolean;
2578
+ };
2579
+ primaryToolLabel?: string | undefined;
2580
+ }[];
2581
+ dashboard: {
2582
+ enabled: boolean;
2583
+ port: number;
2584
+ bind: string;
2585
+ daemonUrl: string;
2586
+ daemons: {
2587
+ name: string;
2588
+ url: string;
2589
+ token?: string | undefined;
2590
+ }[];
2591
+ token?: string | undefined;
2592
+ draftAgent?: string | undefined;
2593
+ };
2594
+ session: {
2595
+ staleMinutes: number;
2596
+ };
2597
+ business?: {
2598
+ enabled: boolean;
2599
+ timezone: string;
2600
+ mainChannel: {
2601
+ channel: string;
2602
+ chatId: string;
2603
+ accountId?: string | undefined;
2604
+ };
2605
+ workSource: {
2606
+ path: string;
2607
+ type: "backlog";
2608
+ } | {
2609
+ type: "gitlab";
2610
+ projects: string[];
2611
+ } | {
2612
+ path: string;
2613
+ type: "wiki";
2614
+ glob: string;
2615
+ };
2616
+ roles: Record<string, {
2617
+ title: string;
2618
+ responsibilities: string[];
2619
+ kpis: string[];
2620
+ sopPath?: string | undefined;
2621
+ }>;
2622
+ orgChart: Record<string, {
2623
+ role: string;
2624
+ schedule: {
2625
+ end: string;
2626
+ days: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[];
2627
+ start: string;
2628
+ lunch?: {
2629
+ end: string;
2630
+ start: string;
2631
+ } | undefined;
2632
+ };
2633
+ utilizationTarget: number;
2634
+ reportsTo?: string | undefined;
2635
+ }>;
2636
+ workTickMinutes: number;
2637
+ idleQueueThreshold: number;
2638
+ } | undefined;
1950
2639
  }, {
1951
2640
  node: {
1952
2641
  id: string;
1953
2642
  name: string;
1954
2643
  bind?: string | undefined;
2644
+ defaultAgent?: string | undefined;
1955
2645
  };
1956
2646
  agents?: Record<string, {
1957
2647
  name: string;
@@ -1962,6 +2652,7 @@ declare const daemonConfigSchema: z.ZodObject<{
1962
2652
  systemPrompt?: string | undefined;
1963
2653
  mentions?: string[] | undefined;
1964
2654
  maxConcurrent?: number | undefined;
2655
+ maxExecutionMinutes?: number | undefined;
1965
2656
  permissionMode?: string | undefined;
1966
2657
  queueMode?: "collect" | "followup" | "drop" | undefined;
1967
2658
  heartbeat?: {
@@ -1990,6 +2681,24 @@ declare const daemonConfigSchema: z.ZodObject<{
1990
2681
  baseUrl?: string | undefined;
1991
2682
  }> | undefined;
1992
2683
  channels?: {
2684
+ gitlab?: {
2685
+ enabled?: boolean | undefined;
2686
+ token?: string | undefined;
2687
+ routes?: {
2688
+ agent: string;
2689
+ project: string;
2690
+ }[] | undefined;
2691
+ webhookPort?: number | undefined;
2692
+ webhookSecret?: string | undefined;
2693
+ host?: string | undefined;
2694
+ agentMappings?: {
2695
+ agentId: string;
2696
+ token?: string | undefined;
2697
+ gitlabUsernames?: string[] | undefined;
2698
+ keywords?: string[] | undefined;
2699
+ node?: string | undefined;
2700
+ }[] | undefined;
2701
+ } | undefined;
1993
2702
  telegram?: {
1994
2703
  enabled?: boolean | undefined;
1995
2704
  accounts?: Record<string, {
@@ -2017,39 +2726,143 @@ declare const daemonConfigSchema: z.ZodObject<{
2017
2726
  token?: string | undefined;
2018
2727
  agentBinding?: string | undefined;
2019
2728
  } | undefined;
2020
- gitlab?: {
2021
- enabled?: boolean | undefined;
2022
- token?: string | undefined;
2023
- routes?: {
2024
- agent: string;
2025
- project: string;
2026
- }[] | undefined;
2027
- webhookPort?: number | undefined;
2028
- webhookSecret?: string | undefined;
2029
- host?: string | undefined;
2030
- agentMappings?: {
2031
- agentId: string;
2032
- token?: string | undefined;
2033
- gitlabUsernames?: string[] | undefined;
2034
- keywords?: string[] | undefined;
2035
- }[] | undefined;
2729
+ } | undefined;
2730
+ crons?: Record<string, {
2731
+ agent: string;
2732
+ prompt: string;
2733
+ schedule: string;
2734
+ model?: string | undefined;
2735
+ enabled?: boolean | undefined;
2736
+ timeout?: number | undefined;
2737
+ timezone?: string | undefined;
2738
+ notify?: {
2739
+ channel: string;
2740
+ chatId: string;
2741
+ accountId?: string | undefined;
2742
+ } | undefined;
2743
+ maxOutputTokens?: number | undefined;
2744
+ onError?: "notify" | "log" | "disable" | ("notify" | "log" | "disable")[] | undefined;
2745
+ }> | undefined;
2746
+ services?: Record<string, {
2747
+ agent: string;
2748
+ name: string;
2749
+ prompt: string;
2750
+ triggers: {
2751
+ pattern: string;
2752
+ channel?: string | undefined;
2753
+ }[];
2754
+ schedule?: string | undefined;
2755
+ timezone?: string | undefined;
2756
+ notify?: {
2757
+ channel: string;
2758
+ chatId: string;
2759
+ accountId?: string | undefined;
2760
+ } | undefined;
2761
+ allowedContacts?: string[] | undefined;
2762
+ }> | undefined;
2763
+ notifications?: {
2764
+ on?: {
2765
+ taskComplete?: boolean | undefined;
2766
+ taskError?: boolean | undefined;
2767
+ taskQueued?: boolean | undefined;
2768
+ } | undefined;
2769
+ longTaskThreshold?: number | undefined;
2770
+ destination?: {
2771
+ channel: string;
2772
+ chatId: string;
2773
+ accountId?: string | undefined;
2774
+ } | undefined;
2775
+ } | undefined;
2776
+ business?: {
2777
+ mainChannel: {
2778
+ channel: string;
2779
+ chatId: string;
2780
+ accountId?: string | undefined;
2781
+ };
2782
+ workSource: {
2783
+ type: "backlog";
2784
+ path?: string | undefined;
2785
+ } | {
2786
+ type: "gitlab";
2787
+ projects?: string[] | undefined;
2788
+ } | {
2789
+ path: string;
2790
+ type: "wiki";
2791
+ glob?: string | undefined;
2792
+ };
2793
+ enabled?: boolean | undefined;
2794
+ timezone?: string | undefined;
2795
+ roles?: Record<string, {
2796
+ title: string;
2797
+ responsibilities?: string[] | undefined;
2798
+ sopPath?: string | undefined;
2799
+ kpis?: string[] | undefined;
2800
+ }> | undefined;
2801
+ orgChart?: Record<string, {
2802
+ role: string;
2803
+ schedule: {
2804
+ end: string;
2805
+ start: string;
2806
+ days?: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[] | undefined;
2807
+ lunch?: {
2808
+ end: string;
2809
+ start: string;
2810
+ } | undefined;
2811
+ };
2812
+ reportsTo?: string | undefined;
2813
+ utilizationTarget?: number | undefined;
2814
+ }> | undefined;
2815
+ workTickMinutes?: number | undefined;
2816
+ idleQueueThreshold?: number | undefined;
2817
+ } | undefined;
2818
+ boards?: {
2819
+ id: string;
2820
+ name: string;
2821
+ source: {
2822
+ type: "gitlab";
2823
+ projects: string[];
2824
+ };
2825
+ primaryToolLabel?: string | undefined;
2826
+ labels?: {
2827
+ name: string;
2828
+ description?: string | undefined;
2829
+ color?: string | undefined;
2830
+ }[] | undefined;
2831
+ columns?: {
2832
+ id: string;
2833
+ title: string;
2834
+ kind?: "open-backlog" | "scoped-label" | "closed" | "label" | undefined;
2835
+ mapsToLabel?: string | undefined;
2836
+ scopedLabel?: string | undefined;
2837
+ scopedPrefix?: string | undefined;
2838
+ accent?: string | undefined;
2839
+ }[] | undefined;
2840
+ timeRangeDays?: number | undefined;
2841
+ closedWindowDays?: number | undefined;
2842
+ reconciliation?: {
2843
+ enabled?: boolean | undefined;
2844
+ action?: "badge" | "notify" | undefined;
2845
+ staleDoingMinutes?: number | undefined;
2846
+ respectLunchBreak?: boolean | undefined;
2847
+ respectSchedule?: boolean | undefined;
2036
2848
  } | undefined;
2037
- } | undefined;
2038
- crons?: Record<string, {
2039
- agent: string;
2040
- prompt: string;
2041
- schedule: string;
2042
- model?: string | undefined;
2849
+ }[] | undefined;
2850
+ dashboard?: {
2043
2851
  enabled?: boolean | undefined;
2044
- timeout?: number | undefined;
2045
- timezone?: string | undefined;
2046
- notify?: {
2047
- channel: string;
2048
- chatId: string;
2049
- accountId?: string | undefined;
2050
- } | undefined;
2051
- onError?: "log" | "notify" | "disable" | undefined;
2052
- }> | undefined;
2852
+ token?: string | undefined;
2853
+ port?: number | undefined;
2854
+ bind?: string | undefined;
2855
+ daemonUrl?: string | undefined;
2856
+ daemons?: {
2857
+ name: string;
2858
+ url: string;
2859
+ token?: string | undefined;
2860
+ }[] | undefined;
2861
+ draftAgent?: string | undefined;
2862
+ } | undefined;
2863
+ session?: {
2864
+ staleMinutes?: number | undefined;
2865
+ } | undefined;
2053
2866
  }>;
2054
2867
  type DaemonConfig = z.infer<typeof daemonConfigSchema>;
2055
2868
  type AgentDef = z.infer<typeof agentConfigSchema>;
@@ -2119,14 +2932,35 @@ declare class AgentXDaemon {
2119
2932
  private hooks;
2120
2933
  private landscape;
2121
2934
  private heartbeat;
2935
+ private business?;
2122
2936
  private httpServer?;
2123
2937
  private webhooks;
2124
2938
  private log;
2125
2939
  private sseClients;
2940
+ private configPath?;
2941
+ private configWatcher?;
2942
+ private reloadTimer?;
2126
2943
  constructor(configPath?: string);
2127
2944
  start(): Promise<void>;
2128
2945
  stop(): Promise<void>;
2129
2946
  private midnightTimer?;
2947
+ /**
2948
+ * Watch agentx.json for external edits (e.g. `agentx config set ...`) and
2949
+ * reload cron jobs + in-memory config. Channels / agents / mesh changes
2950
+ * still require a restart — we log a warning so the operator knows.
2951
+ */
2952
+ private startConfigWatcher;
2953
+ /**
2954
+ * Re-read agentx.json, diff against the in-memory config, apply what we
2955
+ * can hot-reload (crons, notify-destination, business metadata), and warn
2956
+ * about sections that require a daemon restart (channels, agents, mesh,
2957
+ * node.bind, providers).
2958
+ */
2959
+ reload(): Promise<{
2960
+ applied: string[];
2961
+ restartRequired: string[];
2962
+ error?: string;
2963
+ }>;
2130
2964
  private scheduleMidnightHook;
2131
2965
  private runDailyCostReport;
2132
2966
  private startChannels;
@@ -2156,9 +2990,24 @@ declare class AgentXDaemon {
2156
2990
  private json;
2157
2991
  }
2158
2992
 
2159
- interface DailyUsage {
2160
- date: string;
2161
- agents: Record<string, AgentUsage>;
2993
+ declare const CACHE_AWARE_PRICING: Record<string, {
2994
+ input: number;
2995
+ output: number;
2996
+ cacheRead: number;
2997
+ cacheCreate: number;
2998
+ }>;
2999
+ interface ChannelUsage {
3000
+ tasks: number;
3001
+ inputTokens: number;
3002
+ outputTokens: number;
3003
+ cacheReadTokens: number;
3004
+ cacheCreateTokens: number;
3005
+ tier2InputTokens: number;
3006
+ tier2OutputTokens: number;
3007
+ tier2CacheReadTokens: number;
3008
+ tier2CacheCreateTokens: number;
3009
+ totalDuration: number;
3010
+ errors: number;
2162
3011
  }
2163
3012
  interface AgentUsage {
2164
3013
  tasks: number;
@@ -2166,9 +3015,26 @@ interface AgentUsage {
2166
3015
  outputTokens: number;
2167
3016
  cacheReadTokens: number;
2168
3017
  cacheCreateTokens: number;
3018
+ /** Tokens from requests whose input crossed CONTEXT_TIER_THRESHOLD (billed at
3019
+ * TIER2_MULTIPLIER × normal rate). Kept separate from the tier1 buckets so
3020
+ * cost math stays honest when a session accumulates past 200K. */
3021
+ tier2InputTokens?: number;
3022
+ tier2OutputTokens?: number;
3023
+ tier2CacheReadTokens?: number;
3024
+ tier2CacheCreateTokens?: number;
2169
3025
  totalDuration: number;
2170
3026
  errors: number;
2171
3027
  model?: string;
3028
+ /** Per-channel breakdown so we can attribute cost to Telegram vs GitLab vs WhatsApp. */
3029
+ byChannel?: Record<string, ChannelUsage>;
3030
+ /** Unique session identifiers (channel:chatId) this agent participated in
3031
+ * today. Used to derive avg tasks/session. Capped at 500 entries to keep
3032
+ * the daily JSON small. */
3033
+ sessionKeys?: string[];
3034
+ }
3035
+ interface DailyUsage {
3036
+ date: string;
3037
+ agents: Record<string, AgentUsage>;
2172
3038
  }
2173
3039
  interface DailyReport {
2174
3040
  date: string;
@@ -2181,24 +3047,50 @@ interface DailyReport {
2181
3047
  topAgent: string;
2182
3048
  topCost: number;
2183
3049
  agentCosts: Record<string, number>;
3050
+ /** Per-agent avg tasks/session — high values suggest retry chains. */
3051
+ agentSessionStats: Record<string, {
3052
+ sessions: number;
3053
+ avgTasksPerSession: number;
3054
+ }>;
3055
+ /** Aggregate cost by channel across all agents. */
3056
+ byChannel: Record<string, number>;
3057
+ }
3058
+ /** Shape of a per-request usage report coming from the runtime. Keeps the
3059
+ * record() signature tidy and lets callers opt into tier2 accounting. */
3060
+ interface TaskUsage {
3061
+ inputTokens: number;
3062
+ outputTokens: number;
3063
+ cacheReadTokens: number;
3064
+ cacheCreateTokens: number;
2184
3065
  }
2185
3066
  declare class TokenTracker {
2186
3067
  private dir;
2187
3068
  private cache;
3069
+ private pricing;
2188
3070
  constructor(baseDir?: string);
3071
+ /** Returns the active pricing table (hardcoded defaults with any per-model
3072
+ * overrides merged in). Useful for UI / debugging. */
3073
+ getPricing(): typeof CACHE_AWARE_PRICING;
3074
+ /**
3075
+ * Calculate cost for a slice of usage. Accepts either a full AgentUsage or
3076
+ * a narrowed ChannelUsage — both expose the same token buckets we price on.
3077
+ * Tier2 tokens are billed at TIER2_MULTIPLIER × the normal rate.
3078
+ */
3079
+ static calculateCost(usage: AgentUsage | ChannelUsage, model?: string, pricingTable?: typeof CACHE_AWARE_PRICING): number;
2189
3080
  /**
2190
- * Calculate cost for an agent's usage with cache-aware pricing.
3081
+ * Instance-level cost calculation — uses the tracker's resolved pricing
3082
+ * table so any custom override file is honored. Prefer this over the
3083
+ * static variant when available.
2191
3084
  */
2192
- static calculateCost(usage: AgentUsage): number;
3085
+ cost(usage: AgentUsage | ChannelUsage, model?: string): number;
2193
3086
  /**
2194
3087
  * Record a task execution with real or estimated token counts.
3088
+ *
3089
+ * `channel` attributes the cost to a surface (telegram/gitlab/whatsapp/cron).
3090
+ * `sessionKey` is an opaque "this chat on this day" identifier — we use it
3091
+ * to count unique sessions so an avg-tasks-per-session metric falls out.
2195
3092
  */
2196
- record(agentId: string, duration: number, realUsage?: {
2197
- inputTokens: number;
2198
- outputTokens: number;
2199
- cacheReadTokens: number;
2200
- cacheCreateTokens: number;
2201
- }, messageLength?: number, responseLength?: number, error?: boolean, model?: string): void;
3093
+ record(agentId: string, duration: number, realUsage?: TaskUsage, messageLength?: number, responseLength?: number, error?: boolean, model?: string, channel?: string, sessionKey?: string): void;
2202
3094
  /**
2203
3095
  * Get today's usage summary.
2204
3096
  */
@@ -2208,11 +3100,13 @@ declare class TokenTracker {
2208
3100
  */
2209
3101
  getDate(date: string): DailyUsage | null;
2210
3102
  /**
2211
- * Generate a daily cost report for a given date.
3103
+ * Generate a daily cost report for a given date. Includes per-agent,
3104
+ * per-channel costs and session statistics.
2212
3105
  */
2213
3106
  generateDailyReport(date?: string): DailyReport | null;
2214
3107
  /**
2215
- * Append a daily report row to TOKEN_COSTS.md.
3108
+ * Append a daily report row to TOKEN_COSTS.md. Adds channel + session
3109
+ * breakdown inline for at-a-glance spend attribution.
2216
3110
  */
2217
3111
  appendToTokenCosts(report: DailyReport, filePath?: string): void;
2218
3112
  /**
@@ -2238,6 +3132,14 @@ declare class TokenTracker {
2238
3132
  avgDuration: number;
2239
3133
  cost: number;
2240
3134
  }>;
3135
+ byChannel: Record<string, {
3136
+ tasks: number;
3137
+ cost: number;
3138
+ }>;
3139
+ sessionStats: Record<string, {
3140
+ sessions: number;
3141
+ avgTasksPerSession: number;
3142
+ }>;
2241
3143
  };
2242
3144
  private filePath;
2243
3145
  private save;
@@ -2252,6 +3154,13 @@ interface AgentPeer {
2252
3154
  interface AgentTask {
2253
3155
  message: string;
2254
3156
  agentId: string;
3157
+ /** Per-invocation model override (e.g. cron model). Falls back to agent.model. */
3158
+ model?: string;
3159
+ /** Cacheable text delivered to Claude via --append-system-prompt. Typically
3160
+ * agent.systemPrompt + SOUL/IDENTITY/AGENTS.md. Passing stable content
3161
+ * here (instead of in the user-message body) keeps it inside Claude's
3162
+ * cached system prompt across session resumes. */
3163
+ systemPromptAppend?: string;
2255
3164
  context?: {
2256
3165
  channel?: string;
2257
3166
  sender?: string;
@@ -2299,6 +3208,12 @@ interface AgentResponse {
2299
3208
  duration?: number;
2300
3209
  claudeSessionId?: string;
2301
3210
  usage?: TokenUsage;
3211
+ /** The model Claude actually billed for (from the CLI's init event). When
3212
+ * absent, cost reporting should fall back to the model override / agent
3213
+ * config. Knowing the billed model is what makes cache-aware pricing
3214
+ * trustworthy — a task that ran sonnet but was logged as opus would
3215
+ * overstate cost by ~5×. */
3216
+ billedModel?: string;
2302
3217
  }
2303
3218
  /** Callback for streaming text deltas */
2304
3219
  type StreamCallback = (delta: string, fullText: string) => void;
@@ -2320,11 +3235,11 @@ declare function executeClaudeCode(agent: AgentDef, task: AgentTask, historyCont
2320
3235
  /**
2321
3236
  * Execute a task using the Claude Agent SDK (tier: "sdk").
2322
3237
  */
2323
- declare function executeSdk(agent: AgentDef, task: AgentTask, apiKey: string): Promise<AgentResponse>;
3238
+ declare function executeSdk(agent: AgentDef, task: AgentTask, apiKey: string, historyContext?: string): Promise<AgentResponse>;
2324
3239
  /**
2325
3240
  * Execute a task using agentx's own orchestrator (tier: "orchestrator").
2326
3241
  */
2327
- declare function executeOrchestrator(agent: AgentDef, task: AgentTask, apiKey?: string): Promise<AgentResponse>;
3242
+ declare function executeOrchestrator(agent: AgentDef, task: AgentTask, apiKey?: string, historyContext?: string): Promise<AgentResponse>;
2328
3243
  /**
2329
3244
  * Route a task to the correct execution tier.
2330
3245
  */
@@ -2406,6 +3321,22 @@ declare class WikiStore {
2406
3321
  * Write or update a wiki article.
2407
3322
  */
2408
3323
  writeArticle(path: string, meta: WikiArticleMeta, content: string, agentId: string): boolean;
3324
+ /**
3325
+ * Save current article content as an immutable version before overwriting.
3326
+ * Versions stored in _versions/{article-path}/{timestamp}.md
3327
+ */
3328
+ private saveVersion;
3329
+ /**
3330
+ * List all versions of an article (newest first).
3331
+ */
3332
+ getVersions(articlePath: string): Array<{
3333
+ timestamp: string;
3334
+ path: string;
3335
+ }>;
3336
+ /**
3337
+ * Restore a specific version of an article.
3338
+ */
3339
+ restoreVersion(articlePath: string, versionTimestamp: string): boolean;
2409
3340
  /**
2410
3341
  * Read an article. Returns null if not found.
2411
3342
  */
@@ -2575,16 +3506,26 @@ declare class LandscapeBuilder {
2575
3506
  private config;
2576
3507
  private meshPeers;
2577
3508
  constructor(config: DaemonConfig);
3509
+ /** Fingerprint of the peer set that produced the current cache. A rebuild
3510
+ * is skipped when `refresh()` gets a topologically-identical set — this
3511
+ * is the common case on every mesh heartbeat and rebuilding would
3512
+ * needlessly invalidate every agent's cached prompt prefix. */
3513
+ private fingerprint;
2578
3514
  /**
2579
3515
  * Build landscape strings for all agents. Call at startup.
2580
3516
  */
2581
3517
  build(meshPeers?: MeshPeerInfo[]): void;
3518
+ /** Set-only signature of peers + their skill IDs. Health is excluded on
3519
+ * purpose — we don't want a flapping heartbeat to rebuild the cache. */
3520
+ private computeFingerprint;
2582
3521
  /**
2583
3522
  * Get the cached landscape string for a specific agent.
2584
3523
  */
2585
3524
  getForAgent(agentId: string): string | undefined;
2586
3525
  /**
2587
- * Rebuild after mesh topology changes.
3526
+ * Rebuild after mesh topology changes. Skipped when the peer set is
3527
+ * unchanged so a flapping health heartbeat doesn't invalidate every
3528
+ * agent's cached prompt prefix.
2588
3529
  */
2589
3530
  refresh(meshPeers: MeshPeerInfo[]): void;
2590
3531
  private renderForAgent;
@@ -2600,6 +3541,20 @@ declare class LandscapeBuilder {
2600
3541
  private extractCapability;
2601
3542
  }
2602
3543
 
3544
+ interface RunningTask {
3545
+ /** Unique id for this execution (timestamp-based). */
3546
+ id: string;
3547
+ /** First 200 chars of the user message, for display. */
3548
+ messagePreview: string;
3549
+ /** Origin channel (telegram, whatsapp, gitlab, api, cron, business, a2a, …). */
3550
+ channel: string;
3551
+ /** Group / chat / issue id from which the task arrived. */
3552
+ chatId?: string;
3553
+ /** Sender id/name (user, agent id, "cron:<id>", "mesh:<peer>", …). */
3554
+ sender?: string;
3555
+ /** Wall-clock start. */
3556
+ startedAt: Date;
3557
+ }
2603
3558
  declare class AgentRegistry {
2604
3559
  private agents;
2605
3560
  private config;
@@ -2607,10 +3562,13 @@ declare class AgentRegistry {
2607
3562
  private sessions;
2608
3563
  private wikiHub;
2609
3564
  private memoryStore;
3565
+ private patternStore;
2610
3566
  private rateLimiter;
2611
3567
  private tokenTracker;
2612
3568
  private landscape?;
2613
3569
  private messageQueue;
3570
+ /** Active soul profile per agent+chat session: "agentId:channel:chatId" → profile name */
3571
+ private activeSouls;
2614
3572
  private log;
2615
3573
  constructor(config: DaemonConfig, log?: (...args: unknown[]) => void);
2616
3574
  /**
@@ -2624,8 +3582,17 @@ declare class AgentRegistry {
2624
3582
  /**
2625
3583
  * Find agent by mention pattern (e.g., "@my_bot" -> "my-agent").
2626
3584
  * Returns the agent with the longest (most specific) mention match.
3585
+ *
3586
+ * When `atMentionsOnly` is true, only `@`-prefixed mentions are considered.
3587
+ * This is used for messages originating from another bot (cross-daemon
3588
+ * Telegram cascades, for example) where we don't want bare-word matches
3589
+ * like "nadia" in prose or "devops-mtgl" quoted in a reply to trigger
3590
+ * agents spuriously. Intentional handoffs still work because agents
3591
+ * write explicit `@noqta_X_bot` handles.
2627
3592
  */
2628
- findByMention(text: string): string | undefined;
3593
+ findByMention(text: string, opts?: {
3594
+ atMentionsOnly?: boolean;
3595
+ }): string | undefined;
2629
3596
  /**
2630
3597
  * Find ALL agents mentioned in text (for bot-to-bot detection).
2631
3598
  */
@@ -2651,11 +3618,13 @@ declare class AgentRegistry {
2651
3618
  id: string;
2652
3619
  name: string;
2653
3620
  tier: string;
3621
+ model?: string;
2654
3622
  workspace: string;
2655
3623
  active: number;
2656
3624
  total: number;
2657
3625
  errors: number;
2658
3626
  lastActive?: Date;
3627
+ runningTasks: RunningTask[];
2659
3628
  }>;
2660
3629
  /**
2661
3630
  * Get token usage summary.
@@ -2680,6 +3649,14 @@ declare class AgentRegistry {
2680
3649
  avgDuration: number;
2681
3650
  cost: number;
2682
3651
  }>;
3652
+ byChannel: Record<string, {
3653
+ tasks: number;
3654
+ cost: number;
3655
+ }>;
3656
+ sessionStats: Record<string, {
3657
+ sessions: number;
3658
+ avgTasksPerSession: number;
3659
+ }>;
2683
3660
  };
2684
3661
  /**
2685
3662
  * Get today's usage.
@@ -2723,6 +3700,10 @@ interface IncomingMessage {
2723
3700
  id: string;
2724
3701
  name: string;
2725
3702
  username?: string;
3703
+ /** True when the origin is another bot account (Telegram `from.is_bot`).
3704
+ * Used by the router to apply strict @-mention-only routing — prevents
3705
+ * cross-daemon cascades from bare-word matches in bot replies. */
3706
+ isBot?: boolean;
2726
3707
  };
2727
3708
  group?: {
2728
3709
  id: string;
@@ -2739,6 +3720,7 @@ interface IncomingMessage {
2739
3720
  };
2740
3721
  raw?: unknown;
2741
3722
  resolvedAgent?: string;
3723
+ preferNode?: string;
2742
3724
  channelMeta?: ChannelMeta;
2743
3725
  }
2744
3726
  interface OutgoingMessage {
@@ -2769,16 +3751,623 @@ interface ChannelAdapter {
2769
3751
  getChannelMeta?(chatId: string): Promise<ChannelMeta | undefined>;
2770
3752
  }
2771
3753
 
3754
+ interface ServiceTrigger {
3755
+ pattern: string;
3756
+ channel?: string;
3757
+ }
3758
+ interface ServiceNotify {
3759
+ channel: string;
3760
+ chatId: string;
3761
+ accountId?: string;
3762
+ }
3763
+ interface ServiceDef {
3764
+ id: string;
3765
+ name: string;
3766
+ triggers: ServiceTrigger[];
3767
+ allowedContacts?: string[];
3768
+ agent: string;
3769
+ prompt: string;
3770
+ schedule?: string;
3771
+ timezone?: string;
3772
+ notify?: ServiceNotify;
3773
+ }
3774
+ interface ServiceMatch {
3775
+ service: ServiceDef;
3776
+ trigger: string;
3777
+ captured: string;
3778
+ }
3779
+ declare class ServiceMatcher {
3780
+ private services;
3781
+ private log;
3782
+ constructor(serviceDefs: Record<string, Omit<ServiceDef, "id">>, log?: (...args: unknown[]) => void);
3783
+ /**
3784
+ * Match an incoming message against all service triggers.
3785
+ * Returns the first matching service or null.
3786
+ */
3787
+ match(text: string, senderId: string, channel: string): ServiceMatch | null;
3788
+ /**
3789
+ * Execute a matched service.
3790
+ * Sends the service's predefined prompt to the agent, returns the response.
3791
+ */
3792
+ execute(service: ServiceDef, registry: AgentRegistry, context: {
3793
+ channel: string;
3794
+ sender: string;
3795
+ chatId: string;
3796
+ }, replyFn: (text: string) => Promise<void>): Promise<void>;
3797
+ /**
3798
+ * Get all services that have a schedule (for cron registration).
3799
+ */
3800
+ getScheduledServices(): ServiceDef[];
3801
+ /**
3802
+ * List all registered services.
3803
+ */
3804
+ list(): Array<{
3805
+ id: string;
3806
+ name: string;
3807
+ triggers: number;
3808
+ agent: string;
3809
+ scheduled: boolean;
3810
+ }>;
3811
+ }
3812
+
3813
+ declare const roleSchema: z.ZodObject<{
3814
+ title: z.ZodString;
3815
+ responsibilities: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
3816
+ sopPath: z.ZodOptional<z.ZodString>;
3817
+ kpis: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
3818
+ }, "strip", z.ZodTypeAny, {
3819
+ title: string;
3820
+ responsibilities: string[];
3821
+ kpis: string[];
3822
+ sopPath?: string | undefined;
3823
+ }, {
3824
+ title: string;
3825
+ responsibilities?: string[] | undefined;
3826
+ sopPath?: string | undefined;
3827
+ kpis?: string[] | undefined;
3828
+ }>;
3829
+ declare const orgEntrySchema: z.ZodObject<{
3830
+ role: z.ZodString;
3831
+ reportsTo: z.ZodOptional<z.ZodString>;
3832
+ schedule: z.ZodObject<{
3833
+ days: z.ZodDefault<z.ZodArray<z.ZodEnum<["mon", "tue", "wed", "thu", "fri", "sat", "sun"]>, "many">>;
3834
+ start: z.ZodString;
3835
+ end: z.ZodString;
3836
+ lunch: z.ZodOptional<z.ZodObject<{
3837
+ start: z.ZodString;
3838
+ end: z.ZodString;
3839
+ }, "strip", z.ZodTypeAny, {
3840
+ end: string;
3841
+ start: string;
3842
+ }, {
3843
+ end: string;
3844
+ start: string;
3845
+ }>>;
3846
+ }, "strip", z.ZodTypeAny, {
3847
+ end: string;
3848
+ days: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[];
3849
+ start: string;
3850
+ lunch?: {
3851
+ end: string;
3852
+ start: string;
3853
+ } | undefined;
3854
+ }, {
3855
+ end: string;
3856
+ start: string;
3857
+ days?: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[] | undefined;
3858
+ lunch?: {
3859
+ end: string;
3860
+ start: string;
3861
+ } | undefined;
3862
+ }>;
3863
+ utilizationTarget: z.ZodDefault<z.ZodNumber>;
3864
+ }, "strip", z.ZodTypeAny, {
3865
+ role: string;
3866
+ schedule: {
3867
+ end: string;
3868
+ days: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[];
3869
+ start: string;
3870
+ lunch?: {
3871
+ end: string;
3872
+ start: string;
3873
+ } | undefined;
3874
+ };
3875
+ utilizationTarget: number;
3876
+ reportsTo?: string | undefined;
3877
+ }, {
3878
+ role: string;
3879
+ schedule: {
3880
+ end: string;
3881
+ start: string;
3882
+ days?: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[] | undefined;
3883
+ lunch?: {
3884
+ end: string;
3885
+ start: string;
3886
+ } | undefined;
3887
+ };
3888
+ reportsTo?: string | undefined;
3889
+ utilizationTarget?: number | undefined;
3890
+ }>;
3891
+ declare const businessConfigSchema: z.ZodObject<{
3892
+ enabled: z.ZodDefault<z.ZodBoolean>;
3893
+ timezone: z.ZodDefault<z.ZodString>;
3894
+ mainChannel: z.ZodObject<{
3895
+ channel: z.ZodString;
3896
+ chatId: z.ZodString;
3897
+ accountId: z.ZodOptional<z.ZodString>;
3898
+ }, "strip", z.ZodTypeAny, {
3899
+ channel: string;
3900
+ chatId: string;
3901
+ accountId?: string | undefined;
3902
+ }, {
3903
+ channel: string;
3904
+ chatId: string;
3905
+ accountId?: string | undefined;
3906
+ }>;
3907
+ workSource: z.ZodDiscriminatedUnion<"type", [z.ZodObject<{
3908
+ type: z.ZodLiteral<"backlog">;
3909
+ path: z.ZodDefault<z.ZodString>;
3910
+ }, "strip", z.ZodTypeAny, {
3911
+ path: string;
3912
+ type: "backlog";
3913
+ }, {
3914
+ type: "backlog";
3915
+ path?: string | undefined;
3916
+ }>, z.ZodObject<{
3917
+ type: z.ZodLiteral<"gitlab">;
3918
+ projects: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
3919
+ }, "strip", z.ZodTypeAny, {
3920
+ type: "gitlab";
3921
+ projects: string[];
3922
+ }, {
3923
+ type: "gitlab";
3924
+ projects?: string[] | undefined;
3925
+ }>, z.ZodObject<{
3926
+ type: z.ZodLiteral<"wiki">;
3927
+ path: z.ZodString;
3928
+ glob: z.ZodDefault<z.ZodString>;
3929
+ }, "strip", z.ZodTypeAny, {
3930
+ path: string;
3931
+ type: "wiki";
3932
+ glob: string;
3933
+ }, {
3934
+ path: string;
3935
+ type: "wiki";
3936
+ glob?: string | undefined;
3937
+ }>]>;
3938
+ roles: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
3939
+ title: z.ZodString;
3940
+ responsibilities: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
3941
+ sopPath: z.ZodOptional<z.ZodString>;
3942
+ kpis: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
3943
+ }, "strip", z.ZodTypeAny, {
3944
+ title: string;
3945
+ responsibilities: string[];
3946
+ kpis: string[];
3947
+ sopPath?: string | undefined;
3948
+ }, {
3949
+ title: string;
3950
+ responsibilities?: string[] | undefined;
3951
+ sopPath?: string | undefined;
3952
+ kpis?: string[] | undefined;
3953
+ }>>>;
3954
+ orgChart: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
3955
+ role: z.ZodString;
3956
+ reportsTo: z.ZodOptional<z.ZodString>;
3957
+ schedule: z.ZodObject<{
3958
+ days: z.ZodDefault<z.ZodArray<z.ZodEnum<["mon", "tue", "wed", "thu", "fri", "sat", "sun"]>, "many">>;
3959
+ start: z.ZodString;
3960
+ end: z.ZodString;
3961
+ lunch: z.ZodOptional<z.ZodObject<{
3962
+ start: z.ZodString;
3963
+ end: z.ZodString;
3964
+ }, "strip", z.ZodTypeAny, {
3965
+ end: string;
3966
+ start: string;
3967
+ }, {
3968
+ end: string;
3969
+ start: string;
3970
+ }>>;
3971
+ }, "strip", z.ZodTypeAny, {
3972
+ end: string;
3973
+ days: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[];
3974
+ start: string;
3975
+ lunch?: {
3976
+ end: string;
3977
+ start: string;
3978
+ } | undefined;
3979
+ }, {
3980
+ end: string;
3981
+ start: string;
3982
+ days?: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[] | undefined;
3983
+ lunch?: {
3984
+ end: string;
3985
+ start: string;
3986
+ } | undefined;
3987
+ }>;
3988
+ utilizationTarget: z.ZodDefault<z.ZodNumber>;
3989
+ }, "strip", z.ZodTypeAny, {
3990
+ role: string;
3991
+ schedule: {
3992
+ end: string;
3993
+ days: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[];
3994
+ start: string;
3995
+ lunch?: {
3996
+ end: string;
3997
+ start: string;
3998
+ } | undefined;
3999
+ };
4000
+ utilizationTarget: number;
4001
+ reportsTo?: string | undefined;
4002
+ }, {
4003
+ role: string;
4004
+ schedule: {
4005
+ end: string;
4006
+ start: string;
4007
+ days?: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[] | undefined;
4008
+ lunch?: {
4009
+ end: string;
4010
+ start: string;
4011
+ } | undefined;
4012
+ };
4013
+ reportsTo?: string | undefined;
4014
+ utilizationTarget?: number | undefined;
4015
+ }>>>;
4016
+ /** Work-tick cadence in minutes during business hours. Default 15. */
4017
+ workTickMinutes: z.ZodDefault<z.ZodNumber>;
4018
+ /** Max queue depth for an idle agent before skipping the work tick (avoids piling up). */
4019
+ idleQueueThreshold: z.ZodDefault<z.ZodNumber>;
4020
+ }, "strip", z.ZodTypeAny, {
4021
+ enabled: boolean;
4022
+ timezone: string;
4023
+ mainChannel: {
4024
+ channel: string;
4025
+ chatId: string;
4026
+ accountId?: string | undefined;
4027
+ };
4028
+ workSource: {
4029
+ path: string;
4030
+ type: "backlog";
4031
+ } | {
4032
+ type: "gitlab";
4033
+ projects: string[];
4034
+ } | {
4035
+ path: string;
4036
+ type: "wiki";
4037
+ glob: string;
4038
+ };
4039
+ roles: Record<string, {
4040
+ title: string;
4041
+ responsibilities: string[];
4042
+ kpis: string[];
4043
+ sopPath?: string | undefined;
4044
+ }>;
4045
+ orgChart: Record<string, {
4046
+ role: string;
4047
+ schedule: {
4048
+ end: string;
4049
+ days: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[];
4050
+ start: string;
4051
+ lunch?: {
4052
+ end: string;
4053
+ start: string;
4054
+ } | undefined;
4055
+ };
4056
+ utilizationTarget: number;
4057
+ reportsTo?: string | undefined;
4058
+ }>;
4059
+ workTickMinutes: number;
4060
+ idleQueueThreshold: number;
4061
+ }, {
4062
+ mainChannel: {
4063
+ channel: string;
4064
+ chatId: string;
4065
+ accountId?: string | undefined;
4066
+ };
4067
+ workSource: {
4068
+ type: "backlog";
4069
+ path?: string | undefined;
4070
+ } | {
4071
+ type: "gitlab";
4072
+ projects?: string[] | undefined;
4073
+ } | {
4074
+ path: string;
4075
+ type: "wiki";
4076
+ glob?: string | undefined;
4077
+ };
4078
+ enabled?: boolean | undefined;
4079
+ timezone?: string | undefined;
4080
+ roles?: Record<string, {
4081
+ title: string;
4082
+ responsibilities?: string[] | undefined;
4083
+ sopPath?: string | undefined;
4084
+ kpis?: string[] | undefined;
4085
+ }> | undefined;
4086
+ orgChart?: Record<string, {
4087
+ role: string;
4088
+ schedule: {
4089
+ end: string;
4090
+ start: string;
4091
+ days?: ("mon" | "tue" | "wed" | "thu" | "fri" | "sat" | "sun")[] | undefined;
4092
+ lunch?: {
4093
+ end: string;
4094
+ start: string;
4095
+ } | undefined;
4096
+ };
4097
+ reportsTo?: string | undefined;
4098
+ utilizationTarget?: number | undefined;
4099
+ }> | undefined;
4100
+ workTickMinutes?: number | undefined;
4101
+ idleQueueThreshold?: number | undefined;
4102
+ }>;
4103
+ type BusinessConfig = z.infer<typeof businessConfigSchema>;
4104
+ type BusinessRole = z.infer<typeof roleSchema>;
4105
+ type BusinessOrgEntry = z.infer<typeof orgEntrySchema>;
4106
+
4107
+ interface EmployeeProfile {
4108
+ agentId: string;
4109
+ role: BusinessRole;
4110
+ roleKey: string;
4111
+ reportsTo?: string;
4112
+ schedule: BusinessOrgEntry["schedule"];
4113
+ utilizationTarget: number;
4114
+ }
4115
+ declare class Organization {
4116
+ private employees;
4117
+ constructor(config: BusinessConfig);
4118
+ get(agentId: string): EmployeeProfile | undefined;
4119
+ all(): EmployeeProfile[];
4120
+ reportsTo(agentId: string): string | undefined;
4121
+ directReports(agentId: string): string[];
4122
+ /** Walk up the org tree to the root. First element is `agentId` itself. */
4123
+ chainOfCommand(agentId: string): string[];
4124
+ }
4125
+
4126
+ declare class Schedule {
4127
+ private org;
4128
+ private config;
4129
+ constructor(org: Organization, config: BusinessConfig);
4130
+ isOnClock(agentId: string, when?: Date): boolean;
4131
+ /** Is `when` exactly (to the minute) the scheduled day-start for this agent? */
4132
+ isDayStart(agentId: string, when?: Date): boolean;
4133
+ /** Is `when` exactly the scheduled day-end for this agent? */
4134
+ isDayEnd(agentId: string, when?: Date): boolean;
4135
+ clockedInAgents(when?: Date): string[];
4136
+ }
4137
+
4138
+ interface WorkItem {
4139
+ id: string;
4140
+ title: string;
4141
+ description?: string;
4142
+ assignee?: string;
4143
+ estimatedSeconds?: number;
4144
+ url?: string;
4145
+ priority?: number;
4146
+ /** Board stage derived from labels (kanban column id). */
4147
+ stage?: "triage" | "todo" | "doing" | "onhold" | "review" | "done";
4148
+ /** Raw labels from the source (GitLab). Empty array if source doesn't support labels. */
4149
+ labels?: string[];
4150
+ /** Label name+color when the source returns colored labels (GitLab with_labels_details). */
4151
+ labelDetails?: Array<{
4152
+ name: string;
4153
+ color: string;
4154
+ text_color?: string;
4155
+ }>;
4156
+ /** ISO timestamp of last update on the source. */
4157
+ updatedAt?: string;
4158
+ /** Open/closed state from the source. */
4159
+ state?: "opened" | "closed";
4160
+ /** Optional milestone title (GitLab: issue.milestone.title). */
4161
+ milestone?: string;
4162
+ /** GitLab assignees (0..n). `assignee` above is the agentId alias for assignees[0]. */
4163
+ assignees?: Array<{
4164
+ username: string;
4165
+ name?: string;
4166
+ avatarUrl?: string;
4167
+ }>;
4168
+ }
4169
+ interface WorkReport {
4170
+ status: "in-progress" | "done" | "blocked";
4171
+ note?: string;
4172
+ timeSeconds?: number;
4173
+ blocker?: string;
4174
+ }
4175
+ /** What a WorkSource can do beyond the minimal listOpen/claim/report triple. */
4176
+ interface WorkSourceCapabilities {
4177
+ /** Enumerate items beyond assignee filter — required for a board view. */
4178
+ listAll: boolean;
4179
+ /** Create new items (e.g. POST GitLab issue). */
4180
+ create: boolean;
4181
+ /** Arbitrary column transitions (label add/remove pair). */
4182
+ transition: boolean;
4183
+ /** Surfaces labels[] on returned items. */
4184
+ labels: boolean;
4185
+ /** Server-side text search. */
4186
+ search: boolean;
4187
+ }
4188
+ interface WorkCreateInput {
4189
+ title: string;
4190
+ description?: string;
4191
+ /** agentId */
4192
+ assignee?: string;
4193
+ /** Raw GitLab usernames — bypass agentId resolution for UI-driven creates. */
4194
+ assigneeUsernames?: string[];
4195
+ labels?: string[];
4196
+ /** Milestone title (resolved to id). */
4197
+ milestoneTitle?: string;
4198
+ /** For sources that span multiple projects (gitlab): "group/project". */
4199
+ projectHint?: string;
4200
+ }
4201
+ interface ListAllOpts {
4202
+ sinceDays?: number;
4203
+ labels?: string[];
4204
+ /** Exclude items carrying any of these labels (client-side filter). */
4205
+ notLabels?: string[];
4206
+ /** Exclude items whose labels carry this scoped prefix (e.g. "Status"). */
4207
+ withoutScopedPrefix?: string;
4208
+ search?: string;
4209
+ assignee?: string;
4210
+ /** GitLab issue state. Defaults to "opened" (boards hide closed issues). */
4211
+ state?: "opened" | "closed" | "all";
4212
+ /** Milestone filter (GitLab "milestone" query param). */
4213
+ milestone?: string;
4214
+ }
4215
+ interface WorkSource {
4216
+ type: string;
4217
+ capabilities: WorkSourceCapabilities;
4218
+ listOpen(agentId: string): Promise<WorkItem[]>;
4219
+ claim(agentId: string, itemId: string): Promise<void>;
4220
+ report(itemId: string, update: WorkReport): Promise<void>;
4221
+ /** Optional — gated by capabilities.listAll. */
4222
+ listAll?(opts: ListAllOpts): Promise<WorkItem[]>;
4223
+ /** Optional — gated by capabilities.create. */
4224
+ create?(input: WorkCreateInput): Promise<WorkItem>;
4225
+ /**
4226
+ * Optional — gated by capabilities.transition. Add `toLabel` and remove
4227
+ * `fromLabel` (if provided) from the item. Used by the kanban board on drag.
4228
+ */
4229
+ transition?(itemId: string, toLabel: string, fromLabel?: string): Promise<void>;
4230
+ }
4231
+
4232
+ declare class Reporter {
4233
+ private router;
4234
+ private org;
4235
+ private config;
4236
+ private log;
4237
+ constructor(router: MessageRouter, org: Organization, config: BusinessConfig, log: (...args: unknown[]) => void);
4238
+ postToMain(text: string, agentId?: string): Promise<void>;
4239
+ /** Post an escalation message up the chain of command. */
4240
+ escalate(fromAgent: string, subject: string, detail: string): Promise<void>;
4241
+ }
4242
+
4243
+ interface DailyStats {
4244
+ date: string;
4245
+ perAgent: Record<string, {
4246
+ tasksCompleted: number;
4247
+ timeLoggedSeconds: number;
4248
+ onClockSeconds: number;
4249
+ blockers: number;
4250
+ utilization: number;
4251
+ }>;
4252
+ }
4253
+ interface TaskCompletion {
4254
+ agentId: string;
4255
+ durationSeconds: number;
4256
+ success: boolean;
4257
+ channel?: string;
4258
+ }
4259
+ declare class KPI {
4260
+ private org;
4261
+ private schedule;
4262
+ private log;
4263
+ private stats;
4264
+ private dir;
4265
+ private onClockTick;
4266
+ constructor(org: Organization, schedule: Schedule, log: (...args: unknown[]) => void);
4267
+ private loadOrInit;
4268
+ /** Called by the day-cycle minute tick to accumulate on-clock time. */
4269
+ tick(): void;
4270
+ recordTaskCompletion(t: TaskCompletion): void;
4271
+ recordBlocker(agentId: string): void;
4272
+ private recomputeUtil;
4273
+ private persist;
4274
+ flush(): void;
4275
+ snapshot(): DailyStats;
4276
+ /** Markdown summary for end-of-day main-channel post. */
4277
+ dailySummaryText(): string;
4278
+ }
4279
+
4280
+ declare class DayCycle {
4281
+ private config;
4282
+ private org;
4283
+ private schedule;
4284
+ private registry;
4285
+ private reporter;
4286
+ private kpi;
4287
+ private workSource;
4288
+ private daemonBase;
4289
+ private log;
4290
+ private timer?;
4291
+ private day;
4292
+ private currentDate;
4293
+ private runningTask;
4294
+ constructor(config: BusinessConfig, org: Organization, schedule: Schedule, registry: AgentRegistry, reporter: Reporter, kpi: KPI, workSource: WorkSource, daemonBase: string, log: (...args: unknown[]) => void);
4295
+ start(): void;
4296
+ stop(): void;
4297
+ private tick;
4298
+ private roleContext;
4299
+ private runLifecycle;
4300
+ private fireStandup;
4301
+ private fireWorkTick;
4302
+ private fireWrap;
4303
+ }
4304
+
4305
+ /**
4306
+ * Business layer facade — constructed once by the daemon when
4307
+ * config.business?.enabled is true.
4308
+ */
4309
+ declare class BusinessLayer {
4310
+ readonly org: Organization;
4311
+ readonly schedule: Schedule;
4312
+ readonly workSource: WorkSource;
4313
+ readonly reporter: Reporter;
4314
+ readonly kpi: KPI;
4315
+ readonly dayCycle: DayCycle;
4316
+ constructor(business: BusinessConfig, daemon: DaemonConfig, registry: AgentRegistry, router: MessageRouter, log: (...args: unknown[]) => void);
4317
+ start(): void;
4318
+ stop(): void;
4319
+ /** Record a task completion (called by router when an agent finishes a task). */
4320
+ recordTaskCompletion(agentId: string, durationSeconds: number, success: boolean, channel?: string): void;
4321
+ handleHttp(route: string, req: IncomingMessage$1, res: ServerResponse): Promise<boolean>;
4322
+ /** Short startup banner line. */
4323
+ summary(): string;
4324
+ }
4325
+
2772
4326
  declare class MessageRouter {
2773
4327
  private registry;
2774
4328
  private config;
2775
4329
  private channels;
2776
4330
  private hooks?;
2777
4331
  private mesh?;
4332
+ private serviceMatcher?;
4333
+ private business?;
2778
4334
  private groupLog;
2779
4335
  private log;
4336
+ /**
4337
+ * Short-TTL cache of recently processed incoming message IDs, keyed by
4338
+ * `<channel>:<accountId>:<id>`. Prevents duplicate replies from:
4339
+ * - GitLab webhook retries (same object_attributes.id redelivered)
4340
+ * - WhatsApp Baileys double-emitting messages.upsert (notify + append)
4341
+ * - Telegram polling re-delivering an update after a long-poll hiccup
4342
+ * - A daemon crash-loop replaying messages the previous process had
4343
+ * already handled (fixed by persisting this map to disk — see below)
4344
+ *
4345
+ * The key INCLUDES accountId so two bots in the same Telegram group
4346
+ * (different accountId) both get to run their routing logic — the router's
4347
+ * downstream boundAccount check then picks the one bot that should actually
4348
+ * reply. Without accountId in the key, the second bot's legitimate view of
4349
+ * the same Telegram message_id would be wrongly suppressed.
4350
+ *
4351
+ * Persisted to .agentx/router/dedup.json so survival-across-restart is not
4352
+ * just a Telegram concern — the same universal LRU covers every channel.
4353
+ * Writes are debounced (every 20 new ids, or 5s, whichever first) and the
4354
+ * file is pruned to only live TTL entries before each write.
4355
+ */
4356
+ private recentMessageIds;
4357
+ private readonly MESSAGE_ID_TTL_MS;
4358
+ private readonly MESSAGE_ID_MAX_ENTRIES;
4359
+ private readonly DEDUP_STORE_PATH;
4360
+ private dedupDirtyCount;
4361
+ private dedupSaveTimer?;
2780
4362
  constructor(registry: AgentRegistry, config: DaemonConfig, hooks?: HookRegistry, log?: (...args: unknown[]) => void);
4363
+ private loadDedupFromDisk;
4364
+ private scheduleDedupSave;
4365
+ private flushDedupToDisk;
4366
+ /** Called by the daemon on graceful shutdown so no in-memory ids are lost. */
4367
+ flushPersistence(): void;
2781
4368
  setMesh(mesh: A2AMesh): void;
4369
+ setServiceMatcher(matcher: ServiceMatcher): void;
4370
+ setBusiness(business: BusinessLayer): void;
2782
4371
  addChannel(adapter: ChannelAdapter): void;
2783
4372
  /**
2784
4373
  * Send an outbound message to any registered channel.
@@ -2793,6 +4382,11 @@ declare class MessageRouter {
2793
4382
  getChannelNames(): string[];
2794
4383
  startAll(): Promise<void>;
2795
4384
  stopAll(): Promise<void>;
4385
+ /**
4386
+ * Returns true if this message id was processed within MESSAGE_ID_TTL_MS.
4387
+ * Stamps the key when false. Size-bounded GC avoids unbounded growth.
4388
+ */
4389
+ private isDuplicateMessage;
2796
4390
  private handleMessage;
2797
4391
  private static readonly MAX_BOT_CHAIN_DEPTH;
2798
4392
  /**
@@ -2812,6 +4406,16 @@ declare class MessageRouter {
2812
4406
  * Searches peer agent cards for mention matches.
2813
4407
  */
2814
4408
  private handleViaMesh;
4409
+ /**
4410
+ * Route to a mesh peer by resolved agentId (not text matching).
4411
+ * Used when the channel adapter resolved the agent but it's not local.
4412
+ */
4413
+ private handleViaMeshByAgentId;
4414
+ /**
4415
+ * Route to a specific named mesh peer by agentId.
4416
+ * Used when preferNode is set on the incoming message.
4417
+ */
4418
+ private handleViaMeshByPeer;
2815
4419
  private getAccountForAgent;
2816
4420
  private resolveAgent;
2817
4421
  }
@@ -2823,7 +4427,7 @@ interface TelegramAccountConfig {
2823
4427
  declare class TelegramAdapter implements ChannelAdapter {
2824
4428
  readonly name = "telegram";
2825
4429
  private accounts;
2826
- private offsets;
4430
+ private offsetStore;
2827
4431
  private handler?;
2828
4432
  private polling;
2829
4433
  private log;
@@ -2926,7 +4530,12 @@ interface CronJobState {
2926
4530
  prompt: string;
2927
4531
  timeout: number;
2928
4532
  model?: string;
2929
- onError: "log" | "notify" | "disable";
4533
+ /** Soft output-length cap appended to the prompt at invocation time.
4534
+ * Claude Code CLI has no hard flag for this, so we instruct the model
4535
+ * via the prompt tail; reliably honored and keeps cache-hit intact
4536
+ * (hint text is per-job, not per-run). */
4537
+ maxOutputTokens?: number;
4538
+ onError: Array<"log" | "notify" | "disable">;
2930
4539
  lastRun?: Date;
2931
4540
  nextRun?: Date;
2932
4541
  lastSuccess?: Date;