@virtengine/openfleet 0.25.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/.env.example +914 -0
  2. package/LICENSE +190 -0
  3. package/README.md +500 -0
  4. package/agent-endpoint.mjs +918 -0
  5. package/agent-hook-bridge.mjs +230 -0
  6. package/agent-hooks.mjs +1188 -0
  7. package/agent-pool.mjs +2403 -0
  8. package/agent-prompts.mjs +689 -0
  9. package/agent-sdk.mjs +141 -0
  10. package/anomaly-detector.mjs +1195 -0
  11. package/autofix.mjs +1294 -0
  12. package/claude-shell.mjs +708 -0
  13. package/cli.mjs +906 -0
  14. package/codex-config.mjs +1274 -0
  15. package/codex-model-profiles.mjs +135 -0
  16. package/codex-shell.mjs +762 -0
  17. package/config-doctor.mjs +613 -0
  18. package/config.mjs +1720 -0
  19. package/conflict-resolver.mjs +248 -0
  20. package/container-runner.mjs +450 -0
  21. package/copilot-shell.mjs +827 -0
  22. package/daemon-restart-policy.mjs +56 -0
  23. package/diff-stats.mjs +282 -0
  24. package/error-detector.mjs +829 -0
  25. package/fetch-runtime.mjs +34 -0
  26. package/fleet-coordinator.mjs +838 -0
  27. package/get-telegram-chat-id.mjs +71 -0
  28. package/git-safety.mjs +170 -0
  29. package/github-reconciler.mjs +403 -0
  30. package/hook-profiles.mjs +651 -0
  31. package/kanban-adapter.mjs +4491 -0
  32. package/lib/logger.mjs +645 -0
  33. package/maintenance.mjs +828 -0
  34. package/merge-strategy.mjs +1171 -0
  35. package/monitor.mjs +12207 -0
  36. package/openfleet.config.example.json +115 -0
  37. package/openfleet.schema.json +465 -0
  38. package/package.json +203 -0
  39. package/postinstall.mjs +187 -0
  40. package/pr-cleanup-daemon.mjs +978 -0
  41. package/preflight.mjs +408 -0
  42. package/prepublish-check.mjs +90 -0
  43. package/presence.mjs +328 -0
  44. package/primary-agent.mjs +282 -0
  45. package/publish.mjs +151 -0
  46. package/repo-root.mjs +29 -0
  47. package/restart-controller.mjs +100 -0
  48. package/review-agent.mjs +557 -0
  49. package/rotate-agent-logs.sh +133 -0
  50. package/sdk-conflict-resolver.mjs +973 -0
  51. package/session-tracker.mjs +880 -0
  52. package/setup.mjs +3937 -0
  53. package/shared-knowledge.mjs +410 -0
  54. package/shared-state-manager.mjs +841 -0
  55. package/shared-workspace-cli.mjs +199 -0
  56. package/shared-workspace-registry.mjs +537 -0
  57. package/shared-workspaces.json +18 -0
  58. package/startup-service.mjs +1070 -0
  59. package/sync-engine.mjs +1063 -0
  60. package/task-archiver.mjs +801 -0
  61. package/task-assessment.mjs +550 -0
  62. package/task-claims.mjs +924 -0
  63. package/task-complexity.mjs +581 -0
  64. package/task-executor.mjs +5111 -0
  65. package/task-store.mjs +753 -0
  66. package/telegram-bot.mjs +9281 -0
  67. package/telegram-sentinel.mjs +2010 -0
  68. package/ui/app.js +867 -0
  69. package/ui/app.legacy.js +1464 -0
  70. package/ui/app.monolith.js +2488 -0
  71. package/ui/components/charts.js +226 -0
  72. package/ui/components/chat-view.js +567 -0
  73. package/ui/components/command-palette.js +587 -0
  74. package/ui/components/diff-viewer.js +190 -0
  75. package/ui/components/forms.js +327 -0
  76. package/ui/components/kanban-board.js +451 -0
  77. package/ui/components/session-list.js +305 -0
  78. package/ui/components/shared.js +473 -0
  79. package/ui/index.html +70 -0
  80. package/ui/modules/api.js +297 -0
  81. package/ui/modules/icons.js +461 -0
  82. package/ui/modules/router.js +81 -0
  83. package/ui/modules/settings-schema.js +261 -0
  84. package/ui/modules/state.js +679 -0
  85. package/ui/modules/telegram.js +331 -0
  86. package/ui/modules/utils.js +270 -0
  87. package/ui/styles/animations.css +140 -0
  88. package/ui/styles/base.css +98 -0
  89. package/ui/styles/components.css +1915 -0
  90. package/ui/styles/kanban.css +286 -0
  91. package/ui/styles/layout.css +809 -0
  92. package/ui/styles/sessions.css +827 -0
  93. package/ui/styles/variables.css +188 -0
  94. package/ui/styles.css +141 -0
  95. package/ui/styles.monolith.css +1046 -0
  96. package/ui/tabs/agents.js +1417 -0
  97. package/ui/tabs/chat.js +74 -0
  98. package/ui/tabs/control.js +887 -0
  99. package/ui/tabs/dashboard.js +515 -0
  100. package/ui/tabs/infra.js +537 -0
  101. package/ui/tabs/logs.js +783 -0
  102. package/ui/tabs/settings.js +1487 -0
  103. package/ui/tabs/tasks.js +1385 -0
  104. package/ui-server.mjs +4073 -0
  105. package/update-check.mjs +465 -0
  106. package/utils.mjs +172 -0
  107. package/ve-kanban.mjs +654 -0
  108. package/ve-kanban.ps1 +1365 -0
  109. package/ve-kanban.sh +18 -0
  110. package/ve-orchestrator.mjs +340 -0
  111. package/ve-orchestrator.ps1 +6546 -0
  112. package/ve-orchestrator.sh +18 -0
  113. package/vibe-kanban-wrapper.mjs +41 -0
  114. package/vk-error-resolver.mjs +470 -0
  115. package/vk-log-stream.mjs +914 -0
  116. package/whatsapp-channel.mjs +520 -0
  117. package/workspace-monitor.mjs +581 -0
  118. package/workspace-reaper.mjs +405 -0
  119. package/workspace-registry.mjs +238 -0
  120. package/worktree-manager.mjs +1266 -0
@@ -0,0 +1,226 @@
1
+ /* ─────────────────────────────────────────────────────────────
2
+ * VirtEngine Control Center – Chart Components
3
+ * DonutChart, ProgressBar, MiniSparkline
4
+ * ────────────────────────────────────────────────────────────── */
5
+
6
+ import { h } from "preact";
7
+ import htm from "htm";
8
+
9
+ const html = htm.bind(h);
10
+
11
+ /* ═══════════════════════════════════════════════
12
+ * DonutChart
13
+ * ═══════════════════════════════════════════════ */
14
+
15
+ /**
16
+ * SVG donut chart with animated arcs and a legend below.
17
+ *
18
+ * @param {{
19
+ * segments: Array<{value: number, color: string, label: string}>,
20
+ * size?: number,
21
+ * strokeWidth?: number
22
+ * }} props
23
+ */
24
+ export function DonutChart({ segments = [], size = 120, strokeWidth = 12 }) {
25
+ const total = segments.reduce((sum, seg) => sum + (seg.value || 0), 0);
26
+ if (!total) {
27
+ return html`<div class="text-center meta-text">No data</div>`;
28
+ }
29
+
30
+ const cx = size / 2;
31
+ const cy = size / 2;
32
+ const r = (size - strokeWidth) / 2 - 2; // radius with some padding
33
+ const circumference = 2 * Math.PI * r;
34
+ let offset = 0;
35
+
36
+ const arcs = segments.map((seg) => {
37
+ const pct = seg.value / total;
38
+ const dash = pct * circumference;
39
+ const currentOffset = offset;
40
+ offset += dash;
41
+ return html`
42
+ <circle
43
+ cx=${cx}
44
+ cy=${cy}
45
+ r=${r}
46
+ fill="none"
47
+ stroke=${seg.color}
48
+ stroke-width=${strokeWidth}
49
+ stroke-dasharray="${dash} ${circumference - dash}"
50
+ stroke-dashoffset=${-currentOffset}
51
+ stroke-linecap="round"
52
+ style="transition: stroke-dasharray 0.6s ease, stroke-dashoffset 0.6s ease"
53
+ />
54
+ `;
55
+ });
56
+
57
+ return html`
58
+ <div class="donut-wrap">
59
+ <svg
60
+ width=${size}
61
+ height=${size}
62
+ viewBox="0 0 ${size} ${size}"
63
+ style="transform: rotate(-90deg); display: block; margin: 0 auto"
64
+ >
65
+ <!-- Background track -->
66
+ <circle
67
+ cx=${cx}
68
+ cy=${cy}
69
+ r=${r}
70
+ fill="none"
71
+ stroke="var(--bg-secondary, #2a2a3e)"
72
+ stroke-width=${strokeWidth}
73
+ opacity="0.3"
74
+ />
75
+ ${arcs}
76
+ </svg>
77
+ <div
78
+ class="donut-center"
79
+ style="
80
+ position: absolute; top: 50%; left: 50%;
81
+ transform: translate(-50%, -50%);
82
+ font-size: 22px; font-weight: 700;
83
+ color: var(--text-primary, #fff);
84
+ "
85
+ >
86
+ ${total}
87
+ </div>
88
+ </div>
89
+ <div class="donut-legend">
90
+ ${segments.map(
91
+ (seg) => html`
92
+ <span class="donut-legend-item">
93
+ <span
94
+ class="donut-legend-swatch"
95
+ style="background: ${seg.color}"
96
+ ></span>
97
+ ${seg.label} (${seg.value})
98
+ </span>
99
+ `,
100
+ )}
101
+ </div>
102
+ `;
103
+ }
104
+
105
+ /* ═══════════════════════════════════════════════
106
+ * ProgressBar
107
+ * ═══════════════════════════════════════════════ */
108
+
109
+ /**
110
+ * Horizontal progress bar with gradient fill and smooth transition.
111
+ *
112
+ * @param {{
113
+ * value: number,
114
+ * max?: number,
115
+ * color?: string,
116
+ * height?: number,
117
+ * animated?: boolean
118
+ * }} props
119
+ */
120
+ export function ProgressBar({
121
+ value = 0,
122
+ max = 100,
123
+ color,
124
+ height = 8,
125
+ animated = true,
126
+ }) {
127
+ const pct = Math.min(100, Math.max(0, (value / max) * 100));
128
+ const bg = color || "var(--accent, #5b6eae)";
129
+ const transition = animated ? "width 0.5s ease" : "none";
130
+
131
+ return html`
132
+ <div
133
+ class="progress-bar"
134
+ style="height:${height}px;border-radius:${height / 2}px;
135
+ background:var(--bg-secondary, rgba(255,255,255,0.08));overflow:hidden"
136
+ >
137
+ <div
138
+ class="progress-bar-fill"
139
+ style="width:${pct}%;height:100%;border-radius:${height / 2}px;
140
+ background:${bg};transition:${transition}"
141
+ ></div>
142
+ </div>
143
+ `;
144
+ }
145
+
146
+ /* ═══════════════════════════════════════════════
147
+ * MiniSparkline
148
+ * ═══════════════════════════════════════════════ */
149
+
150
+ /**
151
+ * Tiny inline sparkline chart using SVG polyline.
152
+ *
153
+ * @param {{
154
+ * data: number[],
155
+ * color?: string,
156
+ * height?: number,
157
+ * width?: number
158
+ * }} props
159
+ */
160
+ let _sparkId = 0;
161
+
162
+ export function MiniSparkline({
163
+ data = [],
164
+ color = "var(--accent, #5b6eae)",
165
+ height = 24,
166
+ width = 80,
167
+ }) {
168
+ if (!data.length) return null;
169
+
170
+ const gradId = `sparkGrad-${++_sparkId}`;
171
+
172
+ const min = Math.min(...data);
173
+ const max = Math.max(...data);
174
+ const range = max - min || 1;
175
+ const padding = 2;
176
+ const usableH = height - padding * 2;
177
+ const usableW = width - padding * 2;
178
+ const step = data.length > 1 ? usableW / (data.length - 1) : 0;
179
+
180
+ const points = data
181
+ .map((v, i) => {
182
+ const x = padding + i * step;
183
+ const y = padding + usableH - ((v - min) / range) * usableH;
184
+ return `${x.toFixed(1)},${y.toFixed(1)}`;
185
+ })
186
+ .join(" ");
187
+
188
+ // Filled area path
189
+ const firstX = padding;
190
+ const lastX = padding + (data.length - 1) * step;
191
+ const areaPath =
192
+ `M${firstX},${height} ` +
193
+ data
194
+ .map((v, i) => {
195
+ const x = padding + i * step;
196
+ const y = padding + usableH - ((v - min) / range) * usableH;
197
+ return `L${x.toFixed(1)},${y.toFixed(1)}`;
198
+ })
199
+ .join(" ") +
200
+ ` L${lastX.toFixed(1)},${height} Z`;
201
+
202
+ return html`
203
+ <svg
204
+ width=${width}
205
+ height=${height}
206
+ viewBox="0 0 ${width} ${height}"
207
+ style="display:block"
208
+ >
209
+ <defs>
210
+ <linearGradient id=${gradId} x1="0" y1="0" x2="0" y2="1">
211
+ <stop offset="0%" stop-color=${color} stop-opacity="0.25" />
212
+ <stop offset="100%" stop-color=${color} stop-opacity="0" />
213
+ </linearGradient>
214
+ </defs>
215
+ <path d=${areaPath} fill="url(#${gradId})" />
216
+ <polyline
217
+ points=${points}
218
+ fill="none"
219
+ stroke=${color}
220
+ stroke-width="1.5"
221
+ stroke-linecap="round"
222
+ stroke-linejoin="round"
223
+ />
224
+ </svg>
225
+ `;
226
+ }