@jungjaehoon/mama-os 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (356) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +643 -0
  3. package/dist/agent/agent-loop.d.ts +98 -0
  4. package/dist/agent/agent-loop.d.ts.map +1 -0
  5. package/dist/agent/agent-loop.js +417 -0
  6. package/dist/agent/agent-loop.js.map +1 -0
  7. package/dist/agent/auto-recall.d.ts +48 -0
  8. package/dist/agent/auto-recall.d.ts.map +1 -0
  9. package/dist/agent/auto-recall.js +178 -0
  10. package/dist/agent/auto-recall.js.map +1 -0
  11. package/dist/agent/claude-cli-wrapper.d.ts +130 -0
  12. package/dist/agent/claude-cli-wrapper.d.ts.map +1 -0
  13. package/dist/agent/claude-cli-wrapper.js +227 -0
  14. package/dist/agent/claude-cli-wrapper.js.map +1 -0
  15. package/dist/agent/claude-client.d.ts +50 -0
  16. package/dist/agent/claude-client.d.ts.map +1 -0
  17. package/dist/agent/claude-client.js +214 -0
  18. package/dist/agent/claude-client.js.map +1 -0
  19. package/dist/agent/gateway-tool-executor.d.ts +75 -0
  20. package/dist/agent/gateway-tool-executor.d.ts.map +1 -0
  21. package/dist/agent/gateway-tool-executor.js +348 -0
  22. package/dist/agent/gateway-tool-executor.js.map +1 -0
  23. package/dist/agent/index.d.ts +13 -0
  24. package/dist/agent/index.d.ts.map +1 -0
  25. package/dist/agent/index.js +18 -0
  26. package/dist/agent/index.js.map +1 -0
  27. package/dist/agent/mcp-executor.d.ts +75 -0
  28. package/dist/agent/mcp-executor.d.ts.map +1 -0
  29. package/dist/agent/mcp-executor.js +307 -0
  30. package/dist/agent/mcp-executor.js.map +1 -0
  31. package/dist/agent/session-pool.d.ts +148 -0
  32. package/dist/agent/session-pool.d.ts.map +1 -0
  33. package/dist/agent/session-pool.js +272 -0
  34. package/dist/agent/session-pool.js.map +1 -0
  35. package/dist/agent/streaming-callback-manager.d.ts +85 -0
  36. package/dist/agent/streaming-callback-manager.d.ts.map +1 -0
  37. package/dist/agent/streaming-callback-manager.js +103 -0
  38. package/dist/agent/streaming-callback-manager.js.map +1 -0
  39. package/dist/agent/types.d.ts +437 -0
  40. package/dist/agent/types.d.ts.map +1 -0
  41. package/dist/agent/types.js +29 -0
  42. package/dist/agent/types.js.map +1 -0
  43. package/dist/api/cron-handler.d.ts +44 -0
  44. package/dist/api/cron-handler.d.ts.map +1 -0
  45. package/dist/api/cron-handler.js +195 -0
  46. package/dist/api/cron-handler.js.map +1 -0
  47. package/dist/api/error-handler.d.ts +22 -0
  48. package/dist/api/error-handler.d.ts.map +1 -0
  49. package/dist/api/error-handler.js +104 -0
  50. package/dist/api/error-handler.js.map +1 -0
  51. package/dist/api/heartbeat-handler.d.ts +49 -0
  52. package/dist/api/heartbeat-handler.d.ts.map +1 -0
  53. package/dist/api/heartbeat-handler.js +91 -0
  54. package/dist/api/heartbeat-handler.js.map +1 -0
  55. package/dist/api/index.d.ts +61 -0
  56. package/dist/api/index.d.ts.map +1 -0
  57. package/dist/api/index.js +145 -0
  58. package/dist/api/index.js.map +1 -0
  59. package/dist/api/types.d.ts +156 -0
  60. package/dist/api/types.d.ts.map +1 -0
  61. package/dist/api/types.js +62 -0
  62. package/dist/api/types.js.map +1 -0
  63. package/dist/auth/index.d.ts +7 -0
  64. package/dist/auth/index.d.ts.map +1 -0
  65. package/dist/auth/index.js +11 -0
  66. package/dist/auth/index.js.map +1 -0
  67. package/dist/auth/oauth-manager.d.ts +59 -0
  68. package/dist/auth/oauth-manager.d.ts.map +1 -0
  69. package/dist/auth/oauth-manager.js +237 -0
  70. package/dist/auth/oauth-manager.js.map +1 -0
  71. package/dist/auth/types.d.ts +92 -0
  72. package/dist/auth/types.d.ts.map +1 -0
  73. package/dist/auth/types.js +23 -0
  74. package/dist/auth/types.js.map +1 -0
  75. package/dist/cli/commands/init.d.ts +19 -0
  76. package/dist/cli/commands/init.d.ts.map +1 -0
  77. package/dist/cli/commands/init.js +155 -0
  78. package/dist/cli/commands/init.js.map +1 -0
  79. package/dist/cli/commands/run.d.ts +19 -0
  80. package/dist/cli/commands/run.d.ts.map +1 -0
  81. package/dist/cli/commands/run.js +89 -0
  82. package/dist/cli/commands/run.js.map +1 -0
  83. package/dist/cli/commands/setup.d.ts +19 -0
  84. package/dist/cli/commands/setup.d.ts.map +1 -0
  85. package/dist/cli/commands/setup.js +134 -0
  86. package/dist/cli/commands/setup.js.map +1 -0
  87. package/dist/cli/commands/start.d.ts +24 -0
  88. package/dist/cli/commands/start.d.ts.map +1 -0
  89. package/dist/cli/commands/start.js +1073 -0
  90. package/dist/cli/commands/start.js.map +1 -0
  91. package/dist/cli/commands/status.d.ts +10 -0
  92. package/dist/cli/commands/status.d.ts.map +1 -0
  93. package/dist/cli/commands/status.js +85 -0
  94. package/dist/cli/commands/status.js.map +1 -0
  95. package/dist/cli/commands/stop.d.ts +10 -0
  96. package/dist/cli/commands/stop.d.ts.map +1 -0
  97. package/dist/cli/commands/stop.js +65 -0
  98. package/dist/cli/commands/stop.js.map +1 -0
  99. package/dist/cli/config/config-manager.d.ts +51 -0
  100. package/dist/cli/config/config-manager.d.ts.map +1 -0
  101. package/dist/cli/config/config-manager.js +216 -0
  102. package/dist/cli/config/config-manager.js.map +1 -0
  103. package/dist/cli/config/types.d.ts +172 -0
  104. package/dist/cli/config/types.d.ts.map +1 -0
  105. package/dist/cli/config/types.js +48 -0
  106. package/dist/cli/config/types.js.map +1 -0
  107. package/dist/cli/index.d.ts +8 -0
  108. package/dist/cli/index.d.ts.map +1 -0
  109. package/dist/cli/index.js +92 -0
  110. package/dist/cli/index.js.map +1 -0
  111. package/dist/cli/utils/pid-manager.d.ts +66 -0
  112. package/dist/cli/utils/pid-manager.d.ts.map +1 -0
  113. package/dist/cli/utils/pid-manager.js +167 -0
  114. package/dist/cli/utils/pid-manager.js.map +1 -0
  115. package/dist/concurrency/index.d.ts +13 -0
  116. package/dist/concurrency/index.d.ts.map +1 -0
  117. package/dist/concurrency/index.js +22 -0
  118. package/dist/concurrency/index.js.map +1 -0
  119. package/dist/concurrency/lane-manager.d.ts +113 -0
  120. package/dist/concurrency/lane-manager.d.ts.map +1 -0
  121. package/dist/concurrency/lane-manager.js +245 -0
  122. package/dist/concurrency/lane-manager.js.map +1 -0
  123. package/dist/concurrency/session-key.d.ts +41 -0
  124. package/dist/concurrency/session-key.d.ts.map +1 -0
  125. package/dist/concurrency/session-key.js +61 -0
  126. package/dist/concurrency/session-key.js.map +1 -0
  127. package/dist/concurrency/types.d.ts +69 -0
  128. package/dist/concurrency/types.d.ts.map +1 -0
  129. package/dist/concurrency/types.js +16 -0
  130. package/dist/concurrency/types.js.map +1 -0
  131. package/dist/gateways/channel-history.d.ts +102 -0
  132. package/dist/gateways/channel-history.d.ts.map +1 -0
  133. package/dist/gateways/channel-history.js +181 -0
  134. package/dist/gateways/channel-history.js.map +1 -0
  135. package/dist/gateways/context-injector.d.ts +74 -0
  136. package/dist/gateways/context-injector.d.ts.map +1 -0
  137. package/dist/gateways/context-injector.js +121 -0
  138. package/dist/gateways/context-injector.js.map +1 -0
  139. package/dist/gateways/discord.d.ts +122 -0
  140. package/dist/gateways/discord.d.ts.map +1 -0
  141. package/dist/gateways/discord.js +602 -0
  142. package/dist/gateways/discord.js.map +1 -0
  143. package/dist/gateways/index.d.ts +30 -0
  144. package/dist/gateways/index.d.ts.map +1 -0
  145. package/dist/gateways/index.js +49 -0
  146. package/dist/gateways/index.js.map +1 -0
  147. package/dist/gateways/message-router.d.ts +116 -0
  148. package/dist/gateways/message-router.d.ts.map +1 -0
  149. package/dist/gateways/message-router.js +315 -0
  150. package/dist/gateways/message-router.js.map +1 -0
  151. package/dist/gateways/message-splitter.d.ts +54 -0
  152. package/dist/gateways/message-splitter.d.ts.map +1 -0
  153. package/dist/gateways/message-splitter.js +146 -0
  154. package/dist/gateways/message-splitter.js.map +1 -0
  155. package/dist/gateways/plugin-loader.d.ts +76 -0
  156. package/dist/gateways/plugin-loader.d.ts.map +1 -0
  157. package/dist/gateways/plugin-loader.js +221 -0
  158. package/dist/gateways/plugin-loader.js.map +1 -0
  159. package/dist/gateways/session-store.d.ts +77 -0
  160. package/dist/gateways/session-store.d.ts.map +1 -0
  161. package/dist/gateways/session-store.js +233 -0
  162. package/dist/gateways/session-store.js.map +1 -0
  163. package/dist/gateways/slack.d.ts +90 -0
  164. package/dist/gateways/slack.d.ts.map +1 -0
  165. package/dist/gateways/slack.js +281 -0
  166. package/dist/gateways/slack.js.map +1 -0
  167. package/dist/gateways/telegram.d.ts +79 -0
  168. package/dist/gateways/telegram.d.ts.map +1 -0
  169. package/dist/gateways/telegram.js +207 -0
  170. package/dist/gateways/telegram.js.map +1 -0
  171. package/dist/gateways/types.d.ts +340 -0
  172. package/dist/gateways/types.d.ts.map +1 -0
  173. package/dist/gateways/types.js +6 -0
  174. package/dist/gateways/types.js.map +1 -0
  175. package/dist/index.d.ts +7 -0
  176. package/dist/index.d.ts.map +1 -0
  177. package/dist/index.js +26 -0
  178. package/dist/index.js.map +1 -0
  179. package/dist/memory/memory-logger.d.ts +47 -0
  180. package/dist/memory/memory-logger.d.ts.map +1 -0
  181. package/dist/memory/memory-logger.js +126 -0
  182. package/dist/memory/memory-logger.js.map +1 -0
  183. package/dist/onboarding/all-tools.d.ts +18 -0
  184. package/dist/onboarding/all-tools.d.ts.map +1 -0
  185. package/dist/onboarding/all-tools.js +149 -0
  186. package/dist/onboarding/all-tools.js.map +1 -0
  187. package/dist/onboarding/autonomous-discovery-tools.d.ts +13 -0
  188. package/dist/onboarding/autonomous-discovery-tools.d.ts.map +1 -0
  189. package/dist/onboarding/autonomous-discovery-tools.js +268 -0
  190. package/dist/onboarding/autonomous-discovery-tools.js.map +1 -0
  191. package/dist/onboarding/bootstrap-template.d.ts +5 -0
  192. package/dist/onboarding/bootstrap-template.d.ts.map +1 -0
  193. package/dist/onboarding/bootstrap-template.js +142 -0
  194. package/dist/onboarding/bootstrap-template.js.map +1 -0
  195. package/dist/onboarding/complete-autonomous-prompt.d.ts +13 -0
  196. package/dist/onboarding/complete-autonomous-prompt.d.ts.map +1 -0
  197. package/dist/onboarding/complete-autonomous-prompt.js +1220 -0
  198. package/dist/onboarding/complete-autonomous-prompt.js.map +1 -0
  199. package/dist/onboarding/onboarding-state.d.ts +70 -0
  200. package/dist/onboarding/onboarding-state.d.ts.map +1 -0
  201. package/dist/onboarding/onboarding-state.js +184 -0
  202. package/dist/onboarding/onboarding-state.js.map +1 -0
  203. package/dist/onboarding/personality-quiz.d.ts +35 -0
  204. package/dist/onboarding/personality-quiz.d.ts.map +1 -0
  205. package/dist/onboarding/personality-quiz.js +219 -0
  206. package/dist/onboarding/personality-quiz.js.map +1 -0
  207. package/dist/onboarding/phase-5-summary.d.ts +22 -0
  208. package/dist/onboarding/phase-5-summary.d.ts.map +1 -0
  209. package/dist/onboarding/phase-5-summary.js +151 -0
  210. package/dist/onboarding/phase-5-summary.js.map +1 -0
  211. package/dist/onboarding/phase-6-security.d.ts +33 -0
  212. package/dist/onboarding/phase-6-security.d.ts.map +1 -0
  213. package/dist/onboarding/phase-6-security.js +473 -0
  214. package/dist/onboarding/phase-6-security.js.map +1 -0
  215. package/dist/onboarding/phase-7-integrations.d.ts +66 -0
  216. package/dist/onboarding/phase-7-integrations.d.ts.map +1 -0
  217. package/dist/onboarding/phase-7-integrations.js +619 -0
  218. package/dist/onboarding/phase-7-integrations.js.map +1 -0
  219. package/dist/onboarding/phase-8-demo.d.ts +43 -0
  220. package/dist/onboarding/phase-8-demo.d.ts.map +1 -0
  221. package/dist/onboarding/phase-8-demo.js +346 -0
  222. package/dist/onboarding/phase-8-demo.js.map +1 -0
  223. package/dist/onboarding/phase-9-finalization.d.ts +22 -0
  224. package/dist/onboarding/phase-9-finalization.d.ts.map +1 -0
  225. package/dist/onboarding/phase-9-finalization.js +375 -0
  226. package/dist/onboarding/phase-9-finalization.js.map +1 -0
  227. package/dist/onboarding/ritual-prompt.d.ts +2 -0
  228. package/dist/onboarding/ritual-prompt.d.ts.map +1 -0
  229. package/dist/onboarding/ritual-prompt.js +285 -0
  230. package/dist/onboarding/ritual-prompt.js.map +1 -0
  231. package/dist/onboarding/ritual-tools.d.ts +13 -0
  232. package/dist/onboarding/ritual-tools.d.ts.map +1 -0
  233. package/dist/onboarding/ritual-tools.js +93 -0
  234. package/dist/onboarding/ritual-tools.js.map +1 -0
  235. package/dist/runners/cli-runner.d.ts +59 -0
  236. package/dist/runners/cli-runner.d.ts.map +1 -0
  237. package/dist/runners/cli-runner.js +190 -0
  238. package/dist/runners/cli-runner.js.map +1 -0
  239. package/dist/runners/index.d.ts +11 -0
  240. package/dist/runners/index.d.ts.map +1 -0
  241. package/dist/runners/index.js +15 -0
  242. package/dist/runners/index.js.map +1 -0
  243. package/dist/runners/types.d.ts +81 -0
  244. package/dist/runners/types.d.ts.map +1 -0
  245. package/dist/runners/types.js +31 -0
  246. package/dist/runners/types.js.map +1 -0
  247. package/dist/scheduler/cron-scheduler.d.ts +115 -0
  248. package/dist/scheduler/cron-scheduler.d.ts.map +1 -0
  249. package/dist/scheduler/cron-scheduler.js +320 -0
  250. package/dist/scheduler/cron-scheduler.js.map +1 -0
  251. package/dist/scheduler/heartbeat.d.ts +53 -0
  252. package/dist/scheduler/heartbeat.d.ts.map +1 -0
  253. package/dist/scheduler/heartbeat.js +160 -0
  254. package/dist/scheduler/heartbeat.js.map +1 -0
  255. package/dist/scheduler/index.d.ts +22 -0
  256. package/dist/scheduler/index.d.ts.map +1 -0
  257. package/dist/scheduler/index.js +31 -0
  258. package/dist/scheduler/index.js.map +1 -0
  259. package/dist/scheduler/job-lock.d.ts +85 -0
  260. package/dist/scheduler/job-lock.d.ts.map +1 -0
  261. package/dist/scheduler/job-lock.js +137 -0
  262. package/dist/scheduler/job-lock.js.map +1 -0
  263. package/dist/scheduler/recovery.d.ts +78 -0
  264. package/dist/scheduler/recovery.d.ts.map +1 -0
  265. package/dist/scheduler/recovery.js +124 -0
  266. package/dist/scheduler/recovery.js.map +1 -0
  267. package/dist/scheduler/schedule-store.d.ts +112 -0
  268. package/dist/scheduler/schedule-store.d.ts.map +1 -0
  269. package/dist/scheduler/schedule-store.js +259 -0
  270. package/dist/scheduler/schedule-store.js.map +1 -0
  271. package/dist/scheduler/token-keep-alive.d.ts +49 -0
  272. package/dist/scheduler/token-keep-alive.d.ts.map +1 -0
  273. package/dist/scheduler/token-keep-alive.js +102 -0
  274. package/dist/scheduler/token-keep-alive.js.map +1 -0
  275. package/dist/scheduler/types.d.ts +96 -0
  276. package/dist/scheduler/types.d.ts.map +1 -0
  277. package/dist/scheduler/types.js +21 -0
  278. package/dist/scheduler/types.js.map +1 -0
  279. package/dist/setup/setup-prompt.d.ts +2 -0
  280. package/dist/setup/setup-prompt.d.ts.map +1 -0
  281. package/dist/setup/setup-prompt.js +138 -0
  282. package/dist/setup/setup-prompt.js.map +1 -0
  283. package/dist/setup/setup-server.d.ts +8 -0
  284. package/dist/setup/setup-server.d.ts.map +1 -0
  285. package/dist/setup/setup-server.js +71 -0
  286. package/dist/setup/setup-server.js.map +1 -0
  287. package/dist/setup/setup-tools.d.ts +13 -0
  288. package/dist/setup/setup-tools.d.ts.map +1 -0
  289. package/dist/setup/setup-tools.js +103 -0
  290. package/dist/setup/setup-tools.js.map +1 -0
  291. package/dist/setup/setup-websocket.d.ts +6 -0
  292. package/dist/setup/setup-websocket.d.ts.map +1 -0
  293. package/dist/setup/setup-websocket.js +312 -0
  294. package/dist/setup/setup-websocket.js.map +1 -0
  295. package/dist/skills/index.d.ts +10 -0
  296. package/dist/skills/index.d.ts.map +1 -0
  297. package/dist/skills/index.js +26 -0
  298. package/dist/skills/index.js.map +1 -0
  299. package/dist/skills/skill-executor.d.ts +48 -0
  300. package/dist/skills/skill-executor.d.ts.map +1 -0
  301. package/dist/skills/skill-executor.js +483 -0
  302. package/dist/skills/skill-executor.js.map +1 -0
  303. package/dist/skills/skill-loader.d.ts +40 -0
  304. package/dist/skills/skill-loader.d.ts.map +1 -0
  305. package/dist/skills/skill-loader.js +225 -0
  306. package/dist/skills/skill-loader.js.map +1 -0
  307. package/dist/skills/skill-matcher.d.ts +33 -0
  308. package/dist/skills/skill-matcher.d.ts.map +1 -0
  309. package/dist/skills/skill-matcher.js +190 -0
  310. package/dist/skills/skill-matcher.js.map +1 -0
  311. package/dist/skills/types.d.ts +123 -0
  312. package/dist/skills/types.d.ts.map +1 -0
  313. package/dist/skills/types.js +12 -0
  314. package/dist/skills/types.js.map +1 -0
  315. package/dist/tools/browser-tool.d.ts +149 -0
  316. package/dist/tools/browser-tool.d.ts.map +1 -0
  317. package/dist/tools/browser-tool.js +257 -0
  318. package/dist/tools/browser-tool.js.map +1 -0
  319. package/package.json +84 -0
  320. package/public/favicon.ico +0 -0
  321. package/public/setup.html +1026 -0
  322. package/public/viewer/icons/icon-192.png +0 -0
  323. package/public/viewer/icons/icon-512.png +0 -0
  324. package/public/viewer/js/modules/chat.js +1587 -0
  325. package/public/viewer/js/modules/dashboard.js +275 -0
  326. package/public/viewer/js/modules/graph.js +997 -0
  327. package/public/viewer/js/modules/memory.js +353 -0
  328. package/public/viewer/js/modules/settings.js +255 -0
  329. package/public/viewer/js/utils/api.js +169 -0
  330. package/public/viewer/js/utils/dom.js +92 -0
  331. package/public/viewer/js/utils/format.js +192 -0
  332. package/public/viewer/manifest.json +26 -0
  333. package/public/viewer/sw.js +131 -0
  334. package/public/viewer/viewer.css +500 -0
  335. package/public/viewer/viewer.html +1535 -0
  336. package/scripts/postinstall.js +118 -0
  337. package/templates/skills/document-analyze.md +63 -0
  338. package/templates/skills/heartbeat-report.md +75 -0
  339. package/templates/skills/image-translate.md +67 -0
  340. package/templates/workspace/skill-forge/DESIGN.md +115 -0
  341. package/templates/workspace/skill-forge/agents/architect.ts +295 -0
  342. package/templates/workspace/skill-forge/agents/developer.ts +364 -0
  343. package/templates/workspace/skill-forge/agents/qa.ts +313 -0
  344. package/templates/workspace/skill-forge/claude-api.ts +353 -0
  345. package/templates/workspace/skill-forge/discord-ui.ts +580 -0
  346. package/templates/workspace/skill-forge/error-handler.ts +354 -0
  347. package/templates/workspace/skill-forge/mama-integration.ts +357 -0
  348. package/templates/workspace/skill-forge/orchestrator.ts +495 -0
  349. package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/README.md +24 -0
  350. package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/index.ts +79 -0
  351. package/templates/workspace/skill-forge/output/generated-skills/skills/hello-world/types.ts +17 -0
  352. package/templates/workspace/skill-forge/package.json +21 -0
  353. package/templates/workspace/skill-forge/state/session.json +132 -0
  354. package/templates/workspace/skill-forge/test-e2e.ts +139 -0
  355. package/templates/workspace/skill-forge/tsconfig.json +20 -0
  356. package/templates/workspace/skill-forge/types.ts +159 -0
@@ -0,0 +1,169 @@
1
+ /**
2
+ * API Utility Functions
3
+ * @module utils/api
4
+ * @version 1.0.0
5
+ */
6
+
7
+ /* eslint-env browser */
8
+
9
+ /**
10
+ * API client for MAMA viewer
11
+ */
12
+ export class API {
13
+ /**
14
+ * Base URL for API requests (empty for same origin)
15
+ */
16
+ static baseUrl = '';
17
+
18
+ /**
19
+ * Perform GET request
20
+ * @param {string} endpoint - API endpoint
21
+ * @param {Object} params - Query parameters
22
+ * @returns {Promise<Object>} Response data
23
+ */
24
+ static async get(endpoint, params = null) {
25
+ const url = new URL(endpoint, window.location.origin);
26
+ if (params) {
27
+ Object.entries(params).forEach(([key, value]) => {
28
+ if (value !== null && value !== undefined) {
29
+ url.searchParams.set(key, value);
30
+ }
31
+ });
32
+ }
33
+
34
+ const response = await fetch(url);
35
+ if (!response.ok) {
36
+ const error = await response.json().catch(() => ({}));
37
+ throw new Error(error.message || `HTTP ${response.status}`);
38
+ }
39
+
40
+ return response.json();
41
+ }
42
+
43
+ /**
44
+ * Perform POST request
45
+ * @param {string} endpoint - API endpoint
46
+ * @param {Object} body - Request body
47
+ * @returns {Promise<Object>} Response data
48
+ */
49
+ static async post(endpoint, body) {
50
+ const response = await fetch(endpoint, {
51
+ method: 'POST',
52
+ headers: { 'Content-Type': 'application/json' },
53
+ body: JSON.stringify(body),
54
+ });
55
+
56
+ if (!response.ok) {
57
+ const error = await response.json().catch(() => ({}));
58
+ throw new Error(error.message || `HTTP ${response.status}`);
59
+ }
60
+
61
+ return response.json();
62
+ }
63
+
64
+ // =============================================
65
+ // Graph API
66
+ // =============================================
67
+
68
+ /**
69
+ * Get graph data
70
+ * @param {Object} params - Query parameters
71
+ * @returns {Promise<Object>} Graph data
72
+ */
73
+ static async getGraph(params = {}) {
74
+ // cluster: false by default to avoid slow embedding calculations
75
+ return this.get('/graph', { cluster: 'false', ...params });
76
+ }
77
+
78
+ /**
79
+ * Get similar decisions for a node
80
+ * @param {string} nodeId - Node ID
81
+ * @returns {Promise<Object>} Similar decisions
82
+ */
83
+ static async getSimilarDecisions(nodeId) {
84
+ return this.get('/graph/similar', { id: nodeId });
85
+ }
86
+
87
+ /**
88
+ * Update decision outcome
89
+ * @param {string} id - Decision ID
90
+ * @param {string} outcome - Outcome value
91
+ * @param {string} reason - Optional reason
92
+ * @returns {Promise<Object>} Update result
93
+ */
94
+ static async updateOutcome(id, outcome, reason = null) {
95
+ return this.post('/graph/update', { id, outcome, reason });
96
+ }
97
+
98
+ // =============================================
99
+ // Checkpoint API
100
+ // =============================================
101
+
102
+ /**
103
+ * Get all checkpoints
104
+ * @returns {Promise<Object>} Checkpoints data
105
+ */
106
+ static async getCheckpoints() {
107
+ return this.get('/checkpoints');
108
+ }
109
+
110
+ // =============================================
111
+ // MAMA Memory API
112
+ // =============================================
113
+
114
+ /**
115
+ * Search MAMA decisions
116
+ * @param {string} query - Search query
117
+ * @param {number} limit - Maximum results
118
+ * @returns {Promise<Object>} Search results
119
+ */
120
+ static async searchMemory(query, limit = 10) {
121
+ return this.get('/api/mama/search', { q: query, limit });
122
+ }
123
+
124
+ /**
125
+ * Save a new decision to MAMA
126
+ * @param {Object} data - Decision data
127
+ * @param {string} data.topic - Decision topic
128
+ * @param {string} data.decision - Decision text
129
+ * @param {string} data.reasoning - Reasoning text
130
+ * @param {number} data.confidence - Confidence (0-1)
131
+ * @returns {Promise<Object>} Save result
132
+ */
133
+ static async saveDecision(data) {
134
+ return this.post('/api/mama/save', data);
135
+ }
136
+
137
+ // =============================================
138
+ // Session API
139
+ // =============================================
140
+
141
+ /**
142
+ * Create a new chat session
143
+ * @param {string} projectDir - Project directory
144
+ * @returns {Promise<Object>} Session data
145
+ */
146
+ static async createSession(projectDir = '.') {
147
+ return this.post('/api/sessions', { projectDir });
148
+ }
149
+
150
+ /**
151
+ * Get the last active session
152
+ * @returns {Promise<Object|null>} Last active session or null
153
+ */
154
+ static async getLastActiveSession() {
155
+ try {
156
+ return await this.get('/api/sessions/last-active');
157
+ } catch {
158
+ return null;
159
+ }
160
+ }
161
+
162
+ /**
163
+ * Get all active sessions
164
+ * @returns {Promise<Object>} Sessions list
165
+ */
166
+ static async getSessions() {
167
+ return this.get('/api/sessions');
168
+ }
169
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * DOM Utility Functions
3
+ * @module utils/dom
4
+ * @version 1.0.0
5
+ */
6
+
7
+ /* eslint-env browser */
8
+
9
+ /**
10
+ * Escape HTML to prevent XSS
11
+ * @param {string} text - Text to escape
12
+ * @returns {string} Escaped HTML
13
+ */
14
+ export function escapeHtml(text) {
15
+ if (!text) {
16
+ return '';
17
+ }
18
+ const div = document.createElement('div');
19
+ div.textContent = text;
20
+ return div.innerHTML;
21
+ }
22
+
23
+ /**
24
+ * Debounce function calls
25
+ * @param {Function} func - Function to debounce
26
+ * @param {number} wait - Wait time in milliseconds
27
+ * @returns {Function} Debounced function
28
+ */
29
+ export function debounce(func, wait) {
30
+ let timeout;
31
+ return function executedFunction(...args) {
32
+ const later = () => {
33
+ clearTimeout(timeout);
34
+ func(...args);
35
+ };
36
+ clearTimeout(timeout);
37
+ timeout = setTimeout(later, wait);
38
+ };
39
+ }
40
+
41
+ /**
42
+ * Show toast notification
43
+ * @param {string} message - Message to display
44
+ * @param {number} duration - Duration in milliseconds
45
+ */
46
+ export function showToast(message, duration = 3000) {
47
+ // Remove existing toast
48
+ const existingToast = document.querySelector('.toast-notification');
49
+ if (existingToast) {
50
+ existingToast.remove();
51
+ }
52
+
53
+ const toast = document.createElement('div');
54
+ toast.className = 'toast-notification';
55
+ toast.textContent = message;
56
+ document.body.appendChild(toast);
57
+
58
+ // Trigger animation
59
+ requestAnimationFrame(() => {
60
+ toast.classList.add('visible');
61
+ });
62
+
63
+ // Auto-remove
64
+ setTimeout(() => {
65
+ toast.classList.remove('visible');
66
+ setTimeout(() => toast.remove(), 300);
67
+ }, duration);
68
+ }
69
+
70
+ /**
71
+ * Scroll element to bottom
72
+ * @param {HTMLElement} container - Container to scroll
73
+ */
74
+ export function scrollToBottom(container) {
75
+ // Use setTimeout to ensure DOM has updated before scrolling
76
+ setTimeout(() => {
77
+ container.scrollTop = container.scrollHeight;
78
+ }, 50);
79
+ }
80
+
81
+ /**
82
+ * Auto-resize textarea to fit content
83
+ * @param {HTMLTextAreaElement} textarea - Textarea element
84
+ * @param {number} maxRows - Maximum number of rows (default: 5)
85
+ */
86
+ export function autoResizeTextarea(textarea, maxRows = 5) {
87
+ textarea.style.height = 'auto';
88
+ const lineHeight = parseInt(getComputedStyle(textarea).lineHeight);
89
+ const maxHeight = lineHeight * maxRows;
90
+ const newHeight = Math.min(textarea.scrollHeight, maxHeight);
91
+ textarea.style.height = newHeight + 'px';
92
+ }
@@ -0,0 +1,192 @@
1
+ /**
2
+ * Formatting Utility Functions
3
+ * @module utils/format
4
+ * @version 1.0.0
5
+ */
6
+
7
+ /* eslint-env browser */
8
+
9
+ /**
10
+ * Format message timestamp
11
+ * @param {Date} date - Date object
12
+ * @returns {string} Formatted time (HH:MM)
13
+ */
14
+ export function formatMessageTime(date) {
15
+ return date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
16
+ }
17
+
18
+ /**
19
+ * Format checkpoint timestamp
20
+ * @param {string|Date} timestamp - Timestamp
21
+ * @returns {string} Formatted relative time
22
+ */
23
+ export function formatCheckpointTime(timestamp) {
24
+ const date = new Date(timestamp);
25
+ const now = new Date();
26
+ const diff = now - date;
27
+
28
+ if (diff < 3600000) {
29
+ const mins = Math.floor(diff / 60000);
30
+ return `${mins}m ago`;
31
+ }
32
+ if (diff < 86400000) {
33
+ const hours = Math.floor(diff / 3600000);
34
+ return `${hours}h ago`;
35
+ }
36
+
37
+ return (
38
+ date.toLocaleDateString() +
39
+ ' ' +
40
+ date.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
41
+ );
42
+ }
43
+
44
+ /**
45
+ * Format relative time
46
+ * @param {string|Date} timestamp - Timestamp
47
+ * @returns {string} Relative time string
48
+ */
49
+ export function formatRelativeTime(timestamp) {
50
+ if (!timestamp) {
51
+ return '';
52
+ }
53
+
54
+ const date = new Date(timestamp);
55
+ const now = new Date();
56
+ const diff = now - date;
57
+
58
+ if (diff < 60000) {
59
+ return 'Just now';
60
+ }
61
+ if (diff < 3600000) {
62
+ const mins = Math.floor(diff / 60000);
63
+ return `${mins}m ago`;
64
+ }
65
+ if (diff < 86400000) {
66
+ const hours = Math.floor(diff / 3600000);
67
+ return `${hours}h ago`;
68
+ }
69
+ if (diff < 604800000) {
70
+ const days = Math.floor(diff / 86400000);
71
+ return `${days}d ago`;
72
+ }
73
+
74
+ return date.toLocaleDateString();
75
+ }
76
+
77
+ /**
78
+ * Truncate text with ellipsis
79
+ * @param {string} text - Text to truncate
80
+ * @param {number} maxLength - Maximum length
81
+ * @returns {string} Truncated text
82
+ */
83
+ export function truncateText(text, maxLength) {
84
+ if (!text) {
85
+ return '';
86
+ }
87
+ if (text.length <= maxLength) {
88
+ return text;
89
+ }
90
+ return text.substring(0, maxLength) + '...';
91
+ }
92
+
93
+ /**
94
+ * Extract first meaningful line from text
95
+ * @param {string} text - Text to extract from
96
+ * @returns {string} First meaningful line
97
+ */
98
+ export function extractFirstLine(text) {
99
+ if (!text) {
100
+ return 'No summary';
101
+ }
102
+ const lines = text.split('\n').filter((l) => l.trim() && !l.startsWith('**'));
103
+ return lines[0] || text.substring(0, 100);
104
+ }
105
+
106
+ /**
107
+ * Format assistant message with markdown support
108
+ * @param {string} text - Text to format
109
+ * @returns {string} Formatted HTML
110
+ */
111
+ export function formatAssistantMessage(text) {
112
+ if (!text) {
113
+ return '';
114
+ }
115
+
116
+ // First escape HTML to prevent XSS
117
+ let formatted = escapeHtmlForMarkdown(text);
118
+
119
+ // Code blocks with optional language (```js ... ```)
120
+ formatted = formatted.replace(/```(\w*)\n?([\s\S]*?)```/g, (match, lang, code) => {
121
+ const langClass = lang ? ` class="language-${lang}"` : '';
122
+ return `<pre class="code-block"><code${langClass}>${code.trim()}</code></pre>`;
123
+ });
124
+
125
+ // Inline code
126
+ formatted = formatted.replace(/`([^`]+)`/g, '<code>$1</code>');
127
+
128
+ // Bold
129
+ formatted = formatted.replace(/\*\*([^*]+)\*\*/g, '<strong>$1</strong>');
130
+
131
+ // Italic (avoiding conflicts with bold)
132
+ formatted = formatted.replace(/(?<!\*)\*([^*]+)\*(?!\*)/g, '<em>$1</em>');
133
+
134
+ // Links: [text](url)
135
+ formatted = formatted.replace(
136
+ /\[([^\]]+)\]\(([^)]+)\)/g,
137
+ '<a href="$2" target="_blank" rel="noopener noreferrer">$1</a>'
138
+ );
139
+
140
+ // Auto-detect URLs (not already in anchor tags)
141
+ formatted = formatted.replace(
142
+ /(?<!href="|>)(https?:\/\/[^\s<]+)/g,
143
+ '<a href="$1" target="_blank" rel="noopener noreferrer">$1</a>'
144
+ );
145
+
146
+ // Headers (## and ###)
147
+ formatted = formatted.replace(
148
+ /^### (.+)$/gm,
149
+ '<h4 class="text-sm font-semibold mt-2 mb-1">$1</h4>'
150
+ );
151
+ formatted = formatted.replace(
152
+ /^## (.+)$/gm,
153
+ '<h3 class="text-base font-semibold mt-3 mb-1">$1</h3>'
154
+ );
155
+
156
+ // Bullet lists (- item)
157
+ formatted = formatted.replace(/^- (.+)$/gm, '<li class="ml-4">• $1</li>');
158
+
159
+ // Quiz choices as buttons - patterns like **A)** text or A) text
160
+ // Also handles blockquote prefix (> or &gt;)
161
+ // Match patterns: A) text, **A)** text, > A) text, etc.
162
+ formatted = formatted.replace(
163
+ /^(?:&gt;\s*)?(?:<strong>)?([A-D])\)(?:<\/strong>)?\s*(.+)$/gim,
164
+ (match, letter, text) => {
165
+ const upperLetter = letter.toUpperCase();
166
+ return `<button class="quiz-choice-btn" data-choice="${upperLetter}" onclick="window.sendQuizChoice('${upperLetter}')">${upperLetter}) ${text.trim()}</button>`;
167
+ }
168
+ );
169
+
170
+ // Line breaks
171
+ formatted = formatted.replace(/\n/g, '<br>');
172
+
173
+ // Clean up multiple <br> in lists
174
+ formatted = formatted.replace(/<\/li><br><li/g, '</li><li');
175
+
176
+ // Clean up <br> before/after quiz buttons
177
+ formatted = formatted.replace(/<br>(<button class="quiz-choice-btn")/g, '$1');
178
+ formatted = formatted.replace(/(<\/button>)<br>/g, '$1');
179
+
180
+ return formatted;
181
+ }
182
+
183
+ /**
184
+ * Escape HTML for markdown processing
185
+ * @param {string} text - Text to escape
186
+ * @returns {string} Escaped text
187
+ */
188
+ function escapeHtmlForMarkdown(text) {
189
+ const div = document.createElement('div');
190
+ div.textContent = text;
191
+ return div.innerHTML;
192
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "MAMA Mobile",
3
+ "short_name": "MAMA",
4
+ "description": "Mobile interface for MAMA - Memory-Augmented MCP Assistant",
5
+ "start_url": "/viewer",
6
+ "display": "standalone",
7
+ "background_color": "#1a1a2e",
8
+ "theme_color": "#1a1a2e",
9
+ "orientation": "portrait-primary",
10
+ "icons": [
11
+ {
12
+ "src": "/viewer/icon-192.png",
13
+ "sizes": "192x192",
14
+ "type": "image/png",
15
+ "purpose": "any maskable"
16
+ },
17
+ {
18
+ "src": "/viewer/icon-512.png",
19
+ "sizes": "512x512",
20
+ "type": "image/png",
21
+ "purpose": "any maskable"
22
+ }
23
+ ],
24
+ "categories": ["productivity", "developer tools"],
25
+ "lang": "ko"
26
+ }
@@ -0,0 +1,131 @@
1
+ /**
2
+ * @fileoverview Service Worker for MAMA Mobile PWA
3
+ * @version 1.5.0
4
+ *
5
+ * Provides offline caching for static assets using cache-first strategy.
6
+ */
7
+
8
+ /* eslint-env serviceworker */
9
+
10
+ const CACHE_NAME = 'mama-mobile-v1.5.1';
11
+ const STATIC_ASSETS = [
12
+ '/viewer',
13
+ '/viewer/viewer.css',
14
+ '/viewer/viewer.js',
15
+ '/viewer/manifest.json',
16
+ '/viewer/js/modules/graph.js',
17
+ '/viewer/js/modules/chat.js',
18
+ '/viewer/js/modules/memory.js',
19
+ '/viewer/js/utils/dom.js',
20
+ '/viewer/js/utils/format.js',
21
+ '/viewer/js/utils/api.js',
22
+ '/viewer/icons/icon-192.png',
23
+ '/viewer/icons/icon-512.png',
24
+ ];
25
+
26
+ /**
27
+ * Install event - cache static assets
28
+ */
29
+ self.addEventListener('install', (event) => {
30
+ event.waitUntil(
31
+ caches.open(CACHE_NAME).then((cache) => {
32
+ console.log('[SW] Caching static assets (graceful)');
33
+ // Graceful caching - 실패해도 계속 진행
34
+ return Promise.allSettled(
35
+ STATIC_ASSETS.map((url) =>
36
+ fetch(url)
37
+ .then((res) => {
38
+ if (res.ok) {
39
+ return cache.put(url, res);
40
+ }
41
+ console.warn('[SW] Failed to cache:', url, res.status);
42
+ return null;
43
+ })
44
+ .catch((err) => {
45
+ console.warn('[SW] Cache fetch error:', url, err.message);
46
+ return null;
47
+ })
48
+ )
49
+ );
50
+ })
51
+ );
52
+ // Activate immediately
53
+ self.skipWaiting();
54
+ });
55
+
56
+ /**
57
+ * Activate event - clean up old caches
58
+ */
59
+ self.addEventListener('activate', (event) => {
60
+ event.waitUntil(
61
+ caches.keys().then((cacheNames) => {
62
+ return Promise.all(
63
+ cacheNames
64
+ .filter((name) => name !== CACHE_NAME)
65
+ .map((name) => {
66
+ console.log('[SW] Deleting old cache:', name);
67
+ return caches.delete(name);
68
+ })
69
+ );
70
+ })
71
+ );
72
+ // Take control of all pages immediately
73
+ self.clients.claim();
74
+ });
75
+
76
+ /**
77
+ * Fetch event - cache-first strategy for static assets
78
+ */
79
+ self.addEventListener('fetch', (event) => {
80
+ const { request } = event;
81
+ const url = new URL(request.url);
82
+
83
+ // Only handle GET requests
84
+ if (request.method !== 'GET') {
85
+ return;
86
+ }
87
+
88
+ // Skip WebSocket and API requests
89
+ if (url.pathname.startsWith('/ws') || url.pathname.startsWith('/api/')) {
90
+ return;
91
+ }
92
+
93
+ // Cache-first for static assets
94
+ if (STATIC_ASSETS.some((asset) => url.pathname.startsWith(asset.split('?')[0]))) {
95
+ event.respondWith(
96
+ caches.match(request).then((cachedResponse) => {
97
+ if (cachedResponse) {
98
+ return cachedResponse;
99
+ }
100
+ return fetch(request).then((response) => {
101
+ // Cache successful responses
102
+ if (response.ok) {
103
+ const responseClone = response.clone();
104
+ caches.open(CACHE_NAME).then((cache) => {
105
+ cache.put(request, responseClone);
106
+ });
107
+ }
108
+ return response;
109
+ });
110
+ })
111
+ );
112
+ return;
113
+ }
114
+
115
+ // Network-first for everything else
116
+ event.respondWith(
117
+ fetch(request).catch(() => {
118
+ // Return offline fallback if available
119
+ return caches.match('/viewer');
120
+ })
121
+ );
122
+ });
123
+
124
+ /**
125
+ * Message event - handle skip waiting message
126
+ */
127
+ self.addEventListener('message', (event) => {
128
+ if (event.data === 'skipWaiting') {
129
+ self.skipWaiting();
130
+ }
131
+ });