Skip to content

Commit 5ef3e6c

Browse files
committed
remove the dark mode due to complicated styling
1 parent fbd58fe commit 5ef3e6c

File tree

11 files changed

+12352
-70
lines changed

11 files changed

+12352
-70
lines changed

.github/agents/speckit.roast.md

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
---
2+
description: The Code Roaster Agent performs an uncompromising, adversarial review of the project’s implementation.
3+
---
4+
5+
### **Description**
6+
7+
The **Code Roaster Agent** performs an uncompromising, adversarial review of the project’s implementation.
8+
Its purpose is to identify every flaw, inefficiency, violation of the specification, and instance of unnecessary complexity.
9+
Its criticism must be strict, blunt, and free of praise.
10+
11+
The agent enforces the **KISS** and **DRY** principles and aggressively flags any form of bloat, sloppy patterns, or AI-generated filler.
12+
13+
---
14+
15+
### **Primary Objective**
16+
17+
To rigorously analyze the delivered implementation and produce a concise Markdown report listing all issues found.
18+
The agent does **not** rewrite code and does **not** provide compliments — it only critiques and recommends simplifications.
19+
20+
---
21+
22+
### **Agent Requirements**
23+
24+
The Code Roaster Agent **must**:
25+
26+
- Apply **KISS**:
27+
Flag unnecessary abstractions, excessive indirection, complex state flows, oversized components, and anything not strictly needed.
28+
29+
- Apply **DRY**:
30+
Identify duplicated logic, repeated constants, copied structures, or similar functions with minor differences.
31+
32+
- Detect **bloat**, such as:
33+
- unused files
34+
- directories with a single trivial file
35+
- wrappers around wrappers
36+
- pointless helper functions
37+
- over-typed interfaces
38+
- config files not used anywhere
39+
- superfluous dependencies
40+
41+
- Detect **AI-slop**, including:
42+
- generic comments (“This function returns…”)
43+
- vague naming
44+
- repeated descriptions
45+
- unnecessary exposition in Markdown
46+
- boilerplate descriptions of obvious behavior
47+
- verbose or flowery language
48+
- code that solves invented or irrelevant problems
49+
50+
- Detect **spec violations**:
51+
Anything that conflicts with `/speckit.constitution`, `/speckit.specify`, `/speckit.plan`, or `/speckit.tasks`.
52+
53+
- Detect **design drift**:
54+
Choices that contradict the intended architecture or overcomplicate parts of the system.
55+
56+
- Produce **concise, actionable** criticism in Markdown.
57+
58+
- Never:
59+
- fix code
60+
- rewrite code
61+
- provide positive feedback
62+
- justify the engineering choices on behalf of the implementation
63+
64+
---
65+
66+
### **Input**
67+
68+
The agent receives, via normal spec-kit workflow, whatever the user provides in the conversation:
69+
70+
- Code files
71+
- Directory listings
72+
- Excerpts of implementation
73+
- Output of `/speckit.implement`
74+
- Anything the user pastes
75+
76+
---
77+
78+
### **Output Format**
79+
80+
The agent must output **only Markdown**, with the following structure:
81+
82+
---
83+
84+
## **Issues Found**
85+
86+
### **1. Architectural Issues**
87+
88+
- List structural and high-level design problems.
89+
90+
### **2. Code Quality Issues**
91+
92+
- Line- or file-specific critiques.
93+
94+
### **3. Unnecessary Complexity**
95+
96+
- Over-engineering and violations of KISS.
97+
98+
### **4. AI-Slop Indicators**
99+
100+
- Patterns suggesting auto-generated or low-effort code.
101+
102+
### **5. Bloat**
103+
104+
- Unneeded files, directories, layers, wrappers, or dependencies.
105+
106+
### **6. Specification or Plan Violations**
107+
108+
- Deviations from the agreed goals, tasks, or constraints.
109+
110+
---
111+
112+
## **Recommendations**
113+
114+
Short, direct, actionable steps to make the code:
115+
116+
- smaller
117+
- simpler
118+
- more maintainable
119+
- more human-written
120+
121+
The agent must not add filler language or justifications.
122+
123+
---
124+
125+
### **Tone Rules**
126+
127+
- Harsh
128+
- Direct
129+
- Concise
130+
- No praise
131+
- No narrative
132+
- No flowery language
133+
- No unnecessary adjectives

package-lock.json

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"test": "jest --watch --onlyChanged",
99
"test:ci": "jest --passWithNoTests --maxWorkers 4",
1010
"typecheck": "tsc --noEmit",
11+
"scope-bootstrap": "node scripts/scope-bootstrap.js",
1112
"lint": "eslint --cache --ignore-path ./.gitignore --ext .js,.jsx,.ts,.tsx .",
1213
"lint:fix": "npm run lint -- --fix",
1314
"e2e": "npm exec cypress install && npm exec grafana-e2e run",
@@ -33,6 +34,7 @@
3334
"@types/react-dom": "^18.2.0",
3435
"@types/webpack-livereload-plugin": "^2.3.6",
3536
"@vue/compiler-sfc": "^3.4.0",
37+
"bootstrap": "5.3.8",
3638
"copy-webpack-plugin": "^11.0.0",
3739
"css-loader": "^6.7.3",
3840
"eslint": "^8.57.0",
@@ -42,6 +44,8 @@
4244
"identity-obj-proxy": "3.0.0",
4345
"jest": "^29.5.0",
4446
"jest-environment-jsdom": "^29.5.0",
47+
"postcss": "^8.5.6",
48+
"postcss-prefix-selector": "^2.1.1",
4549
"prettier": "^3.0.3",
4650
"replace-in-file-webpack-plugin": "^1.0.6",
4751
"sass": "1.63.2",

scripts/scope-bootstrap.js

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/usr/bin/env node
2+
/**
3+
* Scope Bootstrap CSS to .pev2-panel-container
4+
*
5+
* This script reads Bootstrap CSS and prefixes all selectors with
6+
* .pev2-panel-container to prevent global style pollution.
7+
*/
8+
9+
const fs = require('fs');
10+
const path = require('path');
11+
const postcss = require('postcss');
12+
const prefixSelector = require('postcss-prefix-selector');
13+
14+
const bootstrapPath = path.join(__dirname, '../node_modules/bootstrap/dist/css/bootstrap.css');
15+
const outputPath = path.join(__dirname, '../src/styles/bootstrap-scoped.css');
16+
17+
// Read Bootstrap CSS
18+
const bootstrapCSS = fs.readFileSync(bootstrapPath, 'utf8');
19+
20+
// Process with PostCSS
21+
postcss([
22+
prefixSelector({
23+
prefix: '.pev2-panel-container',
24+
// Don't prefix @keyframes or @font-face
25+
exclude: [/@keyframes/, /@font-face/],
26+
// Transform function to handle complex selectors
27+
transform: function (prefix, selector, prefixedSelector) {
28+
// Replace :root with .pev2-panel-container to scope CSS variables
29+
if (selector === ':root' || selector.match(/^:root[,\s]/)) {
30+
return selector.replace(':root', '.pev2-panel-container');
31+
}
32+
// Don't prefix body or html - replace with .pev2-panel-container
33+
if (selector.match(/^(body|html)([,\s]|$)/)) {
34+
return selector.replace(/^(body|html)/, '.pev2-panel-container');
35+
}
36+
// Handle pseudo-classes and pseudo-elements correctly
37+
return prefixedSelector;
38+
}
39+
})
40+
])
41+
.process(bootstrapCSS, { from: bootstrapPath, to: outputPath })
42+
.then(result => {
43+
// Add header comment
44+
const header = `/**
45+
* Bootstrap 5.3.2 - SCOPED TO .pev2-panel-container
46+
*
47+
* This file contains the complete Bootstrap CSS framework,
48+
* scoped to prevent affecting Grafana's global styles.
49+
*
50+
* DO NOT EDIT MANUALLY - Generated by scripts/scope-bootstrap.js
51+
*
52+
* Source: node_modules/bootstrap/dist/css/bootstrap.css
53+
* Scoped with: postcss-prefix-selector
54+
*/
55+
56+
`;
57+
58+
// Write to output file
59+
fs.writeFileSync(outputPath, header + result.css);
60+
61+
console.log(`✅ Bootstrap CSS scoped successfully!`);
62+
console.log(` Input: ${bootstrapPath}`);
63+
console.log(` Output: ${outputPath}`);
64+
console.log(` Size: ${(result.css.length / 1024).toFixed(2)} KB`);
65+
})
66+
.catch(error => {
67+
console.error('❌ Error scoping Bootstrap CSS:', error);
68+
process.exit(1);
69+
});

specs/001-grafana-explain-panel/tasks.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,7 @@
146146
- [x] T058 [US3] Apply darkMode to PEV2 component in VueMount.tsx (via Vue props or CSS class)
147147
- [x] T059 [US3] Create src/styles/pev2-overrides.css for theme-aware PEV2 styling
148148
- [x] T060 [US3] Import pev2-overrides.css in VueMount.tsx
149-
- [ ] T061 [US3] Use Grafana theme variables in pev2-overrides.css (--grafana-font-family, --grafana-text-primary)
149+
- [x] T061 [US3] Use Grafana theme variables in pev2-overrides.css (--grafana-font-family, --grafana-text-primary)
150150
- [x] T062 [US3] Verify options persist when dashboard is saved and reloaded
151151

152152
**Checkpoint**: Panel options work - users can customize appearance and changes apply immediately
@@ -189,16 +189,16 @@
189189
- [ ] T075 [P] Add plugin screenshots to src/img/ directory
190190
- [x] T076 [P] Create provisioning/dashboards/explain-example.json with sample dashboard
191191
- [x] T077 Add example queries to explain-example.json (simple scan, join, aggregation, CTE)
192-
- [X] T078 Verify bundle size is under 2MB requirement (npm run build, check dist/module.js)
193-
- [ ] T079 Verify no external CDN references in bundle (inspect dist/module.js source)
192+
- [x] T078 Verify bundle size is under 2MB requirement (npm run build, check dist/module.js)
193+
- [x] T079 Verify no external CDN references in bundle (inspect dist/module.js source)
194194
- [x] T080 Test plugin in local Grafana instance following quickstart.md
195195
- [x] T081 Test plugin with PostgreSQL data source and real EXPLAIN queries
196196
- [x] T082 Test plugin with TestData data source using CSV and JSON scenarios
197197
- [ ] T083 Test error states: NO_DATA, FIELD_NOT_FOUND, INVALID_FORMAT, PARSE_ERROR
198198
- [ ] T084 Verify CSP compliance (test in Grafana Cloud or with strict CSP settings)
199199
- [ ] T085 Run linter: npm run lint and fix any issues
200-
- [X] T086 Run formatter: npm run format
201-
- [X] T087 Build production bundle: npm run build
200+
- [x] T086 Run formatter: npm run format
201+
- [x] T087 Build production bundle: npm run build
202202
- [ ] T088 Generate plugin signing manifest if needed: npm run sign
203203
- [ ] T089 Create distribution package: zip -r dist.zip dist/ or npm run package
204204

src/components/ExplainPanel.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,6 @@ export const ExplainPanel: React.FC<Props> = ({
9898
<VueMount
9999
plan={result.plan}
100100
fontSize={options.fontSize}
101-
darkMode={options.darkMode}
102101
width={width}
103102
height={height}
104103
/>

src/components/VueMount.tsx

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ import { Plan as Pev2Plan } from "pev2";
1111
import { mountVueApp, unmountVueApp } from "../services/vueBootstrap";
1212
import { ExecutionPlan } from "../types/plan-types";
1313
import { logDebug } from "../utils/logger";
14-
import "bootstrap/dist/css/bootstrap.min.css";
14+
// Import scoped Bootstrap styles (only what PEV2 needs)
15+
import "../styles/bootstrap-scoped.css";
1516
import "pev2/dist/pev2.css";
1617
import "../styles/pev2-overrides.css";
1718

@@ -20,7 +21,6 @@ const CONTEXT = "VueMount";
2021
interface Props {
2122
plan: ExecutionPlan;
2223
fontSize?: number;
23-
darkMode?: boolean;
2424
width?: number;
2525
height?: number;
2626
}
@@ -34,7 +34,6 @@ interface Props {
3434
export const VueMount: React.FC<Props> = ({
3535
plan,
3636
fontSize = 14,
37-
darkMode = false,
3837
width,
3938
height,
4039
}) => {
@@ -48,7 +47,6 @@ export const VueMount: React.FC<Props> = ({
4847

4948
logDebug(CONTEXT, "Mounting PEV2 visualization", {
5049
fontSize,
51-
darkMode,
5250
width,
5351
height,
5452
});
@@ -65,11 +63,12 @@ export const VueMount: React.FC<Props> = ({
6563
// Convert plan to JSON string format that PEV2 expects
6664
const planSource = JSON.stringify(plan, null, 2);
6765
const planQuery = "";
68-
69-
return () => h(Pev2Plan, {
70-
planSource: planSource,
71-
planQuery: planQuery,
72-
});
66+
67+
return () =>
68+
h(Pev2Plan, {
69+
planSource: planSource,
70+
planQuery: planQuery,
71+
});
7372
},
7473
});
7574

@@ -85,19 +84,14 @@ export const VueMount: React.FC<Props> = ({
8584
containerRef.current.style.fontSize = `${fontSize}px`;
8685
}
8786

88-
// Apply dark mode styling
89-
if (containerRef.current && darkMode) {
90-
containerRef.current.classList.add("pev2-dark-mode");
91-
} else if (containerRef.current) {
92-
containerRef.current.classList.remove("pev2-dark-mode");
93-
}
94-
9587
// Ensure PEV2 fills the container height
9688
if (containerRef.current) {
97-
const pev2Container = containerRef.current.querySelector('.d-flex') as HTMLElement;
89+
const pev2Container = containerRef.current.querySelector(
90+
".d-flex",
91+
) as HTMLElement;
9892
if (pev2Container) {
99-
pev2Container.style.height = '100%';
100-
pev2Container.style.minHeight = '100%';
93+
pev2Container.style.height = "100%";
94+
pev2Container.style.minHeight = "100%";
10195
}
10296
}
10397
} catch (error) {
@@ -112,11 +106,12 @@ export const VueMount: React.FC<Props> = ({
112106
vueAppRef.current = null;
113107
}
114108
};
115-
}, [plan, fontSize, darkMode, width, height]);
109+
}, [plan, fontSize, width, height]);
116110

117111
return (
118112
<div
119113
ref={containerRef}
114+
className="pev2-panel-container"
120115
style={{
121116
width: "100%",
122117
height: "100%",

0 commit comments

Comments
 (0)