@mazees/mark 5.0.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 (227) hide show
  1. package/LICENSE +29 -0
  2. package/README.md +209 -0
  3. package/bin/mark.js +27 -0
  4. package/out/renderer/assets/icon-DHo2CYph.svg +1 -0
  5. package/out/renderer/assets/index-G2fADWO-.js +4768 -0
  6. package/out/renderer/assets/index-f3mVse3c.css +1 -0
  7. package/out/renderer/assets/music-cover-CG4vi3kZ.png +0 -0
  8. package/out/renderer/assets/poppins-devanagari-400-normal-CJDn6rn8.woff2 +0 -0
  9. package/out/renderer/assets/poppins-devanagari-400-normal-CqVvlrh5.woff +0 -0
  10. package/out/renderer/assets/poppins-devanagari-500-normal-BIdkeU1p.woff2 +0 -0
  11. package/out/renderer/assets/poppins-devanagari-500-normal-DMPDjHtT.woff +0 -0
  12. package/out/renderer/assets/poppins-devanagari-600-normal-ClASKHrr.woff +0 -0
  13. package/out/renderer/assets/poppins-devanagari-600-normal-STEjXBNN.woff2 +0 -0
  14. package/out/renderer/assets/poppins-devanagari-700-normal-O-jipLrW.woff2 +0 -0
  15. package/out/renderer/assets/poppins-devanagari-700-normal-fHs-vx92.woff +0 -0
  16. package/out/renderer/assets/poppins-latin-400-normal-BOb3E3N0.woff +0 -0
  17. package/out/renderer/assets/poppins-latin-400-normal-cpxAROuN.woff2 +0 -0
  18. package/out/renderer/assets/poppins-latin-500-normal-C8OXljZJ.woff2 +0 -0
  19. package/out/renderer/assets/poppins-latin-500-normal-DGXqpDMm.woff +0 -0
  20. package/out/renderer/assets/poppins-latin-600-normal-BJdTmd5m.woff +0 -0
  21. package/out/renderer/assets/poppins-latin-600-normal-zEkxB9Mr.woff2 +0 -0
  22. package/out/renderer/assets/poppins-latin-700-normal-BVuQR_eA.woff +0 -0
  23. package/out/renderer/assets/poppins-latin-700-normal-Qrb0O0WB.woff2 +0 -0
  24. package/out/renderer/assets/poppins-latin-ext-400-normal-DaBSavcJ.woff +0 -0
  25. package/out/renderer/assets/poppins-latin-ext-400-normal-by3JarPu.woff2 +0 -0
  26. package/out/renderer/assets/poppins-latin-ext-500-normal-CK-6C4Hw.woff2 +0 -0
  27. package/out/renderer/assets/poppins-latin-ext-500-normal-CgAe2rWW.woff +0 -0
  28. package/out/renderer/assets/poppins-latin-ext-600-normal-CAhIAdZj.woff2 +0 -0
  29. package/out/renderer/assets/poppins-latin-ext-600-normal-Df5ffKXP.woff +0 -0
  30. package/out/renderer/assets/poppins-latin-ext-700-normal-DctTR6Tg.woff +0 -0
  31. package/out/renderer/assets/poppins-latin-ext-700-normal-cby-RkWa.woff2 +0 -0
  32. package/out/renderer/favicon.ico +0 -0
  33. package/out/renderer/icon-256.png +0 -0
  34. package/out/renderer/icon.svg +1 -0
  35. package/out/renderer/index.html +25 -0
  36. package/out/renderer/manifest.json +25 -0
  37. package/out/renderer/robot-simulator.html +1640 -0
  38. package/package.json +106 -0
  39. package/src/cli/index.js +332 -0
  40. package/src/cli/monitor.js +413 -0
  41. package/src/cli/theme.js +347 -0
  42. package/src/launcher/MarkTray.cs +227 -0
  43. package/src/main/browser-agent.js +1132 -0
  44. package/src/main/git-service.js +90 -0
  45. package/src/main/google/google-calendar.js +69 -0
  46. package/src/main/google/google-drive.js +263 -0
  47. package/src/main/google/google-gmail.js +131 -0
  48. package/src/main/google/google-service.js +241 -0
  49. package/src/main/node-tools.js +23 -0
  50. package/src/main/pc-agent-scripts/mouse-locker.ps1 +76 -0
  51. package/src/main/pc-agent-scripts/ocr-region.ps1 +185 -0
  52. package/src/main/pc-agent-scripts/pc-daemon.ps1 +726 -0
  53. package/src/main/pc-agent-scripts/pc-overlay.ps1 +253 -0
  54. package/src/main/pc-agent-scripts/pick-folder.ps1 +33 -0
  55. package/src/main/pc-agent-scripts/read-ui.ps1 +181 -0
  56. package/src/main/pc-agent-scripts/take-screenshot.ps1 +24 -0
  57. package/src/main/pc-agent-scripts/win-action.ps1 +380 -0
  58. package/src/main/plugins/plugin-loader.js +306 -0
  59. package/src/main/skills/skill-manager.js +265 -0
  60. package/src/main/syntax-validator.js +455 -0
  61. package/src/main/task-daemon.js +117 -0
  62. package/src/main/telegram/telegram-service.js +835 -0
  63. package/src/main/tools/browser-tools.js +516 -0
  64. package/src/main/tools/file-tools.js +1126 -0
  65. package/src/main/tools/git-tools.js +79 -0
  66. package/src/main/tools/google-tools.js +566 -0
  67. package/src/main/tools/index.js +36 -0
  68. package/src/main/tools/media-tools.js +42 -0
  69. package/src/main/tools/system-tools.js +295 -0
  70. package/src/main/tools/task-tools.js +73 -0
  71. package/src/main/tools/telegram-tools.js +101 -0
  72. package/src/renderer/index.html +24 -0
  73. package/src/renderer/public/favicon.ico +0 -0
  74. package/src/renderer/public/icon-256.png +0 -0
  75. package/src/renderer/public/icon.svg +1 -0
  76. package/src/renderer/public/manifest.json +25 -0
  77. package/src/renderer/public/robot-simulator.html +1640 -0
  78. package/src/renderer/src/App.jsx +304 -0
  79. package/src/renderer/src/api/ai/awareness.js +294 -0
  80. package/src/renderer/src/api/ai/chatSummarizer.js +79 -0
  81. package/src/renderer/src/api/ai/contextCompactor.js +129 -0
  82. package/src/renderer/src/api/ai/contextManager.js +1130 -0
  83. package/src/renderer/src/api/ai/core.js +167 -0
  84. package/src/renderer/src/api/ai/index.js +4 -0
  85. package/src/renderer/src/api/ai/memoryGroomer.js +101 -0
  86. package/src/renderer/src/api/ai/persona.js +115 -0
  87. package/src/renderer/src/api/ai/planning.js +317 -0
  88. package/src/renderer/src/api/ai/relationship.js +177 -0
  89. package/src/renderer/src/api/ai/skillSynthesizer.js +168 -0
  90. package/src/renderer/src/api/ai/tools.js +167 -0
  91. package/src/renderer/src/api/ai/utils.js +359 -0
  92. package/src/renderer/src/api/db.js +1013 -0
  93. package/src/renderer/src/api/oramaStore.js +592 -0
  94. package/src/renderer/src/api/ragPipeline.js +87 -0
  95. package/src/renderer/src/api/subagent/subagentExecutor.js +780 -0
  96. package/src/renderer/src/api/subagent/subagentPrompt.js +44 -0
  97. package/src/renderer/src/api/subagent/subagentStore.js +173 -0
  98. package/src/renderer/src/api/taskExecutor.js +18 -0
  99. package/src/renderer/src/api/taskStore.js +315 -0
  100. package/src/renderer/src/api/tools/core-tools.js +707 -0
  101. package/src/renderer/src/api/tools/index.js +151 -0
  102. package/src/renderer/src/api/turnPairMigrator.js +200 -0
  103. package/src/renderer/src/api/vectorMemory.js +136 -0
  104. package/src/renderer/src/api/wakeWord.js +101 -0
  105. package/src/renderer/src/api/web-bridge.js +885 -0
  106. package/src/renderer/src/api/webSpeech.js +178 -0
  107. package/src/renderer/src/api/workspaceRag.js +76 -0
  108. package/src/renderer/src/assets/electron.svg +10 -0
  109. package/src/renderer/src/assets/icon.svg +1 -0
  110. package/src/renderer/src/assets/main.css +589 -0
  111. package/src/renderer/src/assets/music-cover.png +0 -0
  112. package/src/renderer/src/assets/wavy-lines.svg +25 -0
  113. package/src/renderer/src/components/Chat/ApprovalBubble.jsx +127 -0
  114. package/src/renderer/src/components/Chat/CodeBlock.jsx +83 -0
  115. package/src/renderer/src/components/Chat/DurableTaskBubble.jsx +455 -0
  116. package/src/renderer/src/components/Chat/FileDiffModal.jsx +328 -0
  117. package/src/renderer/src/components/Chat/GeminiWidgets.jsx +82 -0
  118. package/src/renderer/src/components/Chat/MemoryFooterBubble.jsx +34 -0
  119. package/src/renderer/src/components/Chat/MessageBubble.jsx +459 -0
  120. package/src/renderer/src/components/Chat/PluginExecutionBubble.jsx +41 -0
  121. package/src/renderer/src/components/Chat/ThinkingBubble.jsx +316 -0
  122. package/src/renderer/src/components/Chat/YoutubeSearchBubble.jsx +43 -0
  123. package/src/renderer/src/components/Chat/YoutubeSummaryBubble.jsx +40 -0
  124. package/src/renderer/src/components/Chat/index.js +11 -0
  125. package/src/renderer/src/components/ChatList.jsx +434 -0
  126. package/src/renderer/src/components/GlobalCameraManager.jsx +67 -0
  127. package/src/renderer/src/components/Versions.jsx +15 -0
  128. package/src/renderer/src/components/YoutubeMusicPlayer.jsx +375 -0
  129. package/src/renderer/src/components/camera/CameraPreview.jsx +236 -0
  130. package/src/renderer/src/components/config/AiEngineSection.jsx +363 -0
  131. package/src/renderer/src/components/config/CameraSection.jsx +100 -0
  132. package/src/renderer/src/components/config/PermissionsSection.jsx +130 -0
  133. package/src/renderer/src/components/config/ShortcutSection.jsx +102 -0
  134. package/src/renderer/src/components/config/VoiceSection.jsx +110 -0
  135. package/src/renderer/src/components/config/index.js +5 -0
  136. package/src/renderer/src/components/core/Avatar.jsx +2197 -0
  137. package/src/renderer/src/components/core/ConfirmModal.jsx +80 -0
  138. package/src/renderer/src/components/core/DraggableHoloCard.jsx +125 -0
  139. package/src/renderer/src/components/core/FloatingMenu.jsx +272 -0
  140. package/src/renderer/src/components/core/HoloCard.jsx +64 -0
  141. package/src/renderer/src/components/core/InputBar.jsx +1346 -0
  142. package/src/renderer/src/components/core/ProcessPanel.jsx +216 -0
  143. package/src/renderer/src/components/core/ResponseArea.jsx +149 -0
  144. package/src/renderer/src/components/core/StatusIndicator.jsx +59 -0
  145. package/src/renderer/src/components/core/ThoughtNeuralFlow.jsx +168 -0
  146. package/src/renderer/src/components/core/ToolClustersDeck.jsx +210 -0
  147. package/src/renderer/src/components/core/native-skills.js +43 -0
  148. package/src/renderer/src/components/neural-core/EmotionalCortexLobe.jsx +359 -0
  149. package/src/renderer/src/components/neural-core/NodeDissectionModal.jsx +57 -0
  150. package/src/renderer/src/components/neural-core/ProceduralMatrixLobe.jsx +193 -0
  151. package/src/renderer/src/components/neural-core/ProceduralSkillModal.jsx +53 -0
  152. package/src/renderer/src/components/neural-core/ResetAiModal.jsx +198 -0
  153. package/src/renderer/src/components/neural-core/SynapticMemoryLobe.jsx +204 -0
  154. package/src/renderer/src/components/neural-core/traitMeta.js +102 -0
  155. package/src/renderer/src/components/subagent/AgentChatFeed.jsx +603 -0
  156. package/src/renderer/src/components/subagent/AgentInspector.jsx +224 -0
  157. package/src/renderer/src/components/subagent/AgentSidebar.jsx +216 -0
  158. package/src/renderer/src/components/subagent/SubagentIntercom.jsx +572 -0
  159. package/src/renderer/src/components/subagent/SubagentTopologyMap.jsx +423 -0
  160. package/src/renderer/src/contexts/ApprovalContext.jsx +425 -0
  161. package/src/renderer/src/contexts/ChatContext.jsx +61 -0
  162. package/src/renderer/src/contexts/YoutubeMusicContext.jsx +333 -0
  163. package/src/renderer/src/data/faqData.js +202 -0
  164. package/src/renderer/src/hooks/agent/executeAgentTool.js +895 -0
  165. package/src/renderer/src/hooks/agent/index.js +4 -0
  166. package/src/renderer/src/hooks/agent/useMarkMusic.js +75 -0
  167. package/src/renderer/src/hooks/agent/useMarkPlan.js +2739 -0
  168. package/src/renderer/src/hooks/agent/useMarkState.js +173 -0
  169. package/src/renderer/src/hooks/agent/useMarkYoutube.js +82 -0
  170. package/src/renderer/src/hooks/agent/useRelationalGrowth.js +201 -0
  171. package/src/renderer/src/hooks/telegram/useTelegramBot.js +63 -0
  172. package/src/renderer/src/hooks/useAwareness.js +289 -0
  173. package/src/renderer/src/hooks/useChatArchiver.js +52 -0
  174. package/src/renderer/src/hooks/useConfirm.jsx +68 -0
  175. package/src/renderer/src/hooks/useMarkAgent.js +454 -0
  176. package/src/renderer/src/hooks/useMemoryGroomer.js +152 -0
  177. package/src/renderer/src/hooks/useVAD.js +511 -0
  178. package/src/renderer/src/hooks/useWebSpeechWakeWord.js +122 -0
  179. package/src/renderer/src/main.jsx +12 -0
  180. package/src/renderer/src/pages/ChatStudio.jsx +922 -0
  181. package/src/renderer/src/pages/Configuration.jsx +360 -0
  182. package/src/renderer/src/pages/GoogleWorkspace.jsx +293 -0
  183. package/src/renderer/src/pages/Guidebook.jsx +917 -0
  184. package/src/renderer/src/pages/Knowledge.jsx +241 -0
  185. package/src/renderer/src/pages/MarkHome.jsx +491 -0
  186. package/src/renderer/src/pages/NeuralCore.jsx +786 -0
  187. package/src/renderer/src/pages/Plugins.jsx +630 -0
  188. package/src/renderer/src/pages/SkillEditor.jsx +380 -0
  189. package/src/renderer/src/pages/Skills.jsx +219 -0
  190. package/src/renderer/src/pages/Subagents.jsx +342 -0
  191. package/src/renderer/src/pages/TelegramBot.jsx +343 -0
  192. package/src/renderer/src/utils/chatContentParser.js +203 -0
  193. package/src/renderer/src/utils/toolClusters.js +201 -0
  194. package/src/server/bin/sha3_wasm_bg.wasm +0 -0
  195. package/src/server/config-manager.js +57 -0
  196. package/src/server/index.js +195 -0
  197. package/src/server/launcher.js +87 -0
  198. package/src/server/memory/db-store.js +758 -0
  199. package/src/server/memory/orama-store.js +177 -0
  200. package/src/server/memory/vector-engine.js +109 -0
  201. package/src/server/routes/ai.routes.js +280 -0
  202. package/src/server/routes/awareness.routes.js +62 -0
  203. package/src/server/routes/chat.routes.js +61 -0
  204. package/src/server/routes/config.routes.js +41 -0
  205. package/src/server/routes/index.js +35 -0
  206. package/src/server/routes/integrations.routes.js +116 -0
  207. package/src/server/routes/memory.routes.js +256 -0
  208. package/src/server/routes/plugins.routes.js +72 -0
  209. package/src/server/routes/skills.routes.js +139 -0
  210. package/src/server/routes/subagents.routes.js +70 -0
  211. package/src/server/routes/tasks.routes.js +175 -0
  212. package/src/server/routes/workspace.routes.js +127 -0
  213. package/src/server/services/ai/ai-utils.js +161 -0
  214. package/src/server/services/ai/openai-provider.js +757 -0
  215. package/src/server/services/ai/web-provider.js +729 -0
  216. package/src/server/services/ai-bridge.js +46 -0
  217. package/src/server/services/deepseek-web.js +956 -0
  218. package/src/server/services/gemini-web.js +170 -0
  219. package/src/server/services/notification-service.js +91 -0
  220. package/src/server/services/updater.js +125 -0
  221. package/src/server/tools/awareness-tracker.js +292 -0
  222. package/src/server/tools/group-tools.js +1164 -0
  223. package/src/server/tools/media-tools.js +244 -0
  224. package/src/server/tools/pc-agent.js +327 -0
  225. package/src/server/tools/screen-service.js +51 -0
  226. package/src/server/ws-hub.js +168 -0
  227. package/src/shared/parsers/mark-tag-parser.js +275 -0
@@ -0,0 +1,79 @@
1
+ import path from 'path'
2
+ import os from 'os'
3
+ import { getGitStatus, getGitDiff, gitCommit, gitRevert } from '../git-service.js'
4
+
5
+ function resolveGitRoot(customPath, config) {
6
+ const raw = String(customPath || '').trim()
7
+ const baseRoot = config?.workspaceRoot || path.join(os.homedir(), 'Documents', 'Mark Workspace')
8
+ if (!raw) return baseRoot
9
+ return path.isAbsolute(raw) ? raw : path.resolve(baseRoot, raw)
10
+ }
11
+
12
+ export const gitTools = {
13
+ 'git-status': {
14
+ needsApproval: false,
15
+ handler: async (args, config) => {
16
+ const customPath = typeof args === 'object' && args !== null ? args.path : String(args || '').trim()
17
+ const activeRoot = resolveGitRoot(customPath, config)
18
+ return await getGitStatus(activeRoot)
19
+ }
20
+ },
21
+
22
+ 'git-diff': {
23
+ needsApproval: false,
24
+ handler: async (args, config) => {
25
+ let file = ''
26
+ let customPath = ''
27
+ if (typeof args === 'object' && args !== null) {
28
+ file = args.file || ''
29
+ customPath = args.path || ''
30
+ } else {
31
+ file = String(args || '').trim()
32
+ }
33
+ const activeRoot = resolveGitRoot(customPath, config)
34
+ return await getGitDiff(activeRoot, file)
35
+ }
36
+ },
37
+
38
+ 'git-commit': {
39
+ needsApproval: true,
40
+ approvalMessage: (args) => {
41
+ const msg = typeof args === 'object' && args !== null ? args.message : String(args || '').split('||')[0]
42
+ return `Mark ingin melakukan git commit dengan pesan:\n"${msg}"`
43
+ },
44
+ handler: async (args, config) => {
45
+ let message = 'Mark Agent Commit'
46
+ let customCwd = ''
47
+ if (typeof args === 'object' && args !== null) {
48
+ message = args.message || 'Mark Agent Commit'
49
+ customCwd = args.path || ''
50
+ } else {
51
+ const parts = String(args || '').split('||')
52
+ message = parts[0]?.trim() || 'Mark Agent Commit'
53
+ customCwd = parts[1]?.trim()
54
+ }
55
+ const activeRoot = resolveGitRoot(customCwd, config)
56
+ return await gitCommit(activeRoot, message)
57
+ }
58
+ },
59
+
60
+ 'git-revert': {
61
+ needsApproval: true,
62
+ approvalMessage: (args) => {
63
+ const target = typeof args === 'object' && args !== null ? (args.file || args.path || 'Seluruh file') : String(args || 'Seluruh file (reset --hard)')
64
+ return `Mark ingin me-rollback perubahan git:\n"${target}"`
65
+ },
66
+ handler: async (args, config) => {
67
+ let file = ''
68
+ let customPath = ''
69
+ if (typeof args === 'object' && args !== null) {
70
+ file = args.file || ''
71
+ customPath = args.path || ''
72
+ } else {
73
+ file = String(args || '').trim()
74
+ }
75
+ const activeRoot = resolveGitRoot(customPath, config)
76
+ return await gitRevert(activeRoot, file)
77
+ }
78
+ }
79
+ }
@@ -0,0 +1,566 @@
1
+ import fs from 'fs'
2
+ import path from 'path'
3
+ import os from 'os'
4
+ import {
5
+ searchFiles,
6
+ listFiles,
7
+ readFile,
8
+ uploadFile,
9
+ createFile,
10
+ moveFile,
11
+ copyFile,
12
+ shareFile,
13
+ getDriveInfo
14
+ } from '../google/google-drive.js'
15
+ import { listEvents, createEvent, deleteEvent } from '../google/google-calendar.js'
16
+ import { searchEmails, readEmail, sendEmail, markAsRead } from '../google/google-gmail.js'
17
+
18
+ export const parsePagination = (pagination) => {
19
+ let start = 0,
20
+ end = 10
21
+ if (!pagination) return { start, end, fetchCount: end }
22
+ if (typeof pagination === 'object') {
23
+ start = parseInt(pagination.start, 10) || 0
24
+ end = parseInt(pagination.end, 10) || 10
25
+ } else {
26
+ const s = String(pagination).trim()
27
+ if (s.includes('-')) {
28
+ const p = s.split('-')
29
+ start = parseInt(p[0], 10) || 0
30
+ end = parseInt(p[1], 10) || 10
31
+ } else {
32
+ end = parseInt(s, 10) || 10
33
+ }
34
+ }
35
+ if (start < 0) start = 0
36
+ if (end <= start) end = start + 10
37
+ const fetchCount = end > 500 ? 500 : end
38
+ return { start, end, fetchCount }
39
+ }
40
+
41
+ export const getGoogleCredentials = (config) => {
42
+ let clientId =
43
+ config?.googleClientId || (Array.isArray(config) ? config[0]?.googleClientId : null)
44
+ let clientSecret =
45
+ config?.googleClientSecret || (Array.isArray(config) ? config[0]?.googleClientSecret : null)
46
+
47
+ if (!clientId || !clientSecret) {
48
+ try {
49
+ const configPath = path.join(os.homedir(), '.config', 'mark-agent', 'config.json')
50
+ if (fs.existsSync(configPath)) {
51
+ const raw = fs.readFileSync(configPath, 'utf8')
52
+ const parsed = JSON.parse(raw)
53
+ clientId = clientId || parsed?.googleClientId
54
+ clientSecret = clientSecret || parsed?.googleClientSecret
55
+ }
56
+ } catch {
57
+ // Ignore missing local config file
58
+ }
59
+ }
60
+
61
+ return { clientId, clientSecret }
62
+ }
63
+
64
+ export const googleTools = {
65
+ // Google Drive
66
+ 'gdrive-info': {
67
+ needsApproval: false,
68
+ handler: async (_args, config) => {
69
+ try {
70
+ const { clientId, clientSecret } = getGoogleCredentials(config)
71
+ const result = await getDriveInfo(clientId, clientSecret)
72
+ return { success: true, data: result }
73
+ } catch (e) {
74
+ return { success: false, error: e.message }
75
+ }
76
+ }
77
+ },
78
+
79
+ 'gdrive-search': {
80
+ needsApproval: false,
81
+ handler: async (args, config) => {
82
+ try {
83
+ let q = ''
84
+ let pagination = null
85
+ if (typeof args === 'object' && args !== null) {
86
+ q = (args.query || '').trim()
87
+ pagination = args.pagination
88
+ } else {
89
+ const parts = String(args || '').split('||')
90
+ q = parts[0].trim()
91
+ pagination = parts[1]
92
+ }
93
+ const { start, end, fetchCount } = parsePagination(pagination)
94
+ const { clientId, clientSecret } = getGoogleCredentials(config)
95
+ const rawResult = await searchFiles(clientId, clientSecret, q, fetchCount)
96
+ return { success: true, data: rawResult.slice(start, end) }
97
+ } catch (e) {
98
+ return { success: false, error: e.message }
99
+ }
100
+ }
101
+ },
102
+
103
+ 'gdrive-list': {
104
+ needsApproval: false,
105
+ handler: async (args, config) => {
106
+ try {
107
+ let folderId = null
108
+ let pagination = null
109
+ if (typeof args === 'object' && args !== null) {
110
+ folderId = (args.folder_id || args.folderId || '').trim() || null
111
+ pagination = args.pagination
112
+ } else {
113
+ const parts = String(args || '').split('||')
114
+ folderId = parts[0].trim() || null
115
+ pagination = parts[1]
116
+ }
117
+ const { start, end, fetchCount } = parsePagination(pagination)
118
+ const { clientId, clientSecret } = getGoogleCredentials(config)
119
+ const rawResult = await listFiles(clientId, clientSecret, folderId, fetchCount)
120
+ return { success: true, data: rawResult.slice(start, end) }
121
+ } catch (e) {
122
+ return { success: false, error: e.message }
123
+ }
124
+ }
125
+ },
126
+
127
+ 'gdrive-read': {
128
+ needsApproval: false,
129
+ handler: async (args, config) => {
130
+ try {
131
+ const fileId = (
132
+ typeof args === 'object' && args !== null
133
+ ? args.file_id || args.fileId
134
+ : String(args || '')
135
+ ).trim()
136
+ const { clientId, clientSecret } = getGoogleCredentials(config)
137
+ const result = await readFile(clientId, clientSecret, fileId)
138
+ return { success: true, data: result }
139
+ } catch (e) {
140
+ return { success: false, error: e.message }
141
+ }
142
+ }
143
+ },
144
+
145
+ 'gdrive-upload': {
146
+ needsApproval: true,
147
+ approvalMessage: (args) => {
148
+ let filePath = ''
149
+ if (typeof args === 'object' && args !== null) {
150
+ filePath = (args.file_path || args.filepath || '').trim()
151
+ } else {
152
+ filePath = String(args || '').trim()
153
+ }
154
+ return `Mark ingin mengunggah berkas ke Google Drive:\n${filePath}`
155
+ },
156
+ handler: async (args, config) => {
157
+ try {
158
+ let filePath = ''
159
+ if (typeof args === 'object' && args !== null) {
160
+ filePath = (args.file_path || args.filepath || '').trim()
161
+ } else {
162
+ filePath = String(args || '').trim()
163
+ }
164
+
165
+ if (!filePath) {
166
+ return { success: false, error: 'Parameter file_path wajib diisi.' }
167
+ }
168
+
169
+ const activeRoot =
170
+ config?.workspaceRoot || path.join(os.homedir(), 'Documents', 'Mark Workspace')
171
+ if (!path.isAbsolute(filePath)) {
172
+ filePath = path.join(activeRoot, filePath)
173
+ }
174
+
175
+ const { clientId, clientSecret } = getGoogleCredentials(config)
176
+ const result = await uploadFile(clientId, clientSecret, filePath)
177
+ return { success: true, data: result }
178
+ } catch (e) {
179
+ return { success: false, error: e.message }
180
+ }
181
+ }
182
+ },
183
+
184
+ 'gdrive-create': {
185
+ needsApproval: true,
186
+ approvalMessage: (args) => {
187
+ let name = ''
188
+ let type = 'doc'
189
+ if (typeof args === 'object' && args !== null) {
190
+ name = args.name
191
+ type = args.type || 'doc'
192
+ } else {
193
+ const parts = String(args || '').split('||')
194
+ name = parts[0]
195
+ type = parts[1] || 'doc'
196
+ }
197
+ return `Mark ingin membuat dokumen kosong baru di Google Drive:\nNama: ${name}\nTipe: ${type}`
198
+ },
199
+ handler: async (args, config) => {
200
+ try {
201
+ let name = ''
202
+ let type = 'doc'
203
+ if (typeof args === 'object' && args !== null) {
204
+ name = (args.name || '').trim()
205
+ type = (args.type || 'doc').trim()
206
+ } else {
207
+ const parts = String(args || '').split('||')
208
+ name = parts[0].trim()
209
+ type = parts[1] ? parts[1].trim() : 'doc'
210
+ }
211
+ const { clientId, clientSecret } = getGoogleCredentials(config)
212
+ const result = await createFile(clientId, clientSecret, name, type)
213
+ return { success: true, data: result }
214
+ } catch (e) {
215
+ return { success: false, error: e.message }
216
+ }
217
+ }
218
+ },
219
+
220
+ 'gdrive-move': {
221
+ needsApproval: true,
222
+ approvalMessage: (args) => {
223
+ let fileId = ''
224
+ let folderId = ''
225
+ if (typeof args === 'object' && args !== null) {
226
+ fileId = args.file_id || args.fileId
227
+ folderId = args.folder_id || args.folderId
228
+ } else {
229
+ const parts = String(args || '').split('||')
230
+ fileId = parts[0]
231
+ folderId = parts[1]
232
+ }
233
+ return `Mark ingin memindahkan file di Google Drive.\nFile ID: ${fileId}\nFolder Tujuan ID: ${folderId}`
234
+ },
235
+ handler: async (args, config) => {
236
+ try {
237
+ let fileId = ''
238
+ let folderId = ''
239
+ if (typeof args === 'object' && args !== null) {
240
+ fileId = (args.file_id || args.fileId || '').trim()
241
+ folderId = (args.folder_id || args.folderId || '').trim()
242
+ } else {
243
+ const parts = String(args || '').split('||')
244
+ fileId = parts[0].trim()
245
+ folderId = parts[1].trim()
246
+ }
247
+ const { clientId, clientSecret } = getGoogleCredentials(config)
248
+ const result = await moveFile(clientId, clientSecret, fileId, folderId)
249
+ return { success: true, data: result }
250
+ } catch (e) {
251
+ return { success: false, error: e.message }
252
+ }
253
+ }
254
+ },
255
+
256
+ 'gdrive-copy': {
257
+ needsApproval: true,
258
+ approvalMessage: (args) => {
259
+ let fileId = ''
260
+ let newName = ''
261
+ if (typeof args === 'object' && args !== null) {
262
+ fileId = args.file_id || args.fileId
263
+ newName = args.new_name || args.newName
264
+ } else {
265
+ const parts = String(args || '').split('||')
266
+ fileId = parts[0]
267
+ newName = parts[1]
268
+ }
269
+ return `Mark ingin menduplikasi file di Google Drive.\nFile ID: ${fileId}\nNama Baru: ${newName}`
270
+ },
271
+ handler: async (args, config) => {
272
+ try {
273
+ let fileId = ''
274
+ let newName = ''
275
+ if (typeof args === 'object' && args !== null) {
276
+ fileId = (args.file_id || args.fileId || '').trim()
277
+ newName = (args.new_name || args.newName || '').trim()
278
+ } else {
279
+ const parts = String(args || '').split('||')
280
+ fileId = parts[0].trim()
281
+ newName = parts[1].trim()
282
+ }
283
+ const { clientId, clientSecret } = getGoogleCredentials(config)
284
+ const result = await copyFile(clientId, clientSecret, fileId, newName)
285
+ return { success: true, data: result }
286
+ } catch (e) {
287
+ return { success: false, error: e.message }
288
+ }
289
+ }
290
+ },
291
+
292
+ 'gdrive-share': {
293
+ needsApproval: true,
294
+ approvalMessage: (args) => {
295
+ let fileId = ''
296
+ let role = 'reader'
297
+ let type = 'anyone'
298
+ if (typeof args === 'object' && args !== null) {
299
+ fileId = args.file_id || args.fileId || ''
300
+ role = args.role || 'reader'
301
+ type = args.type || 'anyone'
302
+ } else {
303
+ fileId = String(args || '').trim()
304
+ }
305
+ return `Mark ingin mengubah izin akses berkas di Google Drive:\nFile ID: ${fileId}\nTipe: ${type}\nPeran: ${role}`
306
+ },
307
+ handler: async (args, config) => {
308
+ try {
309
+ let fileId = ''
310
+ let role = 'reader'
311
+ let type = 'anyone'
312
+ let email = null
313
+
314
+ if (typeof args === 'object' && args !== null) {
315
+ fileId = (args.file_id || args.fileId || '').trim()
316
+ role = (args.role || 'reader').trim()
317
+ type = (args.type || 'anyone').trim()
318
+ email = (args.email || args.emailAddress || '').trim() || null
319
+ } else {
320
+ fileId = String(args || '').trim()
321
+ }
322
+
323
+ if (!fileId) {
324
+ return { success: false, error: 'Parameter file_id wajib diisi.' }
325
+ }
326
+
327
+ const { clientId, clientSecret } = getGoogleCredentials(config)
328
+ const result = await shareFile(clientId, clientSecret, fileId, role, type, email)
329
+ return { success: true, data: result }
330
+ } catch (e) {
331
+ return { success: false, error: e.message }
332
+ }
333
+ }
334
+ },
335
+ // Google Calendar
336
+ 'gcalendar-list': {
337
+ needsApproval: false,
338
+ handler: async (args, config) => {
339
+ try {
340
+ let pagination = null
341
+ let timeMin = new Date().toISOString()
342
+ if (typeof args === 'object' && args !== null) {
343
+ pagination = args.pagination
344
+ timeMin = args.time_min || args.timeMin || new Date().toISOString()
345
+ } else {
346
+ const parts = String(args || '').split('||')
347
+ pagination = parts[0]
348
+ timeMin = parts[1] ? parts[1].trim() : new Date().toISOString()
349
+ }
350
+ const { start, end, fetchCount } = parsePagination(pagination)
351
+ const { clientId, clientSecret } = getGoogleCredentials(config)
352
+ const rawResult = await listEvents(clientId, clientSecret, fetchCount, timeMin)
353
+ return { success: true, data: rawResult.slice(start, end) }
354
+ } catch (e) {
355
+ return { success: false, error: e.message }
356
+ }
357
+ }
358
+ },
359
+
360
+ 'gcalendar-create': {
361
+ needsApproval: true,
362
+ approvalMessage: (args) => {
363
+ let summary = ''
364
+ let startTime = ''
365
+ if (typeof args === 'object' && args !== null) {
366
+ summary = args.summary
367
+ startTime = args.start_time || args.startTime
368
+ } else {
369
+ const parts = String(args || '').split('||')
370
+ summary = parts[0]
371
+ startTime = parts[2]
372
+ }
373
+ return `Mark ingin membuat jadwal baru di kalendermu:\nJudul: ${summary}\nWaktu Mulai: ${startTime}`
374
+ },
375
+ handler: async (args, config) => {
376
+ try {
377
+ let summary = ''
378
+ let description = ''
379
+ let startTime = ''
380
+ let endTime = ''
381
+ if (typeof args === 'object' && args !== null) {
382
+ summary = (args.summary || '').trim()
383
+ description = (args.description || '').trim()
384
+ startTime = (args.start_time || args.startTime || '').trim()
385
+ endTime = (args.end_time || args.endTime || '').trim()
386
+ } else {
387
+ const parts = String(args || '').split('||')
388
+ summary = parts[0].trim()
389
+ description = parts[1].trim()
390
+ startTime = parts[2].trim()
391
+ endTime = parts[3].trim()
392
+ }
393
+ const { clientId, clientSecret } = getGoogleCredentials(config)
394
+ const result = await createEvent(
395
+ clientId,
396
+ clientSecret,
397
+ summary,
398
+ description,
399
+ startTime,
400
+ endTime
401
+ )
402
+ return { success: true, data: result }
403
+ } catch (e) {
404
+ return { success: false, error: e.message }
405
+ }
406
+ }
407
+ },
408
+
409
+ 'gcalendar-delete': {
410
+ needsApproval: true,
411
+ approvalMessage: (args) => {
412
+ const id =
413
+ typeof args === 'object' && args !== null
414
+ ? args.event_id || args.eventId
415
+ : String(args || '')
416
+ return `Mark ingin MENGHAPUS jadwal/event ini:\nEvent ID: ${id}`
417
+ },
418
+ handler: async (args, config) => {
419
+ try {
420
+ const eventId = (
421
+ typeof args === 'object' && args !== null
422
+ ? args.event_id || args.eventId
423
+ : String(args || '')
424
+ ).trim()
425
+ const { clientId, clientSecret } = getGoogleCredentials(config)
426
+ const result = await deleteEvent(clientId, clientSecret, eventId)
427
+ return { success: true, data: result }
428
+ } catch (e) {
429
+ return { success: false, error: e.message }
430
+ }
431
+ }
432
+ },
433
+
434
+ // Gmail
435
+ 'gmail-search': {
436
+ needsApproval: false,
437
+ handler: async (args, config) => {
438
+ try {
439
+ let q = 'is:unread'
440
+ let pagination = null
441
+ if (typeof args === 'object' && args !== null) {
442
+ q = (args.query || 'is:unread').trim()
443
+ pagination = args.pagination
444
+ } else {
445
+ const parts = String(args || '').split('||')
446
+ q = parts[0].trim() || 'is:unread'
447
+ pagination = parts[1] || ''
448
+ }
449
+ const { start, end, fetchCount } = parsePagination(pagination)
450
+ const { clientId, clientSecret } = getGoogleCredentials(config)
451
+ const rawResult = await searchEmails(clientId, clientSecret, q, fetchCount)
452
+ return { success: true, data: rawResult.slice(start, end) }
453
+ } catch (e) {
454
+ return { success: false, error: e.message }
455
+ }
456
+ }
457
+ },
458
+
459
+ 'gmail-list': {
460
+ needsApproval: false,
461
+ handler: async (args, config) => {
462
+ try {
463
+ const pagination = typeof args === 'object' && args !== null ? args.pagination : args
464
+ const { start, end, fetchCount } = parsePagination(pagination)
465
+ const { clientId, clientSecret } = getGoogleCredentials(config)
466
+ const rawResult = await searchEmails(clientId, clientSecret, 'is:unread', fetchCount)
467
+ return { success: true, data: rawResult.slice(start, end) }
468
+ } catch (e) {
469
+ return { success: false, error: e.message }
470
+ }
471
+ }
472
+ },
473
+
474
+ 'new-gmail-list': {
475
+ needsApproval: false,
476
+ handler: async (args, config) => {
477
+ try {
478
+ const pagination = typeof args === 'object' && args !== null ? args.pagination : args
479
+ const { start, end, fetchCount } = parsePagination(pagination)
480
+ const { clientId, clientSecret } = getGoogleCredentials(config)
481
+ const rawResult = await searchEmails(clientId, clientSecret, 'is:unread', fetchCount)
482
+ return { success: true, data: rawResult.slice(start, end) }
483
+ } catch (e) {
484
+ return { success: false, error: e.message }
485
+ }
486
+ }
487
+ },
488
+
489
+ 'gmail-read': {
490
+ needsApproval: false,
491
+ handler: async (args, config) => {
492
+ try {
493
+ const messageId = (
494
+ typeof args === 'object' && args !== null
495
+ ? args.message_id || args.messageId || args.id
496
+ : String(args || '')
497
+ ).trim()
498
+ const { clientId, clientSecret } = getGoogleCredentials(config)
499
+ const result = await readEmail(clientId, clientSecret, messageId)
500
+ return { success: true, data: result }
501
+ } catch (e) {
502
+ return { success: false, error: e.message }
503
+ }
504
+ }
505
+ },
506
+
507
+ 'gmail-send': {
508
+ needsApproval: true,
509
+ approvalMessage: (args) => {
510
+ let to = ''
511
+ let subject = ''
512
+ let body = ''
513
+ if (typeof args === 'object' && args !== null) {
514
+ to = args.to
515
+ subject = args.subject
516
+ body = args.body || ''
517
+ } else {
518
+ const parts = String(args || '').split('||')
519
+ to = parts[0]
520
+ subject = parts[1]
521
+ body = parts[2] || ''
522
+ }
523
+ return `Mark ingin MENGIRIM EMAIL baru.\nTujuan: ${to}\nSubjek: ${subject}\nIsi Pesan:\n${body.slice(0, 100)}...`
524
+ },
525
+ handler: async (args, config) => {
526
+ try {
527
+ let to = ''
528
+ let subject = ''
529
+ let bodyText = ''
530
+ if (typeof args === 'object' && args !== null) {
531
+ to = (args.to || '').trim()
532
+ subject = (args.subject || '').trim()
533
+ bodyText = args.body || ''
534
+ } else {
535
+ const parts = String(args || '').split('||')
536
+ to = parts[0].trim()
537
+ subject = parts[1].trim()
538
+ bodyText = parts.slice(2).join('||')
539
+ }
540
+ const { clientId, clientSecret } = getGoogleCredentials(config)
541
+ const result = await sendEmail(clientId, clientSecret, to, subject, bodyText)
542
+ return { success: true, data: result }
543
+ } catch (e) {
544
+ return { success: false, error: e.message }
545
+ }
546
+ }
547
+ },
548
+
549
+ 'gmail-mark-read': {
550
+ needsApproval: false,
551
+ handler: async (args, config) => {
552
+ try {
553
+ const messageId = (
554
+ typeof args === 'object' && args !== null
555
+ ? args.message_id || args.messageId || args.id
556
+ : String(args || '')
557
+ ).trim()
558
+ const { clientId, clientSecret } = getGoogleCredentials(config)
559
+ const result = await markAsRead(clientId, clientSecret, messageId)
560
+ return { success: true, data: result }
561
+ } catch (e) {
562
+ return { success: false, error: e.message }
563
+ }
564
+ }
565
+ }
566
+ }
@@ -0,0 +1,36 @@
1
+ import { fileTools } from './file-tools.js'
2
+ import { browserTools } from './browser-tools.js'
3
+ import { systemTools, isDangerousCommand, isDangerousKeyCombo } from './system-tools.js'
4
+ import { gitTools } from './git-tools.js'
5
+ import { taskTools } from './task-tools.js'
6
+ import { googleTools, parsePagination, getGoogleCredentials } from './google-tools.js'
7
+ import { telegramTools } from './telegram-tools.js'
8
+ import { mediaTools } from './media-tools.js'
9
+
10
+ export const NATIVE_TOOLS = {
11
+ ...fileTools,
12
+ ...browserTools,
13
+ ...systemTools,
14
+ ...gitTools,
15
+ ...taskTools,
16
+ ...googleTools,
17
+ ...telegramTools,
18
+ ...mediaTools
19
+ }
20
+
21
+ export const getNativeToolsDefinition = () => NATIVE_TOOLS
22
+
23
+ export {
24
+ fileTools,
25
+ browserTools,
26
+ systemTools,
27
+ gitTools,
28
+ taskTools,
29
+ googleTools,
30
+ telegramTools,
31
+ mediaTools,
32
+ isDangerousCommand,
33
+ isDangerousKeyCombo,
34
+ parsePagination,
35
+ getGoogleCredentials
36
+ }