mach6-core 1.1.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 (245) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +454 -0
  3. package/dist/agent/context-monitor.d.ts +40 -0
  4. package/dist/agent/context-monitor.d.ts.map +1 -0
  5. package/dist/agent/context-monitor.js +138 -0
  6. package/dist/agent/context-monitor.js.map +1 -0
  7. package/dist/agent/context.d.ts +8 -0
  8. package/dist/agent/context.d.ts.map +1 -0
  9. package/dist/agent/context.js +197 -0
  10. package/dist/agent/context.js.map +1 -0
  11. package/dist/agent/runner.d.ts +42 -0
  12. package/dist/agent/runner.d.ts.map +1 -0
  13. package/dist/agent/runner.js +168 -0
  14. package/dist/agent/runner.js.map +1 -0
  15. package/dist/agent/system-prompt.d.ts +10 -0
  16. package/dist/agent/system-prompt.d.ts.map +1 -0
  17. package/dist/agent/system-prompt.js +120 -0
  18. package/dist/agent/system-prompt.js.map +1 -0
  19. package/dist/boot/sequence.d.ts +34 -0
  20. package/dist/boot/sequence.d.ts.map +1 -0
  21. package/dist/boot/sequence.js +103 -0
  22. package/dist/boot/sequence.js.map +1 -0
  23. package/dist/channels/__test__/integration.test.d.ts +8 -0
  24. package/dist/channels/__test__/integration.test.d.ts.map +1 -0
  25. package/dist/channels/__test__/integration.test.js +221 -0
  26. package/dist/channels/__test__/integration.test.js.map +1 -0
  27. package/dist/channels/adapter.d.ts +53 -0
  28. package/dist/channels/adapter.d.ts.map +1 -0
  29. package/dist/channels/adapter.js +164 -0
  30. package/dist/channels/adapter.js.map +1 -0
  31. package/dist/channels/adapters/discord.d.ts +49 -0
  32. package/dist/channels/adapters/discord.d.ts.map +1 -0
  33. package/dist/channels/adapters/discord.js +382 -0
  34. package/dist/channels/adapters/discord.js.map +1 -0
  35. package/dist/channels/adapters/whatsapp.d.ts +59 -0
  36. package/dist/channels/adapters/whatsapp.d.ts.map +1 -0
  37. package/dist/channels/adapters/whatsapp.js +503 -0
  38. package/dist/channels/adapters/whatsapp.js.map +1 -0
  39. package/dist/channels/bus.d.ts +55 -0
  40. package/dist/channels/bus.d.ts.map +1 -0
  41. package/dist/channels/bus.js +307 -0
  42. package/dist/channels/bus.js.map +1 -0
  43. package/dist/channels/formatter.d.ts +16 -0
  44. package/dist/channels/formatter.d.ts.map +1 -0
  45. package/dist/channels/formatter.js +226 -0
  46. package/dist/channels/formatter.js.map +1 -0
  47. package/dist/channels/presence.d.ts +67 -0
  48. package/dist/channels/presence.d.ts.map +1 -0
  49. package/dist/channels/presence.js +209 -0
  50. package/dist/channels/presence.js.map +1 -0
  51. package/dist/channels/registry.d.ts +57 -0
  52. package/dist/channels/registry.d.ts.map +1 -0
  53. package/dist/channels/registry.js +159 -0
  54. package/dist/channels/registry.js.map +1 -0
  55. package/dist/channels/router.d.ts +49 -0
  56. package/dist/channels/router.d.ts.map +1 -0
  57. package/dist/channels/router.js +244 -0
  58. package/dist/channels/router.js.map +1 -0
  59. package/dist/channels/types.d.ts +279 -0
  60. package/dist/channels/types.d.ts.map +1 -0
  61. package/dist/channels/types.js +67 -0
  62. package/dist/channels/types.js.map +1 -0
  63. package/dist/cli/brand.d.ts +71 -0
  64. package/dist/cli/brand.d.ts.map +1 -0
  65. package/dist/cli/brand.js +194 -0
  66. package/dist/cli/brand.js.map +1 -0
  67. package/dist/cli/wizard.d.ts +8 -0
  68. package/dist/cli/wizard.d.ts.map +1 -0
  69. package/dist/cli/wizard.js +520 -0
  70. package/dist/cli/wizard.js.map +1 -0
  71. package/dist/config/config.d.ts +47 -0
  72. package/dist/config/config.d.ts.map +1 -0
  73. package/dist/config/config.js +63 -0
  74. package/dist/config/config.js.map +1 -0
  75. package/dist/config/validator.d.ts +18 -0
  76. package/dist/config/validator.d.ts.map +1 -0
  77. package/dist/config/validator.js +92 -0
  78. package/dist/config/validator.js.map +1 -0
  79. package/dist/cron/budget.d.ts +39 -0
  80. package/dist/cron/budget.d.ts.map +1 -0
  81. package/dist/cron/budget.js +98 -0
  82. package/dist/cron/budget.js.map +1 -0
  83. package/dist/formatters/markdown.d.ts +6 -0
  84. package/dist/formatters/markdown.d.ts.map +1 -0
  85. package/dist/formatters/markdown.js +85 -0
  86. package/dist/formatters/markdown.js.map +1 -0
  87. package/dist/gateway/daemon.d.ts +97 -0
  88. package/dist/gateway/daemon.d.ts.map +1 -0
  89. package/dist/gateway/daemon.js +772 -0
  90. package/dist/gateway/daemon.js.map +1 -0
  91. package/dist/heartbeat/scheduler.d.ts +45 -0
  92. package/dist/heartbeat/scheduler.d.ts.map +1 -0
  93. package/dist/heartbeat/scheduler.js +102 -0
  94. package/dist/heartbeat/scheduler.js.map +1 -0
  95. package/dist/index.d.ts +3 -0
  96. package/dist/index.d.ts.map +1 -0
  97. package/dist/index.js +305 -0
  98. package/dist/index.js.map +1 -0
  99. package/dist/memory/integrity.d.ts +37 -0
  100. package/dist/memory/integrity.d.ts.map +1 -0
  101. package/dist/memory/integrity.js +108 -0
  102. package/dist/memory/integrity.js.map +1 -0
  103. package/dist/providers/anthropic.d.ts +3 -0
  104. package/dist/providers/anthropic.d.ts.map +1 -0
  105. package/dist/providers/anthropic.js +232 -0
  106. package/dist/providers/anthropic.js.map +1 -0
  107. package/dist/providers/diagnostics.d.ts +18 -0
  108. package/dist/providers/diagnostics.d.ts.map +1 -0
  109. package/dist/providers/diagnostics.js +87 -0
  110. package/dist/providers/diagnostics.js.map +1 -0
  111. package/dist/providers/github-copilot.d.ts +3 -0
  112. package/dist/providers/github-copilot.d.ts.map +1 -0
  113. package/dist/providers/github-copilot.js +145 -0
  114. package/dist/providers/github-copilot.js.map +1 -0
  115. package/dist/providers/gladius.d.ts +3 -0
  116. package/dist/providers/gladius.d.ts.map +1 -0
  117. package/dist/providers/gladius.js +16 -0
  118. package/dist/providers/gladius.js.map +1 -0
  119. package/dist/providers/openai.d.ts +3 -0
  120. package/dist/providers/openai.d.ts.map +1 -0
  121. package/dist/providers/openai.js +161 -0
  122. package/dist/providers/openai.js.map +1 -0
  123. package/dist/providers/retry.d.ts +2 -0
  124. package/dist/providers/retry.d.ts.map +1 -0
  125. package/dist/providers/retry.js +50 -0
  126. package/dist/providers/retry.js.map +1 -0
  127. package/dist/providers/types.d.ts +78 -0
  128. package/dist/providers/types.d.ts.map +1 -0
  129. package/dist/providers/types.js +3 -0
  130. package/dist/providers/types.js.map +1 -0
  131. package/dist/security/sanitizer.d.ts +26 -0
  132. package/dist/security/sanitizer.d.ts.map +1 -0
  133. package/dist/security/sanitizer.js +115 -0
  134. package/dist/security/sanitizer.js.map +1 -0
  135. package/dist/sessions/manager.d.ts +40 -0
  136. package/dist/sessions/manager.d.ts.map +1 -0
  137. package/dist/sessions/manager.js +255 -0
  138. package/dist/sessions/manager.js.map +1 -0
  139. package/dist/sessions/queue.d.ts +41 -0
  140. package/dist/sessions/queue.d.ts.map +1 -0
  141. package/dist/sessions/queue.js +93 -0
  142. package/dist/sessions/queue.js.map +1 -0
  143. package/dist/sessions/store.d.ts +12 -0
  144. package/dist/sessions/store.d.ts.map +1 -0
  145. package/dist/sessions/store.js +74 -0
  146. package/dist/sessions/store.js.map +1 -0
  147. package/dist/sessions/sub-agent.d.ts +18 -0
  148. package/dist/sessions/sub-agent.d.ts.map +1 -0
  149. package/dist/sessions/sub-agent.js +117 -0
  150. package/dist/sessions/sub-agent.js.map +1 -0
  151. package/dist/sessions/types.d.ts +48 -0
  152. package/dist/sessions/types.d.ts.map +1 -0
  153. package/dist/sessions/types.js +3 -0
  154. package/dist/sessions/types.js.map +1 -0
  155. package/dist/test/channel-integration.d.ts +10 -0
  156. package/dist/test/channel-integration.d.ts.map +1 -0
  157. package/dist/test/channel-integration.js +226 -0
  158. package/dist/test/channel-integration.js.map +1 -0
  159. package/dist/test/prompt-test.d.ts +2 -0
  160. package/dist/test/prompt-test.d.ts.map +1 -0
  161. package/dist/test/prompt-test.js +33 -0
  162. package/dist/test/prompt-test.js.map +1 -0
  163. package/dist/test/smoke.d.ts +8 -0
  164. package/dist/test/smoke.d.ts.map +1 -0
  165. package/dist/test/smoke.js +134 -0
  166. package/dist/test/smoke.js.map +1 -0
  167. package/dist/tools/builtin/comb.d.ts +4 -0
  168. package/dist/tools/builtin/comb.d.ts.map +1 -0
  169. package/dist/tools/builtin/comb.js +50 -0
  170. package/dist/tools/builtin/comb.js.map +1 -0
  171. package/dist/tools/builtin/edit.d.ts +3 -0
  172. package/dist/tools/builtin/edit.d.ts.map +1 -0
  173. package/dist/tools/builtin/edit.js +42 -0
  174. package/dist/tools/builtin/edit.js.map +1 -0
  175. package/dist/tools/builtin/exec.d.ts +3 -0
  176. package/dist/tools/builtin/exec.d.ts.map +1 -0
  177. package/dist/tools/builtin/exec.js +75 -0
  178. package/dist/tools/builtin/exec.js.map +1 -0
  179. package/dist/tools/builtin/image.d.ts +3 -0
  180. package/dist/tools/builtin/image.d.ts.map +1 -0
  181. package/dist/tools/builtin/image.js +208 -0
  182. package/dist/tools/builtin/image.js.map +1 -0
  183. package/dist/tools/builtin/memory.d.ts +3 -0
  184. package/dist/tools/builtin/memory.d.ts.map +1 -0
  185. package/dist/tools/builtin/memory.js +36 -0
  186. package/dist/tools/builtin/memory.js.map +1 -0
  187. package/dist/tools/builtin/message.d.ts +13 -0
  188. package/dist/tools/builtin/message.d.ts.map +1 -0
  189. package/dist/tools/builtin/message.js +330 -0
  190. package/dist/tools/builtin/message.js.map +1 -0
  191. package/dist/tools/builtin/process.d.ts +43 -0
  192. package/dist/tools/builtin/process.d.ts.map +1 -0
  193. package/dist/tools/builtin/process.js +178 -0
  194. package/dist/tools/builtin/process.js.map +1 -0
  195. package/dist/tools/builtin/read.d.ts +3 -0
  196. package/dist/tools/builtin/read.d.ts.map +1 -0
  197. package/dist/tools/builtin/read.js +36 -0
  198. package/dist/tools/builtin/read.js.map +1 -0
  199. package/dist/tools/builtin/spawn.d.ts +8 -0
  200. package/dist/tools/builtin/spawn.d.ts.map +1 -0
  201. package/dist/tools/builtin/spawn.js +90 -0
  202. package/dist/tools/builtin/spawn.js.map +1 -0
  203. package/dist/tools/builtin/tts.d.ts +3 -0
  204. package/dist/tools/builtin/tts.d.ts.map +1 -0
  205. package/dist/tools/builtin/tts.js +77 -0
  206. package/dist/tools/builtin/tts.js.map +1 -0
  207. package/dist/tools/builtin/web-fetch.d.ts +3 -0
  208. package/dist/tools/builtin/web-fetch.d.ts.map +1 -0
  209. package/dist/tools/builtin/web-fetch.js +46 -0
  210. package/dist/tools/builtin/web-fetch.js.map +1 -0
  211. package/dist/tools/builtin/write.d.ts +3 -0
  212. package/dist/tools/builtin/write.d.ts.map +1 -0
  213. package/dist/tools/builtin/write.js +31 -0
  214. package/dist/tools/builtin/write.js.map +1 -0
  215. package/dist/tools/mcp-bridge.d.ts +42 -0
  216. package/dist/tools/mcp-bridge.d.ts.map +1 -0
  217. package/dist/tools/mcp-bridge.js +198 -0
  218. package/dist/tools/mcp-bridge.js.map +1 -0
  219. package/dist/tools/policy.d.ts +57 -0
  220. package/dist/tools/policy.d.ts.map +1 -0
  221. package/dist/tools/policy.js +106 -0
  222. package/dist/tools/policy.js.map +1 -0
  223. package/dist/tools/registry.d.ts +15 -0
  224. package/dist/tools/registry.d.ts.map +1 -0
  225. package/dist/tools/registry.js +41 -0
  226. package/dist/tools/registry.js.map +1 -0
  227. package/dist/tools/sandbox.d.ts +91 -0
  228. package/dist/tools/sandbox.d.ts.map +1 -0
  229. package/dist/tools/sandbox.js +279 -0
  230. package/dist/tools/sandbox.js.map +1 -0
  231. package/dist/tools/types.d.ts +23 -0
  232. package/dist/tools/types.d.ts.map +1 -0
  233. package/dist/tools/types.js +3 -0
  234. package/dist/tools/types.js.map +1 -0
  235. package/dist/web/http-api.d.ts +61 -0
  236. package/dist/web/http-api.d.ts.map +1 -0
  237. package/dist/web/http-api.js +200 -0
  238. package/dist/web/http-api.js.map +1 -0
  239. package/dist/web/server.d.ts +7 -0
  240. package/dist/web/server.d.ts.map +1 -0
  241. package/dist/web/server.js +396 -0
  242. package/dist/web/server.js.map +1 -0
  243. package/mach6.example.json +50 -0
  244. package/package.json +58 -0
  245. package/web/index.html +1370 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Artifact Virtual (SMC-Private) Limited
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,454 @@
1
+ <div align="center">
2
+
3
+ # ⚡ Mach6
4
+
5
+ **Multi-channel AI agent framework that runs on a laptop.**
6
+
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
8
+ [![Node.js 20+](https://img.shields.io/badge/Node.js-20%2B-green.svg)](https://nodejs.org/)
9
+ [![Platform](https://img.shields.io/badge/Platform-Windows%20%7C%20Linux%20%7C%20macOS-lightgrey.svg)]()
10
+ [![TypeScript](https://img.shields.io/badge/TypeScript-5.x-blue.svg)](https://www.typescriptlang.org/)
11
+
12
+ A persistent daemon that connects to messaging platforms, routes conversations through LLM providers, and executes tool calls in an agentic loop. No cloud dependencies. No vendor lock-in. **Your machine, your data, your keys.**
13
+
14
+ [Quick Start](#-quick-start) · [Architecture](#-architecture) · [Config](#-configuration) · [Providers](#-providers) · [Tools](#-tools) · [Web UI](#-web-ui)
15
+
16
+ </div>
17
+
18
+ ---
19
+
20
+ ## 🚀 Quick Start
21
+
22
+ ```bash
23
+ # Clone & build
24
+ git clone https://github.com/amuzetnoM/mach6.git
25
+ cd mach6
26
+ npm install && npm run build
27
+
28
+ # Interactive setup — generates mach6.json + .env
29
+ npx mach6 init
30
+
31
+ # Start the daemon
32
+ node dist/gateway/daemon.js --config=mach6.json
33
+ ```
34
+
35
+ > **Windows (PowerShell):** Same commands — Mach6 is fully cross-platform. Use `.\mach6.ps1` or `node dist/gateway/daemon.js --config=mach6.json`.
36
+
37
+ <details>
38
+ <summary><strong>Manual setup (without wizard)</strong></summary>
39
+
40
+ ```bash
41
+ cp mach6.example.json mach6.json
42
+ cp .env.example .env
43
+ # Edit both files — set API keys, channel tokens, workspace path, ownerIds
44
+ ```
45
+
46
+ </details>
47
+
48
+ ---
49
+
50
+ ## 🏗 Architecture
51
+
52
+ ```
53
+ ┌──────────────┐
54
+ │ Web UI │
55
+ │ :3006 │
56
+ └──────┬───────┘
57
+ │ SSE
58
+ ┌──────────┐ ┌──────────┐ ┌──┴───────────┐ ┌──────────┐ ┌─────────┐
59
+ │ Discord │──│ Router │──│ Message Bus │──│ Agent │──│ Provider│──→ LLM
60
+ │ WhatsApp │ │ Policy │ │ Priority Q │ │ Runner │ │ (swap) │
61
+ │ HTTP API │ │ Dedup │ │ Coalesce │ │ Tools │ └─────────┘
62
+ └──────────┘ └──────────┘ │ Interrupt │ │ Abort │
63
+ │ Backpressure│ │ Iterate │
64
+ └──────────────┘ └──────────┘
65
+ ```
66
+
67
+ | Layer | What it does |
68
+ |-------|-------------|
69
+ | **Channels** | Discord (discord.js), WhatsApp (Baileys v7). Adapter pattern — add any platform. |
70
+ | **Router** | Policy enforcement, JID normalization, deduplication, interrupt detection, priority. |
71
+ | **Message Bus** | Priority queue with interrupt bypass, message coalescing, backpressure management. |
72
+ | **Agent Runner** | Agentic loop — tool calling, context management, abort signals, iteration limits. |
73
+ | **Providers** | GitHub Copilot, Anthropic, OpenAI, Gladius (local). Hot-swappable mid-session. |
74
+ | **Tools** | 18 built-in. File I/O, shell, browser, TTS, memory, process management, messaging. |
75
+ | **Sessions** | Persistent, labeled, TTL-aware. Sub-agent spawning up to depth 3. |
76
+
77
+ ---
78
+
79
+ ## 🔥 What Makes Mach6 Different
80
+
81
+ ### Real-Time Interrupts
82
+
83
+ Most agent frameworks are request-response: you send a message, you wait, you get a reply. If the agent is mid-turn, your new message queues silently. You can't stop it. You can't redirect it.
84
+
85
+ **Mach6 doesn't work that way.** Every message is priority-classified in real-time:
86
+
87
+ ```
88
+ interrupt → Bypasses queue. Cancels active turn immediately.
89
+ high → Skips coalescing. Next in line.
90
+ normal → Standard processing with coalescing.
91
+ low → Reactions, group mentions. Queued politely.
92
+ background → Typing indicators. Dropped under backpressure.
93
+ ```
94
+
95
+ Send "stop" while the agent is mid-thought → the agent stops. Immediately. Not after the current tool call. Not after the current paragraph. **Now.**
96
+
97
+ ### Message Coalescing
98
+
99
+ Three messages in rapid succession? Mach6 buffers and merges them:
100
+
101
+ ```
102
+ "hey" → buffered
103
+ "can you" → buffered
104
+ "check the logs" → 2s timer expires → merged into one envelope
105
+ ```
106
+
107
+ One coherent request, one turn, no wasted tokens.
108
+
109
+ ### Single Process, Zero Infrastructure
110
+
111
+ One Node.js daemon. No Docker. No Redis. No Kubernetes. No microservices. Install, configure, run. It's a binary that talks to LLMs and messaging platforms. That's it.
112
+
113
+ ---
114
+
115
+ ## ⚙ Configuration
116
+
117
+ ### `mach6.json` — Agent configuration
118
+
119
+ ```jsonc
120
+ {
121
+ "defaultProvider": "github-copilot",
122
+ "defaultModel": "claude-opus-4-6",
123
+ "maxTokens": 8192,
124
+ "maxIterations": 50,
125
+ "temperature": 0.3,
126
+
127
+ // Use forward slashes on all platforms
128
+ // Windows: "C:/Users/you/workspace"
129
+ "workspace": "/home/you/workspace",
130
+ "sessionsDir": ".sessions",
131
+
132
+ "providers": {
133
+ "github-copilot": {},
134
+ "anthropic": {},
135
+ "openai": {},
136
+ "gladius": { "baseUrl": "http://127.0.0.1:8741" }
137
+ },
138
+
139
+ "ownerIds": [
140
+ "your-discord-user-id",
141
+ "your-phone@s.whatsapp.net"
142
+ ],
143
+
144
+ "discord": {
145
+ "enabled": true,
146
+ "token": "${DISCORD_BOT_TOKEN}",
147
+ "botId": "${DISCORD_CLIENT_ID}",
148
+ "siblingBotIds": [],
149
+ "policy": {
150
+ "dmPolicy": "allowlist",
151
+ "groupPolicy": "mention-only",
152
+ "requireMention": true,
153
+ "allowedSenders": ["your-discord-user-id"],
154
+ "allowedGroups": []
155
+ }
156
+ },
157
+
158
+ "whatsapp": {
159
+ "enabled": true,
160
+ "authDir": "~/.mach6/whatsapp-auth",
161
+ "phoneNumber": "your-phone-number",
162
+ "autoRead": true,
163
+ "policy": {
164
+ "dmPolicy": "allowlist",
165
+ "groupPolicy": "mention-only",
166
+ "allowedSenders": ["your-phone@s.whatsapp.net"],
167
+ "allowedGroups": []
168
+ }
169
+ },
170
+
171
+ "apiPort": 3006
172
+ }
173
+ ```
174
+
175
+ All string values support `${ENV_VAR}` interpolation.
176
+
177
+ ### `.env` — Secrets
178
+
179
+ ```bash
180
+ # LLM Providers
181
+ ANTHROPIC_API_KEY=sk-ant-...
182
+ OPENAI_API_KEY=sk-...
183
+
184
+ # GitHub Copilot — usually automatic via `gh auth login`
185
+ # COPILOT_GITHUB_TOKEN=
186
+
187
+ # Discord
188
+ DISCORD_BOT_TOKEN=
189
+ DISCORD_CLIENT_ID=
190
+
191
+ # HTTP API authentication
192
+ MACH6_API_KEY=
193
+
194
+ # Port (default: 3006)
195
+ MACH6_PORT=3006
196
+ ```
197
+
198
+ > Run `mach6 init` to generate both files interactively.
199
+
200
+ ---
201
+
202
+ ## 🧠 Providers
203
+
204
+ | Provider | Config Key | How it authenticates |
205
+ |----------|-----------|---------------------|
206
+ | **GitHub Copilot** | `github-copilot` | Auto-resolved (see below) — no API key needed |
207
+ | **Anthropic** | `anthropic` | `ANTHROPIC_API_KEY` env var |
208
+ | **OpenAI** | `openai` | `OPENAI_API_KEY` env var |
209
+ | **Gladius** | `gladius` | Local HTTP endpoint |
210
+
211
+ ### GitHub Copilot token resolution
212
+
213
+ No API key required if `gh` CLI is installed and authenticated. Token resolves in order:
214
+
215
+ 1. `COPILOT_GITHUB_TOKEN` env var
216
+ 2. `~/.copilot-cli-access-token` file
217
+ 3. `GH_TOKEN` / `GITHUB_TOKEN` env vars
218
+ 4. `~/.config/github-copilot/hosts.json` (Linux/macOS)
219
+ 5. `%APPDATA%\github-copilot\hosts.json` (Windows)
220
+ 6. `gh auth token` CLI fallback (all platforms)
221
+
222
+ ### Available models (via Copilot proxy)
223
+
224
+ | Model | Config value |
225
+ |-------|-------------|
226
+ | Claude Opus 4.6 | `claude-opus-4-6` |
227
+ | Claude Sonnet 4 | `claude-sonnet-4` |
228
+ | GPT-4o | `gpt-4o` |
229
+ | o3-mini | `o3-mini` |
230
+
231
+ Providers are hot-swappable mid-session via `/provider` and `/model` commands.
232
+
233
+ ---
234
+
235
+ ## 🛠 Tools
236
+
237
+ 18 built-in tools, available to the agent by default:
238
+
239
+ | Tool | Description |
240
+ |------|------------|
241
+ | `read` | Read file contents (with offset/limit for large files) |
242
+ | `write` | Write/create files (auto-creates parent directories) |
243
+ | `edit` | Surgical find-and-replace editing |
244
+ | `exec` | Execute shell commands |
245
+ | `image` | Analyze images with vision models |
246
+ | `web_fetch` | Fetch URLs, strip HTML to text |
247
+ | `tts` | Text-to-speech (Edge TTS, multiple voices) |
248
+ | `memory_search` | Hybrid BM25 + vector search over indexed files |
249
+ | `comb_recall` | Recall persistent session-to-session memory |
250
+ | `comb_stage` | Stage information for next session |
251
+ | `message` | Send messages, media, and reactions to any channel |
252
+ | `typing` | Send typing indicators |
253
+ | `presence` | Update presence status |
254
+ | `delete_message` | Delete messages |
255
+ | `mark_read` | Send read receipts |
256
+ | `process_start` | Start background processes |
257
+ | `process_poll` | Poll background process output |
258
+ | `process_kill` | Kill background processes |
259
+ | `process_list` | List background processes |
260
+ | `spawn` | Spawn sub-agents (up to depth 3) |
261
+
262
+ Tools are sandboxed per-session via the policy engine. MCP bridge available for external tool servers.
263
+
264
+ ---
265
+
266
+ ## 🖥 Web UI
267
+
268
+ Mach6 ships with a built-in web interface at `http://localhost:3006`:
269
+
270
+ - **Session management** — create, switch, delete sessions
271
+ - **Streaming responses** — real-time SSE with tool call visualization
272
+ - **Config panel** — change provider, model, temperature, API keys live
273
+ - **Sub-agent monitoring** — view and kill running sub-agents
274
+ - **Generative UI** — file reads, exec outputs, and fetches render as rich cards
275
+
276
+ No build step. No npm dependencies. One static HTML file.
277
+
278
+ ---
279
+
280
+ ## 🖥 CLI
281
+
282
+ ### Interactive REPL
283
+
284
+ ```bash
285
+ node dist/index.js --config=mach6.json
286
+ ```
287
+
288
+ ```
289
+ Mach6 v0.2 | github-copilot/claude-opus-4-6 | session: default
290
+ Tools (18): read, write, edit, exec, image, web_fetch, tts, ...
291
+ Type /help for commands
292
+
293
+ ❯ What's in the logs?
294
+ ⚡ exec
295
+ ✓ exec tail -50 /var/log/syslog
296
+ ...
297
+ ```
298
+
299
+ ### Commands
300
+
301
+ | Command | Description |
302
+ |---------|------------|
303
+ | `/help` | Show all commands |
304
+ | `/tools` | List available tools |
305
+ | `/model <name>` | Switch model mid-session |
306
+ | `/provider <name>` | Switch provider mid-session |
307
+ | `/spawn <task>` | Spawn a sub-agent |
308
+ | `/status` | Session stats (tokens, tool usage) |
309
+ | `/sessions` | List all sessions |
310
+ | `/history [N]` | Show last N messages |
311
+ | `/clear` | Clear current session |
312
+ | `/quit` | Exit |
313
+
314
+ ### One-shot mode
315
+
316
+ ```bash
317
+ node dist/index.js "Summarize the README in this directory"
318
+ ```
319
+
320
+ ---
321
+
322
+ ## 🐧 Running as a Service
323
+
324
+ ### Linux (systemd)
325
+
326
+ ```bash
327
+ # Copy the included service file
328
+ sudo cp mach6-gateway.service /etc/systemd/system/
329
+ # Edit it — set your paths and user
330
+ sudo systemctl enable --now mach6-gateway
331
+
332
+ # Hot-reload config without restarting:
333
+ kill -USR1 $(pgrep -f "gateway/daemon.js")
334
+ ```
335
+
336
+ ### macOS (launchd)
337
+
338
+ Create `~/Library/LaunchAgents/com.mach6.gateway.plist` pointing to `node dist/gateway/daemon.js`.
339
+
340
+ ### Windows
341
+
342
+ Use [NSSM](https://nssm.cc/) or Task Scheduler to run `node dist/gateway/daemon.js --config=mach6.json`.
343
+
344
+ > **Note:** `SIGUSR1` hot-reload is not available on Windows. Restart the process to reload config.
345
+
346
+ ---
347
+
348
+ ## 📁 Project Structure
349
+
350
+ ```
351
+ mach6/
352
+ ├── src/
353
+ │ ├── agent/ # Runner, context manager, system prompt builder
354
+ │ ├── boot/ # Boot sequence & validation
355
+ │ ├── channels/ # Adapter pattern — Discord, WhatsApp, router, bus
356
+ │ │ ├── bus.ts # Priority queue, coalescing, interrupts, backpressure
357
+ │ │ ├── router.ts # Policy, dedup, JID normalization, priority
358
+ │ │ └── adapters/ # Discord (discord.js), WhatsApp (Baileys v7)
359
+ │ ├── cli/ # Interactive setup wizard
360
+ │ ├── config/ # Config loader, validator, env interpolation
361
+ │ ├── cron/ # Cron budget management
362
+ │ ├── formatters/ # Platform-aware markdown formatting
363
+ │ ├── gateway/ # Persistent daemon — signals, hot-reload, turns
364
+ │ ├── heartbeat/ # Activity-aware periodic health checks
365
+ │ ├── memory/ # Index integrity checks
366
+ │ ├── providers/ # LLM providers — Copilot, Anthropic, OpenAI, Gladius
367
+ │ ├── security/ # Input sanitization
368
+ │ ├── sessions/ # Session store, queue, sub-agents
369
+ │ ├── tools/ # 18 built-in tools, policy engine, registry, MCP bridge
370
+ │ └── web/ # Web UI server (SSE streaming, static serving)
371
+ ├── web/ # Web UI (single HTML file)
372
+ ├── mach6.example.json # Example config
373
+ ├── .env.example # Example environment variables
374
+ ├── mach6.sh # Linux/macOS start script
375
+ ├── mach6.ps1 # Windows start script
376
+ └── mach6-gateway.service # systemd unit file
377
+ ```
378
+
379
+ ---
380
+
381
+ ## 🔒 Hardening
382
+
383
+ 20 production pain points addressed:
384
+
385
+ - **Config validation** with human-readable diagnostics at boot
386
+ - **Context monitor** with progressive warnings (70/80/90% thresholds)
387
+ - **Priority message queue** — real messages never drop, only background signals shed under backpressure
388
+ - **Tool policy engine** — scope available tools per session and security tier
389
+ - **Provider diagnostics** — health checks and automatic failover
390
+ - **Activity-aware heartbeat** — adapts frequency to system load
391
+ - **Cron budget management** — prevents runaway scheduled tasks
392
+ - **Boot sequence validation** — catch misconfigurations before they become incidents
393
+ - **JID normalization** for WhatsApp Baileys v7 (device suffix stripping)
394
+ - **Abort signal propagation** through agent runner → LLM stream → tool execution
395
+ - **MCP bridge** for connecting external tool servers
396
+ - **Sibling bot yield** — @mention one bot, only that one responds
397
+
398
+ ---
399
+
400
+ ## 📊 Stats
401
+
402
+ | Metric | Value |
403
+ |--------|-------|
404
+ | Lines of TypeScript | ~8,400 |
405
+ | Built-in tools | 18 |
406
+ | LLM providers | 4 |
407
+ | Channel adapters | 2 + HTTP API |
408
+ | Cold boot to connected | ~2.3s |
409
+ | External runtime deps | Node.js only |
410
+
411
+ ---
412
+
413
+ ## 🌐 Platform Compatibility
414
+
415
+ | Feature | Windows | Linux | macOS |
416
+ |---------|---------|-------|-------|
417
+ | Gateway daemon | ✅ | ✅ | ✅ |
418
+ | Discord adapter | ✅ | ✅ | ✅ |
419
+ | WhatsApp adapter | ✅ | ✅ | ✅ |
420
+ | HTTP API + Web UI | ✅ | ✅ | ✅ |
421
+ | CLI (REPL + one-shot) | ✅ | ✅ | ✅ |
422
+ | Hot-reload (SIGUSR1) | ❌ | ✅ | ✅ |
423
+ | Service manager | Task Scheduler | systemd | launchd |
424
+ | Temp directory | `%TEMP%` | `/tmp` | `/tmp` |
425
+ | Home directory | `%USERPROFILE%` | `~` | `~` |
426
+
427
+ All paths resolved via `os.tmpdir()` and `os.homedir()` — zero hardcoded Unix paths.
428
+
429
+ ---
430
+
431
+ ## 📜 History
432
+
433
+ | Date | Milestone |
434
+ |------|----------|
435
+ | **Feb 22, 2026** | Built from scratch. WhatsApp, Discord, gateway, config, tools, sessions. |
436
+ | **Feb 22, 2026** | 14/14 smoke tests. 20 hardening fixes. Flipped to production same day. |
437
+ | **Feb 23, 2026** | Open-sourced. MIT license. |
438
+ | **Feb 28, 2026** | Cross-platform (Windows/Linux/macOS). CLI wizard. v1.0.0. |
439
+
440
+ ---
441
+
442
+ ## 📄 License
443
+
444
+ [MIT](LICENSE) — do whatever you want with it.
445
+
446
+ ---
447
+
448
+ <div align="center">
449
+
450
+ Built by **[Artifact Virtual](https://artifactvirtual.com)**
451
+
452
+ Open-sourced because infrastructure wants to be free.
453
+
454
+ </div>
@@ -0,0 +1,40 @@
1
+ import type { Message } from '../providers/types.js';
2
+ export interface ContextMonitorConfig {
3
+ maxContextTokens: number;
4
+ warnThreshold?: number;
5
+ compactThreshold?: number;
6
+ emergencyThreshold?: number;
7
+ transcriptDir?: string;
8
+ onCombStage?: (content: string) => Promise<void>;
9
+ }
10
+ export type ContextHealth = 'ok' | 'warning' | 'compacting' | 'emergency';
11
+ export interface ContextStatus {
12
+ totalTokens: number;
13
+ maxTokens: number;
14
+ usage: number;
15
+ health: ContextHealth;
16
+ messageCount: number;
17
+ }
18
+ export declare class ContextMonitor {
19
+ private config;
20
+ private transcriptDir;
21
+ private onCombStage?;
22
+ private hasWarned;
23
+ constructor(cfg: ContextMonitorConfig);
24
+ /** Check current context health without modifying anything */
25
+ check(messages: Message[]): ContextStatus;
26
+ /**
27
+ * Check and act: returns (possibly compacted) messages.
28
+ * - warning: logs, returns as-is
29
+ * - compacting: COMB stage + summarize old messages
30
+ * - emergency: save transcript to disk, hard-truncate
31
+ */
32
+ manage(messages: Message[]): Promise<Message[]>;
33
+ /** Summarize old messages, keep system + recent */
34
+ private compact;
35
+ /** Emergency: save full transcript, keep only last N messages */
36
+ private hardTruncate;
37
+ private buildSummary;
38
+ private saveTranscript;
39
+ }
40
+ //# sourceMappingURL=context-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-monitor.d.ts","sourceRoot":"","sources":["../../src/agent/context-monitor.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAErD,MAAM,WAAW,oBAAoB;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAClD;AAED,MAAM,MAAM,aAAa,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY,GAAG,WAAW,CAAC;AAE1E,MAAM,WAAW,aAAa;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,aAAa,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;CACtB;AAiBD,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAyH;IACvI,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAC,CAAqC;IACzD,OAAO,CAAC,SAAS,CAAS;gBAEd,GAAG,EAAE,oBAAoB;IAWrC,8DAA8D;IAC9D,KAAK,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,aAAa;IAYzC;;;;;OAKG;IACG,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAqCrD,mDAAmD;IACnD,OAAO,CAAC,OAAO;IAwBf,iEAAiE;IACjE,OAAO,CAAC,YAAY;IAQpB,OAAO,CAAC,YAAY;YAUN,cAAc;CAU7B"}
@@ -0,0 +1,138 @@
1
+ // Mach6 — Proactive Context Management (fixes Pain #3)
2
+ // Track tokens in real-time. Compact before overflow. Never hit the wall.
3
+ import os from 'node:os';
4
+ import path from 'node:path';
5
+ /** Rough token estimate: ~4 chars per token */
6
+ function estimateTokens(text) {
7
+ return Math.ceil(text.length / 4);
8
+ }
9
+ function messageTokens(msg) {
10
+ if (typeof msg.content === 'string')
11
+ return estimateTokens(msg.content);
12
+ return msg.content.reduce((sum, b) => {
13
+ if (b.text)
14
+ return sum + estimateTokens(b.text);
15
+ if (b.content)
16
+ return sum + estimateTokens(b.content);
17
+ if (b.input)
18
+ return sum + estimateTokens(JSON.stringify(b.input));
19
+ return sum + 50;
20
+ }, 0);
21
+ }
22
+ export class ContextMonitor {
23
+ config;
24
+ transcriptDir;
25
+ onCombStage;
26
+ hasWarned = false;
27
+ constructor(cfg) {
28
+ this.config = {
29
+ maxContextTokens: cfg.maxContextTokens,
30
+ warnThreshold: cfg.warnThreshold ?? 0.7,
31
+ compactThreshold: cfg.compactThreshold ?? 0.8,
32
+ emergencyThreshold: cfg.emergencyThreshold ?? 0.9,
33
+ };
34
+ this.transcriptDir = cfg.transcriptDir ?? path.join(os.tmpdir(), 'mach6-transcripts');
35
+ this.onCombStage = cfg.onCombStage;
36
+ }
37
+ /** Check current context health without modifying anything */
38
+ check(messages) {
39
+ const totalTokens = messages.reduce((s, m) => s + messageTokens(m), 0);
40
+ const usage = totalTokens / this.config.maxContextTokens;
41
+ let health = 'ok';
42
+ if (usage >= this.config.emergencyThreshold)
43
+ health = 'emergency';
44
+ else if (usage >= this.config.compactThreshold)
45
+ health = 'compacting';
46
+ else if (usage >= this.config.warnThreshold)
47
+ health = 'warning';
48
+ return { totalTokens, maxTokens: this.config.maxContextTokens, usage, health, messageCount: messages.length };
49
+ }
50
+ /**
51
+ * Check and act: returns (possibly compacted) messages.
52
+ * - warning: logs, returns as-is
53
+ * - compacting: COMB stage + summarize old messages
54
+ * - emergency: save transcript to disk, hard-truncate
55
+ */
56
+ async manage(messages) {
57
+ const status = this.check(messages);
58
+ if (status.health === 'ok') {
59
+ this.hasWarned = false;
60
+ return messages;
61
+ }
62
+ if (status.health === 'warning') {
63
+ if (!this.hasWarned) {
64
+ console.warn(`⚠️ Context at ${(status.usage * 100).toFixed(0)}% (${status.totalTokens}/${status.maxTokens} tokens)`);
65
+ this.hasWarned = true;
66
+ }
67
+ return messages;
68
+ }
69
+ // Before any compaction, stage to COMB
70
+ if (this.onCombStage) {
71
+ const summary = this.buildSummary(messages);
72
+ try {
73
+ await this.onCombStage(summary);
74
+ }
75
+ catch (err) {
76
+ console.error('COMB stage failed during compaction:', err);
77
+ }
78
+ }
79
+ if (status.health === 'emergency') {
80
+ console.error(`🚨 Context EMERGENCY at ${(status.usage * 100).toFixed(0)}% — flushing to disk`);
81
+ await this.saveTranscript(messages);
82
+ return this.hardTruncate(messages, 10);
83
+ }
84
+ // compacting
85
+ console.warn(`🔄 Context at ${(status.usage * 100).toFixed(0)}% — auto-compacting`);
86
+ return this.compact(messages);
87
+ }
88
+ /** Summarize old messages, keep system + recent */
89
+ compact(messages) {
90
+ const system = messages.filter(m => m.role === 'system');
91
+ const rest = messages.filter(m => m.role !== 'system');
92
+ // Keep last 40% of non-system messages
93
+ const keepCount = Math.max(10, Math.floor(rest.length * 0.4));
94
+ const old = rest.slice(0, rest.length - keepCount);
95
+ const recent = rest.slice(rest.length - keepCount);
96
+ // Build summary of old messages
97
+ const summaryParts = ['[Context compacted. Summary of earlier conversation:]'];
98
+ for (const msg of old) {
99
+ const text = typeof msg.content === 'string' ? msg.content : '[structured content]';
100
+ const preview = text.slice(0, 200);
101
+ summaryParts.push(`${msg.role}: ${preview}${text.length > 200 ? '...' : ''}`);
102
+ }
103
+ const summaryMsg = {
104
+ role: 'user',
105
+ content: summaryParts.join('\n').slice(0, 2000),
106
+ };
107
+ return [...system, summaryMsg, ...recent];
108
+ }
109
+ /** Emergency: save full transcript, keep only last N messages */
110
+ hardTruncate(messages, keepLast) {
111
+ const system = messages.filter(m => m.role === 'system');
112
+ const rest = messages.filter(m => m.role !== 'system');
113
+ const kept = rest.slice(-keepLast);
114
+ const notice = { role: 'user', content: '[Emergency context flush. Earlier messages saved to disk. Recent context only.]' };
115
+ return [...system, notice, ...kept];
116
+ }
117
+ buildSummary(messages) {
118
+ const parts = [`Context snapshot at ${new Date().toISOString()} (${messages.length} messages)`];
119
+ for (const msg of messages) {
120
+ if (msg.role === 'system')
121
+ continue;
122
+ const text = typeof msg.content === 'string' ? msg.content : JSON.stringify(msg.content);
123
+ parts.push(`[${msg.role}] ${text.slice(0, 500)}`);
124
+ }
125
+ return parts.join('\n');
126
+ }
127
+ async saveTranscript(messages) {
128
+ // Dynamic import to avoid top-level fs dependency issues
129
+ const fs = await import('node:fs');
130
+ const path = await import('node:path');
131
+ fs.mkdirSync(this.transcriptDir, { recursive: true });
132
+ const filename = `transcript-${Date.now()}.json`;
133
+ const filepath = path.join(this.transcriptDir, filename);
134
+ fs.writeFileSync(filepath, JSON.stringify(messages, null, 2));
135
+ console.log(`📝 Transcript saved: ${filepath}`);
136
+ }
137
+ }
138
+ //# sourceMappingURL=context-monitor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context-monitor.js","sourceRoot":"","sources":["../../src/agent/context-monitor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Message } from '../providers/types.js';
2
+ /**
3
+ * Truncate message history to fit within a token budget.
4
+ * Strategy: keep system prompt + last N messages, drop oldest first.
5
+ * CRITICAL: tool_use/tool_result messages must stay paired.
6
+ */
7
+ export declare function truncateContext(messages: Message[], maxTokens: number): Message[];
8
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/agent/context.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAgB,MAAM,uBAAuB,CAAC;AAkFnE;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,CAuFjF"}