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.
- package/README.md +22 -9
- package/apps/dashboard/dist/assets/{chat-core-Cx4sTxDd.js → chat-core-3KirthZA.js} +1 -1
- package/apps/dashboard/dist/assets/index-GSWxxEPO.js +2 -0
- package/apps/dashboard/dist/assets/{tab-pm-loop-tab-Bfd449B4.js → tab-pm-loop-tab-DiAPTJXu.js} +1 -1
- package/apps/dashboard/dist/assets/{tab-projects-tab-DhNWnlzt.js → tab-projects-tab-SFH4E--a.js} +1 -1
- package/apps/dashboard/dist/assets/tab-settings-tab-BselH1c0.js +1 -0
- package/apps/dashboard/dist/index.html +82 -11
- package/apps/vibe/README.md +2 -2
- package/apps/vibe/package.json +1 -1
- package/apps/vibe/server.mjs +3 -3
- package/crew-lead.mjs +34 -4
- package/lib/bridges/gateway-ws.mjs +4 -0
- package/lib/crew-lead/chat-handler.mjs +34 -0
- package/lib/crew-lead/http-server.mjs +55 -14
- package/lib/crew-lead/llm-caller.mjs +24 -8
- package/lib/crew-lead/prompts.mjs +7 -0
- package/lib/crew-lead/wave-dispatcher.mjs +15 -3
- package/lib/crew-lead/ws-router.mjs +219 -27
- package/lib/engines/engine-registry.mjs +9 -0
- package/lib/engines/rt-envelope.mjs +1 -0
- package/lib/engines/runners.mjs +5 -2
- package/lib/runtime/paths.mjs +12 -8
- package/package.json +35 -15
- package/scripts/capture-build-flow.mjs +118 -0
- package/scripts/coverage-report.mjs +209 -0
- package/scripts/coverage-summary.mjs +47 -0
- package/scripts/dashboard-validation.mjs +74 -0
- package/scripts/dashboard.mjs +560 -70
- package/scripts/live-bridge-matrix.mjs +79 -0
- package/scripts/live-cli-matrix.mjs +166 -0
- package/scripts/live-crewchat-check.mjs +42 -0
- package/scripts/live-engine-matrix.mjs +50 -0
- package/scripts/live-provider-failover-matrix.mjs +107 -0
- package/scripts/live-provider-matrix.mjs +228 -0
- package/scripts/restart-all-from-repo.sh +4 -4
- package/scripts/smoke-dispatch.mjs +4 -1
- package/scripts/test-blast-radius.mjs +204 -0
- package/scripts/test-report-summary.mjs +88 -0
- package/scripts/test-reporter.mjs +651 -0
- package/scripts/test-rerun.mjs +136 -0
- package/scripts/tmux-bridge +130 -0
- package/apps/dashboard/dist/assets/chat-core-Cx4sTxDd.js.br +0 -0
- package/apps/dashboard/dist/assets/cli-process-COMRNPqr.js.br +0 -0
- package/apps/dashboard/dist/assets/components-BS9fQjE_.js.br +0 -0
- package/apps/dashboard/dist/assets/core-utils-CmOkXgzi.js.br +0 -0
- package/apps/dashboard/dist/assets/index-CF0aJRtC.css.br +0 -0
- package/apps/dashboard/dist/assets/index-DnClJ1ee.js +0 -2
- package/apps/dashboard/dist/assets/index-DnClJ1ee.js.br +0 -0
- package/apps/dashboard/dist/assets/orchestration-Ca2DLWN-.js.br +0 -0
- package/apps/dashboard/dist/assets/setup-wizard-CA0Or47w.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-agents-tab-BgpIsjkw.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-comms-tab-kguqTIzD.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-contacts-tab-DiOyMYth.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-engines-tab-BsdZVvU0.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-memory-tab-Cu6u13EQ.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-models-tab-BLEjmd19.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-pm-loop-tab-Bfd449B4.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-projects-tab-DhNWnlzt.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-prompts-tab-DVkUNaJd.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-services-tab-DU_LH3uG.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-settings-tab-Bn4nXtDe.js +0 -1
- package/apps/dashboard/dist/assets/tab-settings-tab-Bn4nXtDe.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-skills-tab-BpY0uZHW.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-spending-tab-DEccQHnt.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-swarm-chat-tab-BNrd88-r.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-swarm-tab-B1AcjL1W.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-usage-tab-BIOOnB-Y.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-waves-tab-SaJDkb4x.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-workflows-tab-B-soSy1k.js.br +0 -0
- package/apps/dashboard/dist/index.html.br +0 -0
- package/apps/dashboard/dist/index.html.gz +0 -0
- package/apps/dashboard/index.html +0 -6529
- package/apps/dashboard/package.json +0 -15
- package/apps/dashboard/src/app.js +0 -2828
- package/apps/dashboard/src/app.js.br +0 -0
- package/apps/dashboard/src/app.js.gz +0 -0
- package/apps/dashboard/src/chat/chat-actions.js +0 -1847
- package/apps/dashboard/src/chat/chat-actions.js.br +0 -0
- package/apps/dashboard/src/chat/unified-messages.js +0 -327
- package/apps/dashboard/src/chat/unified-messages.js.br +0 -0
- package/apps/dashboard/src/cli-process.js +0 -208
- package/apps/dashboard/src/cli-process.js.br +0 -0
- package/apps/dashboard/src/cli-process.js.gz +0 -0
- package/apps/dashboard/src/components/active-tasks-panel.js +0 -175
- package/apps/dashboard/src/components/active-tasks-panel.js.br +0 -0
- package/apps/dashboard/src/core/api.js +0 -18
- package/apps/dashboard/src/core/api.js.br +0 -0
- package/apps/dashboard/src/core/dom.js +0 -228
- package/apps/dashboard/src/core/dom.js.br +0 -0
- package/apps/dashboard/src/core/state.js +0 -91
- package/apps/dashboard/src/core/state.js.br +0 -0
- package/apps/dashboard/src/core/task-manager.js +0 -134
- package/apps/dashboard/src/core/task-manager.js.br +0 -0
- package/apps/dashboard/src/orchestration-status.js +0 -127
- package/apps/dashboard/src/orchestration-status.js.br +0 -0
- package/apps/dashboard/src/setup-wizard.js +0 -562
- package/apps/dashboard/src/setup-wizard.js.br +0 -0
- package/apps/dashboard/src/styles.css +0 -2085
- package/apps/dashboard/src/styles.css.br +0 -0
- package/apps/dashboard/src/styles.css.gz +0 -0
- package/apps/dashboard/src/tabs/agents-tab.js +0 -2237
- package/apps/dashboard/src/tabs/agents-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/benchmarks-tab.js +0 -229
- package/apps/dashboard/src/tabs/benchmarks-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/comms-tab.js +0 -955
- package/apps/dashboard/src/tabs/comms-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/contacts-tab.js +0 -654
- package/apps/dashboard/src/tabs/contacts-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/engines-tab.js +0 -175
- package/apps/dashboard/src/tabs/engines-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/memory-tab.js +0 -182
- package/apps/dashboard/src/tabs/memory-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/models-tab.js +0 -450
- package/apps/dashboard/src/tabs/models-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/pm-loop-tab.js +0 -185
- package/apps/dashboard/src/tabs/pm-loop-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/projects-tab.js +0 -663
- package/apps/dashboard/src/tabs/projects-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/projects-tab.js.gz +0 -0
- package/apps/dashboard/src/tabs/prompts-tab.js +0 -160
- package/apps/dashboard/src/tabs/prompts-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/services-tab.js +0 -202
- package/apps/dashboard/src/tabs/services-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/settings-tab.js +0 -861
- package/apps/dashboard/src/tabs/settings-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/skills-tab.js +0 -284
- package/apps/dashboard/src/tabs/skills-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/spending-tab.js +0 -173
- package/apps/dashboard/src/tabs/spending-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/swarm-chat-tab.js +0 -660
- package/apps/dashboard/src/tabs/swarm-chat-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/swarm-tab.js +0 -538
- package/apps/dashboard/src/tabs/swarm-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/usage-tab.js +0 -390
- package/apps/dashboard/src/tabs/usage-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/waves-tab.js +0 -238
- package/apps/dashboard/src/tabs/waves-tab.js.br +0 -0
- package/apps/dashboard/src/tabs/workflows-tab.js +0 -747
- package/apps/dashboard/src/tabs/workflows-tab.js.br +0 -0
- package/apps/vibe/.crew/agent-memory/pipeline.json +0 -304
- package/apps/vibe/.crew/cost.json +0 -17
- package/apps/vibe/.crew/json-parse-metrics.jsonl +0 -27
- package/apps/vibe/.crew/pipeline-metrics.jsonl +0 -27
- package/apps/vibe/.crew/pipeline-runs/pipeline-0f90c392-2425-4ae5-850c-bd9d17b1d690.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-1c269dd9-a63f-4fba-af81-5cf08048ef06.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-288a7765-da24-4a22-89bc-1f3cc9b0562c.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-2c78fd22-a657-4bd1-bc49-0679fb384409.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-3da23550-22ed-4904-9a0a-8e79c1f3024c.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-3e6fe08d-3264-404a-8df3-aab7efef10e7.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-42eec610-57fe-4e09-9e7e-b315038495c2.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-4438eb4c-ae13-42b1-90e2-b043d8983be8.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-4740a9f5-86e7-44b6-a394-de433e291727.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-49e1da6a-957e-48fd-9220-415019e4f8e2.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-4c9251db-be68-427b-a3fc-a264f2b5778d.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-6413fa33-a802-4b57-a8c0-a9056ad67842.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-65e29a57-664d-4196-8109-017e364f182e.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-6aa04bc5-9593-4b1f-b58d-3bf2978cb602.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-6e1cba53-9b70-457e-99e0-59199149dd21.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-749f41cc-4dac-4204-be64-873a6080a0d2.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-74d68121-e181-4864-bd9a-c3211341dfaf.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-8509bc24-142d-4e07-b44a-a50bf99d1103.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-960339c6-07ca-43ce-9900-f6e1702b39b9.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-9bef2dd2-6122-42e5-b3d9-19f4d80f9e40.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-9c6480a9-7031-4146-b241-825b9a2d1de1.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-9fd42426-8492-4157-9d5f-e1537c060489.jsonl +0 -2
- package/apps/vibe/.crew/pipeline-runs/pipeline-ad6d40a3-2f5e-46a9-a345-47caaccc51aa.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-bc606133-8d5b-4535-8d85-f1a29cdaa981.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-c1418f4e-b773-4ca1-84a3-216acf36e2f2.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-c1a13ccd-634a-4d01-a4a7-1177b8a752ff.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-c7d27b42-249e-4bd4-8f26-6aa998110b8a.jsonl +0 -5
- package/apps/vibe/.crew/pipeline-runs/pipeline-cca2e9b9-4a34-4d25-a311-5c793fa7e91e.jsonl +0 -5
- package/apps/vibe/.crew/sandbox.json +0 -7
- package/apps/vibe/.crew/session.json +0 -330
- package/apps/vibe/.crew/training-data.jsonl +0 -0
- package/apps/vibe/.github/workflows/studio-quality.yml +0 -37
- package/apps/vibe/.studio-data/project-messages/chuck-norris.jsonl +0 -18
- package/apps/vibe/.studio-data/project-messages/general.jsonl +0 -81
- package/apps/vibe/.studio-data/project-messages/studio-local.jsonl +0 -18
- package/apps/vibe/ARCHITECTURE.md +0 -3393
- package/apps/vibe/QUICK-REFERENCE.md +0 -211
- package/apps/vibe/ROADMAP.md +0 -41
- package/apps/vibe/STUDIO-SETUP-COMPLETE.md +0 -35
- package/apps/vibe/VISUAL-GUIDE.md +0 -378
- package/apps/vibe/capture-demo.mjs +0 -160
- package/apps/vibe/capture-full-demo.mjs +0 -255
- package/apps/vibe/capture-quickstart.mjs +0 -256
- package/apps/vibe/capture-vibe-assets.mjs +0 -71
- package/apps/vibe/capture-vibe-video.mjs +0 -260
- package/apps/vibe/check-buttons.js +0 -41
- package/apps/vibe/diagnose.html +0 -106
- package/apps/vibe/fix-buttons.js +0 -103
- package/apps/vibe/index.html +0 -3404
- package/apps/vibe/package-lock.json +0 -920
- package/apps/vibe/scripts/studio-pty-host.py +0 -117
- package/apps/vibe/src/main.js +0 -2940
- package/apps/vibe/src/register-all-languages.js +0 -98
- package/apps/vibe/start-studio.sh +0 -11
- package/apps/vibe/test/accessibility-tests.js +0 -77
- package/apps/vibe/test/browser-performance-audit.mjs +0 -205
- package/apps/vibe/test/performance-tests.js +0 -120
- package/apps/vibe/test/security-tests.js +0 -213
- package/apps/vibe/tests/e2e.local.mjs +0 -54
- package/apps/vibe/tests/server.smoke.mjs +0 -106
- package/apps/vibe/update_website.mjs +0 -74
- package/apps/vibe/vite.config.js +0 -19
- package/lib/crew-lead/chat-handler.mjs.bak +0 -1274
- package/lib/engines/rt-envelope.mjs.backup-current +0 -870
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from "node:fs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
|
+
import { getWorkspaceState, assessTestFreshness } from "./test-blast-radius.mjs";
|
|
7
|
+
|
|
8
|
+
const resultsDir = process.env.TEST_RESULTS_DIR || path.join(process.cwd(), "test-results");
|
|
9
|
+
const runsDir = path.join(resultsDir, "runs");
|
|
10
|
+
|
|
11
|
+
function latestRunId() {
|
|
12
|
+
const dirs = fs.readdirSync(runsDir, { withFileTypes: true })
|
|
13
|
+
.filter((entry) => entry.isDirectory())
|
|
14
|
+
.map((entry) => entry.name)
|
|
15
|
+
.sort();
|
|
16
|
+
return dirs.at(-1) || null;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function parseArgs(argv) {
|
|
20
|
+
const args = {
|
|
21
|
+
runId: null,
|
|
22
|
+
testId: null,
|
|
23
|
+
failed: false,
|
|
24
|
+
skipped: false,
|
|
25
|
+
stale: false,
|
|
26
|
+
exec: false,
|
|
27
|
+
reason: null,
|
|
28
|
+
};
|
|
29
|
+
for (let i = 0; i < argv.length; i++) {
|
|
30
|
+
const arg = argv[i];
|
|
31
|
+
if (arg === "--run" && argv[i + 1]) args.runId = argv[++i];
|
|
32
|
+
else if (arg === "--test-id" && argv[i + 1]) args.testId = argv[++i];
|
|
33
|
+
else if (arg === "--failed") args.failed = true;
|
|
34
|
+
else if (arg === "--skipped") args.skipped = true;
|
|
35
|
+
else if (arg === "--stale") args.stale = true;
|
|
36
|
+
else if (arg === "--exec") args.exec = true;
|
|
37
|
+
else if (arg === "--reason" && argv[i + 1]) args.reason = argv[++i];
|
|
38
|
+
}
|
|
39
|
+
return args;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function shellQuote(value) {
|
|
43
|
+
return `'${String(value).replace(/'/g, `'\\''`)}'`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function rerunCommand(test) {
|
|
47
|
+
return test.rerun_command || `node --test --test-reporter=./scripts/test-reporter.mjs --test-name-pattern=${shellQuote(test.name)} ${shellQuote(test.file)}`;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const args = parseArgs(process.argv.slice(2));
|
|
51
|
+
const runId = args.runId || latestRunId();
|
|
52
|
+
|
|
53
|
+
if (!runId) {
|
|
54
|
+
console.error("No test runs found.");
|
|
55
|
+
process.exit(1);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const summaryPath = path.join(runsDir, runId, "summary.json");
|
|
59
|
+
if (!fs.existsSync(summaryPath)) {
|
|
60
|
+
console.error(`Missing summary for run ${runId}`);
|
|
61
|
+
process.exit(1);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
const summary = JSON.parse(fs.readFileSync(summaryPath, "utf8"));
|
|
65
|
+
const baselineWorkspaceState = summary.workspace_state_at_run_start || null;
|
|
66
|
+
let tests = [];
|
|
67
|
+
if (args.testId) {
|
|
68
|
+
tests = [...(summary.tests || []), ...(summary.failedTests || []), ...(summary.skippedTests || [])]
|
|
69
|
+
.filter((test, index, all) => all.findIndex((item) => item.testId === test.testId) === index)
|
|
70
|
+
.filter((test) => test.testId === args.testId);
|
|
71
|
+
} else if (args.failed) {
|
|
72
|
+
tests = summary.failedTests || [];
|
|
73
|
+
} else if (args.skipped) {
|
|
74
|
+
tests = summary.skippedTests || [];
|
|
75
|
+
} else if (args.stale) {
|
|
76
|
+
tests = summary.tests || [];
|
|
77
|
+
} else {
|
|
78
|
+
tests = [...(summary.failedTests || []), ...(summary.skippedTests || [])];
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
if (tests.length === 0) {
|
|
82
|
+
console.log("No matching tests found.");
|
|
83
|
+
process.exit(0);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (args.reason) {
|
|
87
|
+
tests = tests.filter((test) => test.reason_code === args.reason);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
const workspaceState = getWorkspaceState();
|
|
91
|
+
const assessments = tests.map((test) => ({
|
|
92
|
+
test,
|
|
93
|
+
freshness: assessTestFreshness(test, workspaceState, baselineWorkspaceState),
|
|
94
|
+
}));
|
|
95
|
+
|
|
96
|
+
if (args.stale) {
|
|
97
|
+
tests = assessments.filter((item) => item.freshness.status === "stale").map((item) => ({
|
|
98
|
+
...item.test,
|
|
99
|
+
freshness: item.freshness,
|
|
100
|
+
}));
|
|
101
|
+
} else {
|
|
102
|
+
tests = assessments.map((item) => ({
|
|
103
|
+
...item.test,
|
|
104
|
+
freshness: item.freshness,
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (tests.length === 0) {
|
|
109
|
+
console.log("No matching tests found after applying filters.");
|
|
110
|
+
process.exit(0);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
for (const test of tests) {
|
|
114
|
+
console.log(`${test.testId}`);
|
|
115
|
+
if (test.reason_code || test.reason_summary) {
|
|
116
|
+
console.log(`${test.reason_code || "unknown"}: ${test.reason_summary || "no summary"}`);
|
|
117
|
+
}
|
|
118
|
+
if (test.freshness) {
|
|
119
|
+
console.log(`${test.freshness.status}: ${test.freshness.rerun_advice}`);
|
|
120
|
+
if (test.freshness.changed_relevant_files?.length) {
|
|
121
|
+
console.log(`blast-radius=${test.freshness.changed_relevant_files.join(",")}`);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (test.engine?.engine || test.engine?.provider || test.engine?.model) {
|
|
125
|
+
console.log(`engine=${test.engine?.engine || "n/a"} provider=${test.engine?.provider || "n/a"} model=${test.engine?.model || "n/a"}`);
|
|
126
|
+
}
|
|
127
|
+
console.log(rerunCommand(test));
|
|
128
|
+
if (args.exec) {
|
|
129
|
+
const result = spawnSync("/bin/zsh", ["-lc", rerunCommand(test)], {
|
|
130
|
+
cwd: process.cwd(),
|
|
131
|
+
stdio: "inherit",
|
|
132
|
+
env: process.env,
|
|
133
|
+
});
|
|
134
|
+
if (result.status !== 0) process.exit(result.status ?? 1);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# tmux-bridge — lightweight replacement for smux's tmux-bridge
|
|
3
|
+
# Implements the same CLI interface using raw tmux commands.
|
|
4
|
+
# No external dependencies beyond tmux itself.
|
|
5
|
+
|
|
6
|
+
set -euo pipefail
|
|
7
|
+
|
|
8
|
+
CMD="${1:-help}"
|
|
9
|
+
shift 2>/dev/null || true
|
|
10
|
+
|
|
11
|
+
# Storage for pane labels (agent ID → pane ID mapping)
|
|
12
|
+
LABEL_DIR="${CREWSWARM_TMUX_LABEL_DIR:-${HOME}/.crewswarm/state/tmux-labels}"
|
|
13
|
+
mkdir -p "$LABEL_DIR" 2>/dev/null || true
|
|
14
|
+
|
|
15
|
+
case "$CMD" in
|
|
16
|
+
|
|
17
|
+
id)
|
|
18
|
+
# Print this process's tmux pane ID
|
|
19
|
+
tmux display-message -p '#{pane_id}' 2>/dev/null
|
|
20
|
+
;;
|
|
21
|
+
|
|
22
|
+
name|label)
|
|
23
|
+
# Label a pane with an agent ID
|
|
24
|
+
# Usage: tmux-bridge name %0 crew-coder
|
|
25
|
+
PANE_ID="${1:?pane_id required}"
|
|
26
|
+
AGENT_ID="${2:?agent_id required}"
|
|
27
|
+
# Store label mapping
|
|
28
|
+
echo "$PANE_ID" > "$LABEL_DIR/$AGENT_ID"
|
|
29
|
+
# Also set tmux pane title
|
|
30
|
+
tmux select-pane -t "$PANE_ID" -T "$AGENT_ID" 2>/dev/null
|
|
31
|
+
echo "ok"
|
|
32
|
+
;;
|
|
33
|
+
|
|
34
|
+
resolve)
|
|
35
|
+
# Resolve agent ID to pane ID
|
|
36
|
+
# Usage: tmux-bridge resolve crew-coder
|
|
37
|
+
AGENT_ID="${1:?agent_id required}"
|
|
38
|
+
LABEL_FILE="$LABEL_DIR/$AGENT_ID"
|
|
39
|
+
if [ -f "$LABEL_FILE" ]; then
|
|
40
|
+
PANE_ID=$(cat "$LABEL_FILE")
|
|
41
|
+
# Verify pane still exists
|
|
42
|
+
if tmux has-session -t "$PANE_ID" 2>/dev/null || tmux display-message -t "$PANE_ID" -p '#{pane_id}' 2>/dev/null >/dev/null; then
|
|
43
|
+
echo "$PANE_ID"
|
|
44
|
+
else
|
|
45
|
+
# Pane gone, clean up stale label
|
|
46
|
+
rm -f "$LABEL_FILE"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
else
|
|
50
|
+
# Try finding by pane title
|
|
51
|
+
PANE_ID=$(tmux list-panes -a -F '#{pane_id} #{pane_title}' 2>/dev/null | grep " ${AGENT_ID}$" | head -1 | cut -d' ' -f1)
|
|
52
|
+
if [ -n "$PANE_ID" ]; then
|
|
53
|
+
echo "$PANE_ID" > "$LABEL_FILE"
|
|
54
|
+
echo "$PANE_ID"
|
|
55
|
+
else
|
|
56
|
+
exit 1
|
|
57
|
+
fi
|
|
58
|
+
fi
|
|
59
|
+
;;
|
|
60
|
+
|
|
61
|
+
read)
|
|
62
|
+
# Read last N lines from a pane
|
|
63
|
+
# Usage: tmux-bridge read %0 50
|
|
64
|
+
PANE_ID="${1:?pane_id required}"
|
|
65
|
+
LINES="${2:-50}"
|
|
66
|
+
tmux capture-pane -t "$PANE_ID" -p -S "-${LINES}" 2>/dev/null
|
|
67
|
+
;;
|
|
68
|
+
|
|
69
|
+
type)
|
|
70
|
+
# Type text into a pane (without pressing Enter)
|
|
71
|
+
# Usage: tmux-bridge type %0 "ls -la"
|
|
72
|
+
PANE_ID="${1:?pane_id required}"
|
|
73
|
+
TEXT="${2:?text required}"
|
|
74
|
+
tmux send-keys -t "$PANE_ID" -l "$TEXT" 2>/dev/null
|
|
75
|
+
echo "ok"
|
|
76
|
+
;;
|
|
77
|
+
|
|
78
|
+
keys)
|
|
79
|
+
# Send a key to a pane
|
|
80
|
+
# Usage: tmux-bridge keys %0 Enter
|
|
81
|
+
PANE_ID="${1:?pane_id required}"
|
|
82
|
+
KEY="${2:?key required}"
|
|
83
|
+
tmux send-keys -t "$PANE_ID" "$KEY" 2>/dev/null
|
|
84
|
+
echo "ok"
|
|
85
|
+
;;
|
|
86
|
+
|
|
87
|
+
list)
|
|
88
|
+
# List all panes with labels
|
|
89
|
+
printf "%-8s %-20s %-12s %-25s %-15s %s\n" "TARGET" "SESSION:WIN" "SIZE" "PROCESS" "LABEL" "CWD"
|
|
90
|
+
tmux list-panes -a -F '#{pane_id} #{session_name}:#{window_index} #{pane_width}x#{pane_height} #{pane_current_command} #{pane_title} #{pane_current_path}' 2>/dev/null | while read -r PANE_ID SESSION SIZE PROC TITLE CWD; do
|
|
91
|
+
# Check if we have a stored label for this pane
|
|
92
|
+
LABEL="-"
|
|
93
|
+
for f in "$LABEL_DIR"/*; do
|
|
94
|
+
[ -f "$f" ] || continue
|
|
95
|
+
if [ "$(cat "$f" 2>/dev/null)" = "$PANE_ID" ]; then
|
|
96
|
+
LABEL=$(basename "$f")
|
|
97
|
+
break
|
|
98
|
+
fi
|
|
99
|
+
done
|
|
100
|
+
# Use pane title as label if no stored label
|
|
101
|
+
if [ "$LABEL" = "-" ] && [ -n "$TITLE" ] && [ "$TITLE" != "$PROC" ]; then
|
|
102
|
+
LABEL="$TITLE"
|
|
103
|
+
fi
|
|
104
|
+
printf "%-8s %-20s %-12s %-25s %-15s %s\n" "$PANE_ID" "$SESSION" "$SIZE" "$PROC" "$LABEL" "$CWD"
|
|
105
|
+
done
|
|
106
|
+
;;
|
|
107
|
+
|
|
108
|
+
help|--help|-h)
|
|
109
|
+
echo "tmux-bridge — CrewSwarm tmux pane communication"
|
|
110
|
+
echo ""
|
|
111
|
+
echo "Commands:"
|
|
112
|
+
echo " id Print current pane ID"
|
|
113
|
+
echo " name <pane> <agent> Label a pane with agent ID"
|
|
114
|
+
echo " resolve <agent> Find pane ID by agent label"
|
|
115
|
+
echo " read <pane> [lines] Read last N lines from pane"
|
|
116
|
+
echo " type <pane> <text> Type text into pane"
|
|
117
|
+
echo " keys <pane> <key> Send key to pane (e.g. Enter)"
|
|
118
|
+
echo " list List all panes with labels"
|
|
119
|
+
echo ""
|
|
120
|
+
echo "Environment:"
|
|
121
|
+
echo " CREWSWARM_TMUX_BRIDGE=1 Enable bridge"
|
|
122
|
+
echo " SMUX_BRIDGE_BIN=path Override binary path"
|
|
123
|
+
;;
|
|
124
|
+
|
|
125
|
+
*)
|
|
126
|
+
echo "Unknown command: $CMD" >&2
|
|
127
|
+
echo "Run 'tmux-bridge help' for usage" >&2
|
|
128
|
+
exit 1
|
|
129
|
+
;;
|
|
130
|
+
esac
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/tab-benchmarks-tab-BHjKCPm3.js","assets/core-utils-CmOkXgzi.js"])))=>i.map(i=>d[i]);
|
|
2
|
-
var e,t,n;import{a as o,g as a,b as s,s as i,p as r,d as l,c,k as d,r as p,h as m,l as u,m as g,e as h}from"./core-utils-CmOkXgzi.js";import{c as v}from"./setup-wizard-CA0Or47w.js";import{i as f}from"./components-BS9fQjE_.js";import{s as y}from"./orchestration-Ca2DLWN-.js";import"./cli-process-COMRNPqr.js";import{i as w}from"./chat-core-Cx4sTxDd.js";import{i as b,s as x,h as k}from"./tab-swarm-chat-tab-BNrd88-r.js";import{i as C}from"./tab-waves-tab-SaJDkb4x.js";import{i as E,s as I}from"./tab-workflows-tab-B-soSy1k.js";import{c as T,m as B,s as S,l as j,a as A}from"./tab-memory-tab-Cu6u13EQ.js";import{i as P,s as L,l as M,a as _,r as N}from"./tab-services-tab-DU_LH3uG.js";import{i as R,s as O,l as F,a as H,t as D,b as z,c as G,d as $,e as V,f as q,g as K,h as U,j as W,k as J,m as Q,n as Y,o as X,p as Z,r as ee,q as te,u as ne,v as oe,w as ae,x as se,y as ie,z as re,A as le}from"./tab-agents-tab-BgpIsjkw.js";import{i as ce,a as de}from"./tab-prompts-tab-DVkUNaJd.js";import{s as pe,a as me,l as ue,c as ge,b as he,i as ve,t as fe,d as ye,f as we,r as be,e as xe,g as ke,u as Ce}from"./tab-skills-tab-BpY0uZHW.js";import{s as Ee,i as Ie,a as Te,l as Be}from"./tab-contacts-tab-DiOyMYth.js";import{i as Se,t as je,l as Ae,d as Pe}from"./tab-engines-tab-BsdZVvU0.js";import{s as Le,a as Me,b as _e,c as Ne,t as Re,d as Oe,r as Fe,i as He}from"./tab-swarm-tab-B1AcjL1W.js";import{i as De,s as ze,t as Ge,a as $e,b as Ve,c as qe,d as Ke,e as Ue,f as We,g as Je,h as Qe,j as Ye}from"./tab-models-tab-BLEjmd19.js";import{s as Xe,a as Ze,b as et,t as tt,c as nt,d as ot,e as at,f as st,g as it,h as rt,i as lt,j as ct,k as dt,l as pt,u as mt,m as ut,n as gt,o as ht,p as vt,q as ft,r as yt,v as wt,w as bt,x as xt,y as kt,z as Ct,A as Et,B as It,C as Tt,D as Bt,E as St,F as jt,G as At,H as Pt}from"./tab-settings-tab-Bn4nXtDe.js";import{i as Lt,s as Mt,l as _t,a as Nt,b as Rt,c as Ot,d as Ft,e as Ht,f as Dt,g as zt,h as Gt,r as $t,j as Vt}from"./tab-comms-tab-kguqTIzD.js";import{i as qt,p as Kt,r as Ut,c as Wt,a as Jt,b as Qt,e as Yt,d as Xt,l as Zt,o as en,f as tn,h as nn,j as on,k as an,m as sn,n as rn,q as ln,t as cn,v as dn,w as pn}from"./tab-projects-tab-DhNWnlzt.js";import{a as mn,r as un,c as gn,b as hn,l as vn,d as fn}from"./tab-usage-tab-BIOOnB-Y.js";import{s as yn,r as wn,l as bn,a as xn,b as kn}from"./tab-spending-tab-DEccQHnt.js";import{i as Cn}from"./tab-pm-loop-tab-Bfd449B4.js";!function(){const e=document.createElement("link").relList;if(!(e&&e.supports&&e.supports("modulepreload"))){for(const e of document.querySelectorAll('link[rel="modulepreload"]'))t(e);new MutationObserver(e=>{for(const n of e)if("childList"===n.type)for(const e of n.addedNodes)"LINK"===e.tagName&&"modulepreload"===e.rel&&t(e)}).observe(document,{childList:!0,subtree:!0})}function t(e){if(e.ep)return;e.ep=!0;const t=function(e){const t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),"use-credentials"===e.crossOrigin?t.credentials="include":"anonymous"===e.crossOrigin?t.credentials="omit":t.credentials="same-origin",t}(e);fetch(e.href,t)}}();const En={};let In=null;async function Tn(){return In||(In=await function(e,t){let n=Promise.resolve();if(t&&t.length>0){let e=function(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:"fulfilled",value:e}),e=>({status:"rejected",reason:e}))))};document.getElementsByTagName("link");const o=document.querySelector("meta[property=csp-nonce]"),a=(null==o?void 0:o.nonce)||(null==o?void 0:o.getAttribute("nonce"));n=e(t.map(e=>{if((e=function(e){return"/"+e}(e))in En)return;En[e]=!0;const t=e.endsWith(".css"),n=t?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${e}"]${n}`))return;const o=document.createElement("link");return o.rel=t?"stylesheet":"modulepreload",t||(o.as="script"),o.crossOrigin="",o.href=e,a&&o.setAttribute("nonce",a),document.head.appendChild(o),t?new Promise((t,n)=>{o.addEventListener("load",t),o.addEventListener("error",()=>n(new Error(`Unable to preload CSS for ${e}`)))}):void 0}))}function o(e){const t=new Event("vite:preloadError",{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return n.then(t=>{for(const e of t||[])"rejected"===e.status&&o(e.reason);return e().catch(o)})}(()=>import("./tab-benchmarks-tab-BHjKCPm3.js"),__vite__mapDeps([0,1]))),In}async function Bn(){try{const e=document.getElementById("statusDot");document.getElementById("status").textContent="online",e.className="status-dot online",await gn();const t=await a("/api/dlq"),n=document.getElementById("dlqBadge");t.length?(n.textContent=t.length,n.classList.remove("hidden")):n.classList.add("hidden")}catch(e){document.getElementById("status").textContent="error",document.getElementById("statusDot").className="status-dot error"}}async function Sn(){await Bn()}function jn(e){document.querySelectorAll(".nav-item").forEach(e=>e.classList.remove("active"));const t=document.getElementById(e);t&&t.classList.add("active")}function An(){u(o.activeTab),document.querySelectorAll(".view, .view-sessions").forEach(e=>{e.classList.remove("active"),e.style.display&&(e.style.display="")});const e=document.querySelector(".msg-bar");e&&(e.style.display="")}async function Pn(e){const t=document.getElementById(e),n=encodeURIComponent((null==t?void 0:t.value)||window._crewHome||""),o=await a("/api/pick-folder?default="+n).catch(()=>null);(null==o?void 0:o.path)&&t&&(t.value=o.path)}function Ln(){const e=(location.hash||"#chat").slice(1),t=(e.split("?")[0]||"chat").split("/");return{view:t[0]||"chat",subtab:t[1],raw:e}}function Mn(){return Ln().view}function _n(e){const t=e&&String(e).trim()&&"undefined"!==e?e:"general",n=`#chat?project=${encodeURIComponent(t)}`;location.hash!==n&&history.replaceState(null,"",n)}async function Nn(){try{const e=await a("/api/ui/active-project");return String((null==e?void 0:e.projectId)||"").trim()||"general"}catch{return"general"}}async function Rn(e){const t=e&&String(e).trim()&&"undefined"!==e?String(e).trim():"general";try{await r("/api/ui/active-project",{projectId:t})}catch{}}async function On(){An(),document.getElementById("chatView").classList.add("active"),jn("navChat"),o.activeTab="chat",s();const e=document.querySelector(".msg-bar");e&&(e.style.display="none"),y();const t=document.getElementById("chatMessages");"true"===(null==t?void 0:t.dataset.historyLoading)&&await Yn();const n=t&&"true"===t.dataset.historyLoaded&&t.children.length>0;try{const e=(await a("/api/projects")).projects||[];o.projectsData={},e.forEach(e=>{o.projectsData[e.id]=e}),s(),Kt(e)}catch(c){console.warn("Failed to refresh projects dropdown:",c)}const i=new URLSearchParams(window.location.hash.replace(/^#chat\?/,"")).get("project");if(i)o.chatActiveProjectId=i;else{const e=await Nn();try{o.chatActiveProjectId=e||localStorage.getItem("crewswarm_chat_active_project_id")||"general"}catch{o.chatActiveProjectId=e||"general"}}window.location.hash.includes("?project=")||_n(o.chatActiveProjectId),console.log("🔵 [INIT] Active project from URL:",o.chatActiveProjectId);const r=document.getElementById("chatProjectTabs");r&&Array.from(r.children).forEach(e=>{e.dataset.projectId===o.chatActiveProjectId?e.classList.add("active"):e.classList.remove("active")});const l=document.getElementById("chatProjectSelect");l&&o.chatActiveProjectId&&l.querySelector('option[value="'+o.chatActiveProjectId+'"]')&&(l.value=o.chatActiveProjectId),Rn(o.chatActiveProjectId),gn(),zn(),async function(){try{const e=((await a("/api/agents-config")).agents||[]).find(e=>"crew-lead"===e.id);if(!e)return;window._crewLeadInfo={emoji:e.emoji||"🧠",name:e.name||"crew-lead",theme:e.theme||""};const t=document.getElementById("chatAgentTitle"),n=document.getElementById("chatAgentSub");t&&(t.textContent=(e.emoji||"🧠")+" "+(e.name||"Crew Lead")),n&&e.theme&&(n.textContent=e.theme+" — chat naturally, dispatch tasks to the crew")}catch(c){}}(),window.loadChatAgentSelector&&window.loadChatAgentSelector(),n?m("chat"):await Qn()}function Fn(){An(),document.getElementById("filesView").classList.add("active"),jn("navFiles"),o.activeTab="files",s(),po()}function Hn(){return"owner"}P({hideAllViews:An,setNavActive:jn}),R({hideAllViews:An,setNavActive:jn,refreshAgents:F}),ce({hideAllViews:An,setNavActive:jn}),He({hideAllViews:An,setNavActive:jn}),C(),E({hideAllViews:An,setNavActive:jn});let Dn=null;function zn(){if(Dn)return;const e=`http://${window.location.hostname||"127.0.0.1"}:5010/events`;console.log("[crewswarm] Starting EventSource listener for",e),Dn=new EventSource(e);const t="undefined"!=typeof localStorage&&"1"===localStorage.getItem("crewswarm_debug_sse");Dn.onmessage=e=>{if(e.data)try{const a=JSON.parse(e.data),s=e=>e&&"general"!==e?e:"general",r="owner";t&&console.log("[crewswarm] SSE:",a.type,e.data.slice(0,120));const l=document.getElementById("chatMessages");if(k(a))return;if("chat_stream"===a.type&&a.sessionId===r){const e=s(a.projectId);if(s(o.chatActiveProjectId)!==e)return;let t=document.getElementById("streaming-bubble");if(!t){const e=document.createElement("div");e.id="streaming-wrapper",e.style.cssText="display:flex;flex-direction:column;align-items:flex-start;gap:4px;";const n=document.createElement("div");n.style.cssText="font-size:11px;color:var(--text-3);padding:0 6px;";const o=window._crewLeadInfo||{emoji:"🧠",name:"crew-lead"};n.textContent=o.emoji+" "+o.name+" (streaming...)",t=document.createElement("div"),t.id="streaming-bubble",t.className="chat-bubble assistant",t.style.cssText="max-width:80%;padding:10px 14px;border-radius:14px 14px 14px 4px;background:var(--surface-2);color:var(--text-2);font-size:14px;line-height:1.5;white-space:pre-wrap;word-break:break-word;border:1px solid var(--border);",t._textNode=document.createTextNode(""),t.appendChild(t._textNode),e.appendChild(n),e.appendChild(t),l&&l.appendChild(e)}const n=(t.dataset.streamChunk||"")+a.token;return t.dataset.streamChunk=n,void(t._rafId||(t._rafId=requestAnimationFrame(()=>{const e=t.dataset.streamChunk||"";e&&(t._textNode||(t._textNode=document.createTextNode(""),t.appendChild(t._textNode)),t._textNode.textContent+=e,t.dataset.streamChunk=""),l&&(l.scrollTop=l.scrollHeight),t._rafId=null})))}if("draft_discarded"===a.type&&a.draftId){const e=document.querySelector('[data-draft-id="'+a.draftId+'"]');return void(e&&e.remove())}if("context_warning"===a.type&&"owner"===a.sessionId){const e=document.getElementById("contextWarningBanner");e&&e.remove();const t=document.createElement("div");t.id="contextWarningBanner";const n="critical"===a.level;t.style.cssText=`display:flex;align-items:center;gap:10px;padding:8px 14px;border-radius:8px;margin:6px 0;font-size:12px;background:${n?"rgba(239,68,68,0.1)":"rgba(245,158,11,0.1)"};border:1px solid ${n?"rgba(239,68,68,0.3)":"rgba(245,158,11,0.3)"};color:${n?"#f87171":"#f59e0b"};`,t.innerHTML=`<span style="flex:1;">${a.message}</span><button onclick="clearChatHistory()" style="padding:2px 8px;font-size:11px;border-radius:4px;border:1px solid currentColor;background:transparent;color:inherit;cursor:pointer;">Clear now</button><button onclick="this.parentElement.remove()" style="background:none;border:none;cursor:pointer;color:inherit;font-size:14px;padding:0 2px;">✕</button>`;const o=document.getElementById("chatMessages");return void(o&&(o.appendChild(t),o.scrollTop=o.scrollHeight))}if("chat_message"===a.type&&"owner"===a.sessionId){const e=s(o.chatActiveProjectId),t=s(a.projectId);if(e!==t)return void console.log("[crewswarm] ❌ SKIP - projectId mismatch:",{current:e||"(General)",message:t||"(General)"});if(console.log("[crewswarm] ✅ Displaying message for current session"),"user"===a.role){if(a.content===Jn)return console.log("[crewswarm] Skipping SSE echo of locally-sent message"),void(Jn=null);a.content!==Wn?(console.log("[crewswarm] Appending user bubble:",a.content.slice(0,50)),g("user",a.content),Wn=a.content):console.log("[crewswarm] Skipping duplicate user message")}else if("assistant"===a.role){document.querySelectorAll('[id^="typing-"]').forEach(e=>e.remove());const e=String(a.content||"").trim();if(e&&function(e){if(!e)return"";for(let t=e.children.length-1;t>=0;t--){const n=e.children[t];if("streaming-wrapper"!==n.id&&!(n.children.length<2)&&String(n.style.alignItems||"").includes("flex-start"))return(n.children[1].textContent||"").trim()}return""}(l)===e)return Un=a.content,void(l&&(l.scrollTop=l.scrollHeight));const t=document.getElementById("streaming-wrapper"),n=document.getElementById("streaming-bubble");if(n){n._rafId&&cancelAnimationFrame(n._rafId),n._rafId=null;const e=n.dataset.streamChunk||"";e&&(n._textNode||(n._textNode=document.createTextNode(""),n.appendChild(n._textNode)),n._textNode.textContent+=e,n.dataset.streamChunk="")}if(t&&n){const e=window._crewLeadInfo||{emoji:"🧠",name:"crew-lead"},o=t.firstElementChild;o&&o!==n&&(o.textContent=e.emoji+" "+e.name);const s=a.content??"";n._textNode?n._textNode.textContent=s:n.textContent=s,t.removeAttribute("id"),n.removeAttribute("id"),delete n.dataset.streamChunk,Un=a.content}else{t&&t.remove();const e=a.content===Un&&function(e,t){if(!e||null==t)return!1;const n=String(t).trim();if(!n)return!1;for(let o=e.children.length-1;o>=0;o--){const t=e.children[o];if("streaming-wrapper"!==t.id&&(!(t.children.length<2)&&String(t.style.alignItems||"").includes("flex-start")&&(t.children[1].textContent||"").trim()===n))return!0}return!1}(l,a.content);e?console.log("[crewswarm] Skipping duplicate assistant message"):(console.log("[crewswarm] Appending assistant bubble (final)"),g("assistant",a.content,a.fallbackModel,a.fallbackReason,a.model,a.engineUsed),Un=a.content)}}return void(l&&(l.scrollTop=l.scrollHeight))}if("pending_project"===a.type&&"owner"===a.sessionId&&a.pendingProject&&l)return Kn(l,a.pendingProject),void(l.scrollTop=l.scrollHeight);if("agent_working"===a.type&&a.agent){const e=document.getElementById("coding-dot-"+a.agent);e&&(e.style.display="inline-flex")}if("agent_idle"===a.type&&a.agent){const e=document.getElementById("coding-dot-"+a.agent);e&&(e.style.display="none")}if("opencode_event"===a.type){const e=document.getElementById("ocFeed"),t=document.getElementById("ocFeedDot");if(!e)return;t&&(t.style.display="inline-block");const o=document.createElement("div");o.style.cssText="display:flex;align-items:center;gap:8px;padding:5px 10px;border-radius:8px;background:var(--bg-2);font-size:12px;font-family:var(--font-mono,monospace);animation:fadeIn .25s ease;";const s=new Date(a.ts||Date.now()).toLocaleTimeString([],{hour:"2-digit",minute:"2-digit",second:"2-digit"});let i="⚙️",r="";if("session_start"===a.kind){i="▶",o.style.borderLeft="3px solid var(--green-hi)";var n=a.dir||"";r="session started"+(n?" — "+n.split("/").pop():"")}else if("session_end"===a.kind)i="■",o.style.borderLeft="3px solid var(--text-3)",r="session ended",t&&(t.style.display="none");else if("file_edit"===a.kind)i="✏️",o.style.borderLeft="3px solid var(--amber)",r=(a.file||a.path||"")+(a.extra?' <span style="opacity:.5;">'+a.extra+"</span>":"");else if("error"===a.kind)i="✗",o.style.borderLeft="3px solid var(--red-hi)",o.style.color="var(--red-hi)",r=a.message||"error";else if("tool"===a.kind){const e={read_file:"var(--accent)",write_file:"var(--amber)",bash:"var(--purple)",list_directory:"var(--green)",grep:"var(--green)"}[a.tool]||"var(--text-2)";i="done"===a.phase?"✓":"→",o.style.borderLeft="3px solid "+e,o.style.color="done"===a.phase?"var(--text-2)":"var(--text-1)",r='<span style="color:'+e+';font-weight:600;">'+(a.tool||"")+"</span>"+(a.label?' <span style="opacity:.6;">'+a.label+"</span>":"")}for(o.innerHTML='<span style="opacity:.4;flex-shrink:0;">'+s+'</span><span style="flex-shrink:0;">'+i+'</span><span style="flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;">'+r+"</span>",e.appendChild(o);e.children.length>80;)e.removeChild(e.firstChild);return void(e.scrollTop=e.scrollHeight)}if("agent_working"===a.type&&a.agent){const e="agent-spinner-"+(a.taskId||a.agent);if(l&&!document.getElementById(e)){const t=document.createElement("div");t.id=e,t.className="msg a",t.style.cssText="opacity:.7; font-style:italic;",t.innerHTML='<div class="meta"><strong>'+a.agent+'</strong> · working…</div><div class="t" style="display:flex;align-items:center;gap:8px;"><span style="display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--accent);animation:pulse 1s ease-in-out infinite;"></span>Processing task…</div>',l.appendChild(t),l.scrollTop=l.scrollHeight}return}if("agent_reply"===a.type||a.from&&a.content){if(!a.from||!a.content)return;if(a._passthroughSummary)return;const e="agent-spinner-"+(a.taskId||a.from),t=document.getElementById(e);t&&t.remove();const n=document.getElementById("agent-spinner-"+a.from);return n&&n.remove(),g("🤖 "+a.from,a.content,!1,null,null,a.engineUsed),l&&(l.scrollTop=l.scrollHeight),void i(a.from+" finished a task")}if("task.timeout"===a.type&&a.agent){const e="agent-spinner-"+(a.taskId||a.agent),t=document.getElementById(e);t&&t.remove();const n=document.getElementById("agent-spinner-"+a.agent);n&&n.remove();const o="[crew-lead] Task to "+a.agent+" timed out (no reply in 90s). Consider @@SERVICE restart "+a.agent+" or re-dispatch to another agent.";if(l){const e=document.createElement("div");e.className="msg a",e.style.cssText="opacity:.85; font-style:italic; color:var(--text-3);",e.innerHTML='<div class="meta"><strong>'+a.agent+'</strong> · no reply</div><div class="t">'+h(o)+"</div>",l.appendChild(e),l.scrollTop=l.scrollHeight}return void i("Task to "+a.agent+" timed out")}if("pipeline_progress"===a.type){let e;e=a.agents?"Wave "+(a.waveIndex+1)+"/"+a.totalWaves+" → "+a.agents.join(" + "):"Step "+(a.stepIndex+1)+"/"+a.total+" → "+a.agent;const t=document.createElement("div");return t.style.cssText="font-size:11px;color:var(--text-3);padding:2px 8px;margin:2px 0;",t.textContent="↳ "+e,void(l&&(l.appendChild(t),l.scrollTop=l.scrollHeight))}if("pipeline_quality_gate"===a.type){const e=document.createElement("div"),t=a.willRetry?" — retrying wave":" — advancing anyway";return e.style.cssText="font-size:11px;color:var(--warning, #e8a030);padding:2px 8px;margin:2px 0;",e.textContent="⚠️ Wave "+(a.waveIndex+1)+" quality gate: "+(a.issues||[]).join("; ")+t,void(l&&(l.appendChild(e),l.scrollTop=l.scrollHeight))}if("project_launched"===a.type&&a.project){const e=a.project.projectId||a.project.id;return void setTimeout(async()=>{await Xt(),e&&pn(e);const t=document.getElementById("chatMessages");if(t){const n=document.createElement("div");n.style.cssText="font-size:11px;color:var(--green);padding:2px 8px;margin:2px 0;",n.textContent='📁 Project "'+(a.project.name||e)+'" registered — selected in chat',t.appendChild(n),t.scrollTop=t.scrollHeight}},800)}if("pipeline_done"===a.type){const e=document.createElement("div");return e.style.cssText="font-size:11px;color:var(--green);padding:2px 8px;margin:2px 0;",e.textContent="✅ Pipeline complete",void(l&&(l.appendChild(e),l.scrollTop=l.scrollHeight))}if("confirm_run_cmd"===a.type&&a.approvalId)return void function(e,t,n){if(document.getElementById("cmd-approval-"+e))return;const o=document.createElement("div");o.id="cmd-approval-"+e,o.style.cssText=["position:fixed;bottom:80px;right:24px;z-index:9999;","background:var(--bg-card);border:1px solid var(--border);border-radius:12px;","padding:16px 20px;max-width:440px;box-shadow:0 8px 32px rgba(0,0,0,.4);","display:flex;flex-direction:column;gap:10px;"].join("");const a=document.createElement("div");a.style.cssText="font-size:13px;font-weight:600;color:var(--text-1);",a.textContent="🔐 "+t+" wants to run a command";const s=document.createElement("code");s.style.cssText="display:block;font-size:12px;color:var(--accent);background:var(--bg-1);padding:6px 10px;border-radius:6px;word-break:break-all;",s.textContent=n;const r=document.createElement("label");r.style.cssText="display:flex;align-items:center;gap:8px;font-size:12px;color:var(--text-2);cursor:pointer;";const l=document.createElement("input");l.type="checkbox",l.style.cssText="width:14px;height:14px;cursor:pointer;accent-color:var(--green);";const c=n.trim().split(/\s+/)[0]+" *";r.appendChild(l),r.appendChild(document.createTextNode("Always allow "));const d=document.createElement("code");d.style.cssText="font-size:11px;background:var(--bg-1);padding:2px 6px;border-radius:4px;color:var(--accent);",d.textContent=c,r.appendChild(d);const p=document.createElement("div");p.style.cssText="font-size:11px;color:var(--text-3);";let m=60;p.textContent="Auto-reject in "+m+"s";const u=setInterval(()=>{m--,p.textContent="Auto-reject in "+m+"s",m<=0&&(clearInterval(u),o.remove())},1e3),g=document.createElement("div");g.style.cssText="display:flex;gap:8px;";const h=document.createElement("button");h.textContent="✅ Allow",h.style.cssText="flex:1;padding:8px;border-radius:8px;border:none;background:var(--green);color:#fff;cursor:pointer;font-weight:600;font-size:13px;",h.onclick=async()=>{clearInterval(u),o.remove(),l.checked&&(await fetch("/api/cmd-allowlist",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({pattern:c})}),i("Allowlisted: "+c)),await fetch("/api/cmd-approve",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}).catch(e=>i("Approve failed: "+e.message,!0)),l.checked||i(t+": command approved")};const v=document.createElement("button");v.textContent="⛔ Deny",v.style.cssText="flex:1;padding:8px;border-radius:8px;border:none;background:var(--red-hi);color:#fff;cursor:pointer;font-weight:600;font-size:13px;",v.onclick=async()=>{clearInterval(u),o.remove(),await fetch("/api/cmd-reject",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}).catch(e=>i("Reject failed: "+e.message,!0)),i(t+": command denied")},g.appendChild(h),g.appendChild(v),o.appendChild(a),o.appendChild(s),o.appendChild(r),o.appendChild(p),o.appendChild(g),document.body.appendChild(o)}(a.approvalId,a.agent,a.cmd);if("telemetry"===a.type&&a.payload){window._telemetryEvents=window._telemetryEvents||[],window._telemetryEvents.push(a.payload),window._telemetryEvents.length>100&&window._telemetryEvents.shift();const e=document.getElementById("toolMatrixView");e&&e.classList.contains("active")&&fn(window._telemetryEvents)}}catch{}else console.warn("[crewswarm] SSE message with null/empty data")},Dn.onopen=()=>{console.log("[crewswarm] SSE connection opened"),window._sseReconnectDelay=2e3},Dn.onerror=e=>{console.error("[crewswarm] SSE error:",e),Dn.close(),Dn=null,window._sseReconnectTimer&&clearTimeout(window._sseReconnectTimer),window._sseReconnectTimer=setTimeout(()=>{window._sseReconnectTimer=null,window._sseReconnectDelay=Math.min(2*(window._sseReconnectDelay||2e3),3e4),zn()},window._sseReconnectDelay||2e3)}}const Gn=[{label:"npm",pattern:"npm *",desc:"install, run, build, test…"},{label:"node",pattern:"node *",desc:"run any node script"},{label:"python",pattern:"python *",desc:"python / python3 scripts"},{label:"pip",pattern:"pip *",desc:"pip install packages"},{label:"git",pattern:"git *",desc:"all git operations"},{label:"cursor",pattern:"cursor *",desc:"open files in Cursor"},{label:"make",pattern:"make *",desc:"Makefile targets"},{label:"yarn",pattern:"yarn *",desc:"yarn install / build / run"},{label:"pnpm",pattern:"pnpm *",desc:"pnpm package manager"},{label:"ls / cat / echo",pattern:"ls *",desc:"read-only shell utilities"}];async function $n(){const e=document.getElementById("cmdAllowlistItems"),t=document.getElementById("cmdPresets");if(!e)return;const n=(await a("/api/cmd-allowlist").catch(()=>({list:[]}))).list||[];t&&(t.innerHTML="",Gn.forEach(function(e){const o=n.includes(e.pattern),a=document.createElement("label");a.style.cssText="display:flex;align-items:center;gap:8px;cursor:pointer;padding:4px 6px;border-radius:6px;transition:background 0.1s;",a.onmouseover=function(){a.style.background="var(--bg-hover)"},a.onmouseout=function(){a.style.background=""};const s=document.createElement("input");s.type="checkbox",s.checked=o,s.style.cssText="width:14px;height:14px;cursor:pointer;accent-color:var(--green);flex-shrink:0;",s.onchange=async function(){s.checked?await fetch("/api/cmd-allowlist",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({pattern:e.pattern})}).catch(e=>i("Failed to add pattern: "+e.message,!0)):await fetch("/api/cmd-allowlist",{method:"DELETE",headers:{"content-type":"application/json"},body:JSON.stringify({pattern:e.pattern})}).catch(e=>i("Failed to remove pattern: "+e.message,!0)),$n()};const r=document.createElement("code");r.style.cssText="font-size:12px;color:var(--accent);min-width:90px;",r.textContent=e.pattern;const l=document.createElement("span");l.style.cssText="font-size:11px;color:var(--text-3);",l.textContent=e.desc,a.appendChild(s),a.appendChild(r),a.appendChild(l),t.appendChild(a)}));const o=new Set(Gn.map(function(e){return e.pattern})),s=t?n.filter(function(e){return!o.has(e)}):n;if(e.innerHTML="",s.length)for(const a of s){const t=document.createElement("div");t.style.cssText="display:flex;align-items:center;gap:8px;padding:5px 0;border-bottom:1px solid var(--border);";const n=document.createElement("code");n.style.cssText="flex:1;font-size:12px;color:var(--accent);",n.textContent=a;const o=document.createElement("button");o.textContent="✕",o.style.cssText="border:none;background:transparent;color:var(--text-3);cursor:pointer;font-size:14px;padding:0 4px;",o.title="Remove",o.onclick=async function(){await fetch("/api/cmd-allowlist",{method:"DELETE",headers:{"content-type":"application/json"},body:JSON.stringify({pattern:a})}).catch(e=>i("Failed to delete pattern: "+e.message,!0)),$n()},t.appendChild(n),t.appendChild(o),e.appendChild(t)}else e.innerHTML='<div style="color:var(--text-3);font-size:12px;padding:4px 0;">'+(t?"No custom patterns yet.":"No patterns yet.")+"</div>"}async function Vn(){const e=document.getElementById("cmdAllowlistInput"),t=e?e.value.trim():"";t&&(await fetch("/api/cmd-allowlist",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({pattern:t})}).catch(e=>i("Failed to add pattern: "+e.message,!0)),e.value="",$n())}window._telemetryEvents=window._telemetryEvents||[];const qn=()=>vn(kn);function Kn(e,{draftId:t,name:n,outputDir:o,roadmapMd:a}){function s(e){return(e.match(/^- \[ \]/gm)||[]).length}const i=document.createElement("div");i.setAttribute("data-draft-id",t),i.style.cssText="width:100%;display:flex;flex-direction:column;gap:4px;";const l=document.createElement("div");l.style.cssText="font-size:11px;color:var(--text-3);padding:0 6px;",l.textContent="🗺️ Roadmap draft — review before building";const c=document.createElement("div");c.style.cssText="width:100%;border:1px solid var(--border);border-radius:12px;overflow:hidden;background:var(--bg-card);";const d=document.createElement("div");d.style.cssText="background:var(--bg-card2);padding:10px 14px;display:flex;align-items:center;justify-content:space-between;border-bottom:1px solid var(--border);",d.innerHTML='<div><div style="font-size:13px;font-weight:600;color:var(--accent);">🚀 '+n+'</div><div style="font-size:11px;color:var(--blue);margin-top:2px;">'+o+'</div></div><span style="font-size:10px;color:var(--text-3);padding:2px 7px;background:var(--bg-card2);border-radius:10px;" class="task-count">'+s(a)+" tasks</span>";const p=document.createElement("textarea");p.value=a,p.spellcheck=!1,p.style.cssText="width:100%;background:var(--bg-card);border:none;outline:none;color:var(--text-1);font-size:11.5px;font-family:SF Mono,Monaco,Menlo,monospace;line-height:1.6;padding:12px 14px;resize:none;min-height:160px;max-height:320px;display:block;",setTimeout(()=>{p.style.height="",p.style.height=Math.min(p.scrollHeight,320)+"px"},50),p.addEventListener("input",()=>{p.style.height="",p.style.height=Math.min(p.scrollHeight,320)+"px",d.querySelector(".task-count").textContent=s(p.value)+" tasks"});const m=document.createElement("div");m.style.cssText="display:flex;gap:8px;align-items:center;padding:10px 14px 12px;border-top:1px solid var(--border);background:var(--bg-card2);";const u=document.createElement("button");u.textContent="▶ Start Building",u.style.cssText="background:var(--green-hi);color:#000;border:none;border-radius:8px;padding:8px 16px;font-size:12px;font-weight:700;cursor:pointer;",u.onclick=async()=>{u.disabled=!0,u.textContent="⏳ Launching…";try{const e=await r("/api/crew-lead/confirm-project",{draftId:t,roadmapMd:p.value});e.ok?(c.innerHTML='<div style="padding:14px;color:var(--green-hi);font-size:13px;font-weight:600;">✅ '+n+' — project created, PM loop running!<br><span style="color:var(--blue);font-size:11px;font-weight:400">'+(e.outputDir||o)+"</span></div>",g("assistant","🚀 "+n+" is building. Check the Projects tab to watch progress.")):(u.disabled=!1,u.textContent="▶ Start Building",v.textContent="⚠️ "+(e.error||"Launch failed"))}catch(e){u.disabled=!1,u.textContent="▶ Start Building",v.textContent="⚠️ "+e.message}};const h=document.createElement("button");h.textContent="Discard",h.style.cssText="background:none;border:1px solid var(--border);color:var(--text-3);border-radius:8px;padding:8px 14px;font-size:12px;cursor:pointer;",h.onclick=async()=>{await r("/api/crew-lead/discard-project",{draftId:t}).catch(()=>{}),i.remove()};const v=document.createElement("span");v.style.cssText="font-size:11px;color:var(--blue);margin-left:auto;",v.textContent="Edit above, then confirm",m.appendChild(u),m.appendChild(h),m.appendChild(v),c.appendChild(d),c.appendChild(p),c.appendChild(m),i.appendChild(l),i.appendChild(c),e.appendChild(i),e.scrollTop=e.scrollHeight}let Un="",Wn="",Jn=null;const{loadChatHistory:Qn,waitForChatHistoryIdle:Yn,chatAtAtInput:Xn,chatKeydown:Zn,sendChat:eo,clearChatHistory:to,stopAll:no,killAll:oo,killPassthrough:ao,refreshSessionIndicator:so,clearPassthroughSession:io,resetSendButton:ro,handleImageUpload:lo,toggleVoiceRecording:co}=w({postJSON:r,getJSON:a,appendChatBubble:g,showNotification:i,state:o,getChatSessionId:()=>"owner",getChatActiveProjectId:()=>o.chatActiveProjectId,getCrewLeadInfo:()=>window._crewLeadInfo,appendRoadmapCard:Kn,getLastAppendedAssistantContent:()=>Un,setLastAppendedAssistantContent:e=>{Un=e},setLastAppendedUserContent:e=>{Wn=e},setLastSentContent:e=>{Jn=e}});async function po(e){const t=document.getElementById("filesContent"),n=document.getElementById("filesDir").value.trim()||window._crewCwd||(window._crewHome?window._crewHome+"/CrewSwarm":"");d(t,"Scanning "+n+"...");try{const e=await a("/api/files?dir="+encodeURIComponent(n));if(!e.files||!e.files.length)return void c(t,"No files found in "+n);const o={};e.files.forEach(e=>{const t=e.path.split(".").pop().toLowerCase()||"other";o[t]||(o[t]=[]),o[t].push(e)});const s=["html","css","js","mjs","ts","json","md","sh","txt","other"],i={html:"🌐",css:"🎨",js:"⚡",mjs:"⚡",ts:"🔷",json:"📋",md:"📝",sh:"🖥️",txt:"📄",other:"📁"};let r='<div style="display:grid;gap:1rem;padding:4px 0;">';for(const t of s)o[t]&&(r+="<div>",r+='<div style="font-size:11px;font-weight:600;color:var(--text-2);text-transform:uppercase;letter-spacing:0.08em;margin-bottom:8px;padding-left:2px;">'+(i[t]||"📁")+" ."+t+" — "+o[t].length+" file"+(o[t].length>1?"s":"")+"</div>",r+='<div style="display:grid;gap:6px;">',o[t].sort((e,t)=>t.mtime-e.mtime).forEach(e=>{const t=e.path.replace(n+"/",""),o=go(e.mtime),a=ho(e.size);r+='<div class="file-row">',r+='<div class="file-info"><span class="file-name">'+t+'</span><span class="file-meta">'+a+" · "+o+"</span></div>",r+='<div class="file-actions">',r+='<a href="cursor://file/'+e.path+'" class="file-btn file-btn-cursor" title="Open in Cursor">Cursor</a>',r+='<a href="opencode://open?path='+encodeURIComponent(e.path)+'" class="file-btn file-btn-opencode" title="Open in OpenCode">OpenCode</a>',r+='<button data-action="previewFile" data-arg=\''+e.path.replace(/'/g,"'")+'\' data-self="1" class="file-btn" title="Preview">👁</button>',r+="</div></div>"}),r+="</div></div>");r+="</div>",r+='<div id="file-preview-pane" style="display:none;margin-top:1rem;background:#0d1117;border:1px solid var(--border);border-radius:8px;overflow:hidden;"><div id="file-preview-bar" style="display:flex;align-items:center;gap:8px;padding:8px 12px;background:#0d1420;border-bottom:1px solid var(--border);font-size:12px;color:var(--text-2);"><span id="file-preview-name"></span><button data-action="closePreviewPane" style="margin-left:auto;background:none;border:none;color:var(--text-2);cursor:pointer;">✕</button></div><pre id="file-preview-content" style="margin:0;padding:1rem;font-size:0.75rem;overflow:auto;max-height:400px;"></pre></div>',t.innerHTML=r}catch(o){l(t,"Error: "+o.message)}}async function mo(e,t){const n=document.getElementById("file-preview-pane"),o=document.getElementById("file-preview-content"),s=document.getElementById("file-preview-name");if(n){s.textContent=e.split("/").pop(),o.textContent="Loading...",n.style.display="block",n.scrollIntoView({behavior:"smooth",block:"nearest"});try{const t=await a("/api/file-content?path="+encodeURIComponent(e));o.textContent=t.content||"(empty)"}catch(i){o.textContent="Error: "+i.message}}}function uo(){const e=document.getElementById("file-preview-pane");e&&(e.style.display="none")}function go(e){const t=Date.now()-e,n=Math.floor(t/6e4);if(n<1)return"just now";if(n<60)return n+"m ago";const o=Math.floor(n/60);return o<24?o+"h ago":Math.floor(o/24)+"d ago"}function ho(e){return e<1024?e+"B":e<1048576?(e/1024).toFixed(1)+"KB":(e/1024/1024).toFixed(1)+"MB"}function vo(){An(),document.getElementById("settingsView").classList.add("active"),jn("navSettings"),o.activeTab="settings",s();const e=(location.hash||"").replace("#settings/",""),t={system:"engines",telegram:"comms",whatsapp:"comms"}[e]||e;fo(["usage","engines","comms","security","webhooks"].includes(t)?t:"usage")}function fo(e){var t;["usage","engines","comms","security","webhooks"].forEach(t=>{const n=document.getElementById("stab-panel-"+t),o=document.getElementById("stab-"+t);n&&o&&(n.style.display=t===e?"usage"===t?"grid":"block":"none",o.classList.toggle("active",t===e))}),"usage"===e&&(hn(),xn()),"engines"===e&&(vt(),ft(),yt(),wt(),bt(),xt(),kt(),Ct(),Et(),It(),Tt(),Bt(),St(),jt()),"comms"===e&&Vt(),"security"===e&&($n(),At()),(null==(t=document.getElementById("settingsView"))?void 0:t.classList.contains("active"))&&history.replaceState(null,"","#settings/"+e)}function yo(){An(),document.getElementById("enginesView").classList.add("active"),jn("navEngines"),Ae()}null==(e=document.getElementById("attachImageBtn"))||e.addEventListener("click",()=>{document.getElementById("imageUpload").click()}),null==(t=document.getElementById("imageUpload"))||t.addEventListener("change",lo),null==(n=document.getElementById("recordVoiceBtn"))||n.addEventListener("click",co),window.loadChatHistory=Qn,window.getChatSessionId=Hn,window.selectProjectTab=e=>{const t=e&&String(e).trim()&&"undefined"!==e?e:"general",n=o.chatActiveProjectId;console.log("🔵 [TAB CLICK] START",t,"- from:",n);const a=document.getElementById("chatProjectTabs");if(!a)return void console.error("🔵 [TAB CLICK] ERROR: chatProjectTabs container not found!");if(n===t)return void console.log("🔵 [TAB CLICK] Already on this tab, skipping reload");_n(t),Array.from(a.children).forEach(e=>{e.classList.remove("active")});const s=Array.from(a.children).find(e=>e.dataset.projectId===t);s&&s.classList.add("active"),o.chatActiveProjectId=t;try{localStorage.setItem("crewswarm_chat_active_project_id",t)}catch{}Rn(t),console.log("🔵 [TAB CLICK] Updated state:",{projectId:o.chatActiveProjectId,sessionId:"owner",url:window.location.hash}),console.log("🔵 [TAB CLICK] Calling loadChatHistory()..."),Qn().then(()=>{console.log("🔵 [TAB CLICK] loadChatHistory() completed");const e=document.getElementById("chatMessages");console.log("🔵 [TAB CLICK] Messages in DOM:",(null==e?void 0:e.children.length)||0)}).catch(e=>{console.error("🔵 [TAB CLICK] loadChatHistory() ERROR:",e)})},window.addEventListener("focus",()=>{(async function(){if("chat"!==Ln().view)return;const e=await Nn(),t=e&&"undefined"!==e?e:"general";t!==(o.chatActiveProjectId&&"undefined"!==o.chatActiveProjectId?o.chatActiveProjectId:"general")&&window.selectProjectTab&&window.selectProjectTab(t)})().catch(()=>{})}),Lt({showSettings:vo,showSettingsTab:fo}),Pt({getModels:F,populateModelDropdown:le}),Ye({hideAllViews:An,setNavActive:jn,loadAgents:F}),De(),b({hideAllViews:An,setNavActive:jn});const wo=async()=>{const{showBenchmarks:e}=await Tn();e({hideAllViews:An,setNavActive:jn})};function bo(){An(),document.getElementById("memoryView").classList.add("active"),jn("navMemory"),A()}function xo(){An(),document.getElementById("cliProcessView").classList.add("active"),jn("navCLI"),window.initCLIProcess&&window.initCLIProcess()}function ko(){An(),document.getElementById("toolMatrixView").classList.add("active"),jn("navToolMatrix"),mn()}async function Co(){const e=document.getElementById("webhookChannel").value.trim()||"test";let t={};try{const e=document.getElementById("webhookPayload").value.trim();e&&(t=JSON.parse(e))}catch{t={raw:document.getElementById("webhookPayload").value}}const n=document.getElementById("webhookTestResult");try{const o=await fetch("/proxy-webhook/"+e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),a=await o.json();n.textContent=a.ok?"✅ Sent to RT bus":"❌ "+(a.error||"failed"),n.style.color=a.ok?"var(--green)":"var(--red)"}catch(o){n.textContent="❌ "+o.message,n.style.color="var(--red)"}}async function Eo(){document.getElementById("pendingApprovals").innerHTML='<div style="color:var(--text-3);font-size:12px;">Pending skill approvals appear here when an agent triggers a skill marked requiresApproval. You will also receive a Telegram notification with inline Approve/Reject buttons if Telegram is configured.</div>'}function Io(){on({hideAllViews:An,setNavActive:jn})}function To(){nn({hideAllViews:An,setNavActive:jn})}qt({showChat:On,showBuild:Io}),Bn(),setInterval(Bn,3e4),(async()=>{try{const e=(await a("/api/projects")).projects||[];o.projectsData={},e.forEach(e=>{o.projectsData[e.id]=e}),Kt(e),s(),"#projects"===location.hash&&To()}catch{}})(),document.getElementById("refreshBtn").onclick=Sn,document.getElementById("runBuildBtn").onclick=Ut,document.getElementById("continuousBuildBtn").onclick=Wt,document.getElementById("stopBuildBtn").onclick=Jt,document.getElementById("stopContinuousBtn").onclick=Qt,document.getElementById("enhancePromptBtn").onclick=Yt,Cn(),document.getElementById("newProjectBtn").onclick=()=>{const e=document.getElementById("newProjectForm");e.style.display="none"===e.style.display?"block":"none"},document.getElementById("npCancelBtn").onclick=()=>{document.getElementById("newProjectForm").style.display="none"},document.getElementById("npCreateBtn").onclick=async()=>{const e=document.getElementById("npName").value.trim(),t=document.getElementById("npDesc").value.trim(),n=document.getElementById("npOutputDir").value.trim(),o=document.getElementById("npFeaturesDoc").value.trim();if(e&&n)try{const a=await r("/api/projects",{name:e,description:t,outputDir:n,featuresDoc:o});i(`Project "${a.project.name}" created!`),document.getElementById("newProjectForm").style.display="none",document.getElementById("npName").value="",document.getElementById("npDesc").value="",document.getElementById("npOutputDir").value="",document.getElementById("npFeaturesDoc").value="",Xt()}catch(a){i("Failed: "+a.message,!0)}else i("Name and output directory required",!0)};const Bo={chat:On,"swarm-chat":x,swarm:_e,rt:Me,dlq:Le,files:Fn,services:L,agents:O,models:ze,settings:vo,engines:yo,skills:me,"run-skills":pe,benchmarks:wo,"tool-matrix":ko,build:Io,messaging:Mt,projects:To,contacts:Ee,memory:bo,workflows:I,"cli-process":xo,prompts:de};for(const[Lo,Mo]of Object.entries(Bo)){const e=Mo,t=function(...t){const n=location.hash||"";return"chat"===Lo?n.startsWith("#chat")||history.replaceState(null,"","#chat"):history.replaceState(null,"","#"+Lo),e(...t)};Bo[Lo]=t,window[e.name]=t}function So(e){const t=String(e||"chat").split("?")[0].split("/")[0];(Bo[t]||Bo.chat)()}(async()=>{if(await v())return;const{view:e,subtab:t}=Ln();"1"===new URLSearchParams(window.location.search).get("focus")?setTimeout(()=>{const e=document.getElementById("chatInput");e&&(So("chat"),e.focus())},500):(So(e||"chat"),"settings"===e&&t&&fo(t))})(),window.addEventListener("hashchange",()=>{const{view:e,subtab:t}=Ln(),n=Po[e];n?(n(),"settings"===e&&t&&fo(t)):On()}),fetch("/api/env").then(e=>e.json()).then(e=>{window._crewHome=e.HOME||"",window._crewCwd=e.cwd||"";const t=document.getElementById("filesDir");t&&!t.value&&(t.value=e.cwd||"")}).catch(()=>{}),F().catch(e=>console.error("Initial agents-config load failed:",e)),Sn(),function(){function e(e){if(e.closest("form"))return;const t=document.createElement("form");t.autocomplete="off",t.onsubmit=()=>!1,t.style.cssText="margin:0;padding:0;display:contents;";const n=document.createElement("input");n.type="text",n.autocomplete="username",n.setAttribute("aria-hidden","true"),n.style.cssText="display:none;position:absolute;width:0;height:0;opacity:0;",t.appendChild(n),e.parentNode.insertBefore(t,e),t.appendChild(e)}function t(t){(t||document).querySelectorAll('input[type="password"]').forEach(e)}t();new MutationObserver(n=>{for(const o of n)for(const n of o.addedNodes)1===n.nodeType&&(n.matches&&n.matches('input[type="password"]')?e(n):t(n))}).observe(document.body,{childList:!0,subtree:!0})}();const jo={showChat:On,showSwarm:_e,showRT:Me,showBuild:Io,showFiles:Fn,showDLQ:Le,showProjects:To,showAgents:O,showModels:ze,showEngines:yo,showSkills:me,showRunSkills:pe,showBenchmarks:wo,showToolMatrix:ko,showServices:L,showSettings:vo,pickFolder:e=>Pn(e),loadFiles:e=>po(),clearChatHistory:to,clearAgentChat:()=>{const e=document.getElementById("agentChatSelector"),t=document.getElementById("agentChatMessages"),n=document.getElementById("agentChatInput");t&&(t.innerHTML='<div class="empty-state">No messages yet. Start chatting!</div>'),n&&(n.value=""),(null==e?void 0:e.value)&&i("Chat history cleared","success")},sendChat:eo,stopAll:no,killAll:oo,stopPassthrough:ao,clearPassthroughSession:io,loadServices:M,saveRTToken:gt,lockConfig:ut,unlockConfig:mt,startCrew:H,toggleEmojiPicker:e=>oe(e),bulkSetRoute:(e,t)=>ae(e,t),loadSpending:bn,resetSpending:wn,saveGlobalCaps:yn,loadOcStats:qn,addAllowlistPattern:Vn,sendTestWebhook:Co,startTgBridge:Gt,stopTgBridge:zt,saveTgConfig:Dt,loadTelegramSessions:Ht,loadTgMessages:Ft,startWaBridge:Ot,stopWaBridge:Rt,saveWaConfig:Nt,loadWaMessages:_t,saveOpencodeSettings:pt,saveOpencodeModel:dt,saveGlobalFallback:ct,toggleBgConsciousness:lt,toggleCursorWaves:rt,toggleAutonomousMentions:it,toggleClaudeCode:st,toggleCodexExecutor:at,toggleGeminiCliExecutor:ot,toggleCrewCliExecutor:nt,toggleOpencodeExecutor:tt,saveGlobalOcLoop:et,saveGlobalOcLoopRounds:Ze,savePassthroughNotify:Xe,toggleAddSkill:ye,toggleImportSkill:fe,importSkillFromUrl:ve,showSkills:me,saveSkill:he,cancelSkillForm:ge,loadRunSkills:ue,loadBenchmarks:async()=>(await Tn()).loadBenchmarks(),loadBenchmarkLeaderboard:async()=>(await Tn()).loadBenchmarkLeaderboard(),loadBenchmarkTasks:async()=>(await Tn()).loadBenchmarkTasks(),onBenchmarkTaskSelect:async e=>(await Tn()).onBenchmarkTaskSelect(e),runBenchmarkTask:async()=>(await Tn()).runBenchmarkTask(),stopBenchmarkRun:async()=>(await Tn()).stopBenchmarkRun(),loadMemoryStats:j,searchMemory:S,migrateMemory:B,compactMemory:T,loadEngines:Ae,toggleImportEngine:je,importEngineFromUrl:Se,deleteEngine:e=>Pe(e),loadToolMatrix:mn,loadBuildProjectPicker:Zt,scrollRTToBottom:()=>{const e=document.getElementById("rtView");e&&(e.scrollTop=e.scrollHeight)},toggleRTPause:Re,clearRTMessages:Ne,togglePmAdvanced:()=>{const e=document.getElementById("pmAdvanced");e&&(e.style.display="none"===e.style.display?"block":"none")},toggleRTTokenVis:()=>{const e=document.getElementById("rtTokenInput");e&&(e.type="password"===e.type?"text":"password")},restartService:e=>N(e),stopService:e=>_(e),closePreviewPane:uo,previewFile:(e,t)=>mo(e),replayDLQ:e=>Fe(e),deleteDLQ:e=>Oe(e),runSkillFromUI:e=>be(e),editSkill:e=>xe(e),deleteSkill:e=>ke(e),restartAgentFromUI:e=>un(e),saveSearchTool:e=>Ke(e),testSearchTool:e=>$e(e),saveBuiltinKey:e=>We(e),testBuiltinProvider:e=>qe(e),fetchBuiltinModels:(e,t)=>Qe(e,t),saveKey:e=>Ue(e),testKey:e=>Ve(e),fetchModels:(e,t)=>Je(e,t),toggleKeyVis:(e,t)=>Ge(e,t),toggleAgentBody:e=>D(e),deleteAgent:e=>te(e),saveAgentModel:e=>Q(e),saveAgentFallback:e=>Z(e),saveAgentVoice:e=>X(e),toggleEmojiPicker:e=>oe(e),saveAgentIdentity:e=>Y(e),saveAgentPrompt:e=>J(e),resetAgentSession:e=>ee(e),saveAgentTools:e=>W(e),applyToolPreset:e=>ne(e),setRoute:(e,t)=>z(e,t),saveOpenCodeConfig:e=>V(e),saveOpenCodeFallback:e=>$(e),saveCursorCliConfig:e=>U(e),saveClaudeCodeConfig:e=>K(e),saveCodexConfig:e=>G(e),saveGeminiCliConfig:e=>q(e),saveCrewCLIConfig:e=>re(e),"pm-toggle":e=>{var t;const n=null==(t=o.projects)?void 0:t.find(t=>t.id===e);n&&n.running?cn(e):dn(e)},"edit-roadmap":e=>{var t;const n=null==(t=o.projects)?void 0:t.find(t=>t.id===e);n&&ln(e,n.roadmapFile)},"retry-failed":e=>{var t;const n=null==(t=o.projects)?void 0:t.find(t=>t.id===e);n&&rn(n.roadmapFile)},"save-roadmap":e=>sn(e),"reset-failed":e=>an(e),showSettingsTab:e=>fo(e)};let Ao=!1;document.addEventListener("touchstart",e=>{if(!(e.target instanceof Element))return;e.target.closest("[data-action]")&&(Ao=!0,setTimeout(()=>{Ao=!1},500))},{passive:!0}),document.addEventListener("click",e=>{if(!(e.target instanceof Element))return;const t=e.target.closest("[data-action]");if(!t)return;if(Ao)return void e.preventDefault();e.stopPropagation();const n=t.dataset.action,o=jo[n];if(!o)return void console.warn("[crewswarm] unknown data-action:",n);const a=t.dataset.arg??null,s=t.dataset.arg2??null,i="1"===t.dataset.self;null!==a&&null!==s?o(a,s):null!==a&&i?o(a,t):null!==a?o(a):i?o(t):o()}),document.addEventListener("change",e=>{const t=e.target.closest("[data-onchange]");if(!t)return;const n=jo[t.dataset.onchange];if(!n)return;const o="this.value"===t.dataset.onchangeArg?t.value:null;null!==o?n(o):n()}),document.addEventListener("DOMContentLoaded",()=>{f("activeTasksPanel"),Ie();const e=document.getElementById("dashSelfLink");e&&(e.href=window.location.origin,e.textContent=window.location.host),document.querySelectorAll(".nav-item").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation();const n=e.dataset.view;if(!n)return;if(Mn()!==n)return void(window.location.hash=n);const o=Po[n];o&&o()})});const t=document.getElementById("chatInput");t&&!t.dataset.boundChatComposer&&(t.dataset.boundChatComposer="1",t.addEventListener("keydown",Zn),t.addEventListener("input",Xn));const n=document.getElementById("chatSendBtn")||document.querySelector('[data-action="sendChat"]');n&&!n.dataset.boundChatComposer&&(n.dataset.boundChatComposer="1",n.addEventListener("click",e=>{e.preventDefault(),e.stopPropagation(),eo()}));const o=document.getElementById("cmdAllowlistInput");o&&o.addEventListener("keydown",e=>{"Enter"===e.key&&Vn()});const a=document.getElementById("waAllowedNumbers");a&&a.addEventListener("input",$t);const s=document.getElementById("skillSearch");s&&s.addEventListener("input",e=>we(e.target.value));const i=document.getElementById("passthroughEngine");i&&i.addEventListener("change",()=>{so(),function(){const e=document.getElementById("passthroughEngine"),t=document.getElementById("passthroughModel");if(!e||!t)return;const n=e.value,o={cursor:[{value:"",label:"— default (opus-4.6-thinking) —"},{optgroup:"Recommended (No Rate Limits)"},{value:"gemini-3-flash",label:"🟢 Gemini 3 Flash (fastest)"},{value:"gemini-3-pro",label:"🟢 Gemini 3 Pro"},{value:"gemini-3.1-pro",label:"🟢 Gemini 3.1 Pro"},{value:"gpt-5.2-codex",label:"🟢 GPT-5.2 Codex"},{value:"gpt-5.3-codex",label:"🟢 GPT-5.3 Codex"},{optgroup:"Claude Models (May Hit Rate Limits)"},{value:"sonnet-4.5",label:"🟡 Claude 4.5 Sonnet"},{value:"sonnet-4.6",label:"🟡 Claude 4.6 Sonnet (current)"},{value:"opus-4.5",label:"🟡 Claude 4.5 Opus"},{value:"opus-4.6",label:"🟡 Claude 4.6 Opus"},{optgroup:"Thinking Models (Slower)"},{value:"sonnet-4.5-thinking",label:"Claude 4.5 Sonnet Thinking"},{value:"opus-4.6-thinking",label:"Claude 4.6 Opus Thinking"},{optgroup:"Other"},{value:"grok",label:"xAI Grok"},{value:"kimi-k2.5",label:"Moonshot Kimi K2.5"}],claude:[{value:"",label:"— default (Sonnet 4.6) —"},{optgroup:"Recommended"},{value:"sonnet",label:"🟢 Sonnet (alias for latest)"},{value:"Default",label:"🟢 Default (Sonnet 4.6)"},{optgroup:"Specific Versions"},{value:"claude-sonnet-4-6",label:"Sonnet 4.6 · Best for everyday tasks"},{value:"Opus",label:"Opus (Opus 4.6) · Most capable for complex work"},{value:"claude-opus-4-6",label:"Opus 4.6 · Most capable"},{value:"Haiku",label:"Haiku (Haiku 4.5) · Fastest for quick answers"},{value:"claude-haiku-4-5",label:"Haiku 4.5 · Fastest"},{optgroup:"Legacy"},{value:"claude-sonnet-4-5",label:"Sonnet 4.5 (legacy)"}],codex:[{value:"",label:"— default (gpt-5.3-codex) —"},{optgroup:"Recommended"},{value:"gpt-5.3-codex",label:"🟢 GPT-5.3 Codex (current)"},{value:"gpt-5.2-codex",label:"🟢 GPT-5.2 Codex"},{optgroup:"Specialized"},{value:"gpt-5.1-codex-max",label:"GPT-5.1 Codex Max (deep reasoning)"},{value:"gpt-5.2",label:"GPT-5.2 (general purpose)"},{value:"gpt-5.1-codex-mini",label:"GPT-5.1 Codex Mini (fast & cheap)"}],opencode:[{value:"",label:"— default —"},{optgroup:"Free Models 🎁"},{value:"opencode/big-pickle",label:"🆓 Big Pickle (Free)"},{value:"opencode/minimax-m2.5-free",label:"🆓 MiniMax M2.5 Free"},{value:"openai/gpt-5-nano",label:"🆓 GPT 5 Nano (Free)"},{optgroup:"Budget Models 💰"},{value:"openai/gpt-5.1-codex-mini",label:"💰 GPT 5.1 Codex Mini ($0.25/$2)"},{value:"google/gemini-3-flash",label:"💰 Gemini 3 Flash ($0.50/$3)"},{value:"anthropic/claude-haiku-4-5",label:"💰 Claude Haiku 4.5 ($1/$5)"},{optgroup:"Interesting Models 🎯"},{value:"moonshot/kimi-k2.5",label:"Kimi K2.5 ($0.60/$3)"},{value:"moonshot/kimi-k2-thinking",label:"Kimi K2 Thinking ($0.40/$2.50)"},{value:"alibaba/qwen3-coder-480b",label:"Qwen3 Coder 480B ($0.45/$1.50)"},{value:"zhipu/glm-5",label:"GLM 5 ($1/$3.20)"},{optgroup:"Premium Claude"},{value:"anthropic/claude-sonnet-4-6",label:"Claude Sonnet 4.6 ($3/$15)"},{value:"anthropic/claude-opus-4-6",label:"Claude Opus 4.6 ($5/$25)"},{optgroup:"Premium OpenAI"},{value:"openai/gpt-5.3-codex",label:"GPT 5.3 Codex ($1.75/$14)"},{value:"openai/gpt-5.2-codex",label:"GPT 5.2 Codex ($1.75/$14)"},{value:"openai/gpt-5.1-codex-max",label:"GPT 5.1 Codex Max ($1.25/$10)"},{optgroup:"Premium Google"},{value:"google/gemini-3.1-pro",label:"Gemini 3.1 Pro ($2/$12)"},{value:"google/gemini-3-pro",label:"Gemini 3 Pro ($2/$12)"}],gemini:[{value:"",label:"— default (gemini-3-flash-preview) —"},{optgroup:"Recommended (Latest)"},{value:"gemini-3-flash-preview",label:"🟢 Gemini 3 Flash Preview (current)"},{value:"gemini-3.1-pro-preview",label:"🟢 Gemini 3.1 Pro Preview"},{optgroup:"Gemini 2.5 Series"},{value:"gemini-2.5-pro",label:"Gemini 2.5 Pro"},{value:"gemini-2.5-flash",label:"Gemini 2.5 Flash"},{value:"gemini-2.5-flash-lite",label:"Gemini 2.5 Flash Lite (fastest)"}]};if(!n||!o[n])return void(t.style.display="none");t.style.display="inline-block",t.innerHTML="";let a=null;for(const s of o[n])if(s.optgroup)a=document.createElement("optgroup"),a.label=s.optgroup,t.appendChild(a);else{const e=document.createElement("option");e.value=s.value,e.textContent=s.label,a?a.appendChild(e):t.appendChild(e)}}(),ro()});const r=document.getElementById("chatProjectSelect");r&&r.addEventListener("change",so);const l=document.getElementById("passthroughModel");l&&l.addEventListener("change",()=>{ro()})},{once:!0});const Po={chat:On,"swarm-chat":x,swarm:_e,rt:Me,build:Io,files:Fn,dlq:Le,projects:To,contacts:Ee,agents:O,models:ze,engines:yo,skills:me,"run-skills":pe,waves:()=>{An(),document.getElementById("wavesView").style.display="block",jn("navWaves")},workflows:I,benchmarks:wo,"tool-matrix":ko,memory:bo,"cli-process":xo,services:L,prompts:de,settings:vo};document.addEventListener("click",e=>{const t=e.target.closest("[data-view]");if(t){const e=t.dataset.view,n=Po[e];return void(n&&(Mn()!==e?window.location.hash=e:n()))}const n=e.target.closest("[data-stab]");if(n){const e=n.dataset.stab;window.location.hash=`settings/${e}`,fo(e)}const o=e.target.closest("[data-toggle-child]");if(o){const e=o.dataset.toggleChild,t=o.parentElement&&o.parentElement.querySelector(e);t&&(t.style.display="none"===t.style.display?"block":"none")}const a=e.target.closest("[data-toggle-sibling]");a&&a.nextElementSibling&&a.nextElementSibling.classList.toggle(a.dataset.toggleSibling)}),Object.assign(window,{addAllowlistPattern:Vn,applyNewAgentToolPreset:ie,applyPromptPreset:se,bulkSetRoute:ae,cancelSkillForm:ge,chatAtAtInput:Xn,chatKeydown:Zn,clearChatHistory:to,filterSkills:we,loadAllUsage:xn,loadBenchmarkLeaderboard:async()=>(await Tn()).loadBenchmarkLeaderboard(),loadBenchmarks:async()=>(await Tn()).loadBenchmarks(),loadBenchmarkTasks:async()=>(await Tn()).loadBenchmarkTasks(),onBenchmarkTaskSelect:async e=>(await Tn()).onBenchmarkTaskSelect(e),runBenchmarkTask:async()=>(await Tn()).runBenchmarkTask(),stopBenchmarkRun:async()=>(await Tn()).stopBenchmarkRun(),loadMemoryStats:j,searchMemory:S,migrateMemory:B,compactMemory:T,loadBuildProjectPicker:Zt,loadFiles:po,loadOcStats:qn,loadRunSkills:ue,loadServices:M,loadSpending:bn,loadTelegramSessions:Ht,loadTgMessages:Ft,loadToolMatrix:mn,loadWaMessages:_t,onBuildProjectChange:tn,onChatProjectChange:en,pickFolder:Pn,renderWaContactRows:$t,resetSpending:wn,approveSkill:async function(e){try{await fetch("/api/skills/approve",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}),i("Approved"),Eo()}catch(t){i("Failed: "+t.message,"error")}},loadPendingApprovals:Eo,rejectSkill:async function(e){try{await fetch("/api/skills/reject",{method:"POST",headers:{"content-type":"application/json"},body:JSON.stringify({approvalId:e})}),i("Rejected"),Eo()}catch(t){i("Failed: "+t.message,"error")}},saveGlobalCaps:yn,saveGlobalFallback:ct,saveBgConsciousnessModel:ht,saveOpencodeSettings:pt,saveRTToken:gt,saveSkill:he,saveTgConfig:Dt,saveWaConfig:Nt,sendChat:eo,sendTestWebhook:Co,showAgents:O,showBenchmarks:wo,showBuild:Io,showChat:On,showContacts:Ee,showDLQ:Le,showFiles:Fn,showModels:ze,showProjects:To,showRT:Me,showRunSkills:pe,showServices:L,showSettings:vo,showSettingsTab:fo,showSkills:me,showSwarm:_e,showToolMatrix:ko,showMemoryView:bo,startCrew:H,startTgBridge:Gt,startWaBridge:Ot,stopTgBridge:zt,stopWaBridge:Rt,toggleAddSkill:ye,toggleBgConsciousness:lt,toggleCursorWaves:rt,toggleClaudeCode:st,toggleEmojiPicker:oe,updateSkillAuthFields:Ce,navigateTo:So,renderStatusBadge:p,showLoading:d,showEmpty:c,showError:l,loadContacts:Be,applyContactFilters:Te,applyToolPreset:ne,closePreviewPane:uo,deleteAgent:te,deleteSkill:ke,editSkill:xe,fetchBuiltinModels:Qe,fetchModels:Je,previewFile:mo,resetAgentSession:ee,restartAgentFromUI:un,restartService:N,runSkillFromUI:be,saveAgentFallback:Z,saveAgentVoice:X,saveAgentIdentity:Y,saveAgentModel:Q,saveAgentPrompt:J,saveAgentTools:W,saveBuiltinKey:We,saveCursorCliConfig:U,saveClaudeCodeConfig:K,saveGeminiCliConfig:q,saveKey:Ue,saveOpenCodeConfig:V,saveOpenCodeFallback:$,saveSearchTool:Ke,saveCodexConfig:G,setRoute:z,stopService:_,testBuiltinProvider:qe,testKey:Ve,testSearchTool:$e,toggleAgentBody:D,toggleKeyVis:Ge});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{p as e,s as t,g as o,a,e as n}from"./core-utils-CmOkXgzi.js";import{s,u as r}from"./tab-projects-tab-DhNWnlzt.js";let l=null,c=null;function i({getModels:e,populateModelDropdown:t}={}){l=e||l,c=t||c}async function d(){const a=document.getElementById("rtTokenInput").value.trim();if(a)try{await e("/api/settings/rt-token",{token:a}),t("RT Bus token saved"),document.getElementById("rtTokenInput").value="",async function(){try{const e=await o("/api/settings/rt-token"),t=document.getElementById("rtTokenBadge"),a=document.getElementById("rtTokenInput");e.token?(t.textContent="set ✓",t.style.background="rgba(52,211,153,0.15)",t.style.color="var(--green)",t.style.borderColor="rgba(52,211,153,0.3)",a.placeholder="••••••••••••••••••••••• (saved)"):(t.textContent="not set",t.style.background="rgba(251,191,36,0.15)",t.style.color="var(--yellow)",t.style.borderColor="rgba(251,191,36,0.3)")}catch{}}()}catch(n){t("Save failed: "+n.message,"error")}else t("Paste a token first","error")}async function u(){const e=document.getElementById("configLockBadge"),t=document.getElementById("configLockStatus"),a=document.querySelector('[data-action="lockConfig"]'),n=document.querySelector('[data-action="unlockConfig"]');try{(await o("/api/config/lock-status")).locked?(e.textContent="🔒 Locked",e.style.background="rgba(52,211,153,0.15)",e.style.color="var(--green)",e.style.borderColor="rgba(52,211,153,0.3)",t&&(t.textContent="✓ Config is protected from overwrites"),a&&(a.className="btn-primary",a.style.opacity="0.6",a.style.pointerEvents="none"),n&&(n.className="btn-ghost",n.style.opacity="1",n.style.pointerEvents="auto")):(e.textContent="🔓 Unlocked",e.style.background="rgba(251,191,36,0.15)",e.style.color="var(--yellow)",e.style.borderColor="rgba(251,191,36,0.3)",t&&(t.textContent="⚠️ Config can be modified — lock it after making changes"),a&&(a.className="btn-primary",a.style.opacity="1",a.style.pointerEvents="auto"),n&&(n.className="btn-ghost",n.style.opacity="0.6",n.style.pointerEvents="none"))}catch{e&&(e.textContent="? unknown")}}async function g(){try{await e("/api/config/lock",{}),t("✓ Config locked — protected from overwrites"),u()}catch(o){t("Lock failed: "+o.message,"error")}}async function y(){try{await e("/api/config/unlock",{}),t("✓ Config unlocked — you can now make changes"),u()}catch(o){t("Unlock failed: "+o.message,"error")}}async function m(){try{const e=await o("/api/settings/opencode-project"),t=document.getElementById("opencodeProjInput"),a=document.getElementById("opencodeProjStatus");t&&(t.placeholder=e.dir||"e.g. /Users/you/Desktop/myproject",t.value=e.dir||""),a&&(a.textContent=e.dir?"✅ Current: "+e.dir:"⚠️ Not set — OpenCode will write files to the crewswarm repo root. Set this to your project folder."),document.getElementById("opencodeFallbackSelect")&&l&&(await l(),c&&c("opencodeFallbackSelect",e.fallbackModel||""));const n=document.getElementById("opencodeFallbackStatus");n&&(n.textContent=e.fallbackModel?"✅ Fallback: "+e.fallbackModel:"⚠️ Using default groq/kimi-k2-instruct-0905"),document.getElementById("opencodeModelSelect")&&l&&(await l(),c&&c("opencodeModelSelect",e.opencodeModel||""));const s=document.getElementById("opencodeModelStatus");s&&(s.textContent=e.opencodeModel?"✅ Primary: "+e.opencodeModel:"⚠️ Using default groq/moonshotai/kimi-k2-instruct-0905");const r=document.getElementById("crewLeadModelSelect");r&&e.crewLeadModel&&(r.value=e.crewLeadModel)}catch{}}async function p(){var o,n;const l=((null==(o=document.getElementById("opencodeProjInput"))?void 0:o.value)||"").trim(),c=((null==(n=document.getElementById("opencodeFallbackSelect"))?void 0:n.value)||"").trim();try{if(await e("/api/settings/opencode-project",{dir:l||void 0,fallbackModel:c||void 0}),t("OpenCode settings saved — fallback takes effect on next task (no restart needed)"),m(),l&&a.projectsData){const e=Object.values(a.projectsData).find(e=>e.outputDir===l);if(e){a.chatActiveProjectId=e.id,s(e.id);const t=document.getElementById("chatProjectSelect");t&&(t.value=e.id),r()}}}catch(i){t("Save failed: "+i.message,"error")}}async function f(){const o=document.getElementById("opencodeModelSelect"),a=((null==o?void 0:o.value)||"").trim(),n=document.getElementById("opencodeModelStatus");try{await e("/api/settings/opencode-project",{opencodeModel:a||void 0}),n&&(n.textContent="✓ Saved",n.style.color="var(--green-hi)"),t(a?`Primary OpenCode model → ${a}`:"OpenCode model reset to default"),setTimeout(()=>{n&&(n.textContent=a?"✅ Primary: "+a:"⚠️ Using default groq/moonshotai/kimi-k2-instruct-0905")},3e3)}catch(s){n&&(n.textContent="Error: "+s.message,n.style.color="var(--red)"),t("Save failed: "+s.message,"error")}}async function b(){const e=document.getElementById("bgConsciousnessBtn"),t=document.getElementById("bgConsciousnessStatus"),a=document.getElementById("bgConsciousnessModel");try{const n=await o("/api/settings/bg-consciousness"),s=n.enabled;e&&(e.textContent=s?"🟢 ON":"⚫ OFF",e.style.background=s?"rgba(34,197,94,0.15)":"var(--surface-2)",e.style.borderColor=s?"var(--green-hi)":"var(--border)",e.style.color=s?"var(--green-hi)":"var(--text-2)"),a&&n.model&&(a.placeholder=n.model),t&&(t.textContent=s?"Active — crew-lead reflects every "+Math.round(n.intervalMs/6e4)+"min when idle. Model: "+n.model:"Off — crew-lead will not self-reflect between tasks.")}catch(n){e&&(e.textContent="Error"),t&&(t.textContent="Could not load: "+n.message)}}async function E(){try{const a=await o("/api/settings/bg-consciousness"),n=await e("/api/settings/bg-consciousness",{enabled:!a.enabled});t("Background consciousness "+(n.enabled?"ENABLED":"DISABLED")),b()}catch(a){t("Failed: "+a.message,"error")}}async function v(){const o=document.getElementById("bgConsciousnessModel"),a=((null==o?void 0:o.value)||"").trim();if(a)try{await e("/api/settings/bg-consciousness",{model:a}),t("Background consciousness model → "+a),o.value="",b()}catch(n){t("Failed: "+n.message,"error")}else t("Enter a model first (e.g. groq/llama-3.3-70b-versatile)","error")}async function h(){const e=document.getElementById("cursorWavesBtn"),t=document.getElementById("cursorWavesStatus");try{const a=(await o("/api/settings/cursor-waves")).enabled;e&&(e.textContent=a?"⚡ ON":"⚫ OFF",e.style.background=a?"rgba(168,85,247,0.15)":"var(--surface-2)",e.style.borderColor=a?"#a855f7":"var(--border)",e.style.color=a?"#c084fc":"var(--text-2)"),t&&(t.textContent=a?"Active — multi-agent waves fan out to Cursor subagents in parallel. crew-orchestrator coordinates each wave.":"Off — each agent in a wave dispatches independently through the standard gateway.")}catch(a){e&&(e.textContent="Error"),t&&(t.textContent="Could not load: "+a.message)}}async function C(){try{const a=await o("/api/settings/cursor-waves"),n=await e("/api/settings/cursor-waves",{enabled:!a.enabled});t("Cursor Parallel Waves "+(n.enabled?"ENABLED ⚡":"DISABLED")),h()}catch(a){t("Failed: "+a.message,"error")}}async function k(){const e=document.getElementById("autonomousMentionsBtn"),t=document.getElementById("autonomousMentionsStatus");try{const a=!1!==(await o("/api/settings/autonomous-mentions")).enabled;e&&(e.textContent=a?"🕸 ON":"⚫ OFF",e.style.background=a?"rgba(52,211,153,0.15)":"var(--surface-2)",e.style.borderColor=a?"rgba(52,211,153,0.3)":"var(--border)",e.style.color=a?"var(--green)":"var(--text-2)"),t&&(t.textContent=a?"Active — shared chat @mentions can auto-route to agents and CLI participants.":"Off — @mentions are recorded in chat history, but no autonomous routing will fire.",t.style.color="var(--text-3)")}catch(a){e&&(e.textContent="Error"),t&&(t.textContent="Could not load: "+a.message)}}async function x(){try{const a=await o("/api/settings/autonomous-mentions"),n=await e("/api/settings/autonomous-mentions",{enabled:!a.enabled});t("Autonomous mention routing "+(n.enabled?"ENABLED 🕸":"DISABLED")),k()}catch(a){t("Failed: "+a.message,"error")}}async function w(){const e=document.getElementById("claudeCodeBtn"),t=document.getElementById("claudeCodeStatus");try{const a=await o("/api/settings/claude-code"),n=a.enabled;e&&(e.textContent=n?"🤖 ON":"⚫ OFF",e.style.background=n?"rgba(245,158,11,0.15)":"var(--surface-2)",e.style.borderColor=n?"var(--amber)":"var(--border)",e.style.color=n?"var(--yellow)":"var(--text-2)"),t&&(a.hasKey?(t.textContent=n?"Active — tasks route through Claude Code CLI. Per-agent override: set useClaudeCode: true in crewswarm.json.":"Off — tasks use direct LLM or OpenCode. Enable to run agents through Claude Code CLI.",t.style.color="var(--text-3)"):(t.textContent="⚠️ ANTHROPIC_API_KEY not set — add it to ~/.crewswarm/crewswarm.json under providers.anthropic.apiKey or set the env var.",t.style.color="var(--amber)"))}catch(a){e&&(e.textContent="Error"),t&&(t.textContent="Could not load: "+a.message)}}async function M(){try{const a=await o("/api/settings/claude-code");if(!a.hasKey)return void t("Set ANTHROPIC_API_KEY first — add it in ~/.crewswarm/crewswarm.json under providers.anthropic.apiKey","error");const n=await e("/api/settings/claude-code",{enabled:!a.enabled});t("Claude Code executor "+(n.enabled?"ENABLED 🤖":"DISABLED")),w()}catch(a){t("Failed: "+a.message,"error")}}async function I(){const e=document.getElementById("codexBtn"),t=document.getElementById("codexStatus");try{const a=(await o("/api/settings/codex")).enabled;e&&(e.textContent=a?"🟣 ON":"⚫ OFF",e.style.background=a?"rgba(168,85,247,0.15)":"var(--surface-2)",e.style.borderColor=a?"#a855f7":"var(--border)",e.style.color=a?"#a855f7":"var(--text-2)"),t&&(t.textContent=a?"Active — tasks route through Codex CLI. Per-agent override: set useCodex: true in crewswarm.json.":"Off — tasks use direct LLM or other engine. Enable to route all coding agents through Codex CLI.",t.style.color="var(--text-3)")}catch(a){e&&(e.textContent="Error"),t&&(t.textContent="Could not load: "+a.message,t.style.color="var(--text-3)")}}async function S(){try{const a=await o("/api/settings/codex"),n=await e("/api/settings/codex",{enabled:!a.enabled});t("Codex CLI executor "+(n.enabled?"ENABLED 🟣":"DISABLED")),I()}catch(a){t("Failed: "+a.message,"error")}}async function _(){const e=document.getElementById("geminiCliBtn"),t=document.getElementById("geminiCliStatus");try{const a=await o("/api/settings/gemini-cli"),n=a.enabled;e&&(e.textContent=n?"🔵 ON":"⚫ OFF",e.style.background=n?"rgba(66,133,244,0.15)":"var(--surface-2)",e.style.borderColor=n?"#4285f4":"var(--border)",e.style.color=n?"#4285f4":"var(--text-2)"),t&&(a.installed?(t.textContent=n?"Active — tasks route through Gemini CLI. Run gemini auth login if you haven't authenticated yet.":"Off — tasks use direct LLM or other engine. Enable to route coding agents through Gemini CLI (free Google OAuth tier).",t.style.color="var(--text-3)"):(t.textContent="⚠️ gemini binary not found — run: npm install -g @google/gemini-cli",t.style.color="var(--amber)"))}catch(a){e&&(e.textContent="Error"),t&&(t.textContent="Could not load: "+a.message,t.style.color="var(--text-3)")}}async function O(){try{const a=await o("/api/settings/gemini-cli");if(!a.installed)return void t("Install Gemini CLI first: npm install -g @google/gemini-cli","error");const n=await e("/api/settings/gemini-cli",{enabled:!a.enabled});t("Gemini CLI executor "+(n.enabled?"ENABLED 🔵":"DISABLED")),_()}catch(a){t("Failed: "+a.message,"error")}}async function A(){const e=document.getElementById("crewCliBtn"),t=document.getElementById("crewCliStatus");try{const a=(await o("/api/settings/crew-cli")).enabled;e&&(e.textContent=a?"🔧 ON":"⚫ OFF",e.style.background=a?"rgba(16,185,129,0.15)":"var(--surface-2)",e.style.borderColor=a?"#10b981":"var(--border)",e.style.color=a?"#10b981":"var(--text-2)"),t&&(t.textContent=a?"Active — multi-agent swarm tasks route through crew-cli with intelligent dispatch to specialists.":"Off — tasks use direct LLM or other engine. Enable to route all coding agents through crew-cli natively.")}catch(a){e&&(e.textContent="Error"),t&&(t.textContent="Could not load status")}}async function B(){try{const a=await o("/api/settings/crew-cli"),n=await e("/api/settings/crew-cli",{enabled:!a.enabled});t("Crew CLI executor "+(n.enabled?"ENABLED 🔧":"DISABLED")),A()}catch(a){t("Failed: "+a.message,"error")}}async function R(){const e=document.getElementById("opencodeBtn"),t=document.getElementById("opencodeStatus");try{const a=await o("/api/settings/opencode"),n=a.enabled;e&&(e.textContent=n?"⚡ ON":"⚫ OFF",e.style.background=n?"rgba(52,211,153,0.15)":"var(--surface-2)",e.style.borderColor=n?"rgba(52,211,153,0.3)":"var(--border)",e.style.color=n?"var(--green)":"var(--text-2)"),t&&(a.installed?(t.textContent=n?"⚡ Active — coding agents route through OpenCode for full IDE context and session persistence.":"⚫ Off — tasks use direct LLM or other configured engine. Enable to run agents through OpenCode CLI.",t.style.color="var(--text-3)"):(t.textContent="⚠️ opencode binary not found — install: npm install -g opencode",t.style.color="var(--amber)"))}catch(a){e&&(e.textContent="Error"),t&&(t.textContent="Could not load status",t.style.color="var(--text-3)")}}async function L(){try{const a=await o("/api/settings/opencode");if(!a.installed)return void t("Install OpenCode CLI first: npm install -g opencode","error");const n=await e("/api/settings/opencode",{enabled:!a.enabled});t("OpenCode executor "+(n.enabled?"ENABLED ⚡":"DISABLED")),R()}catch(a){t("Failed: "+a.message,"error")}}async function D(){try{const e=await o("/api/settings/global-fallback"),t=document.getElementById("globalFallbackInput");t&&(t.value=e.globalFallbackModel||"");const a=document.getElementById("globalFallbackStatus");a&&(a.textContent=e.globalFallbackModel?"Active: any agent without a per-agent fallback will use "+e.globalFallbackModel:"Not set — agents without fallback will use the built-in default (groq/llama-3.3-70b-versatile).")}catch(e){console.warn("loadGlobalFallback:",e.message)}}async function N(){var o;const a=((null==(o=document.getElementById("globalFallbackInput"))?void 0:o.value)||"").trim();try{await e("/api/settings/global-fallback",{globalFallbackModel:a}),t(a?"Global fallback → "+a:"Global fallback cleared"),D()}catch(n){t("Failed: "+n.message,"error")}}async function T(){try{const e=await o("/api/settings/global-oc-loop"),t=document.getElementById("globalOcLoop"),a=document.getElementById("globalOcLoopRounds");t&&(t.checked=e.enabled||!1),a&&(a.value=e.maxRounds??10)}catch(e){}}async function W(){var o;const a=null==(o=document.getElementById("globalOcLoop"))?void 0:o.checked;try{await e("/api/settings/global-oc-loop",{enabled:a}),t("Global OC loop "+(a?"enabled":"disabled"))}catch(n){t("Failed: "+n.message,!0)}}async function P(){var o;const a=parseInt(null==(o=document.getElementById("globalOcLoopRounds"))?void 0:o.value)||10;try{await e("/api/settings/global-oc-loop",{maxRounds:a}),t("Max rounds set to "+a)}catch(n){t("Failed: "+n.message,!0)}}async function F(){try{const e=await o("/api/settings/passthrough-notify"),t=document.getElementById("passthroughNotifySelect");t&&(t.value=e.value||"both")}catch(e){}}async function G(){var o;const a=(null==(o=document.getElementById("passthroughNotifySelect"))?void 0:o.value)||"both",n=document.getElementById("passthroughNotifyStatus");try{await e("/api/settings/passthrough-notify",{value:a}),n&&(n.textContent="✓ Saved — takes effect on the next passthrough",n.style.color="var(--green-hi)"),t("Passthrough notifications → "+a)}catch(s){n&&(n.textContent="Error: "+s.message,n.style.color="var(--red)")}}async function j(){try{const e=await o("/api/settings/loop-brain"),t=document.getElementById("loopBrainModel");t&&e.loopBrain&&(t.value=e.loopBrain)}catch{}}const U=[{label:"Engine — OpenCode",vars:[{key:"CREWSWARM_OPENCODE_ENABLED",hint:"Route coding agents through OpenCode globally",default:"off"},{key:"CREWSWARM_OPENCODE_MODEL",hint:"Model passed to OpenCode — leave blank to use per-agent model",default:"per-agent"},{key:"CREWSWARM_OPENCODE_TIMEOUT_MS",hint:"ms before an OpenCode task is killed",default:"300000"},{key:"CREWSWARM_OPENCODE_AGENT",hint:"Override agent name passed to OpenCode",default:"auto"}]},{label:"Engine — Claude Code & Cursor",note:"Both use OAuth login (run claude or cursor once). No API key required.",vars:[{key:"CREWSWARM_CLAUDE_CODE_MODEL",hint:"Model passed to claude -p — leave blank for Claude Code default",default:"claude default"},{key:"CREWSWARM_CURSOR_MODEL",hint:"Cursor CLI --model when agent has no cursorCliModel (default: composer-2-fast)",default:"composer-2-fast"}]},{label:"Engine — Codex & crew-cli",note:"These are the dashboard-wide defaults when an agent does not have a per-route model override.",vars:[{key:"CREWSWARM_CODEX_MODEL",hint:"Model passed to codex exec --model (leave blank for Codex default)",default:"codex default"},{key:"CREWSWARM_CREW_CLI_MODEL",hint:"Model passed to crew chat --model and gateway crew-cli engine",default:"gemini-2.5-flash"}]},{label:"Engine — Gemini CLI",note:"Free tier via Google account — 60 req/min. Run gemini once to auth.",vars:[{key:"CREWSWARM_GEMINI_CLI_ENABLED",hint:"Route agents through Gemini CLI globally",default:"off"},{key:"CREWSWARM_GEMINI_CLI_MODEL",hint:"Model passed to gemini -p (e.g. gemini-2.0-flash) — blank for default",default:"gemini default"}]},{label:"Engine — Docker Sandbox",note:"Runs any inner engine inside an isolated Docker microVM. API keys injected by network proxy — never exposed to the agent.",vars:[{key:"CREWSWARM_DOCKER_SANDBOX",hint:"Route all coding agents through Docker Sandbox globally",default:"off"},{key:"CREWSWARM_DOCKER_SANDBOX_NAME",hint:"Pre-created sandbox name",default:"crewswarm"},{key:"CREWSWARM_DOCKER_SANDBOX_INNER_ENGINE",hint:"Engine inside the sandbox: claude, opencode, or codex",default:"claude"},{key:"CREWSWARM_DOCKER_SANDBOX_TIMEOUT_MS",hint:"ms before a sandboxed task is killed",default:"300000"}]},{label:"Engine Loop & Dispatch",vars:[{key:"CREWSWARM_ENGINE_LOOP",hint:"Enable Ouroboros engine loop for all agents",default:"off"},{key:"CREWSWARM_ENGINE_LOOP_MAX_ROUNDS",hint:"Max STEP iterations per loop run",default:"10"},{key:"CREWSWARM_ENGINE_IDLE_TIMEOUT_MS",hint:"Kill engine (Cursor/Claude) if no output for this many ms",default:"300000"},{key:"CREWSWARM_ENGINE_MAX_TOTAL_MS",hint:"Absolute max ms for any single engine task",default:"2700000"},{key:"CREWSWARM_DISPATCH_TIMEOUT_MS",hint:"ms before an unclaimed dispatch times out",default:"300000"},{key:"CREWSWARM_DISPATCH_CLAIMED_TIMEOUT_MS",hint:"ms before a claimed (in-progress) dispatch times out",default:"900000"},{key:"CREWSWARM_RT_AGENT",hint:"Agent ID used for the RT bus",default:"crew-coder"}]},{label:"Ports",vars:[{key:"CREW_LEAD_PORT",hint:"crew-lead HTTP server port",default:"5010"},{key:"SWARM_DASH_PORT",hint:"Dashboard port",default:"4319"},{key:"WA_HTTP_PORT",hint:"WhatsApp bridge HTTP port",default:"3000"}]},{label:"Background Consciousness",vars:[{key:"CREWSWARM_BG_CONSCIOUSNESS",hint:"Enable idle reflection loop",default:"off"},{key:"CREWSWARM_BG_CONSCIOUSNESS_INTERVAL_MS",hint:"Idle reflection interval in ms",default:"900000"},{key:"CREWSWARM_BG_CONSCIOUSNESS_MODEL",hint:"Model for background cycle (e.g. groq/llama-3.1-8b-instant)",default:"groq/llama-3.1-8b-instant"}]},{label:"Messaging",vars:[{key:"TELEGRAM_ALLOWED_USERNAMES",hint:"Comma-separated Telegram usernames allowed to message the bot",default:"all allowed"},{key:"WA_ALLOWED_NUMBERS",hint:"Comma-separated WhatsApp numbers in intl format (+1555…)",default:"all allowed"}]},{label:"Memory",vars:[{key:"SHARED_MEMORY_NAMESPACE",hint:"Namespace prefix for shared memory keys",default:"crewswarm"},{key:"SHARED_MEMORY_DIR",hint:"Directory for shared memory files",default:"~/.crewswarm/memory"}]},{label:"PM Loop",vars:[{key:"PM_MAX_ITEMS",hint:"Max roadmap items per PM loop run",default:"10"},{key:"PM_MAX_CONCURRENT",hint:"Max concurrent agent tasks in PM loop",default:"20"},{key:"PM_USE_QA",hint:"Include crew-qa review after each PM task",default:"off"},{key:"PM_USE_SECURITY",hint:"Include crew-security review for auth/key tasks",default:"off"},{key:"PM_USE_SPECIALISTS",hint:"Route tasks to specialist agents (front/back/github) by keyword",default:"on"},{key:"PM_SELF_EXTEND",hint:"Auto-generate new roadmap items when queue is empty",default:"on"},{key:"PM_EXTEND_EVERY",hint:"Generate new items every N completions (0 = only when empty)",default:"5"},{key:"PM_CODER_AGENT",hint:"Override default coding agent for PM loop (e.g. crew-coder-front)",default:"crew-coder"},{key:"PM_AGENT_IDLE_TIMEOUT_MS",hint:"Kill PM dispatch if no activity for this many ms",default:"900000"},{key:"PHASED_TASK_TIMEOUT_MS",hint:"Overall timeout for a single agent task in the PM loop",default:"600000"}]}];async function $(){const e=document.getElementById("envAdvancedWidget");if(e)try{const[t,o]=await Promise.all([fetch("/api/env").then(e=>e.json()).catch(()=>({})),fetch("/api/env-advanced").then(e=>e.json()).catch(()=>({env:{}}))]),a=o.env||{},s=null!=t.uptime?t.uptime<60?t.uptime+"s":Math.floor(t.uptime/60)+"m":"—";let r=`<div style="display:flex;gap:24px;flex-wrap:wrap;font-size:11px;color:var(--text-3);margin-bottom:16px;padding-bottom:10px;border-bottom:1px solid var(--border);">\n <span>cwd: <code style="color:var(--text-2);">${n(t.cwd||"—")}</code></span>\n <span>node: <code style="color:var(--text-2);">${n(t.node||"—")}</code></span>\n <span>uptime: <code style="color:var(--text-2);">${s}</code></span>\n </div>`;e.innerHTML=r;for(const l of U){const t=document.createElement("div");t.style.cssText="margin-bottom:18px;",t.innerHTML=`<div style="font-size:11px;font-weight:700;color:var(--text-3);text-transform:uppercase;letter-spacing:.06em;margin-bottom:${l.note?"4px":"8px"};">${n(l.label)}</div>`+(l.note?`<div style="font-size:11px;color:var(--accent);margin-bottom:8px;line-height:1.4;">${n(l.note)}</div>`:"");for(const{key:e,hint:o,default:s}of l.vars){const r=a[e]??null,l=r??s??"",c=null===r,i=s?`default: ${s}`:"not set",d=document.createElement("div");d.style.cssText="margin-bottom:8px;",d.innerHTML=`\n <div style="display:flex;align-items:baseline;gap:6px;margin-bottom:3px;">\n <span style="font-size:11px;font-family:monospace;color:var(--accent);">${n(e)}</span>\n ${c&&s?'<span style="font-size:10px;color:var(--text-3);font-family:monospace;background:var(--bg-1);padding:1px 5px;border-radius:4px;border:1px solid var(--border);">default</span>':""}\n </div>\n <div style="font-size:10px;color:var(--text-3);margin-bottom:4px;">${n(o)}</div>\n <div style="display:flex;gap:6px;align-items:center;">\n <input data-env-key="${n(e)}" data-env-default="${n(s||"")}" type="text" value="${n(l)}"\n placeholder="${n(i)}"\n class="inp-sm inp-mono inp-flex" />\n <button data-env-save="${n(e)}" style="font-size:11px;padding:5px 10px;border-radius:6px;cursor:pointer;border:1px solid var(--border);background:var(--surface-2);color:var(--text-2);white-space:nowrap;">Save</button>\n <span data-env-status="${n(e)}" style="font-size:11px;min-width:50px;"></span>\n </div>`,t.appendChild(d)}e.appendChild(t)}e.querySelectorAll("[data-env-save]").forEach(t=>{t.addEventListener("click",()=>{const o=t.dataset.envSave,a=e.querySelector(`[data-env-key="${o}"]`),n=e.querySelector(`[data-env-status="${o}"]`);a&&n&&async function(e,t,o){const a=t.value.trim();o.textContent="Saving…",o.style.color="var(--text-3)";try{const t=await fetch("/api/env-advanced",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({[e]:a||null})}),n=await t.json();n.ok?(o.textContent=a?"✓ Saved":"✓ Cleared",o.style.color="var(--green)"):(o.textContent="Error: "+(n.error||"unknown"),o.style.color="var(--red, #f87171)")}catch(n){o.textContent="Error: "+n.message,o.style.color="var(--red, #f87171)"}setTimeout(()=>{o.textContent=""},3e3)}(o,a,n)})}),e.querySelectorAll("[data-env-key]").forEach(e=>{e.addEventListener("input",()=>{const t=e.value===(e.dataset.envDefault||"");e.style.color="var(--text-1)",e.style.opacity=t?"0.65":"1"})})}catch(t){e&&(e.textContent="Could not load: "+t.message)}}export{_ as A,A as B,R as C,T as D,j as E,F,$ as G,i as H,P as a,W as b,B as c,O as d,S as e,M as f,x as g,C as h,E as i,N as j,f as k,p as l,g as m,d as n,v as o,m as p,b as q,D as r,G as s,L as t,y as u,u as v,h as w,k as x,w as y,I as z};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|