crewswarm 0.9.2 → 0.9.3

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 (207) hide show
  1. package/README.md +22 -9
  2. package/apps/dashboard/dist/assets/{chat-core-Cx4sTxDd.js → chat-core-3KirthZA.js} +1 -1
  3. package/apps/dashboard/dist/assets/index-GSWxxEPO.js +2 -0
  4. package/apps/dashboard/dist/assets/{tab-pm-loop-tab-Bfd449B4.js → tab-pm-loop-tab-DiAPTJXu.js} +1 -1
  5. package/apps/dashboard/dist/assets/{tab-projects-tab-DhNWnlzt.js → tab-projects-tab-SFH4E--a.js} +1 -1
  6. package/apps/dashboard/dist/assets/tab-settings-tab-BselH1c0.js +1 -0
  7. package/apps/dashboard/dist/index.html +82 -11
  8. package/apps/vibe/README.md +2 -2
  9. package/apps/vibe/package.json +1 -1
  10. package/apps/vibe/server.mjs +3 -3
  11. package/crew-lead.mjs +34 -4
  12. package/lib/bridges/gateway-ws.mjs +4 -0
  13. package/lib/crew-lead/chat-handler.mjs +34 -0
  14. package/lib/crew-lead/http-server.mjs +55 -14
  15. package/lib/crew-lead/llm-caller.mjs +24 -8
  16. package/lib/crew-lead/prompts.mjs +7 -0
  17. package/lib/crew-lead/wave-dispatcher.mjs +15 -3
  18. package/lib/crew-lead/ws-router.mjs +219 -27
  19. package/lib/engines/engine-registry.mjs +9 -0
  20. package/lib/engines/rt-envelope.mjs +1 -0
  21. package/lib/engines/runners.mjs +5 -2
  22. package/lib/runtime/paths.mjs +12 -8
  23. package/package.json +35 -15
  24. package/scripts/capture-build-flow.mjs +118 -0
  25. package/scripts/coverage-report.mjs +209 -0
  26. package/scripts/coverage-summary.mjs +47 -0
  27. package/scripts/dashboard-validation.mjs +74 -0
  28. package/scripts/dashboard.mjs +560 -70
  29. package/scripts/live-bridge-matrix.mjs +79 -0
  30. package/scripts/live-cli-matrix.mjs +166 -0
  31. package/scripts/live-crewchat-check.mjs +42 -0
  32. package/scripts/live-engine-matrix.mjs +50 -0
  33. package/scripts/live-provider-failover-matrix.mjs +107 -0
  34. package/scripts/live-provider-matrix.mjs +228 -0
  35. package/scripts/restart-all-from-repo.sh +4 -4
  36. package/scripts/smoke-dispatch.mjs +4 -1
  37. package/scripts/test-blast-radius.mjs +204 -0
  38. package/scripts/test-report-summary.mjs +88 -0
  39. package/scripts/test-reporter.mjs +651 -0
  40. package/scripts/test-rerun.mjs +136 -0
  41. package/scripts/tmux-bridge +130 -0
  42. package/apps/dashboard/dist/assets/chat-core-Cx4sTxDd.js.br +0 -0
  43. package/apps/dashboard/dist/assets/cli-process-COMRNPqr.js.br +0 -0
  44. package/apps/dashboard/dist/assets/components-BS9fQjE_.js.br +0 -0
  45. package/apps/dashboard/dist/assets/core-utils-CmOkXgzi.js.br +0 -0
  46. package/apps/dashboard/dist/assets/index-CF0aJRtC.css.br +0 -0
  47. package/apps/dashboard/dist/assets/index-DnClJ1ee.js +0 -2
  48. package/apps/dashboard/dist/assets/index-DnClJ1ee.js.br +0 -0
  49. package/apps/dashboard/dist/assets/orchestration-Ca2DLWN-.js.br +0 -0
  50. package/apps/dashboard/dist/assets/setup-wizard-CA0Or47w.js.br +0 -0
  51. package/apps/dashboard/dist/assets/tab-agents-tab-BgpIsjkw.js.br +0 -0
  52. package/apps/dashboard/dist/assets/tab-comms-tab-kguqTIzD.js.br +0 -0
  53. package/apps/dashboard/dist/assets/tab-contacts-tab-DiOyMYth.js.br +0 -0
  54. package/apps/dashboard/dist/assets/tab-engines-tab-BsdZVvU0.js.br +0 -0
  55. package/apps/dashboard/dist/assets/tab-memory-tab-Cu6u13EQ.js.br +0 -0
  56. package/apps/dashboard/dist/assets/tab-models-tab-BLEjmd19.js.br +0 -0
  57. package/apps/dashboard/dist/assets/tab-pm-loop-tab-Bfd449B4.js.br +0 -0
  58. package/apps/dashboard/dist/assets/tab-projects-tab-DhNWnlzt.js.br +0 -0
  59. package/apps/dashboard/dist/assets/tab-prompts-tab-DVkUNaJd.js.br +0 -0
  60. package/apps/dashboard/dist/assets/tab-services-tab-DU_LH3uG.js.br +0 -0
  61. package/apps/dashboard/dist/assets/tab-settings-tab-Bn4nXtDe.js +0 -1
  62. package/apps/dashboard/dist/assets/tab-settings-tab-Bn4nXtDe.js.br +0 -0
  63. package/apps/dashboard/dist/assets/tab-skills-tab-BpY0uZHW.js.br +0 -0
  64. package/apps/dashboard/dist/assets/tab-spending-tab-DEccQHnt.js.br +0 -0
  65. package/apps/dashboard/dist/assets/tab-swarm-chat-tab-BNrd88-r.js.br +0 -0
  66. package/apps/dashboard/dist/assets/tab-swarm-tab-B1AcjL1W.js.br +0 -0
  67. package/apps/dashboard/dist/assets/tab-usage-tab-BIOOnB-Y.js.br +0 -0
  68. package/apps/dashboard/dist/assets/tab-waves-tab-SaJDkb4x.js.br +0 -0
  69. package/apps/dashboard/dist/assets/tab-workflows-tab-B-soSy1k.js.br +0 -0
  70. package/apps/dashboard/dist/index.html.br +0 -0
  71. package/apps/dashboard/dist/index.html.gz +0 -0
  72. package/apps/dashboard/index.html +0 -6529
  73. package/apps/dashboard/package.json +0 -15
  74. package/apps/dashboard/src/app.js +0 -2828
  75. package/apps/dashboard/src/app.js.br +0 -0
  76. package/apps/dashboard/src/app.js.gz +0 -0
  77. package/apps/dashboard/src/chat/chat-actions.js +0 -1847
  78. package/apps/dashboard/src/chat/chat-actions.js.br +0 -0
  79. package/apps/dashboard/src/chat/unified-messages.js +0 -327
  80. package/apps/dashboard/src/chat/unified-messages.js.br +0 -0
  81. package/apps/dashboard/src/cli-process.js +0 -208
  82. package/apps/dashboard/src/cli-process.js.br +0 -0
  83. package/apps/dashboard/src/cli-process.js.gz +0 -0
  84. package/apps/dashboard/src/components/active-tasks-panel.js +0 -175
  85. package/apps/dashboard/src/components/active-tasks-panel.js.br +0 -0
  86. package/apps/dashboard/src/core/api.js +0 -18
  87. package/apps/dashboard/src/core/api.js.br +0 -0
  88. package/apps/dashboard/src/core/dom.js +0 -228
  89. package/apps/dashboard/src/core/dom.js.br +0 -0
  90. package/apps/dashboard/src/core/state.js +0 -91
  91. package/apps/dashboard/src/core/state.js.br +0 -0
  92. package/apps/dashboard/src/core/task-manager.js +0 -134
  93. package/apps/dashboard/src/core/task-manager.js.br +0 -0
  94. package/apps/dashboard/src/orchestration-status.js +0 -127
  95. package/apps/dashboard/src/orchestration-status.js.br +0 -0
  96. package/apps/dashboard/src/setup-wizard.js +0 -562
  97. package/apps/dashboard/src/setup-wizard.js.br +0 -0
  98. package/apps/dashboard/src/styles.css +0 -2085
  99. package/apps/dashboard/src/styles.css.br +0 -0
  100. package/apps/dashboard/src/styles.css.gz +0 -0
  101. package/apps/dashboard/src/tabs/agents-tab.js +0 -2237
  102. package/apps/dashboard/src/tabs/agents-tab.js.br +0 -0
  103. package/apps/dashboard/src/tabs/benchmarks-tab.js +0 -229
  104. package/apps/dashboard/src/tabs/benchmarks-tab.js.br +0 -0
  105. package/apps/dashboard/src/tabs/comms-tab.js +0 -955
  106. package/apps/dashboard/src/tabs/comms-tab.js.br +0 -0
  107. package/apps/dashboard/src/tabs/contacts-tab.js +0 -654
  108. package/apps/dashboard/src/tabs/contacts-tab.js.br +0 -0
  109. package/apps/dashboard/src/tabs/engines-tab.js +0 -175
  110. package/apps/dashboard/src/tabs/engines-tab.js.br +0 -0
  111. package/apps/dashboard/src/tabs/memory-tab.js +0 -182
  112. package/apps/dashboard/src/tabs/memory-tab.js.br +0 -0
  113. package/apps/dashboard/src/tabs/models-tab.js +0 -450
  114. package/apps/dashboard/src/tabs/models-tab.js.br +0 -0
  115. package/apps/dashboard/src/tabs/pm-loop-tab.js +0 -185
  116. package/apps/dashboard/src/tabs/pm-loop-tab.js.br +0 -0
  117. package/apps/dashboard/src/tabs/projects-tab.js +0 -663
  118. package/apps/dashboard/src/tabs/projects-tab.js.br +0 -0
  119. package/apps/dashboard/src/tabs/projects-tab.js.gz +0 -0
  120. package/apps/dashboard/src/tabs/prompts-tab.js +0 -160
  121. package/apps/dashboard/src/tabs/prompts-tab.js.br +0 -0
  122. package/apps/dashboard/src/tabs/services-tab.js +0 -202
  123. package/apps/dashboard/src/tabs/services-tab.js.br +0 -0
  124. package/apps/dashboard/src/tabs/settings-tab.js +0 -861
  125. package/apps/dashboard/src/tabs/settings-tab.js.br +0 -0
  126. package/apps/dashboard/src/tabs/skills-tab.js +0 -284
  127. package/apps/dashboard/src/tabs/skills-tab.js.br +0 -0
  128. package/apps/dashboard/src/tabs/spending-tab.js +0 -173
  129. package/apps/dashboard/src/tabs/spending-tab.js.br +0 -0
  130. package/apps/dashboard/src/tabs/swarm-chat-tab.js +0 -660
  131. package/apps/dashboard/src/tabs/swarm-chat-tab.js.br +0 -0
  132. package/apps/dashboard/src/tabs/swarm-tab.js +0 -538
  133. package/apps/dashboard/src/tabs/swarm-tab.js.br +0 -0
  134. package/apps/dashboard/src/tabs/usage-tab.js +0 -390
  135. package/apps/dashboard/src/tabs/usage-tab.js.br +0 -0
  136. package/apps/dashboard/src/tabs/waves-tab.js +0 -238
  137. package/apps/dashboard/src/tabs/waves-tab.js.br +0 -0
  138. package/apps/dashboard/src/tabs/workflows-tab.js +0 -747
  139. package/apps/dashboard/src/tabs/workflows-tab.js.br +0 -0
  140. package/apps/vibe/.crew/agent-memory/pipeline.json +0 -304
  141. package/apps/vibe/.crew/cost.json +0 -17
  142. package/apps/vibe/.crew/json-parse-metrics.jsonl +0 -27
  143. package/apps/vibe/.crew/pipeline-metrics.jsonl +0 -27
  144. package/apps/vibe/.crew/pipeline-runs/pipeline-0f90c392-2425-4ae5-850c-bd9d17b1d690.jsonl +0 -5
  145. package/apps/vibe/.crew/pipeline-runs/pipeline-1c269dd9-a63f-4fba-af81-5cf08048ef06.jsonl +0 -5
  146. package/apps/vibe/.crew/pipeline-runs/pipeline-288a7765-da24-4a22-89bc-1f3cc9b0562c.jsonl +0 -5
  147. package/apps/vibe/.crew/pipeline-runs/pipeline-2c78fd22-a657-4bd1-bc49-0679fb384409.jsonl +0 -5
  148. package/apps/vibe/.crew/pipeline-runs/pipeline-3da23550-22ed-4904-9a0a-8e79c1f3024c.jsonl +0 -5
  149. package/apps/vibe/.crew/pipeline-runs/pipeline-3e6fe08d-3264-404a-8df3-aab7efef10e7.jsonl +0 -5
  150. package/apps/vibe/.crew/pipeline-runs/pipeline-42eec610-57fe-4e09-9e7e-b315038495c2.jsonl +0 -5
  151. package/apps/vibe/.crew/pipeline-runs/pipeline-4438eb4c-ae13-42b1-90e2-b043d8983be8.jsonl +0 -5
  152. package/apps/vibe/.crew/pipeline-runs/pipeline-4740a9f5-86e7-44b6-a394-de433e291727.jsonl +0 -5
  153. package/apps/vibe/.crew/pipeline-runs/pipeline-49e1da6a-957e-48fd-9220-415019e4f8e2.jsonl +0 -5
  154. package/apps/vibe/.crew/pipeline-runs/pipeline-4c9251db-be68-427b-a3fc-a264f2b5778d.jsonl +0 -5
  155. package/apps/vibe/.crew/pipeline-runs/pipeline-6413fa33-a802-4b57-a8c0-a9056ad67842.jsonl +0 -5
  156. package/apps/vibe/.crew/pipeline-runs/pipeline-65e29a57-664d-4196-8109-017e364f182e.jsonl +0 -5
  157. package/apps/vibe/.crew/pipeline-runs/pipeline-6aa04bc5-9593-4b1f-b58d-3bf2978cb602.jsonl +0 -5
  158. package/apps/vibe/.crew/pipeline-runs/pipeline-6e1cba53-9b70-457e-99e0-59199149dd21.jsonl +0 -5
  159. package/apps/vibe/.crew/pipeline-runs/pipeline-749f41cc-4dac-4204-be64-873a6080a0d2.jsonl +0 -5
  160. package/apps/vibe/.crew/pipeline-runs/pipeline-74d68121-e181-4864-bd9a-c3211341dfaf.jsonl +0 -5
  161. package/apps/vibe/.crew/pipeline-runs/pipeline-8509bc24-142d-4e07-b44a-a50bf99d1103.jsonl +0 -5
  162. package/apps/vibe/.crew/pipeline-runs/pipeline-960339c6-07ca-43ce-9900-f6e1702b39b9.jsonl +0 -5
  163. package/apps/vibe/.crew/pipeline-runs/pipeline-9bef2dd2-6122-42e5-b3d9-19f4d80f9e40.jsonl +0 -5
  164. package/apps/vibe/.crew/pipeline-runs/pipeline-9c6480a9-7031-4146-b241-825b9a2d1de1.jsonl +0 -5
  165. package/apps/vibe/.crew/pipeline-runs/pipeline-9fd42426-8492-4157-9d5f-e1537c060489.jsonl +0 -2
  166. package/apps/vibe/.crew/pipeline-runs/pipeline-ad6d40a3-2f5e-46a9-a345-47caaccc51aa.jsonl +0 -5
  167. package/apps/vibe/.crew/pipeline-runs/pipeline-bc606133-8d5b-4535-8d85-f1a29cdaa981.jsonl +0 -5
  168. package/apps/vibe/.crew/pipeline-runs/pipeline-c1418f4e-b773-4ca1-84a3-216acf36e2f2.jsonl +0 -5
  169. package/apps/vibe/.crew/pipeline-runs/pipeline-c1a13ccd-634a-4d01-a4a7-1177b8a752ff.jsonl +0 -5
  170. package/apps/vibe/.crew/pipeline-runs/pipeline-c7d27b42-249e-4bd4-8f26-6aa998110b8a.jsonl +0 -5
  171. package/apps/vibe/.crew/pipeline-runs/pipeline-cca2e9b9-4a34-4d25-a311-5c793fa7e91e.jsonl +0 -5
  172. package/apps/vibe/.crew/sandbox.json +0 -7
  173. package/apps/vibe/.crew/session.json +0 -330
  174. package/apps/vibe/.crew/training-data.jsonl +0 -0
  175. package/apps/vibe/.github/workflows/studio-quality.yml +0 -37
  176. package/apps/vibe/.studio-data/project-messages/chuck-norris.jsonl +0 -18
  177. package/apps/vibe/.studio-data/project-messages/general.jsonl +0 -81
  178. package/apps/vibe/.studio-data/project-messages/studio-local.jsonl +0 -18
  179. package/apps/vibe/ARCHITECTURE.md +0 -3393
  180. package/apps/vibe/QUICK-REFERENCE.md +0 -211
  181. package/apps/vibe/ROADMAP.md +0 -41
  182. package/apps/vibe/STUDIO-SETUP-COMPLETE.md +0 -35
  183. package/apps/vibe/VISUAL-GUIDE.md +0 -378
  184. package/apps/vibe/capture-demo.mjs +0 -160
  185. package/apps/vibe/capture-full-demo.mjs +0 -255
  186. package/apps/vibe/capture-quickstart.mjs +0 -256
  187. package/apps/vibe/capture-vibe-assets.mjs +0 -71
  188. package/apps/vibe/capture-vibe-video.mjs +0 -260
  189. package/apps/vibe/check-buttons.js +0 -41
  190. package/apps/vibe/diagnose.html +0 -106
  191. package/apps/vibe/fix-buttons.js +0 -103
  192. package/apps/vibe/index.html +0 -3404
  193. package/apps/vibe/package-lock.json +0 -920
  194. package/apps/vibe/scripts/studio-pty-host.py +0 -117
  195. package/apps/vibe/src/main.js +0 -2940
  196. package/apps/vibe/src/register-all-languages.js +0 -98
  197. package/apps/vibe/start-studio.sh +0 -11
  198. package/apps/vibe/test/accessibility-tests.js +0 -77
  199. package/apps/vibe/test/browser-performance-audit.mjs +0 -205
  200. package/apps/vibe/test/performance-tests.js +0 -120
  201. package/apps/vibe/test/security-tests.js +0 -213
  202. package/apps/vibe/tests/e2e.local.mjs +0 -54
  203. package/apps/vibe/tests/server.smoke.mjs +0 -106
  204. package/apps/vibe/update_website.mjs +0 -74
  205. package/apps/vibe/vite.config.js +0 -19
  206. package/lib/crew-lead/chat-handler.mjs.bak +0 -1274
  207. package/lib/engines/rt-envelope.mjs.backup-current +0 -870
@@ -1,213 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { once } from "node:events";
3
- import fs from "node:fs/promises";
4
- import syncFs from "node:fs";
5
- import path from "node:path";
6
- import { spawn } from "node:child_process";
7
- import { setTimeout as delay } from "node:timers/promises";
8
- import { fileURLToPath } from "node:url";
9
- import { chromium } from "playwright";
10
-
11
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
- const rootDir = path.resolve(__dirname, "..");
13
- const reportDir = path.join(rootDir, "output");
14
- const reportPath = path.join(reportDir, "performance-audit.json");
15
- const port = Number(process.env.STUDIO_AUDIT_PORT || 3345);
16
- const baseUrl = `http://127.0.0.1:${port}`;
17
- const systemChrome = [
18
- "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
19
- "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary",
20
- ].find((candidate) => syncFs.existsSync(candidate));
21
-
22
- const BUDGETS = {
23
- domContentLoadedMs: 2500,
24
- loadMs: 4000,
25
- lcpMs: 2500,
26
- resourceCount: 40,
27
- totalTransferBytes: 1_500_000,
28
- jsHeapUsedBytes: 80 * 1024 * 1024,
29
- longTasks: 3,
30
- };
31
-
32
- async function ensureBuildOutput() {
33
- await fs.access(path.join(rootDir, "dist", "index.html"));
34
- }
35
-
36
- async function waitForServer(url, timeoutMs = 15_000) {
37
- const deadline = Date.now() + timeoutMs;
38
- let lastError = null;
39
-
40
- while (Date.now() < deadline) {
41
- try {
42
- const response = await fetch(url);
43
- if (response.ok) {
44
- return;
45
- }
46
- lastError = new Error(`HTTP ${response.status}`);
47
- } catch (error) {
48
- lastError = error;
49
- }
50
- await delay(250);
51
- }
52
-
53
- throw lastError || new Error("Studio server did not become ready");
54
- }
55
-
56
- function startServer() {
57
- const child = spawn(process.execPath, ["server.mjs"], {
58
- cwd: rootDir,
59
- env: {
60
- ...process.env,
61
- STUDIO_PORT: String(port),
62
- },
63
- stdio: "ignore",
64
- });
65
- return child;
66
- }
67
-
68
- async function collectMetrics() {
69
- const browser = await chromium.launch({
70
- headless: true,
71
- ...(systemChrome ? { executablePath: systemChrome } : {}),
72
- });
73
- const page = await browser.newPage();
74
- const cdp = await page.context().newCDPSession(page);
75
-
76
- await page.addInitScript(() => {
77
- window.__studioPerf = {
78
- lcp: 0,
79
- cls: 0,
80
- longTasks: 0,
81
- longTaskTime: 0,
82
- };
83
-
84
- new PerformanceObserver((list) => {
85
- const entries = list.getEntries();
86
- const lastEntry = entries.at(-1);
87
- if (lastEntry) {
88
- window.__studioPerf.lcp = lastEntry.startTime;
89
- }
90
- }).observe({ type: "largest-contentful-paint", buffered: true });
91
-
92
- new PerformanceObserver((list) => {
93
- for (const entry of list.getEntries()) {
94
- if (!entry.hadRecentInput) {
95
- window.__studioPerf.cls += entry.value;
96
- }
97
- }
98
- }).observe({ type: "layout-shift", buffered: true });
99
-
100
- new PerformanceObserver((list) => {
101
- for (const entry of list.getEntries()) {
102
- window.__studioPerf.longTasks += 1;
103
- window.__studioPerf.longTaskTime += entry.duration;
104
- }
105
- }).observe({ type: "longtask", buffered: true });
106
- });
107
-
108
- await cdp.send("Performance.enable");
109
- await page.goto(baseUrl, { waitUntil: "domcontentloaded", timeout: 15_000 });
110
- await page.waitForLoadState("load", { timeout: 15_000 });
111
- await delay(750);
112
-
113
- const browserMetrics = await cdp.send("Performance.getMetrics");
114
- const runtimeMetrics = await page.evaluate(() => {
115
- const navigation = performance.getEntriesByType("navigation")[0];
116
- const resources = performance.getEntriesByType("resource");
117
- const totals = resources.reduce(
118
- (acc, entry) => {
119
- acc.transferSize += entry.transferSize || 0;
120
- if (entry.initiatorType === "script") {
121
- acc.scriptTransferSize += entry.transferSize || 0;
122
- }
123
- return acc;
124
- },
125
- { transferSize: 0, scriptTransferSize: 0 },
126
- );
127
-
128
- return {
129
- domContentLoadedMs: navigation?.domContentLoadedEventEnd || 0,
130
- loadMs: navigation?.loadEventEnd || 0,
131
- resourceCount: resources.length,
132
- totalTransferBytes: totals.transferSize,
133
- scriptTransferBytes: totals.scriptTransferSize,
134
- lcpMs: window.__studioPerf?.lcp || 0,
135
- cls: window.__studioPerf?.cls || 0,
136
- longTasks: window.__studioPerf?.longTasks || 0,
137
- longTaskTimeMs: window.__studioPerf?.longTaskTime || 0,
138
- };
139
- });
140
-
141
- await browser.close();
142
-
143
- const cdpMetricMap = Object.fromEntries(
144
- browserMetrics.metrics.map((metric) => [metric.name, metric.value]),
145
- );
146
-
147
- return {
148
- collectedAt: new Date().toISOString(),
149
- url: baseUrl,
150
- budgets: BUDGETS,
151
- metrics: {
152
- ...runtimeMetrics,
153
- jsHeapUsedBytes: cdpMetricMap.JSHeapUsedSize || 0,
154
- nodes: cdpMetricMap.Nodes || 0,
155
- documents: cdpMetricMap.Documents || 0,
156
- },
157
- };
158
- }
159
-
160
- function evaluateBudgets(report) {
161
- const { metrics } = report;
162
-
163
- const checks = [
164
- ["domContentLoadedMs", metrics.domContentLoadedMs <= BUDGETS.domContentLoadedMs],
165
- ["loadMs", metrics.loadMs <= BUDGETS.loadMs],
166
- ["resourceCount", metrics.resourceCount <= BUDGETS.resourceCount],
167
- ["totalTransferBytes", metrics.totalTransferBytes <= BUDGETS.totalTransferBytes],
168
- ["jsHeapUsedBytes", metrics.jsHeapUsedBytes <= BUDGETS.jsHeapUsedBytes],
169
- ["longTasks", metrics.longTasks <= BUDGETS.longTasks],
170
- ];
171
-
172
- if (metrics.lcpMs > 0) {
173
- checks.push(["lcpMs", metrics.lcpMs <= BUDGETS.lcpMs]);
174
- }
175
-
176
- report.checks = checks.map(([name, pass]) => ({ name, pass }));
177
- report.ok = report.checks.every((check) => check.pass);
178
- }
179
-
180
- async function main() {
181
- await ensureBuildOutput();
182
- await fs.mkdir(reportDir, { recursive: true });
183
-
184
- console.log("Starting Studio server for performance audit...");
185
- const server = startServer();
186
-
187
- try {
188
- console.log("Waiting for Studio server...");
189
- await waitForServer(baseUrl);
190
- console.log("Collecting browser metrics...");
191
- const report = await collectMetrics();
192
- console.log("Evaluating budgets...");
193
- evaluateBudgets(report);
194
- await fs.writeFile(reportPath, `${JSON.stringify(report, null, 2)}\n`, "utf8");
195
-
196
- console.log(`Performance audit written to ${reportPath}`);
197
- report.checks.forEach((check) => {
198
- console.log(`${check.pass ? "PASS" : "FAIL"} ${check.name}`);
199
- });
200
-
201
- assert.ok(report.ok, "Studio performance audit exceeded one or more budgets");
202
- } finally {
203
- if (server.exitCode === null && !server.killed) {
204
- server.kill("SIGTERM");
205
- await Promise.race([once(server, "exit"), delay(2_000)]);
206
- }
207
- }
208
- }
209
-
210
- main().catch((error) => {
211
- console.error(error.stack || error.message);
212
- process.exitCode = 1;
213
- });
@@ -1,54 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import fs from "node:fs/promises";
3
- import os from "node:os";
4
- import path from "node:path";
5
-
6
- process.env.STUDIO_DISABLE_LISTEN = "1";
7
- process.env.STUDIO_DATA_DIR = path.join(process.cwd(), ".tmp-e2e-data");
8
-
9
- const { createOrUpdateProject, listWorkspaceFiles, readProjects } = await import("../server.mjs");
10
-
11
- const projectDir = await fs.mkdtemp(
12
- path.join(os.tmpdir(), "crewswarm-vibe-e2e-"),
13
- );
14
-
15
- try {
16
- const created = createOrUpdateProject({
17
- name: "E2E Project",
18
- description: "Local E2E check",
19
- outputDir: projectDir,
20
- });
21
- assert.equal(created.status, 200);
22
-
23
- await fs.writeFile(
24
- path.join(projectDir, "README.md"),
25
- "# E2E Project\n\nLocal test file.\n",
26
- "utf8",
27
- );
28
-
29
- const projectsPayload = {
30
- projects: readProjects(),
31
- };
32
- assert.ok(
33
- projectsPayload.projects.some((project) => project.id === created.payload.project.id),
34
- );
35
-
36
- const filesPayload = {
37
- files: listWorkspaceFiles(projectDir),
38
- };
39
- assert.ok(filesPayload.files.some((entry) => entry.path.endsWith("README.md")));
40
-
41
- const filePayload = {
42
- content: await fs.readFile(path.join(projectDir, "README.md"), "utf8"),
43
- };
44
- assert.match(filePayload.content, /Local test file/);
45
-
46
- const distIndex = await fs.readFile(path.join(process.cwd(), "dist", "index.html"), "utf8");
47
- assert.match(distIndex, /toggle-bottom-terminal/);
48
- assert.doesNotMatch(distIndex, /cdn\.jsdelivr\.net\/npm\/xterm/);
49
-
50
- console.log("Studio local e2e checks passed");
51
- } finally {
52
- await fs.rm(projectDir, { recursive: true, force: true });
53
- await fs.rm(process.env.STUDIO_DATA_DIR, { recursive: true, force: true });
54
- }
@@ -1,106 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import path from "node:path";
3
- import fs from "node:fs/promises";
4
- import { fileURLToPath } from "node:url";
5
-
6
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
7
- const rootDir = path.resolve(__dirname, "..");
8
-
9
- // Set env vars to avoid side effects during import
10
- process.env.STUDIO_DISABLE_LISTEN = "1";
11
- process.env.STUDIO_DATA_DIR = path.join(rootDir, ".tmp-smoke-data");
12
-
13
- const {
14
- ensureDataDirs,
15
- readProjects,
16
- listWorkspaceFiles,
17
- createOrUpdateProject,
18
- createTerminalSession,
19
- } = await import("../server.mjs");
20
-
21
- async function runSmokeTests() {
22
- console.log("Starting Studio smoke tests...");
23
-
24
- try {
25
- // 1. Data directories
26
- ensureDataDirs();
27
- const dataDirExists = await fs.stat(process.env.STUDIO_DATA_DIR).then(s => s.isDirectory()).catch(() => false);
28
- assert.ok(dataDirExists, "Data directory should be created");
29
-
30
- // 2. Projects
31
- const projects = readProjects();
32
- assert.ok(Array.isArray(projects), "Projects should be an array");
33
- assert.ok(projects.length > 0, "Should have at least one project");
34
- assert.ok(
35
- projects.some((project) => project.id === "studio-local"),
36
- "Projects should include the default studio-local workspace",
37
- );
38
-
39
- // 3. Workspace files
40
- const files = listWorkspaceFiles(rootDir);
41
- console.log(`Found ${files.length} files in ${rootDir}`);
42
- if (files.length > 0) {
43
- console.log("Sample file paths:", files.slice(0, 5).map(f => f.path));
44
- }
45
- assert.ok(Array.isArray(files), "Files should be an array");
46
- assert.ok(files.some(f => f.path.endsWith("package.json")), "Should find package.json in root");
47
-
48
- // 4. Create project
49
- const tempProjectDir = await fs.mkdtemp(path.join(rootDir, ".tmp-project-"));
50
- const newProject = {
51
- name: "Smoke Test Project",
52
- description: "Temporary project for smoke test",
53
- outputDir: tempProjectDir
54
- };
55
- const result = createOrUpdateProject(newProject);
56
- assert.equal(result.status, 200, "Should create project successfully");
57
- assert.ok(result.payload.project.id, "Created project should have an ID");
58
-
59
- // 5. Terminal session
60
- process.env.STUDIO_SHELL_BIN = "/bin/sh";
61
- process.env.STUDIO_SHELL_ARGS_JSON = JSON.stringify([
62
- "-lc",
63
- "printf terminal-smoke-ready\\n",
64
- ]);
65
- const terminalOutput = [];
66
- let terminalExitCode = null;
67
- await new Promise((resolve, reject) => {
68
- const timeout = setTimeout(() => {
69
- reject(new Error("Terminal smoke test timed out"));
70
- }, 5000);
71
-
72
- createTerminalSession({
73
- projectDir: rootDir,
74
- cols: 80,
75
- rows: 24,
76
- onData(chunk) {
77
- terminalOutput.push(chunk);
78
- },
79
- onExit(code) {
80
- terminalExitCode = code;
81
- clearTimeout(timeout);
82
- resolve();
83
- },
84
- });
85
- });
86
- assert.equal(terminalExitCode, 0, "Terminal session should exit cleanly");
87
- assert.match(
88
- terminalOutput.join(""),
89
- /terminal-smoke-ready/,
90
- "Terminal should produce shell output",
91
- );
92
-
93
- // Cleanup temp project dir
94
- await fs.rm(tempProjectDir, { recursive: true, force: true });
95
-
96
- console.log("Studio smoke tests passed!");
97
- } finally {
98
- // Cleanup smoke data dir
99
- await fs.rm(process.env.STUDIO_DATA_DIR, { recursive: true, force: true });
100
- }
101
- }
102
-
103
- runSmokeTests().catch(err => {
104
- console.error("Smoke test failed:", err);
105
- process.exit(1);
106
- });
@@ -1,74 +0,0 @@
1
- import fs from 'fs';
2
- import path from 'path';
3
-
4
- const INDEX_PATH = '../website/index.html';
5
- let html = fs.readFileSync(INDEX_PATH, 'utf8');
6
-
7
- console.log('🚀 Updating crewswarm.ai marketing site...');
8
-
9
- // 1. Tagline & Agent Count Consistency
10
- // Ensuring all instances of 20 or 21 are updated to "21+" for future-proofing
11
- html = html.replace('<h1>One idea.<br/>One build.<br/>', '<h1>One idea.<br/>One build.<br/>');
12
- html = html.replace(/20 specialist agents/g, '21+ specialist agents');
13
- html = html.replace(/21-agent specialist crew/g, '21+ specialist agent crew');
14
-
15
- // 2. Add Vibe to Control Surfaces (Replacing CrewChat cs-item)
16
- const crewChatCsItem = `<div class="cs-item cs-native">
17
- <strong>CrewChat</strong>
18
- <span>Menu bar app — same conversation, one click away</span>
19
- </div>`;
20
-
21
- const vibeCsItem = `<div class="cs-item cs-native">
22
- <strong><a href="vibe.html" style="color:var(--accent);">crewswarm Vibe</a></strong>
23
- <span>Browser-native IDE with Monaco — real-time file tree + agent chat.</span>
24
- </div>
25
- <div class="cs-item cs-native">
26
- <strong>CrewChat v2.0</strong>
27
- <span>Quick & Advanced modes — multimodal image + voice support.</span>
28
- </div>`;
29
-
30
- html = html.replace(crewChatCsItem, vibeCsItem);
31
-
32
- // 3. Update Shared Memory (Replacing Tech Badge)
33
- const sharedMemoryBadge = `<div class="tech-badge">
34
- <img src="https://cdn.simpleicons.org/markdown/94a3b8" alt="Markdown" width="28" height="28" loading="lazy">
35
- <div>
36
- <strong>Shared Memory</strong>
37
- <span>Markdown — current-state, decisions, handoff, roadmap</span>
38
- </div>
39
- </div>`;
40
-
41
- const ragMemoryBadge = `<div class="tech-badge">
42
- <img src="https://cdn.simpleicons.org/markdown/94a3b8" alt="Markdown" width="28" height="28" loading="lazy">
43
- <div>
44
- <strong>Shared Memory RAG</strong>
45
- <span>Semantic search over history via local TF-IDF (no API calls).</span>
46
- </div>
47
- </div>
48
- <div class="tech-badge">
49
- <div style="font-size:24px;">🌊</div>
50
- <div>
51
- <strong>Wave Orchestration</strong>
52
- <span>Parallel task dispatch — 10x faster concurrent builds.</span>
53
- </div>
54
- </div>`;
55
-
56
- html = html.replace(sharedMemoryBadge, ragMemoryBadge);
57
-
58
- // 4. Update Execution Engines (Add Gemini CLI)
59
- html = html.replace('Codex CLI', 'Codex CLI, and Gemini CLI');
60
-
61
- // 5. Add Waves FAQ
62
- const faqListStart = '<div class="faq-list" id="faqList">';
63
- const waveFaq = ` <div class="faq-item">
64
- <button class="faq-question" aria-expanded="false">
65
- <span>What are "Waves" and parallel dispatch?</span>
66
- <span class="faq-icon">+</span>
67
- </button>
68
- <div class="faq-answer"><div class="faq-answer-inner"><p>Waves allow multiple specialists (like crew-coder and crew-qa) to work simultaneously on different parts of the same project. Tasks in Wave 1 must finish before Wave 2 starts, but everything inside a wave runs in parallel.</p></div></div>
69
- </div>`;
70
-
71
- html = html.replace(faqListStart, faqListStart + '\n' + waveFaq);
72
-
73
- fs.writeFileSync(INDEX_PATH, html);
74
- console.log('✨ Website updated successfully!');
@@ -1,19 +0,0 @@
1
- import { defineConfig } from "vite";
2
-
3
- export default defineConfig({
4
- server: {
5
- port: 3333,
6
- strictPort: true,
7
- host: "127.0.0.1",
8
- },
9
- build: {
10
- outDir: "dist",
11
- assetsDir: "assets",
12
- },
13
- optimizeDeps: {
14
- include: ["monaco-editor"],
15
- },
16
- worker: {
17
- format: "es",
18
- },
19
- });