whale-code 6.4.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 (319) hide show
  1. package/README.md +95 -0
  2. package/bin/swag-agent.js +9 -0
  3. package/bin/swagmanager-mcp.js +321 -0
  4. package/dist/cli/app.d.ts +26 -0
  5. package/dist/cli/app.js +64 -0
  6. package/dist/cli/chat/AgentSelector.d.ts +14 -0
  7. package/dist/cli/chat/AgentSelector.js +14 -0
  8. package/dist/cli/chat/ChatApp.d.ts +9 -0
  9. package/dist/cli/chat/ChatApp.js +267 -0
  10. package/dist/cli/chat/ChatInput.d.ts +39 -0
  11. package/dist/cli/chat/ChatInput.js +509 -0
  12. package/dist/cli/chat/MarkdownText.d.ts +10 -0
  13. package/dist/cli/chat/MarkdownText.js +20 -0
  14. package/dist/cli/chat/MessageList.d.ts +37 -0
  15. package/dist/cli/chat/MessageList.js +80 -0
  16. package/dist/cli/chat/ModelSelector.d.ts +20 -0
  17. package/dist/cli/chat/ModelSelector.js +73 -0
  18. package/dist/cli/chat/RewindViewer.d.ts +26 -0
  19. package/dist/cli/chat/RewindViewer.js +185 -0
  20. package/dist/cli/chat/StoreSelector.d.ts +14 -0
  21. package/dist/cli/chat/StoreSelector.js +24 -0
  22. package/dist/cli/chat/StreamingText.d.ts +12 -0
  23. package/dist/cli/chat/StreamingText.js +12 -0
  24. package/dist/cli/chat/SubagentPanel.d.ts +45 -0
  25. package/dist/cli/chat/SubagentPanel.js +110 -0
  26. package/dist/cli/chat/TeamPanel.d.ts +21 -0
  27. package/dist/cli/chat/TeamPanel.js +42 -0
  28. package/dist/cli/chat/ToolIndicator.d.ts +25 -0
  29. package/dist/cli/chat/ToolIndicator.js +436 -0
  30. package/dist/cli/chat/hooks/useAgentLoop.d.ts +39 -0
  31. package/dist/cli/chat/hooks/useAgentLoop.js +382 -0
  32. package/dist/cli/chat/hooks/useSlashCommands.d.ts +37 -0
  33. package/dist/cli/chat/hooks/useSlashCommands.js +387 -0
  34. package/dist/cli/commands/config-cmd.d.ts +10 -0
  35. package/dist/cli/commands/config-cmd.js +99 -0
  36. package/dist/cli/commands/doctor.d.ts +14 -0
  37. package/dist/cli/commands/doctor.js +172 -0
  38. package/dist/cli/commands/init.d.ts +16 -0
  39. package/dist/cli/commands/init.js +278 -0
  40. package/dist/cli/commands/mcp.d.ts +12 -0
  41. package/dist/cli/commands/mcp.js +162 -0
  42. package/dist/cli/login/LoginApp.d.ts +7 -0
  43. package/dist/cli/login/LoginApp.js +157 -0
  44. package/dist/cli/print-mode.d.ts +31 -0
  45. package/dist/cli/print-mode.js +202 -0
  46. package/dist/cli/serve-mode.d.ts +37 -0
  47. package/dist/cli/serve-mode.js +636 -0
  48. package/dist/cli/services/agent-definitions.d.ts +25 -0
  49. package/dist/cli/services/agent-definitions.js +91 -0
  50. package/dist/cli/services/agent-events.d.ts +178 -0
  51. package/dist/cli/services/agent-events.js +175 -0
  52. package/dist/cli/services/agent-loop.d.ts +90 -0
  53. package/dist/cli/services/agent-loop.js +762 -0
  54. package/dist/cli/services/agent-worker-base.d.ts +97 -0
  55. package/dist/cli/services/agent-worker-base.js +220 -0
  56. package/dist/cli/services/auth-service.d.ts +30 -0
  57. package/dist/cli/services/auth-service.js +160 -0
  58. package/dist/cli/services/background-processes.d.ts +126 -0
  59. package/dist/cli/services/background-processes.js +318 -0
  60. package/dist/cli/services/browser-auth.d.ts +24 -0
  61. package/dist/cli/services/browser-auth.js +180 -0
  62. package/dist/cli/services/claude-md-loader.d.ts +16 -0
  63. package/dist/cli/services/claude-md-loader.js +58 -0
  64. package/dist/cli/services/config-store.d.ts +47 -0
  65. package/dist/cli/services/config-store.js +79 -0
  66. package/dist/cli/services/debug-log.d.ts +10 -0
  67. package/dist/cli/services/debug-log.js +52 -0
  68. package/dist/cli/services/error-logger.d.ts +58 -0
  69. package/dist/cli/services/error-logger.js +269 -0
  70. package/dist/cli/services/file-history.d.ts +21 -0
  71. package/dist/cli/services/file-history.js +83 -0
  72. package/dist/cli/services/format-server-response.d.ts +16 -0
  73. package/dist/cli/services/format-server-response.js +440 -0
  74. package/dist/cli/services/git-context.d.ts +11 -0
  75. package/dist/cli/services/git-context.js +66 -0
  76. package/dist/cli/services/hooks.d.ts +85 -0
  77. package/dist/cli/services/hooks.js +258 -0
  78. package/dist/cli/services/interactive-tools.d.ts +125 -0
  79. package/dist/cli/services/interactive-tools.js +260 -0
  80. package/dist/cli/services/keybinding-manager.d.ts +52 -0
  81. package/dist/cli/services/keybinding-manager.js +115 -0
  82. package/dist/cli/services/local-tools.d.ts +22 -0
  83. package/dist/cli/services/local-tools.js +697 -0
  84. package/dist/cli/services/lsp-manager.d.ts +18 -0
  85. package/dist/cli/services/lsp-manager.js +717 -0
  86. package/dist/cli/services/mcp-client.d.ts +48 -0
  87. package/dist/cli/services/mcp-client.js +157 -0
  88. package/dist/cli/services/memory-manager.d.ts +16 -0
  89. package/dist/cli/services/memory-manager.js +57 -0
  90. package/dist/cli/services/model-manager.d.ts +18 -0
  91. package/dist/cli/services/model-manager.js +71 -0
  92. package/dist/cli/services/model-router.d.ts +26 -0
  93. package/dist/cli/services/model-router.js +149 -0
  94. package/dist/cli/services/permission-modes.d.ts +13 -0
  95. package/dist/cli/services/permission-modes.js +43 -0
  96. package/dist/cli/services/rewind.d.ts +84 -0
  97. package/dist/cli/services/rewind.js +194 -0
  98. package/dist/cli/services/ripgrep.d.ts +28 -0
  99. package/dist/cli/services/ripgrep.js +138 -0
  100. package/dist/cli/services/sandbox.d.ts +29 -0
  101. package/dist/cli/services/sandbox.js +97 -0
  102. package/dist/cli/services/server-tools.d.ts +61 -0
  103. package/dist/cli/services/server-tools.js +543 -0
  104. package/dist/cli/services/session-persistence.d.ts +23 -0
  105. package/dist/cli/services/session-persistence.js +99 -0
  106. package/dist/cli/services/subagent-worker.d.ts +19 -0
  107. package/dist/cli/services/subagent-worker.js +41 -0
  108. package/dist/cli/services/subagent.d.ts +47 -0
  109. package/dist/cli/services/subagent.js +647 -0
  110. package/dist/cli/services/system-prompt.d.ts +7 -0
  111. package/dist/cli/services/system-prompt.js +198 -0
  112. package/dist/cli/services/team-lead.d.ts +73 -0
  113. package/dist/cli/services/team-lead.js +512 -0
  114. package/dist/cli/services/team-state.d.ts +77 -0
  115. package/dist/cli/services/team-state.js +398 -0
  116. package/dist/cli/services/teammate.d.ts +31 -0
  117. package/dist/cli/services/teammate.js +689 -0
  118. package/dist/cli/services/telemetry.d.ts +61 -0
  119. package/dist/cli/services/telemetry.js +209 -0
  120. package/dist/cli/services/tools/agent-tools.d.ts +14 -0
  121. package/dist/cli/services/tools/agent-tools.js +347 -0
  122. package/dist/cli/services/tools/file-ops.d.ts +15 -0
  123. package/dist/cli/services/tools/file-ops.js +487 -0
  124. package/dist/cli/services/tools/search-tools.d.ts +8 -0
  125. package/dist/cli/services/tools/search-tools.js +186 -0
  126. package/dist/cli/services/tools/shell-exec.d.ts +10 -0
  127. package/dist/cli/services/tools/shell-exec.js +168 -0
  128. package/dist/cli/services/tools/task-manager.d.ts +28 -0
  129. package/dist/cli/services/tools/task-manager.js +209 -0
  130. package/dist/cli/services/tools/web-tools.d.ts +11 -0
  131. package/dist/cli/services/tools/web-tools.js +395 -0
  132. package/dist/cli/setup/SetupApp.d.ts +9 -0
  133. package/dist/cli/setup/SetupApp.js +191 -0
  134. package/dist/cli/shared/MatrixIntro.d.ts +4 -0
  135. package/dist/cli/shared/MatrixIntro.js +83 -0
  136. package/dist/cli/shared/Theme.d.ts +74 -0
  137. package/dist/cli/shared/Theme.js +127 -0
  138. package/dist/cli/shared/WhaleBanner.d.ts +10 -0
  139. package/dist/cli/shared/WhaleBanner.js +12 -0
  140. package/dist/cli/shared/markdown.d.ts +21 -0
  141. package/dist/cli/shared/markdown.js +756 -0
  142. package/dist/cli/status/StatusApp.d.ts +4 -0
  143. package/dist/cli/status/StatusApp.js +105 -0
  144. package/dist/cli/stores/StoreApp.d.ts +7 -0
  145. package/dist/cli/stores/StoreApp.js +81 -0
  146. package/dist/index.d.ts +15 -0
  147. package/dist/index.js +538 -0
  148. package/dist/local-agent/connection.d.ts +48 -0
  149. package/dist/local-agent/connection.js +332 -0
  150. package/dist/local-agent/discovery.d.ts +18 -0
  151. package/dist/local-agent/discovery.js +146 -0
  152. package/dist/local-agent/executor.d.ts +34 -0
  153. package/dist/local-agent/executor.js +241 -0
  154. package/dist/local-agent/index.d.ts +14 -0
  155. package/dist/local-agent/index.js +198 -0
  156. package/dist/node/adapters/base.d.ts +35 -0
  157. package/dist/node/adapters/base.js +10 -0
  158. package/dist/node/adapters/discord.d.ts +29 -0
  159. package/dist/node/adapters/discord.js +299 -0
  160. package/dist/node/adapters/email.d.ts +23 -0
  161. package/dist/node/adapters/email.js +218 -0
  162. package/dist/node/adapters/imessage.d.ts +17 -0
  163. package/dist/node/adapters/imessage.js +118 -0
  164. package/dist/node/adapters/slack.d.ts +26 -0
  165. package/dist/node/adapters/slack.js +259 -0
  166. package/dist/node/adapters/sms.d.ts +23 -0
  167. package/dist/node/adapters/sms.js +161 -0
  168. package/dist/node/adapters/telegram.d.ts +17 -0
  169. package/dist/node/adapters/telegram.js +101 -0
  170. package/dist/node/adapters/webchat.d.ts +27 -0
  171. package/dist/node/adapters/webchat.js +160 -0
  172. package/dist/node/adapters/whatsapp.d.ts +28 -0
  173. package/dist/node/adapters/whatsapp.js +230 -0
  174. package/dist/node/cli.d.ts +2 -0
  175. package/dist/node/cli.js +325 -0
  176. package/dist/node/config.d.ts +17 -0
  177. package/dist/node/config.js +31 -0
  178. package/dist/node/runtime.d.ts +50 -0
  179. package/dist/node/runtime.js +351 -0
  180. package/dist/server/handlers/__test-utils__/mock-supabase.d.ts +11 -0
  181. package/dist/server/handlers/__test-utils__/mock-supabase.js +393 -0
  182. package/dist/server/handlers/analytics.d.ts +17 -0
  183. package/dist/server/handlers/analytics.js +266 -0
  184. package/dist/server/handlers/api-keys.d.ts +6 -0
  185. package/dist/server/handlers/api-keys.js +221 -0
  186. package/dist/server/handlers/billing.d.ts +33 -0
  187. package/dist/server/handlers/billing.js +272 -0
  188. package/dist/server/handlers/browser.d.ts +10 -0
  189. package/dist/server/handlers/browser.js +517 -0
  190. package/dist/server/handlers/catalog.d.ts +99 -0
  191. package/dist/server/handlers/catalog.js +976 -0
  192. package/dist/server/handlers/comms.d.ts +254 -0
  193. package/dist/server/handlers/comms.js +588 -0
  194. package/dist/server/handlers/creations.d.ts +6 -0
  195. package/dist/server/handlers/creations.js +479 -0
  196. package/dist/server/handlers/crm.d.ts +89 -0
  197. package/dist/server/handlers/crm.js +538 -0
  198. package/dist/server/handlers/discovery.d.ts +6 -0
  199. package/dist/server/handlers/discovery.js +288 -0
  200. package/dist/server/handlers/embeddings.d.ts +92 -0
  201. package/dist/server/handlers/embeddings.js +197 -0
  202. package/dist/server/handlers/enrichment.d.ts +8 -0
  203. package/dist/server/handlers/enrichment.js +768 -0
  204. package/dist/server/handlers/image-gen.d.ts +6 -0
  205. package/dist/server/handlers/image-gen.js +409 -0
  206. package/dist/server/handlers/inventory.d.ts +319 -0
  207. package/dist/server/handlers/inventory.js +447 -0
  208. package/dist/server/handlers/kali.d.ts +10 -0
  209. package/dist/server/handlers/kali.js +210 -0
  210. package/dist/server/handlers/llm-providers.d.ts +6 -0
  211. package/dist/server/handlers/llm-providers.js +673 -0
  212. package/dist/server/handlers/local-agent.d.ts +6 -0
  213. package/dist/server/handlers/local-agent.js +118 -0
  214. package/dist/server/handlers/meta-ads.d.ts +111 -0
  215. package/dist/server/handlers/meta-ads.js +2279 -0
  216. package/dist/server/handlers/nodes.d.ts +33 -0
  217. package/dist/server/handlers/nodes.js +699 -0
  218. package/dist/server/handlers/operations.d.ts +138 -0
  219. package/dist/server/handlers/operations.js +131 -0
  220. package/dist/server/handlers/platform.d.ts +23 -0
  221. package/dist/server/handlers/platform.js +227 -0
  222. package/dist/server/handlers/supply-chain.d.ts +19 -0
  223. package/dist/server/handlers/supply-chain.js +327 -0
  224. package/dist/server/handlers/transcription.d.ts +17 -0
  225. package/dist/server/handlers/transcription.js +121 -0
  226. package/dist/server/handlers/video-gen.d.ts +6 -0
  227. package/dist/server/handlers/video-gen.js +466 -0
  228. package/dist/server/handlers/voice.d.ts +8 -0
  229. package/dist/server/handlers/voice.js +1146 -0
  230. package/dist/server/handlers/workflow-steps.d.ts +86 -0
  231. package/dist/server/handlers/workflow-steps.js +2349 -0
  232. package/dist/server/handlers/workflows.d.ts +7 -0
  233. package/dist/server/handlers/workflows.js +989 -0
  234. package/dist/server/index.d.ts +1 -0
  235. package/dist/server/index.js +2427 -0
  236. package/dist/server/lib/batch-client.d.ts +80 -0
  237. package/dist/server/lib/batch-client.js +467 -0
  238. package/dist/server/lib/code-worker-pool.d.ts +31 -0
  239. package/dist/server/lib/code-worker-pool.js +224 -0
  240. package/dist/server/lib/code-worker.d.ts +1 -0
  241. package/dist/server/lib/code-worker.js +188 -0
  242. package/dist/server/lib/compaction-service.d.ts +32 -0
  243. package/dist/server/lib/compaction-service.js +162 -0
  244. package/dist/server/lib/logger.d.ts +19 -0
  245. package/dist/server/lib/logger.js +46 -0
  246. package/dist/server/lib/otel.d.ts +38 -0
  247. package/dist/server/lib/otel.js +126 -0
  248. package/dist/server/lib/pg-rate-limiter.d.ts +21 -0
  249. package/dist/server/lib/pg-rate-limiter.js +86 -0
  250. package/dist/server/lib/prompt-sanitizer.d.ts +37 -0
  251. package/dist/server/lib/prompt-sanitizer.js +177 -0
  252. package/dist/server/lib/provider-capabilities.d.ts +85 -0
  253. package/dist/server/lib/provider-capabilities.js +190 -0
  254. package/dist/server/lib/provider-failover.d.ts +74 -0
  255. package/dist/server/lib/provider-failover.js +210 -0
  256. package/dist/server/lib/rate-limiter.d.ts +39 -0
  257. package/dist/server/lib/rate-limiter.js +147 -0
  258. package/dist/server/lib/server-agent-loop.d.ts +107 -0
  259. package/dist/server/lib/server-agent-loop.js +667 -0
  260. package/dist/server/lib/server-subagent.d.ts +78 -0
  261. package/dist/server/lib/server-subagent.js +203 -0
  262. package/dist/server/lib/session-checkpoint.d.ts +51 -0
  263. package/dist/server/lib/session-checkpoint.js +145 -0
  264. package/dist/server/lib/ssrf-guard.d.ts +13 -0
  265. package/dist/server/lib/ssrf-guard.js +240 -0
  266. package/dist/server/lib/supabase-client.d.ts +7 -0
  267. package/dist/server/lib/supabase-client.js +78 -0
  268. package/dist/server/lib/template-resolver.d.ts +31 -0
  269. package/dist/server/lib/template-resolver.js +215 -0
  270. package/dist/server/lib/utils.d.ts +16 -0
  271. package/dist/server/lib/utils.js +147 -0
  272. package/dist/server/local-agent-gateway.d.ts +82 -0
  273. package/dist/server/local-agent-gateway.js +426 -0
  274. package/dist/server/providers/anthropic.d.ts +20 -0
  275. package/dist/server/providers/anthropic.js +199 -0
  276. package/dist/server/providers/bedrock.d.ts +20 -0
  277. package/dist/server/providers/bedrock.js +194 -0
  278. package/dist/server/providers/gemini.d.ts +24 -0
  279. package/dist/server/providers/gemini.js +486 -0
  280. package/dist/server/providers/openai.d.ts +24 -0
  281. package/dist/server/providers/openai.js +522 -0
  282. package/dist/server/providers/registry.d.ts +32 -0
  283. package/dist/server/providers/registry.js +58 -0
  284. package/dist/server/providers/shared.d.ts +32 -0
  285. package/dist/server/providers/shared.js +124 -0
  286. package/dist/server/providers/types.d.ts +92 -0
  287. package/dist/server/providers/types.js +12 -0
  288. package/dist/server/proxy-handlers.d.ts +6 -0
  289. package/dist/server/proxy-handlers.js +89 -0
  290. package/dist/server/tool-router.d.ts +149 -0
  291. package/dist/server/tool-router.js +803 -0
  292. package/dist/server/validation.d.ts +24 -0
  293. package/dist/server/validation.js +301 -0
  294. package/dist/server/worker.d.ts +19 -0
  295. package/dist/server/worker.js +201 -0
  296. package/dist/setup.d.ts +8 -0
  297. package/dist/setup.js +181 -0
  298. package/dist/shared/agent-core.d.ts +157 -0
  299. package/dist/shared/agent-core.js +534 -0
  300. package/dist/shared/anthropic-types.d.ts +105 -0
  301. package/dist/shared/anthropic-types.js +7 -0
  302. package/dist/shared/api-client.d.ts +90 -0
  303. package/dist/shared/api-client.js +379 -0
  304. package/dist/shared/constants.d.ts +33 -0
  305. package/dist/shared/constants.js +80 -0
  306. package/dist/shared/sse-parser.d.ts +26 -0
  307. package/dist/shared/sse-parser.js +259 -0
  308. package/dist/shared/tool-dispatch.d.ts +52 -0
  309. package/dist/shared/tool-dispatch.js +191 -0
  310. package/dist/shared/types.d.ts +72 -0
  311. package/dist/shared/types.js +7 -0
  312. package/dist/updater.d.ts +25 -0
  313. package/dist/updater.js +140 -0
  314. package/dist/webchat/widget.d.ts +0 -0
  315. package/dist/webchat/widget.js +397 -0
  316. package/package.json +95 -0
  317. package/src/cli/services/builtin-skills/commit.md +19 -0
  318. package/src/cli/services/builtin-skills/review-pr.md +21 -0
  319. package/src/cli/services/builtin-skills/review.md +18 -0
package/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # @swagmanager/mcp
2
+
3
+ MCP (Model Context Protocol) server for SwagManager — manage inventory, orders, analytics, customers, and more from Claude Code or Claude Desktop.
4
+
5
+ ## Setup
6
+
7
+ ```bash
8
+ npm install -g @swagmanager/mcp
9
+ ```
10
+
11
+ ### Environment Variables
12
+
13
+ Create a `.env` file or set these environment variables:
14
+
15
+ ```
16
+ SUPABASE_URL=https://your-project.supabase.co
17
+ SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
18
+ DEFAULT_STORE_ID=your-store-uuid
19
+ ```
20
+
21
+ ### Claude Code
22
+
23
+ Add to `~/.claude/settings.json`:
24
+
25
+ ```json
26
+ {
27
+ "mcpServers": {
28
+ "swagmanager": {
29
+ "command": "swagmanager-mcp",
30
+ "env": {
31
+ "SUPABASE_URL": "https://your-project.supabase.co",
32
+ "SUPABASE_SERVICE_ROLE_KEY": "your-key",
33
+ "DEFAULT_STORE_ID": "your-store-uuid"
34
+ }
35
+ }
36
+ }
37
+ }
38
+ ```
39
+
40
+ ### Claude Desktop
41
+
42
+ Add to your Claude Desktop MCP config:
43
+
44
+ ```json
45
+ {
46
+ "mcpServers": {
47
+ "swagmanager": {
48
+ "command": "npx",
49
+ "args": ["@swagmanager/mcp"],
50
+ "env": {
51
+ "SUPABASE_URL": "https://your-project.supabase.co",
52
+ "SUPABASE_SERVICE_ROLE_KEY": "your-key",
53
+ "DEFAULT_STORE_ID": "your-store-uuid"
54
+ }
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ ## Tools
61
+
62
+ Tools are loaded dynamically from the `ai_tool_registry` database table. The default set includes:
63
+
64
+ | Tool | Description |
65
+ |------|-------------|
66
+ | `analytics` | Sales analytics with flexible date ranges |
67
+ | `inventory` | Adjust quantities, set stock, transfer between locations |
68
+ | `inventory_query` | Query inventory summary, velocity, by location |
69
+ | `inventory_audit` | Start, count, complete inventory audits |
70
+ | `orders` | Find orders, get details, purchase orders |
71
+ | `purchase_orders` | Create, approve, receive, cancel purchase orders |
72
+ | `transfers` | Transfer inventory between locations |
73
+ | `products` | Find, create, update products and pricing |
74
+ | `customers` | Find, create, update customers |
75
+ | `collections` | Manage product collections |
76
+ | `suppliers` | Find and list suppliers |
77
+ | `locations` | Find store locations |
78
+ | `email` | Send emails, manage inbox |
79
+ | `alerts` | Low stock and pending order alerts |
80
+ | `documents` | Generate COAs and documents |
81
+ | `audit_trail` | View audit logs |
82
+
83
+ ## Development
84
+
85
+ ```bash
86
+ git clone https://github.com/floradistro/whale-mcp.git
87
+ cd whale-mcp
88
+ npm install
89
+ cp .env.example .env # fill in your credentials
90
+ npm run dev
91
+ ```
92
+
93
+ ## License
94
+
95
+ MIT
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ // SwagManager Local Agent — CLI entry point
3
+ // Usage: swag-agent start --key YOUR_API_KEY
4
+
5
+ import("../dist/local-agent/index.js").catch((err) => {
6
+ console.error("Failed to start swag-agent:", err.message);
7
+ console.error("Run 'npm run build' first if you see module not found errors.");
8
+ process.exit(1);
9
+ });
@@ -0,0 +1,321 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * whale code — local-first AI agent CLI
5
+ *
6
+ * Usage:
7
+ * whale Start interactive chat
8
+ * whale -p "prompt" Non-interactive (print) mode
9
+ * whale login Log in with SwagManager credentials
10
+ * whale logout Clear saved session
11
+ * whale status Show connection status
12
+ * whale mcp list|add|remove Manage MCP servers
13
+ * whale doctor Run diagnostics
14
+ * whale config [key] [value] View/set configuration
15
+ * whale help Show this help
16
+ * (non-TTY stdin) MCP stdio server for Claude Code / Cursor
17
+ */
18
+
19
+ import { fileURLToPath } from "url";
20
+ import { dirname, join } from "path";
21
+ import { readFileSync } from "fs";
22
+ import { parseArgs } from "util";
23
+
24
+ const __filename = fileURLToPath(import.meta.url);
25
+ const __dirname = dirname(__filename);
26
+ const distDir = join(__dirname, "..", "dist");
27
+
28
+ // Read version once — used for --version, help banner, etc.
29
+ let PKG_VERSION = "0.0.0";
30
+ try {
31
+ PKG_VERSION = JSON.parse(readFileSync(join(__dirname, "..", "package.json"), "utf-8")).version;
32
+ } catch { /* fallback */ }
33
+
34
+ // ── Parse CLI flags ──
35
+ let parsed;
36
+ try {
37
+ parsed = parseArgs({
38
+ allowPositionals: true,
39
+ strict: false,
40
+ options: {
41
+ // Print / headless mode
42
+ print: { type: "boolean", short: "p" },
43
+ "output-format": { type: "string" },
44
+ // Model & mode
45
+ model: { type: "string", short: "m" },
46
+ "permission-mode": { type: "string" },
47
+ // Session
48
+ resume: { type: "string", short: "r" },
49
+ continue: { type: "boolean", short: "c" },
50
+ "session-id": { type: "string" },
51
+ "no-session-persistence": { type: "boolean" },
52
+ // Limits
53
+ "max-turns": { type: "string" },
54
+ "max-budget-usd": { type: "string" },
55
+ effort: { type: "string" },
56
+ // Tool filtering
57
+ "allowed-tools": { type: "string" },
58
+ "disallowed-tools": { type: "string" },
59
+ // Fallback
60
+ "fallback-model": { type: "string" },
61
+ // Serve mode
62
+ port: { type: "string" },
63
+ host: { type: "string" },
64
+ // Debug / verbose
65
+ debug: { type: "boolean" },
66
+ verbose: { type: "boolean", short: "v" },
67
+ // Standard
68
+ help: { type: "boolean", short: "h" },
69
+ version: { type: "boolean" },
70
+ },
71
+ });
72
+ } catch (err) {
73
+ console.error(`Error: ${err.message}`);
74
+ console.error("Run 'whale help' for usage.");
75
+ process.exit(1);
76
+ }
77
+
78
+ const { values: flags, positionals } = parsed;
79
+
80
+ // First positional is the subcommand (unless --print is used)
81
+ const subcommand = positionals[0];
82
+ // If --print, remaining positionals form the message
83
+ const printMessage = flags.print
84
+ ? positionals.join(" ")
85
+ : undefined;
86
+
87
+ // ── Help ──
88
+ function showHelp() {
89
+ const d = "\x1b[2m";
90
+ const B = "\x1b[1m";
91
+ const r = "\x1b[0m";
92
+ const c = "\x1b[38;2;99;102;241m";
93
+ const g = "\x1b[38;2;100;116;139m";
94
+
95
+ console.log();
96
+ console.log(` ${g}╭──────────────────────────────────────────╮${r}`);
97
+ console.log(` ${g}│${r} ${g}│${r}`);
98
+ console.log(` ${g}│${r} ${c}${B}◆ whale code${r} ${d}v${PKG_VERSION}${r} ${g}│${r}`);
99
+ console.log(` ${g}│${r} ${d}local-first AI agent CLI${r} ${g}│${r}`);
100
+ console.log(` ${g}│${r} ${g}│${r}`);
101
+ console.log(` ${g}╰──────────────────────────────────────────╯${r}`);
102
+ console.log();
103
+ console.log(` ${B}Commands:${r}`);
104
+ console.log(` whale${d} Start chatting (default)${r}`);
105
+ console.log(` whale login${d} Log in to SwagManager${r}`);
106
+ console.log(` whale logout${d} Clear session${r}`);
107
+ console.log(` whale stores${d} Switch active store${r}`);
108
+ console.log(` whale status${d} Connection & tools${r}`);
109
+ console.log(` whale setup${d} Install MCP to IDEs${r}`);
110
+ console.log(` whale mcp${d} Manage MCP servers${r}`);
111
+ console.log(` whale doctor${d} Run diagnostics${r}`);
112
+ console.log(` whale init${d} Generate .whale/CLAUDE.md for project${r}`);
113
+ console.log(` whale config${d} View/set configuration${r}`);
114
+ console.log(` whale serve${d} Local agent WebSocket server${r}`);
115
+ console.log(` whale agent${d} Start local security agent${r}`);
116
+ console.log();
117
+ console.log(` ${B}Print Mode (non-interactive):${r}`);
118
+ console.log(` whale -p "prompt"${d} Run single prompt, output to stdout${r}`);
119
+ console.log(` echo "prompt" | whale -p${d} Read prompt from stdin${r}`);
120
+ console.log();
121
+ console.log(` ${B}Flags:${r}`);
122
+ console.log(` -p, --print${d} Non-interactive mode${r}`);
123
+ console.log(` --output-format <fmt>${d} text|json|stream-json (default: text)${r}`);
124
+ console.log(` -m, --model <name>${d} sonnet|opus|haiku${r}`);
125
+ console.log(` --permission-mode <mode>${d} default|plan|yolo${r}`);
126
+ console.log(` -r, --resume <id>${d} Resume session by ID${r}`);
127
+ console.log(` -c, --continue${d} Continue most recent session${r}`);
128
+ console.log(` --session-id <id>${d} Custom session UUID${r}`);
129
+ console.log(` --no-session-persistence${d} Ephemeral session${r}`);
130
+ console.log(` --max-turns <n>${d} Limit agent turns${r}`);
131
+ console.log(` --max-budget-usd <n>${d} Cost cap in USD${r}`);
132
+ console.log(` --effort <level>${d} low|medium|high${r}`);
133
+ console.log(` --allowed-tools <list>${d} Comma-separated tool whitelist${r}`);
134
+ console.log(` --disallowed-tools <list>${d} Comma-separated tool blacklist${r}`);
135
+ console.log(` --fallback-model <name>${d} Auto-fallback on overload${r}`);
136
+ console.log(` --debug${d} Debug logging to stderr${r}`);
137
+ console.log(` -v, --verbose${d} Extra output${r}`);
138
+ console.log();
139
+ console.log(` ${B}In chat:${r}`);
140
+ console.log(` ${d}Type ${r}/${d} to open command menu${r}`);
141
+ console.log(` ${d}^C to exit, esc to cancel${r}`);
142
+ console.log();
143
+ }
144
+
145
+ // Build options object from flags
146
+ function buildOptions() {
147
+ return {
148
+ model: flags.model,
149
+ permissionMode: flags["permission-mode"],
150
+ resumeSessionId: flags.resume,
151
+ continueLastSession: flags.continue,
152
+ sessionId: flags["session-id"],
153
+ noSessionPersistence: flags["no-session-persistence"],
154
+ maxTurns: flags["max-turns"] ? parseInt(flags["max-turns"], 10) : undefined,
155
+ maxBudgetUsd: flags["max-budget-usd"] ? parseFloat(flags["max-budget-usd"]) : undefined,
156
+ effort: flags.effort,
157
+ allowedTools: flags["allowed-tools"]?.split(",").map(s => s.trim()),
158
+ disallowedTools: flags["disallowed-tools"]?.split(",").map(s => s.trim()),
159
+ fallbackModel: flags["fallback-model"],
160
+ debug: flags.debug,
161
+ verbose: flags.verbose,
162
+ };
163
+ }
164
+
165
+ // ── Version ──
166
+ if (flags.version) {
167
+ console.log(PKG_VERSION);
168
+ process.exit(0);
169
+ }
170
+
171
+ // ── Help ──
172
+ if (flags.help && !subcommand) {
173
+ showHelp();
174
+ process.exit(0);
175
+ }
176
+
177
+ // ── Print mode ──
178
+ if (flags.print) {
179
+ const { runPrintMode } = await import(join(distDir, "cli", "print-mode.js"));
180
+ const options = buildOptions();
181
+
182
+ // Read stdin if available (non-TTY)
183
+ let stdinContent = "";
184
+ if (!process.stdin.isTTY) {
185
+ const chunks = [];
186
+ for await (const chunk of process.stdin) {
187
+ chunks.push(chunk);
188
+ }
189
+ stdinContent = Buffer.concat(chunks).toString("utf-8").trim();
190
+ }
191
+
192
+ // Combine stdin + positional message
193
+ const message = [stdinContent, printMessage].filter(Boolean).join("\n\n");
194
+ if (!message) {
195
+ console.error("Error: --print requires a message. Provide as argument or via stdin.");
196
+ process.exit(1);
197
+ }
198
+
199
+ const exitCode = await runPrintMode({
200
+ message,
201
+ outputFormat: flags["output-format"] || "text",
202
+ ...options,
203
+ });
204
+ process.exit(exitCode);
205
+ }
206
+
207
+ // ── Route subcommands ──
208
+ const command = subcommand;
209
+ switch (command) {
210
+ case "help":
211
+ case "--help":
212
+ case "-h":
213
+ showHelp();
214
+ break;
215
+
216
+ case "login": {
217
+ if (!process.stdin.isTTY) {
218
+ console.error("Error: whale login requires an interactive terminal.");
219
+ process.exit(1);
220
+ }
221
+ const { renderLogin } = await import(join(distDir, "cli", "app.js"));
222
+ await renderLogin();
223
+ break;
224
+ }
225
+
226
+ case "logout": {
227
+ const { renderLogout } = await import(join(distDir, "cli", "app.js"));
228
+ await renderLogout();
229
+ break;
230
+ }
231
+
232
+ case "chat":
233
+ case undefined: {
234
+ if (process.stdin.isTTY) {
235
+ const { renderChat } = await import(join(distDir, "cli", "app.js"));
236
+ await renderChat(buildOptions());
237
+ } else if (command === "chat") {
238
+ console.error("Error: whale chat requires an interactive terminal.");
239
+ process.exit(1);
240
+ } else {
241
+ // Non-TTY, no command → MCP stdio server
242
+ await import(join(distDir, "index.js"));
243
+ }
244
+ break;
245
+ }
246
+
247
+ case "status": {
248
+ const { renderStatus } = await import(join(distDir, "cli", "app.js"));
249
+ await renderStatus();
250
+ break;
251
+ }
252
+
253
+ case "setup": {
254
+ if (!process.stdin.isTTY) {
255
+ console.error("Error: whale setup requires an interactive terminal.");
256
+ process.exit(1);
257
+ }
258
+ const { renderSetup } = await import(join(distDir, "cli", "app.js"));
259
+ await renderSetup();
260
+ break;
261
+ }
262
+
263
+ case "stores":
264
+ case "store": {
265
+ if (!process.stdin.isTTY) {
266
+ console.error("Error: whale stores requires an interactive terminal.");
267
+ process.exit(1);
268
+ }
269
+ const { renderStores } = await import(join(distDir, "cli", "app.js"));
270
+ await renderStores();
271
+ break;
272
+ }
273
+
274
+ case "mcp": {
275
+ const { runMcpCommand } = await import(join(distDir, "cli", "commands", "mcp.js"));
276
+ await runMcpCommand(positionals.slice(1));
277
+ break;
278
+ }
279
+
280
+ case "doctor": {
281
+ const { runDoctor } = await import(join(distDir, "cli", "commands", "doctor.js"));
282
+ await runDoctor();
283
+ break;
284
+ }
285
+
286
+ case "config": {
287
+ const { runConfigCommand } = await import(join(distDir, "cli", "commands", "config-cmd.js"));
288
+ await runConfigCommand(positionals.slice(1), flags);
289
+ break;
290
+ }
291
+
292
+ case "init": {
293
+ const { runInit } = await import(join(distDir, "cli", "commands", "init.js"));
294
+ await runInit();
295
+ break;
296
+ }
297
+
298
+ case "serve": {
299
+ const { runServeMode } = await import(join(distDir, "cli", "serve-mode.js"));
300
+ await runServeMode({
301
+ port: flags.port ? parseInt(flags.port, 10) : 3847,
302
+ host: flags.host || "127.0.0.1",
303
+ ...buildOptions(),
304
+ });
305
+ break;
306
+ }
307
+
308
+ case "agent": {
309
+ // Forward remaining args to local-agent CLI
310
+ // Rebuild process.argv so the agent sees: [node, script, subcommand, ...flags]
311
+ const agentArgs = process.argv.slice(2).filter(a => a !== "agent");
312
+ process.argv = [process.argv[0], process.argv[1], ...agentArgs];
313
+ await import(join(distDir, "local-agent", "index.js"));
314
+ break;
315
+ }
316
+
317
+ default:
318
+ console.error(`Unknown command: ${command}`);
319
+ console.error(`Run 'whale help' for usage.`);
320
+ process.exit(1);
321
+ }
@@ -0,0 +1,26 @@
1
+ /**
2
+ * CLI App Entry Point
3
+ *
4
+ * Dynamic imports for each mode — keeps MCP server path clean.
5
+ */
6
+ export interface ChatOptions {
7
+ model?: string;
8
+ permissionMode?: string;
9
+ resumeSessionId?: string;
10
+ continueLastSession?: boolean;
11
+ sessionId?: string;
12
+ maxTurns?: number;
13
+ maxBudgetUsd?: number;
14
+ effort?: string;
15
+ allowedTools?: string[];
16
+ disallowedTools?: string[];
17
+ fallbackModel?: string;
18
+ debug?: boolean;
19
+ verbose?: boolean;
20
+ }
21
+ export declare function renderLogin(): Promise<void>;
22
+ export declare function renderLogout(): Promise<void>;
23
+ export declare function renderChat(options?: ChatOptions): Promise<void>;
24
+ export declare function renderSetup(): Promise<void>;
25
+ export declare function renderStatus(): Promise<void>;
26
+ export declare function renderStores(): Promise<void>;
@@ -0,0 +1,64 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { render } from "ink";
3
+ import { initErrorLogger, setErrorLoggerUser, captureError } from "./services/error-logger.js";
4
+ import { loadConfig } from "./services/config-store.js";
5
+ export async function renderLogin() {
6
+ const { LoginApp } = await import("./login/LoginApp.js");
7
+ const { waitUntilExit } = render(_jsx(LoginApp, {}));
8
+ await waitUntilExit();
9
+ }
10
+ export async function renderLogout() {
11
+ const { signOut, isLoggedIn } = await import("./services/auth-service.js");
12
+ if (!isLoggedIn()) {
13
+ console.log("Not logged in.");
14
+ }
15
+ else {
16
+ signOut();
17
+ console.log("Logged out. Tokens cleared.");
18
+ }
19
+ }
20
+ export async function renderChat(options) {
21
+ // Initialize error logging before anything else
22
+ initErrorLogger({ serviceName: "whale-code" });
23
+ const cfg = loadConfig();
24
+ if (cfg.user_id || cfg.email || cfg.store_id) {
25
+ setErrorLoggerUser(cfg.user_id, cfg.email, cfg.store_id);
26
+ }
27
+ // Global handlers — catch anything that slips through
28
+ process.on("uncaughtException", (err) => {
29
+ captureError({ error: err, severity: "fatal", tags: { source: "uncaughtException" } });
30
+ });
31
+ process.on("unhandledRejection", (reason) => {
32
+ const err = reason instanceof Error ? reason : new Error(String(reason));
33
+ captureError({ error: err, severity: "error", tags: { source: "unhandledRejection" } });
34
+ });
35
+ const { matrixIntro } = await import("./shared/MatrixIntro.js");
36
+ await matrixIntro();
37
+ // Apply options before starting chat
38
+ if (options?.model || options?.permissionMode) {
39
+ const agentLoop = await import("./services/agent-loop.js");
40
+ if (options.model)
41
+ agentLoop.setModel(options.model);
42
+ if (options.permissionMode) {
43
+ agentLoop.setPermissionMode(options.permissionMode);
44
+ }
45
+ }
46
+ const { ChatApp } = await import("./chat/ChatApp.js");
47
+ const { waitUntilExit } = render(_jsx(ChatApp, {}));
48
+ await waitUntilExit();
49
+ }
50
+ export async function renderSetup() {
51
+ const { SetupApp } = await import("./setup/SetupApp.js");
52
+ const { waitUntilExit } = render(_jsx(SetupApp, {}));
53
+ await waitUntilExit();
54
+ }
55
+ export async function renderStatus() {
56
+ const { StatusApp } = await import("./status/StatusApp.js");
57
+ const { waitUntilExit } = render(_jsx(StatusApp, {}));
58
+ await waitUntilExit();
59
+ }
60
+ export async function renderStores() {
61
+ const { StoreApp } = await import("./stores/StoreApp.js");
62
+ const { waitUntilExit } = render(_jsx(StoreApp, {}));
63
+ await waitUntilExit();
64
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * AgentSelector — polished agent picker with descriptions
3
+ */
4
+ interface Agent {
5
+ id: string;
6
+ name: string;
7
+ model: string;
8
+ }
9
+ interface AgentSelectorProps {
10
+ agents: Agent[];
11
+ onSelect: (agentId: string) => void;
12
+ }
13
+ export declare function AgentSelector({ agents, onSelect }: AgentSelectorProps): import("react/jsx-runtime").JSX.Element;
14
+ export {};
@@ -0,0 +1,14 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text } from "ink";
3
+ import SelectInput from "ink-select-input";
4
+ import { colors, symbols } from "../shared/Theme.js";
5
+ export function AgentSelector({ agents, onSelect }) {
6
+ const items = agents.map((a) => ({
7
+ label: `${a.name}`,
8
+ value: a.id,
9
+ }));
10
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Text, { color: colors.muted, children: "Select an agent:" }), _jsx(Box, { height: 1 }), _jsx(SelectInput, { items: items, onSelect: (item) => onSelect(item.value), indicatorComponent: ({ isSelected }) => (_jsxs(Text, { color: isSelected ? colors.brand : colors.dim, children: [isSelected ? symbols.arrowRight : " ", " "] })), itemComponent: ({ isSelected, label }) => {
11
+ const agent = agents.find((a) => a.name === label);
12
+ return (_jsxs(Box, { children: [_jsx(Text, { color: isSelected ? colors.brand : colors.text, bold: isSelected, children: label }), agent && (_jsxs(Text, { color: colors.dim, children: [" (", agent.model, ")"] }))] }));
13
+ } })] }));
14
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * ChatApp — whale code CLI
3
+ *
4
+ * Uses Ink's <Static> for completed messages — written to stdout once,
5
+ * never re-rendered. Only the active area (streaming, tools, input)
6
+ * is managed by Ink's render loop. This prevents scroll bounce when
7
+ * content exceeds the terminal height.
8
+ */
9
+ export declare function ChatApp(): import("react/jsx-runtime").JSX.Element;