@jakkrichm/create-nexus-devflow 2.0.27 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -7
- package/dist/bin/create-nexus-devflow.d.ts +5 -1
- package/dist/bin/create-nexus-devflow.js +247 -4
- package/dist/bin/create-nexus-devflow.js.map +1 -1
- package/dist/lib/branch-context.d.ts +39 -0
- package/dist/lib/branch-context.js +196 -0
- package/dist/lib/branch-context.js.map +1 -0
- package/dist/lib/code-graph.d.ts +30 -0
- package/dist/lib/code-graph.js +209 -0
- package/dist/lib/code-graph.js.map +1 -0
- package/dist/lib/context-slicer.d.ts +31 -0
- package/dist/lib/context-slicer.js +234 -0
- package/dist/lib/context-slicer.js.map +1 -0
- package/dist/lib/current-work.js +4 -2
- package/dist/lib/current-work.js.map +1 -1
- package/dist/lib/dashboard-page.d.ts +1 -1
- package/dist/lib/dashboard-page.js +140 -56
- package/dist/lib/dashboard-page.js.map +1 -1
- package/dist/lib/dashboard-snapshot.d.ts +13 -0
- package/dist/lib/dashboard-snapshot.js +24 -6
- package/dist/lib/dashboard-snapshot.js.map +1 -1
- package/dist/lib/dashboard.js +38 -0
- package/dist/lib/dashboard.js.map +1 -1
- package/dist/lib/drift-reconciler.d.ts +38 -0
- package/dist/lib/drift-reconciler.js +155 -0
- package/dist/lib/drift-reconciler.js.map +1 -0
- package/dist/lib/gatekeeper.d.ts +1 -0
- package/dist/lib/gatekeeper.js +30 -1
- package/dist/lib/gatekeeper.js.map +1 -1
- package/dist/lib/git-hooks.js +41 -16
- package/dist/lib/git-hooks.js.map +1 -1
- package/dist/lib/ide-extension.d.ts +38 -0
- package/dist/lib/ide-extension.js +61 -0
- package/dist/lib/ide-extension.js.map +1 -0
- package/dist/lib/mcp.d.ts +36 -0
- package/dist/lib/mcp.js +653 -0
- package/dist/lib/mcp.js.map +1 -0
- package/dist/lib/project-metadata.d.ts +1 -1
- package/dist/lib/project-metadata.js +3 -2
- package/dist/lib/project-metadata.js.map +1 -1
- package/dist/lib/status.d.ts +1 -1
- package/dist/lib/status.js +4 -4
- package/dist/lib/status.js.map +1 -1
- package/dist/lib/swarm-orchestrator.d.ts +31 -0
- package/dist/lib/swarm-orchestrator.js +134 -0
- package/dist/lib/swarm-orchestrator.js.map +1 -0
- package/dist/lib/update.js +7 -3
- package/dist/lib/update.js.map +1 -1
- package/dist/lib/webview-studio.d.ts +8 -0
- package/dist/lib/webview-studio.js +463 -0
- package/dist/lib/webview-studio.js.map +1 -0
- package/dist/lib/workflow-state.js +24 -8
- package/dist/lib/workflow-state.js.map +1 -1
- package/package.json +1 -1
- package/template/.agents/skills/adopt/SKILL.md +58 -5
- package/template/.agents/skills/doctor/SKILL.md +23 -16
- package/template/.agents/skills/implement/SKILL.md +2 -2
- package/template/.agents/skills/onboard/SKILL.md +18 -17
- package/template/.agents/skills/rollback/SKILL.md +1 -1
- package/template/.claude/skills/00-explore/SKILL.md +2 -2
- package/template/.claude/skills/10-define/SKILL.md +2 -2
- package/template/.claude/skills/20-spec/SKILL.md +1 -2
- package/template/.claude/skills/30-plan/SKILL.md +1 -2
- package/template/.claude/skills/40-execute/SKILL.md +2 -2
- package/template/.claude/skills/50-verify/SKILL.md +2 -2
- package/template/.claude/skills/60-report/SKILL.md +2 -2
- package/template/.claude/skills/70-deliver/SKILL.md +2 -2
- package/template/.claude/skills/adopt/SKILL.md +191 -75
- package/template/.claude/skills/audit/SKILL.md +267 -133
- package/template/.claude/skills/autopilot/SKILL.md +226 -167
- package/template/.claude/skills/brainstorm/SKILL.md +62 -0
- package/template/.claude/skills/brief/SKILL.md +93 -92
- package/template/.claude/skills/check/SKILL.md +96 -76
- package/template/.claude/skills/ci/SKILL.md +140 -61
- package/template/.claude/skills/complete/SKILL.md +156 -101
- package/template/.claude/skills/convert-any-to-md/SKILL.md +2 -2
- package/template/.claude/skills/convert-any-to-md/references/setup.md +29 -0
- package/template/.claude/skills/convert-any-to-md/scripts/convert_any_to_md.py +487 -0
- package/template/.claude/skills/convert-any-to-md/scripts/requirements.txt +3 -0
- package/template/.claude/skills/debug/SKILL.md +124 -49
- package/template/.claude/skills/devflow/SKILL.md +9 -3
- package/template/.claude/skills/discovery/SKILL.md +150 -129
- package/template/.claude/skills/doctor/SKILL.md +195 -72
- package/template/.claude/skills/feature/SKILL.md +195 -151
- package/template/.claude/skills/fix/SKILL.md +41 -90
- package/template/.claude/skills/idea/SKILL.md +2 -2
- package/template/.claude/skills/implement/SKILL.md +189 -46
- package/template/.claude/skills/onboard/SKILL.md +216 -85
- package/template/.claude/skills/overview/SKILL.md +44 -29
- package/template/.claude/skills/prototype/SKILL.md +82 -27
- package/template/.claude/skills/release/SKILL.md +119 -130
- package/template/.claude/skills/report-html/SKILL.md +2 -2
- package/template/.claude/skills/rollback/SKILL.md +123 -77
- package/template/.claude/skills/status/SKILL.md +109 -0
- package/template/.claude/skills/test/SKILL.md +2 -2
- package/template/.claude/skills/tests/SKILL.md +126 -0
- package/template/.claude/skills/try/SKILL.md +77 -65
- package/template/AGENTS.md +2 -1
- package/template/devflow/build-plan.md +50 -20
- package/template/devflow/history/features/README.md +5 -0
- package/template/devflow/history/fixes/README.md +5 -0
- package/template/devflow/history/rollbacks/README.md +5 -0
- package/template/devflow/project-plan.md +70 -18
- package/template/devflow/reference/studio.html +504 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import fsSync from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { resolveActiveContextPaths } from "./branch-context.js";
|
|
5
|
+
import { readFindings } from "./findings.js";
|
|
6
|
+
import { readProjectStatus } from "./status.js";
|
|
7
|
+
/**
|
|
8
|
+
* Estimates token count for text using standard character/word heuristic for mixed markdown/code.
|
|
9
|
+
*/
|
|
10
|
+
export function estimateTokenCount(text) {
|
|
11
|
+
if (!text || text.length === 0)
|
|
12
|
+
return 0;
|
|
13
|
+
// Standard mixed heuristic: ~3.5 chars per token for markdown + code
|
|
14
|
+
return Math.ceil(text.length / 3.5);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Parses markdown into discrete sections by headings (## or ###) and filters by allowed patterns.
|
|
18
|
+
*/
|
|
19
|
+
export function pruneMarkdownSections(markdown, allowedHeadingPatterns, maxTokens) {
|
|
20
|
+
const lines = markdown.split("\n");
|
|
21
|
+
const sections = [];
|
|
22
|
+
let currentHeading = "Header";
|
|
23
|
+
let currentLines = [];
|
|
24
|
+
for (const line of lines) {
|
|
25
|
+
if (/^#{1,3}\s+/.test(line)) {
|
|
26
|
+
if (currentLines.length > 0) {
|
|
27
|
+
sections.push({ heading: currentHeading, lines: currentLines });
|
|
28
|
+
}
|
|
29
|
+
currentHeading = line;
|
|
30
|
+
currentLines = [line];
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
currentLines.push(line);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
if (currentLines.length > 0) {
|
|
37
|
+
sections.push({ heading: currentHeading, lines: currentLines });
|
|
38
|
+
}
|
|
39
|
+
const filteredSections = sections.filter((sec) => {
|
|
40
|
+
if (sec.heading === "Header")
|
|
41
|
+
return true; // keep frontmatter/title header
|
|
42
|
+
return allowedHeadingPatterns.some((pattern) => pattern.test(sec.heading));
|
|
43
|
+
});
|
|
44
|
+
let result = filteredSections.map((s) => s.lines.join("\n")).join("\n").trim();
|
|
45
|
+
if (maxTokens && estimateTokenCount(result) > maxTokens) {
|
|
46
|
+
// Truncate safely at character limit
|
|
47
|
+
const maxChars = Math.floor(maxTokens * 3.5);
|
|
48
|
+
result = result.slice(0, maxChars) + "\n\n... [Content truncated to satisfy Token Budget]";
|
|
49
|
+
}
|
|
50
|
+
return result;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Creates a stage-aware context slice for AI agents, omitting irrelevant sections.
|
|
54
|
+
*/
|
|
55
|
+
export async function sliceContextForStage(projectRoot, stage, options = {}) {
|
|
56
|
+
const contextPaths = await resolveActiveContextPaths(projectRoot, options.customBranch);
|
|
57
|
+
const sections = [];
|
|
58
|
+
let rawContentAccumulator = "";
|
|
59
|
+
// Helper to read file safely
|
|
60
|
+
async function safeRead(filePath) {
|
|
61
|
+
try {
|
|
62
|
+
if (fsSync.existsSync(filePath)) {
|
|
63
|
+
const text = await fs.readFile(filePath, "utf8");
|
|
64
|
+
rawContentAccumulator += text + "\n\n";
|
|
65
|
+
return text;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
catch { }
|
|
69
|
+
return "";
|
|
70
|
+
}
|
|
71
|
+
switch (stage) {
|
|
72
|
+
case "implement": {
|
|
73
|
+
// 1. Living Spec (Pruned: Scope + Checklist)
|
|
74
|
+
const specRaw = await safeRead(contextPaths.featureSpecPath);
|
|
75
|
+
if (specRaw) {
|
|
76
|
+
const prunedSpec = pruneMarkdownSections(specRaw, [
|
|
77
|
+
/1\.\s*Specification\s*&\s*Scope/i,
|
|
78
|
+
/3\.\s*Implementation\s*Checklist/i
|
|
79
|
+
]);
|
|
80
|
+
sections.push({
|
|
81
|
+
name: "Active Spec (In-Scope & Tasks)",
|
|
82
|
+
tokens: estimateTokenCount(prunedSpec),
|
|
83
|
+
content: prunedSpec
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// 2. Relevant Coding Standards
|
|
87
|
+
const standardsRaw = await safeRead(path.join(projectRoot, "devflow", "context", "coding-standards.md"));
|
|
88
|
+
if (standardsRaw) {
|
|
89
|
+
const prunedStandards = pruneMarkdownSections(standardsRaw, [
|
|
90
|
+
/Core\s*Principles/i,
|
|
91
|
+
/Engineering\s*Conventions/i,
|
|
92
|
+
/Rules/i
|
|
93
|
+
], 800);
|
|
94
|
+
sections.push({
|
|
95
|
+
name: "Core Coding Standards",
|
|
96
|
+
tokens: estimateTokenCount(prunedStandards),
|
|
97
|
+
content: prunedStandards
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
// 3. Active Findings Blockers
|
|
101
|
+
const findings = await readFindings(projectRoot);
|
|
102
|
+
if (findings.blockers.length > 0 || findings.items.length > 0) {
|
|
103
|
+
const blockersText = [
|
|
104
|
+
"## Active Findings Ledger",
|
|
105
|
+
...findings.blockers.map((b) => `- ✖ [${b.severity}] ${b.status}: ${b.title} (${b.id})`),
|
|
106
|
+
...findings.items.filter((a) => !findings.blockers.includes(a)).map((a) => `- ⚠ [${a.severity}] ${a.status}: ${a.title}`)
|
|
107
|
+
].join("\n");
|
|
108
|
+
sections.push({
|
|
109
|
+
name: "Findings & Quality Constraints",
|
|
110
|
+
tokens: estimateTokenCount(blockersText),
|
|
111
|
+
content: blockersText
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
case "check": {
|
|
117
|
+
// 1. Acceptance Criteria & Verification Matrix
|
|
118
|
+
const specRaw = await safeRead(contextPaths.featureSpecPath);
|
|
119
|
+
if (specRaw) {
|
|
120
|
+
const prunedSpec = pruneMarkdownSections(specRaw, [
|
|
121
|
+
/Acceptance\s*Criteria/i,
|
|
122
|
+
/Verification\s*Evidence/i,
|
|
123
|
+
/Quality\s*Gates/i
|
|
124
|
+
]);
|
|
125
|
+
sections.push({
|
|
126
|
+
name: "Acceptance Criteria & Quality Gates",
|
|
127
|
+
tokens: estimateTokenCount(prunedSpec),
|
|
128
|
+
content: prunedSpec
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
// 2. Active Blockers
|
|
132
|
+
const findings = await readFindings(projectRoot);
|
|
133
|
+
if (findings.blockers.length > 0) {
|
|
134
|
+
const blockersText = [
|
|
135
|
+
"## Blockers to Verify",
|
|
136
|
+
...findings.blockers.map((b) => `- ✖ [${b.severity}] ${b.status}: ${b.title}`)
|
|
137
|
+
].join("\n");
|
|
138
|
+
sections.push({
|
|
139
|
+
name: "Blocking Quality Findings",
|
|
140
|
+
tokens: estimateTokenCount(blockersText),
|
|
141
|
+
content: blockersText
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
case "explore": {
|
|
147
|
+
// 1. Project Overview (Architecture Summary)
|
|
148
|
+
const overviewRaw = await safeRead(path.join(projectRoot, "devflow", "context", "project-overview.md"));
|
|
149
|
+
if (overviewRaw) {
|
|
150
|
+
const prunedOverview = pruneMarkdownSections(overviewRaw, [
|
|
151
|
+
/Architecture/i,
|
|
152
|
+
/Vision/i,
|
|
153
|
+
/Directives/i
|
|
154
|
+
], 600);
|
|
155
|
+
sections.push({
|
|
156
|
+
name: "Architecture & Directives",
|
|
157
|
+
tokens: estimateTokenCount(prunedOverview),
|
|
158
|
+
content: prunedOverview
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
// 2. Ideas Backlog
|
|
162
|
+
const ideasRaw = await safeRead(path.join(projectRoot, "devflow", "ideas.md"));
|
|
163
|
+
if (ideasRaw) {
|
|
164
|
+
const prunedIdeas = ideasRaw.split("\n").slice(0, 50).join("\n");
|
|
165
|
+
sections.push({
|
|
166
|
+
name: "Ideas Backlog (Top)",
|
|
167
|
+
tokens: estimateTokenCount(prunedIdeas),
|
|
168
|
+
content: prunedIdeas
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
case "feature": {
|
|
174
|
+
// 1. Build Plan Feature Queue
|
|
175
|
+
const buildPlanRaw = await safeRead(path.join(projectRoot, "devflow", "build-plan.md"));
|
|
176
|
+
if (buildPlanRaw) {
|
|
177
|
+
const nextFeatures = buildPlanRaw.split("\n").filter((l) => l.startsWith("- [ ]") || l.startsWith("##")).slice(0, 30).join("\n");
|
|
178
|
+
sections.push({
|
|
179
|
+
name: "Build Plan Feature Queue",
|
|
180
|
+
tokens: estimateTokenCount(nextFeatures),
|
|
181
|
+
content: nextFeatures
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
// 2. Living Project Overview Constraints
|
|
185
|
+
const overviewRaw = await safeRead(path.join(projectRoot, "devflow", "context", "project-overview.md"));
|
|
186
|
+
if (overviewRaw) {
|
|
187
|
+
const prunedOverview = pruneMarkdownSections(overviewRaw, [
|
|
188
|
+
/Tech\s*Stack/i,
|
|
189
|
+
/Standards/i
|
|
190
|
+
], 500);
|
|
191
|
+
sections.push({
|
|
192
|
+
name: "Tech Stack & Standards",
|
|
193
|
+
tokens: estimateTokenCount(prunedOverview),
|
|
194
|
+
content: prunedOverview
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
break;
|
|
198
|
+
}
|
|
199
|
+
case "status":
|
|
200
|
+
default: {
|
|
201
|
+
const status = await readProjectStatus(projectRoot);
|
|
202
|
+
const statusText = JSON.stringify({
|
|
203
|
+
project: status.project.name,
|
|
204
|
+
currentWork: status.currentWork,
|
|
205
|
+
findings: status.findings.total,
|
|
206
|
+
blockers: status.findings.blockers.length,
|
|
207
|
+
nextAction: status.nextAction
|
|
208
|
+
}, null, 2);
|
|
209
|
+
sections.push({
|
|
210
|
+
name: "Pulse Status",
|
|
211
|
+
tokens: estimateTokenCount(statusText),
|
|
212
|
+
content: statusText
|
|
213
|
+
});
|
|
214
|
+
break;
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
let finalContent = sections.map((s) => `### [Slice: ${s.name}]\n${s.content}`).join("\n\n---\n\n");
|
|
218
|
+
if (options.maxTokens && estimateTokenCount(finalContent) > options.maxTokens) {
|
|
219
|
+
const maxChars = Math.floor(options.maxTokens * 3.5);
|
|
220
|
+
finalContent = finalContent.slice(0, maxChars) + "\n\n... [Truncated by JIT Token Budget]";
|
|
221
|
+
}
|
|
222
|
+
const rawTokens = estimateTokenCount(rawContentAccumulator) || estimateTokenCount(finalContent) * 2;
|
|
223
|
+
const estimatedTokens = estimateTokenCount(finalContent);
|
|
224
|
+
const reductionPercentage = Math.max(0, Math.round(((rawTokens - estimatedTokens) / rawTokens) * 100));
|
|
225
|
+
return {
|
|
226
|
+
stage,
|
|
227
|
+
estimatedTokens,
|
|
228
|
+
rawTokens,
|
|
229
|
+
reductionPercentage,
|
|
230
|
+
content: finalContent,
|
|
231
|
+
sections
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
//# sourceMappingURL=context-slicer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-slicer.js","sourceRoot":"","sources":["../../lib/context-slicer.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/current-work.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
|
+
import { resolveActiveContextPaths } from "./branch-context.js";
|
|
3
4
|
const DEVFLOW_CURRENT_FEATURE_PATH = path.join("devflow", "context", "current-feature.md");
|
|
4
5
|
const DEVFLOW_CURRENT_RUN_DIR = path.join("devflow", "context", "current-run");
|
|
5
6
|
const CURRENT_STAGE_PATH = path.join("devflow", "context", "current-stage.md");
|
|
@@ -7,8 +8,9 @@ const LEGACY_FEATURE_PATH = path.join("blueprint", "context", "current-feature.m
|
|
|
7
8
|
const RESET_MARKER = "_Nothing in progress.";
|
|
8
9
|
const CHECKBOX_PATTERN = /^\s*-\s+\[([ xX])\]\s+(.+?)\s*$/;
|
|
9
10
|
async function readCurrentWork(projectRoot) {
|
|
10
|
-
const
|
|
11
|
-
const
|
|
11
|
+
const contextPaths = await resolveActiveContextPaths(projectRoot);
|
|
12
|
+
const currentStageFile = contextPaths.stagePath;
|
|
13
|
+
const devflowFeatureFile = contextPaths.featureSpecPath;
|
|
12
14
|
// 1. Root Switch Authority: Check devflow/context/current-stage.md
|
|
13
15
|
try {
|
|
14
16
|
const stageStats = await fs.lstat(currentStageFile).catch(() => null);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"current-work.js","sourceRoot":"","sources":["../../lib/current-work.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"current-work.js","sourceRoot":"","sources":["../../lib/current-work.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const DASHBOARD_PAGE_HTML = "<!doctype html>\n<html lang=\"th\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Nexus-DevFlow Blueprint Dashboard</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n <link href=\"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&family=Noto+Sans+Thai:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap\" rel=\"stylesheet\">\n <style>\n :root{\n --font-display:\"Google Sans Thai\",\"Google Sans\",\"Noto Sans Thai\",\"Space Grotesk\",sans-serif;\n --font-sans:\"Google Sans Thai\",\"Google Sans\",\"Noto Sans Thai\",sans-serif;\n --font-mono:\"IBM Plex Mono\",monospace;\n --bg:#0a2540;--bg-deep:#061a2e;--panel:rgba(255,255,255,.04);--panel-strong:#0c2b49;\n --ink:#edf6ff;--soft:#b7d3ef;--muted:#7598ba;--line:rgba(191,224,255,.17);--line-strong:rgba(191,224,255,.36);\n --cyan:#7dd8ff;--mint:#6fe3b4;--gold:#f2c14e;--red:#ff7061;--violet:#b8a4ff;\n --mint-soft:rgba(111,227,180,.14);--gold-soft:rgba(242,193,78,.14);--red-soft:rgba(255,112,97,.14);--violet-soft:rgba(184,164,255,.14);\n }\n *{box-sizing:border-box}\n html{color-scheme:dark}\n body{margin:0;min-height:100vh;background-color:var(--bg);color:var(--ink);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;background-image:linear-gradient(rgba(125,216,255,.065) 1px,transparent 1px),linear-gradient(90deg,rgba(125,216,255,.065) 1px,transparent 1px),radial-gradient(circle at 8% -5%,rgba(125,216,255,.16),transparent 42rem);background-size:34px 34px,34px 34px,auto}\n button{font:inherit}\n code{font-family:var(--font-mono);color:var(--cyan)}\n .sheet{width:min(1180px,calc(100% - 40px));margin:0 auto;padding:34px 0 64px}\n .titleblock{display:flex;align-items:flex-end;justify-content:space-between;gap:26px;padding-bottom:20px;border-bottom:1px solid var(--line-strong);flex-wrap:wrap}\n .eyebrow,.label{font:600 10px/1 var(--font-mono);letter-spacing:.13em;text-transform:uppercase;color:var(--cyan)}\n .eyebrow{display:flex;align-items:center;gap:8px;margin-bottom:12px}.eyebrow:before{content:\"\";width:20px;height:1px;background:var(--cyan)}\n h1{margin:0 0 6px;font:700 clamp(32px,4vw,48px)/1.05 var(--font-display);letter-spacing:-.03em}\n .path,.muted{color:var(--muted);font-size:12px;line-height:1.65}.path{font-family:var(--font-mono)}\n .badges{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.badge,.pill{padding:4px 9px;border:1px solid var(--line-strong);border-radius:3px;background:rgba(255,255,255,.025);color:var(--muted);font:600 10px/1.5 var(--font-mono);text-transform:uppercase}\n .ok,.healthy,.current,.ready,.idle{border-color:rgba(111,227,180,.42)!important;color:var(--mint)!important;background:var(--mint-soft)!important}\n .warning,.available,.offline,.blocked,.fail{border-color:rgba(255,112,97,.42)!important;color:var(--red)!important;background:var(--red-soft)!important}\n .active,.deep,.fast,.configured{border-color:rgba(184,164,255,.42)!important;color:var(--violet)!important;background:var(--violet-soft)!important}\n .meta{display:grid;grid-template-columns:auto auto;gap:4px 20px;margin:0;font:11px/1.55 var(--font-mono)}.meta dt{color:var(--muted);text-transform:uppercase}.meta dd{margin:0;color:var(--soft);text-align:right}\n .live{display:flex;align-items:center;gap:8px;margin:14px 0 24px;font:11px var(--font-mono);color:var(--muted)}.live-dot{width:7px;height:7px;border-radius:50%;background:var(--gold)}.live-dot.on{background:var(--mint);box-shadow:0 0 0 4px rgba(111,227,180,.12)}\n .panel,.card{position:relative;min-width:0;border:1px solid var(--line);border-radius:4px;background:var(--panel)}\n #dual-track{overflow:hidden}\n .stepper{justify-content:center}.step{display:flex;flex-direction:column;align-items:center;text-align:center}.step-icon{display:grid;place-items:center;width:30px;height:30px;margin:10px auto 8px;border:1px solid currentColor;border-radius:8px;background:rgba(255,255,255,.035)}.icon-glyph{display:block;font-size:17px;line-height:1}.step.flow-0,.step.flow-4{color:var(--cyan)}.step.flow-1,.step.flow-5{color:var(--violet)}.step.flow-2,.step.flow-6{color:var(--gold)}.step.flow-3,.step.flow-7{color:var(--mint)}.step .step-name{color:currentColor}.step .step-cmd{color:var(--muted)}\n .panel{padding:24px 26px;margin-bottom:20px}.panel-head,.card-head{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}.panel-head{margin-bottom:20px}.card-head{margin-bottom:17px}\n .track-tabs{display:flex;gap:7px}.tab{display:inline-flex;align-items:center;gap:7px;padding:7px 13px;border:1px solid var(--line-strong);border-radius:99px;background:transparent;color:var(--muted);font:600 10px var(--font-mono);cursor:pointer}.tab:hover,.tab:focus-visible{border-color:var(--cyan);color:var(--cyan);outline:none}.tab.on{background:var(--cyan);border-color:var(--cyan);color:var(--bg-deep)}.tab-active-dot{display:none;padding:2px 6px;border-radius:99px;font:700 8px/1 var(--font-mono);letter-spacing:.05em;text-transform:uppercase;background:var(--mint);color:var(--bg-deep)}.tab.is-active-track .tab-active-dot{display:inline-flex;align-items:center;gap:3px;box-shadow:0 0 0 2px rgba(111,227,180,.25)}.tab.on.is-active-track .tab-active-dot{background:var(--bg-deep);color:var(--mint)}\n .track-view{display:none;min-width:0}.track-view.on{display:block}.stepper{display:flex;width:100%;max-width:100%;overflow-x:auto;padding:4px 0 7px}.step{flex:1 1 0;min-width:104px;position:relative;padding-right:12px}.step-line{position:absolute;top:10px;left:21px;right:0;height:1px;background:var(--line-strong)}.step:last-child .step-line{display:none}.step.done .step-line{background:var(--mint)}\n .step-dot{position:relative;z-index:1;width:21px;height:21px;border-radius:50%;display:grid;place-items:center;border:2px solid var(--line-strong);background:var(--bg-deep);color:var(--muted);font:700 8px var(--font-mono)}.step.done .step-dot{border-color:var(--mint);color:var(--mint)}.step.active .step-dot{border-color:var(--gold);color:var(--gold);box-shadow:0 0 0 4px rgba(242,193,78,.16)}\n .step-name{margin-top:9px;color:var(--soft);font:600 10px/1.35 var(--font-mono)}.step.active .step-name{color:var(--gold)}.step.done .step-name{color:var(--mint)}.step-cmd{margin-top:3px;color:var(--muted);font:9px/1.4 var(--font-mono)}.track-note{margin-top:12px;padding-top:12px;border-top:1px dashed var(--line);color:var(--muted);font:11px/1.65 var(--font-mono)}\n .next-action{background:var(--bg-deep);border-color:var(--line-strong)}.next-head{display:flex;justify-content:space-between;gap:12px;align-items:center}.command{margin:8px 0 6px;color:var(--gold);font:700 clamp(22px,3vw,30px)/1.3 var(--font-mono)}.copy{padding:7px 12px;border:1px solid var(--cyan);border-radius:3px;background:transparent;color:var(--cyan);font:600 10px var(--font-mono);cursor:pointer}.copy:hover,.copy:focus-visible{background:var(--cyan);color:var(--bg-deep);outline:none}\n .stats{display:grid;grid-template-columns:repeat(5,1fr);gap:1px;margin:0 0 20px;border:1px solid var(--line);border-radius:4px;overflow:hidden;background:var(--line)}.stat{padding:16px 18px;background:var(--bg-deep)}.stat-value{font:700 25px/1 var(--font-display)}.stat-label{margin-top:6px;color:var(--muted);font:10px var(--font-mono);text-transform:uppercase;letter-spacing:.08em}\n .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:20px;margin-bottom:20px}.card{grid-column:span 4;min-width:0;padding:clamp(20px,2.4vw,28px)}.card.wide{grid-column:span 8}.card.full{grid-column:1/-1}.value{font:700 18px/1.4 var(--font-display)}\n .facts{display:grid;gap:10px}.fact{display:flex;justify-content:space-between;gap:16px;padding-bottom:10px;border-bottom:1px dashed var(--line)}.fact:last-child{padding-bottom:0;border:0}.fact span:first-child{color:var(--muted);font-size:11px}.fact span:last-child{color:var(--soft);font:11px var(--font-mono);text-align:right;overflow-wrap:anywhere}\n .progress{height:6px;margin:14px 0 9px;border-radius:99px;background:rgba(255,255,255,.07);overflow:hidden}.progress span{display:block;height:100%;width:0;background:var(--gold);transition:width .35s ease}\n ul{list-style:none;margin:0;padding:0}li{padding:10px 0;border-bottom:1px dashed var(--line);color:var(--soft);font-size:12px;line-height:1.55}li:last-child{border:0}.empty{color:var(--muted)}\n .severity{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}.sev{padding:9px 6px;border:1px solid var(--line);border-radius:3px;text-align:center}.sev b{display:block;font:700 17px var(--font-display)}.sev small{color:var(--muted);font:9px var(--font-mono)}\n .commands{display:flex;flex-wrap:wrap;gap:10px}.cmd{position:relative;padding:8px 13px;border:1px solid var(--line-strong);border-radius:3px;background:rgba(255,255,255,.025);color:var(--soft);font:11px var(--font-mono);cursor:pointer}.cmd:hover,.cmd:focus-visible,.cmd:focus{border-color:var(--cyan);color:var(--cyan);outline:2px solid rgba(125,216,255,.2);outline-offset:2px}.cmd:after{content:attr(data-tip);position:absolute;z-index:30;left:50%;bottom:calc(100% + 10px);width:max-content;max-width:min(300px,80vw);padding:9px 11px;border:1px solid var(--line-strong);border-radius:3px;background:#031421;color:var(--soft);font:10px/1.5 var(--font-mono);white-space:normal;text-align:left;opacity:0;visibility:hidden;transform:translate(-50%,5px);box-shadow:0 12px 30px rgba(0,0,0,.4);transition:.15s;pointer-events:none}.cmd:hover:after,.cmd:focus-visible:after,.cmd:focus:after{opacity:1;visibility:visible;transform:translate(-50%,0)}\n .adapters{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}.adapter{padding:15px;border:1px solid var(--line);border-radius:3px;background:rgba(255,255,255,.02)}.adapter strong{display:block;margin-bottom:6px;text-transform:capitalize}.adapter-path{color:var(--muted);font:10px var(--font-mono)}.adapter-state{margin-top:9px;font:10px var(--font-mono)}\n .idea-meta,.history-meta{margin-top:4px;color:var(--muted);font:10px var(--font-mono)}\n .section-note{margin:-2px 0 14px;color:var(--muted);font:10px/1.5 var(--font-mono)}.record-list{display:grid;gap:8px}.record-item{display:grid;grid-template-columns:38px minmax(0,1fr) auto;gap:13px;align-items:center;padding:13px 15px;border:1px solid var(--line);border-left:3px solid var(--record-color,var(--cyan));border-radius:3px;background:rgba(255,255,255,.02)}.record-icon{display:grid;place-items:center;width:31px;height:31px;border-radius:8px;background:color-mix(in srgb,var(--record-color,var(--cyan)) 14%,transparent)}.record-body{min-width:0}.record-meta{color:var(--record-color,var(--cyan));font:700 10px var(--font-mono);letter-spacing:.06em;text-transform:uppercase}.record-title{margin-top:3px;color:var(--ink);font-weight:650}.record-desc{margin-top:3px;color:var(--soft);font-size:12px}.record-desc:empty{display:none}.record-title strong,.record-desc strong{color:var(--record-color,var(--cyan));font-weight:750}.record-title em,.record-desc em{color:var(--gold)}.record-title code,.record-desc code{padding:1px 4px;border:1px solid var(--line);border-radius:3px;color:var(--cyan);font:10px var(--font-mono)}.record-title a,.record-desc a{color:var(--cyan);text-decoration:underline}.record-actions{display:flex;align-items:center;justify-content:flex-end;gap:7px;flex-wrap:wrap}.record-action{border:1px solid var(--record-color,var(--cyan));border-radius:3px;padding:8px 11px;background:transparent;color:var(--record-color,var(--cyan));font:700 10px var(--font-mono);cursor:pointer}.record-action:hover,.record-action:focus-visible{background:var(--record-color,var(--cyan));color:var(--bg)}.record-badge{align-self:start;border:1px solid rgba(111,227,180,.36);border-radius:99px;padding:4px 8px;background:var(--mint-soft);color:var(--mint);font:700 9px var(--font-mono);letter-spacing:.04em;text-transform:uppercase}.record-item.tone-cyan{--record-color:var(--cyan)}.record-item.tone-mint{--record-color:var(--mint)}.record-item.tone-gold{--record-color:var(--gold)}.record-item.tone-red{--record-color:var(--red)}.record-item.tone-violet{--record-color:var(--violet)}.stepper{gap:0;justify-content:center}.step{padding-right:0;overflow:visible}.step-line{left:calc(50% + 10px);right:calc(-50% + 10px);width:auto}#sev-p0{color:var(--red)}#sev-p1{color:var(--gold)}#sev-p2{color:var(--violet)}#sev-p3{color:var(--cyan)}#stat-runs.tone{color:var(--mint)}#stat-findings.tone-ok{color:var(--mint)}#stat-findings.tone-alert{color:var(--red)}#stat-ideas.tone-ok{color:var(--mint)}#stat-ideas.tone-pending{color:var(--gold)}#stat-adapters.tone-ok{color:var(--mint)}#stat-adapters.tone-partial{color:var(--gold)}#stat-state.tone-idle{color:var(--cyan)}#stat-state.tone-active{color:var(--violet)}#stat-state.tone-blocked{color:var(--red)}\n footer{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-top:26px;padding-top:17px;border-top:1px solid var(--line);color:var(--muted);font:10px var(--font-mono)}\n @media(max-width:920px){.grid .card,.grid .card.wide{grid-column:1/-1}.stats{grid-template-columns:repeat(2,1fr)}.adapters{grid-template-columns:repeat(2,1fr)}.titleblock{align-items:flex-start;flex-direction:column}.meta dd{text-align:left}.stepper{gap:0}.cmd:after{position:fixed;left:12px;right:12px;bottom:16px;width:auto;max-width:none;transform:translateY(5px)}.cmd:hover:after,.cmd:focus-visible:after,.cmd:focus:after{transform:none}}\n @media(max-width:560px){.sheet{width:calc(100% - 24px);padding-top:22px}.panel,.card{padding:18px}.grid{gap:14px;margin-bottom:14px}.stats{margin-bottom:14px}.adapters{grid-template-columns:1fr}.cmd:after{position:fixed;left:12px;right:12px;bottom:16px;width:auto;max-width:none;transform:translateY(5px)}.cmd:hover:after,.cmd:focus-visible:after,.cmd:focus:after{transform:none}.meta{grid-template-columns:1fr}.track-tabs{width:100%}.tab{flex:1}.fact{align-items:flex-start}.record-item{grid-template-columns:34px minmax(0,1fr)}.record-action{grid-column:2;justify-self:start}}\n @media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.001ms!important;transition-duration:.001ms!important}}\n </style>\n</head>\n<body>\n <main class=\"sheet\">\n <header class=\"titleblock\">\n <div><div class=\"eyebrow\">Nexus-DevFlow \u00B7 Workspace Status</div><h1 id=\"project-name\">Nexus-DevFlow</h1><div class=\"path\" id=\"project-path\">Connecting...</div><div class=\"badges\"><span class=\"badge\" id=\"version-badge\">version</span><span class=\"badge\" id=\"health-badge\">health</span><span class=\"badge\">MIT</span><span class=\"badge\" id=\"track-badge\">track</span></div></div>\n <dl class=\"meta\"><dt>Package</dt><dd id=\"package-name\">@jakkrichm/create-nexus-devflow</dd><dt>Adapters</dt><dd id=\"adapter-count\">-</dd><dt>Branch</dt><dd id=\"header-branch\">-</dd><dt>Snapshot</dt><dd id=\"generated-at\">-</dd></dl>\n </header>\n <div class=\"live\"><span class=\"live-dot\" id=\"live-dot\"></span><span id=\"live-label\">Connecting to local dashboard...</span></div>\n\n <section class=\"panel\" id=\"dual-track\">\n <div class=\"panel-head\"><span class=\"label\">Dual-Track Delivery Model</span><div class=\"track-tabs\" role=\"tablist\" aria-label=\"Delivery tracks\"><button class=\"tab on\" id=\"tab-fast\" role=\"tab\" aria-selected=\"true\" aria-controls=\"view-fast\" data-track=\"fast\"><span>\uD83D\uDE80 Fast-Track \u00B7 4 steps</span><span class=\"tab-active-dot\">\u25CF ACTIVE</span></button><button class=\"tab\" id=\"tab-deep\" role=\"tab\" aria-selected=\"false\" aria-controls=\"view-deep\" data-track=\"deep\"><span>\u265F\uFE0F Deep-Track \u00B7 8 stages</span><span class=\"tab-active-dot\">\u25CF ACTIVE</span></button></div></div>\n <div class=\"track-view on\" id=\"view-fast\" role=\"tabpanel\" aria-labelledby=\"tab-fast\"><div class=\"stepper\" id=\"pipeline-fast\"></div><div class=\"track-note\" id=\"note-fast\">Fast-Track for daily features, fixes, UI work and iterative refactoring.</div></div>\n <div class=\"track-view\" id=\"view-deep\" role=\"tabpanel\" aria-labelledby=\"tab-deep\"><div class=\"stepper\" id=\"pipeline-deep\"></div><div class=\"track-note\" id=\"note-deep\">Deep-Track for architecture, migrations, security audits and coordinated delivery.</div></div>\n </section>\n\n <section class=\"panel next-action\" id=\"next-panel\">\n <div class=\"next-head\"><span class=\"label\">Next Action</span><button class=\"copy\" id=\"next-copy\" type=\"button\">Copy command</button></div><div class=\"command\" id=\"next-command\" aria-live=\"polite\">Loading...</div><div class=\"muted\" id=\"next-reason\"></div>\n </section>\n\n <section class=\"stats\" aria-label=\"Workspace summary\"><div class=\"stat\"><div class=\"stat-value\" id=\"stat-runs\">-</div><div class=\"stat-label\">Runs released</div></div><div class=\"stat\"><div class=\"stat-value\" id=\"stat-findings\">-</div><div class=\"stat-label\">Active findings</div></div><div class=\"stat\"><div class=\"stat-value\" id=\"stat-ideas\">-</div><div class=\"stat-label\">Pending ideas</div></div><div class=\"stat\"><div class=\"stat-value\" id=\"stat-adapters\">-</div><div class=\"stat-label\">Adapters configured</div></div><div class=\"stat\"><div class=\"stat-value\" id=\"stat-state\">-</div><div class=\"stat-label\">Current state</div></div></section>\n\n <section class=\"grid\">\n <article class=\"card\"><div class=\"card-head\"><span class=\"label\">Nexus-DevFlow</span><span class=\"pill\" id=\"update-pill\">checking</span></div><div class=\"facts\"><div class=\"fact\"><span>Installed / latest</span><span id=\"installed-latest\">-</span></div><div class=\"fact\"><span>Health</span><span id=\"system-health\">-</span></div><div class=\"fact\"><span>Architecture</span><span>3-Pillars + Dual-Track</span></div></div></article>\n <article class=\"card wide\"><div class=\"card-head\"><span class=\"label\">Current Work</span><span class=\"pill\" id=\"work-pill\">loading</span></div><div class=\"value\" id=\"work-title\">Loading...</div><div class=\"progress\"><span id=\"work-progress\"></span></div><div class=\"muted\" id=\"work-meta\"></div></article>\n <article class=\"card\"><div class=\"card-head\"><span class=\"label\">Git Status</span><span class=\"pill\" id=\"git-pill\">loading</span></div><div class=\"facts\"><div class=\"fact\"><span>Branch</span><span id=\"git-branch\">-</span></div><div class=\"fact\"><span>Working tree</span><span id=\"git-changed\">-</span></div><div class=\"fact\"><span>Upstream</span><span id=\"git-upstream\">-</span></div><div class=\"fact\"><span>Last commit</span><span id=\"git-commit\">-</span></div></div></article>\n <article class=\"card\"><div class=\"card-head\"><span class=\"label\">Findings Ledger</span><span class=\"value\" id=\"findings-count\">-</span></div><div class=\"severity\"><div class=\"sev\"><b id=\"sev-p0\">0</b><small>P0</small></div><div class=\"sev\"><b id=\"sev-p1\">0</b><small>P1</small></div><div class=\"sev\"><b id=\"sev-p2\">0</b><small>P2</small></div><div class=\"sev\"><b id=\"sev-p3\">0</b><small>P3</small></div></div><ul id=\"findings-list\"></ul></article>\n <article class=\"card\"><div class=\"card-head\"><span class=\"label\">Completion</span><span class=\"pill\" id=\"completion-pill\">-</span></div><ul id=\"completion-list\"></ul></article>\n <article class=\"card\"><div class=\"card-head\"><span class=\"label\">Warnings</span><span class=\"value\" id=\"warnings-count\">-</span></div><ul id=\"warnings-list\"></ul></article>\n </section>\n\n <section class=\"grid\"><article class=\"card full\"><div class=\"card-head\"><span class=\"label\">Doctor \u00B7 Health Check</span><span class=\"pill\" id=\"doctor-pill\">-</span></div><div class=\"record-list\" id=\"doctor-list\"></div></article></section>\n <section class=\"card full panel\"><div class=\"card-head\"><span class=\"label\">Discoveries</span><span class=\"value\" id=\"discovery-count\">-</span></div><div class=\"record-list\" id=\"discovery-list\"></div></section>\n <section class=\"card full panel\"><div class=\"card-head\"><span class=\"label\">Quick Commands</span><span class=\"muted\">hover or focus for help \u00B7 click to copy</span></div><div class=\"commands\" id=\"command-list\"></div></section>\n <section class=\"card full panel\"><div class=\"card-head\"><span class=\"label\">Adapter Health</span><span class=\"muted\">configured \u00B7 detected \u00B7 healthy</span></div><div class=\"adapters\" id=\"adapter-list\"></div></section>\n <section class=\"card full panel\"><div class=\"card-head\"><span class=\"label\">Idea Inbox & Backlog</span><span class=\"value\" id=\"ideas-count\">-</span></div><div class=\"section-note\">From devflow/ideas.md \u00B7 start a selected item with /feature IDEA-xxx</div><div class=\"record-list\" id=\"ideas-list\"></div></section>\n <section class=\"card full panel\"><div class=\"card-head\"><span class=\"label\">Completed Work Archive</span><span class=\"value\" id=\"history-count\">-</span></div><div class=\"section-note\">Categorized delivery history \u00B7 features, fixes and rollbacks</div><div class=\"record-list\" id=\"history-list\"></div></section>\n <footer><span>Read-only local DevFlow 2.0 dashboard \u00B7 refreshes every 2 seconds</span><span id=\"footer-revision\">snapshot pending</span></footer>\n </main>\n <script>\n const byId = (id) => document.getElementById(id);\n const text = (id, value) => { const node = byId(id); if (node) node.textContent = value == null ? '-' : String(value); };\n const pill = (id, state, label) => { const node = byId(id); if (!node) return; node.className = 'pill ' + (state || 'configured'); node.textContent = label || state || '-'; };\n const list = (id, values, empty) => { const node = byId(id); if (!node) return; node.replaceChildren(); const rows = values.length ? values : [empty]; rows.forEach((value) => { const li = document.createElement('li'); li.textContent = value; if (!values.length) li.className = 'empty'; node.append(li); }); };\n const titleCase = (value) => String(value || '').replaceAll('_',' ').replace(/\bw/g, (c) => c.toUpperCase());\n const ICON_PATHS = { compass:'M12 2l3 7 7 3-7 3-3 7-3-7-7-3 7-3 3-7z', target:'M12 3a9 9 0 1 0 9 9M12 7a5 5 0 1 0 5 5M12 10a2 2 0 1 0 2 2', document:'M6 2h8l4 4v16H6zM14 2v5h5M9 12h6M9 16h6', list:'M8 6h12M8 12h12M8 18h12M3 6h1M3 12h1M3 18h1', code:'M8 8l-4 4 4 4M16 8l4 4-4 4M14 4l-4 16', shield:'M12 2l8 3v6c0 5-3 9-8 11-5-2-8-6-8-11V5zM8 12l3 3 5-6', report:'M5 3h14v18H5zM8 8h8M8 12h8M8 16h5', package:'M3 7l9-5 9 5v10l-9 5-9-5zM3 7l9 5 9-5M12 12v10', bulb:'M9 18h6M10 22h4M8 14c-2-1-3-3-3-5a7 7 0 0 1 14 0c0 2-1 4-3 5-1 1-1 2-1 3H9c0-1 0-2-1-3z', check:'M5 12l4 4L19 6', wrench:'M14 6a4 4 0 0 0-5 5L3 17l4 4 6-6a4 4 0 0 0 5-5l-3 1-2-2 1-3z', rollback:'M9 7H4v-5M4 7a9 9 0 1 1-1 7', search:'M11 4a7 7 0 1 0 0 14 7 7 0 0 0 0-14M16 16l5 5', alert:'M12 3l10 18H2zM12 9v5M12 18h.01' };\n const FLOW_ICON_NAMES = ['compass','target','document','list','code','shield','report','package'];\n const EMOJI_ICONS = { compass:'\uD83D\uDD0E',target:'\uD83C\uDFAF',document:'\uD83D\uDCC4',list:'\uD83E\uDDE9',code:'\u2699\uFE0F',shield:'\uD83D\uDEE1\uFE0F',report:'\uD83D\uDCCA',package:'\uD83D\uDCE6',bulb:'\u26A1',check:'\u2705',wrench:'\uD83D\uDEE0\uFE0F',rollback:'\u21A9\uFE0F',search:'\uD83D\uDD0D',alert:'\u26A0\uFE0F' };\n function iconImage(name) { const icon = document.createElement('span'); icon.className = 'icon-glyph'; icon.setAttribute('aria-hidden','true'); icon.textContent = EMOJI_ICONS[name] || '\uD83D\uDCC4'; return icon; }\n function decoratePipeline(id) { byId(id)?.querySelectorAll('.step').forEach((step,index) => { step.classList.add('flow-' + index); const icon = document.createElement('span'); icon.className = 'step-icon'; icon.setAttribute('aria-hidden','true'); icon.append(iconImage(FLOW_ICON_NAMES[index] || 'document')); const name = step.querySelector('.step-name'); step.insertBefore(icon,name || null); }); }\n function richText(root,value) { const source = String(value || ''); let cursor = 0; const plain = (end) => { if (end > cursor) root.append(document.createTextNode(source.slice(cursor,end))); cursor = end; }; while (cursor < source.length) { if (source.startsWith('**',cursor)) { const end = source.indexOf('**',cursor + 2); if (end > cursor + 2) { const node = document.createElement('strong'); node.textContent = source.slice(cursor + 2,end); root.append(node); cursor = end + 2; continue; } } if (source[cursor] === '*') { const end = source.indexOf('*',cursor + 1); if (end > cursor + 1) { const node = document.createElement('em'); node.textContent = source.slice(cursor + 1,end); root.append(node); cursor = end + 1; continue; } } if (source.charCodeAt(cursor) === 96) { const end = source.indexOf(String.fromCharCode(96),cursor + 1); if (end > cursor + 1) { const node = document.createElement('code'); node.textContent = source.slice(cursor + 1,end); root.append(node); cursor = end + 1; continue; } } if (source[cursor] === '[') { const close = source.indexOf('](',cursor + 1); const end = close >= 0 ? source.indexOf(')',close + 2) : -1; const href = close >= 0 && end > close ? source.slice(close + 2,end) : ''; if (close > cursor + 1 && end > close && (href.startsWith('https://') || href.startsWith('http://'))) { const node = document.createElement('a'); node.textContent = source.slice(cursor + 1,close); node.href = href; node.target = '_blank'; node.rel = 'noreferrer'; root.append(node); cursor = end + 1; continue; } } const next = [source.indexOf('**',cursor + 1),source.indexOf('*',cursor + 1),source.indexOf(String.fromCharCode(96),cursor + 1),source.indexOf('[',cursor + 1)].filter((index) => index >= 0).sort((a,b) => a-b)[0] ?? source.length; plain(next > cursor ? next : cursor + 1); } }\n function recordCard(options) { const card = document.createElement('article'); card.className = 'record-item tone-' + (options.tone || 'cyan'); const icon = document.createElement('span'); icon.className = 'record-icon'; icon.append(iconImage(options.icon || 'document')); const body = document.createElement('div'); body.className = 'record-body'; const meta = document.createElement('div'); meta.className = 'record-meta'; richText(meta,options.meta); const title = document.createElement('div'); title.className = 'record-title'; richText(title,options.title); const desc = document.createElement('div'); desc.className = 'record-desc'; richText(desc,options.description); body.append(meta,title,desc); card.append(icon,body); if (options.badge) { const badge = document.createElement('span'); badge.className = 'record-badge'; badge.textContent = options.badge; card.append(badge); } else if (options.actions?.length) { const actions = document.createElement('div'); actions.className = 'record-actions'; options.actions.forEach((command) => { const action = document.createElement('button'); action.className = 'record-action'; action.type = 'button'; action.textContent = command; action.addEventListener('click',() => { navigator.clipboard?.writeText(command); action.textContent = 'Copied'; setTimeout(() => { action.textContent = command; },1200); }); actions.append(action); }); card.append(actions); } return card; }\n function renderRecords(id,items,empty,mapper) { const root = byId(id); root.replaceChildren(); if (!items?.length) { const node = document.createElement('div'); node.className = 'empty'; node.textContent = empty; root.append(node); return; } items.forEach((item,index) => root.append(recordCard(mapper(item,index)))); }\n function ideaTone(feasibility) { const value = String(feasibility || '').toLowerCase(); if (value.includes('high') || value.includes('easy') || value.includes('\u0E07\u0E48\u0E32\u0E22')) return 'mint'; if (value.includes('low') || value.includes('hard') || value.includes('\u0E22\u0E32\u0E01')) return 'red'; if (value.includes('medium') || value.includes('\u0E1B\u0E32\u0E19\u0E01\u0E25\u0E32\u0E07')) return 'gold'; return 'violet'; }\n function renderIdeas(items) { renderRecords('ideas-list',items,'No pending ideas',(item) => ({ icon:'bulb',tone:ideaTone(item.feasibility),meta:item.id,title:item.title,description:(item.description || '\u26A1') + ' \u00B7 ' + (item.feasibility || '**Not scored**'),actions:['/feature ' + item.id,'/discovery ' + item.id] })); }\n function renderHistory(items) { const map = { feature:{icon:'package',tone:'cyan'},fix:{icon:'wrench',tone:'gold'},rollback:{icon:'rollback',tone:'red'} }; renderRecords('history-list',(items || []).slice(0,10),'No completed work in history archive',(item) => { const type = String(item.type || 'other').toLowerCase(); const style = map[type] || {icon:'report',tone:'violet'}; return { ...style,meta:type + ' ' + (item.buildPlanItem || ''),title:item.title,description:'',badge:'Released' }; }); }\n function renderDoctor(items) { renderRecords('doctor-list',items,'No doctor checks available',(item) => ({ icon:item.status === 'pass' ? 'check' : 'alert',tone:item.status === 'pass' ? 'mint' : item.status === 'warn' ? 'gold' : 'red',meta:item.status,title:item.name,description:item.message })); }\n function renderDiscoveries(items) { renderRecords('discovery-list',items,'No discoveries recorded',(item) => { const decision = item.decision || 'Pending'; const normalized = String(decision).toLowerCase(); return { icon:'search',tone:normalized === 'proceed' || normalized === 'approved' ? 'mint' : 'violet',meta:item.id,title:item.title,description:'',badge:'Decision: ' + decision }; }); }\n let nextCopyValue = '/feature';\n let nextCopyLabel = '/feature';\n byId('next-copy').addEventListener('click',(event) => { event.stopImmediatePropagation(); navigator.clipboard?.writeText(nextCopyValue); const button = byId('next-copy'); button.textContent = 'Copied ' + nextCopyLabel; setTimeout(() => { button.textContent = 'Copy command ' + nextCopyLabel; },1200); },true);\n let preferredTrack = (() => { try { return localStorage.getItem('devflow-dashboard-track'); } catch { return null; } })();\n document.querySelectorAll('[data-track]').forEach((button) => button.addEventListener('click',() => { preferredTrack = button.dataset.track; try { localStorage.setItem('devflow-dashboard-track',preferredTrack); } catch {} },{capture:true}));\n\n function renderPipeline(id, nodes) {\n const root = byId(id); root.replaceChildren();\n (nodes || []).forEach((node, index) => {\n const step = document.createElement('div'); step.className = 'step ' + node.state;\n const line = document.createElement('span'); line.className = 'step-line';\n const dot = document.createElement('span'); dot.className = 'step-dot'; dot.textContent = node.state === 'done' ? '\u2713' : String(index + 1).padStart(nodes.length > 4 ? 2 : 1, '0');\n const name = document.createElement('div'); name.className = 'step-name'; name.textContent = node.label;\n const command = document.createElement('div'); command.className = 'step-cmd'; command.textContent = node.command;\n step.append(line, dot, name, command); root.append(step);\n });\n }\n\n function selectTrack(track) {\n document.querySelectorAll('.tab').forEach((node) => { const on = node.dataset.track === track; node.classList.toggle('on', on); node.setAttribute('aria-selected', String(on)); });\n document.querySelectorAll('.track-view').forEach((node) => node.classList.toggle('on', node.id === 'view-' + track));\n }\n\n function wireCopy(button, getValue) {\n button.addEventListener('click', async () => {\n const original = button.textContent;\n button.textContent = 'Copied!';\n try { await navigator.clipboard.writeText(getValue()); }\n catch { button.textContent = 'Copy unavailable'; }\n setTimeout(() => { button.textContent = original; }, 1100);\n });\n }\n\n document.querySelectorAll('.tab').forEach((node) => node.addEventListener('click', () => selectTrack(node.dataset.track)));\n wireCopy(byId('next-copy'), () => byId('next-command').textContent.trim());\n\n function renderCommands(commands) {\n const root = byId('command-list'); root.replaceChildren();\n (commands || []).filter((item) => item.family === 'companion').forEach((item) => {\n const button = document.createElement('button'); button.type = 'button'; button.className = 'cmd'; button.textContent = item.name; button.dataset.tip = item.description; button.setAttribute('aria-label', item.name + ': ' + item.description); wireCopy(button, () => item.command); root.append(button);\n });\n }\n\n function renderAdapters(adapters) {\n const root = byId('adapter-list'); root.replaceChildren();\n (adapters || []).forEach((item) => { const card = document.createElement('div'); card.className = 'adapter'; const name = document.createElement('strong'); name.textContent = item.name; const path = document.createElement('div'); path.className = 'adapter-path'; path.textContent = item.path; const state = document.createElement('div'); state.className = 'adapter-state ' + item.state; state.textContent = item.state + ' \u00B7 ' + item.message; card.append(name,path,state); root.append(card); });\n }\n\n function renderSnapshot(data) {\n const status = data.status || {}; const project = status.project || {}; const devflow = status.devflow || {}; const work = status.currentWork || {}; const git = status.git || {}; const findings = status.findings || { active: [], blockers: [] }; const workflow = data.workflow || {}; const update = data.update || {}; const doctor = data.doctor || { checks: [] }; const discoveries = data.discoveries || { recent: [] }; const history = data.history || { items: [], total: 0 }; const ideas = status.ideas || { pending: [], totalPending: 0 };\n text('project-name', project.name || 'Nexus-DevFlow'); text('project-path', project.root || ''); text('version-badge', 'v' + (devflow.version || 'unknown')); pill('health-badge', status.health, status.health === 'ok' ? 'Health OK' : 'Health warning'); pill('track-badge', workflow.track, 'Track ' + titleCase(workflow.track || 'idle'));\n text('adapter-count', (devflow.adapters || []).length + ' configured'); text('header-branch', git.branch || 'unknown'); text('generated-at', new Date(data.generatedAt).toLocaleTimeString()); text('footer-revision', 'snapshot ' + data.generatedAt);\n const currentTrack = workflow.track || 'idle';\n const isDeepActive = currentTrack === 'deep';\n const isFastActive = currentTrack === 'fast';\n const tabFast = byId('tab-fast');\n const tabDeep = byId('tab-deep');\n if (tabFast) tabFast.classList.toggle('is-active-track', isFastActive);\n if (tabDeep) tabDeep.classList.toggle('is-active-track', isDeepActive);\n renderPipeline('pipeline-fast', workflow.fast); renderPipeline('pipeline-deep', workflow.deep); decoratePipeline('pipeline-fast'); decoratePipeline('pipeline-deep');\n const effectiveTrack = isDeepActive ? 'deep' : isFastActive ? 'fast' : (preferredTrack || 'fast');\n selectTrack(effectiveTrack);\n text('note-fast', workflow.track === 'fast' ? 'Active Fast-Track run: ' + (work.runId || work.title || 'current work') : 'Fast-Track is ready for daily features, fixes, UI work and iterative refactoring.');\n text('note-deep', workflow.track === 'deep' ? 'Active Deep-Track run: ' + (workflow.activeRunId || workflow.activeDiscoveryId || 'current run') + ' \u00B7 stage ' + (workflow.currentStage || 'unknown') : 'Deep-Track is ready for architecture, migrations, security audits and coordinated delivery.');\n const nextCommand = data.nextAction?.command || status.nextAction?.command || '/feature'; const workTitle = String(work.title || ''); const bracketStart = workTitle.indexOf('['); const bracketEnd = bracketStart >= 0 ? workTitle.indexOf(']',bracketStart + 1) : -1; const titleRunId = bracketStart >= 0 && bracketEnd > bracketStart ? workTitle.slice(bracketStart + 1,bracketEnd).trim() : ''; const nextRunId = work.runId || work.id || workflow.activeRunId || workflow.activeDiscoveryId || titleRunId; nextCopyValue = nextRunId ? nextCommand + ' ' + nextRunId : nextCommand; nextCopyLabel = nextCommand; text('next-command', nextCommand); text('next-copy', 'Copy command ' + nextCopyLabel); byId('next-copy').title = 'Copy ' + nextCopyValue; text('next-reason', data.nextAction?.reason || status.nextAction?.reason || 'Ready for new work.');\n text('stat-runs', history.total || 0); const activeFindings = (findings.active || []).length; text('stat-findings', activeFindings); text('stat-ideas', ideas.totalPending || 0); const healthyAdapters = (data.adapters || []).filter((item) => item.state === 'configured' || item.state === 'detected' || item.state === 'healthy').length; text('stat-adapters', healthyAdapters + '/' + (devflow.adapters || []).length); text('stat-state', titleCase(work.state || 'idle')); byId('stat-runs').className = 'stat-value tone'; byId('stat-findings').className = 'stat-value ' + (activeFindings ? 'tone-alert' : 'tone-ok'); byId('stat-ideas').className = 'stat-value ' + (ideas.totalPending ? 'tone-pending' : 'tone-ok'); byId('stat-adapters').className = 'stat-value ' + (healthyAdapters === (devflow.adapters || []).length ? 'tone-ok' : 'tone-partial'); byId('stat-state').className = 'stat-value tone-' + (work.state === 'blocked' ? 'blocked' : work.state === 'active' ? 'active' : 'idle');\n pill('update-pill', update.state, update.state === 'current' ? 'up to date' : update.state); text('installed-latest', (update.installedVersion || 'unknown') + ' / ' + (update.latestVersion || update.state)); text('system-health', status.health || 'unknown');\n pill('work-pill', work.state, work.state || 'idle'); text('work-title', work.title || 'No active delivery run'); const pct = work.total > 0 ? Math.round((work.completed / work.total) * 100) : 0; byId('work-progress').style.width = pct + '%'; text('work-meta', work.state === 'active' ? work.completed + ' of ' + work.total + ' steps completed' : 'Last completed: ' + (workflow.lastCompletedRun || 'none recorded'));\n pill('git-pill', git.clean ? 'ok' : 'warning', git.clean ? 'clean' : (git.changedFiles || 0) + ' changed'); text('git-branch', git.branch || 'unknown'); text('git-changed', git.clean ? 'clean' : (git.changedFiles || 0) + ' changed files'); text('git-upstream', git.upstream ? git.upstream + ' \u00B7 ' + (git.ahead || 0) + ' ahead / ' + (git.behind || 0) + ' behind' : 'none'); text('git-commit', git.lastCommit || '-');\n text('findings-count', findings.total || 0); ['P0','P1','P2','P3'].forEach((severity) => text('sev-' + severity.toLowerCase(), (findings.active || []).filter((item) => item.severity === severity).length)); list('findings-list', (findings.active || []).map((item) => item.id + ' \u00B7 ' + item.title), 'No active findings');\n pill('completion-pill', status.completion?.state, status.completion?.state || 'unknown'); list('completion-list', status.completion?.blockers || [], work.state === 'idle' ? 'No active run to complete' : 'All readiness checks passed'); text('warnings-count', (status.warnings || []).length); list('warnings-list', (status.warnings || []).map((item) => item.message), 'No active warnings or drift');\n pill('doctor-pill', doctor.failCount ? 'fail' : doctor.warnCount ? 'warning' : 'ok', doctor.passCount + '/' + doctor.totalChecks + ' pass'); renderDoctor(doctor.checks || []);\n text('discovery-count', discoveries.total || 0); renderDiscoveries(discoveries.recent || []); renderCommands(data.commands); renderAdapters(data.adapters);\n text('ideas-count', (ideas.totalPending || 0) + ' pending'); renderIdeas(ideas.pending || []); text('history-count', (history.total || 0) + ' released'); renderHistory(history.items || []);\n }\n\n let refreshing = false;\n async function refresh() { if (refreshing) return; refreshing = true; try { const response = await fetch('/api/dashboard'); if (!response.ok) throw new Error('HTTP ' + response.status); renderSnapshot(await response.json()); byId('live-dot').classList.add('on'); text('live-label','Connected \u00B7 live snapshot every 2 seconds'); } catch (error) { byId('live-dot').classList.remove('on'); text('live-label','Disconnected \u00B7 ' + error.message); } finally { refreshing = false; } }\n refresh(); setInterval(refresh, 2000);\n </script>\n</body>\n</html>";
|
|
1
|
+
declare const DASHBOARD_PAGE_HTML = "<!doctype html>\n<html lang=\"th\">\n<head>\n <meta charset=\"utf-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n <title>Nexus-DevFlow Enterprise Dashboard</title>\n <link rel=\"preconnect\" href=\"https://fonts.googleapis.com\">\n <link rel=\"preconnect\" href=\"https://fonts.gstatic.com\" crossorigin>\n <link href=\"https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500;600;700&family=Noto+Sans+Thai:wght@400;500;600;700&family=Space+Grotesk:wght@500;600;700&display=swap\" rel=\"stylesheet\">\n <style>\n :root{\n --font-display:\"Google Sans Thai\",\"Google Sans\",\"Noto Sans Thai\",\"Space Grotesk\",sans-serif;\n --font-sans:\"Google Sans Thai\",\"Google Sans\",\"Noto Sans Thai\",sans-serif;\n --font-mono:\"IBM Plex Mono\",monospace;\n --bg:#0a2540;--bg-deep:#061a2e;--panel:rgba(255,255,255,.04);--panel-strong:#0c2b49;\n --ink:#edf6ff;--soft:#b7d3ef;--muted:#7598ba;--line:rgba(191,224,255,.17);--line-strong:rgba(191,224,255,.36);\n --cyan:#7dd8ff;--mint:#6fe3b4;--gold:#f2c14e;--red:#ff7061;--violet:#b8a4ff;\n --mint-soft:rgba(111,227,180,.14);--gold-soft:rgba(242,193,78,.14);--red-soft:rgba(255,112,97,.14);--violet-soft:rgba(184,164,255,.14);\n }\n *{box-sizing:border-box}\n html{color-scheme:dark}\n body{margin:0;min-height:100vh;background-color:var(--bg);color:var(--ink);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;background-image:linear-gradient(rgba(125,216,255,.065) 1px,transparent 1px),linear-gradient(90deg,rgba(125,216,255,.065) 1px,transparent 1px),radial-gradient(circle at 8% -5%,rgba(125,216,255,.16),transparent 42rem);background-size:34px 34px,34px 34px,auto}\n button,input{font:inherit}\n code{font-family:var(--font-mono);color:var(--cyan)}\n .sheet{width:min(1180px,calc(100% - 40px));margin:0 auto;padding:34px 0 64px}\n .titleblock{display:flex;align-items:flex-end;justify-content:space-between;gap:26px;padding-bottom:20px;border-bottom:1px solid var(--line-strong);flex-wrap:wrap}\n .eyebrow,.label{font:600 10px/1 var(--font-mono);letter-spacing:.13em;text-transform:uppercase;color:var(--cyan)}\n .eyebrow{display:flex;align-items:center;gap:8px;margin-bottom:12px}.eyebrow:before{content:\"\";width:20px;height:1px;background:var(--cyan)}\n h1{margin:0 0 6px;font:700 clamp(32px,4vw,48px)/1.05 var(--font-display);letter-spacing:-.03em}\n .path,.muted{color:var(--muted);font-size:12px;line-height:1.65}.path{font-family:var(--font-mono)}\n .badges{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}.badge,.pill{padding:4px 9px;border:1px solid var(--line-strong);border-radius:3px;background:rgba(255,255,255,.025);color:var(--muted);font:600 10px/1.5 var(--font-mono);text-transform:uppercase}\n .ok,.healthy,.current,.ready,.idle{border-color:rgba(111,227,180,.42)!important;color:var(--mint)!important;background:var(--mint-soft)!important}\n .warning,.available,.offline,.blocked,.fail{border-color:rgba(255,112,97,.42)!important;color:var(--red)!important;background:var(--red-soft)!important}\n .active,.deep,.fast,.configured{border-color:rgba(184,164,255,.42)!important;color:var(--violet)!important;background:var(--violet-soft)!important}\n .meta{display:grid;grid-template-columns:auto auto;gap:4px 20px;margin:0;font:11px/1.55 var(--font-mono)}.meta dt{color:var(--muted);text-transform:uppercase}.meta dd{margin:0;color:var(--soft);text-align:right}\n .live{display:flex;align-items:center;gap:8px;margin:14px 0 24px;font:11px var(--font-mono);color:var(--muted)}.live-dot{width:7px;height:7px;border-radius:50%;background:var(--gold)}.live-dot.on{background:var(--mint);box-shadow:0 0 0 4px rgba(111,227,180,.12)}\n .panel,.card{position:relative;min-width:0;border:1px solid var(--line);border-radius:4px;background:var(--panel)}\n #dual-track{overflow:hidden}\n .stepper{justify-content:center}.step{display:flex;flex-direction:column;align-items:center;text-align:center}.step-icon{display:grid;place-items:center;width:30px;height:30px;margin:10px auto 8px;border:1px solid currentColor;border-radius:8px;background:rgba(255,255,255,.035)}.icon-glyph{display:block;font-size:17px;line-height:1}.step.flow-0,.step.flow-4{color:var(--cyan)}.step.flow-1,.step.flow-5{color:var(--violet)}.step.flow-2,.step.flow-6{color:var(--gold)}.step.flow-3,.step.flow-7{color:var(--mint)}.step .step-name{color:currentColor}.step .step-cmd{color:var(--muted)}\n .panel{padding:24px 26px;margin-bottom:20px}.panel-head,.card-head{display:flex;align-items:center;justify-content:space-between;gap:14px;flex-wrap:wrap}.panel-head{margin-bottom:20px}.card-head{margin-bottom:17px}\n .track-tabs{display:flex;gap:7px;flex-wrap:wrap}.tab{display:inline-flex;align-items:center;gap:7px;padding:7px 13px;border:1px solid var(--line-strong);border-radius:99px;background:transparent;color:var(--muted);font:600 10px var(--font-mono);cursor:pointer}.tab:hover,.tab:focus-visible{border-color:var(--cyan);color:var(--cyan);outline:none}.tab.on{background:var(--cyan);border-color:var(--cyan);color:var(--bg-deep)}.tab-active-dot{display:none;padding:2px 6px;border-radius:99px;font:700 8px/1 var(--font-mono);letter-spacing:.05em;text-transform:uppercase;background:var(--mint);color:var(--bg-deep)}.tab.is-active-track .tab-active-dot{display:inline-flex;align-items:center;gap:3px;box-shadow:0 0 0 2px rgba(111,227,180,.25)}.tab.on.is-active-track .tab-active-dot{background:var(--bg-deep);color:var(--mint)}\n .track-view{display:none;min-width:0}.track-view.on{display:block}.stepper{display:flex;width:100%;max-width:100%;overflow-x:auto;padding:4px 0 7px}.step{flex:1 1 0;min-width:104px;position:relative;padding-right:12px}.step-line{position:absolute;top:10px;left:21px;right:0;height:1px;background:var(--line-strong)}.step:last-child .step-line{display:none}.step.done .step-line{background:var(--mint)}\n .step-dot{position:relative;z-index:1;width:21px;height:21px;border-radius:50%;display:grid;place-items:center;border:2px solid var(--line-strong);background:var(--bg-deep);color:var(--muted);font:700 8px var(--font-mono)}.step.done .step-dot{border-color:var(--mint);color:var(--mint)}.step.active .step-dot{border-color:var(--gold);color:var(--gold);box-shadow:0 0 0 4px rgba(242,193,78,.16)}\n .step-name{margin-top:9px;color:var(--soft);font:600 10px/1.35 var(--font-mono)}.step.active .step-name{color:var(--gold)}.step.done .step-name{color:var(--mint)}.step-cmd{margin-top:3px;color:var(--muted);font:9px/1.4 var(--font-mono)}.track-note{margin-top:12px;padding-top:12px;border-top:1px dashed var(--line);color:var(--muted);font:11px/1.65 var(--font-mono)}\n .next-action{background:var(--bg-deep);border-color:var(--line-strong)}.next-head{display:flex;justify-content:space-between;gap:12px;align-items:center}.command{margin:8px 0 6px;color:var(--gold);font:700 clamp(22px,3vw,30px)/1.3 var(--font-mono)}.copy{padding:7px 12px;border:1px solid var(--cyan);border-radius:3px;background:transparent;color:var(--cyan);font:600 10px var(--font-mono);cursor:pointer}.copy:hover,.copy:focus-visible{background:var(--cyan);color:var(--bg-deep);outline:none}\n .stats{display:grid;grid-template-columns:repeat(5,1fr);gap:1px;margin:0 0 20px;border:1px solid var(--line);border-radius:4px;overflow:hidden;background:var(--line)}.stat{padding:16px 18px;background:var(--bg-deep)}.stat-value{font:700 25px/1 var(--font-display)}.stat-label{margin-top:6px;color:var(--muted);font:10px var(--font-mono);text-transform:uppercase;letter-spacing:.08em}\n .grid{display:grid;grid-template-columns:repeat(12,1fr);gap:20px;margin-bottom:20px}.card{grid-column:span 4;min-width:0;padding:clamp(20px,2.4vw,28px)}.card.wide{grid-column:span 8}.card.full{grid-column:1/-1}.value{font:700 18px/1.4 var(--font-display)}\n .facts{display:grid;gap:10px}.fact{display:flex;justify-content:space-between;gap:16px;padding-bottom:10px;border-bottom:1px dashed var(--line)}.fact:last-child{padding-bottom:0;border:0}.fact span:first-child{color:var(--muted);font-size:11px}.fact span:last-child{color:var(--soft);font:11px var(--font-mono);text-align:right;overflow-wrap:anywhere}\n .progress{height:6px;margin:14px 0 9px;border-radius:99px;background:rgba(255,255,255,.07);overflow:hidden}.progress span{display:block;height:100%;width:0;background:var(--gold);transition:width .35s ease}\n ul{list-style:none;margin:0;padding:0}li{padding:10px 0;border-bottom:1px dashed var(--line);color:var(--soft);font-size:12px;line-height:1.55}li:last-child{border:0}.empty{color:var(--muted)}\n .severity{display:grid;grid-template-columns:repeat(4,1fr);gap:8px}.sev{padding:9px 6px;border:1px solid var(--line);border-radius:3px;text-align:center}.sev b{display:block;font:700 17px var(--font-display)}.sev small{color:var(--muted);font:9px var(--font-mono)}\n .commands{display:flex;flex-wrap:wrap;gap:10px}.cmd{position:relative;padding:8px 13px;border:1px solid var(--line-strong);border-radius:3px;background:rgba(255,255,255,.025);color:var(--soft);font:11px var(--font-mono);cursor:pointer}.cmd:hover,.cmd:focus-visible,.cmd:focus{border-color:var(--cyan);color:var(--cyan);outline:2px solid rgba(125,216,255,.2);outline-offset:2px}.cmd:after{content:attr(data-tip);position:absolute;z-index:30;left:50%;bottom:calc(100% + 10px);width:max-content;max-width:min(300px,80vw);padding:9px 11px;border:1px solid var(--line-strong);border-radius:3px;background:#031421;color:var(--soft);font:10px/1.5 var(--font-mono);white-space:normal;text-align:left;opacity:0;visibility:hidden;transform:translate(-50%,5px);box-shadow:0 12px 30px rgba(0,0,0,.4);transition:.15s;pointer-events:none}.cmd:hover:after,.cmd:focus-visible:after,.cmd:focus:after{opacity:1;visibility:visible;transform:translate(-50%,0)}\n .adapters,.roster-grid,.mcp-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:12px}.adapter,.roster-card,.mcp-card{padding:15px;border:1px solid var(--line);border-radius:4px;background:rgba(255,255,255,.02)}.adapter strong,.roster-card strong,.mcp-card strong{display:block;margin-bottom:6px;text-transform:capitalize}.adapter-path,.roster-desc,.mcp-desc{color:var(--muted);font:10px var(--font-mono);line-height:1.4}.adapter-state{margin-top:9px;font:10px var(--font-mono)}\n .mcp-grid{grid-template-columns:repeat(3,1fr)}\n .search-row{display:flex;gap:10px;margin-bottom:16px}.search-input{flex:1;padding:10px 14px;background:var(--bg-deep);border:1px solid var(--line-strong);border-radius:4px;color:var(--ink);font-family:var(--font-mono);font-size:12px}.search-btn{padding:10px 18px;border:1px solid var(--cyan);border-radius:4px;background:var(--cyan);color:var(--bg-deep);font-weight:700;cursor:pointer}\n .blast-result{padding:16px;border:1px solid var(--line-strong);border-radius:4px;background:var(--bg-deep);margin-top:12px;display:none}\n .section-note{margin:-2px 0 14px;color:var(--muted);font:10px/1.5 var(--font-mono)}.record-list{display:grid;gap:8px}.record-item{display:grid;grid-template-columns:38px minmax(0,1fr) auto;gap:13px;align-items:center;padding:13px 15px;border:1px solid var(--line);border-left:3px solid var(--record-color,var(--cyan));border-radius:3px;background:rgba(255,255,255,.02)}.record-icon{display:grid;place-items:center;width:31px;height:31px;border-radius:8px;background:color-mix(in srgb,var(--record-color,var(--cyan)) 14%,transparent)}.record-body{min-width:0}.record-meta{color:var(--record-color,var(--cyan));font:700 10px var(--font-mono);letter-spacing:.06em;text-transform:uppercase}.record-title{margin-top:3px;color:var(--ink);font-weight:650}.record-desc{margin-top:3px;color:var(--soft);font-size:12px}.record-desc:empty{display:none}.record-title strong,.record-desc strong{color:var(--record-color,var(--cyan));font-weight:750}.record-title em,.record-desc em{color:var(--gold)}.record-title code,.record-desc code{padding:1px 4px;border:1px solid var(--line);border-radius:3px;color:var(--cyan);font:10px var(--font-mono)}.record-title a,.record-desc a{color:var(--cyan);text-decoration:underline}.record-actions{display:flex;align-items:center;justify-content:flex-end;gap:7px;flex-wrap:wrap}.record-action{border:1px solid var(--record-color,var(--cyan));border-radius:3px;padding:8px 11px;background:transparent;color:var(--record-color,var(--cyan));font:700 10px var(--font-mono);cursor:pointer}.record-action:hover,.record-action:focus-visible{background:var(--record-color,var(--cyan));color:var(--bg)}.record-badge{align-self:start;border:1px solid rgba(111,227,180,.36);border-radius:99px;padding:4px 8px;background:var(--mint-soft);color:var(--mint);font:700 9px var(--font-mono);letter-spacing:.04em;text-transform:uppercase}.record-item.tone-cyan{--record-color:var(--cyan)}.record-item.tone-mint{--record-color:var(--mint)}.record-item.tone-gold{--record-color:var(--gold)}.record-item.tone-red{--record-color:var(--red)}.record-item.tone-violet{--record-color:var(--violet)}.stepper{gap:0;justify-content:center}.step{padding-right:0;overflow:visible}.step-line{left:calc(50% + 10px);right:calc(-50% + 10px);width:auto}#sev-p0{color:var(--red)}#sev-p1{color:var(--gold)}#sev-p2{color:var(--violet)}#sev-p3{color:var(--cyan)}#stat-runs.tone{color:var(--mint)}#stat-findings.tone-ok{color:var(--mint)}#stat-findings.tone-alert{color:var(--red)}#stat-ideas.tone-ok{color:var(--mint)}#stat-ideas.tone-pending{color:var(--gold)}#stat-adapters.tone-ok{color:var(--mint)}#stat-adapters.tone-partial{color:var(--gold)}#stat-state.tone-idle{color:var(--cyan)}#stat-state.tone-active{color:var(--violet)}#stat-state.tone-blocked{color:var(--red)}\n footer{display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;margin-top:26px;padding-top:17px;border-top:1px solid var(--line);color:var(--muted);font:10px var(--font-mono)}\n @media(max-width:920px){.grid .card,.grid .card.wide{grid-column:1/-1}.stats{grid-template-columns:repeat(2,1fr)}.adapters,.roster-grid,.mcp-grid{grid-template-columns:repeat(2,1fr)}.titleblock{align-items:flex-start;flex-direction:column}.meta dd{text-align:left}.stepper{gap:0}.cmd:after{position:fixed;left:12px;right:12px;bottom:16px;width:auto;max-width:none;transform:translateY(5px)}.cmd:hover:after,.cmd:focus-visible:after,.cmd:focus:after{transform:none}}\n @media(max-width:560px){.sheet{width:calc(100% - 24px);padding-top:22px}.panel,.card{padding:18px}.grid{gap:14px;margin-bottom:14px}.stats{margin-bottom:14px}.adapters,.roster-grid,.mcp-grid{grid-template-columns:1fr}.cmd:after{position:fixed;left:12px;right:12px;bottom:16px;width:auto;max-width:none;transform:translateY(5px)}.cmd:hover:after,.cmd:focus-visible:after,.cmd:focus:after{transform:none}.meta{grid-template-columns:1fr}.track-tabs{width:100%}.tab{flex:1}.fact{align-items:flex-start}.record-item{grid-template-columns:34px minmax(0,1fr)}.record-action{grid-column:2;justify-self:start}}\n @media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.001ms!important;transition-duration:.001ms!important}}\n </style>\n</head>\n<body>\n <main class=\"sheet\">\n <header class=\"titleblock\">\n <div>\n <div class=\"eyebrow\">Nexus-DevFlow \u00B7 Enterprise Workspace Status</div>\n <h1 id=\"project-name\">Nexus-DevFlow</h1>\n <div class=\"path\" id=\"project-path\">Connecting...</div>\n <div class=\"badges\">\n <span class=\"badge\" id=\"version-badge\">v2.1.0</span>\n <span class=\"badge\" id=\"health-badge\">health</span>\n <span class=\"badge\" id=\"gate-badge\">Gate: checking</span>\n <span class=\"badge\" id=\"drift-badge\">Drift: checking</span>\n <span class=\"badge\" id=\"track-badge\">track</span>\n </div>\n </div>\n <dl class=\"meta\">\n <dt>Package</dt><dd id=\"package-name\">@jakkrichm/create-nexus-devflow</dd>\n <dt>Adapters</dt><dd id=\"adapter-count\">-</dd>\n <dt>Branch</dt><dd id=\"header-branch\">-</dd>\n <dt>Snapshot</dt><dd id=\"generated-at\">-</dd>\n </dl>\n </header>\n <div class=\"live\"><span class=\"live-dot\" id=\"live-dot\"></span><span id=\"live-label\">Connecting to local dashboard...</span></div>\n\n <section class=\"panel\" id=\"dual-track\">\n <div class=\"panel-head\">\n <span class=\"label\">Dual-Track Delivery Model</span>\n <div class=\"track-tabs\" role=\"tablist\" aria-label=\"Delivery tracks\">\n <button class=\"tab on\" id=\"tab-fast\" role=\"tab\" aria-selected=\"true\" aria-controls=\"view-fast\" data-track=\"fast\"><span>\uD83D\uDE80 Fast-Track \u00B7 4 steps</span><span class=\"tab-active-dot\">\u25CF ACTIVE</span></button>\n <button class=\"tab\" id=\"tab-deep\" role=\"tab\" aria-selected=\"false\" aria-controls=\"view-deep\" data-track=\"deep\"><span>\u265F\uFE0F Deep-Track \u00B7 8 stages</span><span class=\"tab-active-dot\">\u25CF ACTIVE</span></button>\n <button class=\"tab\" id=\"tab-swarm\" role=\"tab\" aria-selected=\"false\" aria-controls=\"view-swarm\" data-track=\"swarm\"><span>\uD83E\uDD16 Multi-Agent Swarm</span></button>\n <button class=\"tab\" id=\"tab-graph\" role=\"tab\" aria-selected=\"false\" aria-controls=\"view-graph\" data-track=\"graph\"><span>\uD83D\uDDFA\uFE0F Code Graph</span></button>\n </div>\n </div>\n <div class=\"track-view on\" id=\"view-fast\" role=\"tabpanel\" aria-labelledby=\"tab-fast\">\n <div class=\"stepper\" id=\"pipeline-fast\"></div>\n <div class=\"track-note\" id=\"note-fast\">Fast-Track for daily features, fixes, UI work and iterative refactoring.</div>\n </div>\n <div class=\"track-view\" id=\"view-deep\" role=\"tabpanel\" aria-labelledby=\"tab-deep\">\n <div class=\"stepper\" id=\"pipeline-deep\"></div>\n <div class=\"track-note\" id=\"note-deep\">Deep-Track for architecture, migrations, security audits and coordinated delivery.</div>\n </div>\n <div class=\"track-view\" id=\"view-swarm\" role=\"tabpanel\" aria-labelledby=\"tab-swarm\">\n <div class=\"section-note\">Role-based specialized AI Subagents roster & execution matrix</div>\n <div class=\"roster-grid\" id=\"swarm-roster\"></div>\n </div>\n <div class=\"track-view\" id=\"view-graph\" role=\"tabpanel\" aria-labelledby=\"tab-graph\">\n <div class=\"section-note\">Semantic dependency graph & instant Blast Radius analyzer</div>\n <div class=\"search-row\">\n <input class=\"search-input\" id=\"graph-file-input\" placeholder=\"Type file path (e.g. packages/create-nexus-devflow/lib/code-graph.ts)...\" />\n <button class=\"search-btn\" id=\"graph-search-btn\" type=\"button\">Analyze Impact</button>\n </div>\n <div class=\"blast-result\" id=\"blast-result\"></div>\n </div>\n </section>\n\n <section class=\"panel next-action\" id=\"next-panel\">\n <div class=\"next-head\"><span class=\"label\">Next Action</span><button class=\"copy\" id=\"next-copy\" type=\"button\">Copy command</button></div>\n <div class=\"command\" id=\"next-command\" aria-live=\"polite\">Loading...</div>\n <div class=\"muted\" id=\"next-reason\"></div>\n </section>\n\n <section class=\"stats\" aria-label=\"Workspace summary\">\n <div class=\"stat\"><div class=\"stat-value\" id=\"stat-runs\">-</div><div class=\"stat-label\">Runs released</div></div>\n <div class=\"stat\"><div class=\"stat-value\" id=\"stat-findings\">-</div><div class=\"stat-label\">Active findings</div></div>\n <div class=\"stat\"><div class=\"stat-value\" id=\"stat-ideas\">-</div><div class=\"stat-label\">Pending ideas</div></div>\n <div class=\"stat\"><div class=\"stat-value\" id=\"stat-mcp\">-</div><div class=\"stat-label\">MCP Tools Ready</div></div>\n <div class=\"stat\"><div class=\"stat-value\" id=\"stat-state\">-</div><div class=\"stat-label\">Current state</div></div>\n </section>\n\n <section class=\"grid\">\n <article class=\"card\"><div class=\"card-head\"><span class=\"label\">Nexus-DevFlow</span><span class=\"pill\" id=\"update-pill\">checking</span></div><div class=\"facts\"><div class=\"fact\"><span>Installed / latest</span><span id=\"installed-latest\">-</span></div><div class=\"fact\"><span>Health</span><span id=\"system-health\">-</span></div><div class=\"fact\"><span>Architecture</span><span>3-Pillars + Swarm RAG</span></div></div></article>\n <article class=\"card wide\"><div class=\"card-head\"><span class=\"label\">Current Work</span><span class=\"pill\" id=\"work-pill\">loading</span></div><div class=\"value\" id=\"work-title\">Loading...</div><div class=\"progress\"><span id=\"work-progress\"></span></div><div class=\"muted\" id=\"work-meta\"></div></article>\n <article class=\"card\"><div class=\"card-head\"><span class=\"label\">Git & Drift</span><span class=\"pill\" id=\"git-pill\">loading</span></div><div class=\"facts\"><div class=\"fact\"><span>Branch</span><span id=\"git-branch\">-</span></div><div class=\"fact\"><span>Working tree</span><span id=\"git-changed\">-</span></div><div class=\"fact\"><span>Drift Status</span><span id=\"git-drift\">-</span></div><div class=\"fact\"><span>Last commit</span><span id=\"git-commit\">-</span></div></div></article>\n <article class=\"card\"><div class=\"card-head\"><span class=\"label\">Findings Ledger</span><span class=\"value\" id=\"findings-count\">-</span></div><div class=\"severity\"><div class=\"sev\"><b id=\"sev-p0\">0</b><small>P0</small></div><div class=\"sev\"><b id=\"sev-p1\">0</b><small>P1</small></div><div class=\"sev\"><b id=\"sev-p2\">0</b><small>P2</small></div><div class=\"sev\"><b id=\"sev-p3\">0</b><small>P3</small></div></div><ul id=\"findings-list\"></ul></article>\n <article class=\"card\"><div class=\"card-head\"><span class=\"label\">Completion & Gate</span><span class=\"pill\" id=\"completion-pill\">-</span></div><ul id=\"completion-list\"></ul></article>\n <article class=\"card\"><div class=\"card-head\"><span class=\"label\">Warnings</span><span class=\"value\" id=\"warnings-count\">-</span></div><ul id=\"warnings-list\"></ul></article>\n </section>\n\n <section class=\"card full panel\"><div class=\"card-head\"><span class=\"label\">Model Context Protocol (MCP) Tools Hub</span><span class=\"value\" id=\"mcp-count\">12 Tools</span></div><div class=\"section-note\">Typed JSON-RPC tools exposed to AI Coding Assistants</div><div class=\"mcp-grid\" id=\"mcp-list\"></div></section>\n <section class=\"card full panel\"><div class=\"card-head\"><span class=\"label\">Quick Commands</span><span class=\"muted\">hover or focus for help \u00B7 click to copy</span></div><div class=\"commands\" id=\"command-list\"></div></section>\n <section class=\"grid\"><article class=\"card full\"><div class=\"card-head\"><span class=\"label\">Doctor \u00B7 Health Check</span><span class=\"pill\" id=\"doctor-pill\">-</span></div><div class=\"record-list\" id=\"doctor-list\"></div></article></section>\n <section class=\"card full panel\"><div class=\"card-head\"><span class=\"label\">Discoveries</span><span class=\"value\" id=\"discovery-count\">-</span></div><div class=\"record-list\" id=\"discovery-list\"></div></section>\n <section class=\"card full panel\"><div class=\"card-head\"><span class=\"label\">Idea Inbox & Backlog</span><span class=\"value\" id=\"ideas-count\">-</span></div><div class=\"section-note\">From devflow/ideas.md \u00B7 start a selected item with /feature IDEA-xxx</div><div class=\"record-list\" id=\"ideas-list\"></div></section>\n <section class=\"card full panel\"><div class=\"card-head\"><span class=\"label\">Completed Work Archive</span><span class=\"value\" id=\"history-count\">-</span></div><div class=\"section-note\">Categorized delivery history \u00B7 features, fixes and rollbacks</div><div class=\"record-list\" id=\"history-list\"></div></section>\n <footer><span>Nexus-DevFlow 2.0 Enterprise Dashboard \u00B7 refreshes every 2 seconds</span><span id=\"footer-revision\">snapshot pending</span></footer>\n </main>\n <script>\n const byId = (id) => document.getElementById(id);\n const text = (id, value) => { const node = byId(id); if (node) node.textContent = value == null ? '-' : String(value); };\n const pill = (id, state, label) => { const node = byId(id); if (!node) return; node.className = 'pill ' + (state || 'configured'); node.textContent = label || state || '-'; };\n const list = (id, values, empty) => { const node = byId(id); if (!node) return; node.replaceChildren(); const rows = values.length ? values : [empty]; rows.forEach((value) => { const li = document.createElement('li'); li.textContent = value; if (!values.length) li.className = 'empty'; node.append(li); }); };\n const titleCase = (value) => String(value || '').replaceAll('_',' ').replace(/\\b\\w/g, (c) => c.toUpperCase());\n const FLOW_ICON_NAMES = ['compass','target','document','list','code','shield','report','package'];\n const EMOJI_ICONS = { compass:'\uD83D\uDD0E',target:'\uD83C\uDFAF',document:'\uD83D\uDCC4',list:'\uD83E\uDDE9',code:'\u2699\uFE0F',shield:'\uD83D\uDEE1\uFE0F',report:'\uD83D\uDCCA',package:'\uD83D\uDCE6',bulb:'\u26A1',check:'\u2705',wrench:'\uD83D\uDEE0\uFE0F',rollback:'\u21A9\uFE0F',search:'\uD83D\uDD0D',alert:'\u26A0\uFE0F' };\n function iconImage(name) { const icon = document.createElement('span'); icon.className = 'icon-glyph'; icon.setAttribute('aria-hidden','true'); icon.textContent = EMOJI_ICONS[name] || '\uD83D\uDCC4'; return icon; }\n function decoratePipeline(id) { byId(id)?.querySelectorAll('.step').forEach((step,index) => { step.classList.add('flow-' + index); const icon = document.createElement('span'); icon.className = 'step-icon'; icon.setAttribute('aria-hidden','true'); icon.append(iconImage(FLOW_ICON_NAMES[index] || 'document')); const name = step.querySelector('.step-name'); step.insertBefore(icon,name || null); }); }\n function richText(root,value) { const source = String(value || ''); let cursor = 0; const plain = (end) => { if (end > cursor) root.append(document.createTextNode(source.slice(cursor,end))); cursor = end; }; while (cursor < source.length) { if (source.startsWith('**',cursor)) { const end = source.indexOf('**',cursor + 2); if (end > cursor + 2) { const node = document.createElement('strong'); node.textContent = source.slice(cursor + 2,end); root.append(node); cursor = end + 2; continue; } } if (source[cursor] === '*') { const end = source.indexOf('*',cursor + 1); if (end > cursor + 1) { const node = document.createElement('em'); node.textContent = source.slice(cursor + 1,end); root.append(node); cursor = end + 1; continue; } } if (source.charCodeAt(cursor) === 96) { const end = source.indexOf(String.fromCharCode(96),cursor + 1); if (end > cursor + 1) { const node = document.createElement('code'); node.textContent = source.slice(cursor + 1,end); root.append(node); cursor = end + 1; continue; } } const next = [source.indexOf('**',cursor + 1),source.indexOf('*',cursor + 1),source.indexOf(String.fromCharCode(96),cursor + 1)].filter((index) => index >= 0).sort((a,b) => a-b)[0] ?? source.length; plain(next > cursor ? next : cursor + 1); } }\n function recordCard(options) { const card = document.createElement('article'); card.className = 'record-item tone-' + (options.tone || 'cyan'); const icon = document.createElement('span'); icon.className = 'record-icon'; icon.append(iconImage(options.icon || 'document')); const body = document.createElement('div'); body.className = 'record-body'; const meta = document.createElement('div'); meta.className = 'record-meta'; richText(meta,options.meta); const title = document.createElement('div'); title.className = 'record-title'; richText(title,options.title); const desc = document.createElement('div'); desc.className = 'record-desc'; richText(desc,options.description); body.append(meta,title,desc); card.append(icon,body); if (options.badge) { const badge = document.createElement('span'); badge.className = 'record-badge'; badge.textContent = options.badge; card.append(badge); } return card; }\n function renderRecords(id,items,empty,mapper) { const root = byId(id); root.replaceChildren(); if (!items?.length) { const node = document.createElement('div'); node.className = 'empty'; node.textContent = empty; root.append(node); return; } items.forEach((item,index) => root.append(recordCard(mapper(item,index)))); }\n function renderIdeas(items) { renderRecords('ideas-list',items,'No pending ideas',(item) => ({ icon:'bulb',tone:'gold',meta:item.id,title:item.title,description:(item.description || '\u26A1') + ' \u00B7 ' + (item.feasibility || 'Not scored') })); }\n function renderHistory(items) { const map = { feature:{icon:'package',tone:'cyan'},fix:{icon:'wrench',tone:'gold'},rollback:{icon:'rollback',tone:'red'} }; renderRecords('history-list',(items || []).slice(0,10),'No completed work in history archive',(item) => { const type = String(item.type || 'other').toLowerCase(); const style = map[type] || {icon:'report',tone:'violet'}; return { ...style,meta:type + ' ' + (item.buildPlanItem || ''),title:item.title,description:'',badge:'Released' }; }); }\n function renderDoctor(items) { renderRecords('doctor-list',items,'No doctor checks available',(item) => ({ icon:item.status === 'pass' ? 'check' : 'alert',tone:item.status === 'pass' ? 'mint' : item.status === 'warn' ? 'gold' : 'red',meta:item.status,title:item.name,description:item.message })); }\n function renderDiscoveries(items) { renderRecords('discovery-list',items,'No discoveries recorded',(item) => ({ icon:'search',tone:'mint',meta:item.id,title:item.title,description:'',badge:'Decision: ' + (item.decision || 'Pending') })); }\n\n function renderPipeline(id, nodes) {\n const root = byId(id); root.replaceChildren();\n (nodes || []).forEach((node, index) => {\n const step = document.createElement('div'); step.className = 'step ' + node.state;\n const line = document.createElement('span'); line.className = 'step-line';\n const dot = document.createElement('span'); dot.className = 'step-dot'; dot.textContent = node.state === 'done' ? '\u2713' : String(index + 1).padStart(nodes.length > 4 ? 2 : 1, '0');\n const name = document.createElement('div'); name.className = 'step-name'; name.textContent = node.label;\n const command = document.createElement('div'); command.className = 'step-cmd'; command.textContent = node.command;\n step.append(line, dot, name, command); root.append(step);\n });\n }\n\n function selectTrack(track) {\n document.querySelectorAll('.tab').forEach((node) => { const on = node.dataset.track === track; node.classList.toggle('on', on); node.setAttribute('aria-selected', String(on)); });\n document.querySelectorAll('.track-view').forEach((node) => node.classList.toggle('on', node.id === 'view-' + track));\n }\n\n function wireCopy(button, getValue) {\n button.addEventListener('click', async () => {\n const original = button.textContent;\n button.textContent = 'Copied!';\n try { await navigator.clipboard.writeText(getValue()); }\n catch { button.textContent = 'Copy unavailable'; }\n setTimeout(() => { button.textContent = original; }, 1100);\n });\n }\n\n document.querySelectorAll('.tab').forEach((node) => node.addEventListener('click', () => selectTrack(node.dataset.track)));\n wireCopy(byId('next-copy'), () => byId('next-command').textContent.trim());\n\n function renderCommands(commands) {\n const root = byId('command-list'); root.replaceChildren();\n const allCommands = [...(commands || [])];\n ['nexus-devflow check-gate', 'nexus-devflow drift', 'nexus-devflow reconcile --fix', 'nexus-devflow slice --stage implement', 'nexus-devflow swarm', 'nexus-devflow studio'].forEach(c => {\n if (!allCommands.some(item => item.command === c)) {\n allCommands.push({ name: c.replace('nexus-devflow ', ''), command: c, family: 'companion', description: 'Run ' + c });\n }\n });\n allCommands.forEach((item) => {\n const button = document.createElement('button'); button.type = 'button'; button.className = 'cmd'; button.textContent = item.name; button.dataset.tip = item.description; wireCopy(button, () => item.command); root.append(button);\n });\n }\n\n function renderSwarm(swarm) {\n const root = byId('swarm-roster'); if (!root) return; root.replaceChildren();\n (swarm?.agentRoster || []).forEach(agent => {\n const card = document.createElement('div'); card.className = 'roster-card';\n card.innerHTML = '<strong>' + agent.avatar + ' ' + agent.name + '</strong><div class=\"roster-desc\">' + agent.responsibility + '</div>';\n root.append(card);\n });\n }\n\n function renderMcp(tools) {\n const root = byId('mcp-list'); if (!root) return; root.replaceChildren();\n (tools || []).forEach(t => {\n const card = document.createElement('div'); card.className = 'mcp-card';\n card.innerHTML = '<strong>\u2699\uFE0F ' + t.name + '</strong><div class=\"mcp-desc\">' + t.description + '</div>';\n root.append(card);\n });\n }\n\n byId('graph-search-btn')?.addEventListener('click', async () => {\n const input = byId('graph-file-input'); const res = byId('blast-result');\n if (!input || !res) return;\n const file = input.value.trim();\n if (!file) return;\n res.style.display = 'block'; res.innerHTML = 'Analyzing Blast Radius...';\n try {\n const resp = await fetch('/api/graph?file=' + encodeURIComponent(file));\n const data = await resp.json();\n if (data.error) { res.innerHTML = '<span style=\"color:var(--red)\">' + data.error + '</span>'; return; }\n let html = '<strong>Impact Score: <span style=\"color:var(--gold)\">' + data.impactScore + '</span> | Total Affected: ' + data.totalAffected + ' files</strong><br/><br/>';\n if (data.directDependents?.length) {\n html += '<strong>Direct Dependents:</strong><ul>' + data.directDependents.map(d => '<li>' + d + '</li>').join('') + '</ul>';\n }\n if (data.transitiveDependents?.length) {\n html += '<br/><strong>Transitive Dependents:</strong><ul>' + data.transitiveDependents.map(t => '<li>' + t + '</li>').join('') + '</ul>';\n }\n res.innerHTML = html;\n } catch (e) {\n res.innerHTML = '<span style=\"color:var(--red)\">Error: ' + e.message + '</span>';\n }\n });\n\n function renderSnapshot(data) {\n const status = data.status || {}; const project = status.project || {}; const devflow = status.devflow || {}; const work = status.currentWork || {}; const git = status.git || {}; const findings = status.findings || { active: [], blockers: [] }; const workflow = data.workflow || {}; const update = data.update || {}; const doctor = data.doctor || { checks: [] }; const discoveries = data.discoveries || { recent: [] }; const history = data.history || { items: [], total: 0 }; const ideas = status.ideas || { pending: [], totalPending: 0 }; const gate = data.gatekeeper || { passed: true }; const drift = data.drift || { hasDrift: false };\n\n text('project-name', project.name || 'Nexus-DevFlow'); text('project-path', project.root || ''); text('version-badge', 'v' + (devflow.version || '2.1.0'));\n pill('health-badge', status.health, status.health === 'ok' ? 'Health OK' : 'Health warning');\n pill('gate-badge', gate.passed ? 'ok' : 'blocked', gate.passed ? '\u2714 Gate Passed' : '\u2716 Gate Blocked');\n pill('drift-badge', !drift.hasDrift ? 'ok' : 'warning', !drift.hasDrift ? '\u2714 In Sync' : '\u26A0 Drift Detected');\n pill('track-badge', workflow.track, 'Track ' + titleCase(workflow.track || 'idle'));\n\n text('adapter-count', (devflow.adapters || []).length + ' configured'); text('header-branch', git.branch || 'unknown'); text('generated-at', new Date(data.generatedAt).toLocaleTimeString()); text('footer-revision', 'snapshot ' + data.generatedAt);\n renderPipeline('pipeline-fast', workflow.fast); renderPipeline('pipeline-deep', workflow.deep); decoratePipeline('pipeline-fast'); decoratePipeline('pipeline-deep');\n renderSwarm(data.swarm); renderMcp(data.mcpTools); text('stat-mcp', (data.mcpTools || []).length + ' Ready');\n\n const nextCommand = data.nextAction?.command || status.nextAction?.command || '/feature'; text('next-command', nextCommand); text('next-reason', data.nextAction?.reason || 'Ready for new work.');\n text('stat-runs', history.total || 0); text('stat-findings', (findings.active || []).length); text('stat-ideas', ideas.totalPending || 0); text('stat-state', titleCase(work.state || 'idle'));\n pill('update-pill', update.state, update.state === 'current' ? 'up to date' : update.state); text('installed-latest', (update.installedVersion || '2.1.0') + ' / ' + (update.latestVersion || '2.1.0')); text('system-health', status.health || 'ok');\n pill('work-pill', work.state, work.state || 'idle'); text('work-title', work.title || 'No active delivery run'); const pct = work.total > 0 ? Math.round((work.completed / work.total) * 100) : 0; byId('work-progress').style.width = pct + '%'; text('work-meta', work.state === 'active' ? work.completed + ' of ' + work.total + ' steps completed' : 'Ready');\n pill('git-pill', git.clean ? 'ok' : 'warning', git.clean ? 'clean' : (git.changedFiles || 0) + ' changed'); text('git-branch', git.branch || 'unknown'); text('git-changed', git.clean ? 'clean' : (git.changedFiles || 0) + ' changed files'); text('git-drift', drift.clean ? 'In Sync' : 'Drift detected'); text('git-commit', git.lastCommit || '-');\n text('findings-count', findings.total || 0); ['P0','P1','P2','P3'].forEach((severity) => text('sev-' + severity.toLowerCase(), (findings.active || []).filter((item) => item.severity === severity).length)); list('findings-list', (findings.active || []).map((item) => item.id + ' \u00B7 ' + item.title), 'No active findings');\n pill('completion-pill', status.completion?.state, status.completion?.state || 'unknown'); list('completion-list', status.completion?.blockers || [], work.state === 'idle' ? 'No active run to complete' : 'All readiness checks passed'); text('warnings-count', (status.warnings || []).length); list('warnings-list', (status.warnings || []).map((item) => item.message), 'No active warnings or drift');\n pill('doctor-pill', doctor.failCount ? 'fail' : doctor.warnCount ? 'warning' : 'ok', doctor.passCount + '/' + doctor.totalChecks + ' pass'); renderDoctor(doctor.checks || []);\n text('discovery-count', discoveries.total || 0); renderDiscoveries(discoveries.recent || []); renderCommands(data.commands);\n text('ideas-count', (ideas.totalPending || 0) + ' pending'); renderIdeas(ideas.pending || []); text('history-count', (history.total || 0) + ' released'); renderHistory(history.items || []);\n }\n\n let refreshing = false;\n async function refresh() { if (refreshing) return; refreshing = true; try { const response = await fetch('/api/dashboard'); if (!response.ok) throw new Error('HTTP ' + response.status); renderSnapshot(await response.json()); byId('live-dot').classList.add('on'); text('live-label','Connected \u00B7 live snapshot every 2 seconds'); } catch (error) { byId('live-dot').classList.remove('on'); text('live-label','Disconnected \u00B7 ' + error.message); } finally { refreshing = false; } }\n refresh(); setInterval(refresh, 2000);\n </script>\n</body>\n</html>";
|
|
2
2
|
export { DASHBOARD_PAGE_HTML };
|