@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,42 @@
1
+ import { searchYoutube, getTranscript, synthesizeTTS } from '../../server/tools/media-tools.js'
2
+
3
+ export const mediaTools = {
4
+ 'search-youtube': {
5
+ needsApproval: false,
6
+ handler: async (args) => {
7
+ try {
8
+ const q = (typeof args === 'object' && args !== null ? (args.query || '') : String(args || '')).trim()
9
+ const result = await searchYoutube(q)
10
+ return { success: true, data: result }
11
+ } catch (e) {
12
+ return { success: false, error: e.message }
13
+ }
14
+ }
15
+ },
16
+
17
+ 'youtube-transcript': {
18
+ needsApproval: false,
19
+ handler: async (args) => {
20
+ try {
21
+ const url = (typeof args === 'object' && args !== null ? (args.url || '') : String(args || '')).trim()
22
+ const result = await getTranscript(url)
23
+ return { success: true, data: result }
24
+ } catch (e) {
25
+ return { success: false, error: e.message }
26
+ }
27
+ }
28
+ },
29
+
30
+ 'tts-speak': {
31
+ needsApproval: false,
32
+ handler: async (args) => {
33
+ try {
34
+ const text = (typeof args === 'object' && args !== null ? (args.text || '') : String(args || '')).trim()
35
+ const result = await synthesizeTTS(text)
36
+ return { success: true, data: result }
37
+ } catch (e) {
38
+ return { success: false, error: e.message }
39
+ }
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,295 @@
1
+ import path from 'path'
2
+ import os from 'os'
3
+ import { exec } from 'child_process'
4
+ import util from 'util'
5
+ import {
6
+ readDesktop,
7
+ executeClick,
8
+ executeDoubleClick,
9
+ executeType,
10
+ executeKey,
11
+ executeScroll,
12
+ openApp,
13
+ listWindows,
14
+ focusWindow,
15
+ openPCSession,
16
+ closePCSession,
17
+ isPCSessionOpen
18
+ } from '../../server/tools/pc-agent.js'
19
+
20
+ const execPromise = util.promisify(exec)
21
+
22
+ const DANGEROUS_KEY_COMBOS = [
23
+ 'alt+f4',
24
+ 'ctrl+shift+del',
25
+ 'win+l',
26
+ 'ctrl+alt+del',
27
+ 'alt+shift+del',
28
+ 'ctrl+shift+esc'
29
+ ]
30
+
31
+ export const isDangerousKeyCombo = (combo = '') => {
32
+ const normalized = String(combo).toLowerCase().replace(/\s+/g, '')
33
+ return DANGEROUS_KEY_COMBOS.some((bad) => normalized.includes(bad.replace(/\s+/g, '')))
34
+ }
35
+
36
+ const DANGEROUS_KEYWORDS = [
37
+ 'Remove-Item',
38
+ 'rm ',
39
+ 'del ',
40
+ 'rmdir',
41
+ 'Format-',
42
+ 'Clear-Disk',
43
+ 'Stop-Process',
44
+ 'kill ',
45
+ 'taskkill',
46
+ 'Set-ExecutionPolicy',
47
+ 'Restart-Computer',
48
+ 'shutdown',
49
+ 'reg delete'
50
+ ]
51
+
52
+ export const isDangerousCommand = (cmd) => {
53
+ const str = typeof cmd === 'object' ? (cmd?.command || '') : String(cmd || '')
54
+ return DANGEROUS_KEYWORDS.some((k) => str.toLowerCase().includes(k.toLowerCase()))
55
+ }
56
+
57
+ export const systemTools = {
58
+ 'run-powershell': {
59
+ needsApproval: (args) => isDangerousCommand(args),
60
+ approvalMessage: (args) => {
61
+ const cmd = typeof args === 'object' && args !== null ? args.command : String(args || '')
62
+ return `Mark ingin mengeksekusi perintah PowerShell yang berpotensi BERBAHAYA:\n\n${cmd}`
63
+ },
64
+ handler: async (args, config) => {
65
+ const command = (typeof args === 'object' && args !== null ? args.command : String(args || '')).trim()
66
+ if (!command) return { success: false, message: 'Tidak ada perintah yang diberikan.' }
67
+ try {
68
+ const activeRoot = config?.workspaceRoot || path.join(os.homedir(), 'Documents', 'Mark Workspace')
69
+
70
+ // Gunakan Base64 EncodedCommand (UTF-16LE) agar karakter khusus ($_, quotes, pipe, regex) 100% aman
71
+ const encodedCmd = Buffer.from(command, 'utf16le').toString('base64')
72
+ const { stdout, stderr } = await execPromise(
73
+ `powershell.exe -NoProfile -ExecutionPolicy Bypass -EncodedCommand ${encodedCmd}`,
74
+ {
75
+ cwd: activeRoot,
76
+ maxBuffer: 10 * 1024 * 1024, // 10MB buffer agar output besar tidak melempar MaxBuffer exceeded
77
+ timeout: 60000 // 60 detik timeout
78
+ }
79
+ )
80
+ const outputText = stdout.trim() || (stderr.trim() ? `[STDERR]: ${stderr.trim()}` : 'Perintah berhasil dieksekusi tanpa output teks.')
81
+ return {
82
+ success: true,
83
+ data: outputText,
84
+ output: outputText,
85
+ error: stderr.trim() || null
86
+ }
87
+ } catch (error) {
88
+ // Tangani jika error membawa stdout parsial
89
+ const partialOutput = error.stdout ? error.stdout.trim() : ''
90
+ const errorMsg = error.stderr ? error.stderr.trim() : error.message
91
+ return {
92
+ success: false,
93
+ message: 'Gagal mengeksekusi perintah.',
94
+ output: partialOutput || null,
95
+ error: errorMsg
96
+ }
97
+ }
98
+ }
99
+ },
100
+
101
+ 'os-read': {
102
+ needsApproval: false,
103
+ handler: async (args) => {
104
+ try {
105
+ const mode = typeof args === 'object' && args !== null ? (args.mode || 'all') : String(args || 'all')
106
+ const result = await readDesktop({}, mode)
107
+ return { success: true, data: result }
108
+ } catch (e) {
109
+ return { success: false, error: e.message }
110
+ }
111
+ }
112
+ },
113
+
114
+ 'os-click': {
115
+ needsApproval: false,
116
+ handler: async (args) => {
117
+ try {
118
+ const target = typeof args === 'object' && args !== null ? (args.target ?? '') : String(args ?? '')
119
+ const result = await executeClick(target)
120
+ return { success: true, data: result }
121
+ } catch (e) {
122
+ return { success: false, error: e.message }
123
+ }
124
+ }
125
+ },
126
+
127
+ 'os-type': {
128
+ needsApproval: false,
129
+ handler: async (args) => {
130
+ try {
131
+ const text = typeof args === 'object' && args !== null ? (args.text ?? '') : String(args ?? '')
132
+ const result = await executeType(text)
133
+ return { success: true, data: result }
134
+ } catch (e) {
135
+ return { success: false, error: e.message }
136
+ }
137
+ }
138
+ },
139
+
140
+ 'os-key': {
141
+ needsApproval: (args) => {
142
+ const combo = typeof args === 'object' && args !== null ? args.combo : String(args || '')
143
+ return isDangerousKeyCombo(combo)
144
+ },
145
+ approvalMessage: (args) => {
146
+ const combo = typeof args === 'object' && args !== null ? args.combo : String(args || '')
147
+ return `Mark ingin menekan shortcut keyboard yang berpotensi BERBAHAYA:\n\n${combo}`
148
+ },
149
+ handler: async (args) => {
150
+ try {
151
+ const combo = typeof args === 'object' && args !== null ? (args.combo ?? '') : String(args ?? '')
152
+ const result = await executeKey(combo)
153
+ return { success: true, data: result }
154
+ } catch (e) {
155
+ return { success: false, error: e.message }
156
+ }
157
+ }
158
+ },
159
+
160
+ 'os-scroll': {
161
+ needsApproval: false,
162
+ handler: async (args) => {
163
+ try {
164
+ let direction = 'down'
165
+ let amount = 3
166
+ if (typeof args === 'object' && args !== null) {
167
+ direction = args.direction || 'down'
168
+ amount = args.amount !== undefined ? Number(args.amount) : 3
169
+ } else {
170
+ const parts = String(args || '').split('||')
171
+ direction = parts[0] || 'down'
172
+ amount = parts[1] ? Number(parts[1]) : 3
173
+ }
174
+ const result = await executeScroll(direction, amount)
175
+ return { success: true, data: result }
176
+ } catch (e) {
177
+ return { success: false, error: e.message }
178
+ }
179
+ }
180
+ },
181
+
182
+ 'open': {
183
+ needsApproval: false,
184
+ handler: async (args) => {
185
+ try {
186
+ const target = typeof args === 'object' && args !== null ? (args.target ?? '') : String(args ?? '')
187
+ await execPromise(`start "" "${target}"`)
188
+ return { success: true, data: `Opened: ${target}` }
189
+ } catch (e) {
190
+ return { success: false, error: e.message }
191
+ }
192
+ }
193
+ },
194
+
195
+ 'os-open': {
196
+ needsApproval: false,
197
+ handler: async (args) => {
198
+ try {
199
+ const target = (typeof args === 'object' && args !== null ? (args.target ?? '') : String(args ?? '')).trim()
200
+ await execPromise(`start "" "${target}"`)
201
+ return { success: true, data: `Opened: ${target}` }
202
+ } catch (e) {
203
+ return { success: false, error: e.message }
204
+ }
205
+ }
206
+ },
207
+
208
+ 'os-search': {
209
+ needsApproval: false,
210
+ handler: async (args) => {
211
+ try {
212
+ const query = typeof args === 'object' && args !== null ? (args.keyword || '') : String(args || '')
213
+ await executeKey('win')
214
+ await new Promise((r) => setTimeout(r, 800))
215
+ const result = await executeType(query)
216
+ return {
217
+ success: true,
218
+ data: `[PC-Agent] Opened Start Menu and searched for "${query}". ${result}`
219
+ }
220
+ } catch (e) {
221
+ return { success: false, error: e.message }
222
+ }
223
+ }
224
+ },
225
+
226
+ 'os-double-click': {
227
+ needsApproval: false,
228
+ handler: async (args) => {
229
+ const target = typeof args === 'object' && args !== null ? (args.target ?? '') : String(args ?? '')
230
+ return await executeDoubleClick(target)
231
+ }
232
+ },
233
+
234
+ 'os-delay': {
235
+ needsApproval: false,
236
+ handler: async (args) => {
237
+ let ms = typeof args === 'object' && args !== null ? parseInt(args.ms, 10) : parseInt(args, 10)
238
+ if (isNaN(ms) || ms < 0) ms = 1000
239
+ if (ms > 10000) ms = 10000
240
+ await new Promise((r) => setTimeout(r, ms))
241
+ return { success: true, data: `[PC-Agent] Delayed for ${ms}ms.` }
242
+ }
243
+ },
244
+
245
+ 'os-list-windows': {
246
+ needsApproval: false,
247
+ handler: async () => {
248
+ try {
249
+ const result = await listWindows()
250
+ return { success: true, data: result }
251
+ } catch (e) {
252
+ return { success: false, error: e.message }
253
+ }
254
+ }
255
+ },
256
+
257
+ 'os-focus-window': {
258
+ needsApproval: false,
259
+ handler: async (args) => {
260
+ try {
261
+ const title = typeof args === 'object' && args !== null ? (args.title || '') : String(args || '')
262
+ const result = await focusWindow(title)
263
+ return { success: true, data: result }
264
+ } catch (e) {
265
+ return { success: false, error: e.message }
266
+ }
267
+ }
268
+ },
269
+
270
+ 'os-control-open': {
271
+ needsApproval: () => !isPCSessionOpen(),
272
+ approvalMessage: () =>
273
+ 'Mark ingin mengontrol fisik PC/desktop-mu (mengunci sesi sementara dan memunculkan overlay kontrol PC). Apakah kamu mengizinkan?',
274
+ handler: async () => {
275
+ try {
276
+ const result = await openPCSession()
277
+ return { success: true, data: result }
278
+ } catch (e) {
279
+ return { success: false, error: e.message }
280
+ }
281
+ }
282
+ },
283
+
284
+ 'os-control-close': {
285
+ needsApproval: false,
286
+ handler: async () => {
287
+ try {
288
+ const result = await closePCSession()
289
+ return { success: true, data: result }
290
+ } catch (e) {
291
+ return { success: false, error: e.message }
292
+ }
293
+ }
294
+ }
295
+ }
@@ -0,0 +1,73 @@
1
+ import path from 'path'
2
+ import os from 'os'
3
+ import {
4
+ spawnBackgroundTask,
5
+ readBackgroundTaskOutput,
6
+ killBackgroundTask,
7
+ listBackgroundTasks
8
+ } from '../task-daemon.js'
9
+ import { isDangerousCommand } from './system-tools.js'
10
+
11
+ export const taskTools = {
12
+ 'run-task': {
13
+ needsApproval: (args) => {
14
+ const cmd = typeof args === 'object' && args !== null ? args.command : String(args || '').split('||')[1]
15
+ return isDangerousCommand(cmd || '')
16
+ },
17
+ approvalMessage: (args) => {
18
+ const cmd = typeof args === 'object' && args !== null ? `${args.task_id}: ${args.command}` : String(args || '')
19
+ return `Mark ingin menjalankan background task:\n${cmd}`
20
+ },
21
+ handler: async (args, config) => {
22
+ let taskId = ''
23
+ let command = ''
24
+ if (typeof args === 'object' && args !== null) {
25
+ taskId = (args.task_id || args.taskId || '').trim()
26
+ command = (args.command || '').trim()
27
+ } else {
28
+ const parts = String(args || '').split('||')
29
+ if (parts.length < 2) {
30
+ return { success: false, message: 'Format salah. Memerlukan task_id dan command.' }
31
+ }
32
+ taskId = parts[0].trim()
33
+ command = parts.slice(1).join('||').trim()
34
+ }
35
+ const activeRoot = config?.workspaceRoot || path.join(os.homedir(), 'Documents', 'Mark Workspace')
36
+ return spawnBackgroundTask(taskId, command, activeRoot)
37
+ }
38
+ },
39
+
40
+ 'read-task-output': {
41
+ needsApproval: false,
42
+ handler: async (args) => {
43
+ let taskId = ''
44
+ let lines = 40
45
+ if (typeof args === 'object' && args !== null) {
46
+ taskId = (args.task_id || args.taskId || '').trim()
47
+ lines = args.lines ? parseInt(args.lines, 10) : 40
48
+ } else {
49
+ const parts = String(args || '').split('||')
50
+ taskId = parts[0]?.trim()
51
+ lines = parts[1] ? parseInt(parts[1].trim(), 10) : 40
52
+ }
53
+ if (!taskId) return { success: false, message: 'Wajib menyertakan task_id' }
54
+ return readBackgroundTaskOutput(taskId, lines)
55
+ }
56
+ },
57
+
58
+ 'kill-task': {
59
+ needsApproval: false,
60
+ handler: async (args) => {
61
+ const taskId = (typeof args === 'object' && args !== null ? (args.task_id || args.taskId) : String(args || '')).trim()
62
+ if (!taskId) return { success: false, message: 'Wajib menyertakan task_id' }
63
+ return killBackgroundTask(taskId)
64
+ }
65
+ },
66
+
67
+ 'list-tasks': {
68
+ needsApproval: false,
69
+ handler: async () => {
70
+ return listBackgroundTasks()
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,101 @@
1
+ import fs from 'fs'
2
+ import {
3
+ sendTelegramMessage,
4
+ sendTelegramFile,
5
+ sendTelegramScreenshot
6
+ } from '../telegram/telegram-service.js'
7
+
8
+ export const telegramTools = {
9
+ 'tg-send': {
10
+ needsApproval: false,
11
+ handler: async (args) => {
12
+ try {
13
+ let chatId = ''
14
+ let type = 'auto'
15
+ let content = ''
16
+ let caption = ''
17
+
18
+ if (typeof args === 'object' && args !== null) {
19
+ chatId = String(args.chat_id || args.chatId || '').trim()
20
+ type = String(args.type || 'auto')
21
+ .trim()
22
+ .toLowerCase()
23
+ content = args.content ?? ''
24
+ caption = String(args.caption || args.text || '').trim()
25
+ } else {
26
+ const rawStr = String(args || '').trim()
27
+ const parts = rawStr.split(/\|+/)
28
+ if (parts.length === 1) {
29
+ content = parts[0].trim()
30
+ } else if (parts.length === 2) {
31
+ if (['text', 'file', 'photo', 'image'].includes(parts[0].trim().toLowerCase())) {
32
+ type = parts[0].trim().toLowerCase()
33
+ content = parts[1].trim()
34
+ } else {
35
+ chatId = parts[0].trim()
36
+ content = parts[1].trim()
37
+ }
38
+ } else {
39
+ chatId = parts[0].trim()
40
+ type = parts[1].trim().toLowerCase()
41
+ content = parts.slice(2).join('||').trim()
42
+ }
43
+ }
44
+
45
+ // Auto-detect type jika 'auto'
46
+ if (type === 'auto') {
47
+ const cleanContent = typeof content === 'string' ? content.trim() : ''
48
+ if (
49
+ cleanContent.startsWith('data:') ||
50
+ fs.existsSync(cleanContent) ||
51
+ /\.(png|jpe?g|webp|gif|bmp|pdf|docx?|xlsx?|txt|zip)$/i.test(cleanContent)
52
+ ) {
53
+ type =
54
+ /\.(png|jpe?g|webp|gif|bmp)$/i.test(cleanContent) ||
55
+ cleanContent.startsWith('data:image/')
56
+ ? 'photo'
57
+ : 'file'
58
+ } else {
59
+ type = 'text'
60
+ }
61
+ }
62
+
63
+ if (type === 'file' || type === 'photo' || type === 'image') {
64
+ const result = await sendTelegramFile(chatId, content, caption, { type })
65
+ return {
66
+ success: result.success,
67
+ data: result.success
68
+ ? `Berhasil mengirim ${type === 'photo' ? 'gambar/foto' : 'berkas'} ke Telegram.`
69
+ : `Gagal: ${result.error}`
70
+ }
71
+ } else {
72
+ const result = await sendTelegramMessage(chatId, content)
73
+ return {
74
+ success: result.success,
75
+ data: result.success ? `Berhasil mengirim pesan ke Telegram.` : `Gagal: ${result.error}`
76
+ }
77
+ }
78
+ } catch (e) {
79
+ return { success: false, error: e.message }
80
+ }
81
+ }
82
+ },
83
+ 'screenshot-to-tg': {
84
+ needsApproval: false,
85
+ handler: async (args) => {
86
+ try {
87
+ const chatId =
88
+ typeof args === 'object' && args !== null ? args.chat_id || args.chatId || null : null
89
+ const result = await sendTelegramScreenshot(chatId)
90
+ return {
91
+ success: result.success,
92
+ data: result.success
93
+ ? 'Berhasil mengirim screenshot PC ke Telegram admin.'
94
+ : `Gagal: ${result.error}`
95
+ }
96
+ } catch (e) {
97
+ return { success: false, error: e.message }
98
+ }
99
+ }
100
+ }
101
+ }
@@ -0,0 +1,24 @@
1
+ <!doctype html>
2
+ <html lang="id" data-theme="forest" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>Mark Agent</title>
6
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7
+ <link rel="icon" type="image/svg+xml" href="/icon.svg" />
8
+ <link rel="icon" type="image/png" sizes="256x256" href="/icon-256.png" />
9
+ <link rel="apple-touch-icon" sizes="256x256" href="/icon-256.png" />
10
+ <link rel="icon" type="image/x-icon" href="/favicon.ico" />
11
+ <link rel="manifest" href="/manifest.json" />
12
+ <link rel="preconnect" href="https://fonts.googleapis.com" />
13
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
14
+ <link
15
+ href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500&family=Poppins:wght@300;400;500;600&display=swap"
16
+ rel="stylesheet"
17
+ />
18
+ </head>
19
+
20
+ <body class="bg-[#0f1715] text-[#cac9c9] min-h-screen m-0 p-0 overflow-hidden font-sans">
21
+ <div id="root"></div>
22
+ <script type="module" src="/src/main.jsx"></script>
23
+ </body>
24
+ </html>
Binary file
Binary file