aicodeman 0.2.8
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 +21 -0
- package/README.md +403 -0
- package/dist/ai-checker-base.d.ts +175 -0
- package/dist/ai-checker-base.d.ts.map +1 -0
- package/dist/ai-checker-base.js +424 -0
- package/dist/ai-checker-base.js.map +1 -0
- package/dist/ai-idle-checker.d.ts +53 -0
- package/dist/ai-idle-checker.d.ts.map +1 -0
- package/dist/ai-idle-checker.js +141 -0
- package/dist/ai-idle-checker.js.map +1 -0
- package/dist/ai-plan-checker.d.ts +52 -0
- package/dist/ai-plan-checker.d.ts.map +1 -0
- package/dist/ai-plan-checker.js +103 -0
- package/dist/ai-plan-checker.js.map +1 -0
- package/dist/bash-tool-parser.d.ts +191 -0
- package/dist/bash-tool-parser.d.ts.map +1 -0
- package/dist/bash-tool-parser.js +598 -0
- package/dist/bash-tool-parser.js.map +1 -0
- package/dist/cli.d.ts +12 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +460 -0
- package/dist/cli.js.map +1 -0
- package/dist/config/buffer-limits.d.ts +59 -0
- package/dist/config/buffer-limits.d.ts.map +1 -0
- package/dist/config/buffer-limits.js +74 -0
- package/dist/config/buffer-limits.js.map +1 -0
- package/dist/config/map-limits.d.ts +40 -0
- package/dist/config/map-limits.d.ts.map +1 -0
- package/dist/config/map-limits.js +52 -0
- package/dist/config/map-limits.js.map +1 -0
- package/dist/file-stream-manager.d.ts +148 -0
- package/dist/file-stream-manager.d.ts.map +1 -0
- package/dist/file-stream-manager.js +351 -0
- package/dist/file-stream-manager.js.map +1 -0
- package/dist/hooks-config.d.ts +31 -0
- package/dist/hooks-config.d.ts.map +1 -0
- package/dist/hooks-config.js +115 -0
- package/dist/hooks-config.js.map +1 -0
- package/dist/image-watcher.d.ts +86 -0
- package/dist/image-watcher.d.ts.map +1 -0
- package/dist/image-watcher.js +275 -0
- package/dist/image-watcher.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +54 -0
- package/dist/index.js.map +1 -0
- package/dist/mux-factory.d.ts +13 -0
- package/dist/mux-factory.d.ts.map +1 -0
- package/dist/mux-factory.js +19 -0
- package/dist/mux-factory.js.map +1 -0
- package/dist/mux-interface.d.ts +145 -0
- package/dist/mux-interface.d.ts.map +1 -0
- package/dist/mux-interface.js +9 -0
- package/dist/mux-interface.js.map +1 -0
- package/dist/plan-orchestrator.d.ts +123 -0
- package/dist/plan-orchestrator.d.ts.map +1 -0
- package/dist/plan-orchestrator.js +500 -0
- package/dist/plan-orchestrator.js.map +1 -0
- package/dist/prompts/index.d.ts +9 -0
- package/dist/prompts/index.d.ts.map +1 -0
- package/dist/prompts/index.js +9 -0
- package/dist/prompts/index.js.map +1 -0
- package/dist/prompts/planner.d.ts +14 -0
- package/dist/prompts/planner.d.ts.map +1 -0
- package/dist/prompts/planner.js +83 -0
- package/dist/prompts/planner.js.map +1 -0
- package/dist/prompts/research-agent.d.ts +10 -0
- package/dist/prompts/research-agent.d.ts.map +1 -0
- package/dist/prompts/research-agent.js +143 -0
- package/dist/prompts/research-agent.js.map +1 -0
- package/dist/push-store.d.ts +41 -0
- package/dist/push-store.d.ts.map +1 -0
- package/dist/push-store.js +168 -0
- package/dist/push-store.js.map +1 -0
- package/dist/ralph-config.d.ts +67 -0
- package/dist/ralph-config.d.ts.map +1 -0
- package/dist/ralph-config.js +134 -0
- package/dist/ralph-config.js.map +1 -0
- package/dist/ralph-loop.d.ts +124 -0
- package/dist/ralph-loop.d.ts.map +1 -0
- package/dist/ralph-loop.js +418 -0
- package/dist/ralph-loop.js.map +1 -0
- package/dist/ralph-tracker.d.ts +1081 -0
- package/dist/ralph-tracker.d.ts.map +1 -0
- package/dist/ralph-tracker.js +3343 -0
- package/dist/ralph-tracker.js.map +1 -0
- package/dist/respawn-controller.d.ts +1182 -0
- package/dist/respawn-controller.d.ts.map +1 -0
- package/dist/respawn-controller.js +2754 -0
- package/dist/respawn-controller.js.map +1 -0
- package/dist/run-summary.d.ts +123 -0
- package/dist/run-summary.d.ts.map +1 -0
- package/dist/run-summary.js +325 -0
- package/dist/run-summary.js.map +1 -0
- package/dist/session-lifecycle-log.d.ts +36 -0
- package/dist/session-lifecycle-log.d.ts.map +1 -0
- package/dist/session-lifecycle-log.js +101 -0
- package/dist/session-lifecycle-log.js.map +1 -0
- package/dist/session-manager.d.ts +97 -0
- package/dist/session-manager.d.ts.map +1 -0
- package/dist/session-manager.js +224 -0
- package/dist/session-manager.js.map +1 -0
- package/dist/session.d.ts +686 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +2025 -0
- package/dist/session.js.map +1 -0
- package/dist/state-store.d.ts +189 -0
- package/dist/state-store.d.ts.map +1 -0
- package/dist/state-store.js +730 -0
- package/dist/state-store.js.map +1 -0
- package/dist/subagent-watcher.d.ts +345 -0
- package/dist/subagent-watcher.d.ts.map +1 -0
- package/dist/subagent-watcher.js +1469 -0
- package/dist/subagent-watcher.js.map +1 -0
- package/dist/task-queue.d.ts +108 -0
- package/dist/task-queue.d.ts.map +1 -0
- package/dist/task-queue.js +235 -0
- package/dist/task-queue.js.map +1 -0
- package/dist/task-tracker.d.ts +306 -0
- package/dist/task-tracker.d.ts.map +1 -0
- package/dist/task-tracker.js +488 -0
- package/dist/task-tracker.js.map +1 -0
- package/dist/task.d.ts +73 -0
- package/dist/task.d.ts.map +1 -0
- package/dist/task.js +177 -0
- package/dist/task.js.map +1 -0
- package/dist/team-watcher.d.ts +53 -0
- package/dist/team-watcher.d.ts.map +1 -0
- package/dist/team-watcher.js +313 -0
- package/dist/team-watcher.js.map +1 -0
- package/dist/templates/case-template.md +461 -0
- package/dist/templates/claude-md.d.ts +26 -0
- package/dist/templates/claude-md.d.ts.map +1 -0
- package/dist/templates/claude-md.js +74 -0
- package/dist/templates/claude-md.js.map +1 -0
- package/dist/tmux-manager.d.ts +181 -0
- package/dist/tmux-manager.d.ts.map +1 -0
- package/dist/tmux-manager.js +1405 -0
- package/dist/tmux-manager.js.map +1 -0
- package/dist/transcript-watcher.d.ts +110 -0
- package/dist/transcript-watcher.d.ts.map +1 -0
- package/dist/transcript-watcher.js +338 -0
- package/dist/transcript-watcher.js.map +1 -0
- package/dist/tunnel-manager.d.ts +54 -0
- package/dist/tunnel-manager.d.ts.map +1 -0
- package/dist/tunnel-manager.js +251 -0
- package/dist/tunnel-manager.js.map +1 -0
- package/dist/types.d.ts +1139 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +215 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/buffer-accumulator.d.ts +111 -0
- package/dist/utils/buffer-accumulator.d.ts.map +1 -0
- package/dist/utils/buffer-accumulator.js +172 -0
- package/dist/utils/buffer-accumulator.js.map +1 -0
- package/dist/utils/claude-cli-resolver.d.ts +26 -0
- package/dist/utils/claude-cli-resolver.d.ts.map +1 -0
- package/dist/utils/claude-cli-resolver.js +78 -0
- package/dist/utils/claude-cli-resolver.js.map +1 -0
- package/dist/utils/cleanup-manager.d.ts +165 -0
- package/dist/utils/cleanup-manager.d.ts.map +1 -0
- package/dist/utils/cleanup-manager.js +274 -0
- package/dist/utils/cleanup-manager.js.map +1 -0
- package/dist/utils/index.d.ts +19 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +19 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/lru-map.d.ts +140 -0
- package/dist/utils/lru-map.d.ts.map +1 -0
- package/dist/utils/lru-map.js +234 -0
- package/dist/utils/lru-map.js.map +1 -0
- package/dist/utils/nice-wrapper.d.ts +13 -0
- package/dist/utils/nice-wrapper.d.ts.map +1 -0
- package/dist/utils/nice-wrapper.js +17 -0
- package/dist/utils/nice-wrapper.js.map +1 -0
- package/dist/utils/opencode-cli-resolver.d.ts +21 -0
- package/dist/utils/opencode-cli-resolver.d.ts.map +1 -0
- package/dist/utils/opencode-cli-resolver.js +67 -0
- package/dist/utils/opencode-cli-resolver.js.map +1 -0
- package/dist/utils/regex-patterns.d.ts +64 -0
- package/dist/utils/regex-patterns.d.ts.map +1 -0
- package/dist/utils/regex-patterns.js +74 -0
- package/dist/utils/regex-patterns.js.map +1 -0
- package/dist/utils/stale-expiration-map.d.ts +159 -0
- package/dist/utils/stale-expiration-map.d.ts.map +1 -0
- package/dist/utils/stale-expiration-map.js +277 -0
- package/dist/utils/stale-expiration-map.js.map +1 -0
- package/dist/utils/string-similarity.d.ts +108 -0
- package/dist/utils/string-similarity.d.ts.map +1 -0
- package/dist/utils/string-similarity.js +189 -0
- package/dist/utils/string-similarity.js.map +1 -0
- package/dist/utils/token-validation.d.ts +39 -0
- package/dist/utils/token-validation.d.ts.map +1 -0
- package/dist/utils/token-validation.js +59 -0
- package/dist/utils/token-validation.js.map +1 -0
- package/dist/utils/type-safety.d.ts +33 -0
- package/dist/utils/type-safety.d.ts.map +1 -0
- package/dist/utils/type-safety.js +35 -0
- package/dist/utils/type-safety.js.map +1 -0
- package/dist/web/public/app.js +491 -0
- package/dist/web/public/app.js.br +0 -0
- package/dist/web/public/app.js.gz +0 -0
- package/dist/web/public/index.html +1675 -0
- package/dist/web/public/index.html.br +0 -0
- package/dist/web/public/index.html.gz +0 -0
- package/dist/web/public/manifest.json +8 -0
- package/dist/web/public/mobile.css +1 -0
- package/dist/web/public/mobile.css.br +0 -0
- package/dist/web/public/mobile.css.gz +0 -0
- package/dist/web/public/ralph-wizard.js +1037 -0
- package/dist/web/public/ralph-wizard.js.br +0 -0
- package/dist/web/public/ralph-wizard.js.gz +0 -0
- package/dist/web/public/styles.css +1 -0
- package/dist/web/public/styles.css.br +0 -0
- package/dist/web/public/styles.css.gz +0 -0
- package/dist/web/public/sw.js +67 -0
- package/dist/web/public/sw.js.br +0 -0
- package/dist/web/public/sw.js.gz +0 -0
- package/dist/web/public/upload.html +155 -0
- package/dist/web/public/upload.html.br +0 -0
- package/dist/web/public/upload.html.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js +1 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.br +0 -0
- package/dist/web/public/vendor/xterm-addon-fit.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js +1 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.br +0 -0
- package/dist/web/public/vendor/xterm-addon-unicode11.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js +2 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.br +0 -0
- package/dist/web/public/vendor/xterm-addon-webgl.min.js.gz +0 -0
- package/dist/web/public/vendor/xterm.css +209 -0
- package/dist/web/public/vendor/xterm.css.br +0 -0
- package/dist/web/public/vendor/xterm.css.gz +0 -0
- package/dist/web/public/vendor/xterm.min.js +9 -0
- package/dist/web/public/vendor/xterm.min.js.br +0 -0
- package/dist/web/public/vendor/xterm.min.js.gz +0 -0
- package/dist/web/schemas.d.ts +479 -0
- package/dist/web/schemas.d.ts.map +1 -0
- package/dist/web/schemas.js +448 -0
- package/dist/web/schemas.js.map +1 -0
- package/dist/web/server.d.ts +207 -0
- package/dist/web/server.d.ts.map +1 -0
- package/dist/web/server.js +5784 -0
- package/dist/web/server.js.map +1 -0
- package/package.json +110 -0
- package/scripts/postinstall.js +390 -0
|
@@ -0,0 +1,1675 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
|
6
|
+
<meta name="description" content="Claude Code session manager with web interface">
|
|
7
|
+
<meta name="theme-color" content="#0a0a0a">
|
|
8
|
+
<meta name="google" content="notranslate">
|
|
9
|
+
<link rel="manifest" href="manifest.json">
|
|
10
|
+
<title>Codeman</title>
|
|
11
|
+
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cdefs%3E%3ClinearGradient id='g' x1='0%25' y1='0%25' x2='100%25' y2='100%25'%3E%3Cstop offset='0%25' stop-color='%2360a5fa'/%3E%3Cstop offset='100%25' stop-color='%233b82f6'/%3E%3C/linearGradient%3E%3C/defs%3E%3Crect width='32' height='32' rx='6' fill='%230a0a0a'/%3E%3Cpath d='M18 4L8 18h6l-2 10 10-14h-6z' fill='url(%23g)'/%3E%3C/svg%3E">
|
|
12
|
+
<link rel="stylesheet" href="styles.css?v=0.1631">
|
|
13
|
+
<link rel="stylesheet" href="mobile.css?v=0.1631" media="(max-width: 1023px)">
|
|
14
|
+
<!-- xterm.css loaded async — terminal won't display until xterm.js runs anyway -->
|
|
15
|
+
<link rel="preload" href="vendor/xterm.css" as="style" onload="this.onload=null;this.rel='stylesheet'">
|
|
16
|
+
<noscript><link rel="stylesheet" href="vendor/xterm.css"></noscript>
|
|
17
|
+
<!-- Self-hosted xterm.js — eliminates CDN DNS/TLS latency (~100ms).
|
|
18
|
+
'defer' preserves execution order (xterm loads before fit addon). -->
|
|
19
|
+
<script defer src="vendor/xterm.min.js"></script>
|
|
20
|
+
<script defer src="vendor/xterm-addon-fit.min.js"></script>
|
|
21
|
+
<script defer src="vendor/xterm-addon-webgl.min.js"></script>
|
|
22
|
+
<script defer src="vendor/xterm-addon-unicode11.min.js"></script>
|
|
23
|
+
<!-- Synchronous mobile detection — runs before first paint to prevent panel flash -->
|
|
24
|
+
<script>if(window.innerWidth<768||(('ontouchstart' in window||navigator.maxTouchPoints>0)&&window.innerWidth<1024))document.documentElement.classList.add('mobile-init');</script>
|
|
25
|
+
<!-- Inline critical CSS for instant skeleton paint (before styles.css loads) -->
|
|
26
|
+
<style>
|
|
27
|
+
.loading-skeleton{display:flex;flex-direction:column;height:100vh;background:#0a0a0a}
|
|
28
|
+
.skeleton-header{height:40px;background:#111;border-bottom:1px solid #1a1a2e;display:flex;align-items:center;padding:0 12px}
|
|
29
|
+
.skeleton-brand{color:#60a5fa;font-size:14px;font-weight:600;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',sans-serif;opacity:.7}
|
|
30
|
+
.skeleton-tabs{display:flex;gap:4px;margin-left:16px}
|
|
31
|
+
.skeleton-tab{width:80px;height:24px;background:#1a1a2e;border-radius:4px}
|
|
32
|
+
.skeleton-terminal{flex:1;background:#0d0d0d}
|
|
33
|
+
.skeleton-toolbar{height:32px;background:#111;border-top:1px solid #1a1a2e}
|
|
34
|
+
.app-loaded .loading-skeleton{display:none}
|
|
35
|
+
</style>
|
|
36
|
+
</head>
|
|
37
|
+
<body>
|
|
38
|
+
<!-- Loading skeleton — visible instantly before CSS/JS loads, hidden by app-loaded class -->
|
|
39
|
+
<div class="loading-skeleton">
|
|
40
|
+
<div class="skeleton-header">
|
|
41
|
+
<span class="skeleton-brand">Codeman</span>
|
|
42
|
+
<div class="skeleton-tabs"><div class="skeleton-tab"></div></div>
|
|
43
|
+
</div>
|
|
44
|
+
<div class="skeleton-terminal"></div>
|
|
45
|
+
<div class="skeleton-toolbar"></div>
|
|
46
|
+
</div>
|
|
47
|
+
<!-- Skip link for keyboard users -->
|
|
48
|
+
<a href="#terminalContainer" class="skip-link">Skip to terminal</a>
|
|
49
|
+
<div class="app">
|
|
50
|
+
<!-- Compact Header with Session Tabs -->
|
|
51
|
+
<header class="header">
|
|
52
|
+
<div class="header-brand">
|
|
53
|
+
<span class="logo" onclick="app.goHome()" title="Go to main page">Codeman</span>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<!-- Session Tabs -->
|
|
57
|
+
<div class="session-tabs" id="sessionTabs" role="tablist" aria-label="Session tabs">
|
|
58
|
+
</div>
|
|
59
|
+
|
|
60
|
+
<div class="header-right">
|
|
61
|
+
<div class="connection-indicator" id="connectionIndicator" style="display: none;">
|
|
62
|
+
<span class="connection-dot" id="connectionDot"></span>
|
|
63
|
+
<span class="connection-text" id="connectionText"></span>
|
|
64
|
+
</div>
|
|
65
|
+
<div class="header-font-controls">
|
|
66
|
+
<button class="btn-icon-header btn-sm" onclick="app.decreaseFontSize()" title="Decrease font (Ctrl+-)" aria-label="Decrease font size">A-</button>
|
|
67
|
+
<span class="font-size-display" id="fontSizeDisplay" aria-label="Current font size">14</span>
|
|
68
|
+
<button class="btn-icon-header btn-sm" onclick="app.increaseFontSize()" title="Increase font (Ctrl++)" aria-label="Increase font size">A+</button>
|
|
69
|
+
</div>
|
|
70
|
+
<div class="header-system-stats" id="headerSystemStats" title="System resource usage">
|
|
71
|
+
<div class="stat-item">
|
|
72
|
+
<span class="stat-label">CPU</span>
|
|
73
|
+
<div class="stat-bar">
|
|
74
|
+
<div class="stat-bar-fill stat-bar-cpu" id="statCpuBar"></div>
|
|
75
|
+
</div>
|
|
76
|
+
<span class="stat-value" id="statCpu">--%</span>
|
|
77
|
+
</div>
|
|
78
|
+
<div class="stat-item">
|
|
79
|
+
<span class="stat-label">MEM</span>
|
|
80
|
+
<div class="stat-bar">
|
|
81
|
+
<div class="stat-bar-fill stat-bar-mem" id="statMemBar"></div>
|
|
82
|
+
</div>
|
|
83
|
+
<span class="stat-value" id="statMem">--</span>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
<button class="btn-icon-header btn-notifications" onclick="app.toggleNotifications()" title="Notifications" aria-label="Toggle notifications">
|
|
87
|
+
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M18 8A6 6 0 0 0 6 8c0 7-3 9-3 9h18s-3-2-3-9"/><path d="M13.73 21a2 2 0 0 1-3.46 0"/></svg>
|
|
88
|
+
<span class="notification-badge" id="notifBadge" style="display:none;">0</span>
|
|
89
|
+
</button>
|
|
90
|
+
<button class="btn-icon-header btn-lifecycle-log" onclick="app.openLifecycleLog()" title="Session Lifecycle Log" aria-label="Open session lifecycle log"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"/><polyline points="14 2 14 8 20 8"/><line x1="16" y1="13" x2="8" y2="13"/><line x1="16" y1="17" x2="8" y2="17"/><polyline points="10 9 9 9 8 9"/></svg></button>
|
|
91
|
+
<button class="btn-icon-header btn-settings" onclick="app.openAppSettings()" title="App Settings" aria-label="Open app settings"><svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg></button>
|
|
92
|
+
<div class="header-tokens" id="headerTokens" title="Total tokens across all sessions">0 tokens</div>
|
|
93
|
+
</div>
|
|
94
|
+
</header>
|
|
95
|
+
|
|
96
|
+
<!-- Timer Banner (shown when timed run is active) -->
|
|
97
|
+
<div class="timer-banner" id="timerBanner" style="display: none;">
|
|
98
|
+
<div class="timer-content">
|
|
99
|
+
<span class="timer-value" id="timerValue">00:00:00</span>
|
|
100
|
+
<div class="timer-progress"><div class="timer-progress-fill" id="timerProgress"></div></div>
|
|
101
|
+
<span class="timer-meta" id="timerMeta">0 tasks | $0.00</span>
|
|
102
|
+
</div>
|
|
103
|
+
<button class="btn-icon-only" onclick="app.stopCurrentRun()" title="Stop" aria-label="Stop current run">■</button>
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<!-- Respawn Banner - Compact 2-column layout -->
|
|
107
|
+
<div class="respawn-banner" id="respawnBanner" style="display: none;">
|
|
108
|
+
<div class="respawn-compact-layout">
|
|
109
|
+
<div class="respawn-status-col">
|
|
110
|
+
<div class="respawn-status-row1">
|
|
111
|
+
<span class="respawn-indicator">↻</span>
|
|
112
|
+
<span class="respawn-state" id="respawnState">Watching</span>
|
|
113
|
+
<span class="detection-confidence" id="detectionConfidence"></span>
|
|
114
|
+
<span class="respawn-cycles">#<span id="respawnCycleCount">0</span></span>
|
|
115
|
+
<span class="respawn-timer" id="respawnTimer" style="display: none;"></span>
|
|
116
|
+
<span class="respawn-tokens" id="respawnTokens" style="display: none;"></span>
|
|
117
|
+
<button class="btn-icon-only" onclick="app.stopRespawn()" title="Stop Respawn" aria-label="Stop respawn">■</button>
|
|
118
|
+
</div>
|
|
119
|
+
<div class="respawn-status-row2" id="respawnStatusRow2">
|
|
120
|
+
<span class="detection-hook" id="detectionHook" style="display: none;"></span>
|
|
121
|
+
<span class="detection-ai-check" id="detectionAiCheck" style="display: none;"></span>
|
|
122
|
+
<span class="detection-status" id="detectionStatus"></span>
|
|
123
|
+
<span class="detection-waiting" id="detectionWaiting" style="display: none;"></span>
|
|
124
|
+
<div class="respawn-countdown-timers" id="respawnCountdownTimers"></div>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
<div class="respawn-action-log" id="respawnActionLog"></div>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
|
|
131
|
+
<!-- Ralph / Todo Tracker Panel -->
|
|
132
|
+
<div class="ralph-panel collapsed" id="ralphStatePanel" style="display: none;">
|
|
133
|
+
<!-- Collapsed Summary Bar -->
|
|
134
|
+
<div class="ralph-summary" id="ralphSummary">
|
|
135
|
+
<div class="ralph-summary-content" onclick="app.toggleRalphStatePanel()">
|
|
136
|
+
<div class="ralph-ring-mini" id="ralphRingMini">
|
|
137
|
+
<svg viewBox="0 0 36 36" class="ralph-ring-svg">
|
|
138
|
+
<defs>
|
|
139
|
+
<linearGradient id="ralphGradientMini" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
140
|
+
<stop offset="0%" stop-color="#3b82f6" />
|
|
141
|
+
<stop offset="100%" stop-color="#22c55e" />
|
|
142
|
+
</linearGradient>
|
|
143
|
+
</defs>
|
|
144
|
+
<circle class="ralph-ring-bg" cx="18" cy="18" r="15.9" />
|
|
145
|
+
<circle class="ralph-ring-progress-mini" cx="18" cy="18" r="15.9" id="ralphRingMiniProgress" style="stroke-dashoffset: 100" />
|
|
146
|
+
</svg>
|
|
147
|
+
<span class="ralph-ring-text" id="ralphRingMiniText">0%</span>
|
|
148
|
+
</div>
|
|
149
|
+
<div class="ralph-summary-info">
|
|
150
|
+
<span class="ralph-title">Ralph / Todo Tracker</span>
|
|
151
|
+
<span class="ralph-status-badge" id="ralphStatusBadge">
|
|
152
|
+
<span class="ralph-status-dot"></span>
|
|
153
|
+
<span class="ralph-status-text">Idle</span>
|
|
154
|
+
</span>
|
|
155
|
+
</div>
|
|
156
|
+
<div class="ralph-summary-stats">
|
|
157
|
+
<span class="ralph-stat"><span class="ralph-stat-icon">⏱</span><span id="ralphStatTime">0m</span></span>
|
|
158
|
+
<span class="ralph-stat"><span class="ralph-stat-icon">✓</span><span id="ralphStatTasks">0/0</span></span>
|
|
159
|
+
</div>
|
|
160
|
+
<span class="ralph-toggle" id="ralphToggle">▼</span>
|
|
161
|
+
</div>
|
|
162
|
+
<div class="ralph-controls">
|
|
163
|
+
<div class="ralph-menu-container">
|
|
164
|
+
<button class="btn-icon-sm" onclick="event.stopPropagation(); app.toggleRalphMenu()" title="Fix Plan Menu" id="ralphMenuBtn">☰</button>
|
|
165
|
+
<div class="ralph-dropdown" id="ralphDropdown">
|
|
166
|
+
<button onclick="event.stopPropagation(); app.showFixPlan(); app.closeRalphMenu()">View Fix Plan</button>
|
|
167
|
+
<button onclick="event.stopPropagation(); app.writeFixPlanToFile(); app.closeRalphMenu()">Write to File</button>
|
|
168
|
+
<button onclick="event.stopPropagation(); app.importFixPlanFromFile(); app.closeRalphMenu()">Import from File</button>
|
|
169
|
+
<hr>
|
|
170
|
+
<button onclick="event.stopPropagation(); app.resetCircuitBreaker(); app.closeRalphMenu()">Reset Circuit Breaker</button>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
<button class="btn-icon-sm" onclick="event.stopPropagation(); app.toggleRalphDetach()" title="Detach/Attach panel" id="ralphDetachBtn">⧉</button>
|
|
174
|
+
<button class="btn-icon-sm" onclick="event.stopPropagation(); app.closeRalphTracker()" title="Close tracker">×</button>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
|
|
178
|
+
<!-- Expanded Detail View - Compact horizontal layout -->
|
|
179
|
+
<div class="ralph-detail" id="ralphDetail">
|
|
180
|
+
<div class="ralph-detail-row">
|
|
181
|
+
<!-- Progress Ring -->
|
|
182
|
+
<div class="ralph-ring-compact">
|
|
183
|
+
<svg viewBox="0 0 100 100" class="ralph-ring-svg-large">
|
|
184
|
+
<defs>
|
|
185
|
+
<linearGradient id="ralphGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
|
186
|
+
<stop offset="0%" stop-color="#3b82f6" />
|
|
187
|
+
<stop offset="100%" stop-color="#22c55e" />
|
|
188
|
+
</linearGradient>
|
|
189
|
+
</defs>
|
|
190
|
+
<circle class="ralph-ring-track" cx="50" cy="50" r="42" />
|
|
191
|
+
<circle class="ralph-ring-fill" cx="50" cy="50" r="42" id="ralphRingProgress" style="stroke-dashoffset: 264" />
|
|
192
|
+
</svg>
|
|
193
|
+
<div class="ralph-ring-center">
|
|
194
|
+
<div class="ralph-ring-percent" id="ralphRingPercent">0%</div>
|
|
195
|
+
<div class="ralph-ring-label">Complete</div>
|
|
196
|
+
</div>
|
|
197
|
+
</div>
|
|
198
|
+
<!-- Meta Info + Tasks unified -->
|
|
199
|
+
<div class="ralph-info-unified">
|
|
200
|
+
<div class="ralph-info-labels">
|
|
201
|
+
<div class="ralph-info-row">
|
|
202
|
+
<span class="ralph-info-label">Tasks</span>
|
|
203
|
+
<span class="ralph-tasks-count" id="ralphTasksCount">0/0</span>
|
|
204
|
+
</div>
|
|
205
|
+
<div class="ralph-info-row">
|
|
206
|
+
<span class="ralph-info-label">Phrase</span>
|
|
207
|
+
<code id="ralphPhrase">--</code>
|
|
208
|
+
</div>
|
|
209
|
+
<div class="ralph-info-row">
|
|
210
|
+
<span class="ralph-info-label">Elapsed</span>
|
|
211
|
+
<span id="ralphElapsed">0m</span>
|
|
212
|
+
</div>
|
|
213
|
+
<div class="ralph-info-row" id="ralphVersionRow" style="display: none;">
|
|
214
|
+
<span class="ralph-info-label">Plan</span>
|
|
215
|
+
<div class="ralph-version-info">
|
|
216
|
+
<span class="version-badge" id="ralphPlanVersion">v1</span>
|
|
217
|
+
<button class="rollback-btn" id="ralphRollbackBtn" onclick="app.showPlanHistory()" title="View history">history</button>
|
|
218
|
+
</div>
|
|
219
|
+
</div>
|
|
220
|
+
</div>
|
|
221
|
+
<div class="ralph-tasks-grid" id="ralphTasksGrid"></div>
|
|
222
|
+
</div>
|
|
223
|
+
</div>
|
|
224
|
+
</div>
|
|
225
|
+
|
|
226
|
+
</div>
|
|
227
|
+
|
|
228
|
+
<!-- Main Terminal Area -->
|
|
229
|
+
<main class="main">
|
|
230
|
+
<div class="terminal-container" id="terminalContainer"></div>
|
|
231
|
+
|
|
232
|
+
<!-- Welcome Overlay (shown when no session active) -->
|
|
233
|
+
<div class="welcome-overlay" id="welcomeOverlay">
|
|
234
|
+
<div class="welcome-content">
|
|
235
|
+
<h1 class="welcome-title">Codeman</h1>
|
|
236
|
+
<p class="welcome-desc">Manage AI Coding tools in persistent tmux sessions.</p>
|
|
237
|
+
<div class="welcome-actions">
|
|
238
|
+
<button class="welcome-btn welcome-btn-claude" onclick="app.setRunMode('claude'); app.runClaude()">
|
|
239
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
|
240
|
+
Run Claude Code
|
|
241
|
+
</button>
|
|
242
|
+
<button class="welcome-btn welcome-btn-tunnel" id="welcomeTunnelBtn" onclick="app.toggleTunnelFromWelcome()">
|
|
243
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 2L2 7l10 5 10-5-10-5z"/><path d="M2 17l10 5 10-5"/><path d="M2 12l10 5 10-5"/></svg>
|
|
244
|
+
Cloudflare Tunnel
|
|
245
|
+
</button>
|
|
246
|
+
<button class="welcome-btn welcome-btn-opencode" onclick="app.setRunMode('opencode'); app.runOpenCode()">
|
|
247
|
+
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
|
248
|
+
Run OpenCode
|
|
249
|
+
</button>
|
|
250
|
+
</div>
|
|
251
|
+
<div class="welcome-qr" id="welcomeQr" onclick="app.toggleWelcomeQrSize()">
|
|
252
|
+
<div class="welcome-qr-inner" id="welcomeQrInner"></div>
|
|
253
|
+
<div class="welcome-qr-url" id="welcomeQrUrl"></div>
|
|
254
|
+
</div>
|
|
255
|
+
<p class="welcome-hint">Or press <kbd>Ctrl</kbd>+<kbd>Enter</kbd> to start</p>
|
|
256
|
+
<button class="welcome-ralph-link" onclick="app.showRalphWizard()">Start Ralph Loop →</button>
|
|
257
|
+
</div>
|
|
258
|
+
</div>
|
|
259
|
+
</main>
|
|
260
|
+
|
|
261
|
+
<!-- Project Insights Panel (shows file-viewing Bash commands) -->
|
|
262
|
+
<div class="project-insights-panel" id="projectInsightsPanel">
|
|
263
|
+
<div class="project-insights-header">
|
|
264
|
+
<span class="project-insights-title">Project Insights</span>
|
|
265
|
+
<button class="btn-icon-sm" onclick="app.closeProjectInsightsPanel()" title="Close">×</button>
|
|
266
|
+
</div>
|
|
267
|
+
<div class="project-insights-body" id="projectInsightsList"></div>
|
|
268
|
+
<div class="project-insights-resize-handle"></div>
|
|
269
|
+
</div>
|
|
270
|
+
|
|
271
|
+
<!-- File Browser Panel -->
|
|
272
|
+
<div class="file-browser-panel" id="fileBrowserPanel">
|
|
273
|
+
<div class="file-browser-header">
|
|
274
|
+
<span class="file-browser-title">Files</span>
|
|
275
|
+
<div class="file-browser-actions">
|
|
276
|
+
<button class="btn-icon-sm" onclick="app.refreshFileBrowser()" title="Refresh">↻</button>
|
|
277
|
+
<button class="btn-icon-sm" onclick="app.toggleFileBrowserExpand()" title="Expand/Collapse All" id="fileBrowserExpandBtn">⊞</button>
|
|
278
|
+
<button class="btn-icon-sm" onclick="app.closeFileBrowserPanel()" title="Close">×</button>
|
|
279
|
+
</div>
|
|
280
|
+
</div>
|
|
281
|
+
<div class="file-browser-search">
|
|
282
|
+
<input type="text" id="fileBrowserSearch" placeholder="Filter files..." oninput="app.filterFileBrowser(this.value)">
|
|
283
|
+
</div>
|
|
284
|
+
<div class="file-browser-body" id="fileBrowserTree">
|
|
285
|
+
<div class="file-browser-empty">Select a session to view files</div>
|
|
286
|
+
</div>
|
|
287
|
+
<div class="file-browser-status" id="fileBrowserStatus"></div>
|
|
288
|
+
</div>
|
|
289
|
+
|
|
290
|
+
<!-- File Preview Overlay -->
|
|
291
|
+
<div class="file-preview-overlay" id="filePreviewOverlay">
|
|
292
|
+
<div class="file-preview-window">
|
|
293
|
+
<div class="file-preview-header">
|
|
294
|
+
<span class="file-preview-title" id="filePreviewTitle">file.ts</span>
|
|
295
|
+
<div class="file-preview-actions">
|
|
296
|
+
<button class="btn-icon-sm" onclick="app.copyFilePreviewContent()" title="Copy content">⎘</button>
|
|
297
|
+
<button class="btn-icon-sm" onclick="app.closeFilePreview()" title="Close">×</button>
|
|
298
|
+
</div>
|
|
299
|
+
</div>
|
|
300
|
+
<div class="file-preview-body" id="filePreviewBody"></div>
|
|
301
|
+
<div class="file-preview-footer" id="filePreviewFooter"></div>
|
|
302
|
+
</div>
|
|
303
|
+
</div>
|
|
304
|
+
|
|
305
|
+
<!-- Bottom Toolbar -->
|
|
306
|
+
<footer class="toolbar">
|
|
307
|
+
<div class="toolbar-left">
|
|
308
|
+
<!-- Run AI -->
|
|
309
|
+
<div class="toolbar-group">
|
|
310
|
+
<div class="run-btn-group">
|
|
311
|
+
<button class="btn-toolbar btn-run" id="runBtn" onclick="app.run()" title="Run (Ctrl+Enter)">
|
|
312
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5"><polygon points="5 3 19 12 5 21 5 3"/></svg>
|
|
313
|
+
<span id="runBtnLabel">Run</span>
|
|
314
|
+
</button>
|
|
315
|
+
<button class="btn-toolbar btn-run-gear" onclick="app.toggleRunModeMenu(event)" title="Select AI backend">
|
|
316
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M6 9l6 6 6-6"/></svg>
|
|
317
|
+
</button>
|
|
318
|
+
<div class="run-mode-menu" id="runModeMenu">
|
|
319
|
+
<button class="run-mode-option" data-mode="claude" onclick="app.setRunMode('claude')">
|
|
320
|
+
<span class="run-mode-dot claude"></span>Claude Code
|
|
321
|
+
</button>
|
|
322
|
+
<button class="run-mode-option" data-mode="opencode" onclick="app.setRunMode('opencode')">
|
|
323
|
+
<span class="run-mode-dot opencode"></span>OpenCode
|
|
324
|
+
</button>
|
|
325
|
+
</div>
|
|
326
|
+
</div>
|
|
327
|
+
<div class="tab-count-group" title="Instance count">
|
|
328
|
+
<button class="tab-count-btn" onclick="app.decrementTabCount()">−</button>
|
|
329
|
+
<input type="number" id="tabCount" class="tab-count-input" value="1" min="1" max="20" readonly>
|
|
330
|
+
<button class="tab-count-btn" onclick="app.incrementTabCount()">+</button>
|
|
331
|
+
</div>
|
|
332
|
+
<button class="btn-toolbar btn-stop" onclick="app.stopClaude()" title="Stop (Ctrl+C)">
|
|
333
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="currentColor"><rect x="4" y="4" width="16" height="16" rx="2"/></svg>
|
|
334
|
+
</button>
|
|
335
|
+
<button class="btn-toolbar btn-shell" onclick="app.runShell()" title="Run Shell">
|
|
336
|
+
Run Shell
|
|
337
|
+
</button>
|
|
338
|
+
<div class="tab-count-group" title="Instance count">
|
|
339
|
+
<button class="tab-count-btn" onclick="app.decrementShellCount()">−</button>
|
|
340
|
+
<input type="number" id="shellCount" class="tab-count-input" value="1" min="1" max="20" readonly>
|
|
341
|
+
<button class="tab-count-btn" onclick="app.incrementShellCount()">+</button>
|
|
342
|
+
</div>
|
|
343
|
+
<div class="case-select-group">
|
|
344
|
+
<select id="quickStartCase" class="toolbar-select" title="Select case">
|
|
345
|
+
<option value="testcase">testcase</option>
|
|
346
|
+
</select>
|
|
347
|
+
<button class="btn-case-add" onclick="app.showCreateCaseModal()" title="Create new case">+</button>
|
|
348
|
+
<button class="btn-case-settings" onclick="app.toggleCaseSettings()" title="Case settings">⚙</button>
|
|
349
|
+
<div class="case-settings-popover hidden" id="caseSettingsPopover">
|
|
350
|
+
<label class="checkbox-inline">
|
|
351
|
+
<input type="checkbox" id="caseAgentTeams" onchange="app.onCaseSettingChanged()">
|
|
352
|
+
<span>Agent Teams</span>
|
|
353
|
+
</label>
|
|
354
|
+
<span class="form-hint">Enable experimental Agent Teams for new sessions in this case</span>
|
|
355
|
+
</div>
|
|
356
|
+
</div>
|
|
357
|
+
<!-- Mobile-only case button + gear -->
|
|
358
|
+
<button class="btn-voice-mobile" id="voiceInputBtnMobile" onclick="VoiceInput.toggle()"
|
|
359
|
+
title="Voice input" aria-label="Start voice input" aria-pressed="false">
|
|
360
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
361
|
+
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
|
|
362
|
+
<path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
|
|
363
|
+
<line x1="12" y1="19" x2="12" y2="23"/>
|
|
364
|
+
<line x1="8" y1="23" x2="16" y2="23"/>
|
|
365
|
+
</svg>
|
|
366
|
+
</button>
|
|
367
|
+
<button class="btn-settings-mobile" onclick="app.openAppSettings()" title="App Settings">⚙</button>
|
|
368
|
+
<button class="btn-toolbar btn-case-mobile" onclick="app.showMobileCasePicker()" title="Select case">
|
|
369
|
+
<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"/></svg>
|
|
370
|
+
<span id="mobileCaseName">Case</span>
|
|
371
|
+
</button>
|
|
372
|
+
<button class="btn-case-settings-mobile" id="btnCaseSettingsMobile" onclick="app.toggleCaseSettingsMobile()" title="Case settings"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="3"/><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1-2.83 2.83l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-4 0v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83-2.83l.06-.06A1.65 1.65 0 0 0 4.68 15a1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1 0-4h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 2.83-2.83l.06.06A1.65 1.65 0 0 0 9 4.68a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 4 0v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 2.83l-.06.06A1.65 1.65 0 0 0 19.4 9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 0 4h-.09a1.65 1.65 0 0 0-1.51 1z"/></svg></button>
|
|
373
|
+
<div class="case-settings-popover-mobile hidden" id="caseSettingsPopoverMobile">
|
|
374
|
+
<label class="checkbox-inline">
|
|
375
|
+
<input type="checkbox" id="caseAgentTeamsMobile" onchange="app.onCaseSettingChangedMobile()">
|
|
376
|
+
<span>Agent Teams</span>
|
|
377
|
+
</label>
|
|
378
|
+
<span class="form-hint">Enable Agent Teams for new sessions</span>
|
|
379
|
+
</div>
|
|
380
|
+
</div>
|
|
381
|
+
|
|
382
|
+
<!-- Directory (hidden) -->
|
|
383
|
+
<div class="toolbar-group" style="display: none;">
|
|
384
|
+
<button class="btn-toolbar" onclick="app.toggleDirInput()" title="Set working directory">
|
|
385
|
+
<span id="dirDisplay">No directory</span>
|
|
386
|
+
</button>
|
|
387
|
+
<input type="text" id="dirInput" class="toolbar-input hidden" placeholder="Working directory..." onblur="app.hideDirInput()">
|
|
388
|
+
</div>
|
|
389
|
+
</div>
|
|
390
|
+
|
|
391
|
+
<div class="toolbar-center">
|
|
392
|
+
<button class="btn-toolbar btn-sm btn-voice" id="voiceInputBtn" onclick="VoiceInput.toggle()"
|
|
393
|
+
title="Voice input (Ctrl+Shift+V)" aria-label="Start voice input" aria-pressed="false">
|
|
394
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
395
|
+
<path d="M12 1a3 3 0 0 0-3 3v8a3 3 0 0 0 6 0V4a3 3 0 0 0-3-3z"/>
|
|
396
|
+
<path d="M19 10v2a7 7 0 0 1-14 0v-2"/>
|
|
397
|
+
<line x1="12" y1="19" x2="12" y2="23"/>
|
|
398
|
+
<line x1="8" y1="23" x2="16" y2="23"/>
|
|
399
|
+
</svg>
|
|
400
|
+
</button>
|
|
401
|
+
</div>
|
|
402
|
+
|
|
403
|
+
<div class="toolbar-right">
|
|
404
|
+
<span class="version-display" id="versionDisplay" title="Codeman version">v0.0.0</span>
|
|
405
|
+
</div>
|
|
406
|
+
</footer>
|
|
407
|
+
|
|
408
|
+
<!-- Help Modal -->
|
|
409
|
+
<div class="modal" id="helpModal">
|
|
410
|
+
<div class="modal-backdrop" onclick="app.closeHelp()"></div>
|
|
411
|
+
<div class="modal-content">
|
|
412
|
+
<div class="modal-header">
|
|
413
|
+
<h3>Keyboard Shortcuts</h3>
|
|
414
|
+
<button class="modal-close" onclick="app.closeHelp()" aria-label="Close help">×</button>
|
|
415
|
+
</div>
|
|
416
|
+
<div class="modal-body">
|
|
417
|
+
<div class="shortcuts-grid">
|
|
418
|
+
<div><kbd>Ctrl</kbd>+<kbd>Enter</kbd></div><div>Run Claude</div>
|
|
419
|
+
<div><kbd>Ctrl</kbd>+<kbd>W</kbd></div><div>Close Session</div>
|
|
420
|
+
<div><kbd>Ctrl</kbd>+<kbd>Tab</kbd></div><div>Next Session</div>
|
|
421
|
+
<div><kbd>Ctrl</kbd>+<kbd>K</kbd></div><div>Kill All Sessions + Tmux</div>
|
|
422
|
+
<div><kbd>Ctrl</kbd>+<kbd>L</kbd></div><div>Clear Terminal</div>
|
|
423
|
+
<div><kbd>Ctrl</kbd>+<kbd>+</kbd></div><div>Increase Font</div>
|
|
424
|
+
<div><kbd>Ctrl</kbd>+<kbd>-</kbd></div><div>Decrease Font</div>
|
|
425
|
+
<div><kbd>Ctrl</kbd>+<kbd>?</kbd></div><div>Show Help</div>
|
|
426
|
+
<div><kbd>Ctrl</kbd>+<kbd>Shift</kbd>+<kbd>V</kbd></div><div>Voice Input</div>
|
|
427
|
+
<div><kbd>Escape</kbd></div><div>Close Panels</div>
|
|
428
|
+
</div>
|
|
429
|
+
</div>
|
|
430
|
+
</div>
|
|
431
|
+
</div>
|
|
432
|
+
|
|
433
|
+
<!-- Monitor Panel (Tmux Sessions + Background Tasks) -->
|
|
434
|
+
<div class="monitor-panel" id="monitorPanel">
|
|
435
|
+
<div class="monitor-panel-header" id="monitorPanelHeader">
|
|
436
|
+
<div class="monitor-panel-title">Monitor</div>
|
|
437
|
+
<div class="monitor-panel-actions">
|
|
438
|
+
<button class="btn-toolbar btn-sm btn-danger" onclick="app.killAllSessions()" title="Kill all sessions and their tmux processes">Kill All</button>
|
|
439
|
+
<button class="btn-icon-sm" onclick="app.reconcileMuxSessions()" title="Refresh tmux sessions">↻</button>
|
|
440
|
+
<button class="btn-icon-sm" onclick="app.toggleMonitorDetach()" title="Detach panel" id="monitorDetachBtn">⧉</button>
|
|
441
|
+
<button class="btn-icon-sm" onclick="app.toggleMonitorPanel()" title="Toggle panel" id="monitorToggleBtn">▲</button>
|
|
442
|
+
<button class="btn-icon-sm" onclick="app.closeMonitor()" title="Close monitor">×</button>
|
|
443
|
+
</div>
|
|
444
|
+
</div>
|
|
445
|
+
<div class="monitor-resize-handle" id="monitorResizeHandle"></div>
|
|
446
|
+
<div class="monitor-panel-body" id="monitorTabContent">
|
|
447
|
+
<div class="monitor-section">
|
|
448
|
+
<div class="monitor-section-header">
|
|
449
|
+
<span>Tmux Sessions</span>
|
|
450
|
+
</div>
|
|
451
|
+
<div class="monitor-section-body" id="muxSessionsBody">
|
|
452
|
+
<div class="monitor-empty">No mux sessions</div>
|
|
453
|
+
</div>
|
|
454
|
+
</div>
|
|
455
|
+
<div class="monitor-section" id="monitorPlanAgentsSection" style="display: none;">
|
|
456
|
+
<div class="monitor-section-header">
|
|
457
|
+
<span>Plan Wizard Agents</span>
|
|
458
|
+
<span class="task-stats" id="monitorPlanAgentStats">0 active</span>
|
|
459
|
+
<button class="btn-toolbar btn-sm btn-danger" onclick="app.cancelPlanFromMonitor()" title="Cancel plan generation">Cancel</button>
|
|
460
|
+
</div>
|
|
461
|
+
<div class="monitor-section-body" id="monitorPlanAgentsBody">
|
|
462
|
+
<div class="monitor-empty">No plan agents</div>
|
|
463
|
+
</div>
|
|
464
|
+
</div>
|
|
465
|
+
<div class="monitor-section" id="monitorSubagentsSection">
|
|
466
|
+
<div class="monitor-section-header">
|
|
467
|
+
<span>Background Agents</span>
|
|
468
|
+
<span class="task-stats" id="monitorSubagentStats">0 tracked</span>
|
|
469
|
+
<button class="btn-toolbar btn-sm btn-danger" onclick="app.clearAllSubagents()" title="Clear all">Clear</button>
|
|
470
|
+
</div>
|
|
471
|
+
<div class="monitor-section-body" id="monitorSubagentsBody">
|
|
472
|
+
<div class="monitor-empty">No background agents</div>
|
|
473
|
+
</div>
|
|
474
|
+
</div>
|
|
475
|
+
<div class="monitor-section" id="backgroundTasksSection" style="display: none;">
|
|
476
|
+
<div class="monitor-section-header">
|
|
477
|
+
<span>Background Tasks</span>
|
|
478
|
+
<span class="task-stats" id="taskPanelStats">0 running</span>
|
|
479
|
+
</div>
|
|
480
|
+
<div class="monitor-section-body" id="backgroundTasksBody">
|
|
481
|
+
</div>
|
|
482
|
+
</div>
|
|
483
|
+
</div>
|
|
484
|
+
</div>
|
|
485
|
+
|
|
486
|
+
<!-- Subagents Panel (separate from Monitor) -->
|
|
487
|
+
<div class="subagents-panel" id="subagentsPanel">
|
|
488
|
+
<div class="subagents-panel-header" id="subagentsPanelHeader">
|
|
489
|
+
<div class="subagents-panel-title">
|
|
490
|
+
Subagents <span id="subagentCountBadge" class="subagent-badge"></span>
|
|
491
|
+
</div>
|
|
492
|
+
<div class="subagents-panel-actions">
|
|
493
|
+
<button class="btn-toolbar btn-sm btn-danger" onclick="app.clearAllSubagents()" title="Clear all tracked subagents">Clear All</button>
|
|
494
|
+
<button class="btn-icon-sm" onclick="app.toggleSubagentsDetach()" title="Detach panel" id="subagentsDetachBtn">⧉</button>
|
|
495
|
+
<button class="btn-icon-sm" onclick="app.toggleSubagentsPanel()" title="Toggle panel" id="subagentsToggleBtn">▲</button>
|
|
496
|
+
<button class="btn-icon-sm" onclick="app.closeSubagentsPanel()" title="Close">×</button>
|
|
497
|
+
</div>
|
|
498
|
+
</div>
|
|
499
|
+
<div class="subagents-resize-handle" id="subagentsResizeHandle"></div>
|
|
500
|
+
<div class="subagents-panel-body" id="subagentsTabContent">
|
|
501
|
+
<div class="subagent-container">
|
|
502
|
+
<div class="subagent-list" id="subagentList">
|
|
503
|
+
<div class="subagent-empty">No background agents detected</div>
|
|
504
|
+
</div>
|
|
505
|
+
<div class="subagent-detail" id="subagentDetail">
|
|
506
|
+
<div class="subagent-empty">Select an agent to view details</div>
|
|
507
|
+
</div>
|
|
508
|
+
</div>
|
|
509
|
+
</div>
|
|
510
|
+
</div>
|
|
511
|
+
|
|
512
|
+
<!-- Session Options Modal (includes Respawn Settings) -->
|
|
513
|
+
<div class="modal" id="sessionOptionsModal">
|
|
514
|
+
<div class="modal-backdrop" onclick="app.closeSessionOptions()"></div>
|
|
515
|
+
<div class="modal-content">
|
|
516
|
+
<div class="modal-header">
|
|
517
|
+
<h3>Session Options</h3>
|
|
518
|
+
<button class="modal-close" onclick="app.closeSessionOptions()" aria-label="Close session options">×</button>
|
|
519
|
+
</div>
|
|
520
|
+
<!-- Modal Tabs -->
|
|
521
|
+
<div class="modal-tabs">
|
|
522
|
+
<button class="modal-tab-btn active" data-tab="respawn" data-claude-only onclick="app.switchOptionsTab('respawn')">Respawn</button>
|
|
523
|
+
<button class="modal-tab-btn" data-tab="context" onclick="app.switchOptionsTab('context')">Context</button>
|
|
524
|
+
<button class="modal-tab-btn" data-tab="ralph" data-claude-only onclick="app.switchOptionsTab('ralph')">Ralph / Todo</button>
|
|
525
|
+
<button class="modal-tab-btn" data-tab="summary" onclick="app.switchOptionsTab('summary')">Summary</button>
|
|
526
|
+
</div>
|
|
527
|
+
<div class="modal-body">
|
|
528
|
+
<!-- Respawn Tab Content -->
|
|
529
|
+
<div class="modal-tab-content" id="respawn-tab">
|
|
530
|
+
<!-- Respawn Settings Section -->
|
|
531
|
+
<div class="session-respawn-section" id="sessionRespawnSection">
|
|
532
|
+
<div class="respawn-header">
|
|
533
|
+
<div class="session-respawn-status" id="sessionRespawnStatus">
|
|
534
|
+
<span class="respawn-status-indicator"></span>
|
|
535
|
+
<span class="respawn-status-text">Not active</span>
|
|
536
|
+
</div>
|
|
537
|
+
<div class="respawn-actions">
|
|
538
|
+
<button class="btn-toolbar btn-success btn-sm" onclick="app.enableRespawnFromModal()" id="modalEnableRespawnBtn">Enable</button>
|
|
539
|
+
<button class="btn-toolbar btn-danger btn-sm" onclick="app.stopRespawnFromModal()" id="modalStopRespawnBtn" style="display: none;">Stop</button>
|
|
540
|
+
</div>
|
|
541
|
+
</div>
|
|
542
|
+
|
|
543
|
+
<div class="form-row">
|
|
544
|
+
<label>Duration</label>
|
|
545
|
+
<div class="duration-presets">
|
|
546
|
+
<button type="button" class="duration-preset-btn" data-minutes="30" onclick="app.selectDurationPreset('30')">30m</button>
|
|
547
|
+
<button type="button" class="duration-preset-btn" data-minutes="60" onclick="app.selectDurationPreset('60')">1h</button>
|
|
548
|
+
<button type="button" class="duration-preset-btn" data-minutes="120" onclick="app.selectDurationPreset('120')">2h</button>
|
|
549
|
+
<button type="button" class="duration-preset-btn" data-minutes="240" onclick="app.selectDurationPreset('240')">4h</button>
|
|
550
|
+
<button type="button" class="duration-preset-btn" data-minutes="480" onclick="app.selectDurationPreset('480')">8h</button>
|
|
551
|
+
<button type="button" class="duration-preset-btn active" data-minutes="" onclick="app.selectDurationPreset('')">∞</button>
|
|
552
|
+
<div class="duration-custom">
|
|
553
|
+
<button type="button" class="duration-preset-btn" data-minutes="custom" onclick="app.selectDurationPreset('custom')">Custom</button>
|
|
554
|
+
<div class="input-suffix input-suffix-sm duration-custom-input">
|
|
555
|
+
<input type="number" id="modalRespawnDuration" value="" min="1" placeholder="min">
|
|
556
|
+
<span>min</span>
|
|
557
|
+
</div>
|
|
558
|
+
</div>
|
|
559
|
+
</div>
|
|
560
|
+
</div>
|
|
561
|
+
|
|
562
|
+
<div class="form-section-header">Presets</div>
|
|
563
|
+
<div class="form-row">
|
|
564
|
+
<label>Load Preset</label>
|
|
565
|
+
<div class="preset-selector">
|
|
566
|
+
<select id="respawnPresetSelect" onchange="app.updatePresetDescription()">
|
|
567
|
+
<option value="">-- Select preset --</option>
|
|
568
|
+
<optgroup label="Built-in" id="builtinPresetsGroup">
|
|
569
|
+
</optgroup>
|
|
570
|
+
<optgroup label="Custom" id="customPresetsGroup">
|
|
571
|
+
</optgroup>
|
|
572
|
+
</select>
|
|
573
|
+
<button type="button" class="btn btn-sm" onclick="app.loadRespawnPreset()" title="Apply preset">Apply</button>
|
|
574
|
+
<button type="button" class="btn btn-sm btn-secondary" onclick="app.saveCurrentAsPreset()" title="Save current config as preset">Save As...</button>
|
|
575
|
+
</div>
|
|
576
|
+
<p class="form-hint" id="presetDescriptionHint"></p>
|
|
577
|
+
</div>
|
|
578
|
+
|
|
579
|
+
<div class="form-section-header">Respawn Cycle</div>
|
|
580
|
+
<div class="form-row">
|
|
581
|
+
<label>1. Update Prompt</label>
|
|
582
|
+
<textarea id="modalRespawnPrompt" rows="3" placeholder="Prompt to send when idle" onchange="app.autoSaveRespawnConfig()" style="resize: vertical; min-height: 60px;">update all the docs and CLAUDE.md</textarea>
|
|
583
|
+
</div>
|
|
584
|
+
|
|
585
|
+
<div class="respawn-options-row" style="margin: 8px 0;">
|
|
586
|
+
<label class="checkbox-inline">
|
|
587
|
+
<input type="checkbox" id="modalRespawnSendClear" checked onchange="app.autoSaveRespawnConfig()">
|
|
588
|
+
<span>2. Send /clear</span>
|
|
589
|
+
</label>
|
|
590
|
+
<label class="checkbox-inline">
|
|
591
|
+
<input type="checkbox" id="modalRespawnSendInit" checked onchange="app.autoSaveRespawnConfig()">
|
|
592
|
+
<span>3. Send /init</span>
|
|
593
|
+
</label>
|
|
594
|
+
</div>
|
|
595
|
+
|
|
596
|
+
<div class="form-row">
|
|
597
|
+
<label>4. Kickstart Prompt</label>
|
|
598
|
+
<textarea id="modalRespawnKickstart" rows="2" placeholder="Optional: prompt if /init doesn't trigger work" onchange="app.autoSaveRespawnConfig()" style="resize: vertical; min-height: 40px;"></textarea>
|
|
599
|
+
<span class="form-hint">Sent only when /init completes but Claude stays idle</span>
|
|
600
|
+
</div>
|
|
601
|
+
|
|
602
|
+
<div class="form-section-header">Behavior</div>
|
|
603
|
+
<div class="respawn-options-row">
|
|
604
|
+
<label class="checkbox-inline">
|
|
605
|
+
<input type="checkbox" id="modalRespawnAutoAccept" checked onchange="app.autoSaveRespawnConfig()">
|
|
606
|
+
<span>Auto-accept prompts</span>
|
|
607
|
+
</label>
|
|
608
|
+
</div>
|
|
609
|
+
<span class="form-hint">Auto-accept presses Enter for plan approvals and default question options</span>
|
|
610
|
+
</div>
|
|
611
|
+
</div><!-- End respawn-tab -->
|
|
612
|
+
|
|
613
|
+
<!-- Context Management Tab Content -->
|
|
614
|
+
<div class="modal-tab-content hidden" id="context-tab">
|
|
615
|
+
<div class="form-section-header">Appearance</div>
|
|
616
|
+
<div class="form-row">
|
|
617
|
+
<label>Session Name</label>
|
|
618
|
+
<input type="text" id="modalSessionName" maxlength="128" placeholder="Auto (directory name)" onblur="app.saveSessionName()">
|
|
619
|
+
<span class="form-hint">Custom name shown in the tab (right-click tab to rename inline)</span>
|
|
620
|
+
</div>
|
|
621
|
+
<div class="form-row">
|
|
622
|
+
<label>Session Color</label>
|
|
623
|
+
<div class="color-picker" id="sessionColorPicker">
|
|
624
|
+
<button type="button" class="color-swatch" data-color="default" title="Default">
|
|
625
|
+
<span class="swatch-inner" style="background: var(--bg-hover)"></span>
|
|
626
|
+
</button>
|
|
627
|
+
<button type="button" class="color-swatch" data-color="red" title="Red">
|
|
628
|
+
<span class="swatch-inner" style="background: var(--session-red)"></span>
|
|
629
|
+
</button>
|
|
630
|
+
<button type="button" class="color-swatch" data-color="orange" title="Orange">
|
|
631
|
+
<span class="swatch-inner" style="background: var(--session-orange)"></span>
|
|
632
|
+
</button>
|
|
633
|
+
<button type="button" class="color-swatch" data-color="yellow" title="Yellow">
|
|
634
|
+
<span class="swatch-inner" style="background: var(--session-yellow)"></span>
|
|
635
|
+
</button>
|
|
636
|
+
<button type="button" class="color-swatch" data-color="green" title="Green">
|
|
637
|
+
<span class="swatch-inner" style="background: var(--session-green)"></span>
|
|
638
|
+
</button>
|
|
639
|
+
<button type="button" class="color-swatch" data-color="blue" title="Blue">
|
|
640
|
+
<span class="swatch-inner" style="background: var(--session-blue)"></span>
|
|
641
|
+
</button>
|
|
642
|
+
<button type="button" class="color-swatch" data-color="purple" title="Purple">
|
|
643
|
+
<span class="swatch-inner" style="background: var(--session-purple)"></span>
|
|
644
|
+
</button>
|
|
645
|
+
<button type="button" class="color-swatch" data-color="pink" title="Pink">
|
|
646
|
+
<span class="swatch-inner" style="background: var(--session-pink)"></span>
|
|
647
|
+
</button>
|
|
648
|
+
</div>
|
|
649
|
+
</div>
|
|
650
|
+
|
|
651
|
+
<div class="form-section-header">Token Management</div>
|
|
652
|
+
<div class="context-settings-grid">
|
|
653
|
+
<div class="context-setting">
|
|
654
|
+
<div class="context-setting-header">
|
|
655
|
+
<label class="checkbox-inline">
|
|
656
|
+
<input type="checkbox" id="modalAutoCompactEnabled" onchange="app.autoSaveAutoCompact()">
|
|
657
|
+
<span>Auto-Compact</span>
|
|
658
|
+
</label>
|
|
659
|
+
<div class="input-suffix input-suffix-sm">
|
|
660
|
+
<input type="number" id="modalAutoCompactThreshold" value="110000" min="10000" max="500000" step="10000" onchange="app.autoSaveAutoCompact()">
|
|
661
|
+
<span>tokens</span>
|
|
662
|
+
</div>
|
|
663
|
+
</div>
|
|
664
|
+
<input type="text" id="modalAutoCompactPrompt" value="" placeholder="Focus prompt (optional)" onchange="app.autoSaveAutoCompact()">
|
|
665
|
+
<span class="form-hint">Summarizes context while preserving key information</span>
|
|
666
|
+
</div>
|
|
667
|
+
|
|
668
|
+
<div class="context-setting">
|
|
669
|
+
<div class="context-setting-header">
|
|
670
|
+
<label class="checkbox-inline">
|
|
671
|
+
<input type="checkbox" id="modalAutoClearEnabled" onchange="app.autoSaveAutoClear()">
|
|
672
|
+
<span>Auto-Clear</span>
|
|
673
|
+
</label>
|
|
674
|
+
<div class="input-suffix input-suffix-sm">
|
|
675
|
+
<input type="number" id="modalAutoClearThreshold" value="140000" min="10000" max="500000" step="10000" onchange="app.autoSaveAutoClear()">
|
|
676
|
+
<span>tokens</span>
|
|
677
|
+
</div>
|
|
678
|
+
</div>
|
|
679
|
+
<span class="form-hint">Full context reset at threshold (use higher than compact)</span>
|
|
680
|
+
</div>
|
|
681
|
+
</div>
|
|
682
|
+
|
|
683
|
+
<div class="form-section-header">File Watching</div>
|
|
684
|
+
<div class="form-row form-row-switch">
|
|
685
|
+
<label>Image Watcher</label>
|
|
686
|
+
<label class="switch">
|
|
687
|
+
<input type="checkbox" id="modalImageWatcherEnabled" checked onchange="app.toggleSessionImageWatcher()">
|
|
688
|
+
<span class="slider"></span>
|
|
689
|
+
</label>
|
|
690
|
+
<span class="form-hint">Auto-popup new images (screenshots, generated files) in this session's directory</span>
|
|
691
|
+
</div>
|
|
692
|
+
|
|
693
|
+
<div class="form-section-header">Performance</div>
|
|
694
|
+
<div class="form-row form-row-switch">
|
|
695
|
+
<label>Flicker Filter</label>
|
|
696
|
+
<label class="switch">
|
|
697
|
+
<input type="checkbox" id="modalFlickerFilterEnabled" onchange="app.toggleFlickerFilter()">
|
|
698
|
+
<span class="slider"></span>
|
|
699
|
+
</label>
|
|
700
|
+
<span class="form-hint">Buffers output after screen clears to reduce Ink UI flickering (adds ~50ms latency)</span>
|
|
701
|
+
</div>
|
|
702
|
+
</div><!-- End context-tab -->
|
|
703
|
+
|
|
704
|
+
<!-- Ralph Wiggum Tab Content -->
|
|
705
|
+
<div class="modal-tab-content hidden" id="ralph-tab">
|
|
706
|
+
<div class="form-row form-row-switch">
|
|
707
|
+
<label>Enable Tracker</label>
|
|
708
|
+
<label class="switch">
|
|
709
|
+
<input type="checkbox" id="modalRalphEnabled">
|
|
710
|
+
<span class="slider"></span>
|
|
711
|
+
</label>
|
|
712
|
+
<span class="form-hint">Auto-detects loops and todos in Claude output</span>
|
|
713
|
+
</div>
|
|
714
|
+
|
|
715
|
+
<div class="form-row">
|
|
716
|
+
<label>Completion Phrase</label>
|
|
717
|
+
<input type="text" id="modalRalphPhrase" placeholder="e.g., COMPLETE, DONE, FINISHED">
|
|
718
|
+
<span class="form-hint">Phrase Claude outputs when loop is complete (without <promise> tags)</span>
|
|
719
|
+
</div>
|
|
720
|
+
|
|
721
|
+
<div class="form-section-header">Limits</div>
|
|
722
|
+
<div class="ralph-limits-grid">
|
|
723
|
+
<div class="form-col">
|
|
724
|
+
<label>Max Iterations</label>
|
|
725
|
+
<input type="number" id="modalRalphMaxIterations" value="0" min="0" max="1000">
|
|
726
|
+
<span class="form-hint">0 = unlimited</span>
|
|
727
|
+
</div>
|
|
728
|
+
<div class="form-col">
|
|
729
|
+
<label>Max Todos</label>
|
|
730
|
+
<input type="number" id="modalRalphMaxTodos" value="50" min="1" max="500">
|
|
731
|
+
<span class="form-hint">Per session</span>
|
|
732
|
+
</div>
|
|
733
|
+
<div class="form-col">
|
|
734
|
+
<label>Todo Expiration</label>
|
|
735
|
+
<div class="input-suffix input-suffix-sm">
|
|
736
|
+
<input type="number" id="modalRalphTodoExpiration" value="60" min="1" max="1440">
|
|
737
|
+
<span>min</span>
|
|
738
|
+
</div>
|
|
739
|
+
</div>
|
|
740
|
+
</div>
|
|
741
|
+
|
|
742
|
+
<div class="ralph-config-actions">
|
|
743
|
+
<button class="btn-toolbar btn-primary" onclick="app.saveRalphConfig()">Save Ralph Config</button>
|
|
744
|
+
</div>
|
|
745
|
+
</div><!-- End ralph-tab -->
|
|
746
|
+
|
|
747
|
+
<!-- Summary Tab Content -->
|
|
748
|
+
<div class="modal-tab-content hidden" id="summary-tab">
|
|
749
|
+
<!-- Filter Buttons -->
|
|
750
|
+
<div class="run-summary-filters">
|
|
751
|
+
<button class="filter-btn active" data-filter="all" onclick="app.filterRunSummary('all')">All</button>
|
|
752
|
+
<button class="filter-btn" data-filter="errors" onclick="app.filterRunSummary('errors')">Errors</button>
|
|
753
|
+
<button class="filter-btn" data-filter="warnings" onclick="app.filterRunSummary('warnings')">Warnings</button>
|
|
754
|
+
<button class="filter-btn" data-filter="respawn" onclick="app.filterRunSummary('respawn')">Respawn</button>
|
|
755
|
+
<button class="filter-btn" data-filter="idle" onclick="app.filterRunSummary('idle')">Idle/Working</button>
|
|
756
|
+
</div>
|
|
757
|
+
|
|
758
|
+
<!-- Timeline -->
|
|
759
|
+
<div class="run-summary-timeline" id="runSummaryTimeline">
|
|
760
|
+
<p class="empty-message">Select a session to view summary</p>
|
|
761
|
+
</div>
|
|
762
|
+
|
|
763
|
+
<!-- Footer with actions -->
|
|
764
|
+
<div class="run-summary-footer">
|
|
765
|
+
<span class="run-summary-session-info" id="runSummarySessionInfo"></span>
|
|
766
|
+
<div class="run-summary-actions">
|
|
767
|
+
<label class="auto-refresh-label">
|
|
768
|
+
<input type="checkbox" id="runSummaryAutoRefresh" onchange="app.toggleRunSummaryAutoRefresh()">
|
|
769
|
+
Auto-refresh
|
|
770
|
+
</label>
|
|
771
|
+
<button class="btn-toolbar btn-sm" onclick="app.refreshRunSummary()" title="Refresh summary">↻ Refresh</button>
|
|
772
|
+
<button class="btn-toolbar btn-sm" onclick="app.exportRunSummary('json')" title="Export as JSON">Export JSON</button>
|
|
773
|
+
<button class="btn-toolbar btn-sm" onclick="app.exportRunSummary('md')" title="Export as Markdown">Export MD</button>
|
|
774
|
+
</div>
|
|
775
|
+
</div>
|
|
776
|
+
</div><!-- End summary-tab -->
|
|
777
|
+
</div>
|
|
778
|
+
</div>
|
|
779
|
+
</div>
|
|
780
|
+
|
|
781
|
+
<!-- Close Session Confirmation Modal -->
|
|
782
|
+
<div class="modal" id="closeConfirmModal">
|
|
783
|
+
<div class="modal-backdrop" onclick="app.cancelCloseSession()"></div>
|
|
784
|
+
<div class="modal-content modal-sm">
|
|
785
|
+
<div class="modal-header">
|
|
786
|
+
<h3>Close Session</h3>
|
|
787
|
+
<button class="modal-close" onclick="app.cancelCloseSession()" aria-label="Cancel close session">×</button>
|
|
788
|
+
</div>
|
|
789
|
+
<div class="modal-body">
|
|
790
|
+
<p class="modal-session-name" id="closeConfirmSessionName"></p>
|
|
791
|
+
</div>
|
|
792
|
+
<div class="close-options">
|
|
793
|
+
<button class="close-option" onclick="app.confirmCloseSession(false)">
|
|
794
|
+
<span class="close-option-title">Remove Tab</span>
|
|
795
|
+
<span class="close-option-desc">Tmux session keeps running in background</span>
|
|
796
|
+
</button>
|
|
797
|
+
<button class="close-option close-option-danger" onclick="app.confirmCloseSession(true)">
|
|
798
|
+
<span class="close-option-title" id="closeConfirmKillTitle">Kill Tmux & Claude Code</span>
|
|
799
|
+
<span class="close-option-desc">Terminate the session completely</span>
|
|
800
|
+
</button>
|
|
801
|
+
</div>
|
|
802
|
+
<div class="modal-footer-cancel">
|
|
803
|
+
<button class="btn-toolbar btn-sm" onclick="app.cancelCloseSession()">Cancel</button>
|
|
804
|
+
</div>
|
|
805
|
+
</div>
|
|
806
|
+
</div>
|
|
807
|
+
|
|
808
|
+
<!-- App Settings Modal -->
|
|
809
|
+
<div class="modal" id="appSettingsModal">
|
|
810
|
+
<div class="modal-backdrop" onclick="app.closeAppSettings()"></div>
|
|
811
|
+
<div class="modal-content modal-lg">
|
|
812
|
+
<div class="modal-header">
|
|
813
|
+
<h3>App Settings</h3>
|
|
814
|
+
<button class="modal-close" onclick="app.closeAppSettings()" aria-label="Close app settings">×</button>
|
|
815
|
+
</div>
|
|
816
|
+
<div class="modal-tabs">
|
|
817
|
+
<button class="modal-tab-btn active" data-tab="settings-display">Display</button>
|
|
818
|
+
<button class="modal-tab-btn" data-tab="settings-claude">Claude CLI</button>
|
|
819
|
+
<button class="modal-tab-btn" data-tab="settings-models">Models</button>
|
|
820
|
+
<button class="modal-tab-btn" data-tab="settings-paths">Paths</button>
|
|
821
|
+
<button class="modal-tab-btn" data-tab="settings-notifications">Notifications</button>
|
|
822
|
+
<button class="modal-tab-btn" data-tab="settings-voice">Voice</button>
|
|
823
|
+
</div>
|
|
824
|
+
<div class="modal-body">
|
|
825
|
+
<!-- Display Tab -->
|
|
826
|
+
<div class="modal-tab-content" id="settings-display">
|
|
827
|
+
<div class="settings-grid">
|
|
828
|
+
<!-- Input Section -->
|
|
829
|
+
<div class="settings-section-header">Input</div>
|
|
830
|
+
<div class="settings-item settings-item-multiline" title="Shows typed characters instantly via overlay while forwarding keystrokes to the server in the background. Enables Tab completion, preserves input across tab switches, and protects against session crashes. Recommended for mobile and high-latency connections.">
|
|
831
|
+
<div class="settings-item-text">
|
|
832
|
+
<span class="settings-item-label">Local Echo</span>
|
|
833
|
+
<span class="settings-item-desc">Instant typing feedback with local echo</span>
|
|
834
|
+
</div>
|
|
835
|
+
<label class="switch switch-sm">
|
|
836
|
+
<input type="checkbox" id="appSettingsLocalEcho">
|
|
837
|
+
<span class="slider"></span>
|
|
838
|
+
</label>
|
|
839
|
+
</div>
|
|
840
|
+
|
|
841
|
+
<!-- Header Displays Section -->
|
|
842
|
+
<div class="settings-section-header">Header Displays</div>
|
|
843
|
+
<div class="settings-item" title="Show A-/A+ font size buttons in header">
|
|
844
|
+
<span class="settings-item-label">Font Controls</span>
|
|
845
|
+
<label class="switch switch-sm">
|
|
846
|
+
<input type="checkbox" id="appSettingsShowFontControls">
|
|
847
|
+
<span class="slider"></span>
|
|
848
|
+
</label>
|
|
849
|
+
</div>
|
|
850
|
+
<div class="settings-item" title="Show CPU and memory usage in header">
|
|
851
|
+
<span class="settings-item-label">System Stats</span>
|
|
852
|
+
<label class="switch switch-sm">
|
|
853
|
+
<input type="checkbox" id="appSettingsShowSystemStats" checked>
|
|
854
|
+
<span class="slider"></span>
|
|
855
|
+
</label>
|
|
856
|
+
</div>
|
|
857
|
+
<div class="settings-item" title="Show total token count in header">
|
|
858
|
+
<span class="settings-item-label">Token Count</span>
|
|
859
|
+
<label class="switch switch-sm">
|
|
860
|
+
<input type="checkbox" id="appSettingsShowTokenCount" checked>
|
|
861
|
+
<span class="slider"></span>
|
|
862
|
+
</label>
|
|
863
|
+
</div>
|
|
864
|
+
<div class="settings-item" title="Show estimated cost next to token count">
|
|
865
|
+
<span class="settings-item-label">Show Cost ($)</span>
|
|
866
|
+
<label class="switch switch-sm">
|
|
867
|
+
<input type="checkbox" id="appSettingsShowCost">
|
|
868
|
+
<span class="slider"></span>
|
|
869
|
+
</label>
|
|
870
|
+
</div>
|
|
871
|
+
<div class="settings-item" title="Show session lifecycle log button in header">
|
|
872
|
+
<span class="settings-item-label">Lifecycle Log</span>
|
|
873
|
+
<label class="switch switch-sm">
|
|
874
|
+
<input type="checkbox" id="appSettingsShowLifecycleLog">
|
|
875
|
+
<span class="slider"></span>
|
|
876
|
+
</label>
|
|
877
|
+
</div>
|
|
878
|
+
|
|
879
|
+
<!-- Tab Bar Section -->
|
|
880
|
+
<div class="settings-section-header">Tab Bar</div>
|
|
881
|
+
<div class="settings-item" title="Show folder path below tab name and allow tab bar to wrap into multiple rows">
|
|
882
|
+
<span class="settings-item-label">Tall Tabs (Name + Folder)</span>
|
|
883
|
+
<label class="switch switch-sm">
|
|
884
|
+
<input type="checkbox" id="appSettingsTabTwoRows">
|
|
885
|
+
<span class="slider"></span>
|
|
886
|
+
</label>
|
|
887
|
+
</div>
|
|
888
|
+
|
|
889
|
+
<!-- Panels Section -->
|
|
890
|
+
<div class="settings-section-header">Panels</div>
|
|
891
|
+
<div class="settings-item" title="Show Monitor panel at bottom right">
|
|
892
|
+
<span class="settings-item-label">Monitor</span>
|
|
893
|
+
<label class="switch switch-sm">
|
|
894
|
+
<input type="checkbox" id="appSettingsShowMonitor" checked>
|
|
895
|
+
<span class="slider"></span>
|
|
896
|
+
</label>
|
|
897
|
+
</div>
|
|
898
|
+
<div class="settings-item" title="Show active tools and file viewers in a floating panel">
|
|
899
|
+
<span class="settings-item-label">Project Insights</span>
|
|
900
|
+
<label class="switch switch-sm">
|
|
901
|
+
<input type="checkbox" id="appSettingsShowProjectInsights">
|
|
902
|
+
<span class="slider"></span>
|
|
903
|
+
</label>
|
|
904
|
+
</div>
|
|
905
|
+
<div class="settings-item" title="Show file browser panel on the right side">
|
|
906
|
+
<span class="settings-item-label">File Browser</span>
|
|
907
|
+
<label class="switch switch-sm">
|
|
908
|
+
<input type="checkbox" id="appSettingsShowFileBrowser">
|
|
909
|
+
<span class="slider"></span>
|
|
910
|
+
</label>
|
|
911
|
+
</div>
|
|
912
|
+
<div class="settings-item" title="Show the Subagents panel (independent from Monitor)">
|
|
913
|
+
<span class="settings-item-label">Subagents</span>
|
|
914
|
+
<label class="switch switch-sm">
|
|
915
|
+
<input type="checkbox" id="appSettingsShowSubagents">
|
|
916
|
+
<span class="slider"></span>
|
|
917
|
+
</label>
|
|
918
|
+
</div>
|
|
919
|
+
|
|
920
|
+
<!-- Subagent Options Section -->
|
|
921
|
+
<div class="settings-section-header">Subagent Options</div>
|
|
922
|
+
<div class="settings-item" title="Monitor Claude Code background agents in real-time">
|
|
923
|
+
<span class="settings-item-label">Enable Tracking</span>
|
|
924
|
+
<label class="switch switch-sm">
|
|
925
|
+
<input type="checkbox" id="appSettingsSubagentTracking" checked>
|
|
926
|
+
<span class="slider"></span>
|
|
927
|
+
</label>
|
|
928
|
+
</div>
|
|
929
|
+
<div class="settings-item" title="Only show subagent windows when their parent tab is selected">
|
|
930
|
+
<span class="settings-item-label">Active Tab Only</span>
|
|
931
|
+
<label class="switch switch-sm">
|
|
932
|
+
<input type="checkbox" id="appSettingsSubagentActiveTabOnly" checked>
|
|
933
|
+
<span class="slider"></span>
|
|
934
|
+
</label>
|
|
935
|
+
</div>
|
|
936
|
+
|
|
937
|
+
<!-- Image Watcher Options Section -->
|
|
938
|
+
<div class="settings-section-header">Image Watcher</div>
|
|
939
|
+
<div class="settings-item" title="Automatically detect and popup new images in session directories">
|
|
940
|
+
<span class="settings-item-label">Enable Globally</span>
|
|
941
|
+
<label class="switch switch-sm">
|
|
942
|
+
<input type="checkbox" id="appSettingsImageWatcherEnabled">
|
|
943
|
+
<span class="slider"></span>
|
|
944
|
+
</label>
|
|
945
|
+
</div>
|
|
946
|
+
|
|
947
|
+
<!-- Remote Access Section -->
|
|
948
|
+
<div class="settings-section-header">Remote Access</div>
|
|
949
|
+
<div class="settings-item" title="Expose Codeman via Cloudflare Tunnel for remote access">
|
|
950
|
+
<span class="settings-item-label">Cloudflare Tunnel</span>
|
|
951
|
+
<label class="switch switch-sm">
|
|
952
|
+
<input type="checkbox" id="appSettingsTunnelEnabled">
|
|
953
|
+
<span class="slider"></span>
|
|
954
|
+
</label>
|
|
955
|
+
</div>
|
|
956
|
+
<div class="settings-item" id="tunnelUrlRow" style="display:none">
|
|
957
|
+
<span class="settings-item-label">Tunnel URL</span>
|
|
958
|
+
<div style="display:flex; align-items:center; gap:8px">
|
|
959
|
+
<span id="tunnelUrlDisplay" class="settings-item-value" style="cursor:pointer; text-decoration:underline; font-family:monospace; font-size:12px" title="Click to copy"></span>
|
|
960
|
+
<button class="btn-icon-sm" id="tunnelQrBtn" onclick="app.showTunnelQR()" title="Show QR code" style="font-size:16px; padding:2px 6px; background:none; border:1px solid var(--border); border-radius:4px; cursor:pointer; color:var(--text-secondary)">⊞</button>
|
|
961
|
+
</div>
|
|
962
|
+
</div>
|
|
963
|
+
|
|
964
|
+
</div>
|
|
965
|
+
</div>
|
|
966
|
+
<!-- Tab-Switch Tab -->
|
|
967
|
+
<!-- Claude CLI Tab -->
|
|
968
|
+
<div class="modal-tab-content hidden" id="settings-claude">
|
|
969
|
+
<div class="form-row">
|
|
970
|
+
<label>Startup Mode</label>
|
|
971
|
+
<select id="appSettingsClaudeMode" class="form-select">
|
|
972
|
+
<option value="dangerously-skip-permissions">Skip Permissions (default)</option>
|
|
973
|
+
<option value="normal">Normal (with prompts)</option>
|
|
974
|
+
<option value="allowedTools">Allowed Tools Only</option>
|
|
975
|
+
</select>
|
|
976
|
+
<span class="form-hint">How Claude CLI is started in screen sessions</span>
|
|
977
|
+
</div>
|
|
978
|
+
<div class="form-row" id="allowedToolsRow" style="display: none;">
|
|
979
|
+
<label>Allowed Tools</label>
|
|
980
|
+
<input type="text" id="appSettingsAllowedTools" placeholder="Read,Glob,Grep,Bash">
|
|
981
|
+
<span class="form-hint">Comma-separated list of tools to allow</span>
|
|
982
|
+
</div>
|
|
983
|
+
<div class="form-row form-row-switch">
|
|
984
|
+
<label>Enable Ralph / Todo Tracker</label>
|
|
985
|
+
<label class="switch">
|
|
986
|
+
<input type="checkbox" id="appSettingsRalphEnabled">
|
|
987
|
+
<span class="slider"></span>
|
|
988
|
+
</label>
|
|
989
|
+
<span class="form-hint">Auto-enable for new sessions (otherwise auto-enables on Ralph pattern detection)</span>
|
|
990
|
+
</div>
|
|
991
|
+
<!-- Claude Permissions Section -->
|
|
992
|
+
<div class="form-section-header">Claude Permissions</div>
|
|
993
|
+
<div class="form-row form-row-switch">
|
|
994
|
+
<label>Agent Teams</label>
|
|
995
|
+
<label class="switch">
|
|
996
|
+
<input type="checkbox" id="appSettingsAgentTeams">
|
|
997
|
+
<span class="slider"></span>
|
|
998
|
+
</label>
|
|
999
|
+
<span class="form-hint">Enable experimental Agent Teams for all new Claude sessions (disabled by default)</span>
|
|
1000
|
+
</div>
|
|
1001
|
+
<!-- Nice Priority Section -->
|
|
1002
|
+
<div class="form-section-header">Nice Priority</div>
|
|
1003
|
+
<div class="form-row form-row-switch">
|
|
1004
|
+
<label>Enable Nice Priority Reduction</label>
|
|
1005
|
+
<label class="switch">
|
|
1006
|
+
<input type="checkbox" id="appSettingsNiceEnabled">
|
|
1007
|
+
<span class="slider"></span>
|
|
1008
|
+
</label>
|
|
1009
|
+
<span class="form-hint">Lower priority of Claude sessions (reduces system impact, only affects new sessions)</span>
|
|
1010
|
+
</div>
|
|
1011
|
+
<div class="form-row" id="niceValueRow">
|
|
1012
|
+
<label>Nice Value</label>
|
|
1013
|
+
<input type="number" id="appSettingsNiceValue" min="-20" max="19" value="10" style="width: 80px;">
|
|
1014
|
+
<span class="form-hint">Process priority (-20 to 19, higher = lower priority, default: 10)</span>
|
|
1015
|
+
</div>
|
|
1016
|
+
</div>
|
|
1017
|
+
<!-- Models Tab -->
|
|
1018
|
+
<div class="modal-tab-content hidden" id="settings-models">
|
|
1019
|
+
<div class="form-row">
|
|
1020
|
+
<label>Default Model</label>
|
|
1021
|
+
<select id="appSettingsDefaultModel" class="form-select">
|
|
1022
|
+
<option value="opus">Opus (Most capable)</option>
|
|
1023
|
+
<option value="sonnet">Sonnet (Balanced)</option>
|
|
1024
|
+
<option value="haiku">Haiku (Fast & cheap)</option>
|
|
1025
|
+
</select>
|
|
1026
|
+
<span class="form-hint">Model used for execution tasks. Optimizer suggestions are advisory only.</span>
|
|
1027
|
+
</div>
|
|
1028
|
+
<div class="form-row form-row-switch">
|
|
1029
|
+
<label>Show Optimizer Recommendations</label>
|
|
1030
|
+
<label class="switch">
|
|
1031
|
+
<input type="checkbox" id="appSettingsShowModelRecommendations" checked>
|
|
1032
|
+
<span class="slider"></span>
|
|
1033
|
+
</label>
|
|
1034
|
+
<span class="form-hint">Show what the optimizer recommends (doesn't override your choice)</span>
|
|
1035
|
+
</div>
|
|
1036
|
+
<div class="form-section-header">Agent Type Overrides</div>
|
|
1037
|
+
<p class="form-hint" style="margin: 0 0 12px 0;">Optionally set specific models for each task type. Leave as "Use Default" to use your default model.</p>
|
|
1038
|
+
<div class="form-row">
|
|
1039
|
+
<label>Explore Tasks</label>
|
|
1040
|
+
<select id="appSettingsModelExplore" class="form-select">
|
|
1041
|
+
<option value="">Use Default</option>
|
|
1042
|
+
<option value="haiku">Haiku</option>
|
|
1043
|
+
<option value="sonnet">Sonnet</option>
|
|
1044
|
+
<option value="opus">Opus</option>
|
|
1045
|
+
</select>
|
|
1046
|
+
<span class="form-hint">Quick searches, codebase exploration</span>
|
|
1047
|
+
</div>
|
|
1048
|
+
<div class="form-row">
|
|
1049
|
+
<label>Implement Tasks</label>
|
|
1050
|
+
<select id="appSettingsModelImplement" class="form-select">
|
|
1051
|
+
<option value="">Use Default</option>
|
|
1052
|
+
<option value="haiku">Haiku</option>
|
|
1053
|
+
<option value="sonnet">Sonnet</option>
|
|
1054
|
+
<option value="opus">Opus</option>
|
|
1055
|
+
</select>
|
|
1056
|
+
<span class="form-hint">Code writing, feature implementation</span>
|
|
1057
|
+
</div>
|
|
1058
|
+
<div class="form-row">
|
|
1059
|
+
<label>Test Tasks</label>
|
|
1060
|
+
<select id="appSettingsModelTest" class="form-select">
|
|
1061
|
+
<option value="">Use Default</option>
|
|
1062
|
+
<option value="haiku">Haiku</option>
|
|
1063
|
+
<option value="sonnet">Sonnet</option>
|
|
1064
|
+
<option value="opus">Opus</option>
|
|
1065
|
+
</select>
|
|
1066
|
+
<span class="form-hint">Writing and running tests</span>
|
|
1067
|
+
</div>
|
|
1068
|
+
<div class="form-row">
|
|
1069
|
+
<label>Review Tasks</label>
|
|
1070
|
+
<select id="appSettingsModelReview" class="form-select">
|
|
1071
|
+
<option value="">Use Default</option>
|
|
1072
|
+
<option value="haiku">Haiku</option>
|
|
1073
|
+
<option value="sonnet">Sonnet</option>
|
|
1074
|
+
<option value="opus">Opus</option>
|
|
1075
|
+
</select>
|
|
1076
|
+
<span class="form-hint">Code review, quality checks</span>
|
|
1077
|
+
</div>
|
|
1078
|
+
</div>
|
|
1079
|
+
<!-- Paths Tab -->
|
|
1080
|
+
<div class="modal-tab-content hidden" id="settings-paths">
|
|
1081
|
+
<div class="form-row">
|
|
1082
|
+
<label>Default CLAUDE.md Template</label>
|
|
1083
|
+
<input type="text" id="appSettingsClaudeMdPath" placeholder="/path/to/CLAUDE.md template">
|
|
1084
|
+
<span class="form-hint">Used when creating new cases. Leave empty for built-in template.</span>
|
|
1085
|
+
</div>
|
|
1086
|
+
<div class="form-row">
|
|
1087
|
+
<label>Default Working Directory</label>
|
|
1088
|
+
<input type="text" id="appSettingsDefaultDir" placeholder="~/projects">
|
|
1089
|
+
<span class="form-hint">Default directory for new sessions.</span>
|
|
1090
|
+
</div>
|
|
1091
|
+
</div>
|
|
1092
|
+
<!-- Notifications Tab -->
|
|
1093
|
+
<div class="modal-tab-content hidden" id="settings-notifications">
|
|
1094
|
+
<div class="settings-grid">
|
|
1095
|
+
<!-- Master Control Section -->
|
|
1096
|
+
<div class="settings-section-header">Master Control</div>
|
|
1097
|
+
<div class="settings-item" title="Master toggle for all notification layers">
|
|
1098
|
+
<span class="settings-item-label">Enable Notifications</span>
|
|
1099
|
+
<label class="switch switch-sm">
|
|
1100
|
+
<input type="checkbox" id="appSettingsNotifEnabled" checked>
|
|
1101
|
+
<span class="slider"></span>
|
|
1102
|
+
</label>
|
|
1103
|
+
</div>
|
|
1104
|
+
<div class="settings-item" title="Show OS-level notifications when tab is hidden">
|
|
1105
|
+
<span class="settings-item-label">Browser</span>
|
|
1106
|
+
<div class="settings-item-actions">
|
|
1107
|
+
<label class="switch switch-sm">
|
|
1108
|
+
<input type="checkbox" id="appSettingsNotifBrowser">
|
|
1109
|
+
<span class="slider"></span>
|
|
1110
|
+
</label>
|
|
1111
|
+
<button class="btn-toolbar btn-sm" onclick="app.notificationManager?.requestPermission()" title="Request browser notification permission">Ask</button>
|
|
1112
|
+
<span class="settings-status" id="notifPermissionStatus">?</span>
|
|
1113
|
+
</div>
|
|
1114
|
+
</div>
|
|
1115
|
+
<span class="form-hint" style="grid-column: 1 / -1; margin-top: -8px;">For remote access, HTTPS is required. Start with: <code>codeman web --https</code></span>
|
|
1116
|
+
|
|
1117
|
+
<div class="settings-item" title="OS-level push notifications — works even when tab is closed">
|
|
1118
|
+
<span class="settings-item-label">Push</span>
|
|
1119
|
+
<div class="settings-item-actions">
|
|
1120
|
+
<label class="switch switch-sm">
|
|
1121
|
+
<input type="checkbox" id="appSettingsPushEnabled">
|
|
1122
|
+
<span class="slider"></span>
|
|
1123
|
+
</label>
|
|
1124
|
+
<button class="btn-toolbar btn-sm" id="pushSubscribeBtn" onclick="app.togglePushSubscription()" title="Subscribe/unsubscribe to push notifications">Subscribe</button>
|
|
1125
|
+
<span class="settings-status" id="pushSubscriptionStatus">off</span>
|
|
1126
|
+
</div>
|
|
1127
|
+
</div>
|
|
1128
|
+
<span class="form-hint" style="grid-column: 1 / -1; margin-top: -8px;">Works through Cloudflare tunnel. Requires HTTPS or localhost. iOS requires PWA (Add to Home Screen).</span>
|
|
1129
|
+
|
|
1130
|
+
<!-- Alerts Section -->
|
|
1131
|
+
<div class="settings-section-header">Alerts</div>
|
|
1132
|
+
<div class="settings-item" title="Play a short beep for critical events">
|
|
1133
|
+
<span class="settings-item-label">Audio Alerts</span>
|
|
1134
|
+
<label class="switch switch-sm">
|
|
1135
|
+
<input type="checkbox" id="appSettingsNotifAudio">
|
|
1136
|
+
<span class="slider"></span>
|
|
1137
|
+
</label>
|
|
1138
|
+
</div>
|
|
1139
|
+
<div class="settings-item" title="Notify when a session is idle longer than this">
|
|
1140
|
+
<span class="settings-item-label">Idle Threshold</span>
|
|
1141
|
+
<div class="settings-item-actions">
|
|
1142
|
+
<input type="number" id="appSettingsNotifStuckMins" class="settings-item-input" value="10" min="1" max="120">
|
|
1143
|
+
<span style="font-size: 0.65rem; color: var(--text-muted);">min</span>
|
|
1144
|
+
</div>
|
|
1145
|
+
</div>
|
|
1146
|
+
|
|
1147
|
+
<!-- Notification Levels Section -->
|
|
1148
|
+
<div class="settings-section-header">Notification Levels</div>
|
|
1149
|
+
</div>
|
|
1150
|
+
<div class="settings-grid settings-grid-3col">
|
|
1151
|
+
<div class="settings-item" title="Errors, crashes, agent failures">
|
|
1152
|
+
<span class="settings-item-label">Critical</span>
|
|
1153
|
+
<label class="switch switch-sm">
|
|
1154
|
+
<input type="checkbox" id="appSettingsNotifCritical" checked>
|
|
1155
|
+
<span class="slider"></span>
|
|
1156
|
+
</label>
|
|
1157
|
+
</div>
|
|
1158
|
+
<div class="settings-item" title="Completions, budget warnings, stuck sessions">
|
|
1159
|
+
<span class="settings-item-label">Warning</span>
|
|
1160
|
+
<label class="switch switch-sm">
|
|
1161
|
+
<input type="checkbox" id="appSettingsNotifWarning" checked>
|
|
1162
|
+
<span class="slider"></span>
|
|
1163
|
+
</label>
|
|
1164
|
+
</div>
|
|
1165
|
+
<div class="settings-item" title="Auto-accepts, auto-clears, agent completions">
|
|
1166
|
+
<span class="settings-item-label">Info</span>
|
|
1167
|
+
<label class="switch switch-sm">
|
|
1168
|
+
<input type="checkbox" id="appSettingsNotifInfo" checked>
|
|
1169
|
+
<span class="slider"></span>
|
|
1170
|
+
</label>
|
|
1171
|
+
</div>
|
|
1172
|
+
</div>
|
|
1173
|
+
|
|
1174
|
+
<!-- Event Type Preferences -->
|
|
1175
|
+
<div class="settings-grid" style="margin-top: 12px;">
|
|
1176
|
+
<div class="settings-section-header">Per-Event Settings</div>
|
|
1177
|
+
</div>
|
|
1178
|
+
<div class="event-type-grid">
|
|
1179
|
+
<div class="event-header">Event</div>
|
|
1180
|
+
<div class="event-header">On</div>
|
|
1181
|
+
<div class="event-header">Browser</div>
|
|
1182
|
+
<div class="event-header">Push</div>
|
|
1183
|
+
<div class="event-header">Sound</div>
|
|
1184
|
+
|
|
1185
|
+
<div class="event-label">Permission prompts</div>
|
|
1186
|
+
<input type="checkbox" id="eventPermissionEnabled" checked>
|
|
1187
|
+
<input type="checkbox" id="eventPermissionBrowser" checked>
|
|
1188
|
+
<input type="checkbox" id="eventPermissionPush" checked>
|
|
1189
|
+
<input type="checkbox" id="eventPermissionAudio" checked>
|
|
1190
|
+
|
|
1191
|
+
<div class="event-label">Questions from Claude</div>
|
|
1192
|
+
<input type="checkbox" id="eventQuestionEnabled" checked>
|
|
1193
|
+
<input type="checkbox" id="eventQuestionBrowser" checked>
|
|
1194
|
+
<input type="checkbox" id="eventQuestionPush" checked>
|
|
1195
|
+
<input type="checkbox" id="eventQuestionAudio" checked>
|
|
1196
|
+
|
|
1197
|
+
<div class="event-label">Session idle</div>
|
|
1198
|
+
<input type="checkbox" id="eventIdleEnabled" checked>
|
|
1199
|
+
<input type="checkbox" id="eventIdleBrowser" checked>
|
|
1200
|
+
<input type="checkbox" id="eventIdlePush">
|
|
1201
|
+
<input type="checkbox" id="eventIdleAudio">
|
|
1202
|
+
|
|
1203
|
+
<div class="event-label">Response complete</div>
|
|
1204
|
+
<input type="checkbox" id="eventStopEnabled" checked>
|
|
1205
|
+
<input type="checkbox" id="eventStopBrowser">
|
|
1206
|
+
<input type="checkbox" id="eventStopPush">
|
|
1207
|
+
<input type="checkbox" id="eventStopAudio">
|
|
1208
|
+
|
|
1209
|
+
<div class="event-label">Respawn cycles</div>
|
|
1210
|
+
<input type="checkbox" id="eventRespawnEnabled" checked>
|
|
1211
|
+
<input type="checkbox" id="eventRespawnBrowser">
|
|
1212
|
+
<input type="checkbox" id="eventRespawnPush">
|
|
1213
|
+
<input type="checkbox" id="eventRespawnAudio">
|
|
1214
|
+
|
|
1215
|
+
<div class="event-label">Task complete</div>
|
|
1216
|
+
<input type="checkbox" id="eventRalphEnabled" checked>
|
|
1217
|
+
<input type="checkbox" id="eventRalphBrowser" checked>
|
|
1218
|
+
<input type="checkbox" id="eventRalphPush">
|
|
1219
|
+
<input type="checkbox" id="eventRalphAudio" checked>
|
|
1220
|
+
|
|
1221
|
+
<div class="event-label">Subagent activity</div>
|
|
1222
|
+
<input type="checkbox" id="eventSubagentEnabled">
|
|
1223
|
+
<input type="checkbox" id="eventSubagentBrowser">
|
|
1224
|
+
<input type="checkbox" id="eventSubagentPush">
|
|
1225
|
+
<input type="checkbox" id="eventSubagentAudio">
|
|
1226
|
+
</div>
|
|
1227
|
+
</div>
|
|
1228
|
+
|
|
1229
|
+
<!-- Voice Tab -->
|
|
1230
|
+
<div class="modal-tab-content hidden" id="settings-voice">
|
|
1231
|
+
<div class="settings-grid">
|
|
1232
|
+
<div class="settings-section-header">Provider</div>
|
|
1233
|
+
<div class="settings-item">
|
|
1234
|
+
<span class="settings-item-label">Active Provider</span>
|
|
1235
|
+
<span class="voice-provider-status" id="voiceProviderStatus">—</span>
|
|
1236
|
+
</div>
|
|
1237
|
+
|
|
1238
|
+
<div class="settings-section-header">Behavior</div>
|
|
1239
|
+
<div class="settings-item" style="grid-column: 1 / -1;">
|
|
1240
|
+
<span class="settings-item-label">Insert mode</span>
|
|
1241
|
+
<select id="voiceInsertMode" class="form-select" style="width: auto;">
|
|
1242
|
+
<option value="direct">Direct to input</option>
|
|
1243
|
+
<option value="compose">Compose dialog</option>
|
|
1244
|
+
</select>
|
|
1245
|
+
</div>
|
|
1246
|
+
|
|
1247
|
+
<div class="settings-section-header">Deepgram Nova-3</div>
|
|
1248
|
+
<div class="form-row" style="grid-column: 1 / -1;">
|
|
1249
|
+
<label for="voiceDeepgramKey">API Key</label>
|
|
1250
|
+
<div style="display: flex; gap: 6px; align-items: center;">
|
|
1251
|
+
<input type="password" id="voiceDeepgramKey" placeholder="Enter Deepgram API key" autocomplete="off" style="flex: 1; width: 100%; padding: 0.5rem 0.75rem; background: var(--bg-input); border: 1px solid var(--border); border-radius: 4px; color: var(--text); font-size: 0.8rem; font-family: inherit;">
|
|
1252
|
+
<button class="btn-toolbar btn-sm" onclick="app.toggleDeepgramKeyVisibility()" id="voiceKeyToggleBtn" type="button">Show</button>
|
|
1253
|
+
</div>
|
|
1254
|
+
<span class="form-hint">Stored locally only, never sent to server. Get a key at <a href="https://console.deepgram.com" target="_blank" rel="noopener" style="color: var(--accent);">console.deepgram.com</a></span>
|
|
1255
|
+
</div>
|
|
1256
|
+
|
|
1257
|
+
<div class="form-row" style="grid-column: 1 / -1;">
|
|
1258
|
+
<label for="voiceLanguage">Language</label>
|
|
1259
|
+
<select id="voiceLanguage" class="form-select">
|
|
1260
|
+
<option value="en-US">English (US)</option>
|
|
1261
|
+
<option value="en-GB">English (UK)</option>
|
|
1262
|
+
<option value="es">Spanish</option>
|
|
1263
|
+
<option value="fr">French</option>
|
|
1264
|
+
<option value="de">German</option>
|
|
1265
|
+
<option value="ja">Japanese</option>
|
|
1266
|
+
<option value="multi">Auto-detect (multi)</option>
|
|
1267
|
+
</select>
|
|
1268
|
+
</div>
|
|
1269
|
+
|
|
1270
|
+
<div class="form-row" style="grid-column: 1 / -1;">
|
|
1271
|
+
<label for="voiceKeyterms">Domain Keywords</label>
|
|
1272
|
+
<input type="text" id="voiceKeyterms" placeholder="codeman, tmux, respawn, subagent" style="width: 100%; padding: 0.5rem 0.75rem; background: var(--bg-input); border: 1px solid var(--border); border-radius: 4px; color: var(--text); font-size: 0.8rem; font-family: inherit;">
|
|
1273
|
+
<span class="form-hint">Comma-separated terms to boost recognition accuracy</span>
|
|
1274
|
+
</div>
|
|
1275
|
+
</div>
|
|
1276
|
+
</div>
|
|
1277
|
+
</div>
|
|
1278
|
+
<div class="form-actions">
|
|
1279
|
+
<button class="btn-toolbar" onclick="app.closeAppSettings()">Cancel</button>
|
|
1280
|
+
<button class="btn-toolbar btn-primary" onclick="app.saveAppSettings()">Save</button>
|
|
1281
|
+
</div>
|
|
1282
|
+
</div>
|
|
1283
|
+
</div>
|
|
1284
|
+
|
|
1285
|
+
<!-- Create Case Modal -->
|
|
1286
|
+
<div class="modal" id="createCaseModal">
|
|
1287
|
+
<div class="modal-backdrop" onclick="app.closeCreateCaseModal()"></div>
|
|
1288
|
+
<div class="modal-content modal-lg">
|
|
1289
|
+
<div class="modal-header">
|
|
1290
|
+
<h3>Add Case</h3>
|
|
1291
|
+
<button class="modal-close" onclick="app.closeCreateCaseModal()" aria-label="Close create case">×</button>
|
|
1292
|
+
</div>
|
|
1293
|
+
<div class="modal-tabs">
|
|
1294
|
+
<button class="modal-tab-btn active" data-tab="case-create">Create New</button>
|
|
1295
|
+
<button class="modal-tab-btn" data-tab="case-link">Link Existing</button>
|
|
1296
|
+
</div>
|
|
1297
|
+
<div class="modal-body">
|
|
1298
|
+
<!-- Create New Tab -->
|
|
1299
|
+
<div class="modal-tab-content" id="case-create">
|
|
1300
|
+
<div class="form-row">
|
|
1301
|
+
<label>Case Name</label>
|
|
1302
|
+
<input type="text" id="newCaseName" placeholder="my-project" pattern="[a-zA-Z0-9_-]+" autocomplete="off" autocapitalize="off" spellcheck="false">
|
|
1303
|
+
<span class="form-hint">Letters, numbers, hyphens, underscores only. Created in ~/codeman-cases/</span>
|
|
1304
|
+
</div>
|
|
1305
|
+
<div class="form-row">
|
|
1306
|
+
<label>Description (optional)</label>
|
|
1307
|
+
<input type="text" id="newCaseDescription" placeholder="A brief description..." autocomplete="off">
|
|
1308
|
+
</div>
|
|
1309
|
+
</div>
|
|
1310
|
+
<!-- Link Existing Tab -->
|
|
1311
|
+
<div class="modal-tab-content hidden" id="case-link">
|
|
1312
|
+
<div class="form-row">
|
|
1313
|
+
<label>Case Name</label>
|
|
1314
|
+
<input type="text" id="linkCaseName" placeholder="my-project" pattern="[a-zA-Z0-9_-]+" autocomplete="off" autocapitalize="off" spellcheck="false">
|
|
1315
|
+
<span class="form-hint">Name to identify this case in Codeman</span>
|
|
1316
|
+
</div>
|
|
1317
|
+
<div class="form-row">
|
|
1318
|
+
<label>Folder Path</label>
|
|
1319
|
+
<input type="text" id="linkCasePath" placeholder="/home/user/projects/my-project" autocomplete="off" autocapitalize="off" autocorrect="off" spellcheck="false">
|
|
1320
|
+
<span class="form-hint">Absolute path to an existing project folder, e.g. /home/you/my-project</span>
|
|
1321
|
+
</div>
|
|
1322
|
+
</div>
|
|
1323
|
+
</div>
|
|
1324
|
+
<div class="form-actions">
|
|
1325
|
+
<button class="btn-toolbar" onclick="app.closeCreateCaseModal()">Cancel</button>
|
|
1326
|
+
<button class="btn-toolbar btn-primary" id="caseModalSubmit" onclick="app.submitCaseModal()">Create</button>
|
|
1327
|
+
</div>
|
|
1328
|
+
</div>
|
|
1329
|
+
</div>
|
|
1330
|
+
|
|
1331
|
+
<!-- Mobile Case Picker (Bottom Sheet) -->
|
|
1332
|
+
<div class="modal mobile-case-picker" id="mobileCasePickerModal">
|
|
1333
|
+
<div class="modal-backdrop" onclick="app.closeMobileCasePicker()"></div>
|
|
1334
|
+
<div class="mobile-case-picker-sheet">
|
|
1335
|
+
<div class="mobile-case-picker-header">
|
|
1336
|
+
<h3>Select Case</h3>
|
|
1337
|
+
<button class="modal-close" onclick="app.closeMobileCasePicker()" aria-label="Close case picker">×</button>
|
|
1338
|
+
</div>
|
|
1339
|
+
<div class="mobile-case-picker-body">
|
|
1340
|
+
<div class="mobile-case-list" id="mobileCaseList">
|
|
1341
|
+
<!-- Cases populated by JS -->
|
|
1342
|
+
</div>
|
|
1343
|
+
</div>
|
|
1344
|
+
<div class="mobile-case-picker-footer">
|
|
1345
|
+
<button class="btn-toolbar btn-case-create-mobile" onclick="app.showCreateCaseFromMobile()">
|
|
1346
|
+
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><line x1="12" y1="5" x2="12" y2="19"/><line x1="5" y1="12" x2="19" y2="12"/></svg>
|
|
1347
|
+
Create New Case
|
|
1348
|
+
</button>
|
|
1349
|
+
</div>
|
|
1350
|
+
</div>
|
|
1351
|
+
</div>
|
|
1352
|
+
|
|
1353
|
+
<!-- Ralph Loop Wizard Modal -->
|
|
1354
|
+
<div class="modal" id="ralphWizardModal">
|
|
1355
|
+
<div class="modal-backdrop"></div>
|
|
1356
|
+
<div class="modal-content modal-wizard">
|
|
1357
|
+
<div class="modal-header">
|
|
1358
|
+
<h3>Start Ralph Loop</h3>
|
|
1359
|
+
<div class="modal-header-actions">
|
|
1360
|
+
<button class="modal-close" onclick="app.closeRalphWizard()" aria-label="Close Ralph wizard">×</button>
|
|
1361
|
+
</div>
|
|
1362
|
+
</div>
|
|
1363
|
+
|
|
1364
|
+
<!-- Wizard Progress Steps -->
|
|
1365
|
+
<div class="wizard-progress">
|
|
1366
|
+
<div class="wizard-step active" data-step="1">
|
|
1367
|
+
<span class="wizard-step-number">1</span>
|
|
1368
|
+
<span class="wizard-step-label">Describe</span>
|
|
1369
|
+
</div>
|
|
1370
|
+
<div class="wizard-step" data-step="2">
|
|
1371
|
+
<span class="wizard-step-number">2</span>
|
|
1372
|
+
<span class="wizard-step-label">Plan</span>
|
|
1373
|
+
</div>
|
|
1374
|
+
<div class="wizard-step" data-step="3">
|
|
1375
|
+
<span class="wizard-step-number">3</span>
|
|
1376
|
+
<span class="wizard-step-label">Launch</span>
|
|
1377
|
+
</div>
|
|
1378
|
+
</div>
|
|
1379
|
+
|
|
1380
|
+
<div class="modal-body">
|
|
1381
|
+
<!-- Step 1: Task & Completion Setup -->
|
|
1382
|
+
<div class="wizard-page wizard-page-compact" id="ralphWizardStep1">
|
|
1383
|
+
<div class="wizard-step-intro">
|
|
1384
|
+
<p>Describe your task below. Claude will generate an implementation plan with testing steps.</p>
|
|
1385
|
+
</div>
|
|
1386
|
+
<div class="form-row">
|
|
1387
|
+
<label>What do you want to build?</label>
|
|
1388
|
+
<div class="textarea-with-assist">
|
|
1389
|
+
<textarea
|
|
1390
|
+
id="ralphTaskDescription"
|
|
1391
|
+
rows="3"
|
|
1392
|
+
placeholder="Build a REST API for user authentication with JWT tokens, login/logout endpoints, and password reset flow."></textarea>
|
|
1393
|
+
</div>
|
|
1394
|
+
</div>
|
|
1395
|
+
|
|
1396
|
+
<div class="wizard-inline-row">
|
|
1397
|
+
<div class="wizard-inline-field">
|
|
1398
|
+
<label>Working Directory <span id="existingPlanBadge" class="existing-plan-badge" style="display:none"></span></label>
|
|
1399
|
+
<div class="case-select-inline">
|
|
1400
|
+
<select id="ralphCaseSelect" class="form-select" onchange="app.onRalphCaseChange()"></select>
|
|
1401
|
+
<button class="btn-toolbar btn-sm" onclick="app.showCreateCaseModal()">+</button>
|
|
1402
|
+
</div>
|
|
1403
|
+
</div>
|
|
1404
|
+
<div class="wizard-inline-field wizard-inline-field-small">
|
|
1405
|
+
<label>Iterations</label>
|
|
1406
|
+
<div class="iteration-presets-compact">
|
|
1407
|
+
<button type="button" class="iteration-preset-btn active" data-iterations="10" onclick="app.selectIterationPreset(10)">10</button>
|
|
1408
|
+
<button type="button" class="iteration-preset-btn" data-iterations="25" onclick="app.selectIterationPreset(25)">25</button>
|
|
1409
|
+
<button type="button" class="iteration-preset-btn" data-iterations="50" onclick="app.selectIterationPreset(50)">50</button>
|
|
1410
|
+
<button type="button" class="iteration-preset-btn" data-iterations="0" onclick="app.selectIterationPreset(0)">∞</button>
|
|
1411
|
+
</div>
|
|
1412
|
+
</div>
|
|
1413
|
+
</div>
|
|
1414
|
+
<!-- Hidden completion phrase with default -->
|
|
1415
|
+
<input type="hidden" id="ralphCompletionPhrase" value="COMPLETE">
|
|
1416
|
+
</div>
|
|
1417
|
+
|
|
1418
|
+
<!-- Step 2: Plan Generation -->
|
|
1419
|
+
<div class="wizard-page wizard-page-compact hidden" id="ralphWizardStep2">
|
|
1420
|
+
<!-- Existing plan detected (shown when @fix_plan.md exists) -->
|
|
1421
|
+
<div id="existingPlanSection" class="plan-section hidden">
|
|
1422
|
+
<!-- Content populated by app.updateExistingPlanUI() -->
|
|
1423
|
+
</div>
|
|
1424
|
+
|
|
1425
|
+
<!-- Loading state (shown during generation) -->
|
|
1426
|
+
<div id="planGenerationLoading" class="plan-loading-state hidden">
|
|
1427
|
+
<div class="plan-loading-content">
|
|
1428
|
+
<div class="plan-spinner"></div>
|
|
1429
|
+
<div class="plan-loading-text">
|
|
1430
|
+
<span class="plan-loading-title" id="planLoadingTitle">Starting Opus 4.5...</span>
|
|
1431
|
+
<span class="plan-loading-time" id="planLoadingTime">0s</span>
|
|
1432
|
+
</div>
|
|
1433
|
+
</div>
|
|
1434
|
+
<p class="plan-loading-hint" id="planLoadingHint">Initializing deep reasoning model</p>
|
|
1435
|
+
<div class="plan-loading-actions">
|
|
1436
|
+
<button class="btn-toolbar btn-sm plan-cancel-btn" onclick="app.cancelPlanGeneration()">Stop</button>
|
|
1437
|
+
<button class="btn-toolbar btn-sm" onclick="app.regeneratePlan()">Regenerate</button>
|
|
1438
|
+
</div>
|
|
1439
|
+
<!-- Auto-start toggle visible during generation -->
|
|
1440
|
+
<div class="plan-autostart-toggle">
|
|
1441
|
+
<label class="plan-autostart-label">
|
|
1442
|
+
<input type="checkbox" id="ralphAutoStartStep2" onchange="app.ralphWizardConfig.autoStart = this.checked">
|
|
1443
|
+
<span class="plan-autostart-text">Auto-launch when plan completes</span>
|
|
1444
|
+
</label>
|
|
1445
|
+
</div>
|
|
1446
|
+
</div>
|
|
1447
|
+
|
|
1448
|
+
<!-- Stopped/Error state -->
|
|
1449
|
+
<div id="planGenerationError" class="plan-section hidden">
|
|
1450
|
+
<div class="plan-stopped-indicator" id="planStoppedIndicator">
|
|
1451
|
+
<span class="plan-stopped-icon">■</span>
|
|
1452
|
+
<span class="plan-stopped-text">Stopped</span>
|
|
1453
|
+
</div>
|
|
1454
|
+
<p class="plan-error-msg" id="planErrorMsg"></p>
|
|
1455
|
+
<div class="plan-actions">
|
|
1456
|
+
<button class="btn-toolbar btn-primary" onclick="app.generatePlan()">Regenerate Plan</button>
|
|
1457
|
+
</div>
|
|
1458
|
+
<p class="plan-skip-hint">Use <strong>Back</strong> to edit your task, or <strong>Next</strong> to continue without a plan</p>
|
|
1459
|
+
</div>
|
|
1460
|
+
|
|
1461
|
+
<!-- Editor state -->
|
|
1462
|
+
<div id="planEditor" class="plan-section hidden">
|
|
1463
|
+
<div class="plan-editor-header">
|
|
1464
|
+
<span>Implementation Plan <span class="plan-stats" id="planStats"></span></span>
|
|
1465
|
+
<div class="plan-editor-actions">
|
|
1466
|
+
<div class="plan-option-group">
|
|
1467
|
+
<label>Detail:</label>
|
|
1468
|
+
<div class="plan-detail-btns">
|
|
1469
|
+
<button type="button" class="plan-detail-btn" data-detail="standard" onclick="app.setPlanDetail('standard')" title="Single-pass generation with Opus 4.5">Standard</button>
|
|
1470
|
+
<button type="button" class="plan-detail-btn active" data-detail="detailed" onclick="app.setPlanDetail('detailed')" title="Enhanced: parallel subagents + verification (slower but more thorough)">Enhanced</button>
|
|
1471
|
+
</div>
|
|
1472
|
+
</div>
|
|
1473
|
+
<button class="btn-toolbar btn-sm" onclick="app.regeneratePlan()">Regenerate</button>
|
|
1474
|
+
</div>
|
|
1475
|
+
</div>
|
|
1476
|
+
<div id="planItemsList" class="plan-items-list"></div>
|
|
1477
|
+
</div>
|
|
1478
|
+
</div>
|
|
1479
|
+
|
|
1480
|
+
<!-- Step 3: Preview & Launch -->
|
|
1481
|
+
<div class="wizard-page hidden" id="ralphWizardStep3">
|
|
1482
|
+
<div class="ralph-preview-section">
|
|
1483
|
+
<label>Prompt Preview</label>
|
|
1484
|
+
<div class="ralph-prompt-preview" id="ralphPromptPreview"></div>
|
|
1485
|
+
</div>
|
|
1486
|
+
|
|
1487
|
+
<div class="ralph-config-summary">
|
|
1488
|
+
<div class="config-summary-row">
|
|
1489
|
+
<span class="config-label">Completion Phrase:</span>
|
|
1490
|
+
<code id="summaryPhrase">COMPLETE</code>
|
|
1491
|
+
</div>
|
|
1492
|
+
<div class="config-summary-row">
|
|
1493
|
+
<span class="config-label">Max Iterations:</span>
|
|
1494
|
+
<span id="summaryIterations">10</span>
|
|
1495
|
+
</div>
|
|
1496
|
+
<div class="config-summary-row">
|
|
1497
|
+
<span class="config-label">Case:</span>
|
|
1498
|
+
<span id="summaryCase">testcase</span>
|
|
1499
|
+
</div>
|
|
1500
|
+
<div class="config-summary-row" style="display: none;">
|
|
1501
|
+
<span class="config-label">Plan:</span>
|
|
1502
|
+
<span id="summaryPlan">-</span>
|
|
1503
|
+
</div>
|
|
1504
|
+
</div>
|
|
1505
|
+
|
|
1506
|
+
<!-- Advanced Options (Collapsible) -->
|
|
1507
|
+
<details class="advanced-options">
|
|
1508
|
+
<summary>Advanced Options</summary>
|
|
1509
|
+
<div class="advanced-options-content">
|
|
1510
|
+
<div class="form-row form-row-switch">
|
|
1511
|
+
<label>Enable Respawn</label>
|
|
1512
|
+
<label class="switch">
|
|
1513
|
+
<input type="checkbox" id="ralphEnableRespawn">
|
|
1514
|
+
<span class="slider"></span>
|
|
1515
|
+
</label>
|
|
1516
|
+
<span class="form-hint">Auto-restart sessions when context fills up (usually not needed)</span>
|
|
1517
|
+
</div>
|
|
1518
|
+
</div>
|
|
1519
|
+
</details>
|
|
1520
|
+
</div>
|
|
1521
|
+
</div>
|
|
1522
|
+
|
|
1523
|
+
<!-- Wizard Footer -->
|
|
1524
|
+
<div class="wizard-footer">
|
|
1525
|
+
<button class="btn-toolbar" id="ralphBackBtn" onclick="app.ralphWizardBack()" style="display: none;">Back</button>
|
|
1526
|
+
<div class="wizard-footer-right">
|
|
1527
|
+
<button class="btn-toolbar" onclick="app.closeRalphWizard()">Cancel</button>
|
|
1528
|
+
<button class="btn-toolbar btn-primary" id="ralphNextBtn" onclick="app.ralphWizardNext()">Next</button>
|
|
1529
|
+
<button class="btn-toolbar btn-success" id="ralphStartBtn" onclick="app.startRalphLoop()" style="display: none;">Start Loop</button>
|
|
1530
|
+
</div>
|
|
1531
|
+
</div>
|
|
1532
|
+
</div>
|
|
1533
|
+
</div>
|
|
1534
|
+
|
|
1535
|
+
|
|
1536
|
+
<!-- Kill All Confirmation Modal -->
|
|
1537
|
+
<div class="modal" id="killAllModal">
|
|
1538
|
+
<div class="modal-backdrop" onclick="app.closeKillAllModal()"></div>
|
|
1539
|
+
<div class="modal-content modal-sm">
|
|
1540
|
+
<div class="modal-header">
|
|
1541
|
+
<h3>Kill All Sessions</h3>
|
|
1542
|
+
<button class="modal-close" onclick="app.closeKillAllModal()" aria-label="Close kill all modal">×</button>
|
|
1543
|
+
</div>
|
|
1544
|
+
<div class="modal-body">
|
|
1545
|
+
<p class="modal-warning-text">Choose how to close <span id="killAllCount">0</span> session(s):</p>
|
|
1546
|
+
</div>
|
|
1547
|
+
<div class="close-options">
|
|
1548
|
+
<button class="close-option" onclick="app.confirmKillAll(false)">
|
|
1549
|
+
<span class="close-option-title">Remove All Tabs</span>
|
|
1550
|
+
<span class="close-option-desc">Tmux sessions keep running in background</span>
|
|
1551
|
+
</button>
|
|
1552
|
+
<button class="close-option close-option-danger" onclick="app.confirmKillAll(true)">
|
|
1553
|
+
<span class="close-option-title">Kill All Claude + Tmux</span>
|
|
1554
|
+
<span class="close-option-desc">Terminate everything completely</span>
|
|
1555
|
+
</button>
|
|
1556
|
+
</div>
|
|
1557
|
+
<div class="modal-footer-cancel">
|
|
1558
|
+
<button class="btn-toolbar btn-sm" onclick="app.closeKillAllModal()">Cancel</button>
|
|
1559
|
+
</div>
|
|
1560
|
+
</div>
|
|
1561
|
+
</div>
|
|
1562
|
+
|
|
1563
|
+
<!-- Notification Drawer -->
|
|
1564
|
+
<div class="notification-drawer" id="notifDrawer">
|
|
1565
|
+
<div class="notif-drawer-header">
|
|
1566
|
+
<span class="notif-drawer-title">Notifications</span>
|
|
1567
|
+
<div class="notif-drawer-actions">
|
|
1568
|
+
<button class="btn-notif-action" onclick="app.notificationManager?.markAllRead()" title="Mark all read">✓</button>
|
|
1569
|
+
<button class="btn-notif-action" onclick="app.notificationManager?.clearAll()" title="Clear all">🗑</button>
|
|
1570
|
+
<button class="btn-notif-action" onclick="app.toggleNotifications()" title="Close">×</button>
|
|
1571
|
+
</div>
|
|
1572
|
+
</div>
|
|
1573
|
+
<div class="notif-drawer-list" id="notifList"></div>
|
|
1574
|
+
<div class="notif-drawer-empty" id="notifEmpty">No notifications</div>
|
|
1575
|
+
</div>
|
|
1576
|
+
|
|
1577
|
+
<!-- Token Stats Modal -->
|
|
1578
|
+
<div class="modal" id="tokenStatsModal">
|
|
1579
|
+
<div class="modal-backdrop" onclick="app.closeTokenStats()"></div>
|
|
1580
|
+
<div class="modal-content token-stats-modal">
|
|
1581
|
+
<div class="modal-header">
|
|
1582
|
+
<h3>Token Usage Statistics</h3>
|
|
1583
|
+
<button class="modal-close" onclick="app.closeTokenStats()" aria-label="Close token statistics">×</button>
|
|
1584
|
+
</div>
|
|
1585
|
+
<div class="modal-body">
|
|
1586
|
+
<div class="stats-summary" id="statsSummary"></div>
|
|
1587
|
+
<div class="stats-chart-container">
|
|
1588
|
+
<div class="stats-chart-label">Last 7 Days</div>
|
|
1589
|
+
<div class="stats-chart" id="statsChart"></div>
|
|
1590
|
+
<div class="stats-chart-days" id="statsChartDays"></div>
|
|
1591
|
+
</div>
|
|
1592
|
+
<div class="stats-table-container">
|
|
1593
|
+
<div class="stats-table-label">Daily Breakdown</div>
|
|
1594
|
+
<div class="stats-table" id="statsTable"></div>
|
|
1595
|
+
</div>
|
|
1596
|
+
</div>
|
|
1597
|
+
</div>
|
|
1598
|
+
</div>
|
|
1599
|
+
</div>
|
|
1600
|
+
|
|
1601
|
+
<!-- Save Preset Modal -->
|
|
1602
|
+
<div class="modal" id="savePresetModal">
|
|
1603
|
+
<div class="modal-backdrop" onclick="app.closeSavePresetModal()"></div>
|
|
1604
|
+
<div class="modal-content modal-sm">
|
|
1605
|
+
<div class="modal-header">
|
|
1606
|
+
<h3>Save Respawn Preset</h3>
|
|
1607
|
+
<button class="modal-close" onclick="app.closeSavePresetModal()" aria-label="Close">×</button>
|
|
1608
|
+
</div>
|
|
1609
|
+
<div class="modal-body">
|
|
1610
|
+
<div class="form-row">
|
|
1611
|
+
<label>Preset Name</label>
|
|
1612
|
+
<input type="text" id="presetNameInput" placeholder="My Custom Preset" maxlength="30">
|
|
1613
|
+
</div>
|
|
1614
|
+
<div class="form-row">
|
|
1615
|
+
<label>Description (optional)</label>
|
|
1616
|
+
<input type="text" id="presetDescriptionInput" placeholder="When to use this preset" maxlength="100">
|
|
1617
|
+
</div>
|
|
1618
|
+
</div>
|
|
1619
|
+
<div class="modal-footer">
|
|
1620
|
+
<button class="btn btn-secondary" onclick="app.closeSavePresetModal()">Cancel</button>
|
|
1621
|
+
<button class="btn btn-primary" onclick="app.confirmSavePreset()">Save Preset</button>
|
|
1622
|
+
</div>
|
|
1623
|
+
</div>
|
|
1624
|
+
</div>
|
|
1625
|
+
|
|
1626
|
+
<!-- Session Lifecycle Audit Log (floating window) -->
|
|
1627
|
+
<div id="lifecycleWindow" style="display:none;position:fixed;z-index:2000;top:60px;left:50%;transform:translateX(-50%);width:900px;max-width:95vw;min-width:400px;min-height:250px;height:520px;background:#111;border:1px solid #333;border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,0.6);resize:both;overflow:hidden">
|
|
1628
|
+
<div id="lifecycleWindowHeader" style="display:flex;align-items:center;justify-content:space-between;padding:6px 12px;background:#1a1a2e;border-bottom:1px solid #333;cursor:move;user-select:none;border-radius:8px 8px 0 0">
|
|
1629
|
+
<span style="color:#e0e0e0;font-size:13px;font-weight:600">Session Lifecycle Log</span>
|
|
1630
|
+
<div style="display:flex;gap:8px;align-items:center">
|
|
1631
|
+
<div style="display:flex;gap:6px;flex-wrap:nowrap">
|
|
1632
|
+
<select id="lifecycleFilterEvent" style="background:#0d0d0d;color:#e0e0e0;border:1px solid #444;border-radius:4px;padding:2px 6px;font-size:11px">
|
|
1633
|
+
<option value="">All Events</option>
|
|
1634
|
+
<option value="created">Created</option>
|
|
1635
|
+
<option value="started">Started</option>
|
|
1636
|
+
<option value="exit">Exit</option>
|
|
1637
|
+
<option value="deleted">Deleted</option>
|
|
1638
|
+
<option value="recovered">Recovered</option>
|
|
1639
|
+
<option value="stale_cleaned">Stale Cleaned</option>
|
|
1640
|
+
<option value="mux_died">Mux Died</option>
|
|
1641
|
+
<option value="server_started">Server Started</option>
|
|
1642
|
+
<option value="server_stopped">Server Stopped</option>
|
|
1643
|
+
</select>
|
|
1644
|
+
<input id="lifecycleFilterSession" type="text" placeholder="Session ID..." style="background:#0d0d0d;color:#e0e0e0;border:1px solid #444;border-radius:4px;padding:2px 6px;font-size:11px;width:120px">
|
|
1645
|
+
<button onclick="app.loadLifecycleLog()" style="background:#333;color:#ccc;border:1px solid #444;border-radius:4px;padding:2px 8px;font-size:11px;cursor:pointer">Refresh</button>
|
|
1646
|
+
</div>
|
|
1647
|
+
<button onclick="app.closeLifecycleLog()" style="background:none;border:none;color:#888;font-size:18px;cursor:pointer;padding:0 4px;line-height:1" aria-label="Close">×</button>
|
|
1648
|
+
</div>
|
|
1649
|
+
</div>
|
|
1650
|
+
<div style="overflow:auto;height:calc(100% - 36px);padding:4px 0">
|
|
1651
|
+
<table id="lifecycleTable" style="width:100%;border-collapse:collapse;font-size:12px;font-family:monospace">
|
|
1652
|
+
<thead>
|
|
1653
|
+
<tr style="color:#888;text-align:left;border-bottom:1px solid #333;position:sticky;top:0;background:#111">
|
|
1654
|
+
<th style="padding:4px 8px">Time</th>
|
|
1655
|
+
<th style="padding:4px 8px">Event</th>
|
|
1656
|
+
<th style="padding:4px 8px">Session</th>
|
|
1657
|
+
<th style="padding:4px 8px">Reason</th>
|
|
1658
|
+
<th style="padding:4px 8px">Extra</th>
|
|
1659
|
+
</tr>
|
|
1660
|
+
</thead>
|
|
1661
|
+
<tbody id="lifecycleTableBody"></tbody>
|
|
1662
|
+
</table>
|
|
1663
|
+
<div id="lifecycleEmpty" style="color:#666;text-align:center;padding:20px;display:none">No lifecycle entries found</div>
|
|
1664
|
+
</div>
|
|
1665
|
+
</div>
|
|
1666
|
+
|
|
1667
|
+
<!-- SVG Overlay for Subagent Connection Lines -->
|
|
1668
|
+
<svg id="connectionLines" class="connection-lines-svg">
|
|
1669
|
+
<!-- Lines drawn dynamically -->
|
|
1670
|
+
</svg>
|
|
1671
|
+
|
|
1672
|
+
<script defer src="app.js?v=0.1631"></script>
|
|
1673
|
+
<script defer src="ralph-wizard.js?v=0.1631"></script>
|
|
1674
|
+
</body>
|
|
1675
|
+
</html>
|