@eltonssouza/development-utility-kit 0.10.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/.claude/agents/README.md +24 -0
- package/.claude/agents/analyst.md +198 -0
- package/.claude/agents/backend-developer.md +126 -0
- package/.claude/agents/brain-keeper.md +229 -0
- package/.claude/agents/code-reviewer.md +181 -0
- package/.claude/agents/database-engineer.md +94 -0
- package/.claude/agents/devops-engineer.md +141 -0
- package/.claude/agents/frontend-developer.md +97 -0
- package/.claude/agents/gate-keeper.md +118 -0
- package/.claude/agents/migrator.md +291 -0
- package/.claude/agents/mobile-developer.md +80 -0
- package/.claude/agents/n8n-specialist.md +94 -0
- package/.claude/agents/product-owner.md +115 -0
- package/.claude/agents/qa-engineer.md +232 -0
- package/.claude/agents/release-engineer.md +204 -0
- package/.claude/agents/scaffold.md +87 -0
- package/.claude/agents/security-engineer.md +199 -0
- package/.claude/agents/sprint-runner.md +46 -0
- package/.claude/agents/stack-resolver.md +104 -0
- package/.claude/agents/tech-lead.md +182 -0
- package/.claude/agents/update-template.md +54 -0
- package/.claude/agents/ux-designer.md +118 -0
- package/.claude/hooks/flow-guard.js +261 -0
- package/.claude/hooks/flow-state.js +197 -0
- package/.claude/local/CLAUDE.md +71 -0
- package/.claude/settings.json +55 -0
- package/.claude/skills/README.md +331 -0
- package/.claude/skills/active-project/SKILL.md +131 -0
- package/.claude/skills/api-integration-test/SKILL.md +84 -0
- package/.claude/skills/auto-test-guard/SKILL.md +239 -0
- package/.claude/skills/auto-test-guard/resources/backend-tests.md +20 -0
- package/.claude/skills/auto-test-guard/resources/e2e-tests.md +24 -0
- package/.claude/skills/auto-test-guard/resources/execution-report.md +49 -0
- package/.claude/skills/auto-test-guard/resources/frontend-tests.md +18 -0
- package/.claude/skills/auto-test-guard/resources/initial-setup.md +108 -0
- package/.claude/skills/auto-test-guard/resources/run-suite.md +48 -0
- package/.claude/skills/auto-test-guard/resources/senior-gate.md +19 -0
- package/.claude/skills/brain-keeper/SKILL.md +62 -0
- package/.claude/skills/brain-keeper/obsidian/app.json +9 -0
- package/.claude/skills/brain-keeper/obsidian/appearance.json +4 -0
- package/.claude/skills/brain-keeper/obsidian/core-plugins.json +20 -0
- package/.claude/skills/brain-keeper/obsidian/daily-notes.json +5 -0
- package/.claude/skills/brain-keeper/obsidian/graph.json +32 -0
- package/.claude/skills/brain-keeper/obsidian/snippets/folder-colors.css +90 -0
- package/.claude/skills/brain-keeper/obsidian/templates.json +5 -0
- package/.claude/skills/brain-keeper/templates/README.md +51 -0
- package/.claude/skills/brain-keeper/templates/adr.md +40 -0
- package/.claude/skills/brain-keeper/templates/bug.md +35 -0
- package/.claude/skills/brain-keeper/templates/daily.md +38 -0
- package/.claude/skills/brain-keeper/templates/feature.md +62 -0
- package/.claude/skills/brain-keeper/templates/meeting.md +34 -0
- package/.claude/skills/brain-keeper/templates/tech-debt.md +21 -0
- package/.claude/skills/caveman/SKILL.md +189 -0
- package/.claude/skills/create-stack-pack/SKILL.md +281 -0
- package/.claude/skills/grill-me/SKILL.md +80 -0
- package/.claude/skills/pair-debug/SKILL.md +288 -0
- package/.claude/skills/prd-ready-check/SKILL.md +86 -0
- package/.claude/skills/project-manager/SKILL.md +334 -0
- package/.claude/skills/quality-standards/SKILL.md +203 -0
- package/.claude/skills/quick-feature/SKILL.md +266 -0
- package/.claude/skills/run-sprint/SKILL.md +41 -0
- package/.claude/skills/scaffold/SKILL.md +60 -0
- package/.claude/skills/stack-discovery/SKILL.md +161 -0
- package/.claude/skills/test-coverage-auditor/SKILL.md +87 -0
- package/.claude/skills/to-issues/SKILL.md +163 -0
- package/.claude/skills/to-prd/SKILL.md +130 -0
- package/.claude/skills/update-template/SKILL.md +256 -0
- package/.claude/stacks/CODEOWNERS +30 -0
- package/.claude/stacks/README.md +97 -0
- package/.claude/stacks/_template.md +116 -0
- package/.claude/stacks/dotnet/aspire-9.md +528 -0
- package/.claude/stacks/go/gin-1.10.md +570 -0
- package/.claude/stacks/java/spring-boot-3.md +376 -0
- package/.claude/stacks/java/spring-boot-4.md +438 -0
- package/.claude/stacks/node/express-5.md +538 -0
- package/.claude/stacks/python/django-5.md +483 -0
- package/.claude/stacks/python/fastapi-0.115.md +522 -0
- package/.claude/stacks/typescript/angular-18.md +420 -0
- package/.claude/stacks/typescript/angular-19.md +397 -0
- package/.claude/stacks/typescript/angular-21.md +494 -0
- package/CLAUDE.md +472 -0
- package/README.md +412 -0
- package/bin/cli.js +848 -0
- package/bin/lib/adr.js +146 -0
- package/bin/lib/backup.js +62 -0
- package/bin/lib/detect-stack.js +476 -0
- package/bin/lib/doctor.js +527 -0
- package/bin/lib/help.js +328 -0
- package/bin/lib/identity.js +108 -0
- package/bin/lib/lint-allowlist.json +15 -0
- package/bin/lib/lint.js +798 -0
- package/bin/lib/local-dir.js +68 -0
- package/bin/lib/manifest.js +236 -0
- package/bin/lib/sync-all.js +394 -0
- package/bin/lib/version-check.js +398 -0
- package/dashboard/db.js +321 -0
- package/dashboard/package.json +22 -0
- package/dashboard/public/app.js +853 -0
- package/dashboard/public/content/docs/agents-reference.en.md +911 -0
- package/dashboard/public/content/docs/architecture-overview.en.md +252 -0
- package/dashboard/public/content/docs/autonomy-matrix.en.md +186 -0
- package/dashboard/public/content/docs/cli-reference.en.md +538 -0
- package/dashboard/public/content/docs/git-flow.en.md +525 -0
- package/dashboard/public/content/docs/honcho-memory.en.md +394 -0
- package/dashboard/public/content/docs/hooks-reference.en.md +404 -0
- package/dashboard/public/content/docs/pipeline.en.md +414 -0
- package/dashboard/public/content/docs/plugins.en.md +289 -0
- package/dashboard/public/content/docs/quality-gate.en.md +315 -0
- package/dashboard/public/content/docs/skills-reference.en.md +484 -0
- package/dashboard/public/content/docs/stack-rules.en.md +362 -0
- package/dashboard/public/content/docs/troubleshooting.en.md +565 -0
- package/dashboard/public/content/manifest.json +114 -0
- package/dashboard/public/content/manual/backend.en.md +1053 -0
- package/dashboard/public/content/manual/existing-project.en.md +848 -0
- package/dashboard/public/content/manual/frontend.en.md +1008 -0
- package/dashboard/public/content/manual/fullstack.en.md +1459 -0
- package/dashboard/public/content/manual/mobile.en.md +837 -0
- package/dashboard/public/content/manual/quickstart.en.md +169 -0
- package/dashboard/public/index.html +217 -0
- package/dashboard/public/style.css +857 -0
- package/dashboard/public/vendor/marked.min.js +69 -0
- package/dashboard/rtk.js +143 -0
- package/dashboard/server-app.js +421 -0
- package/dashboard/server.js +104 -0
- package/dashboard/test/sprint1.test.js +406 -0
- package/dashboard/test/sprint2.test.js +571 -0
- package/dashboard/test/sprint3.test.js +560 -0
- package/package.json +33 -0
- package/scripts/hooks/subagent-telemetry.sh +14 -0
- package/scripts/hooks/telemetry-writer.js +250 -0
- package/scripts/latest-versions.json +56 -0
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# Quickstart — 5 minutes to first value
|
|
2
|
+
|
|
3
|
+
Goal: from zero installation to a useful response from `duk` in 5 minutes. No prior knowledge of the harness's internals required.
|
|
4
|
+
|
|
5
|
+
If you are evaluating whether `duk` fits your workflow, this is the right starting point. Architecture, ADRs, and stack packs come later.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Prerequisites (30 seconds to verify)
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
node --version # need >= 18
|
|
13
|
+
git --version # any recent version
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
If both pass, you are ready. If not, install Node 18+ and Git first.
|
|
17
|
+
|
|
18
|
+
You also need either **Claude Code** (CLI) or **Cowork** (the conversational desktop app). They are how the harness gets its work done. The harness itself is just installable skills and agents that live in your project — there is no `duk run` command that talks to an LLM. The LLM client (Claude Code / Cowork) reads the skills and invokes the agents.
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Path A — Brand new project (1 minute)
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cd C:/development/source/projects # or wherever you keep projects
|
|
26
|
+
|
|
27
|
+
npx @eltonssouza/development-utility-kit new my-app
|
|
28
|
+
cd my-app
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
What just happened:
|
|
32
|
+
|
|
33
|
+
- A folder `my-app/` was created
|
|
34
|
+
- `git init -q` initialized a fresh repo
|
|
35
|
+
- The harness was injected: `.claude/` (skills + agents + stacks), `CLAUDE.md` (template), `.claude/local/` placeholder
|
|
36
|
+
- The Project Identity block in `CLAUDE.md` is empty, waiting for you to declare your stack
|
|
37
|
+
|
|
38
|
+
Open the folder in Cowork or Claude Code, then type in chat:
|
|
39
|
+
|
|
40
|
+
```
|
|
41
|
+
sabatina pra projeto novo
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
(or in English: `stack discovery`)
|
|
45
|
+
|
|
46
|
+
The `stack-discovery` skill walks you through 5–8 questions about your stack (language, framework, version, database, UI lib, domain). Each question comes with a recommended answer — you just confirm. At the end, your `Project Identity` is filled and you can scaffold.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Path B — Existing project (2 minutes)
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cd path/to/existing-project
|
|
54
|
+
|
|
55
|
+
npx @eltonssouza/development-utility-kit install
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
What just happened:
|
|
59
|
+
|
|
60
|
+
- The CLI scanned `pom.xml`, `package.json`, `pyproject.toml`, `go.mod`, etc. to detect your stack
|
|
61
|
+
- It injected `.claude/` and `CLAUDE.md` into the project
|
|
62
|
+
- A `.claude/.MANIFEST` file was written (sha256 per file) — future installs will detect any local drift and refuse to overwrite without `--force`
|
|
63
|
+
- Your existing `CLAUDE.md` is preserved if present (the `## Project Identity` block in particular)
|
|
64
|
+
|
|
65
|
+
Open the folder in Cowork or Claude Code. The harness is ready.
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## Your first useful prompt
|
|
70
|
+
|
|
71
|
+
In chat, try one of these:
|
|
72
|
+
|
|
73
|
+
| You say | What happens |
|
|
74
|
+
|---|---|
|
|
75
|
+
| `"scaffold the project"` | `scaffold` skill reads your Project Identity and generates the appropriate skeleton (backend / frontend / fullstack monorepo). |
|
|
76
|
+
| `"cria endpoint POST /api/v1/users"` | `project-manager` routes to `backend-developer` agent, which writes controller + service + DTO + test, following your stack pack's conventions. |
|
|
77
|
+
| `"audita seguranca do projeto"` | `project-manager` routes to `security-engineer` agent, which runs an OWASP/LGPD scan and reports findings. |
|
|
78
|
+
| `"grill me about authentication"` | `grill-me` skill starts a discovery interview — one decision at a time — and persists conclusions to `docs/discovery/DISCOVERY_authentication.md`. |
|
|
79
|
+
| `"executa Sprint 1 do PLAN_users.md"` | `run-sprint` skill executes the sprint with TDD, dispatching `qa-engineer`, `backend-developer`, `frontend-developer`, and `gate-keeper` in parallel. |
|
|
80
|
+
|
|
81
|
+
Each prompt triggers the right skill via keyword match (declarations in `.claude/skills/<name>/SKILL.md` frontmatter `description`). You do not need to memorize them — just describe what you want.
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Inspect what is running — duk dashboard
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
duk dashboard
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Opens a local web UI at `http://localhost:4242` (or next free port) with:
|
|
92
|
+
|
|
93
|
+
- **Telemetry**: which subagent was invoked, when, how long
|
|
94
|
+
- **Model breakdown**: how much Opus vs Sonnet vs Haiku you have used
|
|
95
|
+
- **RTK savings**: if you have RTK on PATH, real token savings from the proxy
|
|
96
|
+
- **Manuals + Tech Docs tabs**: this very page (quickstart), architecture overview, skills reference, agents reference, plugins, ADR catalog
|
|
97
|
+
|
|
98
|
+
The dashboard reads from `~/.claude/telemetry.db` (SQLite, populated by the `SubagentStop` hook). It is read-only — nothing you do in the UI changes your project.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Validate everything is OK — duk doctor
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
duk doctor
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Mechanical health check. No LLM, no API call. Validates:
|
|
109
|
+
|
|
110
|
+
- Node ≥18, git, npx, python presence
|
|
111
|
+
- Harness `.claude/` structure is complete
|
|
112
|
+
- `~/.claude/settings.json` is valid JSON; hooks point to existing files
|
|
113
|
+
- Stack packs are available
|
|
114
|
+
- Credentials file exists (for VPS-aware skills)
|
|
115
|
+
- If you are inside an adopted project: `MANIFEST` exists and Project Identity is filled
|
|
116
|
+
|
|
117
|
+
Returns exit code `0` if all PASS. Use `--strict` to fail on WARNs too. Use `--json` for CI parsing.
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
duk doctor --strict
|
|
121
|
+
duk doctor --json | jq .summary
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
---
|
|
125
|
+
|
|
126
|
+
## What to read next
|
|
127
|
+
|
|
128
|
+
You just installed the harness, scaffolded or adopted a project, ran your first prompt, and verified the environment. From here, three reading paths depending on your goal:
|
|
129
|
+
|
|
130
|
+
| Goal | Read |
|
|
131
|
+
|---|---|
|
|
132
|
+
| "How do skills know when to fire?" | [architecture-overview](../docs/architecture-overview) — 3-layer model, keyword matching, agent dispatch |
|
|
133
|
+
| "What skill should I use for X?" | [skills-reference](../docs/skills-reference) — full catalog, per-skill triggers, when NOT to use |
|
|
134
|
+
| "Which agent does what?" | [agents-reference](../docs/agents-reference) — 25 agents grouped by domain authority |
|
|
135
|
+
| "What is the discovery → delivery pipeline?" | [pipeline](../docs/pipeline) — full canonical flow + shortcuts for small features |
|
|
136
|
+
| "Who decides what, when do I get interrupted?" | [autonomy-matrix](../docs/autonomy-matrix) — the master rule |
|
|
137
|
+
| "Why these external plugins?" | [plugins](../docs/plugins) — selection rationale for grill-me, caveman, impeccable, rtk |
|
|
138
|
+
| "What CLI commands exist?" | [cli-reference](../docs/cli-reference) — all `duk` commands with flags, examples, exit codes |
|
|
139
|
+
| "Java + Spring Boot specifics" | [Fullstack manual](fullstack) |
|
|
140
|
+
| "Angular specifics" | [Frontend manual](frontend) |
|
|
141
|
+
| "Spring Boot backend only" | [Backend manual](backend) |
|
|
142
|
+
| "React Native mobile" | [Mobile manual](mobile) |
|
|
143
|
+
|
|
144
|
+
If you adopt the harness on a real project and ship something with it, please consider contributing an entry to `docs/EVIDENCE.md` — real metrics from real projects are what move the harness forward.
|
|
145
|
+
|
|
146
|
+
---
|
|
147
|
+
|
|
148
|
+
## Troubleshooting
|
|
149
|
+
|
|
150
|
+
| Symptom | Likely cause | Fix |
|
|
151
|
+
|---|---|---|
|
|
152
|
+
| `duk doctor` reports Node < 18 | Old Node installed | Install Node 18+ from nodejs.org or your package manager |
|
|
153
|
+
| `duk install` aborts with "drift detected" | You modified `.claude/` after the previous install | Move your changes to `.claude/local/` (preserved across installs) OR run `duk install --force` (overwrite + backup) |
|
|
154
|
+
| Chat does not seem to trigger any skill | Keywords do not match any skill's `description` | Try a more explicit phrasing OR fall through to `project-manager` (catch-all) by phrasing as a normal dev request like "create endpoint POST /api/v1/foo" |
|
|
155
|
+
| `duk dashboard` says "port 4242 in use" | Another process holds the port | Pass `--port 5000` (or any free port) |
|
|
156
|
+
| RTK widget shows no data | RTK not on PATH (intentional fallback) | Install rtk separately if you want the metric; otherwise ignore |
|
|
157
|
+
| `duk lint` reports ERRORs in skills you did not touch | Frontmatter incomplete in the harness | Open an issue with the lint output — likely a regression |
|
|
158
|
+
|
|
159
|
+
For deeper problems: [troubleshooting](../docs/troubleshooting).
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## What this guide skipped on purpose
|
|
164
|
+
|
|
165
|
+
- The 8-stage canonical pipeline (`grill-me → to-prd → to-issues → analyst → architect → tech-lead → sprint-runner → gate-keeper → code-reviewer → tech-lead → brain-keeper`). For 99% of tasks you do not invoke it directly — `project-manager` handles routing. Read [pipeline](../docs/pipeline) when you need the formal flow.
|
|
166
|
+
- 34 ADRs. They explain why each architectural choice was made. Read them when you are evaluating whether to adopt the harness for a serious project, or when you propose a change. Not required for daily use.
|
|
167
|
+
- The senior+ quality gate thresholds (coverage ≥85%, mutation ≥70%, a11y, Lighthouse). They run when `gate-keeper` is invoked — you do not need to memorize them.
|
|
168
|
+
|
|
169
|
+
If after 5 minutes you got the value above and want to go deeper, all of this is one click away in the dashboard. Welcome.
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>development-utility-kit dashboard</title>
|
|
7
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
8
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
9
|
+
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=JetBrains+Mono:wght@400;500;700&display=swap" rel="stylesheet" />
|
|
10
|
+
<link rel="stylesheet" href="style.css" />
|
|
11
|
+
<script src="https://cdn.jsdelivr.net/npm/chart.js@4/dist/chart.umd.min.js"></script>
|
|
12
|
+
<script
|
|
13
|
+
src="https://cdn.jsdelivr.net/npm/marked@15/marked.min.js"
|
|
14
|
+
onerror="(function(){var s=document.createElement('script');s.src='vendor/marked.min.js';document.head.appendChild(s);})()"
|
|
15
|
+
></script>
|
|
16
|
+
</head>
|
|
17
|
+
<body>
|
|
18
|
+
|
|
19
|
+
<!-- LOADING SCREEN -->
|
|
20
|
+
<div class="loader" id="loader">
|
|
21
|
+
<div style="text-align:center">
|
|
22
|
+
<div class="loader-ring-wrap">
|
|
23
|
+
<div class="loader-ring"></div>
|
|
24
|
+
<div class="loader-ring"></div>
|
|
25
|
+
<div class="loader-ring"></div>
|
|
26
|
+
</div>
|
|
27
|
+
<div class="loader-text">INITIALIZING</div>
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<!-- NEURAL NETWORK BACKGROUND -->
|
|
32
|
+
<canvas id="neuralCanvas"></canvas>
|
|
33
|
+
|
|
34
|
+
<header class="app-header">
|
|
35
|
+
<h1>development-utility-kit</h1>
|
|
36
|
+
<span class="badge">dashboard</span>
|
|
37
|
+
<span class="badge" id="last-updated">loading…</span>
|
|
38
|
+
|
|
39
|
+
<nav class="tab-nav" role="tablist">
|
|
40
|
+
<button class="tab-btn active" data-tab="dashboard" role="tab" aria-selected="true">Dashboard</button>
|
|
41
|
+
<button class="tab-btn" data-tab="manual" role="tab" aria-selected="false">Manual</button>
|
|
42
|
+
<button class="tab-btn" data-tab="docs" role="tab" aria-selected="false">Tech Docs</button>
|
|
43
|
+
</nav>
|
|
44
|
+
|
|
45
|
+
</header>
|
|
46
|
+
|
|
47
|
+
<!-- Panel: Dashboard (existing telemetry) -->
|
|
48
|
+
<section id="panel-dashboard" class="tab-panel active" role="tabpanel">
|
|
49
|
+
<main class="grid">
|
|
50
|
+
|
|
51
|
+
<!-- Card: Projects -->
|
|
52
|
+
<section class="card" id="projects-card">
|
|
53
|
+
<h2 class="card-title">Projects (last 30 days)</h2>
|
|
54
|
+
<ul class="project-list" id="project-list">
|
|
55
|
+
<li class="empty-state">Loading…</li>
|
|
56
|
+
</ul>
|
|
57
|
+
</section>
|
|
58
|
+
|
|
59
|
+
<!-- Card: Models -->
|
|
60
|
+
<section class="card" id="models-card">
|
|
61
|
+
<h2 class="card-title">Model Breakdown</h2>
|
|
62
|
+
<div class="chart-wrap">
|
|
63
|
+
<canvas id="models-chart"></canvas>
|
|
64
|
+
</div>
|
|
65
|
+
</section>
|
|
66
|
+
|
|
67
|
+
<!-- Card: RTK Token Savings -->
|
|
68
|
+
<section class="card" id="rtk-card">
|
|
69
|
+
<h2 class="card-title">RTK Token Savings</h2>
|
|
70
|
+
<div class="rtk-summary" id="rtk-summary">
|
|
71
|
+
<div class="rtk-stat">
|
|
72
|
+
<span class="value" id="rtk-tokens">—</span>
|
|
73
|
+
<span class="label">tokens saved</span>
|
|
74
|
+
</div>
|
|
75
|
+
<div class="rtk-stat">
|
|
76
|
+
<span class="value" id="rtk-pct">—</span>
|
|
77
|
+
<span class="label">savings %</span>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<div class="chart-wrap">
|
|
81
|
+
<canvas id="rtk-chart"></canvas>
|
|
82
|
+
</div>
|
|
83
|
+
</section>
|
|
84
|
+
|
|
85
|
+
</main>
|
|
86
|
+
|
|
87
|
+
<!-- Processes panel: shown when a project is selected from the list -->
|
|
88
|
+
<section id="processes-panel" class="processes-panel" hidden aria-live="polite">
|
|
89
|
+
<div class="processes-header">
|
|
90
|
+
<h2 class="processes-title">Processes — <span id="processes-project-name"></span></h2>
|
|
91
|
+
<button class="processes-close" id="processes-close" aria-label="Close processes panel">×</button>
|
|
92
|
+
</div>
|
|
93
|
+
<div id="processes-list" class="processes-list">
|
|
94
|
+
<p class="empty-state">Loading…</p>
|
|
95
|
+
</div>
|
|
96
|
+
</section>
|
|
97
|
+
</section>
|
|
98
|
+
|
|
99
|
+
<!-- Panel: Manual -->
|
|
100
|
+
<section id="panel-manual" class="tab-panel" role="tabpanel" hidden>
|
|
101
|
+
<div class="panel-layout">
|
|
102
|
+
<aside class="toc-sidebar" id="toc-manual" aria-label="Table of contents"></aside>
|
|
103
|
+
<div class="panel-content">
|
|
104
|
+
<div class="scenario-selector" id="manual-scenario-selector">
|
|
105
|
+
<!-- Scenario buttons rendered by app.js from manifest -->
|
|
106
|
+
</div>
|
|
107
|
+
<div id="translation-banner-manual" class="translation-banner" hidden>
|
|
108
|
+
</div>
|
|
109
|
+
<div class="content-body" id="manual-content-body">
|
|
110
|
+
<p class="empty-state">Select a scenario above.</p>
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</div>
|
|
114
|
+
</section>
|
|
115
|
+
|
|
116
|
+
<!-- Panel: Tech Docs -->
|
|
117
|
+
<section id="panel-docs" class="tab-panel" role="tabpanel" hidden>
|
|
118
|
+
<div class="panel-layout">
|
|
119
|
+
<aside class="toc-sidebar" id="toc-docs" aria-label="Table of contents"></aside>
|
|
120
|
+
<div class="panel-content">
|
|
121
|
+
<div id="translation-banner-docs" class="translation-banner" hidden>
|
|
122
|
+
</div>
|
|
123
|
+
<div class="content-body" id="docs-content-body">
|
|
124
|
+
<p class="empty-state">Select a section.</p>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</section>
|
|
129
|
+
|
|
130
|
+
<footer class="status-bar">
|
|
131
|
+
<span><span class="dot"></span>live — polling every 5 s</span>
|
|
132
|
+
<span id="status-msg">connecting…</span>
|
|
133
|
+
</footer>
|
|
134
|
+
|
|
135
|
+
<!-- Neural canvas + loader dismiss -->
|
|
136
|
+
<script>
|
|
137
|
+
(function () {
|
|
138
|
+
var canvas = document.getElementById('neuralCanvas');
|
|
139
|
+
var ctx = canvas.getContext('2d');
|
|
140
|
+
var particles = [];
|
|
141
|
+
|
|
142
|
+
function resize() {
|
|
143
|
+
canvas.width = window.innerWidth;
|
|
144
|
+
canvas.height = window.innerHeight;
|
|
145
|
+
}
|
|
146
|
+
resize();
|
|
147
|
+
window.addEventListener('resize', resize);
|
|
148
|
+
|
|
149
|
+
function Particle() {
|
|
150
|
+
this.reset();
|
|
151
|
+
}
|
|
152
|
+
Particle.prototype.reset = function () {
|
|
153
|
+
this.x = Math.random() * canvas.width;
|
|
154
|
+
this.y = Math.random() * canvas.height;
|
|
155
|
+
this.size = Math.random() * 1.4 + 0.4;
|
|
156
|
+
this.vx = (Math.random() - 0.5) * 0.35;
|
|
157
|
+
this.vy = (Math.random() - 0.5) * 0.35;
|
|
158
|
+
this.opacity = Math.random() * 0.35 + 0.08;
|
|
159
|
+
};
|
|
160
|
+
Particle.prototype.update = function () {
|
|
161
|
+
this.x += this.vx;
|
|
162
|
+
this.y += this.vy;
|
|
163
|
+
if (this.x > canvas.width) this.x = 0;
|
|
164
|
+
if (this.x < 0) this.x = canvas.width;
|
|
165
|
+
if (this.y > canvas.height) this.y = 0;
|
|
166
|
+
if (this.y < 0) this.y = canvas.height;
|
|
167
|
+
};
|
|
168
|
+
Particle.prototype.draw = function () {
|
|
169
|
+
ctx.beginPath();
|
|
170
|
+
ctx.arc(this.x, this.y, this.size, 0, Math.PI * 2);
|
|
171
|
+
ctx.fillStyle = 'rgba(109,179,255,' + this.opacity + ')';
|
|
172
|
+
ctx.fill();
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
function init() {
|
|
176
|
+
particles = [];
|
|
177
|
+
var n = Math.min(55, Math.floor((canvas.width * canvas.height) / 22000));
|
|
178
|
+
for (var i = 0; i < n; i++) particles.push(new Particle());
|
|
179
|
+
}
|
|
180
|
+
init();
|
|
181
|
+
window.addEventListener('resize', init);
|
|
182
|
+
|
|
183
|
+
function animate() {
|
|
184
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
185
|
+
for (var i = 0; i < particles.length; i++) {
|
|
186
|
+
particles[i].update();
|
|
187
|
+
particles[i].draw();
|
|
188
|
+
for (var j = i + 1; j < particles.length; j++) {
|
|
189
|
+
var dx = particles[i].x - particles[j].x;
|
|
190
|
+
var dy = particles[i].y - particles[j].y;
|
|
191
|
+
var d = Math.sqrt(dx * dx + dy * dy);
|
|
192
|
+
if (d < 120) {
|
|
193
|
+
ctx.beginPath();
|
|
194
|
+
ctx.strokeStyle = 'rgba(26,107,255,' + (1 - d / 120) * 0.1 + ')';
|
|
195
|
+
ctx.lineWidth = 0.5;
|
|
196
|
+
ctx.moveTo(particles[i].x, particles[i].y);
|
|
197
|
+
ctx.lineTo(particles[j].x, particles[j].y);
|
|
198
|
+
ctx.stroke();
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
requestAnimationFrame(animate);
|
|
203
|
+
}
|
|
204
|
+
animate();
|
|
205
|
+
|
|
206
|
+
window.addEventListener('load', function () {
|
|
207
|
+
setTimeout(function () {
|
|
208
|
+
var loader = document.getElementById('loader');
|
|
209
|
+
if (loader) loader.classList.add('hidden');
|
|
210
|
+
}, 900);
|
|
211
|
+
});
|
|
212
|
+
})();
|
|
213
|
+
</script>
|
|
214
|
+
|
|
215
|
+
<script src="app.js"></script>
|
|
216
|
+
</body>
|
|
217
|
+
</html>
|