Update agents, dashboard, kb +2 more (+6 ~11)
This commit is contained in:
100
dashboard/api.py
100
dashboard/api.py
@@ -108,6 +108,8 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
self.handle_activity()
|
||||
elif self.path.startswith('/api/files'):
|
||||
self.handle_files_get()
|
||||
elif self.path.startswith('/api/diff'):
|
||||
self.handle_git_diff()
|
||||
elif self.path.startswith('/api/'):
|
||||
self.send_error(404)
|
||||
else:
|
||||
@@ -155,6 +157,14 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
cwd=workspace, capture_output=True, text=True, timeout=5
|
||||
).stdout.strip()
|
||||
|
||||
# Parse uncommitted into structured format
|
||||
uncommitted_parsed = []
|
||||
for line in uncommitted:
|
||||
if len(line) >= 3:
|
||||
status = line[:2].strip()
|
||||
filepath = line[3:].strip()
|
||||
uncommitted_parsed.append({'status': status, 'path': filepath})
|
||||
|
||||
self.send_json({
|
||||
'branch': branch,
|
||||
'lastCommit': {
|
||||
@@ -163,6 +173,7 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
'time': commit_parts[2] if len(commit_parts) > 2 else ''
|
||||
},
|
||||
'uncommitted': uncommitted,
|
||||
'uncommittedParsed': uncommitted_parsed,
|
||||
'uncommittedCount': len(uncommitted),
|
||||
'diffStat': diff_stat,
|
||||
'clean': len(uncommitted) == 0
|
||||
@@ -170,6 +181,60 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
except Exception as e:
|
||||
self.send_json({'error': str(e)}, 500)
|
||||
|
||||
def handle_git_diff(self):
|
||||
"""Get git diff for a specific file."""
|
||||
from urllib.parse import urlparse, parse_qs
|
||||
parsed = urlparse(self.path)
|
||||
params = parse_qs(parsed.query)
|
||||
|
||||
filepath = params.get('path', [''])[0]
|
||||
|
||||
if not filepath:
|
||||
self.send_json({'error': 'path required'}, 400)
|
||||
return
|
||||
|
||||
try:
|
||||
workspace = Path('/home/moltbot/clawd')
|
||||
|
||||
# Security check
|
||||
target = (workspace / filepath).resolve()
|
||||
if not str(target).startswith(str(workspace)):
|
||||
self.send_json({'error': 'Access denied'}, 403)
|
||||
return
|
||||
|
||||
# Get diff (try staged first, then unstaged)
|
||||
diff = subprocess.run(
|
||||
['git', 'diff', '--cached', '--', filepath],
|
||||
cwd=workspace, capture_output=True, text=True, timeout=10
|
||||
).stdout
|
||||
|
||||
if not diff:
|
||||
diff = subprocess.run(
|
||||
['git', 'diff', '--', filepath],
|
||||
cwd=workspace, capture_output=True, text=True, timeout=10
|
||||
).stdout
|
||||
|
||||
# If still no diff, file might be untracked - show full content
|
||||
if not diff:
|
||||
status = subprocess.run(
|
||||
['git', 'status', '--short', '--', filepath],
|
||||
cwd=workspace, capture_output=True, text=True, timeout=5
|
||||
).stdout.strip()
|
||||
|
||||
if status.startswith('??'):
|
||||
# Untracked file - show as new
|
||||
if target.exists():
|
||||
content = target.read_text(encoding='utf-8', errors='replace')[:50000]
|
||||
diff = f"+++ b/{filepath}\n" + '\n'.join(f'+{line}' for line in content.split('\n'))
|
||||
|
||||
self.send_json({
|
||||
'path': filepath,
|
||||
'diff': diff or 'No changes',
|
||||
'hasDiff': bool(diff)
|
||||
})
|
||||
except Exception as e:
|
||||
self.send_json({'error': str(e)}, 500)
|
||||
|
||||
def handle_agents_status(self):
|
||||
"""Get agents status - fast version reading session files directly."""
|
||||
try:
|
||||
@@ -361,11 +426,44 @@ class TaskBoardHandler(SimpleHTTPRequestHandler):
|
||||
'text': message[:60] + ('...' if len(message) > 60 else ''),
|
||||
'agent': 'git',
|
||||
'time': local_time.strftime('%H:%M'),
|
||||
'timestamp': timestamp * 1000
|
||||
'timestamp': timestamp * 1000,
|
||||
'commitHash': commit_hash[:8]
|
||||
})
|
||||
except:
|
||||
pass
|
||||
|
||||
# 2b. Git uncommitted files
|
||||
try:
|
||||
result = subprocess.run(
|
||||
['git', 'status', '--short'],
|
||||
cwd=workspace, capture_output=True, text=True, timeout=10
|
||||
)
|
||||
if result.returncode == 0 and result.stdout.strip():
|
||||
for line in result.stdout.strip().split('\n'):
|
||||
if len(line) >= 4:
|
||||
# Git status format: XY filename (XY = 2 chars status)
|
||||
# Handle both "M " and " M" formats
|
||||
status = line[:2]
|
||||
# Find filepath - skip status chars and any spaces
|
||||
filepath = line[2:].lstrip()
|
||||
if not filepath:
|
||||
continue
|
||||
status_clean = status.strip()
|
||||
status_labels = {'M': 'modificat', 'A': 'adăugat', 'D': 'șters', '??': 'nou', 'R': 'redenumit'}
|
||||
status_label = status_labels.get(status_clean, status_clean)
|
||||
activities.append({
|
||||
'type': 'git-file',
|
||||
'icon': 'file-diff',
|
||||
'text': f"{filepath}",
|
||||
'agent': f"git ({status_label})",
|
||||
'time': 'acum',
|
||||
'timestamp': int(datetime.now().timestamp() * 1000),
|
||||
'path': filepath,
|
||||
'gitStatus': status_clean
|
||||
})
|
||||
except:
|
||||
pass
|
||||
|
||||
# 3. Recent files in kb/ (last 24h)
|
||||
try:
|
||||
kb_dir = workspace / 'kb'
|
||||
|
||||
Reference in New Issue
Block a user