mixdog 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (404) hide show
  1. package/.claude-plugin/marketplace.json +31 -0
  2. package/.claude-plugin/plugin.json +20 -0
  3. package/.gitattributes +34 -0
  4. package/.mcp.json +14 -0
  5. package/ARCHITECTURE.md +77 -0
  6. package/CHANGELOG.md +7 -0
  7. package/CONTRIBUTING.md +45 -0
  8. package/DATA-FLOW.md +79 -0
  9. package/LICENSE +21 -0
  10. package/README.md +389 -0
  11. package/SECURITY.md +138 -0
  12. package/UNINSTALL.md +112 -0
  13. package/agents/maintenance.md +5 -0
  14. package/agents/memory-classification.md +30 -0
  15. package/agents/scheduler-task.md +18 -0
  16. package/agents/webhook-handler.md +27 -0
  17. package/agents/worker.md +24 -0
  18. package/bin/bridge +133 -0
  19. package/bin/statusline-launcher.mjs +78 -0
  20. package/bin/statusline-lib.mjs +550 -0
  21. package/bin/statusline.mjs +607 -0
  22. package/bun.lock +802 -0
  23. package/commands/config.md +16 -0
  24. package/commands/doctor.md +13 -0
  25. package/commands/setup.md +17 -0
  26. package/defaults/cycle3-review-prompt.md +90 -0
  27. package/defaults/hidden-roles.json +65 -0
  28. package/defaults/memory-chunk-prompt.md +63 -0
  29. package/defaults/memory-promote-prompt.md +135 -0
  30. package/defaults/mixdog-config.template.json +27 -0
  31. package/defaults/user-workflow.json +8 -0
  32. package/defaults/user-workflow.md +12 -0
  33. package/hooks/hooks.json +73 -0
  34. package/hooks/lib/active-instance.cjs +77 -0
  35. package/hooks/lib/permission-evaluator.cjs +411 -0
  36. package/hooks/lib/permission-route.cjs +63 -0
  37. package/hooks/lib/permission-rules.cjs +170 -0
  38. package/hooks/lib/settings-loader.cjs +116 -0
  39. package/hooks/post-tool-use.cjs +84 -0
  40. package/hooks/pre-mcp-sandbox.cjs +158 -0
  41. package/hooks/pre-tool-subagent.cjs +253 -0
  42. package/hooks/session-start.cjs +1372 -0
  43. package/hooks/turn-timer.cjs +82 -0
  44. package/lib/claude-md-writer.cjs +386 -0
  45. package/lib/config-cjs.cjs +61 -0
  46. package/lib/hook-pipe-path.cjs +10 -0
  47. package/lib/keychain-cjs.cjs +263 -0
  48. package/lib/plugin-paths.cjs +61 -0
  49. package/lib/rules-builder.cjs +241 -0
  50. package/lib/text-utils.cjs +61 -0
  51. package/native/README.md +117 -0
  52. package/native/prebuilt/linux-aarch64/mixdog-shim +0 -0
  53. package/native/prebuilt/linux-x86_64/mixdog-shim +0 -0
  54. package/native/prebuilt/macos-aarch64/mixdog-shim +0 -0
  55. package/native/prebuilt/macos-x86_64/mixdog-shim +0 -0
  56. package/native/prebuilt/windows-x86_64/mixdog-shim.exe +0 -0
  57. package/package.json +107 -0
  58. package/prompts/code-review.txt +16 -0
  59. package/prompts/security-audit.txt +17 -0
  60. package/rules/bridge/00-common.md +39 -0
  61. package/rules/bridge/20-skip-protocol.md +18 -0
  62. package/rules/bridge/30-explorer.md +33 -0
  63. package/rules/bridge/40-cycle1-agent.md +52 -0
  64. package/rules/bridge/41-cycle2-agent.md +62 -0
  65. package/rules/bridge/42-cycle3-agent.md +44 -0
  66. package/rules/lead/00-tool-lead.md +61 -0
  67. package/rules/lead/01-general.md +23 -0
  68. package/rules/lead/02-channels.md +49 -0
  69. package/rules/lead/03-team.md +27 -0
  70. package/rules/lead/04-workflow.md +20 -0
  71. package/rules/shared/00-language.md +14 -0
  72. package/rules/shared/01-tool.md +138 -0
  73. package/scripts/bootstrap.mjs +184 -0
  74. package/scripts/bridge-unify-smoke.mjs +308 -0
  75. package/scripts/build-runtime-linux.sh +348 -0
  76. package/scripts/build-runtime-macos.sh +217 -0
  77. package/scripts/build-runtime-windows.ps1 +242 -0
  78. package/scripts/builtin-utils-smoke.mjs +392 -0
  79. package/scripts/check-json.mjs +45 -0
  80. package/scripts/check-syntax-changed.mjs +102 -0
  81. package/scripts/check-syntax.mjs +58 -0
  82. package/scripts/code-graph-batch.test.mjs +33 -0
  83. package/scripts/config-preserve-smoke.mjs +180 -0
  84. package/scripts/doctor.mjs +484 -0
  85. package/scripts/edit-normalize-fuzz.mjs +130 -0
  86. package/scripts/edit-normalize-smoke.mjs +401 -0
  87. package/scripts/edit-operation-smoke.mjs +369 -0
  88. package/scripts/edit2-smoke.mjs +63 -0
  89. package/scripts/fuzzy-e2e.mjs +28 -0
  90. package/scripts/fuzzy-smoke.mjs +26 -0
  91. package/scripts/generate-runtime-manifest.mjs +166 -0
  92. package/scripts/guard-smoke.mjs +66 -0
  93. package/scripts/hidden-role-schema-smoke.mjs +162 -0
  94. package/scripts/hook-routing-smoke.mjs +29 -0
  95. package/scripts/inject-input.ps1 +204 -0
  96. package/scripts/io-complex-smoke.mjs +667 -0
  97. package/scripts/io-explore-bench.mjs +424 -0
  98. package/scripts/io-guardrails-smoke.mjs +205 -0
  99. package/scripts/io-mini-bench-baseline.json +11 -0
  100. package/scripts/io-mini-bench.mjs +216 -0
  101. package/scripts/io-route-harness.mjs +933 -0
  102. package/scripts/io-telemetry-report.mjs +691 -0
  103. package/scripts/mutation-bench.mjs +564 -0
  104. package/scripts/mutation-io-smoke.mjs +1081 -0
  105. package/scripts/native-patch-bridge-smoke.mjs +288 -0
  106. package/scripts/native-patch-smoke.mjs +304 -0
  107. package/scripts/patch-interior-context-smoke.mjs +49 -0
  108. package/scripts/patch-newline-utf8-smoke.mjs +157 -0
  109. package/scripts/perf-hook-smoke.mjs +71 -0
  110. package/scripts/permission-eval-smoke.mjs +426 -0
  111. package/scripts/prep-patch.mjs +53 -0
  112. package/scripts/prep-shim.mjs +96 -0
  113. package/scripts/provider-cache-smoke.mjs +687 -0
  114. package/scripts/report-runtime-health.mjs +132 -0
  115. package/scripts/run-mcp.mjs +1547 -0
  116. package/scripts/salvage-v4a-shatter.test.mjs +58 -0
  117. package/scripts/scoped-cache-io-smoke.mjs +103 -0
  118. package/scripts/shell-policy-round3-smoke.mjs +46 -0
  119. package/scripts/smoke-runtime-negative.ps1 +100 -0
  120. package/scripts/smoke-runtime-negative.sh +95 -0
  121. package/scripts/stall-policy-smoke.mjs +50 -0
  122. package/scripts/start-memory-worker.mjs +23 -0
  123. package/scripts/statusline-launcher-smoke.mjs +82 -0
  124. package/scripts/stress-atomic-write.mjs +1028 -0
  125. package/scripts/test-config-rmw-restore.mjs +122 -0
  126. package/scripts/test-fault-inject.mjs +164 -0
  127. package/scripts/test-large-file.mjs +174 -0
  128. package/scripts/tool-edge-smoke.mjs +209 -0
  129. package/scripts/uninstall.mjs +201 -0
  130. package/scripts/webhook-selfheal-smoke.mjs +29 -0
  131. package/scripts/write-overwrite-guard-smoke.mjs +56 -0
  132. package/server-main.mjs +3055 -0
  133. package/server.mjs +468 -0
  134. package/setup/config-merge.mjs +254 -0
  135. package/setup/install.mjs +120 -0
  136. package/setup/launch-core.mjs +507 -0
  137. package/setup/launch.mjs +101 -0
  138. package/setup/setup-server.mjs +3206 -0
  139. package/setup/setup.html +3693 -0
  140. package/skills/retro-skill-proposer/SKILL.md +92 -0
  141. package/skills/schedule-add/SKILL.md +77 -0
  142. package/skills/setup/SKILL.md +346 -0
  143. package/skills/webhook-add/SKILL.md +81 -0
  144. package/src/agent/bridge-stall-watchdog.mjs +337 -0
  145. package/src/agent/index.mjs +2138 -0
  146. package/src/agent/orchestrator/activity-bus.mjs +38 -0
  147. package/src/agent/orchestrator/ai-wrapped-dispatch.mjs +1010 -0
  148. package/src/agent/orchestrator/bridge-retry.mjs +220 -0
  149. package/src/agent/orchestrator/bridge-trace.mjs +583 -0
  150. package/src/agent/orchestrator/cache-mtime.mjs +58 -0
  151. package/src/agent/orchestrator/config.mjs +358 -0
  152. package/src/agent/orchestrator/context/collect.mjs +651 -0
  153. package/src/agent/orchestrator/dispatch-persist.mjs +549 -0
  154. package/src/agent/orchestrator/drain-registry.mjs +50 -0
  155. package/src/agent/orchestrator/explore-validator.mjs +8 -0
  156. package/src/agent/orchestrator/internal-roles.mjs +118 -0
  157. package/src/agent/orchestrator/internal-tools.mjs +88 -0
  158. package/src/agent/orchestrator/jobs.mjs +116 -0
  159. package/src/agent/orchestrator/mcp/client.mjs +364 -0
  160. package/src/agent/orchestrator/providers/anthropic-betas.mjs +21 -0
  161. package/src/agent/orchestrator/providers/anthropic-oauth.mjs +1745 -0
  162. package/src/agent/orchestrator/providers/anthropic.mjs +437 -0
  163. package/src/agent/orchestrator/providers/gemini.mjs +1175 -0
  164. package/src/agent/orchestrator/providers/grok-oauth.mjs +782 -0
  165. package/src/agent/orchestrator/providers/model-catalog.mjs +241 -0
  166. package/src/agent/orchestrator/providers/openai-compat.mjs +1467 -0
  167. package/src/agent/orchestrator/providers/openai-oauth-ws.mjs +1890 -0
  168. package/src/agent/orchestrator/providers/openai-oauth.mjs +1307 -0
  169. package/src/agent/orchestrator/providers/openai-ws.mjs +104 -0
  170. package/src/agent/orchestrator/providers/registry.mjs +192 -0
  171. package/src/agent/orchestrator/providers/retry-classifier.mjs +325 -0
  172. package/src/agent/orchestrator/session/abort-lookup.mjs +13 -0
  173. package/src/agent/orchestrator/session/cache/post-edit-marks.mjs +42 -0
  174. package/src/agent/orchestrator/session/cache/prefetch-cache.mjs +142 -0
  175. package/src/agent/orchestrator/session/cache/read-cache.mjs +319 -0
  176. package/src/agent/orchestrator/session/cache/scoped-cache-outcome.mjs +11 -0
  177. package/src/agent/orchestrator/session/cache/scoped-cache.mjs +361 -0
  178. package/src/agent/orchestrator/session/cache/util.mjs +49 -0
  179. package/src/agent/orchestrator/session/loop.mjs +1478 -0
  180. package/src/agent/orchestrator/session/manager.mjs +1975 -0
  181. package/src/agent/orchestrator/session/read-dedup.mjs +6 -0
  182. package/src/agent/orchestrator/session/result-classification.mjs +65 -0
  183. package/src/agent/orchestrator/session/save-session-worker.mjs +18 -0
  184. package/src/agent/orchestrator/session/store.mjs +624 -0
  185. package/src/agent/orchestrator/session/stream-watchdog.mjs +130 -0
  186. package/src/agent/orchestrator/session/tool-result-offload.mjs +166 -0
  187. package/src/agent/orchestrator/session/trim.mjs +491 -0
  188. package/src/agent/orchestrator/smart-bridge/CACHE-SHARD.md +115 -0
  189. package/src/agent/orchestrator/smart-bridge/bridge-llm.mjs +327 -0
  190. package/src/agent/orchestrator/smart-bridge/cache-obs.mjs +150 -0
  191. package/src/agent/orchestrator/smart-bridge/cache-strategy.mjs +228 -0
  192. package/src/agent/orchestrator/smart-bridge/index.mjs +215 -0
  193. package/src/agent/orchestrator/smart-bridge/profiles.mjs +37 -0
  194. package/src/agent/orchestrator/smart-bridge/registry.mjs +348 -0
  195. package/src/agent/orchestrator/smart-bridge/session-builder.mjs +116 -0
  196. package/src/agent/orchestrator/stall-policy.mjs +195 -0
  197. package/src/agent/orchestrator/tool-loop-guard.mjs +75 -0
  198. package/src/agent/orchestrator/tools/bash-policy-scan.mjs +77 -0
  199. package/src/agent/orchestrator/tools/bash-session.mjs +721 -0
  200. package/src/agent/orchestrator/tools/builtin/advisory-lock.mjs +171 -0
  201. package/src/agent/orchestrator/tools/builtin/arg-guard.mjs +455 -0
  202. package/src/agent/orchestrator/tools/builtin/atomic-write.mjs +236 -0
  203. package/src/agent/orchestrator/tools/builtin/bash-tool.mjs +480 -0
  204. package/src/agent/orchestrator/tools/builtin/binary-file.mjs +76 -0
  205. package/src/agent/orchestrator/tools/builtin/builtin-tools.mjs +256 -0
  206. package/src/agent/orchestrator/tools/builtin/cache-layers.mjs +386 -0
  207. package/src/agent/orchestrator/tools/builtin/cwd-utils.mjs +37 -0
  208. package/src/agent/orchestrator/tools/builtin/device-paths.mjs +154 -0
  209. package/src/agent/orchestrator/tools/builtin/diagnostics-tool.mjs +292 -0
  210. package/src/agent/orchestrator/tools/builtin/diff-utils.mjs +109 -0
  211. package/src/agent/orchestrator/tools/builtin/edit-base-guard.mjs +58 -0
  212. package/src/agent/orchestrator/tools/builtin/edit-byte-plan.mjs +240 -0
  213. package/src/agent/orchestrator/tools/builtin/edit-byte-utils.mjs +113 -0
  214. package/src/agent/orchestrator/tools/builtin/edit-commit.mjs +74 -0
  215. package/src/agent/orchestrator/tools/builtin/edit-context-utils.mjs +242 -0
  216. package/src/agent/orchestrator/tools/builtin/edit-diagnostics.mjs +211 -0
  217. package/src/agent/orchestrator/tools/builtin/edit-engine.mjs +1364 -0
  218. package/src/agent/orchestrator/tools/builtin/edit-failure-context.mjs +126 -0
  219. package/src/agent/orchestrator/tools/builtin/edit-hint.mjs +141 -0
  220. package/src/agent/orchestrator/tools/builtin/edit-match-utils.mjs +194 -0
  221. package/src/agent/orchestrator/tools/builtin/edit-partial-write.mjs +60 -0
  222. package/src/agent/orchestrator/tools/builtin/edit-stale-refresh.mjs +168 -0
  223. package/src/agent/orchestrator/tools/builtin/edit-tool.mjs +173 -0
  224. package/src/agent/orchestrator/tools/builtin/edit-utf8-guard.mjs +48 -0
  225. package/src/agent/orchestrator/tools/builtin/fs-reachability.mjs +48 -0
  226. package/src/agent/orchestrator/tools/builtin/fuzzy-match.mjs +99 -0
  227. package/src/agent/orchestrator/tools/builtin/glob-walk.mjs +170 -0
  228. package/src/agent/orchestrator/tools/builtin/grep-formatting.mjs +113 -0
  229. package/src/agent/orchestrator/tools/builtin/hash-utils.mjs +6 -0
  230. package/src/agent/orchestrator/tools/builtin/list-formatting.mjs +7 -0
  231. package/src/agent/orchestrator/tools/builtin/list-tool.mjs +593 -0
  232. package/src/agent/orchestrator/tools/builtin/native-edit-runner.mjs +89 -0
  233. package/src/agent/orchestrator/tools/builtin/notebook-edit-tool.mjs +300 -0
  234. package/src/agent/orchestrator/tools/builtin/open-config-tool.mjs +26 -0
  235. package/src/agent/orchestrator/tools/builtin/path-diagnostics.mjs +152 -0
  236. package/src/agent/orchestrator/tools/builtin/path-locks.mjs +35 -0
  237. package/src/agent/orchestrator/tools/builtin/path-utils.mjs +201 -0
  238. package/src/agent/orchestrator/tools/builtin/read-args.mjs +103 -0
  239. package/src/agent/orchestrator/tools/builtin/read-batch.mjs +172 -0
  240. package/src/agent/orchestrator/tools/builtin/read-constants.mjs +40 -0
  241. package/src/agent/orchestrator/tools/builtin/read-formatting.mjs +118 -0
  242. package/src/agent/orchestrator/tools/builtin/read-image-resize.mjs +189 -0
  243. package/src/agent/orchestrator/tools/builtin/read-image.mjs +88 -0
  244. package/src/agent/orchestrator/tools/builtin/read-lines.mjs +12 -0
  245. package/src/agent/orchestrator/tools/builtin/read-mode-tool.mjs +455 -0
  246. package/src/agent/orchestrator/tools/builtin/read-open.mjs +190 -0
  247. package/src/agent/orchestrator/tools/builtin/read-range-index.mjs +271 -0
  248. package/src/agent/orchestrator/tools/builtin/read-ranges.mjs +26 -0
  249. package/src/agent/orchestrator/tools/builtin/read-single-tool.mjs +728 -0
  250. package/src/agent/orchestrator/tools/builtin/read-snapshot-runtime.mjs +173 -0
  251. package/src/agent/orchestrator/tools/builtin/read-special-files.mjs +268 -0
  252. package/src/agent/orchestrator/tools/builtin/read-streaming.mjs +602 -0
  253. package/src/agent/orchestrator/tools/builtin/read-tool.mjs +530 -0
  254. package/src/agent/orchestrator/tools/builtin/read-windows.mjs +107 -0
  255. package/src/agent/orchestrator/tools/builtin/rename-tool.mjs +196 -0
  256. package/src/agent/orchestrator/tools/builtin/rg-runner.mjs +422 -0
  257. package/src/agent/orchestrator/tools/builtin/search-builders.mjs +158 -0
  258. package/src/agent/orchestrator/tools/builtin/search-tool.mjs +869 -0
  259. package/src/agent/orchestrator/tools/builtin/shell-analysis.mjs +653 -0
  260. package/src/agent/orchestrator/tools/builtin/shell-jobs.mjs +936 -0
  261. package/src/agent/orchestrator/tools/builtin/shell-output.mjs +36 -0
  262. package/src/agent/orchestrator/tools/builtin/shell-runtime.mjs +214 -0
  263. package/src/agent/orchestrator/tools/builtin/snapshot-helpers.mjs +143 -0
  264. package/src/agent/orchestrator/tools/builtin/snapshot-store.mjs +206 -0
  265. package/src/agent/orchestrator/tools/builtin/snapshot-validation.mjs +98 -0
  266. package/src/agent/orchestrator/tools/builtin/text-stats.mjs +69 -0
  267. package/src/agent/orchestrator/tools/builtin/windows-roots.mjs +23 -0
  268. package/src/agent/orchestrator/tools/builtin/write-tool.mjs +401 -0
  269. package/src/agent/orchestrator/tools/builtin.mjs +500 -0
  270. package/src/agent/orchestrator/tools/code-graph-prewarm-worker.mjs +39 -0
  271. package/src/agent/orchestrator/tools/code-graph-tool-defs.mjs +24 -0
  272. package/src/agent/orchestrator/tools/code-graph.mjs +4095 -0
  273. package/src/agent/orchestrator/tools/cwd-tool.mjs +298 -0
  274. package/src/agent/orchestrator/tools/destructive-warning.mjs +323 -0
  275. package/src/agent/orchestrator/tools/edit-normalize.mjs +603 -0
  276. package/src/agent/orchestrator/tools/env-scrub.mjs +100 -0
  277. package/src/agent/orchestrator/tools/graph-binary-fetcher.mjs +144 -0
  278. package/src/agent/orchestrator/tools/graph-manifest.json +26 -0
  279. package/src/agent/orchestrator/tools/host-input.mjs +204 -0
  280. package/src/agent/orchestrator/tools/mutation-content-cache.mjs +67 -0
  281. package/src/agent/orchestrator/tools/mutation-planner.mjs +75 -0
  282. package/src/agent/orchestrator/tools/next-call-utils.mjs +48 -0
  283. package/src/agent/orchestrator/tools/patch-binary-fetcher.mjs +133 -0
  284. package/src/agent/orchestrator/tools/patch-manifest.json +26 -0
  285. package/src/agent/orchestrator/tools/patch-tool-defs.mjs +20 -0
  286. package/src/agent/orchestrator/tools/patch.mjs +2754 -0
  287. package/src/agent/orchestrator/tools/progress-message.mjs +118 -0
  288. package/src/agent/orchestrator/tools/result-compression.mjs +279 -0
  289. package/src/agent/orchestrator/tools/shell-command.mjs +865 -0
  290. package/src/agent/orchestrator/tools/shell-exec-policy.mjs +89 -0
  291. package/src/agent/orchestrator/tools/shell-policy-danger-target.mjs +27 -0
  292. package/src/agent/orchestrator/tools/shell-policy-imports.mjs +7 -0
  293. package/src/agent/orchestrator/tools/shell-policy.mjs +345 -0
  294. package/src/agent/orchestrator/tools/shell-snapshot.mjs +313 -0
  295. package/src/agent/orchestrator/workflow-store.mjs +93 -0
  296. package/src/agent/tool-defs.mjs +103 -0
  297. package/src/channels/backends/discord.mjs +784 -0
  298. package/src/channels/data/voice-runtime-manifest.json +138 -0
  299. package/src/channels/index.mjs +3229 -0
  300. package/src/channels/lib/cli-worker-host.mjs +12 -0
  301. package/src/channels/lib/config-lock.mjs +13 -0
  302. package/src/channels/lib/config.mjs +292 -0
  303. package/src/channels/lib/drop-trace.mjs +71 -0
  304. package/src/channels/lib/event-pipeline.mjs +81 -0
  305. package/src/channels/lib/event-queue.mjs +345 -0
  306. package/src/channels/lib/executor.mjs +168 -0
  307. package/src/channels/lib/format.mjs +188 -0
  308. package/src/channels/lib/holidays.mjs +138 -0
  309. package/src/channels/lib/hook-pipe-server.mjs +802 -0
  310. package/src/channels/lib/interaction-workflows.mjs +184 -0
  311. package/src/channels/lib/memory-client.mjs +149 -0
  312. package/src/channels/lib/output-forwarder.mjs +765 -0
  313. package/src/channels/lib/runtime-paths.mjs +479 -0
  314. package/src/channels/lib/scheduler.mjs +723 -0
  315. package/src/channels/lib/session-control.mjs +36 -0
  316. package/src/channels/lib/session-discovery.mjs +103 -0
  317. package/src/channels/lib/settings.mjs +11 -0
  318. package/src/channels/lib/state-file.mjs +68 -0
  319. package/src/channels/lib/status-snapshot.mjs +219 -0
  320. package/src/channels/lib/tool-format.mjs +140 -0
  321. package/src/channels/lib/transcript-discovery.mjs +195 -0
  322. package/src/channels/lib/voice-runtime-fetcher.mjs +734 -0
  323. package/src/channels/lib/webhook.mjs +1179 -0
  324. package/src/channels/lib/whisper-server.mjs +477 -0
  325. package/src/channels/tool-defs.mjs +170 -0
  326. package/src/daemon/host.mjs +118 -0
  327. package/src/daemon/mcp-transport.mjs +47 -0
  328. package/src/daemon/session.mjs +100 -0
  329. package/src/daemon/thin-client.mjs +71 -0
  330. package/src/daemon/transport.mjs +163 -0
  331. package/src/memory/data/runtime-manifest.json +40 -0
  332. package/src/memory/index.mjs +3305 -0
  333. package/src/memory/lib/agent-ipc.mjs +93 -0
  334. package/src/memory/lib/bridge-trace-queries.mjs +120 -0
  335. package/src/memory/lib/core-memory-store.mjs +330 -0
  336. package/src/memory/lib/embedding-provider.mjs +269 -0
  337. package/src/memory/lib/embedding-worker.mjs +323 -0
  338. package/src/memory/lib/llm-worker-host.mjs +17 -0
  339. package/src/memory/lib/memory-cycle.mjs +11 -0
  340. package/src/memory/lib/memory-cycle1.mjs +641 -0
  341. package/src/memory/lib/memory-cycle2.mjs +1284 -0
  342. package/src/memory/lib/memory-cycle3.mjs +540 -0
  343. package/src/memory/lib/memory-embed.mjs +299 -0
  344. package/src/memory/lib/memory-extraction.mjs +5 -0
  345. package/src/memory/lib/memory-maintenance-store.mjs +32 -0
  346. package/src/memory/lib/memory-ops-policy.mjs +190 -0
  347. package/src/memory/lib/memory-recall-id-patch.mjs +15 -0
  348. package/src/memory/lib/memory-recall-read-query.mjs +7 -0
  349. package/src/memory/lib/memory-recall-scope-filter.mjs +63 -0
  350. package/src/memory/lib/memory-recall-store.mjs +621 -0
  351. package/src/memory/lib/memory-retrievers.mjs +112 -0
  352. package/src/memory/lib/memory-score.mjs +71 -0
  353. package/src/memory/lib/memory-text-utils.mjs +58 -0
  354. package/src/memory/lib/memory.mjs +412 -0
  355. package/src/memory/lib/model-profile.mjs +85 -0
  356. package/src/memory/lib/pg/adapter.mjs +308 -0
  357. package/src/memory/lib/pg/process.mjs +360 -0
  358. package/src/memory/lib/pg/supervisor.mjs +396 -0
  359. package/src/memory/lib/project-id-resolver.mjs +86 -0
  360. package/src/memory/lib/runtime-fetcher.mjs +442 -0
  361. package/src/memory/lib/trace-store.mjs +728 -0
  362. package/src/memory/tool-defs.mjs +79 -0
  363. package/src/search/index.mjs +1173 -0
  364. package/src/search/lib/backends/anthropic-oauth.mjs +98 -0
  365. package/src/search/lib/backends/exa.mjs +50 -0
  366. package/src/search/lib/backends/firecrawl.mjs +61 -0
  367. package/src/search/lib/backends/gemini-api.mjs +83 -0
  368. package/src/search/lib/backends/grok-oauth.mjs +86 -0
  369. package/src/search/lib/backends/index.mjs +150 -0
  370. package/src/search/lib/backends/openai-api.mjs +144 -0
  371. package/src/search/lib/backends/openai-oauth.mjs +98 -0
  372. package/src/search/lib/backends/openai-web-search.mjs +76 -0
  373. package/src/search/lib/backends/tavily.mjs +55 -0
  374. package/src/search/lib/backends/xai-api.mjs +113 -0
  375. package/src/search/lib/cache.mjs +131 -0
  376. package/src/search/lib/config.mjs +192 -0
  377. package/src/search/lib/formatter.mjs +115 -0
  378. package/src/search/lib/provider-usage.mjs +67 -0
  379. package/src/search/lib/providers.mjs +47 -0
  380. package/src/search/lib/search-intent.mjs +109 -0
  381. package/src/search/lib/setup-handler.mjs +261 -0
  382. package/src/search/lib/state.mjs +201 -0
  383. package/src/search/lib/web-tools.mjs +1207 -0
  384. package/src/search/tool-defs.mjs +83 -0
  385. package/src/setup/defender-exclusion.mjs +183 -0
  386. package/src/shared/abort-controller.mjs +15 -0
  387. package/src/shared/atomic-file.mjs +420 -0
  388. package/src/shared/config.mjs +350 -0
  389. package/src/shared/daemon-recycle.mjs +108 -0
  390. package/src/shared/disable-claude-builtins.mjs +88 -0
  391. package/src/shared/err-text.mjs +12 -0
  392. package/src/shared/llm/cost.mjs +66 -0
  393. package/src/shared/llm/http-agent.mjs +123 -0
  394. package/src/shared/llm/index.mjs +41 -0
  395. package/src/shared/llm/pid-cleanup.mjs +27 -0
  396. package/src/shared/llm/usage-log.mjs +47 -0
  397. package/src/shared/plugin-paths.mjs +58 -0
  398. package/src/shared/schedules-store.mjs +70 -0
  399. package/src/shared/seed.mjs +119 -0
  400. package/src/shared/user-cwd.mjs +213 -0
  401. package/src/shared/user-data-guard.mjs +238 -0
  402. package/src/status/aggregator.mjs +584 -0
  403. package/src/status/server.mjs +413 -0
  404. package/tools.json +1653 -0
@@ -0,0 +1,12 @@
1
+ function hasCliWorker() {
2
+ return true;
3
+ }
4
+ function startCliWorker(_options) {
5
+ }
6
+ async function stopCliWorker() {
7
+ }
8
+ export {
9
+ hasCliWorker,
10
+ startCliWorker,
11
+ stopCliWorker
12
+ };
@@ -0,0 +1,13 @@
1
+ let pending = Promise.resolve();
2
+ function withConfigLock(fn) {
3
+ const next = pending.then(() => fn());
4
+ pending = next.then(() => {
5
+ }, (e) => {
6
+ process.stderr.write(`[config-lock] Error: ${e}
7
+ `);
8
+ });
9
+ return next;
10
+ }
11
+ export {
12
+ withConfigLock
13
+ };
@@ -0,0 +1,292 @@
1
+ import { readFileSync, mkdirSync } from "fs";
2
+ import { join } from "path";
3
+ import { DiscordBackend } from "../backends/discord.mjs";
4
+ import { readSection, updateSection, CONFIG_PATH as MIXDOG_CONFIG_PATH, getDiscordToken, diagnoseDiscordTokenValue } from "../../shared/config.mjs";
5
+ import { listSchedules } from "../../shared/schedules-store.mjs";
6
+ import { isHolidaySync } from "./holidays.mjs";
7
+ if (!process.env.CLAUDE_PLUGIN_DATA) {
8
+ process.stderr.write(
9
+ "mixdog: CLAUDE_PLUGIN_DATA not set.\n This plugin must be run through Claude Code.\n"
10
+ );
11
+ process.exit(1);
12
+ }
13
+ const DATA_DIR = process.env.CLAUDE_PLUGIN_DATA;
14
+ const PLUGIN_ROOT = process.env.CLAUDE_PLUGIN_ROOT ?? new URL("..", import.meta.url).pathname;
15
+ const CONFIG_FILE = MIXDOG_CONFIG_PATH;
16
+ const DEFAULT_ACCESS = {
17
+ dmPolicy: "allowlist",
18
+ allowFrom: [],
19
+ channels: {}
20
+ };
21
+ const DEFAULT_CONFIG = {
22
+ backend: "discord",
23
+ discord: { token: "" },
24
+ access: DEFAULT_ACCESS,
25
+ mainChannel: "main",
26
+ channelsConfig: {
27
+ main: { channelId: "", mode: "interactive" }
28
+ }
29
+ };
30
+ // Shared defaults layer (DND / per-channel respectQuiet). Merge
31
+ // semantics: user values win; defaults only fill missing fields.
32
+ // Helper is exported so the setup UI and runtime both produce the same
33
+ // shape when the file has missing sections.
34
+ const CONFIG_DEFAULTS = {
35
+ quiet: { schedule: "23:00-09:00", holidays: false },
36
+ schedules: { respectQuiet: true },
37
+ webhook: { enabled: true, respectQuiet: false }
38
+ };
39
+ const DEFAULT_HOLIDAY_COUNTRY = "KR";
40
+ function normalizeHolidaySetting(value) {
41
+ if (value === true) return DEFAULT_HOLIDAY_COUNTRY;
42
+ if (typeof value === "string") {
43
+ const code = value.trim().toUpperCase();
44
+ return /^[A-Z]{2}$/.test(code) ? code : false;
45
+ }
46
+ return false;
47
+ }
48
+ function applyDefaults(config) {
49
+ const out = { ...(config || {}) };
50
+ out.quiet = { ...CONFIG_DEFAULTS.quiet, ...(out.quiet || {}) };
51
+ out.quiet.holidays = normalizeHolidaySetting(out.quiet.holidays);
52
+ out.schedules = { ...CONFIG_DEFAULTS.schedules, ...(out.schedules || {}) };
53
+ out.webhook = { ...CONFIG_DEFAULTS.webhook, ...(out.webhook || {}) };
54
+ return out;
55
+ }
56
+ /**
57
+ * Shared DND / quiet-window helper used by scheduler + webhook.
58
+ *
59
+ * Signature contract (as of 0.1.62):
60
+ * isInQuietWindow(cfg, now = new Date(), tz = null) -> boolean
61
+ *
62
+ * `cfg` accepts exactly two shapes (top-level config with `.quiet`
63
+ * subtree, or a flat `{ schedule, holidays }` descriptor); anything
64
+ * else returns `false`.
65
+ *
66
+ * `tz` is an optional IANA timezone. When set, both the schedule
67
+ * window (HH:MM) and the holiday/weekend day are evaluated in that
68
+ * zone; when absent, the host's local timezone is used (unchanged
69
+ * behavior for callers that omit it, e.g. webhook.mjs).
70
+ *
71
+ * Behavior:
72
+ * - Schedule window uses "HH:MM-HH:MM". Midnight-crossing windows
73
+ * (start > end, e.g. "23:00-09:00") are honored. When start === end
74
+ * the window is treated as empty/never (preserved doc-ambiguous
75
+ * behavior — callers should avoid that shape).
76
+ * - `holidays` enabled AND today is a recognized holiday => true,
77
+ * regardless of schedule window.
78
+ * - `holidays === false` or missing => holidays ignored.
79
+ *
80
+ * Holiday detection strategy (0.1.63):
81
+ * Sync, non-blocking lookup via holidays.mjs `isHolidaySync`, backed
82
+ * by a pre-warmed in-memory cache (Nager-sourced). The `holidays`
83
+ * value doubles as the ISO country code (`true` => default country).
84
+ * - cache WARM => real public-holiday data (weekday holidays count).
85
+ * - cache COLD => documented fallback: weekend-only (Sat/Sun), while
86
+ * an async warm is kicked off for the next evaluation. No blocking
87
+ * I/O and no heuristics beyond this weekend fallback.
88
+ *
89
+ * Exported so scheduler.mjs and webhook.mjs can share one implementation.
90
+ */
91
+ // Day-of-week and HH:MM for `now`, in `tz` when given, else host-local.
92
+ // An invalid IANA `tz` makes `Intl.DateTimeFormat` throw a RangeError;
93
+ // we catch it once and fall back to host-local rather than propagating.
94
+ function quietDayTime(now, tz) {
95
+ if (tz) {
96
+ try {
97
+ const parts = new Intl.DateTimeFormat("en-US", {
98
+ hour12: false, timeZone: tz,
99
+ hour: "2-digit", minute: "2-digit", weekday: "short",
100
+ }).formatToParts(now).reduce((acc, p) => { acc[p.type] = p.value; return acc; }, {});
101
+ const hour = parts.hour === "24" ? "00" : parts.hour;
102
+ const dowMap = { Sun: 0, Mon: 1, Tue: 2, Wed: 3, Thu: 4, Fri: 5, Sat: 6 };
103
+ return {
104
+ dow: dowMap[parts.weekday] ?? now.getDay(),
105
+ hhmm: `${hour}:${parts.minute}`,
106
+ };
107
+ } catch {
108
+ // Invalid timezone — fall through to host-local.
109
+ }
110
+ }
111
+ return {
112
+ dow: now.getDay(),
113
+ hhmm: `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}`,
114
+ };
115
+ }
116
+ // Return the target calendar day as a plain 'YYYY-MM-DD' string, in `tz`
117
+ // when given (else host-local). A string (not a Date) keeps the holiday
118
+ // contract symmetric: isHolidaySync compares the same string, so there
119
+ // is no UTC<->local round-trip to shift the day on UTC+12..+14 hosts.
120
+ // An invalid IANA `tz` throws a RangeError; catch once, fall to local.
121
+ function quietHolidayDateStr(now, tz) {
122
+ if (tz) {
123
+ try {
124
+ const parts = new Intl.DateTimeFormat("en-CA", {
125
+ timeZone: tz, year: "numeric", month: "2-digit", day: "2-digit",
126
+ }).formatToParts(now).reduce((acc, p) => { acc[p.type] = p.value; return acc; }, {});
127
+ return `${parts.year}-${parts.month}-${parts.day}`;
128
+ } catch {
129
+ // Invalid timezone — fall through to host-local.
130
+ }
131
+ }
132
+ return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
133
+ }
134
+ function isInQuietWindow(cfg, now = new Date(), tz = null) {
135
+ if (!cfg || typeof cfg !== "object") return false;
136
+ // Auto-detect shape: prefer cfg.quiet when present, else treat cfg as
137
+ // the flat { schedule, holidays } descriptor.
138
+ const quiet = cfg.quiet && typeof cfg.quiet === "object" ? cfg.quiet : cfg;
139
+ const schedule = quiet.schedule;
140
+ const holidaysOn = quiet.holidays === true || (typeof quiet.holidays === "string" && !!quiet.holidays.trim());
141
+ const country = quiet.holidays === true
142
+ ? DEFAULT_HOLIDAY_COUNTRY
143
+ : (typeof quiet.holidays === "string" ? quiet.holidays.trim().toUpperCase() : null);
144
+
145
+ // Holiday branch: toggle on AND today qualifies => quiet regardless of window.
146
+ // Sync, pre-warmed cache lookup; cold cache falls back to weekend-only.
147
+ if (holidaysOn) {
148
+ const holiday = isHolidaySync(quietHolidayDateStr(now, tz), country);
149
+ if (holiday === true) return true;
150
+ if (holiday === null) {
151
+ // Cold cache: documented Sat/Sun fallback until the async warm lands.
152
+ const { dow } = quietDayTime(now, tz);
153
+ if (dow === 0 || dow === 6) return true;
154
+ }
155
+ // Warm cache + not a holiday: fall through to the schedule window.
156
+ }
157
+
158
+ // Schedule window check (TZ-aware when tz is set; host-local otherwise).
159
+ if (!schedule || typeof schedule !== "string") return false;
160
+ const parts = schedule.split("-");
161
+ if (parts.length !== 2) return false;
162
+ const [start, end] = parts;
163
+ // start === end => empty window (never matches); documented caveat.
164
+ const { hhmm } = quietDayTime(now, tz);
165
+ if (start > end) return hhmm >= start || hhmm < end; // midnight-crossing
166
+ return hhmm >= start && hhmm < end;
167
+ }
168
+ function loadConfig() {
169
+ try {
170
+ let raw = readSection("channels");
171
+ raw = raw && typeof raw === "object" ? raw : {};
172
+ // Schedules live in `${CLAUDE_PLUGIN_DATA}/schedules/<name>/` (single
173
+ // source of truth). The legacy `raw.schedules.items` / `raw.nonInteractive`
174
+ // / `raw.interactive` arrays in mixdog-config.json are no longer read.
175
+ const scheduleEntries = listSchedules().filter((s) => s.enabled !== false);
176
+ // Channel-presence routing (no `type` field): an entry WITH a channel is
177
+ // dispatched directly to that channel; an entry WITHOUT a channel is
178
+ // injected into the current (Lead) session. Mirrors the webhook model.
179
+ raw.nonInteractive = scheduleEntries.filter((i) => !!i.channel);
180
+ raw.interactive = scheduleEntries.filter((i) => !i.channel);
181
+ const accessChannels = { ...raw.access?.channels ?? {} };
182
+ // voice config lives at the top level of mixdog-config.json (peer of
183
+ // channels), so readSection("channels") never sees it. Pull it explicitly.
184
+ let voice = {};
185
+ try {
186
+ const v = readSection("voice");
187
+ if (v && typeof v === "object") voice = v;
188
+ } catch { /* missing section is fine */ }
189
+ const discordToken = getDiscordToken();
190
+ const discordTokenProblem = diagnoseDiscordTokenValue(discordToken, raw);
191
+ if (discordTokenProblem) {
192
+ process.stderr.write(`mixdog: discord token ignored: ${discordTokenProblem}\n`);
193
+ }
194
+ return applyDefaults({
195
+ ...DEFAULT_CONFIG,
196
+ ...raw,
197
+ backend: "discord",
198
+ discord: { ...DEFAULT_CONFIG.discord, ...(({ token: _, ...rest }) => rest)(raw.discord || {}), ...(discordToken && !discordTokenProblem ? { token: discordToken } : {}) },
199
+ access: {
200
+ ...DEFAULT_ACCESS,
201
+ // Drop the retired pairing-era keys at the config layer too (the
202
+ // Discord backend's normalizeAccess() is the runtime belt): legacy
203
+ // dmPolicy "pairing" → "allowlist", and the `pending` code store is
204
+ // gone entirely.
205
+ ...(({ pending: _pending, ...rest }) => rest)(raw.access || {}),
206
+ ...(raw.access?.dmPolicy === "pairing" ? { dmPolicy: "allowlist" } : {}),
207
+ channels: accessChannels,
208
+ },
209
+ voice: { ...(raw.voice || {}), ...voice }
210
+ });
211
+ } catch (err) {
212
+ if (err.code === "ENOENT") {
213
+ mkdirSync(DATA_DIR, { recursive: true });
214
+ updateSection("channels", () => DEFAULT_CONFIG);
215
+ process.stderr.write(
216
+ `mixdog: default channels config created in ${MIXDOG_CONFIG_PATH}
217
+ edit discord.token and channelsConfig.main.channelId to connect.
218
+ `
219
+ );
220
+ return applyDefaults(DEFAULT_CONFIG);
221
+ }
222
+ throw err;
223
+ }
224
+ }
225
+ const HEADLESS_BACKEND = {
226
+ name: "headless",
227
+ async connect() {
228
+ },
229
+ async disconnect() {
230
+ },
231
+ async sendMessage() {
232
+ return { sentIds: [] };
233
+ },
234
+ async fetchMessages() {
235
+ return [];
236
+ },
237
+ async react() {
238
+ },
239
+ async removeReaction() {
240
+ },
241
+ async editMessage() {
242
+ return "";
243
+ },
244
+ async deleteMessage() {
245
+ },
246
+ async downloadAttachment() {
247
+ return Buffer.alloc(0);
248
+ },
249
+ on() {
250
+ }
251
+ };
252
+ function createBackend(config) {
253
+ const discordToken = getDiscordToken();
254
+ const discordTokenProblem = diagnoseDiscordTokenValue(discordToken, config);
255
+ if (discordTokenProblem) {
256
+ process.stderr.write(`mixdog: discord token ignored: ${discordTokenProblem}\n`);
257
+ }
258
+ if (config.backend !== "discord" || !discordToken || discordTokenProblem) {
259
+ process.stderr.write("mixdog: discord bot not configured; channel worker running in headless mode\n");
260
+ return HEADLESS_BACKEND;
261
+ }
262
+ const stateDir = config.discord.stateDir ?? join(DATA_DIR, "discord");
263
+ mkdirSync(stateDir, { recursive: true });
264
+ return new DiscordBackend({
265
+ ...config.discord,
266
+ configPath: CONFIG_FILE,
267
+ access: config.access,
268
+ // Single-source channel setup: the main channel is auto-allowed inside
269
+ // DiscordBackend.loadAccess() so a configured channelsConfig.main.channelId
270
+ // is enough for both inbound and outbound — no separate access.channels entry.
271
+ mainChannelId: config.channelsConfig?.main?.channelId
272
+ }, stateDir);
273
+ }
274
+ const PROFILE_FILE = join(DATA_DIR, "profile.json");
275
+ function loadProfileConfig() {
276
+ try {
277
+ return JSON.parse(readFileSync(PROFILE_FILE, "utf8"));
278
+ } catch {
279
+ return {};
280
+ }
281
+ }
282
+ export {
283
+ DATA_DIR,
284
+ DEFAULT_HOLIDAY_COUNTRY,
285
+ PLUGIN_ROOT,
286
+ applyDefaults,
287
+ createBackend,
288
+ getDiscordToken,
289
+ isInQuietWindow,
290
+ loadConfig,
291
+ loadProfileConfig
292
+ };
@@ -0,0 +1,71 @@
1
+ import { statSync, renameSync, createWriteStream } from "fs";
2
+ import { join } from "path";
3
+ import { homedir } from "os";
4
+ // ── drop-trace (output-forwarder) ───────────────────────────────────────────
5
+ const _dtDataDir = process.env.CLAUDE_PLUGIN_DATA || join(homedir(), ".mixdog-data");
6
+ const _dtLog = join(_dtDataDir, "drop-trace.log");
7
+ const DROP_TRACE_ENABLED =
8
+ process.env.MIXDOG_DROP_TRACE === "1" ||
9
+ process.env.MIXDOG_DROP_TRACE === "true" ||
10
+ process.env.MIXDOG_DEBUG_CHANNELS === "1" ||
11
+ process.env.MIXDOG_DEBUG_CHANNELS === "true";
12
+ // One-shot rotation at module init (10 MB threshold, .1 suffix overwrite).
13
+ if (DROP_TRACE_ENABLED) {
14
+ try { if (statSync(_dtLog).size > 10 * 1024 * 1024) renameSync(_dtLog, _dtLog + '.1') } catch {}
15
+ }
16
+
17
+ // ── Buffered drop-trace writer ───────────────────────────────────────────────
18
+ // Flushes every 1 s OR when the buffer reaches 64 KB — whichever fires first.
19
+ // Drains synchronously on process exit so no log lines are lost.
20
+ let _dtBuf = "";
21
+ let _dtBufBytes = 0;
22
+ let _dtFlushTimer = null;
23
+ let _dtStream = null;
24
+ function _dtGetStream() {
25
+ if (!_dtStream) _dtStream = createWriteStream(_dtLog, { flags: "a" });
26
+ return _dtStream;
27
+ }
28
+ function _dtFlush() {
29
+ if (_dtFlushTimer) { clearTimeout(_dtFlushTimer); _dtFlushTimer = null; }
30
+ if (!_dtBuf) return;
31
+ try { _dtGetStream().write(_dtBuf); } catch {}
32
+ _dtBuf = "";
33
+ _dtBufBytes = 0;
34
+ }
35
+ function _dtScheduleFlush() {
36
+ if (_dtFlushTimer) return;
37
+ _dtFlushTimer = setTimeout(_dtFlush, 1000);
38
+ if (_dtFlushTimer.unref) _dtFlushTimer.unref();
39
+ }
40
+ function _dtAppend(line) {
41
+ _dtBuf += line;
42
+ _dtBufBytes += Buffer.byteLength(line);
43
+ if (_dtBufBytes >= 65536) { _dtFlush(); return; }
44
+ _dtScheduleFlush();
45
+ }
46
+ process.on("exit", _dtFlush);
47
+ // Note: do not install a module-level SIGTERM handler that calls
48
+ // process.exit() here. The channels worker owns shutdown sequencing
49
+ // (forwarder drain, queue persist, etc.) and a library-level exit(0)
50
+ // preempts that drain. The `exit` listener above still synchronously
51
+ // flushes buffered trace bytes when the worker exits on its own terms.
52
+
53
+ function _dtPreview(text) {
54
+ if (!text) return "";
55
+ const s = String(text).slice(0, 121).replace(/\n/g, "\\n");
56
+ return s.length > 120 ? s.slice(0, 120) + "…" : s;
57
+ }
58
+ function dropTrace(event, fields) {
59
+ if (!DROP_TRACE_ENABLED) return;
60
+ try {
61
+ const ts = new Date().toISOString();
62
+ if (!fields) {
63
+ _dtAppend(`[${ts}][pid=${process.pid}] ${event}\n`);
64
+ return;
65
+ }
66
+ const kv = " " + Object.entries(fields).map(([k, v]) => `${k}=${v}`).join(" ");
67
+ _dtAppend(`[${ts}][pid=${process.pid}] ${event}${kv}\n`);
68
+ } catch {}
69
+ }
70
+
71
+ export { dropTrace, _dtPreview, DROP_TRACE_ENABLED };
@@ -0,0 +1,81 @@
1
+ import { EventQueue } from "./event-queue.mjs";
2
+ import { applyParser, evaluateFilter, applyTemplate, logEvent } from "./executor.mjs";
3
+ class EventPipeline {
4
+ rules;
5
+ queue;
6
+ constructor(config, channelsConfig) {
7
+ const rawRules = config?.rules;
8
+ this.rules = (Array.isArray(rawRules) ? rawRules : [])
9
+ .filter((r) => r && typeof r === "object" && r.enabled !== false);
10
+ this.queue = new EventQueue(config?.queue, channelsConfig);
11
+ }
12
+ getQueue() {
13
+ return this.queue;
14
+ }
15
+ start() {
16
+ this.queue.start();
17
+ }
18
+ stop() {
19
+ this.queue.stop();
20
+ }
21
+ reloadConfig(config, channelsConfig) {
22
+ const rawRules = config?.rules;
23
+ this.rules = (Array.isArray(rawRules) ? rawRules : [])
24
+ .filter((r) => r && typeof r === "object" && r.enabled !== false);
25
+ this.queue.reloadConfig(config?.queue, channelsConfig);
26
+ }
27
+ // ── Source: webhook ───────────────────────────────────────────────
28
+ /** Handle an incoming webhook event */
29
+ handleWebhook(endpointName, body, headers) {
30
+ const rule = this.rules.find((r) => r.source === "webhook" && r.name === endpointName);
31
+ if (!rule) return false;
32
+ const data = applyParser(rule.parser, body, headers);
33
+ if (rule.filter && !evaluateFilter(rule.filter, data)) {
34
+ return true;
35
+ }
36
+ const prompt = applyTemplate(rule.execute, data);
37
+ this.enqueue(rule, prompt);
38
+ return true;
39
+ }
40
+ // ── Direct enqueue (folder-based webhooks) ─────────────────────────
41
+ enqueueDirect(name, prompt, channel, exec = "interactive", instruction) {
42
+ const item = {
43
+ name,
44
+ source: "webhook",
45
+ priority: "normal",
46
+ prompt,
47
+ instruction,
48
+ exec,
49
+ channel,
50
+ timestamp: Date.now()
51
+ };
52
+ this.queue.enqueue(item);
53
+ }
54
+ // ── Common enqueue ────────────────────────────────────────────────
55
+ enqueue(rule, prompt) {
56
+ const item = {
57
+ name: rule.name,
58
+ source: rule.source,
59
+ priority: rule.priority,
60
+ prompt,
61
+ exec: rule.exec,
62
+ channel: rule.channel,
63
+ script: rule.script,
64
+ timestamp: Date.now()
65
+ };
66
+ this.queue.enqueue(item);
67
+ }
68
+ // ── Status ────────────────────────────────────────────────────────
69
+ getRules() {
70
+ return this.rules;
71
+ }
72
+ getStatus() {
73
+ return {
74
+ rules: this.rules.length,
75
+ queue: this.queue.getStatus()
76
+ };
77
+ }
78
+ }
79
+ export {
80
+ EventPipeline
81
+ };