chore: add coding standards (ESLint, Prettier), theme check script, and gated workflow documentation
This commit is contained in:
@@ -0,0 +1,82 @@
|
|||||||
|
# Gated Development Workflow
|
||||||
|
|
||||||
|
Each phase must be completed and signed off before the next phase begins.
|
||||||
|
The gatekeeper is the stakeholder (Shreyas Kamat) unless otherwise noted.
|
||||||
|
|
||||||
|
## 1. Ideation (Steve)
|
||||||
|
- **Goal:** Capture high‑level requirements and success criteria.
|
||||||
|
- **Entry:** None (project kickoff).
|
||||||
|
- **Exit:** Approved PRD outline (stakeholder sign‑off).
|
||||||
|
- **Artifact:** PRD draft in `.hermes/plans/`.
|
||||||
|
- **Verification:** Stakeholder confirms requirements are complete.
|
||||||
|
|
||||||
|
## 2. PRD Documentation (Turing)
|
||||||
|
- **Goal:** Expand ideas into a formal Product Requirements Document.
|
||||||
|
- **Entry:** Approved Ideation output.
|
||||||
|
- **Exit:** PRD approved by stakeholder.
|
||||||
|
- **Artifact:** `.hermes/plans/PRD-<date>-<slug>.md`
|
||||||
|
- **Verification:** Stakeholder review & sign‑off.
|
||||||
|
|
||||||
|
## 3. Design & Planning (Ada)
|
||||||
|
- **Goal:** Produce technical design (SAD) and implementation plan.
|
||||||
|
- **Entry:** Approved PRD.
|
||||||
|
- **Exit:** Approved Technical Plan (this document) and SAD.
|
||||||
|
- **Artifacts:**
|
||||||
|
- Technical Plan (`.hermes/plans/<timestamp>-<slug>.md`)
|
||||||
|
- Solution Architecture Document (`.hermes/docs/SAD-<date>-<slug>.md`)
|
||||||
|
- **Verification:** Stakeholder reviews both documents; sign‑off required.
|
||||||
|
|
||||||
|
## 4. Orchestration (Woz)
|
||||||
|
- **Goal:** Break technical plan into bite‑sized tasks and assign to specialist agents.
|
||||||
|
- **Entry:** Approved Technical Plan & SAD.
|
||||||
|
- **Exit:** Task backlog ready for development (each task 2‑5 min).
|
||||||
|
- **Artifact:** Task list in `.hermes/plans/` or a Kanban board (if used).
|
||||||
|
- **Verification:** Woz confirms each task is clear, estimable, and independent.
|
||||||
|
|
||||||
|
## 5. Development (Specialists: Linus, Sergey, Zaha, Craig, Gilfoyle, etc.)
|
||||||
|
- **Goal:** Implement tasks using TDD and strict adherence to coding standards.
|
||||||
|
- **Entry:** Task backlog from Orchestration.
|
||||||
|
- **Exit:** All tasks completed, code passes lint, tests, and security review.
|
||||||
|
- **Artifacts:**
|
||||||
|
- Feature branches with incremental commits.
|
||||||
|
- Unit/test files alongside source.
|
||||||
|
- **Verification:**
|
||||||
|
- **Spec Compliance Review** (Satya) – each task must satisfy its acceptance criteria.
|
||||||
|
- **Code Quality Review** (Sundar) – lint passes, tests pass, security scan clean.
|
||||||
|
- **Gilfoyle Security Review** – embedded from first commit; any security finding blocks progress.
|
||||||
|
|
||||||
|
## 6. Independent Review (Satya & Sundar)
|
||||||
|
- **Goal:** Objective evaluation of the completed implementation.
|
||||||
|
- **Entry:** Development complete, all tests pass, lint clean.
|
||||||
|
- **Exit:** Review sign‑off from both specialists.
|
||||||
|
- **Artifacts:** Review reports (`.hermes/reviews/<date>-<feature>.md`).
|
||||||
|
- **Verification:** No open critical issues; all review comments addressed.
|
||||||
|
|
||||||
|
## 7. Deployment (Jenson)
|
||||||
|
- **Goal:** Release the artifact to the target environment (local testing server/Gitea).
|
||||||
|
- **Entry:** Review sign‑off obtained.
|
||||||
|
- **Exit:** Application deployed and smoke‑tested.
|
||||||
|
- **Artifacts:** Deployment log, built assets in `dist/`, Gitea repo update.
|
||||||
|
- **Verification:** Stakeholder performs final sanity check; gives go/no‑go.
|
||||||
|
|
||||||
|
## 8. Post‑Deployment Monitoring (Optional)
|
||||||
|
- **Goal:** Capture feedback and log any issues for next iteration.
|
||||||
|
- **Entry:** Deployment complete.
|
||||||
|
- **Exit:** Stakeholder accepts product or opens new issues.
|
||||||
|
- **Artifact:** Feedback log.
|
||||||
|
|
||||||
|
### Gate Enforcement Mechanisms
|
||||||
|
- **Coding Standards:** Enforced via `lint-staged` + husky pre‑commit; CI runs `npm run lint` and `npm run theme-check`.
|
||||||
|
- **Security:** Gilfoyle’s review is triggered automatically on each PR via label‑based workflow (or manual checkpoint) – no merge without his approval.
|
||||||
|
- **Theme:** `npm run theme-check` runs in CI; failure blocks merge.
|
||||||
|
- **Documentation:** Each phase requires a markdown artifact stored under `.hermes/plans/` or `.hermes/docs/`; missing artifact blocks progression.
|
||||||
|
|
||||||
|
### Definition of Done (DoD) for a Task
|
||||||
|
1. Code written and passes ESLint + Prettier.
|
||||||
|
2. Unit test written (if applicable) and passes.
|
||||||
|
3. Commit message follows conventional format (`feat:`, `fix:`, `chore:`).
|
||||||
|
4. No lint or theme‑check warnings.
|
||||||
|
5. Security scan clean (Gilfoyle’s checklist).
|
||||||
|
6. Specification acceptance criteria met (verified by Satya).
|
||||||
|
7. Code reviewed and approved by Sundar.
|
||||||
|
8. Change merged to `main` only after all gates satisfied.
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"semi": true,
|
||||||
|
"trailingComma": "es5",
|
||||||
|
"singleQuote": true,
|
||||||
|
"printWidth": 100,
|
||||||
|
"tabWidth": 2
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import globals from 'globals';
|
||||||
|
import pluginJs from '@eslint/js';
|
||||||
|
import pluginReact from 'eslint-plugin-react';
|
||||||
|
import pluginSecurity from 'eslint-plugin-security';
|
||||||
|
import babelParser from '@babel/eslint-parser';
|
||||||
|
|
||||||
|
export default [
|
||||||
|
{ ignores: ['node_modules/', 'dist/'] },
|
||||||
|
{
|
||||||
|
files: ['**/*.js', '**/*.jsx'],
|
||||||
|
languageOptions: {
|
||||||
|
parser: babelParser,
|
||||||
|
parserOptions: {
|
||||||
|
ecmaVersion: 2021,
|
||||||
|
sourceType: 'module',
|
||||||
|
ecmaFeatures: {
|
||||||
|
jsx: true,
|
||||||
|
},
|
||||||
|
requireConfigFile: false,
|
||||||
|
babelOptions: {
|
||||||
|
presets: ['@babel/preset-react']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
...globals.es2021,
|
||||||
|
...globals.node,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
plugins: {
|
||||||
|
react: pluginReact,
|
||||||
|
security: pluginSecurity,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...pluginJs.configs.recommended.rules,
|
||||||
|
...pluginReact.configs.recommended.rules,
|
||||||
|
...pluginSecurity.configs.recommended.rules,
|
||||||
|
'no-var': 'error',
|
||||||
|
'prefer-const': 'error',
|
||||||
|
'eqeqeq': ['error', 'always'],
|
||||||
|
'no-unused-vars': ['error', { argsIgnorePattern: '^_' }],
|
||||||
|
'react/react-in-jsx-scope': 'off', // React 17+
|
||||||
|
'security/detect-object-injection': 'error',
|
||||||
|
'security/detect-non-literal-fs-filename': 'error',
|
||||||
|
},
|
||||||
|
settings: {
|
||||||
|
react: {
|
||||||
|
version: 'detect',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
||||||
Generated
+4969
-858
File diff suppressed because it is too large
Load Diff
+31
-3
@@ -6,15 +6,43 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"preview": "vite preview"
|
"preview": "vite preview",
|
||||||
|
"lint": "eslint src --ext .js,.jsx,.ts,.tsx",
|
||||||
|
"format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,css,md}\"",
|
||||||
|
"prepare": "husky install",
|
||||||
|
"theme-check": "node src/theme/theme-check.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"framer-motion": "^10.12.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0"
|
||||||
"framer-motion": "^10.12.0"
|
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/eslint-parser": "^8.0.1",
|
||||||
|
"@babel/preset-react": "^8.0.1",
|
||||||
"@vitejs/plugin-react": "^4.0.0",
|
"@vitejs/plugin-react": "^4.0.0",
|
||||||
|
"eslint": "^9.39.5",
|
||||||
|
"eslint-plugin-react": "^7.37.5",
|
||||||
|
"eslint-plugin-security": "^4.0.1",
|
||||||
|
"husky": "^9.1.7",
|
||||||
|
"lint-staged": "^17.2.0",
|
||||||
|
"prettier": "^3.9.6",
|
||||||
|
"prop-types": "^15.8.1",
|
||||||
"vite": "^4.3.0"
|
"vite": "^4.3.0"
|
||||||
|
},
|
||||||
|
"husky": {
|
||||||
|
"hooks": {
|
||||||
|
"pre-commit": "lint-staged"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"lint-staged": {
|
||||||
|
"*.{js,jsx,ts,tsx}": [
|
||||||
|
"eslint --fix",
|
||||||
|
"prettier --write"
|
||||||
|
],
|
||||||
|
"*.{css,md}": [
|
||||||
|
"prettier --write"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"type": "module"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
:root {
|
||||||
|
--bg-primary: #121212;
|
||||||
|
--text-primary: #E0E0E0;
|
||||||
|
--accent: #FF9800;
|
||||||
|
/* Light-mode overrides are intentionally omitted */
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
const rootCss = fs.readFileSync(path.join(import.meta.dirname, 'dark-only.css'), 'utf8');
|
||||||
|
const lightPatterns = [/background:\s*#ffffff/i, /color:\s*#000000/i, /--bg-primary\s*:\s*#ffffff/i];
|
||||||
|
const files = [];
|
||||||
|
function collectFiles(dir) {
|
||||||
|
const items = fs.readdirSync(dir, { withFileTypes: true });
|
||||||
|
for (const item of items) {
|
||||||
|
const full = path.join(dir, item.name);
|
||||||
|
if (item.isDirectory()) collectFiles(full);
|
||||||
|
else if (item.name.endsWith('.css') || item.name.endsWith('.js') || item.name.endsWith('.jsx')) files.push(full);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
collectFiles(path.join(import.meta.dirname, '..')); // src directory
|
||||||
|
const violations = [];
|
||||||
|
for (const file of files) {
|
||||||
|
const content = fs.readFileSync(file, 'utf8');
|
||||||
|
for (const pattern of lightPatterns) {
|
||||||
|
if (pattern.test(content)) violations.push(`${file}: light-mode pattern detected`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (violations.length) {
|
||||||
|
console.error('Theme violation detected (light-mode styles found):');
|
||||||
|
violations.forEach(v => console.error(' -', v));
|
||||||
|
process.exit(1);
|
||||||
|
} else {
|
||||||
|
console.log('✅ Theme check passed – only dark-mode variables used.');
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user