crewswarm 0.9.2 → 0.9.4
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-uXb_C0GM.js +1 -0
- package/apps/dashboard/dist/assets/chat-core-uXb_C0GM.js.br +0 -0
- package/apps/dashboard/dist/assets/cli-process-CNZ_UBCt.js +1 -0
- package/apps/dashboard/dist/assets/cli-process-CNZ_UBCt.js.br +0 -0
- package/apps/dashboard/dist/assets/index-BeVllEj_.js +2 -0
- package/apps/dashboard/dist/assets/index-BeVllEj_.js.br +0 -0
- package/apps/dashboard/dist/assets/{index-CF0aJRtC.css → index-D-sRshvg.css} +1 -1
- package/apps/dashboard/dist/assets/index-D-sRshvg.css.br +0 -0
- package/apps/dashboard/dist/assets/tab-benchmarks-tab-BHjKCPm3.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-models-tab-dNRgsTOO.js +1 -0
- package/apps/dashboard/dist/assets/tab-models-tab-dNRgsTOO.js.br +0 -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-pm-loop-tab-DiAPTJXu.js.br +0 -0
- package/apps/dashboard/dist/assets/{tab-projects-tab-DhNWnlzt.js → tab-projects-tab-SFH4E--a.js} +1 -1
- package/apps/dashboard/dist/assets/tab-projects-tab-SFH4E--a.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-settings-tab-CuvH_Fj_.js +1 -0
- package/apps/dashboard/dist/assets/tab-settings-tab-CuvH_Fj_.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-skills-tab-DR7PJ7NB.js +1 -0
- package/apps/dashboard/dist/assets/tab-skills-tab-DR7PJ7NB.js.br +0 -0
- package/apps/dashboard/dist/assets/tab-testing-tab-CezZOZcJ.js +1 -0
- package/apps/dashboard/dist/assets/tab-testing-tab-CezZOZcJ.js.br +0 -0
- package/apps/dashboard/dist/index.html +135 -15
- package/apps/dashboard/dist/index.html.br +0 -0
- package/apps/dashboard/dist/index.html.gz +0 -0
- package/apps/vibe/README.md +2 -2
- package/apps/vibe/package.json +1 -1
- package/apps/vibe/server.mjs +101 -56
- package/crew-lead.mjs +34 -4
- package/lib/bridges/cli-executor.mjs +1 -1
- package/lib/bridges/gateway-ws.mjs +4 -0
- package/lib/browser/passthrough-stderr.js +1 -0
- package/lib/chat/project-messages.mjs +3 -5
- package/lib/cli-process-tracker.mjs +3 -2
- package/lib/contacts/identity-linker.mjs +1 -0
- package/lib/crew-judge/judge.mjs +19 -18
- package/lib/crew-lead/agent-manager.mjs +1 -1
- package/lib/crew-lead/background.mjs +14 -1
- package/lib/crew-lead/chat-handler.mjs +38 -1
- package/lib/crew-lead/http-server.mjs +106 -57
- package/lib/crew-lead/llm-caller.mjs +24 -8
- package/lib/crew-lead/prompts.mjs +14 -1
- package/lib/crew-lead/tools.mjs +3 -2
- package/lib/crew-lead/wave-dispatcher.mjs +19 -5
- package/lib/crew-lead/ws-router.mjs +219 -27
- package/lib/engines/crew-cli.mjs +1 -1
- package/lib/engines/engine-registry.mjs +14 -3
- package/lib/engines/rt-envelope.mjs +1 -0
- package/lib/engines/runners.mjs +28 -4
- package/lib/gemini-cli-passthrough-noise.mjs +1 -1
- package/lib/integrations/code-search.mjs +4 -3
- package/lib/memory/shared-adapter.mjs +23 -10
- package/lib/pipeline/manager.mjs +2 -1
- package/lib/runtime/config.mjs +1 -1
- package/lib/runtime/paths.mjs +12 -8
- package/lib/runtime/spending.mjs +2 -1
- package/package.json +42 -14
- 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 +76 -0
- package/scripts/dashboard.mjs +1667 -551
- package/scripts/generate-openapi.mjs +683 -277
- 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/restart-service.sh +12 -9
- 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 +0 -1
- package/apps/dashboard/dist/assets/chat-core-Cx4sTxDd.js.br +0 -0
- package/apps/dashboard/dist/assets/cli-process-COMRNPqr.js +0 -1
- package/apps/dashboard/dist/assets/cli-process-COMRNPqr.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/tab-models-tab-BLEjmd19.js +0 -1
- 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-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 +0 -1
- package/apps/dashboard/dist/assets/tab-skills-tab-BpY0uZHW.js.br +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
|
Binary file
|
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Prompts tab — view and edit agent system prompts
|
|
3
|
-
* Deps: getJSON, postJSON (core/api), escHtml, showNotification (core/dom)
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { getJSON, postJSON } from "../core/api.js";
|
|
7
|
-
import { escHtml, showNotification } from "../core/dom.js";
|
|
8
|
-
import { state, persistState } from "../core/state.js";
|
|
9
|
-
|
|
10
|
-
let currentEditingAgent = null;
|
|
11
|
-
|
|
12
|
-
let hideAllViews = () => {};
|
|
13
|
-
let setNavActive = () => {};
|
|
14
|
-
|
|
15
|
-
/** Call once from app.js (same pattern as initAgentsTab). */
|
|
16
|
-
export function initPromptsTabDeps(deps = {}) {
|
|
17
|
-
hideAllViews = deps.hideAllViews || hideAllViews;
|
|
18
|
-
setNavActive = deps.setNavActive || setNavActive;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export async function initPromptsTab() {
|
|
22
|
-
hideAllViews();
|
|
23
|
-
const view = document.getElementById("promptsView");
|
|
24
|
-
if (view) {
|
|
25
|
-
view.classList.add("active");
|
|
26
|
-
}
|
|
27
|
-
setNavActive("navPrompts");
|
|
28
|
-
state.activeTab = "prompts";
|
|
29
|
-
persistState();
|
|
30
|
-
|
|
31
|
-
// Wire up event listeners (only once)
|
|
32
|
-
const list = document.getElementById("promptsList");
|
|
33
|
-
if (list && !list.dataset.wired) {
|
|
34
|
-
list.dataset.wired = "true";
|
|
35
|
-
list.addEventListener("click", (e) => {
|
|
36
|
-
if (e.target.closest(".prompt-edit-btn")) {
|
|
37
|
-
const agent = e.target.closest(".prompt-edit-btn").dataset.agent;
|
|
38
|
-
showPromptEditor(agent);
|
|
39
|
-
}
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
const cancelBtn = document.getElementById("promptEditorCancel");
|
|
44
|
-
const saveBtn = document.getElementById("promptEditorSave");
|
|
45
|
-
if (cancelBtn && !cancelBtn.dataset.wired) {
|
|
46
|
-
cancelBtn.dataset.wired = "true";
|
|
47
|
-
cancelBtn.addEventListener("click", hidePromptEditor);
|
|
48
|
-
}
|
|
49
|
-
if (saveBtn && !saveBtn.dataset.wired) {
|
|
50
|
-
saveBtn.dataset.wired = "true";
|
|
51
|
-
saveBtn.addEventListener("click", savePrompt);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
await loadPrompts();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export async function loadPrompts() {
|
|
58
|
-
try {
|
|
59
|
-
const data = await getJSON('/api/prompts');
|
|
60
|
-
const container = document.getElementById('promptsList');
|
|
61
|
-
if (!container) return;
|
|
62
|
-
|
|
63
|
-
const prompts = Object.entries(data.prompts || {});
|
|
64
|
-
|
|
65
|
-
if (!prompts.length) {
|
|
66
|
-
container.innerHTML = '<p style="color:var(--text-2);padding:16px;">No agent prompts configured.</p>';
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const html = prompts.map(([agentId, prompt]) => {
|
|
71
|
-
const preview = (prompt || '').slice(0, 150).replace(/\n/g, ' ');
|
|
72
|
-
const lines = (prompt || '').split('\n').length;
|
|
73
|
-
const chars = (prompt || '').length;
|
|
74
|
-
|
|
75
|
-
return `
|
|
76
|
-
<div class="prompt-card">
|
|
77
|
-
<div class="prompt-header">
|
|
78
|
-
<div>
|
|
79
|
-
<strong style="font-size:14px;">${escHtml(agentId)}</strong>
|
|
80
|
-
<div style="font-size:11px;color:var(--text-3);margin-top:2px;">
|
|
81
|
-
${lines} lines · ${chars} chars
|
|
82
|
-
</div>
|
|
83
|
-
</div>
|
|
84
|
-
<button class="btn-secondary prompt-edit-btn" data-agent="${escHtml(agentId)}">
|
|
85
|
-
Edit
|
|
86
|
-
</button>
|
|
87
|
-
</div>
|
|
88
|
-
<div class="prompt-preview">
|
|
89
|
-
${escHtml(preview)}${prompt.length > 150 ? '...' : ''}
|
|
90
|
-
</div>
|
|
91
|
-
</div>
|
|
92
|
-
`;
|
|
93
|
-
}).join('');
|
|
94
|
-
|
|
95
|
-
container.innerHTML = html;
|
|
96
|
-
|
|
97
|
-
// Update stats
|
|
98
|
-
document.getElementById('promptsCount').textContent = prompts.length;
|
|
99
|
-
|
|
100
|
-
} catch (e) {
|
|
101
|
-
showNotification('Failed to load prompts: ' + e.message, 'error');
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function showPromptEditor(agentId) {
|
|
106
|
-
currentEditingAgent = agentId;
|
|
107
|
-
|
|
108
|
-
getJSON('/api/prompts').then(data => {
|
|
109
|
-
const prompt = data.prompts[agentId] || '';
|
|
110
|
-
|
|
111
|
-
document.getElementById('promptEditorAgent').textContent = agentId;
|
|
112
|
-
document.getElementById('promptEditorTextarea').value = prompt;
|
|
113
|
-
document.getElementById('promptEditorChar').textContent = prompt.length;
|
|
114
|
-
document.getElementById('promptEditorLine').textContent = prompt.split('\n').length;
|
|
115
|
-
|
|
116
|
-
document.getElementById('promptEditor').style.display = 'block';
|
|
117
|
-
document.getElementById('promptEditorTextarea').focus();
|
|
118
|
-
|
|
119
|
-
// Live character count
|
|
120
|
-
document.getElementById('promptEditorTextarea').oninput = (e) => {
|
|
121
|
-
const val = e.target.value;
|
|
122
|
-
document.getElementById('promptEditorChar').textContent = val.length;
|
|
123
|
-
document.getElementById('promptEditorLine').textContent = val.split('\n').length;
|
|
124
|
-
};
|
|
125
|
-
}).catch(e => {
|
|
126
|
-
showNotification('Failed to load prompt: ' + e.message, 'error');
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
function hidePromptEditor() {
|
|
131
|
-
document.getElementById('promptEditor').style.display = 'none';
|
|
132
|
-
currentEditingAgent = null;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
async function savePrompt() {
|
|
136
|
-
if (!currentEditingAgent) return;
|
|
137
|
-
|
|
138
|
-
const newPrompt = document.getElementById('promptEditorTextarea').value;
|
|
139
|
-
const saveBtn = document.getElementById('promptEditorSave');
|
|
140
|
-
|
|
141
|
-
saveBtn.disabled = true;
|
|
142
|
-
saveBtn.textContent = 'Saving...';
|
|
143
|
-
|
|
144
|
-
try {
|
|
145
|
-
await postJSON('/api/prompts', {
|
|
146
|
-
agent: currentEditingAgent,
|
|
147
|
-
prompt: newPrompt
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
showNotification(`Prompt updated for ${currentEditingAgent}. Restart its bridge to apply.`);
|
|
151
|
-
hidePromptEditor();
|
|
152
|
-
await loadPrompts();
|
|
153
|
-
|
|
154
|
-
} catch (e) {
|
|
155
|
-
showNotification('Save failed: ' + e.message, 'error');
|
|
156
|
-
} finally {
|
|
157
|
-
saveBtn.disabled = false;
|
|
158
|
-
saveBtn.textContent = 'Save';
|
|
159
|
-
}
|
|
160
|
-
}
|
|
Binary file
|
|
@@ -1,202 +0,0 @@
|
|
|
1
|
-
import { getJSON, postJSON } from '../core/api.js';
|
|
2
|
-
import { escHtml, showNotification } from '../core/dom.js';
|
|
3
|
-
|
|
4
|
-
let servicesPollTimer = null;
|
|
5
|
-
let hideAllViews = () => {};
|
|
6
|
-
let setNavActive = () => {};
|
|
7
|
-
|
|
8
|
-
export function initServicesTab(deps = {}) {
|
|
9
|
-
hideAllViews = deps.hideAllViews || hideAllViews;
|
|
10
|
-
setNavActive = deps.setNavActive || setNavActive;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export function showServices() {
|
|
14
|
-
hideAllViews();
|
|
15
|
-
document.getElementById('servicesView').classList.add('active');
|
|
16
|
-
setNavActive('navServices');
|
|
17
|
-
loadServices();
|
|
18
|
-
if (servicesPollTimer) clearInterval(servicesPollTimer);
|
|
19
|
-
servicesPollTimer = setInterval(() => {
|
|
20
|
-
if (document.getElementById('servicesView').classList.contains('active')) loadServices();
|
|
21
|
-
else { clearInterval(servicesPollTimer); servicesPollTimer = null; }
|
|
22
|
-
}, 10000);
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export async function loadServices() {
|
|
26
|
-
const grid = document.getElementById('servicesGrid');
|
|
27
|
-
const summary = document.getElementById('servicesSummary');
|
|
28
|
-
if (!grid) return;
|
|
29
|
-
const hasRenderedServices = grid.children.length > 0;
|
|
30
|
-
if (!hasRenderedServices) {
|
|
31
|
-
grid.innerHTML = '<div class="meta" style="padding:20px;">Checking services...</div>';
|
|
32
|
-
}
|
|
33
|
-
try {
|
|
34
|
-
const services = await getJSON('/api/services/status');
|
|
35
|
-
const downCount = services.filter(s => !s.running && !s.optional).length;
|
|
36
|
-
const optionalDown = services.filter(s => !s.running && s.optional).length;
|
|
37
|
-
const badge = document.getElementById('servicesBadge');
|
|
38
|
-
if (badge) {
|
|
39
|
-
if (downCount > 0) {
|
|
40
|
-
badge.textContent = downCount;
|
|
41
|
-
badge.classList.remove('hidden');
|
|
42
|
-
} else {
|
|
43
|
-
badge.classList.add('hidden');
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
if (summary) {
|
|
47
|
-
const runningCount = services.filter(s => s.running).length;
|
|
48
|
-
const totalCount = services.length;
|
|
49
|
-
let tone = 'rgba(52, 211, 153, 0.08)';
|
|
50
|
-
let border = 'rgba(52, 211, 153, 0.26)';
|
|
51
|
-
let heading = `Healthy: ${runningCount}/${totalCount} services are up`;
|
|
52
|
-
let detail = 'You can keep working normally.';
|
|
53
|
-
if (downCount > 0) {
|
|
54
|
-
tone = 'rgba(248, 113, 113, 0.08)';
|
|
55
|
-
border = 'rgba(248, 113, 113, 0.28)';
|
|
56
|
-
heading = `${downCount} required service${downCount === 1 ? '' : 's'} down`;
|
|
57
|
-
detail = 'Try the service-specific restart first. If multiple services are down, run `npm run restart-all`, wait a few seconds, then refresh this tab.';
|
|
58
|
-
} else if (optionalDown > 0) {
|
|
59
|
-
tone = 'rgba(251, 191, 36, 0.08)';
|
|
60
|
-
border = 'rgba(251, 191, 36, 0.28)';
|
|
61
|
-
heading = `${optionalDown} optional service${optionalDown === 1 ? '' : 's'} down`;
|
|
62
|
-
detail = 'Core chat/runtime is still available. Start the optional service only if you need that surface.';
|
|
63
|
-
}
|
|
64
|
-
summary.style.display = 'block';
|
|
65
|
-
summary.style.background = tone;
|
|
66
|
-
summary.style.borderColor = border;
|
|
67
|
-
summary.innerHTML =
|
|
68
|
-
'<div style="font-weight:700;margin-bottom:6px;">' + escHtml(heading) + '</div>' +
|
|
69
|
-
'<div style="font-size:12px;color:var(--text-2);line-height:1.5;">' + escHtml(detail) + '</div>';
|
|
70
|
-
}
|
|
71
|
-
grid.innerHTML = services.map(svc => {
|
|
72
|
-
const up = svc.running;
|
|
73
|
-
const canRestart = svc.canRestart;
|
|
74
|
-
const statusColor = up ? 'var(--green-hi)' : 'var(--red-hi)';
|
|
75
|
-
const statusText = svc.statusText || (up ? (svc.pid ? '● running pid ' + svc.pid : '● running') : '● stopped');
|
|
76
|
-
const uptime = svc.uptimeSec ? formatUptime(svc.uptimeSec) : '';
|
|
77
|
-
const footerNote = svc.noteText || (!canRestart ? 'status only' : '');
|
|
78
|
-
return '<div class="card" style="display:flex;flex-direction:column;gap:10px;">' +
|
|
79
|
-
'<div style="display:flex;justify-content:space-between;align-items:flex-start;">' +
|
|
80
|
-
'<div>' +
|
|
81
|
-
'<div style="font-weight:700;font-size:14px;margin-bottom:3px;">' + escHtml(svc.label) + '</div>' +
|
|
82
|
-
'<div style="font-size:11px;color:var(--text-3);">' + escHtml(svc.description) + '</div>' +
|
|
83
|
-
'</div>' +
|
|
84
|
-
'<span style="font-size:11px;font-weight:600;color:' + statusColor + ';white-space:nowrap;margin-left:8px;">' + statusText + '</span>' +
|
|
85
|
-
'</div>' +
|
|
86
|
-
(uptime ? '<div style="font-size:11px;color:var(--text-3);">Up ' + uptime + '</div>' : '') +
|
|
87
|
-
(svc.port ? '<div style="font-size:11px;color:var(--text-3);">Port ' + svc.port + '</div>' : '') +
|
|
88
|
-
'<div style="display:flex;gap:6px;flex-wrap:wrap;">' +
|
|
89
|
-
(canRestart && up ? '<button class="btn-ghost" style="font-size:12px;" data-action="restartService" data-arg="' + svc.id + '">↻ Restart</button>' : '') +
|
|
90
|
-
(canRestart && !up ? '<button class="btn-green" style="font-size:12px;" data-action="restartService" data-arg="' + svc.id + '">▶ Start</button>' : '') +
|
|
91
|
-
(canRestart && up ? '<button class="btn-red" style="font-size:12px;" data-action="stopService" data-arg="' + svc.id + '">⏹ Stop</button>' : '') +
|
|
92
|
-
(!canRestart ? '<span style="font-size:11px;color:var(--text-3);align-self:center;">' + escHtml(footerNote) + '</span>' : '') +
|
|
93
|
-
'</div>' +
|
|
94
|
-
'</div>';
|
|
95
|
-
}).join('');
|
|
96
|
-
} catch (e) {
|
|
97
|
-
if (summary) {
|
|
98
|
-
summary.style.display = 'block';
|
|
99
|
-
summary.style.background = 'rgba(248, 113, 113, 0.08)';
|
|
100
|
-
summary.style.borderColor = 'rgba(248, 113, 113, 0.28)';
|
|
101
|
-
summary.innerHTML =
|
|
102
|
-
'<div style="font-weight:700;margin-bottom:6px;">Services status unavailable</div>' +
|
|
103
|
-
'<div style="font-size:12px;color:var(--text-2);line-height:1.5;">Run <code>npm run doctor</code> to check the stack, then try <code>npm run restart-all</code> if the dashboard API is up but service status is stale.</div>';
|
|
104
|
-
}
|
|
105
|
-
if (!hasRenderedServices) {
|
|
106
|
-
grid.innerHTML = '<div class="meta" style="padding:20px;color:var(--red-hi);">Error loading services: ' + e.message + '<div style="margin-top:8px;color:var(--text-3);font-size:12px;">Try <code>npm run doctor</code>, then <code>npm run restart-all</code> if core services are down.</div></div>';
|
|
107
|
-
}
|
|
108
|
-
showNotification('⚠️ Failed to load services: ' + e.message, true);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
function formatUptime(sec) {
|
|
113
|
-
if (sec < 60) return sec + 's';
|
|
114
|
-
if (sec < 3600) return Math.floor(sec / 60) + 'm ' + (sec % 60) + 's';
|
|
115
|
-
return Math.floor(sec / 3600) + 'h ' + Math.floor((sec % 3600) / 60) + 'm';
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export async function restartService(id) {
|
|
119
|
-
// Find and disable the button immediately
|
|
120
|
-
const btn = document.querySelector(`button[data-action="restartService"][data-arg="${id}"]`);
|
|
121
|
-
if (btn) {
|
|
122
|
-
btn.disabled = true;
|
|
123
|
-
btn.style.opacity = '0.5';
|
|
124
|
-
btn.style.cursor = 'not-allowed';
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Debounce: prevent rapid double-clicks
|
|
128
|
-
const now = Date.now();
|
|
129
|
-
const lastRestart = window._lastServiceRestart || {};
|
|
130
|
-
if (lastRestart[id] && (now - lastRestart[id]) < 3000) {
|
|
131
|
-
showNotification('⏳ Restart already in progress...', 'warning');
|
|
132
|
-
if (btn) {
|
|
133
|
-
btn.disabled = false;
|
|
134
|
-
btn.style.opacity = '';
|
|
135
|
-
btn.style.cursor = '';
|
|
136
|
-
}
|
|
137
|
-
return;
|
|
138
|
-
}
|
|
139
|
-
if (!window._lastServiceRestart) window._lastServiceRestart = {};
|
|
140
|
-
window._lastServiceRestart[id] = now;
|
|
141
|
-
|
|
142
|
-
try {
|
|
143
|
-
const r = await postJSON('/api/services/restart', { id });
|
|
144
|
-
if (r && r.ok === false && r.message) {
|
|
145
|
-
showNotification('⚠️ ' + r.message, 'warning');
|
|
146
|
-
} else {
|
|
147
|
-
showNotification('Restarting ' + id + '... Refresh in a few seconds if the status looks stale.');
|
|
148
|
-
// Reload after delay to show new status
|
|
149
|
-
setTimeout(loadServices, id === 'crew-lead' ? 4000 : 3000);
|
|
150
|
-
}
|
|
151
|
-
} catch (e) {
|
|
152
|
-
showNotification('❌ Restart failed: ' + e.message + ' — try `npm run doctor` or a full `npm run restart-all`.', true);
|
|
153
|
-
if (btn) {
|
|
154
|
-
btn.disabled = false;
|
|
155
|
-
btn.style.opacity = '';
|
|
156
|
-
btn.style.cursor = '';
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
export async function stopService(id) {
|
|
162
|
-
// Find and disable all buttons for this service immediately
|
|
163
|
-
const buttons = document.querySelectorAll(`button[data-arg="${id}"]`);
|
|
164
|
-
buttons.forEach(b => {
|
|
165
|
-
b.disabled = true;
|
|
166
|
-
b.style.opacity = '0.5';
|
|
167
|
-
b.style.cursor = 'not-allowed';
|
|
168
|
-
});
|
|
169
|
-
|
|
170
|
-
// Debounce: prevent rapid double-clicks
|
|
171
|
-
const now = Date.now();
|
|
172
|
-
const lastStop = window._lastServiceStop || {};
|
|
173
|
-
if (lastStop[id] && (now - lastStop[id]) < 2000) {
|
|
174
|
-
showNotification('⏳ Stop already in progress...', 'warning');
|
|
175
|
-
buttons.forEach(b => {
|
|
176
|
-
b.disabled = false;
|
|
177
|
-
b.style.opacity = '';
|
|
178
|
-
b.style.cursor = '';
|
|
179
|
-
});
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
if (!window._lastServiceStop) window._lastServiceStop = {};
|
|
183
|
-
window._lastServiceStop[id] = now;
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
const r = await postJSON('/api/services/stop', { id });
|
|
187
|
-
if (r && r.ok === false && r.message) {
|
|
188
|
-
showNotification('⚠️ ' + r.message, 'warning');
|
|
189
|
-
} else {
|
|
190
|
-
showNotification('Stopping ' + id + '...');
|
|
191
|
-
// Reload after delay to show new status
|
|
192
|
-
setTimeout(loadServices, 1500);
|
|
193
|
-
}
|
|
194
|
-
} catch (e) {
|
|
195
|
-
showNotification('❌ Stop failed: ' + e.message + ' — use `npm run doctor` if service state looks inconsistent.', true);
|
|
196
|
-
buttons.forEach(b => {
|
|
197
|
-
b.disabled = false;
|
|
198
|
-
b.style.opacity = '';
|
|
199
|
-
b.style.cursor = '';
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
}
|
|
Binary file
|