botinabox 2.5.2 → 2.6.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 (277) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +190 -190
  3. package/bin/botinabox.mjs +1 -1
  4. package/dist/{chunk-UACT2WXX.js → chunk-7AGWGYZC.js} +43 -5
  5. package/dist/cli.js +1 -1
  6. package/dist/connectors/google/index.d.ts +10 -1
  7. package/dist/connectors/google/index.js +1 -1
  8. package/dist/{gmail-connector-2FVYTQJH.js → gmail-connector-VP5FF56J.js} +2 -1
  9. package/dist/index.d.ts +64 -1
  10. package/dist/index.js +44 -10
  11. package/package.json +100 -100
  12. package/dist/channels/discord/adapter.d.ts +0 -32
  13. package/dist/channels/discord/adapter.js +0 -70
  14. package/dist/channels/discord/inbound.d.ts +0 -25
  15. package/dist/channels/discord/inbound.js +0 -24
  16. package/dist/channels/discord/models.d.ts +0 -8
  17. package/dist/channels/discord/models.js +0 -5
  18. package/dist/channels/discord/outbound.d.ts +0 -14
  19. package/dist/channels/discord/outbound.js +0 -38
  20. package/dist/channels/slack/adapter.d.ts +0 -33
  21. package/dist/channels/slack/adapter.js +0 -74
  22. package/dist/channels/slack/inbound.d.ts +0 -59
  23. package/dist/channels/slack/inbound.js +0 -96
  24. package/dist/channels/slack/models.d.ts +0 -9
  25. package/dist/channels/slack/models.js +0 -5
  26. package/dist/channels/slack/outbound.d.ts +0 -12
  27. package/dist/channels/slack/outbound.js +0 -18
  28. package/dist/channels/slack/transcribe.d.ts +0 -41
  29. package/dist/channels/slack/transcribe.js +0 -106
  30. package/dist/channels/webhook/adapter.d.ts +0 -23
  31. package/dist/channels/webhook/adapter.js +0 -86
  32. package/dist/channels/webhook/hmac.d.ts +0 -13
  33. package/dist/channels/webhook/hmac.js +0 -26
  34. package/dist/channels/webhook/models.d.ts +0 -9
  35. package/dist/channels/webhook/models.js +0 -5
  36. package/dist/channels/webhook/server.d.ts +0 -20
  37. package/dist/channels/webhook/server.js +0 -91
  38. package/dist/chat-pipeline-C-XlLGNl.d.ts +0 -648
  39. package/dist/chat-pipeline-CR1KF6eX.d.ts +0 -652
  40. package/dist/chat-pipeline-DisuC8SB.d.ts +0 -643
  41. package/dist/chunk-2LGXQPEA.js +0 -41
  42. package/dist/chunk-3X3YKI4T.js +0 -357
  43. package/dist/chunk-D47AIFOD.js +0 -351
  44. package/dist/chunk-DSNJKNEW.js +0 -328
  45. package/dist/chunk-GS2JFL6I.js +0 -144
  46. package/dist/chunk-J6S6QMUY.js +0 -144
  47. package/dist/chunk-QLA6YOFN.js +0 -22
  48. package/dist/cli/templates/config.yml.d.ts +0 -7
  49. package/dist/cli/templates/config.yml.js +0 -61
  50. package/dist/cli/templates/env.d.ts +0 -1
  51. package/dist/cli/templates/env.js +0 -30
  52. package/dist/cli/templates/index.ts.d.ts +0 -2
  53. package/dist/cli/templates/index.ts.js +0 -30
  54. package/dist/cli/templates/package.json.d.ts +0 -5
  55. package/dist/cli/templates/package.json.js +0 -28
  56. package/dist/connector-DDahQw-2.d.ts +0 -63
  57. package/dist/connectors/google/calendar-connector.d.ts +0 -40
  58. package/dist/connectors/google/calendar-connector.js +0 -243
  59. package/dist/connectors/google/gmail-connector.d.ts +0 -42
  60. package/dist/connectors/google/gmail-connector.js +0 -345
  61. package/dist/connectors/google/oauth.d.ts +0 -48
  62. package/dist/connectors/google/oauth.js +0 -112
  63. package/dist/connectors/google/types.d.ts +0 -78
  64. package/dist/connectors/google/types.js +0 -2
  65. package/dist/core/chat/auto-discovery.d.ts +0 -16
  66. package/dist/core/chat/auto-discovery.js +0 -54
  67. package/dist/core/chat/channel-registry.d.ts +0 -45
  68. package/dist/core/chat/channel-registry.js +0 -96
  69. package/dist/core/chat/chat-pipeline.d.ts +0 -113
  70. package/dist/core/chat/chat-pipeline.js +0 -395
  71. package/dist/core/chat/chat-responder.d.ts +0 -90
  72. package/dist/core/chat/chat-responder.js +0 -185
  73. package/dist/core/chat/formatter.d.ts +0 -11
  74. package/dist/core/chat/formatter.js +0 -60
  75. package/dist/core/chat/index.d.ts +0 -24
  76. package/dist/core/chat/index.js +0 -18
  77. package/dist/core/chat/message-interpreter.d.ts +0 -91
  78. package/dist/core/chat/message-interpreter.js +0 -166
  79. package/dist/core/chat/message-store.d.ts +0 -66
  80. package/dist/core/chat/message-store.js +0 -131
  81. package/dist/core/chat/notification-queue.d.ts +0 -34
  82. package/dist/core/chat/notification-queue.js +0 -111
  83. package/dist/core/chat/pipeline.d.ts +0 -38
  84. package/dist/core/chat/pipeline.js +0 -89
  85. package/dist/core/chat/policies.d.ts +0 -16
  86. package/dist/core/chat/policies.js +0 -25
  87. package/dist/core/chat/routing.d.ts +0 -17
  88. package/dist/core/chat/routing.js +0 -36
  89. package/dist/core/chat/session-key.d.ts +0 -30
  90. package/dist/core/chat/session-key.js +0 -65
  91. package/dist/core/chat/session-manager.d.ts +0 -17
  92. package/dist/core/chat/session-manager.js +0 -23
  93. package/dist/core/chat/text-chunker.d.ts +0 -9
  94. package/dist/core/chat/text-chunker.js +0 -48
  95. package/dist/core/chat/triage-router.d.ts +0 -75
  96. package/dist/core/chat/triage-router.js +0 -142
  97. package/dist/core/chat/types.d.ts +0 -5
  98. package/dist/core/chat/types.js +0 -5
  99. package/dist/core/config/defaults.d.ts +0 -2
  100. package/dist/core/config/defaults.js +0 -38
  101. package/dist/core/config/index.d.ts +0 -6
  102. package/dist/core/config/index.js +0 -4
  103. package/dist/core/config/interpolate.d.ts +0 -5
  104. package/dist/core/config/interpolate.js +0 -27
  105. package/dist/core/config/loader.d.ts +0 -24
  106. package/dist/core/config/loader.js +0 -59
  107. package/dist/core/config/schema.d.ts +0 -5
  108. package/dist/core/config/schema.js +0 -119
  109. package/dist/core/data/core-entity-contexts.d.ts +0 -14
  110. package/dist/core/data/core-entity-contexts.js +0 -197
  111. package/dist/core/data/core-migrations.d.ts +0 -5
  112. package/dist/core/data/core-migrations.js +0 -45
  113. package/dist/core/data/core-schema.d.ts +0 -6
  114. package/dist/core/data/core-schema.js +0 -454
  115. package/dist/core/data/data-store.d.ts +0 -67
  116. package/dist/core/data/data-store.js +0 -218
  117. package/dist/core/data/domain-entity-contexts.d.ts +0 -29
  118. package/dist/core/data/domain-entity-contexts.js +0 -321
  119. package/dist/core/data/domain-schema.d.ts +0 -36
  120. package/dist/core/data/domain-schema.js +0 -323
  121. package/dist/core/data/index.d.ts +0 -7
  122. package/dist/core/data/index.js +0 -7
  123. package/dist/core/data/types.d.ts +0 -111
  124. package/dist/core/data/types.js +0 -1
  125. package/dist/core/hooks/hook-bus.d.ts +0 -18
  126. package/dist/core/hooks/hook-bus.js +0 -120
  127. package/dist/core/hooks/index.d.ts +0 -2
  128. package/dist/core/hooks/index.js +0 -1
  129. package/dist/core/hooks/types.d.ts +0 -19
  130. package/dist/core/hooks/types.js +0 -1
  131. package/dist/core/index.d.ts +0 -4
  132. package/dist/core/index.js +0 -4
  133. package/dist/core/llm/auto-discovery.d.ts +0 -11
  134. package/dist/core/llm/auto-discovery.js +0 -49
  135. package/dist/core/llm/cost-tracker.d.ts +0 -6
  136. package/dist/core/llm/cost-tracker.js +0 -38
  137. package/dist/core/llm/index.d.ts +0 -4
  138. package/dist/core/llm/index.js +0 -3
  139. package/dist/core/llm/model-router.d.ts +0 -25
  140. package/dist/core/llm/model-router.js +0 -49
  141. package/dist/core/llm/provider-registry.d.ts +0 -9
  142. package/dist/core/llm/provider-registry.js +0 -25
  143. package/dist/core/llm/types.d.ts +0 -2
  144. package/dist/core/llm/types.js +0 -2
  145. package/dist/core/orchestrator/adapters/api-adapter.d.ts +0 -34
  146. package/dist/core/orchestrator/adapters/api-adapter.js +0 -88
  147. package/dist/core/orchestrator/adapters/cli-adapter.d.ts +0 -22
  148. package/dist/core/orchestrator/adapters/cli-adapter.js +0 -69
  149. package/dist/core/orchestrator/adapters/deterministic-adapter.d.ts +0 -35
  150. package/dist/core/orchestrator/adapters/deterministic-adapter.js +0 -75
  151. package/dist/core/orchestrator/adapters/env-whitelist.d.ts +0 -4
  152. package/dist/core/orchestrator/adapters/env-whitelist.js +0 -27
  153. package/dist/core/orchestrator/adapters/output-extractor.d.ts +0 -11
  154. package/dist/core/orchestrator/adapters/output-extractor.js +0 -59
  155. package/dist/core/orchestrator/adapters/process-manager.d.ts +0 -15
  156. package/dist/core/orchestrator/adapters/process-manager.js +0 -26
  157. package/dist/core/orchestrator/adapters/tool-loop.d.ts +0 -22
  158. package/dist/core/orchestrator/adapters/tool-loop.js +0 -66
  159. package/dist/core/orchestrator/agent-registry.d.ts +0 -31
  160. package/dist/core/orchestrator/agent-registry.js +0 -135
  161. package/dist/core/orchestrator/budget-controller.d.ts +0 -19
  162. package/dist/core/orchestrator/budget-controller.js +0 -73
  163. package/dist/core/orchestrator/chain-guard.d.ts +0 -14
  164. package/dist/core/orchestrator/chain-guard.js +0 -23
  165. package/dist/core/orchestrator/circuit-breaker.d.ts +0 -65
  166. package/dist/core/orchestrator/circuit-breaker.js +0 -159
  167. package/dist/core/orchestrator/claude-stream-parser.d.ts +0 -31
  168. package/dist/core/orchestrator/claude-stream-parser.js +0 -99
  169. package/dist/core/orchestrator/config-revisions.d.ts +0 -6
  170. package/dist/core/orchestrator/config-revisions.js +0 -17
  171. package/dist/core/orchestrator/dependency-resolver.d.ts +0 -20
  172. package/dist/core/orchestrator/dependency-resolver.js +0 -78
  173. package/dist/core/orchestrator/governance-gate.d.ts +0 -110
  174. package/dist/core/orchestrator/governance-gate.js +0 -170
  175. package/dist/core/orchestrator/learning-pipeline.d.ts +0 -109
  176. package/dist/core/orchestrator/learning-pipeline.js +0 -249
  177. package/dist/core/orchestrator/loop-detector.d.ts +0 -51
  178. package/dist/core/orchestrator/loop-detector.js +0 -133
  179. package/dist/core/orchestrator/ndjson-logger.d.ts +0 -6
  180. package/dist/core/orchestrator/ndjson-logger.js +0 -18
  181. package/dist/core/orchestrator/permission-relay.d.ts +0 -72
  182. package/dist/core/orchestrator/permission-relay.js +0 -164
  183. package/dist/core/orchestrator/run-manager.d.ts +0 -31
  184. package/dist/core/orchestrator/run-manager.js +0 -178
  185. package/dist/core/orchestrator/scheduler.d.ts +0 -70
  186. package/dist/core/orchestrator/scheduler.js +0 -198
  187. package/dist/core/orchestrator/secret-store.d.ts +0 -57
  188. package/dist/core/orchestrator/secret-store.js +0 -171
  189. package/dist/core/orchestrator/session-manager.d.ts +0 -13
  190. package/dist/core/orchestrator/session-manager.js +0 -66
  191. package/dist/core/orchestrator/task-queue.d.ts +0 -34
  192. package/dist/core/orchestrator/task-queue.js +0 -83
  193. package/dist/core/orchestrator/template-interpolate.d.ts +0 -5
  194. package/dist/core/orchestrator/template-interpolate.js +0 -18
  195. package/dist/core/orchestrator/user-registry.d.ts +0 -47
  196. package/dist/core/orchestrator/user-registry.js +0 -76
  197. package/dist/core/orchestrator/wakeup-queue.d.ts +0 -9
  198. package/dist/core/orchestrator/wakeup-queue.js +0 -45
  199. package/dist/core/orchestrator/workflow-engine.d.ts +0 -47
  200. package/dist/core/orchestrator/workflow-engine.js +0 -204
  201. package/dist/core/security/audit.d.ts +0 -20
  202. package/dist/core/security/audit.js +0 -33
  203. package/dist/core/security/column-validator.d.ts +0 -20
  204. package/dist/core/security/column-validator.js +0 -37
  205. package/dist/core/security/index.d.ts +0 -5
  206. package/dist/core/security/index.js +0 -5
  207. package/dist/core/security/process-env.d.ts +0 -13
  208. package/dist/core/security/process-env.js +0 -49
  209. package/dist/core/security/sanitizer.d.ts +0 -11
  210. package/dist/core/security/sanitizer.js +0 -39
  211. package/dist/core/security/types.d.ts +0 -11
  212. package/dist/core/security/types.js +0 -1
  213. package/dist/core/update/auto-update.d.ts +0 -21
  214. package/dist/core/update/auto-update.js +0 -102
  215. package/dist/core/update/backup-manager.d.ts +0 -7
  216. package/dist/core/update/backup-manager.js +0 -24
  217. package/dist/core/update/index.d.ts +0 -8
  218. package/dist/core/update/index.js +0 -6
  219. package/dist/core/update/migration-hooks.d.ts +0 -11
  220. package/dist/core/update/migration-hooks.js +0 -10
  221. package/dist/core/update/types.d.ts +0 -11
  222. package/dist/core/update/types.js +0 -1
  223. package/dist/core/update/update-checker.d.ts +0 -11
  224. package/dist/core/update/update-checker.js +0 -63
  225. package/dist/core/update/update-manager.d.ts +0 -25
  226. package/dist/core/update/update-manager.js +0 -101
  227. package/dist/core/update/version-utils.d.ts +0 -6
  228. package/dist/core/update/version-utils.js +0 -34
  229. package/dist/gmail-connector-MNUBRNFM.js +0 -6
  230. package/dist/gmail-connector-PS2VLGNE.js +0 -6
  231. package/dist/gmail-connector-ULSMN6X2.js +0 -6
  232. package/dist/gmail-connector-URRFX6A3.js +0 -6
  233. package/dist/inbound-AFBUPSPG.js +0 -10
  234. package/dist/inbound-AFOHYNUY.js +0 -6
  235. package/dist/inbound-CGIXRXGC.js +0 -8
  236. package/dist/inbound-MCOLRH6U.js +0 -10
  237. package/dist/inbound-SNEMBLGA.js +0 -6
  238. package/dist/inbound-ZJHAYVMF.js +0 -10
  239. package/dist/provider-qqJYv9nv.d.ts +0 -75
  240. package/dist/providers/anthropic/models.d.ts +0 -2
  241. package/dist/providers/anthropic/models.js +0 -29
  242. package/dist/providers/anthropic/provider.d.ts +0 -13
  243. package/dist/providers/anthropic/provider.js +0 -119
  244. package/dist/providers/anthropic/tool-converter.d.ts +0 -10
  245. package/dist/providers/anthropic/tool-converter.js +0 -7
  246. package/dist/providers/ollama/provider.d.ts +0 -17
  247. package/dist/providers/ollama/provider.js +0 -185
  248. package/dist/providers/openai/models.d.ts +0 -2
  249. package/dist/providers/openai/models.js +0 -29
  250. package/dist/providers/openai/provider.d.ts +0 -13
  251. package/dist/providers/openai/provider.js +0 -163
  252. package/dist/providers/openai/tool-converter.d.ts +0 -10
  253. package/dist/providers/openai/tool-converter.js +0 -10
  254. package/dist/shared/constants.d.ts +0 -50
  255. package/dist/shared/constants.js +0 -64
  256. package/dist/shared/index.d.ts +0 -14
  257. package/dist/shared/index.js +0 -14
  258. package/dist/shared/types/agent.d.ts +0 -36
  259. package/dist/shared/types/agent.js +0 -2
  260. package/dist/shared/types/channel.d.ts +0 -70
  261. package/dist/shared/types/channel.js +0 -2
  262. package/dist/shared/types/config.d.ts +0 -111
  263. package/dist/shared/types/config.js +0 -2
  264. package/dist/shared/types/connector.d.ts +0 -77
  265. package/dist/shared/types/connector.js +0 -2
  266. package/dist/shared/types/execution.d.ts +0 -29
  267. package/dist/shared/types/execution.js +0 -2
  268. package/dist/shared/types/provider.d.ts +0 -73
  269. package/dist/shared/types/provider.js +0 -2
  270. package/dist/shared/types/task.d.ts +0 -47
  271. package/dist/shared/types/task.js +0 -2
  272. package/dist/shared/types/workflow.d.ts +0 -39
  273. package/dist/shared/types/workflow.js +0 -2
  274. package/dist/shared/utils.d.ts +0 -6
  275. package/dist/shared/utils.js +0 -13
  276. package/dist/update-check.d.ts +0 -5
  277. package/dist/update-check.js +0 -56
@@ -1,171 +0,0 @@
1
- import { v4 as uuidv4 } from "uuid";
2
- import { scryptSync, createCipheriv, createDecipheriv, randomBytes } from "node:crypto";
3
- const ENC_PREFIX = "enc:";
4
- const ALGORITHM = "aes-256-gcm";
5
- const IV_LEN = 12;
6
- const TAG_LEN = 16;
7
- function deriveEncKey(masterKey) {
8
- return scryptSync(masterKey, "botinabox-secrets-v1", 32);
9
- }
10
- function encryptValue(plaintext, key) {
11
- const iv = randomBytes(IV_LEN);
12
- const cipher = createCipheriv(ALGORITHM, key, iv);
13
- const encrypted = Buffer.concat([cipher.update(plaintext, "utf8"), cipher.final()]);
14
- const tag = cipher.getAuthTag();
15
- return ENC_PREFIX + Buffer.concat([iv, tag, encrypted]).toString("base64");
16
- }
17
- function decryptValue(ciphertext, key) {
18
- if (!ciphertext.startsWith(ENC_PREFIX))
19
- return ciphertext; // plaintext passthrough for migration
20
- const buf = Buffer.from(ciphertext.slice(ENC_PREFIX.length), "base64");
21
- const iv = buf.subarray(0, IV_LEN);
22
- const tag = buf.subarray(IV_LEN, IV_LEN + TAG_LEN);
23
- const data = buf.subarray(IV_LEN + TAG_LEN);
24
- const decipher = createDecipheriv(ALGORITHM, key, iv);
25
- decipher.setAuthTag(tag);
26
- return decipher.update(data).toString("utf8") + decipher.final("utf8");
27
- }
28
- export class SecretStore {
29
- db;
30
- hooks;
31
- encKey;
32
- /**
33
- * @param db - DataStore instance
34
- * @param hooks - HookBus instance
35
- * @param encryptionKey - Optional master key for encrypting secrets at rest.
36
- * When provided, all new secrets are encrypted with AES-256-GCM.
37
- * Existing plaintext secrets are read transparently (passthrough on decrypt).
38
- */
39
- constructor(db, hooks, encryptionKey) {
40
- this.db = db;
41
- this.hooks = hooks;
42
- this.encKey = encryptionKey ? deriveEncKey(encryptionKey) : null;
43
- }
44
- async set(input) {
45
- const id = uuidv4();
46
- const data = { ...input, id };
47
- if (this.encKey && data.value) {
48
- data.value = encryptValue(data.value, this.encKey);
49
- }
50
- await this.db.insert("secrets", data);
51
- await this.hooks.emit("secret.created", { name: input.name });
52
- const inserted = await this.db.get("secrets", id);
53
- return this._toMeta(inserted);
54
- }
55
- async get(name, environment = "production") {
56
- const rows = await this.db.query("secrets", {
57
- where: { name, environment },
58
- filters: [{ col: "deleted_at", op: "isNull" }],
59
- limit: 1,
60
- });
61
- if (rows.length === 0)
62
- return null;
63
- await this.hooks.emit("secret.accessed", { name, environment });
64
- const raw = rows[0].value ?? null;
65
- if (raw && this.encKey)
66
- return decryptValue(raw, this.encKey);
67
- return raw;
68
- }
69
- async getMeta(name, environment = "production") {
70
- const rows = await this.db.query("secrets", {
71
- where: { name, environment },
72
- filters: [{ col: "deleted_at", op: "isNull" }],
73
- limit: 1,
74
- });
75
- return rows.length > 0 ? this._toMeta(rows[0]) : null;
76
- }
77
- async list() {
78
- const rows = await this.db.query("secrets", {
79
- filters: [{ col: "deleted_at", op: "isNull" }],
80
- orderBy: "name",
81
- });
82
- return rows.map((r) => this._toMeta(r));
83
- }
84
- async rotate(name, newValue, environment = "production") {
85
- const rows = await this.db.query("secrets", {
86
- where: { name, environment },
87
- filters: [{ col: "deleted_at", op: "isNull" }],
88
- limit: 1,
89
- });
90
- if (rows.length === 0)
91
- throw new Error(`Secret "${name}" not found`);
92
- const storedValue = this.encKey ? encryptValue(newValue, this.encKey) : newValue;
93
- await this.db.update("secrets", rows[0].id, {
94
- value: storedValue,
95
- updated_at: new Date().toISOString(),
96
- });
97
- await this.hooks.emit("secret.rotated", { name, environment });
98
- }
99
- async delete(name, environment = "production") {
100
- const rows = await this.db.query("secrets", {
101
- where: { name, environment },
102
- filters: [{ col: "deleted_at", op: "isNull" }],
103
- limit: 1,
104
- });
105
- if (rows.length === 0)
106
- return;
107
- await this.db.update("secrets", rows[0].id, {
108
- deleted_at: new Date().toISOString(),
109
- });
110
- await this.hooks.emit("secret.deleted", { name, environment });
111
- }
112
- // ── Cursor persistence helpers ──────────────────────────────────
113
- /**
114
- * Load a sync cursor by key. Returns undefined if not found.
115
- * Cursors are stored as secrets with type='sync_cursor'.
116
- */
117
- async loadCursor(key) {
118
- const name = `sync-cursor:${key}`;
119
- const rows = await this.db.query("secrets", {
120
- where: { name },
121
- filters: [{ col: "deleted_at", op: "isNull" }],
122
- limit: 1,
123
- });
124
- const raw = rows[0]?.value ?? undefined;
125
- if (raw && this.encKey)
126
- return decryptValue(raw, this.encKey);
127
- return raw;
128
- }
129
- /**
130
- * Persist a sync cursor by key. Creates or updates the secret.
131
- */
132
- async saveCursor(key, value) {
133
- const name = `sync-cursor:${key}`;
134
- const storedValue = this.encKey ? encryptValue(value, this.encKey) : value;
135
- const rows = await this.db.query("secrets", {
136
- where: { name },
137
- filters: [{ col: "deleted_at", op: "isNull" }],
138
- limit: 1,
139
- });
140
- if (rows.length > 0) {
141
- await this.db.update("secrets", rows[0].id, {
142
- value: storedValue,
143
- updated_at: new Date().toISOString(),
144
- });
145
- }
146
- else {
147
- await this.db.insert("secrets", {
148
- id: uuidv4(),
149
- name,
150
- type: "sync_cursor",
151
- value: storedValue,
152
- });
153
- }
154
- }
155
- _toMeta(row) {
156
- return {
157
- id: row.id,
158
- org_id: row.org_id ?? null,
159
- name: row.name,
160
- type: row.type,
161
- environment: row.environment,
162
- location: row.location ?? null,
163
- description: row.description ?? null,
164
- rotation_schedule: row.rotation_schedule ?? null,
165
- expires_at: row.expires_at ?? null,
166
- notes: row.notes ?? null,
167
- created_at: row.created_at,
168
- updated_at: row.updated_at,
169
- };
170
- }
171
- }
@@ -1,13 +0,0 @@
1
- import type { DataStore } from '../data/data-store.js';
2
- export declare class SessionManager {
3
- private db;
4
- constructor(db: DataStore);
5
- save(agentId: string, channelId: string, peerId: string, params: Record<string, unknown>): Promise<string>;
6
- load(agentId: string, channelId: string, peerId: string): Promise<Record<string, unknown> | undefined>;
7
- clear(agentId: string, channelId: string, peerId: string): Promise<void>;
8
- shouldClear(session: Record<string, unknown>, opts: {
9
- maxRuns?: number;
10
- maxAgeHours?: number;
11
- }): Promise<boolean>;
12
- private _find;
13
- }
@@ -1,66 +0,0 @@
1
- export class SessionManager {
2
- db;
3
- constructor(db) {
4
- this.db = db;
5
- }
6
- async save(agentId, channelId, peerId, params) {
7
- const existing = await this._find(agentId, channelId, peerId);
8
- if (existing) {
9
- await this.db.update('sessions', { id: existing['id'] }, {
10
- context: JSON.stringify(params),
11
- last_message_at: new Date().toISOString(),
12
- message_count: (existing['message_count'] ?? 0) + 1,
13
- });
14
- return existing['id'];
15
- }
16
- else {
17
- const row = await this.db.insert('sessions', {
18
- agent_id: agentId,
19
- channel: channelId,
20
- peer_id: peerId,
21
- context: JSON.stringify(params),
22
- last_message_at: new Date().toISOString(),
23
- message_count: 1,
24
- });
25
- return row['id'];
26
- }
27
- }
28
- async load(agentId, channelId, peerId) {
29
- const session = await this._find(agentId, channelId, peerId);
30
- if (!session)
31
- return undefined;
32
- const context = session['context']
33
- ? JSON.parse(session['context'])
34
- : {};
35
- return { ...session, ...context };
36
- }
37
- async clear(agentId, channelId, peerId) {
38
- const session = await this._find(agentId, channelId, peerId);
39
- if (session) {
40
- await this.db.delete('sessions', { id: session['id'] });
41
- }
42
- }
43
- async shouldClear(session, opts) {
44
- if (opts.maxRuns !== undefined) {
45
- const messageCount = session['message_count'] ?? 0;
46
- if (messageCount > opts.maxRuns)
47
- return true;
48
- }
49
- if (opts.maxAgeHours !== undefined) {
50
- const createdAt = session['created_at'];
51
- if (createdAt) {
52
- const ageMs = Date.now() - new Date(createdAt).getTime();
53
- const ageHours = ageMs / (1000 * 60 * 60);
54
- if (ageHours > opts.maxAgeHours)
55
- return true;
56
- }
57
- }
58
- return false;
59
- }
60
- async _find(agentId, channelId, peerId) {
61
- const rows = await this.db.query('sessions', {
62
- where: { agent_id: agentId, channel: channelId, peer_id: peerId },
63
- });
64
- return rows[0] ?? undefined;
65
- }
66
- }
@@ -1,34 +0,0 @@
1
- import type { DataStore } from '../data/data-store.js';
2
- import type { HookBus } from '../hooks/hook-bus.js';
3
- import { MAX_CHAIN_DEPTH } from './chain-guard.js';
4
- export { MAX_CHAIN_DEPTH };
5
- export declare class TaskQueue {
6
- private db;
7
- private hooks;
8
- private config?;
9
- private pollTimer;
10
- private readonly pollIntervalMs;
11
- private readonly staleThresholdMs;
12
- constructor(db: DataStore, hooks: HookBus, config?: {
13
- pollIntervalMs?: number;
14
- staleThresholdMs?: number;
15
- } | undefined);
16
- create(task: {
17
- title: string;
18
- description?: string;
19
- assignee_id?: string;
20
- priority?: number;
21
- chain_depth?: number;
22
- chain_origin_id?: string;
23
- [key: string]: unknown;
24
- }): Promise<string>;
25
- update(id: string, changes: Record<string, unknown>): Promise<void>;
26
- get(id: string): Promise<Record<string, unknown> | undefined>;
27
- list(filter?: {
28
- status?: string;
29
- assignee_id?: string;
30
- }): Promise<Record<string, unknown>[]>;
31
- startPolling(): void;
32
- stopPolling(): void;
33
- private poll;
34
- }
@@ -1,83 +0,0 @@
1
- import { MAX_CHAIN_DEPTH, checkChainDepth } from './chain-guard.js';
2
- export { MAX_CHAIN_DEPTH };
3
- export class TaskQueue {
4
- db;
5
- hooks;
6
- config;
7
- pollTimer = null;
8
- pollIntervalMs;
9
- staleThresholdMs;
10
- constructor(db, hooks, config) {
11
- this.db = db;
12
- this.hooks = hooks;
13
- this.config = config;
14
- this.pollIntervalMs = config?.pollIntervalMs ?? 30_000;
15
- this.staleThresholdMs = config?.staleThresholdMs ?? 5 * 60 * 1_000;
16
- }
17
- async create(task) {
18
- const depth = task.chain_depth ?? 0;
19
- checkChainDepth(depth, MAX_CHAIN_DEPTH);
20
- const row = await this.db.insert('tasks', {
21
- title: task.title,
22
- description: task.description,
23
- assignee_id: task.assignee_id,
24
- priority: task.priority ?? 5,
25
- chain_depth: depth,
26
- chain_origin_id: task.chain_origin_id,
27
- status: 'todo',
28
- ...Object.fromEntries(Object.entries(task).filter(([k]) => !['title', 'description', 'assignee_id', 'priority', 'chain_depth', 'chain_origin_id', 'status'].includes(k))),
29
- });
30
- const taskId = row['id'];
31
- // Non-blocking: let callers do setup (e.g. insert related records) before
32
- // hook handlers (like execution engines) run.
33
- void this.hooks.emit('task.created', { taskId, title: task.title });
34
- return taskId;
35
- }
36
- async update(id, changes) {
37
- await this.db.update('tasks', { id }, {
38
- ...changes,
39
- updated_at: new Date().toISOString(),
40
- });
41
- }
42
- async get(id) {
43
- return (await this.db.get('tasks', { id })) ?? undefined;
44
- }
45
- async list(filter) {
46
- const where = {};
47
- if (filter?.status)
48
- where['status'] = filter.status;
49
- if (filter?.assignee_id)
50
- where['assignee_id'] = filter.assignee_id;
51
- return await this.db.query('tasks', Object.keys(where).length ? { where } : undefined);
52
- }
53
- startPolling() {
54
- if (this.pollTimer)
55
- return;
56
- this.pollTimer = setInterval(() => {
57
- void this.poll();
58
- }, this.pollIntervalMs);
59
- }
60
- stopPolling() {
61
- if (this.pollTimer) {
62
- clearInterval(this.pollTimer);
63
- this.pollTimer = null;
64
- }
65
- }
66
- async poll() {
67
- // Find tasks with status='todo', assignee_id NOT NULL
68
- const todoTasks = (await this.db.query('tasks', { where: { status: 'todo' } }))
69
- .filter((t) => t['assignee_id'] != null);
70
- // Check which have no active run
71
- const activeTasks = new Set((await this.db.query('runs', { where: { status: 'running' } })).map((r) => r['task_id']));
72
- const eligible = todoTasks
73
- .filter((t) => !activeTasks.has(t['id']))
74
- .sort((a, b) => a['priority'] - b['priority']);
75
- for (const task of eligible) {
76
- await this.hooks.emit('agent.wakeup', {
77
- agentId: task['assignee_id'],
78
- taskId: task['id'],
79
- source: 'poll',
80
- });
81
- }
82
- }
83
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * Simple template interpolation for workflow step templates.
3
- * Supports {{key}} and {{steps.stepId.output}} patterns.
4
- */
5
- export declare function interpolate(template: string, context: Record<string, unknown>): string;
@@ -1,18 +0,0 @@
1
- /**
2
- * Simple template interpolation for workflow step templates.
3
- * Supports {{key}} and {{steps.stepId.output}} patterns.
4
- */
5
- export function interpolate(template, context) {
6
- return template.replace(/\{\{([^}]+)\}\}/g, (_match, path) => {
7
- const parts = path.trim().split('.');
8
- let value = context;
9
- for (const part of parts) {
10
- if (value == null || typeof value !== 'object')
11
- return '';
12
- value = value[part];
13
- }
14
- if (value == null)
15
- return '';
16
- return String(value);
17
- });
18
- }
@@ -1,47 +0,0 @@
1
- import type { DataStore } from "../data/data-store.js";
2
- import type { HookBus } from "../hooks/hook-bus.js";
3
- export interface UserInput {
4
- id?: string;
5
- org_id?: string;
6
- name: string;
7
- email?: string;
8
- role?: string;
9
- title?: string;
10
- external_id?: string;
11
- channel?: string;
12
- timezone?: string;
13
- preferences?: string;
14
- notes?: string;
15
- }
16
- export interface User {
17
- id: string;
18
- org_id: string | null;
19
- name: string;
20
- email: string | null;
21
- role: string | null;
22
- title: string | null;
23
- external_id: string | null;
24
- channel: string | null;
25
- timezone: string | null;
26
- preferences: string;
27
- notes: string | null;
28
- created_at: string;
29
- updated_at: string;
30
- deleted_at: string | null;
31
- }
32
- export declare class UserRegistry {
33
- private readonly db;
34
- private readonly hooks;
35
- constructor(db: DataStore, hooks: HookBus);
36
- register(input: UserInput): Promise<User>;
37
- getById(id: string): Promise<User | null>;
38
- getByEmail(email: string): Promise<User | null>;
39
- resolveByIdentity(channel: string, externalId: string): Promise<User | null>;
40
- resolveOrCreate(externalId: string, channel: string, defaults?: Partial<UserInput>): Promise<User>;
41
- list(filter?: {
42
- role?: string;
43
- org_id?: string;
44
- }): Promise<User[]>;
45
- update(id: string, changes: Partial<UserInput>): Promise<void>;
46
- addIdentity(userId: string, channel: string, externalId: string, displayName?: string): Promise<void>;
47
- }
@@ -1,76 +0,0 @@
1
- import { v4 as uuidv4 } from "uuid";
2
- export class UserRegistry {
3
- db;
4
- hooks;
5
- constructor(db, hooks) {
6
- this.db = db;
7
- this.hooks = hooks;
8
- }
9
- async register(input) {
10
- const id = input.id ?? uuidv4();
11
- await this.db.insert("users", { ...input, id });
12
- const user = await this.db.get("users", id);
13
- await this.hooks.emit("user.created", { user });
14
- return user;
15
- }
16
- async getById(id) {
17
- const row = await this.db.get("users", id);
18
- return row ?? null;
19
- }
20
- async getByEmail(email) {
21
- const rows = await this.db.query("users", {
22
- where: { email },
23
- filters: [{ col: "deleted_at", op: "isNull" }],
24
- limit: 1,
25
- });
26
- return rows.length > 0 ? rows[0] : null;
27
- }
28
- async resolveByIdentity(channel, externalId) {
29
- const identities = await this.db.query("user_identities", {
30
- where: { channel, external_id: externalId },
31
- limit: 1,
32
- });
33
- if (identities.length === 0)
34
- return null;
35
- return this.getById(identities[0].user_id);
36
- }
37
- async resolveOrCreate(externalId, channel, defaults) {
38
- const existing = await this.resolveByIdentity(channel, externalId);
39
- if (existing)
40
- return existing;
41
- const user = await this.register({
42
- name: defaults?.name ?? externalId,
43
- external_id: externalId,
44
- channel,
45
- ...defaults,
46
- });
47
- await this.addIdentity(user.id, channel, externalId);
48
- return user;
49
- }
50
- async list(filter) {
51
- const where = {};
52
- const filters = [{ col: "deleted_at", op: "isNull" }];
53
- if (filter?.role)
54
- where.role = filter.role;
55
- if (filter?.org_id)
56
- where.org_id = filter.org_id;
57
- const rows = await this.db.query("users", { where, filters });
58
- return rows;
59
- }
60
- async update(id, changes) {
61
- await this.db.update("users", id, {
62
- ...changes,
63
- updated_at: new Date().toISOString(),
64
- });
65
- }
66
- async addIdentity(userId, channel, externalId, displayName) {
67
- await this.db.insert("user_identities", {
68
- id: uuidv4(),
69
- user_id: userId,
70
- channel,
71
- external_id: externalId,
72
- display_name: displayName ?? null,
73
- verified: 0,
74
- });
75
- }
76
- }
@@ -1,9 +0,0 @@
1
- import type { DataStore } from '../data/data-store.js';
2
- export declare class WakeupQueue {
3
- private db;
4
- constructor(db: DataStore);
5
- enqueue(agentId: string, source: string, context?: Record<string, unknown>): Promise<string>;
6
- coalesce(agentId: string, context?: Record<string, unknown>): Promise<void>;
7
- getNext(agentId: string): Promise<Record<string, unknown> | undefined>;
8
- markFired(wakeupId: string, runId: string): Promise<void>;
9
- }
@@ -1,45 +0,0 @@
1
- export class WakeupQueue {
2
- db;
3
- constructor(db) {
4
- this.db = db;
5
- }
6
- async enqueue(agentId, source, context) {
7
- const row = await this.db.insert('wakeups', {
8
- agent_id: agentId,
9
- scheduled_at: new Date().toISOString(),
10
- context: context ? JSON.stringify({ source, ...context }) : JSON.stringify({ source }),
11
- });
12
- return row['id'];
13
- }
14
- async coalesce(agentId, context) {
15
- // Find existing queued wakeup (no fired_at) for agent
16
- const existing = (await this.db.query('wakeups', {
17
- where: { agent_id: agentId },
18
- })).filter((w) => w['fired_at'] == null);
19
- if (existing.length === 0)
20
- return;
21
- // Merge context into oldest queued wakeup
22
- const wakeup = existing[0];
23
- const currentCtx = wakeup['context']
24
- ? JSON.parse(wakeup['context'])
25
- : {};
26
- const merged = { ...currentCtx, ...(context ?? {}) };
27
- await this.db.update('wakeups', { id: wakeup['id'] }, {
28
- context: JSON.stringify(merged),
29
- });
30
- }
31
- async getNext(agentId) {
32
- const queued = (await this.db.query('wakeups', {
33
- where: { agent_id: agentId },
34
- }))
35
- .filter((w) => w['fired_at'] == null)
36
- .sort((a, b) => a['scheduled_at'].localeCompare(b['scheduled_at']));
37
- return queued[0] ?? undefined;
38
- }
39
- async markFired(wakeupId, runId) {
40
- await this.db.update('wakeups', { id: wakeupId }, {
41
- fired_at: new Date().toISOString(),
42
- run_id: runId,
43
- });
44
- }
45
- }
@@ -1,47 +0,0 @@
1
- import type { DataStore } from '../data/data-store.js';
2
- import type { HookBus } from '../hooks/hook-bus.js';
3
- import type { TaskQueue } from './task-queue.js';
4
- export interface WorkflowStep {
5
- id: string;
6
- name: string;
7
- agentSlug?: string;
8
- taskTemplate: {
9
- title: string;
10
- description: string;
11
- };
12
- dependsOn?: string[];
13
- onComplete?: 'next' | 'parallel' | 'end';
14
- onFail?: 'abort' | 'skip' | 'retry';
15
- }
16
- export interface WorkflowDefinition {
17
- name: string;
18
- description?: string;
19
- steps: WorkflowStep[];
20
- trigger?: {
21
- type: 'task_completed' | 'event' | 'schedule' | 'manual';
22
- filter?: Record<string, unknown>;
23
- };
24
- }
25
- export declare class WorkflowEngine {
26
- private db;
27
- private hooks;
28
- private taskQueue;
29
- constructor(db: DataStore, hooks: HookBus, taskQueue: TaskQueue);
30
- /**
31
- * Define/register a workflow.
32
- */
33
- define(slug: string, def: WorkflowDefinition): Promise<void>;
34
- /**
35
- * Start a workflow run.
36
- */
37
- start(workflowSlug: string, context: Record<string, unknown>): Promise<string>;
38
- /**
39
- * Called when a task with workflow_run_id completes.
40
- */
41
- onStepCompleted(taskId: string, output: string): Promise<void>;
42
- /**
43
- * Mark a workflow run as failed.
44
- */
45
- onStepFailed(taskId: string, error: string): Promise<void>;
46
- private _createStepTask;
47
- }