botinabox 2.5.2 → 2.5.3

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 (276) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +190 -190
  3. package/bin/botinabox.mjs +2 -2
  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/package.json +100 -100
  10. package/dist/channels/discord/adapter.d.ts +0 -32
  11. package/dist/channels/discord/adapter.js +0 -70
  12. package/dist/channels/discord/inbound.d.ts +0 -25
  13. package/dist/channels/discord/inbound.js +0 -24
  14. package/dist/channels/discord/models.d.ts +0 -8
  15. package/dist/channels/discord/models.js +0 -5
  16. package/dist/channels/discord/outbound.d.ts +0 -14
  17. package/dist/channels/discord/outbound.js +0 -38
  18. package/dist/channels/slack/adapter.d.ts +0 -33
  19. package/dist/channels/slack/adapter.js +0 -74
  20. package/dist/channels/slack/inbound.d.ts +0 -59
  21. package/dist/channels/slack/inbound.js +0 -96
  22. package/dist/channels/slack/models.d.ts +0 -9
  23. package/dist/channels/slack/models.js +0 -5
  24. package/dist/channels/slack/outbound.d.ts +0 -12
  25. package/dist/channels/slack/outbound.js +0 -18
  26. package/dist/channels/slack/transcribe.d.ts +0 -41
  27. package/dist/channels/slack/transcribe.js +0 -106
  28. package/dist/channels/webhook/adapter.d.ts +0 -23
  29. package/dist/channels/webhook/adapter.js +0 -86
  30. package/dist/channels/webhook/hmac.d.ts +0 -13
  31. package/dist/channels/webhook/hmac.js +0 -26
  32. package/dist/channels/webhook/models.d.ts +0 -9
  33. package/dist/channels/webhook/models.js +0 -5
  34. package/dist/channels/webhook/server.d.ts +0 -20
  35. package/dist/channels/webhook/server.js +0 -91
  36. package/dist/chat-pipeline-BWrtVqEP.d.ts +0 -652
  37. package/dist/chat-pipeline-C-XlLGNl.d.ts +0 -648
  38. package/dist/chat-pipeline-CR1KF6eX.d.ts +0 -652
  39. package/dist/chat-pipeline-DisuC8SB.d.ts +0 -643
  40. package/dist/chunk-2LGXQPEA.js +0 -41
  41. package/dist/chunk-3X3YKI4T.js +0 -357
  42. package/dist/chunk-D47AIFOD.js +0 -351
  43. package/dist/chunk-DSNJKNEW.js +0 -328
  44. package/dist/chunk-GS2JFL6I.js +0 -144
  45. package/dist/chunk-J6S6QMUY.js +0 -144
  46. package/dist/chunk-QLA6YOFN.js +0 -22
  47. package/dist/cli/templates/config.yml.d.ts +0 -7
  48. package/dist/cli/templates/config.yml.js +0 -61
  49. package/dist/cli/templates/env.d.ts +0 -1
  50. package/dist/cli/templates/env.js +0 -30
  51. package/dist/cli/templates/index.ts.d.ts +0 -2
  52. package/dist/cli/templates/index.ts.js +0 -30
  53. package/dist/cli/templates/package.json.d.ts +0 -5
  54. package/dist/cli/templates/package.json.js +0 -28
  55. package/dist/connector-DDahQw-2.d.ts +0 -63
  56. package/dist/connectors/google/calendar-connector.d.ts +0 -40
  57. package/dist/connectors/google/calendar-connector.js +0 -243
  58. package/dist/connectors/google/gmail-connector.d.ts +0 -42
  59. package/dist/connectors/google/gmail-connector.js +0 -345
  60. package/dist/connectors/google/oauth.d.ts +0 -48
  61. package/dist/connectors/google/oauth.js +0 -112
  62. package/dist/connectors/google/types.d.ts +0 -78
  63. package/dist/connectors/google/types.js +0 -2
  64. package/dist/core/chat/auto-discovery.d.ts +0 -16
  65. package/dist/core/chat/auto-discovery.js +0 -54
  66. package/dist/core/chat/channel-registry.d.ts +0 -45
  67. package/dist/core/chat/channel-registry.js +0 -96
  68. package/dist/core/chat/chat-pipeline.d.ts +0 -113
  69. package/dist/core/chat/chat-pipeline.js +0 -395
  70. package/dist/core/chat/chat-responder.d.ts +0 -90
  71. package/dist/core/chat/chat-responder.js +0 -185
  72. package/dist/core/chat/formatter.d.ts +0 -11
  73. package/dist/core/chat/formatter.js +0 -60
  74. package/dist/core/chat/index.d.ts +0 -24
  75. package/dist/core/chat/index.js +0 -18
  76. package/dist/core/chat/message-interpreter.d.ts +0 -91
  77. package/dist/core/chat/message-interpreter.js +0 -166
  78. package/dist/core/chat/message-store.d.ts +0 -66
  79. package/dist/core/chat/message-store.js +0 -131
  80. package/dist/core/chat/notification-queue.d.ts +0 -34
  81. package/dist/core/chat/notification-queue.js +0 -111
  82. package/dist/core/chat/pipeline.d.ts +0 -38
  83. package/dist/core/chat/pipeline.js +0 -89
  84. package/dist/core/chat/policies.d.ts +0 -16
  85. package/dist/core/chat/policies.js +0 -25
  86. package/dist/core/chat/routing.d.ts +0 -17
  87. package/dist/core/chat/routing.js +0 -36
  88. package/dist/core/chat/session-key.d.ts +0 -30
  89. package/dist/core/chat/session-key.js +0 -65
  90. package/dist/core/chat/session-manager.d.ts +0 -17
  91. package/dist/core/chat/session-manager.js +0 -23
  92. package/dist/core/chat/text-chunker.d.ts +0 -9
  93. package/dist/core/chat/text-chunker.js +0 -48
  94. package/dist/core/chat/triage-router.d.ts +0 -75
  95. package/dist/core/chat/triage-router.js +0 -142
  96. package/dist/core/chat/types.d.ts +0 -5
  97. package/dist/core/chat/types.js +0 -5
  98. package/dist/core/config/defaults.d.ts +0 -2
  99. package/dist/core/config/defaults.js +0 -38
  100. package/dist/core/config/index.d.ts +0 -6
  101. package/dist/core/config/index.js +0 -4
  102. package/dist/core/config/interpolate.d.ts +0 -5
  103. package/dist/core/config/interpolate.js +0 -27
  104. package/dist/core/config/loader.d.ts +0 -24
  105. package/dist/core/config/loader.js +0 -59
  106. package/dist/core/config/schema.d.ts +0 -5
  107. package/dist/core/config/schema.js +0 -119
  108. package/dist/core/data/core-entity-contexts.d.ts +0 -14
  109. package/dist/core/data/core-entity-contexts.js +0 -197
  110. package/dist/core/data/core-migrations.d.ts +0 -5
  111. package/dist/core/data/core-migrations.js +0 -45
  112. package/dist/core/data/core-schema.d.ts +0 -6
  113. package/dist/core/data/core-schema.js +0 -454
  114. package/dist/core/data/data-store.d.ts +0 -67
  115. package/dist/core/data/data-store.js +0 -218
  116. package/dist/core/data/domain-entity-contexts.d.ts +0 -29
  117. package/dist/core/data/domain-entity-contexts.js +0 -321
  118. package/dist/core/data/domain-schema.d.ts +0 -36
  119. package/dist/core/data/domain-schema.js +0 -323
  120. package/dist/core/data/index.d.ts +0 -7
  121. package/dist/core/data/index.js +0 -7
  122. package/dist/core/data/types.d.ts +0 -111
  123. package/dist/core/data/types.js +0 -1
  124. package/dist/core/hooks/hook-bus.d.ts +0 -18
  125. package/dist/core/hooks/hook-bus.js +0 -120
  126. package/dist/core/hooks/index.d.ts +0 -2
  127. package/dist/core/hooks/index.js +0 -1
  128. package/dist/core/hooks/types.d.ts +0 -19
  129. package/dist/core/hooks/types.js +0 -1
  130. package/dist/core/index.d.ts +0 -4
  131. package/dist/core/index.js +0 -4
  132. package/dist/core/llm/auto-discovery.d.ts +0 -11
  133. package/dist/core/llm/auto-discovery.js +0 -49
  134. package/dist/core/llm/cost-tracker.d.ts +0 -6
  135. package/dist/core/llm/cost-tracker.js +0 -38
  136. package/dist/core/llm/index.d.ts +0 -4
  137. package/dist/core/llm/index.js +0 -3
  138. package/dist/core/llm/model-router.d.ts +0 -25
  139. package/dist/core/llm/model-router.js +0 -49
  140. package/dist/core/llm/provider-registry.d.ts +0 -9
  141. package/dist/core/llm/provider-registry.js +0 -25
  142. package/dist/core/llm/types.d.ts +0 -2
  143. package/dist/core/llm/types.js +0 -2
  144. package/dist/core/orchestrator/adapters/api-adapter.d.ts +0 -34
  145. package/dist/core/orchestrator/adapters/api-adapter.js +0 -88
  146. package/dist/core/orchestrator/adapters/cli-adapter.d.ts +0 -22
  147. package/dist/core/orchestrator/adapters/cli-adapter.js +0 -69
  148. package/dist/core/orchestrator/adapters/deterministic-adapter.d.ts +0 -35
  149. package/dist/core/orchestrator/adapters/deterministic-adapter.js +0 -75
  150. package/dist/core/orchestrator/adapters/env-whitelist.d.ts +0 -4
  151. package/dist/core/orchestrator/adapters/env-whitelist.js +0 -27
  152. package/dist/core/orchestrator/adapters/output-extractor.d.ts +0 -11
  153. package/dist/core/orchestrator/adapters/output-extractor.js +0 -59
  154. package/dist/core/orchestrator/adapters/process-manager.d.ts +0 -15
  155. package/dist/core/orchestrator/adapters/process-manager.js +0 -26
  156. package/dist/core/orchestrator/adapters/tool-loop.d.ts +0 -22
  157. package/dist/core/orchestrator/adapters/tool-loop.js +0 -66
  158. package/dist/core/orchestrator/agent-registry.d.ts +0 -31
  159. package/dist/core/orchestrator/agent-registry.js +0 -135
  160. package/dist/core/orchestrator/budget-controller.d.ts +0 -19
  161. package/dist/core/orchestrator/budget-controller.js +0 -73
  162. package/dist/core/orchestrator/chain-guard.d.ts +0 -14
  163. package/dist/core/orchestrator/chain-guard.js +0 -23
  164. package/dist/core/orchestrator/circuit-breaker.d.ts +0 -65
  165. package/dist/core/orchestrator/circuit-breaker.js +0 -159
  166. package/dist/core/orchestrator/claude-stream-parser.d.ts +0 -31
  167. package/dist/core/orchestrator/claude-stream-parser.js +0 -99
  168. package/dist/core/orchestrator/config-revisions.d.ts +0 -6
  169. package/dist/core/orchestrator/config-revisions.js +0 -17
  170. package/dist/core/orchestrator/dependency-resolver.d.ts +0 -20
  171. package/dist/core/orchestrator/dependency-resolver.js +0 -78
  172. package/dist/core/orchestrator/governance-gate.d.ts +0 -110
  173. package/dist/core/orchestrator/governance-gate.js +0 -170
  174. package/dist/core/orchestrator/learning-pipeline.d.ts +0 -109
  175. package/dist/core/orchestrator/learning-pipeline.js +0 -249
  176. package/dist/core/orchestrator/loop-detector.d.ts +0 -51
  177. package/dist/core/orchestrator/loop-detector.js +0 -133
  178. package/dist/core/orchestrator/ndjson-logger.d.ts +0 -6
  179. package/dist/core/orchestrator/ndjson-logger.js +0 -18
  180. package/dist/core/orchestrator/permission-relay.d.ts +0 -72
  181. package/dist/core/orchestrator/permission-relay.js +0 -164
  182. package/dist/core/orchestrator/run-manager.d.ts +0 -31
  183. package/dist/core/orchestrator/run-manager.js +0 -178
  184. package/dist/core/orchestrator/scheduler.d.ts +0 -70
  185. package/dist/core/orchestrator/scheduler.js +0 -198
  186. package/dist/core/orchestrator/secret-store.d.ts +0 -57
  187. package/dist/core/orchestrator/secret-store.js +0 -171
  188. package/dist/core/orchestrator/session-manager.d.ts +0 -13
  189. package/dist/core/orchestrator/session-manager.js +0 -66
  190. package/dist/core/orchestrator/task-queue.d.ts +0 -34
  191. package/dist/core/orchestrator/task-queue.js +0 -83
  192. package/dist/core/orchestrator/template-interpolate.d.ts +0 -5
  193. package/dist/core/orchestrator/template-interpolate.js +0 -18
  194. package/dist/core/orchestrator/user-registry.d.ts +0 -47
  195. package/dist/core/orchestrator/user-registry.js +0 -76
  196. package/dist/core/orchestrator/wakeup-queue.d.ts +0 -9
  197. package/dist/core/orchestrator/wakeup-queue.js +0 -45
  198. package/dist/core/orchestrator/workflow-engine.d.ts +0 -47
  199. package/dist/core/orchestrator/workflow-engine.js +0 -204
  200. package/dist/core/security/audit.d.ts +0 -20
  201. package/dist/core/security/audit.js +0 -33
  202. package/dist/core/security/column-validator.d.ts +0 -20
  203. package/dist/core/security/column-validator.js +0 -37
  204. package/dist/core/security/index.d.ts +0 -5
  205. package/dist/core/security/index.js +0 -5
  206. package/dist/core/security/process-env.d.ts +0 -13
  207. package/dist/core/security/process-env.js +0 -49
  208. package/dist/core/security/sanitizer.d.ts +0 -11
  209. package/dist/core/security/sanitizer.js +0 -39
  210. package/dist/core/security/types.d.ts +0 -11
  211. package/dist/core/security/types.js +0 -1
  212. package/dist/core/update/auto-update.d.ts +0 -21
  213. package/dist/core/update/auto-update.js +0 -102
  214. package/dist/core/update/backup-manager.d.ts +0 -7
  215. package/dist/core/update/backup-manager.js +0 -24
  216. package/dist/core/update/index.d.ts +0 -8
  217. package/dist/core/update/index.js +0 -6
  218. package/dist/core/update/migration-hooks.d.ts +0 -11
  219. package/dist/core/update/migration-hooks.js +0 -10
  220. package/dist/core/update/types.d.ts +0 -11
  221. package/dist/core/update/types.js +0 -1
  222. package/dist/core/update/update-checker.d.ts +0 -11
  223. package/dist/core/update/update-checker.js +0 -63
  224. package/dist/core/update/update-manager.d.ts +0 -25
  225. package/dist/core/update/update-manager.js +0 -101
  226. package/dist/core/update/version-utils.d.ts +0 -6
  227. package/dist/core/update/version-utils.js +0 -34
  228. package/dist/gmail-connector-MNUBRNFM.js +0 -6
  229. package/dist/gmail-connector-PS2VLGNE.js +0 -6
  230. package/dist/gmail-connector-ULSMN6X2.js +0 -6
  231. package/dist/gmail-connector-URRFX6A3.js +0 -6
  232. package/dist/inbound-AFBUPSPG.js +0 -10
  233. package/dist/inbound-AFOHYNUY.js +0 -6
  234. package/dist/inbound-CGIXRXGC.js +0 -8
  235. package/dist/inbound-MCOLRH6U.js +0 -10
  236. package/dist/inbound-SNEMBLGA.js +0 -6
  237. package/dist/inbound-ZJHAYVMF.js +0 -10
  238. package/dist/provider-qqJYv9nv.d.ts +0 -75
  239. package/dist/providers/anthropic/models.d.ts +0 -2
  240. package/dist/providers/anthropic/models.js +0 -29
  241. package/dist/providers/anthropic/provider.d.ts +0 -13
  242. package/dist/providers/anthropic/provider.js +0 -119
  243. package/dist/providers/anthropic/tool-converter.d.ts +0 -10
  244. package/dist/providers/anthropic/tool-converter.js +0 -7
  245. package/dist/providers/ollama/provider.d.ts +0 -17
  246. package/dist/providers/ollama/provider.js +0 -185
  247. package/dist/providers/openai/models.d.ts +0 -2
  248. package/dist/providers/openai/models.js +0 -29
  249. package/dist/providers/openai/provider.d.ts +0 -13
  250. package/dist/providers/openai/provider.js +0 -163
  251. package/dist/providers/openai/tool-converter.d.ts +0 -10
  252. package/dist/providers/openai/tool-converter.js +0 -10
  253. package/dist/shared/constants.d.ts +0 -50
  254. package/dist/shared/constants.js +0 -64
  255. package/dist/shared/index.d.ts +0 -14
  256. package/dist/shared/index.js +0 -14
  257. package/dist/shared/types/agent.d.ts +0 -36
  258. package/dist/shared/types/agent.js +0 -2
  259. package/dist/shared/types/channel.d.ts +0 -70
  260. package/dist/shared/types/channel.js +0 -2
  261. package/dist/shared/types/config.d.ts +0 -111
  262. package/dist/shared/types/config.js +0 -2
  263. package/dist/shared/types/connector.d.ts +0 -77
  264. package/dist/shared/types/connector.js +0 -2
  265. package/dist/shared/types/execution.d.ts +0 -29
  266. package/dist/shared/types/execution.js +0 -2
  267. package/dist/shared/types/provider.d.ts +0 -73
  268. package/dist/shared/types/provider.js +0 -2
  269. package/dist/shared/types/task.d.ts +0 -47
  270. package/dist/shared/types/task.js +0 -2
  271. package/dist/shared/types/workflow.d.ts +0 -39
  272. package/dist/shared/types/workflow.js +0 -2
  273. package/dist/shared/utils.d.ts +0 -6
  274. package/dist/shared/utils.js +0 -13
  275. package/dist/update-check.d.ts +0 -5
  276. 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
- }