@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.
- package/LICENSE +29 -0
- package/README.md +209 -0
- package/bin/mark.js +27 -0
- package/out/renderer/assets/icon-DHo2CYph.svg +1 -0
- package/out/renderer/assets/index-G2fADWO-.js +4768 -0
- package/out/renderer/assets/index-f3mVse3c.css +1 -0
- package/out/renderer/assets/music-cover-CG4vi3kZ.png +0 -0
- package/out/renderer/assets/poppins-devanagari-400-normal-CJDn6rn8.woff2 +0 -0
- package/out/renderer/assets/poppins-devanagari-400-normal-CqVvlrh5.woff +0 -0
- package/out/renderer/assets/poppins-devanagari-500-normal-BIdkeU1p.woff2 +0 -0
- package/out/renderer/assets/poppins-devanagari-500-normal-DMPDjHtT.woff +0 -0
- package/out/renderer/assets/poppins-devanagari-600-normal-ClASKHrr.woff +0 -0
- package/out/renderer/assets/poppins-devanagari-600-normal-STEjXBNN.woff2 +0 -0
- package/out/renderer/assets/poppins-devanagari-700-normal-O-jipLrW.woff2 +0 -0
- package/out/renderer/assets/poppins-devanagari-700-normal-fHs-vx92.woff +0 -0
- package/out/renderer/assets/poppins-latin-400-normal-BOb3E3N0.woff +0 -0
- package/out/renderer/assets/poppins-latin-400-normal-cpxAROuN.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-500-normal-C8OXljZJ.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-500-normal-DGXqpDMm.woff +0 -0
- package/out/renderer/assets/poppins-latin-600-normal-BJdTmd5m.woff +0 -0
- package/out/renderer/assets/poppins-latin-600-normal-zEkxB9Mr.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-700-normal-BVuQR_eA.woff +0 -0
- package/out/renderer/assets/poppins-latin-700-normal-Qrb0O0WB.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-ext-400-normal-DaBSavcJ.woff +0 -0
- package/out/renderer/assets/poppins-latin-ext-400-normal-by3JarPu.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-ext-500-normal-CK-6C4Hw.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-ext-500-normal-CgAe2rWW.woff +0 -0
- package/out/renderer/assets/poppins-latin-ext-600-normal-CAhIAdZj.woff2 +0 -0
- package/out/renderer/assets/poppins-latin-ext-600-normal-Df5ffKXP.woff +0 -0
- package/out/renderer/assets/poppins-latin-ext-700-normal-DctTR6Tg.woff +0 -0
- package/out/renderer/assets/poppins-latin-ext-700-normal-cby-RkWa.woff2 +0 -0
- package/out/renderer/favicon.ico +0 -0
- package/out/renderer/icon-256.png +0 -0
- package/out/renderer/icon.svg +1 -0
- package/out/renderer/index.html +25 -0
- package/out/renderer/manifest.json +25 -0
- package/out/renderer/robot-simulator.html +1640 -0
- package/package.json +106 -0
- package/src/cli/index.js +332 -0
- package/src/cli/monitor.js +413 -0
- package/src/cli/theme.js +347 -0
- package/src/launcher/MarkTray.cs +227 -0
- package/src/main/browser-agent.js +1132 -0
- package/src/main/git-service.js +90 -0
- package/src/main/google/google-calendar.js +69 -0
- package/src/main/google/google-drive.js +263 -0
- package/src/main/google/google-gmail.js +131 -0
- package/src/main/google/google-service.js +241 -0
- package/src/main/node-tools.js +23 -0
- package/src/main/pc-agent-scripts/mouse-locker.ps1 +76 -0
- package/src/main/pc-agent-scripts/ocr-region.ps1 +185 -0
- package/src/main/pc-agent-scripts/pc-daemon.ps1 +726 -0
- package/src/main/pc-agent-scripts/pc-overlay.ps1 +253 -0
- package/src/main/pc-agent-scripts/pick-folder.ps1 +33 -0
- package/src/main/pc-agent-scripts/read-ui.ps1 +181 -0
- package/src/main/pc-agent-scripts/take-screenshot.ps1 +24 -0
- package/src/main/pc-agent-scripts/win-action.ps1 +380 -0
- package/src/main/plugins/plugin-loader.js +306 -0
- package/src/main/skills/skill-manager.js +265 -0
- package/src/main/syntax-validator.js +455 -0
- package/src/main/task-daemon.js +117 -0
- package/src/main/telegram/telegram-service.js +835 -0
- package/src/main/tools/browser-tools.js +516 -0
- package/src/main/tools/file-tools.js +1126 -0
- package/src/main/tools/git-tools.js +79 -0
- package/src/main/tools/google-tools.js +566 -0
- package/src/main/tools/index.js +36 -0
- package/src/main/tools/media-tools.js +42 -0
- package/src/main/tools/system-tools.js +295 -0
- package/src/main/tools/task-tools.js +73 -0
- package/src/main/tools/telegram-tools.js +101 -0
- package/src/renderer/index.html +24 -0
- package/src/renderer/public/favicon.ico +0 -0
- package/src/renderer/public/icon-256.png +0 -0
- package/src/renderer/public/icon.svg +1 -0
- package/src/renderer/public/manifest.json +25 -0
- package/src/renderer/public/robot-simulator.html +1640 -0
- package/src/renderer/src/App.jsx +304 -0
- package/src/renderer/src/api/ai/awareness.js +294 -0
- package/src/renderer/src/api/ai/chatSummarizer.js +79 -0
- package/src/renderer/src/api/ai/contextCompactor.js +129 -0
- package/src/renderer/src/api/ai/contextManager.js +1130 -0
- package/src/renderer/src/api/ai/core.js +167 -0
- package/src/renderer/src/api/ai/index.js +4 -0
- package/src/renderer/src/api/ai/memoryGroomer.js +101 -0
- package/src/renderer/src/api/ai/persona.js +115 -0
- package/src/renderer/src/api/ai/planning.js +317 -0
- package/src/renderer/src/api/ai/relationship.js +177 -0
- package/src/renderer/src/api/ai/skillSynthesizer.js +168 -0
- package/src/renderer/src/api/ai/tools.js +167 -0
- package/src/renderer/src/api/ai/utils.js +359 -0
- package/src/renderer/src/api/db.js +1013 -0
- package/src/renderer/src/api/oramaStore.js +592 -0
- package/src/renderer/src/api/ragPipeline.js +87 -0
- package/src/renderer/src/api/subagent/subagentExecutor.js +780 -0
- package/src/renderer/src/api/subagent/subagentPrompt.js +44 -0
- package/src/renderer/src/api/subagent/subagentStore.js +173 -0
- package/src/renderer/src/api/taskExecutor.js +18 -0
- package/src/renderer/src/api/taskStore.js +315 -0
- package/src/renderer/src/api/tools/core-tools.js +707 -0
- package/src/renderer/src/api/tools/index.js +151 -0
- package/src/renderer/src/api/turnPairMigrator.js +200 -0
- package/src/renderer/src/api/vectorMemory.js +136 -0
- package/src/renderer/src/api/wakeWord.js +101 -0
- package/src/renderer/src/api/web-bridge.js +885 -0
- package/src/renderer/src/api/webSpeech.js +178 -0
- package/src/renderer/src/api/workspaceRag.js +76 -0
- package/src/renderer/src/assets/electron.svg +10 -0
- package/src/renderer/src/assets/icon.svg +1 -0
- package/src/renderer/src/assets/main.css +589 -0
- package/src/renderer/src/assets/music-cover.png +0 -0
- package/src/renderer/src/assets/wavy-lines.svg +25 -0
- package/src/renderer/src/components/Chat/ApprovalBubble.jsx +127 -0
- package/src/renderer/src/components/Chat/CodeBlock.jsx +83 -0
- package/src/renderer/src/components/Chat/DurableTaskBubble.jsx +455 -0
- package/src/renderer/src/components/Chat/FileDiffModal.jsx +328 -0
- package/src/renderer/src/components/Chat/GeminiWidgets.jsx +82 -0
- package/src/renderer/src/components/Chat/MemoryFooterBubble.jsx +34 -0
- package/src/renderer/src/components/Chat/MessageBubble.jsx +459 -0
- package/src/renderer/src/components/Chat/PluginExecutionBubble.jsx +41 -0
- package/src/renderer/src/components/Chat/ThinkingBubble.jsx +316 -0
- package/src/renderer/src/components/Chat/YoutubeSearchBubble.jsx +43 -0
- package/src/renderer/src/components/Chat/YoutubeSummaryBubble.jsx +40 -0
- package/src/renderer/src/components/Chat/index.js +11 -0
- package/src/renderer/src/components/ChatList.jsx +434 -0
- package/src/renderer/src/components/GlobalCameraManager.jsx +67 -0
- package/src/renderer/src/components/Versions.jsx +15 -0
- package/src/renderer/src/components/YoutubeMusicPlayer.jsx +375 -0
- package/src/renderer/src/components/camera/CameraPreview.jsx +236 -0
- package/src/renderer/src/components/config/AiEngineSection.jsx +363 -0
- package/src/renderer/src/components/config/CameraSection.jsx +100 -0
- package/src/renderer/src/components/config/PermissionsSection.jsx +130 -0
- package/src/renderer/src/components/config/ShortcutSection.jsx +102 -0
- package/src/renderer/src/components/config/VoiceSection.jsx +110 -0
- package/src/renderer/src/components/config/index.js +5 -0
- package/src/renderer/src/components/core/Avatar.jsx +2197 -0
- package/src/renderer/src/components/core/ConfirmModal.jsx +80 -0
- package/src/renderer/src/components/core/DraggableHoloCard.jsx +125 -0
- package/src/renderer/src/components/core/FloatingMenu.jsx +272 -0
- package/src/renderer/src/components/core/HoloCard.jsx +64 -0
- package/src/renderer/src/components/core/InputBar.jsx +1346 -0
- package/src/renderer/src/components/core/ProcessPanel.jsx +216 -0
- package/src/renderer/src/components/core/ResponseArea.jsx +149 -0
- package/src/renderer/src/components/core/StatusIndicator.jsx +59 -0
- package/src/renderer/src/components/core/ThoughtNeuralFlow.jsx +168 -0
- package/src/renderer/src/components/core/ToolClustersDeck.jsx +210 -0
- package/src/renderer/src/components/core/native-skills.js +43 -0
- package/src/renderer/src/components/neural-core/EmotionalCortexLobe.jsx +359 -0
- package/src/renderer/src/components/neural-core/NodeDissectionModal.jsx +57 -0
- package/src/renderer/src/components/neural-core/ProceduralMatrixLobe.jsx +193 -0
- package/src/renderer/src/components/neural-core/ProceduralSkillModal.jsx +53 -0
- package/src/renderer/src/components/neural-core/ResetAiModal.jsx +198 -0
- package/src/renderer/src/components/neural-core/SynapticMemoryLobe.jsx +204 -0
- package/src/renderer/src/components/neural-core/traitMeta.js +102 -0
- package/src/renderer/src/components/subagent/AgentChatFeed.jsx +603 -0
- package/src/renderer/src/components/subagent/AgentInspector.jsx +224 -0
- package/src/renderer/src/components/subagent/AgentSidebar.jsx +216 -0
- package/src/renderer/src/components/subagent/SubagentIntercom.jsx +572 -0
- package/src/renderer/src/components/subagent/SubagentTopologyMap.jsx +423 -0
- package/src/renderer/src/contexts/ApprovalContext.jsx +425 -0
- package/src/renderer/src/contexts/ChatContext.jsx +61 -0
- package/src/renderer/src/contexts/YoutubeMusicContext.jsx +333 -0
- package/src/renderer/src/data/faqData.js +202 -0
- package/src/renderer/src/hooks/agent/executeAgentTool.js +895 -0
- package/src/renderer/src/hooks/agent/index.js +4 -0
- package/src/renderer/src/hooks/agent/useMarkMusic.js +75 -0
- package/src/renderer/src/hooks/agent/useMarkPlan.js +2739 -0
- package/src/renderer/src/hooks/agent/useMarkState.js +173 -0
- package/src/renderer/src/hooks/agent/useMarkYoutube.js +82 -0
- package/src/renderer/src/hooks/agent/useRelationalGrowth.js +201 -0
- package/src/renderer/src/hooks/telegram/useTelegramBot.js +63 -0
- package/src/renderer/src/hooks/useAwareness.js +289 -0
- package/src/renderer/src/hooks/useChatArchiver.js +52 -0
- package/src/renderer/src/hooks/useConfirm.jsx +68 -0
- package/src/renderer/src/hooks/useMarkAgent.js +454 -0
- package/src/renderer/src/hooks/useMemoryGroomer.js +152 -0
- package/src/renderer/src/hooks/useVAD.js +511 -0
- package/src/renderer/src/hooks/useWebSpeechWakeWord.js +122 -0
- package/src/renderer/src/main.jsx +12 -0
- package/src/renderer/src/pages/ChatStudio.jsx +922 -0
- package/src/renderer/src/pages/Configuration.jsx +360 -0
- package/src/renderer/src/pages/GoogleWorkspace.jsx +293 -0
- package/src/renderer/src/pages/Guidebook.jsx +917 -0
- package/src/renderer/src/pages/Knowledge.jsx +241 -0
- package/src/renderer/src/pages/MarkHome.jsx +491 -0
- package/src/renderer/src/pages/NeuralCore.jsx +786 -0
- package/src/renderer/src/pages/Plugins.jsx +630 -0
- package/src/renderer/src/pages/SkillEditor.jsx +380 -0
- package/src/renderer/src/pages/Skills.jsx +219 -0
- package/src/renderer/src/pages/Subagents.jsx +342 -0
- package/src/renderer/src/pages/TelegramBot.jsx +343 -0
- package/src/renderer/src/utils/chatContentParser.js +203 -0
- package/src/renderer/src/utils/toolClusters.js +201 -0
- package/src/server/bin/sha3_wasm_bg.wasm +0 -0
- package/src/server/config-manager.js +57 -0
- package/src/server/index.js +195 -0
- package/src/server/launcher.js +87 -0
- package/src/server/memory/db-store.js +758 -0
- package/src/server/memory/orama-store.js +177 -0
- package/src/server/memory/vector-engine.js +109 -0
- package/src/server/routes/ai.routes.js +280 -0
- package/src/server/routes/awareness.routes.js +62 -0
- package/src/server/routes/chat.routes.js +61 -0
- package/src/server/routes/config.routes.js +41 -0
- package/src/server/routes/index.js +35 -0
- package/src/server/routes/integrations.routes.js +116 -0
- package/src/server/routes/memory.routes.js +256 -0
- package/src/server/routes/plugins.routes.js +72 -0
- package/src/server/routes/skills.routes.js +139 -0
- package/src/server/routes/subagents.routes.js +70 -0
- package/src/server/routes/tasks.routes.js +175 -0
- package/src/server/routes/workspace.routes.js +127 -0
- package/src/server/services/ai/ai-utils.js +161 -0
- package/src/server/services/ai/openai-provider.js +757 -0
- package/src/server/services/ai/web-provider.js +729 -0
- package/src/server/services/ai-bridge.js +46 -0
- package/src/server/services/deepseek-web.js +956 -0
- package/src/server/services/gemini-web.js +170 -0
- package/src/server/services/notification-service.js +91 -0
- package/src/server/services/updater.js +125 -0
- package/src/server/tools/awareness-tracker.js +292 -0
- package/src/server/tools/group-tools.js +1164 -0
- package/src/server/tools/media-tools.js +244 -0
- package/src/server/tools/pc-agent.js +327 -0
- package/src/server/tools/screen-service.js +51 -0
- package/src/server/ws-hub.js +168 -0
- package/src/shared/parsers/mark-tag-parser.js +275 -0
|
@@ -0,0 +1,328 @@
|
|
|
1
|
+
/* eslint-disable react/prop-types */
|
|
2
|
+
import { useState, useEffect } from 'react'
|
|
3
|
+
import { createPortal } from 'react-dom'
|
|
4
|
+
import { DiffEditor } from '@monaco-editor/react'
|
|
5
|
+
import { X } from 'lucide-react'
|
|
6
|
+
|
|
7
|
+
function parseToolArgs(tool, query) {
|
|
8
|
+
let parsed = {}
|
|
9
|
+
if (typeof query === 'object' && query !== null) {
|
|
10
|
+
parsed = { ...query }
|
|
11
|
+
} else if (typeof query === 'string') {
|
|
12
|
+
try {
|
|
13
|
+
parsed = JSON.parse(query)
|
|
14
|
+
} catch {
|
|
15
|
+
const parts = query.split('||')
|
|
16
|
+
if (tool === 'write-file') {
|
|
17
|
+
parsed = { path: parts[0]?.trim(), content: parts.slice(1).join('||') }
|
|
18
|
+
} else if (tool === 'replace-content') {
|
|
19
|
+
parsed = {
|
|
20
|
+
path: parts[0]?.trim(),
|
|
21
|
+
target_content: parts[1],
|
|
22
|
+
replacement_content: parts.slice(2).join('||')
|
|
23
|
+
}
|
|
24
|
+
} else if (tool === 'replace-lines') {
|
|
25
|
+
parsed = {
|
|
26
|
+
path: parts[0]?.trim(),
|
|
27
|
+
start_line: parts[1],
|
|
28
|
+
end_line: parts[2],
|
|
29
|
+
new_code: parts.slice(3).join('||')
|
|
30
|
+
}
|
|
31
|
+
} else if (tool === 'delete-file') {
|
|
32
|
+
parsed = { path: parts[0]?.trim() }
|
|
33
|
+
} else {
|
|
34
|
+
parsed = { path: parts[0]?.trim() }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return parsed
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function getLanguageFromPath(filePath) {
|
|
42
|
+
if (!filePath) return 'plaintext'
|
|
43
|
+
const ext = filePath.split('.').pop()?.toLowerCase()
|
|
44
|
+
const map = {
|
|
45
|
+
js: 'javascript',
|
|
46
|
+
jsx: 'javascript',
|
|
47
|
+
ts: 'typescript',
|
|
48
|
+
tsx: 'typescript',
|
|
49
|
+
json: 'json',
|
|
50
|
+
html: 'html',
|
|
51
|
+
css: 'css',
|
|
52
|
+
scss: 'scss',
|
|
53
|
+
less: 'less',
|
|
54
|
+
md: 'markdown',
|
|
55
|
+
py: 'python',
|
|
56
|
+
sh: 'shell',
|
|
57
|
+
bash: 'shell',
|
|
58
|
+
ps1: 'powershell',
|
|
59
|
+
sql: 'sql',
|
|
60
|
+
yaml: 'yaml',
|
|
61
|
+
yml: 'yaml',
|
|
62
|
+
xml: 'xml',
|
|
63
|
+
rs: 'rust',
|
|
64
|
+
go: 'go',
|
|
65
|
+
java: 'java',
|
|
66
|
+
c: 'c',
|
|
67
|
+
cpp: 'cpp',
|
|
68
|
+
cs: 'csharp',
|
|
69
|
+
php: 'php'
|
|
70
|
+
}
|
|
71
|
+
return map[ext] || 'plaintext'
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const FileDiffModal = ({ isOpen = false, onClose, tool = '', query = null, onResolve }) => {
|
|
75
|
+
const [loading, setLoading] = useState(true)
|
|
76
|
+
const [originalContent, setOriginalContent] = useState('')
|
|
77
|
+
const [modifiedContent, setModifiedContent] = useState('')
|
|
78
|
+
const [filePath, setFilePath] = useState('')
|
|
79
|
+
const [isNewFile, setIsNewFile] = useState(false)
|
|
80
|
+
const [errorMessage, setErrorMessage] = useState('')
|
|
81
|
+
const isViewOnly = !onResolve || tool === 'read-file' || tool === 'view-artifact'
|
|
82
|
+
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (!isOpen) return
|
|
85
|
+
|
|
86
|
+
let isMounted = true
|
|
87
|
+
|
|
88
|
+
const loadDiff = async () => {
|
|
89
|
+
setLoading(true)
|
|
90
|
+
setErrorMessage('')
|
|
91
|
+
try {
|
|
92
|
+
const parsed = parseToolArgs(tool, query)
|
|
93
|
+
const targetPath = (parsed.path || parsed.filePath || parsed.target || '').trim()
|
|
94
|
+
setFilePath(targetPath)
|
|
95
|
+
|
|
96
|
+
if (!targetPath) {
|
|
97
|
+
if (isMounted) {
|
|
98
|
+
setErrorMessage('Path file tidak ditemukan dalam argumen tool.')
|
|
99
|
+
setLoading(false)
|
|
100
|
+
}
|
|
101
|
+
return
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
let original = ''
|
|
105
|
+
let exists = true
|
|
106
|
+
|
|
107
|
+
if (window.api?.executeNativeTool) {
|
|
108
|
+
const res = await window.api.executeNativeTool('read-file', {
|
|
109
|
+
path: targetPath,
|
|
110
|
+
raw: true
|
|
111
|
+
})
|
|
112
|
+
if (res && res.success) {
|
|
113
|
+
original = res.content || ''
|
|
114
|
+
exists = res.exists !== false
|
|
115
|
+
} else if (res && res.exists === false) {
|
|
116
|
+
original = ''
|
|
117
|
+
exists = false
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let modified = original
|
|
122
|
+
if (tool === 'write-file') {
|
|
123
|
+
modified =
|
|
124
|
+
typeof parsed.content === 'string'
|
|
125
|
+
? parsed.content
|
|
126
|
+
: JSON.stringify(parsed.content ?? '', null, 2)
|
|
127
|
+
} else if (tool === 'replace-content') {
|
|
128
|
+
const target = parsed.target_content ?? ''
|
|
129
|
+
const replacement = parsed.replacement_content ?? ''
|
|
130
|
+
if (original.includes(target)) {
|
|
131
|
+
modified = original.replace(target, replacement)
|
|
132
|
+
} else {
|
|
133
|
+
modified = original
|
|
134
|
+
}
|
|
135
|
+
} else if (tool === 'replace-lines') {
|
|
136
|
+
const startLine = parseInt(parsed.start_line, 10)
|
|
137
|
+
const endLine = parseInt(parsed.end_line, 10)
|
|
138
|
+
const newCode = parsed.new_code !== undefined ? parsed.new_code : parsed.content || ''
|
|
139
|
+
const lines = original.split('\n')
|
|
140
|
+
if (
|
|
141
|
+
!isNaN(startLine) &&
|
|
142
|
+
!isNaN(endLine) &&
|
|
143
|
+
startLine >= 1 &&
|
|
144
|
+
startLine <= lines.length &&
|
|
145
|
+
endLine >= startLine
|
|
146
|
+
) {
|
|
147
|
+
lines.splice(startLine - 1, endLine - startLine + 1, newCode)
|
|
148
|
+
modified = lines.join('\n')
|
|
149
|
+
}
|
|
150
|
+
} else if (tool === 'delete-file') {
|
|
151
|
+
modified = ''
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (isMounted) {
|
|
155
|
+
setOriginalContent(original)
|
|
156
|
+
setModifiedContent(modified)
|
|
157
|
+
setIsNewFile(!exists)
|
|
158
|
+
setLoading(false)
|
|
159
|
+
}
|
|
160
|
+
} catch (err) {
|
|
161
|
+
if (isMounted) {
|
|
162
|
+
setErrorMessage(`Gagal memuat perbandingan berkas: ${err.message}`)
|
|
163
|
+
setLoading(false)
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
loadDiff()
|
|
169
|
+
|
|
170
|
+
return () => {
|
|
171
|
+
isMounted = false
|
|
172
|
+
}
|
|
173
|
+
}, [isOpen, tool, query])
|
|
174
|
+
|
|
175
|
+
if (!isOpen) return null
|
|
176
|
+
|
|
177
|
+
const language = getLanguageFromPath(filePath)
|
|
178
|
+
const fileName = filePath
|
|
179
|
+
? filePath
|
|
180
|
+
.replace(/[\\/]+/g, '/')
|
|
181
|
+
.split('/')
|
|
182
|
+
.pop()
|
|
183
|
+
: ''
|
|
184
|
+
|
|
185
|
+
const modalContent = (
|
|
186
|
+
<div
|
|
187
|
+
className="fixed inset-0 z-[999999] flex items-center justify-center bg-black/75 backdrop-blur-sm p-4 sm:p-6 animate-[response-fade-in_0.15s_ease-out_forwards]"
|
|
188
|
+
onClick={onClose}
|
|
189
|
+
>
|
|
190
|
+
<div
|
|
191
|
+
className="bg-base-300 border border-white/10 rounded-xl shadow-2xl flex flex-col w-[94vw] max-w-5xl h-[85vh] overflow-hidden text-sm"
|
|
192
|
+
onClick={(e) => e.stopPropagation()}
|
|
193
|
+
>
|
|
194
|
+
{/* Header Informative */}
|
|
195
|
+
<div className="flex items-center justify-between px-4 py-3 bg-base-200/90 border-b border-white/10 shrink-0">
|
|
196
|
+
<div className="flex items-center gap-2.5 min-w-0">
|
|
197
|
+
<span className="font-semibold text-white truncate text-xs sm:text-sm">
|
|
198
|
+
Review Perubahan Berkas: {fileName}
|
|
199
|
+
</span>
|
|
200
|
+
{filePath && (
|
|
201
|
+
<span
|
|
202
|
+
className="text-[11px] font-mono text-white/40 truncate hidden sm:inline"
|
|
203
|
+
title={filePath}
|
|
204
|
+
>
|
|
205
|
+
({filePath})
|
|
206
|
+
</span>
|
|
207
|
+
)}
|
|
208
|
+
{isViewOnly ? (
|
|
209
|
+
<span className="bg-primary/20 text-primary border border-primary/30 px-2 py-0.5 rounded text-[11px] font-mono shrink-0">
|
|
210
|
+
Artefak Tahap
|
|
211
|
+
</span>
|
|
212
|
+
) : (
|
|
213
|
+
<>
|
|
214
|
+
{tool && (
|
|
215
|
+
<span className="bg-white/10 text-white/80 px-2 py-0.5 rounded text-[11px] font-mono shrink-0">
|
|
216
|
+
{tool}
|
|
217
|
+
</span>
|
|
218
|
+
)}
|
|
219
|
+
{isNewFile && (
|
|
220
|
+
<span className="bg-success/15 text-success px-2 py-0.5 rounded text-[11px] font-semibold shrink-0">
|
|
221
|
+
Berkas Baru
|
|
222
|
+
</span>
|
|
223
|
+
)}
|
|
224
|
+
{tool === 'delete-file' && (
|
|
225
|
+
<span className="bg-error/15 text-error px-2 py-0.5 rounded text-[11px] font-semibold shrink-0">
|
|
226
|
+
Hapus Berkas
|
|
227
|
+
</span>
|
|
228
|
+
)}
|
|
229
|
+
</>
|
|
230
|
+
)}
|
|
231
|
+
</div>
|
|
232
|
+
<button
|
|
233
|
+
type="button"
|
|
234
|
+
onClick={onClose}
|
|
235
|
+
className="btn btn-ghost btn-xs btn-circle text-white/60 hover:text-white"
|
|
236
|
+
title="Tutup"
|
|
237
|
+
>
|
|
238
|
+
<X className="w-4 h-4" />
|
|
239
|
+
</button>
|
|
240
|
+
</div>
|
|
241
|
+
|
|
242
|
+
{/* Diff Content Area */}
|
|
243
|
+
<div className="flex-1 relative overflow-hidden bg-[#1e1e1e]">
|
|
244
|
+
{loading ? (
|
|
245
|
+
<div className="absolute inset-0 flex items-center justify-center gap-2 text-white/60 text-xs font-mono">
|
|
246
|
+
<span className="loading loading-spinner loading-sm text-primary" />
|
|
247
|
+
<span>Memuat perbandingan berkas...</span>
|
|
248
|
+
</div>
|
|
249
|
+
) : errorMessage ? (
|
|
250
|
+
<div className="absolute inset-0 flex items-center justify-center p-4 text-error text-xs font-mono">
|
|
251
|
+
{errorMessage}
|
|
252
|
+
</div>
|
|
253
|
+
) : (
|
|
254
|
+
<DiffEditor
|
|
255
|
+
height="100%"
|
|
256
|
+
original={originalContent}
|
|
257
|
+
modified={modifiedContent}
|
|
258
|
+
language={language}
|
|
259
|
+
theme="vs-dark"
|
|
260
|
+
options={{
|
|
261
|
+
readOnly: true,
|
|
262
|
+
renderSideBySide: !isViewOnly,
|
|
263
|
+
minimap: { enabled: false },
|
|
264
|
+
fontSize: 12,
|
|
265
|
+
lineNumbers: 'on',
|
|
266
|
+
wordWrap: 'on',
|
|
267
|
+
automaticLayout: true,
|
|
268
|
+
scrollBeyondLastLine: false,
|
|
269
|
+
padding: { top: 8, bottom: 8 }
|
|
270
|
+
}}
|
|
271
|
+
/>
|
|
272
|
+
)}
|
|
273
|
+
</div>
|
|
274
|
+
|
|
275
|
+
{/* Footer Informative Actions */}
|
|
276
|
+
<div className="flex flex-wrap items-center justify-end px-4 py-3 bg-base-200/90 border-t border-white/10 shrink-0 gap-2">
|
|
277
|
+
{isViewOnly ? (
|
|
278
|
+
<div className="flex items-center gap-2">
|
|
279
|
+
<button
|
|
280
|
+
type="button"
|
|
281
|
+
onClick={onClose}
|
|
282
|
+
className="btn btn-primary btn-sm text-black font-semibold rounded-lg px-4 shadow-sm"
|
|
283
|
+
>
|
|
284
|
+
Tutup Pratinjau
|
|
285
|
+
</button>
|
|
286
|
+
</div>
|
|
287
|
+
) : (
|
|
288
|
+
<div className="flex items-center gap-2">
|
|
289
|
+
<button
|
|
290
|
+
type="button"
|
|
291
|
+
onClick={() => onResolve && onResolve('reject')}
|
|
292
|
+
className="btn btn-ghost btn-sm text-error/80 hover:text-error hover:bg-error/10 rounded-lg px-3"
|
|
293
|
+
>
|
|
294
|
+
Tolak
|
|
295
|
+
</button>
|
|
296
|
+
<button
|
|
297
|
+
type="button"
|
|
298
|
+
onClick={() => onResolve && onResolve('approve_session')}
|
|
299
|
+
className="btn btn-ghost btn-sm text-warning/80 hover:text-warning hover:bg-warning/10 rounded-lg px-3"
|
|
300
|
+
>
|
|
301
|
+
Izinkan Sesi Ini
|
|
302
|
+
</button>
|
|
303
|
+
<button
|
|
304
|
+
type="button"
|
|
305
|
+
onClick={() => onResolve && onResolve('approve_always')}
|
|
306
|
+
className="btn btn-ghost btn-sm text-white/40 hover:text-error hover:bg-error/10 rounded-lg px-3"
|
|
307
|
+
>
|
|
308
|
+
Izinkan Selamanya
|
|
309
|
+
</button>
|
|
310
|
+
<button
|
|
311
|
+
type="button"
|
|
312
|
+
onClick={() => onResolve && onResolve('approve_once')}
|
|
313
|
+
className="btn btn-primary btn-sm text-black font-semibold rounded-lg px-4 shadow-sm"
|
|
314
|
+
>
|
|
315
|
+
Izinkan Sekali
|
|
316
|
+
</button>
|
|
317
|
+
</div>
|
|
318
|
+
)}
|
|
319
|
+
</div>
|
|
320
|
+
</div>
|
|
321
|
+
</div>
|
|
322
|
+
)
|
|
323
|
+
|
|
324
|
+
if (typeof document === 'undefined') return null
|
|
325
|
+
return createPortal(modalContent, document.body)
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
export default FileDiffModal
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* <FollowUp label="..." query="..." />
|
|
5
|
+
* Komponen chip saran pertanyaan lanjutan
|
|
6
|
+
*/
|
|
7
|
+
export const FollowUp = React.memo(({ label, query, children, onClick }) => {
|
|
8
|
+
const displayLabel = label || children || query
|
|
9
|
+
if (!displayLabel) return null
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<button
|
|
13
|
+
type="button"
|
|
14
|
+
onClick={() => onClick && onClick(query || displayLabel)}
|
|
15
|
+
className="px-2.5 py-1 rounded-lg text-xs bg-white/5 hover:bg-primary/20 text-white/90 hover:text-primary border border-white/10 hover:border-primary/40 transition-all cursor-pointer text-left font-sans shadow-sm active:scale-95"
|
|
16
|
+
title={query || displayLabel}
|
|
17
|
+
>
|
|
18
|
+
{displayLabel}
|
|
19
|
+
</button>
|
|
20
|
+
)
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* <Suggestion label="..." query="..." />
|
|
25
|
+
* Komponen chip saran aksi/eksplorasi alternatif
|
|
26
|
+
*/
|
|
27
|
+
export const Suggestion = React.memo(({ label, query, children, onClick }) => {
|
|
28
|
+
const displayLabel = label || children || query
|
|
29
|
+
if (!displayLabel) return null
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<button
|
|
33
|
+
type="button"
|
|
34
|
+
onClick={() => onClick && onClick(query || displayLabel)}
|
|
35
|
+
className="px-2.5 py-1 rounded-lg text-xs bg-white/5 hover:bg-primary/20 text-white/90 hover:text-primary border border-white/10 hover:border-primary/40 transition-all cursor-pointer text-left font-sans shadow-sm active:scale-95"
|
|
36
|
+
title={query || displayLabel}
|
|
37
|
+
>
|
|
38
|
+
{displayLabel}
|
|
39
|
+
</button>
|
|
40
|
+
)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* <Elicitation label="..." query="..." />
|
|
45
|
+
* Komponen opsi jawaban/klarifikasi di dalam ElicitationsGroup
|
|
46
|
+
*/
|
|
47
|
+
export const Elicitation = React.memo(({ label, query, children, onClick }) => {
|
|
48
|
+
const displayLabel = label || children || query
|
|
49
|
+
if (!displayLabel) return null
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<button
|
|
53
|
+
type="button"
|
|
54
|
+
onClick={() => onClick && onClick(query || displayLabel)}
|
|
55
|
+
className="px-3 py-1.5 rounded-lg text-xs bg-primary/10 hover:bg-primary/25 text-primary border border-primary/30 hover:border-primary/60 transition-all cursor-pointer text-left font-sans shadow-sm active:scale-95 font-medium"
|
|
56
|
+
title={query || displayLabel}
|
|
57
|
+
>
|
|
58
|
+
{displayLabel}
|
|
59
|
+
</button>
|
|
60
|
+
)
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* <ElicitationsGroup message="..."> ... </ElicitationsGroup>
|
|
65
|
+
* Kontainer grup klarifikasi ketika percakapan butuh percabangan pilihan
|
|
66
|
+
*/
|
|
67
|
+
export const ElicitationsGroup = React.memo(({ message, children }) => {
|
|
68
|
+
if (!children) return null
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<div className="mt-2 pt-2.5 border-t border-white/10 flex flex-col gap-2 animate-fade-in bg-base-300/40 p-2.5 rounded-xl border border-white/5">
|
|
72
|
+
{message && (
|
|
73
|
+
<span className="text-xs font-semibold text-primary">
|
|
74
|
+
{message}
|
|
75
|
+
</span>
|
|
76
|
+
)}
|
|
77
|
+
<div className="flex flex-wrap gap-1.5">
|
|
78
|
+
{children}
|
|
79
|
+
</div>
|
|
80
|
+
</div>
|
|
81
|
+
)
|
|
82
|
+
})
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Database, PlusCircle, Edit3, Trash2 } from 'lucide-react'
|
|
3
|
+
|
|
4
|
+
export const MemoryFooterBubble = ({
|
|
5
|
+
isMemorySaved = false,
|
|
6
|
+
isMemoryUpdated = false,
|
|
7
|
+
isMemoryDeleted = false
|
|
8
|
+
}) => {
|
|
9
|
+
if (!isMemorySaved && !isMemoryUpdated && !isMemoryDeleted) return null
|
|
10
|
+
|
|
11
|
+
return (
|
|
12
|
+
<div className="flex items-center gap-1.5 mt-1 px-1 text-[10px] font-medium opacity-80 select-none">
|
|
13
|
+
<Database className="w-3 h-3 text-secondary" />
|
|
14
|
+
{isMemorySaved && (
|
|
15
|
+
<span className="text-success flex items-center gap-1">
|
|
16
|
+
<PlusCircle className="w-2.5 h-2.5" />
|
|
17
|
+
Memori baru tersimpan
|
|
18
|
+
</span>
|
|
19
|
+
)}
|
|
20
|
+
{isMemoryUpdated && (
|
|
21
|
+
<span className="text-info flex items-center gap-1">
|
|
22
|
+
<Edit3 className="w-2.5 h-2.5" />
|
|
23
|
+
Memori diperbarui
|
|
24
|
+
</span>
|
|
25
|
+
)}
|
|
26
|
+
{isMemoryDeleted && (
|
|
27
|
+
<span className="text-error flex items-center gap-1">
|
|
28
|
+
<Trash2 className="w-2.5 h-2.5" />
|
|
29
|
+
Memori dihapus
|
|
30
|
+
</span>
|
|
31
|
+
)}
|
|
32
|
+
</div>
|
|
33
|
+
)
|
|
34
|
+
}
|