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
@@ -0,0 +1,140 @@
1
+ /**
2
+ * OTA Auto-Updater for SwagManager MCP Server
3
+ *
4
+ * Checks the npm registry for newer versions and self-updates.
5
+ * - Runs on server startup (non-blocking)
6
+ * - Runs periodically (default: every 4 hours)
7
+ * - Updates in-place via `npm install -g` or local install
8
+ * - Signals the process to restart after update
9
+ */
10
+ import { execFile } from "child_process";
11
+ import { readFileSync } from "fs";
12
+ import { dirname, join } from "path";
13
+ import { fileURLToPath } from "url";
14
+ import https from "https";
15
+ // ============================================================================
16
+ // CONFIG
17
+ // ============================================================================
18
+ const PACKAGE_NAME = "swagmanager-mcp";
19
+ const CHECK_INTERVAL_MS = 4 * 60 * 60 * 1000; // 4 hours
20
+ const REGISTRY_URL = `https://registry.npmjs.org/${PACKAGE_NAME}/latest`;
21
+ // ============================================================================
22
+ // HELPERS
23
+ // ============================================================================
24
+ function getCurrentVersion() {
25
+ try {
26
+ const __filename = fileURLToPath(import.meta.url);
27
+ const __dirname = dirname(__filename);
28
+ const pkgPath = join(__dirname, "..", "package.json");
29
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
30
+ return pkg.version || "0.0.0";
31
+ }
32
+ catch {
33
+ return "0.0.0";
34
+ }
35
+ }
36
+ function parseVersion(v) {
37
+ return v.replace(/^v/, "").split(".").map(Number);
38
+ }
39
+ function isNewer(remote, local) {
40
+ const r = parseVersion(remote);
41
+ const l = parseVersion(local);
42
+ for (let i = 0; i < 3; i++) {
43
+ if ((r[i] || 0) > (l[i] || 0))
44
+ return true;
45
+ if ((r[i] || 0) < (l[i] || 0))
46
+ return false;
47
+ }
48
+ return false;
49
+ }
50
+ function fetchLatestVersion() {
51
+ return new Promise((resolve) => {
52
+ const req = https.get(REGISTRY_URL, { timeout: 10_000 }, (res) => {
53
+ let body = "";
54
+ res.on("data", (chunk) => (body += chunk.toString()));
55
+ res.on("end", () => {
56
+ try {
57
+ const data = JSON.parse(body);
58
+ resolve({
59
+ version: data.version,
60
+ changelog: data.changelog || data.description,
61
+ });
62
+ }
63
+ catch {
64
+ resolve(null);
65
+ }
66
+ });
67
+ });
68
+ req.on("error", () => resolve(null));
69
+ req.on("timeout", () => {
70
+ req.destroy();
71
+ resolve(null);
72
+ });
73
+ });
74
+ }
75
+ function runNpmInstall(version) {
76
+ return new Promise((resolve) => {
77
+ const args = ["install", "-g", `${PACKAGE_NAME}@${version}`];
78
+ console.error(`[updater] Running: npm ${args.join(" ")}`);
79
+ execFile("npm", args, { timeout: 120_000 }, (error, stdout, stderr) => {
80
+ if (error) {
81
+ console.error(`[updater] Install failed: ${error.message}`);
82
+ if (stderr)
83
+ console.error(`[updater] stderr: ${stderr}`);
84
+ resolve(false);
85
+ }
86
+ else {
87
+ console.error(`[updater] Install succeeded`);
88
+ if (stdout)
89
+ console.error(`[updater] ${stdout.trim()}`);
90
+ resolve(true);
91
+ }
92
+ });
93
+ });
94
+ }
95
+ /**
96
+ * Check for updates and install if available.
97
+ * Returns the result without restarting — caller decides restart behavior.
98
+ */
99
+ export async function checkForUpdates(autoInstall = true) {
100
+ const currentVersion = getCurrentVersion();
101
+ const latest = await fetchLatestVersion();
102
+ if (!latest) {
103
+ console.error(`[updater] Could not reach npm registry (offline?)`);
104
+ return { currentVersion, latestVersion: null, updateAvailable: false, updated: false };
105
+ }
106
+ const updateAvailable = isNewer(latest.version, currentVersion);
107
+ if (!updateAvailable) {
108
+ console.error(`[updater] Up to date (v${currentVersion})`);
109
+ return { currentVersion, latestVersion: latest.version, updateAvailable: false, updated: false };
110
+ }
111
+ console.error(`[updater] Update available: v${currentVersion} → v${latest.version}`);
112
+ if (!autoInstall) {
113
+ return { currentVersion, latestVersion: latest.version, updateAvailable: true, updated: false };
114
+ }
115
+ const installed = await runNpmInstall(latest.version);
116
+ if (installed) {
117
+ console.error(`[updater] Updated to v${latest.version}. Restart to use new version.`);
118
+ }
119
+ return {
120
+ currentVersion,
121
+ latestVersion: latest.version,
122
+ updateAvailable: true,
123
+ updated: installed,
124
+ };
125
+ }
126
+ /**
127
+ * Start periodic update checks in the background.
128
+ * First check runs immediately (non-blocking), then every CHECK_INTERVAL_MS.
129
+ */
130
+ export function startUpdateLoop(autoInstall = true) {
131
+ // Initial check (fire-and-forget)
132
+ checkForUpdates(autoInstall).catch(() => { });
133
+ // Periodic checks
134
+ const timer = setInterval(() => {
135
+ checkForUpdates(autoInstall).catch(() => { });
136
+ }, CHECK_INTERVAL_MS);
137
+ // Don't prevent process exit
138
+ timer.unref();
139
+ return timer;
140
+ }
File without changes
@@ -0,0 +1,397 @@
1
+ "use strict";
2
+ // Webchat Widget — embeddable chat bubble for any website
3
+ // Usage: <script src="https://whale-agent.fly.dev/webchat/widget.js" data-channel="CHANNEL_ID"></script>
4
+ //
5
+ // Build: esbuild src/webchat/widget.ts --bundle --minify --outfile=dist/webchat/widget.js
6
+ // This file uses no framework — pure vanilla JS for minimal bundle size.
7
+ // TypeScript annotations are stripped at build time.
8
+ (function () {
9
+ const WIDGET_VERSION = "1.0.0";
10
+ // Read config from script tag
11
+ const script = document.currentScript;
12
+ const channelId = script?.getAttribute("data-channel") || "";
13
+ const serverUrl = script?.getAttribute("data-server") ||
14
+ script?.src.replace(/\/webchat\/widget\.js.*$/, "") ||
15
+ "";
16
+ const position = script?.getAttribute("data-position") || "bottom-right";
17
+ const accentColor = script?.getAttribute("data-color") || "#0066FF";
18
+ const headerTitle = script?.getAttribute("data-title") || "Chat with us";
19
+ if (!channelId) {
20
+ console.error("[WhaleChat] Missing data-channel attribute");
21
+ return;
22
+ }
23
+ // Generate anonymous user ID (persisted in localStorage per channel)
24
+ const STORAGE_KEY = "whalechat_" + channelId;
25
+ let userId = localStorage.getItem(STORAGE_KEY + "_user");
26
+ if (!userId) {
27
+ userId = "anon_" + Math.random().toString(36).substring(2, 15);
28
+ localStorage.setItem(STORAGE_KEY + "_user", userId);
29
+ }
30
+ // Conversation ID — persists across page navigations within same session
31
+ let conversationId = sessionStorage.getItem(STORAGE_KEY + "_conv") || "";
32
+ // State
33
+ let isOpen = false;
34
+ let isSending = false;
35
+ // ─── Styles ───────────────────────────────────────────────
36
+ const posLeft = position === "bottom-left";
37
+ const styles = document.createElement("style");
38
+ styles.textContent = [
39
+ ".wc-bubble {",
40
+ " position: fixed;",
41
+ posLeft ? " left: 20px;" : " right: 20px;",
42
+ " bottom: 20px;",
43
+ " width: 56px;",
44
+ " height: 56px;",
45
+ " border-radius: 50%;",
46
+ " background: " + accentColor + ";",
47
+ " color: white;",
48
+ " border: none;",
49
+ " cursor: pointer;",
50
+ " box-shadow: 0 4px 12px rgba(0,0,0,0.15);",
51
+ " display: flex;",
52
+ " align-items: center;",
53
+ " justify-content: center;",
54
+ " z-index: 99999;",
55
+ " transition: transform 0.2s;",
56
+ " font-size: 24px;",
57
+ "}",
58
+ ".wc-bubble:hover { transform: scale(1.1); }",
59
+ "",
60
+ ".wc-panel {",
61
+ " position: fixed;",
62
+ posLeft ? " left: 20px;" : " right: 20px;",
63
+ " bottom: 88px;",
64
+ " width: 380px;",
65
+ " height: 520px;",
66
+ " background: white;",
67
+ " border-radius: 16px;",
68
+ " box-shadow: 0 8px 32px rgba(0,0,0,0.12);",
69
+ " display: none;",
70
+ " flex-direction: column;",
71
+ " z-index: 99998;",
72
+ " overflow: hidden;",
73
+ " font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;",
74
+ "}",
75
+ ".wc-panel.open { display: flex; }",
76
+ "",
77
+ ".wc-header {",
78
+ " padding: 16px;",
79
+ " background: " + accentColor + ";",
80
+ " color: white;",
81
+ " font-weight: 600;",
82
+ " font-size: 15px;",
83
+ " display: flex;",
84
+ " align-items: center;",
85
+ " justify-content: space-between;",
86
+ "}",
87
+ ".wc-header-close {",
88
+ " background: none;",
89
+ " border: none;",
90
+ " color: white;",
91
+ " font-size: 20px;",
92
+ " cursor: pointer;",
93
+ " padding: 4px 8px;",
94
+ " line-height: 1;",
95
+ "}",
96
+ "",
97
+ ".wc-messages {",
98
+ " flex: 1;",
99
+ " overflow-y: auto;",
100
+ " padding: 12px;",
101
+ " display: flex;",
102
+ " flex-direction: column;",
103
+ " gap: 8px;",
104
+ "}",
105
+ "",
106
+ ".wc-msg {",
107
+ " max-width: 80%;",
108
+ " padding: 10px 14px;",
109
+ " border-radius: 16px;",
110
+ " font-size: 14px;",
111
+ " line-height: 1.4;",
112
+ " word-wrap: break-word;",
113
+ "}",
114
+ ".wc-msg.user {",
115
+ " align-self: flex-end;",
116
+ " background: " + accentColor + ";",
117
+ " color: white;",
118
+ " border-bottom-right-radius: 4px;",
119
+ "}",
120
+ ".wc-msg.agent {",
121
+ " align-self: flex-start;",
122
+ " background: #f0f0f0;",
123
+ " color: #333;",
124
+ " border-bottom-left-radius: 4px;",
125
+ "}",
126
+ ".wc-msg .wc-time {",
127
+ " font-size: 11px;",
128
+ " opacity: 0.6;",
129
+ " margin-top: 4px;",
130
+ "}",
131
+ "",
132
+ ".wc-input-bar {",
133
+ " padding: 12px;",
134
+ " border-top: 1px solid #eee;",
135
+ " display: flex;",
136
+ " gap: 8px;",
137
+ "}",
138
+ ".wc-input-bar input {",
139
+ " flex: 1;",
140
+ " padding: 10px 14px;",
141
+ " border: 1px solid #ddd;",
142
+ " border-radius: 24px;",
143
+ " font-size: 14px;",
144
+ " outline: none;",
145
+ " font-family: inherit;",
146
+ "}",
147
+ ".wc-input-bar input:focus { border-color: " + accentColor + "; }",
148
+ ".wc-input-bar button {",
149
+ " width: 40px;",
150
+ " height: 40px;",
151
+ " border-radius: 50%;",
152
+ " background: " + accentColor + ";",
153
+ " color: white;",
154
+ " border: none;",
155
+ " cursor: pointer;",
156
+ " font-size: 16px;",
157
+ " display: flex;",
158
+ " align-items: center;",
159
+ " justify-content: center;",
160
+ "}",
161
+ ".wc-input-bar button:disabled { opacity: 0.5; cursor: default; }",
162
+ "",
163
+ ".wc-typing {",
164
+ " align-self: flex-start;",
165
+ " padding: 10px 14px;",
166
+ " background: #f0f0f0;",
167
+ " border-radius: 16px;",
168
+ " font-size: 14px;",
169
+ " color: #999;",
170
+ " border-bottom-left-radius: 4px;",
171
+ "}",
172
+ "",
173
+ ".wc-powered {",
174
+ " text-align: center;",
175
+ " font-size: 11px;",
176
+ " color: #bbb;",
177
+ " padding: 4px 0 8px;",
178
+ "}",
179
+ "",
180
+ "@media (max-width: 420px) {",
181
+ " .wc-panel {",
182
+ " width: calc(100vw - 16px);",
183
+ " height: calc(100vh - 100px);",
184
+ " left: 8px;",
185
+ " right: 8px;",
186
+ " bottom: 80px;",
187
+ " border-radius: 12px;",
188
+ " }",
189
+ "}",
190
+ ].join("\n");
191
+ document.head.appendChild(styles);
192
+ // ─── DOM ──────────────────────────────────────────────────
193
+ // Bubble button
194
+ const bubble = document.createElement("button");
195
+ bubble.className = "wc-bubble";
196
+ bubble.setAttribute("aria-label", "Open chat");
197
+ bubble.innerHTML =
198
+ '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>';
199
+ bubble.addEventListener("click", togglePanel);
200
+ document.body.appendChild(bubble);
201
+ // Chat panel
202
+ const panel = document.createElement("div");
203
+ panel.className = "wc-panel";
204
+ // Header
205
+ const header = document.createElement("div");
206
+ header.className = "wc-header";
207
+ const headerSpan = document.createElement("span");
208
+ headerSpan.textContent = headerTitle;
209
+ const closeBtn = document.createElement("button");
210
+ closeBtn.className = "wc-header-close";
211
+ closeBtn.setAttribute("aria-label", "Close chat");
212
+ closeBtn.innerHTML = "&times;";
213
+ closeBtn.addEventListener("click", togglePanel);
214
+ header.appendChild(headerSpan);
215
+ header.appendChild(closeBtn);
216
+ panel.appendChild(header);
217
+ // Messages area
218
+ const msgsEl = document.createElement("div");
219
+ msgsEl.className = "wc-messages";
220
+ panel.appendChild(msgsEl);
221
+ // Input bar
222
+ const inputBar = document.createElement("div");
223
+ inputBar.className = "wc-input-bar";
224
+ const inputEl = document.createElement("input");
225
+ inputEl.type = "text";
226
+ inputEl.placeholder = "Type a message...";
227
+ inputEl.setAttribute("autocomplete", "off");
228
+ inputEl.addEventListener("keydown", function (e) {
229
+ if (e.key === "Enter" && !e.shiftKey) {
230
+ e.preventDefault();
231
+ sendMessage();
232
+ }
233
+ });
234
+ const sendBtn = document.createElement("button");
235
+ sendBtn.setAttribute("aria-label", "Send");
236
+ sendBtn.innerHTML = "&#8593;";
237
+ sendBtn.addEventListener("click", sendMessage);
238
+ inputBar.appendChild(inputEl);
239
+ inputBar.appendChild(sendBtn);
240
+ panel.appendChild(inputBar);
241
+ // Powered-by
242
+ const powered = document.createElement("div");
243
+ powered.className = "wc-powered";
244
+ powered.textContent = "Powered by WhaleChat";
245
+ panel.appendChild(powered);
246
+ document.body.appendChild(panel);
247
+ // ─── Functions ────────────────────────────────────────────
248
+ function togglePanel() {
249
+ isOpen = !isOpen;
250
+ if (isOpen) {
251
+ panel.classList.add("open");
252
+ bubble.innerHTML =
253
+ '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>';
254
+ inputEl.focus();
255
+ // Load conversation history on first open
256
+ if (msgsEl.children.length === 0 && conversationId) {
257
+ loadHistory();
258
+ }
259
+ }
260
+ else {
261
+ panel.classList.remove("open");
262
+ bubble.innerHTML =
263
+ '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>';
264
+ }
265
+ }
266
+ async function loadHistory() {
267
+ try {
268
+ const res = await fetch(serverUrl +
269
+ "/webchat/channels/" +
270
+ channelId +
271
+ "/history?sender_id=" +
272
+ encodeURIComponent(userId) +
273
+ "&conversation_id=" +
274
+ encodeURIComponent(conversationId));
275
+ if (!res.ok)
276
+ return;
277
+ const data = await res.json();
278
+ if (data.messages && Array.isArray(data.messages)) {
279
+ for (const m of data.messages) {
280
+ addMessageToUI({
281
+ role: m.direction === "inbound" ? "user" : "agent",
282
+ content: m.content || "",
283
+ time: formatTime(m.created_at),
284
+ });
285
+ }
286
+ }
287
+ }
288
+ catch {
289
+ // History load is best-effort
290
+ }
291
+ }
292
+ async function sendMessage() {
293
+ const text = inputEl.value.trim();
294
+ if (!text || isSending)
295
+ return;
296
+ inputEl.value = "";
297
+ isSending = true;
298
+ sendBtn.disabled = true;
299
+ // Add user message to UI immediately
300
+ addMessageToUI({
301
+ role: "user",
302
+ content: text,
303
+ time: formatTime(new Date().toISOString()),
304
+ });
305
+ // Show typing indicator
306
+ const typingEl = document.createElement("div");
307
+ typingEl.className = "wc-typing";
308
+ typingEl.textContent = "Thinking...";
309
+ msgsEl.appendChild(typingEl);
310
+ msgsEl.scrollTop = msgsEl.scrollHeight;
311
+ try {
312
+ const res = await fetch(serverUrl + "/webchat/channels/" + channelId + "/messages", {
313
+ method: "POST",
314
+ headers: { "Content-Type": "application/json" },
315
+ body: JSON.stringify({
316
+ sender_id: userId,
317
+ sender_name: "Visitor",
318
+ content: text,
319
+ content_type: "text",
320
+ conversation_id: conversationId || undefined,
321
+ }),
322
+ });
323
+ const data = await res.json();
324
+ typingEl.remove();
325
+ if (!res.ok) {
326
+ addMessageToUI({
327
+ role: "agent",
328
+ content: data.error || "Something went wrong. Please try again.",
329
+ time: formatTime(new Date().toISOString()),
330
+ });
331
+ return;
332
+ }
333
+ // Persist conversation ID for session continuity
334
+ if (data.conversation_id) {
335
+ conversationId = data.conversation_id;
336
+ sessionStorage.setItem(STORAGE_KEY + "_conv", conversationId);
337
+ }
338
+ if (data.agent_response?.content) {
339
+ addMessageToUI({
340
+ role: "agent",
341
+ content: data.agent_response.content,
342
+ time: formatTime(data.agent_response.created_at || new Date().toISOString()),
343
+ });
344
+ }
345
+ }
346
+ catch {
347
+ typingEl.textContent = "Failed to send. Try again.";
348
+ setTimeout(function () {
349
+ typingEl.remove();
350
+ }, 3000);
351
+ }
352
+ finally {
353
+ isSending = false;
354
+ sendBtn.disabled = false;
355
+ }
356
+ }
357
+ function addMessageToUI(msg) {
358
+ const el = document.createElement("div");
359
+ el.className = "wc-msg " + msg.role;
360
+ const contentSpan = document.createElement("span");
361
+ contentSpan.textContent = msg.content;
362
+ el.appendChild(contentSpan);
363
+ const timeDiv = document.createElement("div");
364
+ timeDiv.className = "wc-time";
365
+ timeDiv.textContent = msg.time;
366
+ el.appendChild(timeDiv);
367
+ msgsEl.appendChild(el);
368
+ msgsEl.scrollTop = msgsEl.scrollHeight;
369
+ }
370
+ function formatTime(isoString) {
371
+ try {
372
+ const d = new Date(isoString);
373
+ return d.toLocaleTimeString(undefined, {
374
+ hour: "numeric",
375
+ minute: "2-digit",
376
+ });
377
+ }
378
+ catch {
379
+ return "";
380
+ }
381
+ }
382
+ // Expose API for programmatic control
383
+ window.WhaleChat = {
384
+ version: WIDGET_VERSION,
385
+ open: function () {
386
+ if (!isOpen)
387
+ togglePanel();
388
+ },
389
+ close: function () {
390
+ if (isOpen)
391
+ togglePanel();
392
+ },
393
+ isOpen: function () {
394
+ return isOpen;
395
+ },
396
+ };
397
+ })();
package/package.json ADDED
@@ -0,0 +1,95 @@
1
+ {
2
+ "name": "whale-code",
3
+ "version": "6.4.0",
4
+ "description": "whale code — local-first AI agent CLI for inventory, orders, and analytics powered by MCP",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "bin": {
8
+ "whale": "./bin/swagmanager-mcp.js",
9
+ "swag-agent": "./bin/swag-agent.js",
10
+ "whalenode": "./dist/node/cli.js"
11
+ },
12
+ "scripts": {
13
+ "start": "node dist/index.js",
14
+ "dev": "tsx src/index.ts",
15
+ "build": "tsc",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "dependencies": {
21
+ "@anthropic-ai/sdk": "^0.74.0",
22
+ "@aws-sdk/client-bedrock-runtime": "^3.990.0",
23
+ "@google/genai": "^1.41.0",
24
+ "@modelcontextprotocol/sdk": "^1.25.3",
25
+ "@supabase/supabase-js": "2.95.3",
26
+ "bonjour-service": "^1.3.0",
27
+ "chalk": "^5.6.2",
28
+ "cli-highlight": "^2.1.11",
29
+ "diff": "^7.0.0",
30
+ "ink": "^5.1.0",
31
+ "ink-select-input": "^6.0.0",
32
+ "ink-spinner": "^5.0.0",
33
+ "ink-text-input": "^6.0.0",
34
+ "marked": "^15.0.12",
35
+ "marked-terminal": "^7.3.0",
36
+ "node-pty": "^1.1.0",
37
+ "openai": "^6.22.0",
38
+ "pdf-parse": "^1.1.1",
39
+ "pg": "^8.18.0",
40
+ "pino": "^10.3.1",
41
+ "playwright-core": "^1.58.2",
42
+ "react": "^18.3.1",
43
+ "ws": "^8.19.0",
44
+ "zod": "^4.3.6"
45
+ },
46
+ "optionalDependencies": {
47
+ "@vscode/ripgrep": "^1.15.9"
48
+ },
49
+ "devDependencies": {
50
+ "@types/node": "^20.10.0",
51
+ "@types/pg": "^8.16.0",
52
+ "@types/pino": "^7.0.4",
53
+ "@types/react": "^18.3.0",
54
+ "@types/ws": "^8.18.1",
55
+ "@vitest/coverage-v8": "^4.0.18",
56
+ "dotenv": "^17.3.1",
57
+ "memfs": "^4.56.10",
58
+ "tsx": "^4.7.0",
59
+ "typescript": "^5.3.0",
60
+ "vitest": "^4.0.18"
61
+ },
62
+ "engines": {
63
+ "node": ">=20.0.0"
64
+ },
65
+ "files": [
66
+ "dist",
67
+ "bin",
68
+ "src/cli/services/builtin-skills",
69
+ "README.md"
70
+ ],
71
+ "publishConfig": {
72
+ "access": "public"
73
+ },
74
+ "repository": {
75
+ "type": "git",
76
+ "url": "https://github.com/floradistro/whale-mcp.git"
77
+ },
78
+ "author": "Flora Distribution",
79
+ "keywords": [
80
+ "mcp",
81
+ "claude",
82
+ "anthropic",
83
+ "swagmanager",
84
+ "inventory",
85
+ "retail",
86
+ "ai-tools",
87
+ "cli",
88
+ "tui",
89
+ "ink"
90
+ ],
91
+ "license": "MIT",
92
+ "overrides": {
93
+ "minimatch": ">=10.2.1"
94
+ }
95
+ }
@@ -0,0 +1,19 @@
1
+ ---
2
+ description: Stage changes, draft commit message, create commit
3
+ ---
4
+ Create a git commit for the current changes. Follow these steps:
5
+
6
+ 1. Run `git status` to see all modified and untracked files.
7
+ 2. Run `git diff` to see staged and unstaged changes.
8
+ 3. Run `git log --oneline -5` to see recent commit style.
9
+ 4. Analyze the changes and draft a concise commit message that:
10
+ - Summarizes the nature of changes (feature, fix, refactor, etc.)
11
+ - Focuses on "why" not "what"
12
+ - Follows the repository's existing commit message style
13
+ 5. Stage relevant files (prefer specific files over `git add -A`).
14
+ 6. Create the commit. Never skip hooks.
15
+ 7. Show the result with `git log --oneline -1`.
16
+
17
+ Do NOT push to remote. Do NOT commit files that look like secrets (.env, credentials, etc.).
18
+
19
+ $ARGS
@@ -0,0 +1,21 @@
1
+ ---
2
+ description: Review a pull request by number
3
+ ---
4
+ Review pull request #$1. Steps:
5
+
6
+ 1. Run `gh pr view $1` to get PR details and description.
7
+ 2. Run `gh pr diff $1` to get the full diff.
8
+ 3. Analyze the changes for:
9
+ - Logic errors or bugs
10
+ - Security issues
11
+ - Performance problems
12
+ - Missing tests
13
+ - Style inconsistencies
14
+ - Whether the PR description accurately reflects the changes
15
+ 4. Provide a structured review with:
16
+ - Summary of what the PR does
17
+ - Issues found (organized by severity)
18
+ - Suggestions for improvement
19
+ - Overall assessment (approve / request changes / needs discussion)
20
+
21
+ $ARGS