nexus-dev-toolkit 3.0.0__py3-none-any.whl

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.
@@ -0,0 +1,249 @@
1
+ # /scaffold
2
+
3
+ **Day 0 — Production Scaffold** (one-time project setup)
4
+
5
+ Generates a complete production-grade scaffold from the architecture document and Figma export.
6
+ Output: infrastructure + design system + UI shell + AGENTS.md + knowledge/.
7
+
8
+ **Goal: structure and standards, not live integrations.**
9
+ Day 0 prepares developers to follow golden paths and best practices from the very start.
10
+ Real auth providers, live databases, and external service integrations are Day 1.
11
+
12
+ - No business logic. No API wiring. No placeholder pages.
13
+ - **Auth = mock only** — login form redirects to dashboard, no real provider calls (no Supabase Auth, no NextAuth, no OAuth). Real auth is wired in Day 1.
14
+ - **Data = mock only** — all components use local mock data, no live DB queries.
15
+ - **No external service dependency** — the project must build and run without any credentials or services configured.
16
+ - The install + dev command must work out of the box (e.g. `npm install && npm run dev` for Next.js, `flutter pub get && flutter run` for Flutter).
17
+
18
+ ---
19
+
20
+ ## Prerequisites
21
+
22
+ Before running /scaffold:
23
+ 1. Architecture document must be in `docs/arch-docs/`
24
+ 2. Figma export ZIP must be available
25
+ 3. Run: `ingest_architecture_doc` MCP tool on `docs/arch-docs/`
26
+ 4. Run: `ingest_figma_zip` MCP tool on the Figma ZIP
27
+
28
+ ---
29
+
30
+ ## EVALUATE — Understand the Architecture and Design
31
+
32
+ Load `docs/arch-docs/` (ARCH doc + ADRs) and the Figma export. Then walk through:
33
+
34
+ **Architecture:**
35
+ 1. The stack decisions and why they were made
36
+ 2. The data model — tables, relationships, indexes
37
+ 3. What infrastructure is needed from the start
38
+ 4. The middleware stack and auth flow
39
+ 5. Error response format and error handling strategy
40
+ 6. Security rules and constraints
41
+
42
+ **Design:**
43
+ 7. Design tokens (colors, typography, spacing, radii, shadows)
44
+ 8. Component inventory (every component, variants, states)
45
+ 9. Layout patterns (grid, breakpoints, responsive behavior)
46
+ 10. Iconography (style, sizes, library)
47
+
48
+ **Design token conversion (before writing any design file):**
49
+ Figma exports colors in oklch or hex — never copy them raw. Convert to the target stack's native format:
50
+ - Web (Tailwind v4): `hsl()` — never oklch, hex, or rgb
51
+ - Flutter: `Color(0xFF...)` or generated `color_theme.dart`
52
+ - React Native: hex strings in a `colors.ts` theme file
53
+
54
+ Do NOT generate code yet. Produce an EVALUATE SUMMARY covering all 10 points.
55
+ Stop and wait for confirmation before proceeding to PLAN.
56
+
57
+ ---
58
+
59
+ ## PLAN — Boilerplate + UI Shell + Project Rules
60
+
61
+ Based on the architecture document and Figma design, plan four things:
62
+
63
+ **1. INFRASTRUCTURE BOILERPLATE**
64
+ - Project structure — every directory, annotated
65
+ - Database schema — from the architecture doc's data model
66
+ - Environment variables — complete list, documented
67
+ - Auth flow — as specified in the architecture
68
+ - Error handling — using the format from the architecture
69
+
70
+ **2. UI SHELL (from Figma)**
71
+ - Design system config (tailwind.config.ts, globals.css, CSS custom properties, font loading)
72
+ - Component architecture (name, path, props interface, variants, composition, accessibility)
73
+ - Page layouts (every page from the Figma, structured with placeholder data)
74
+ - Build order (component dependency chain)
75
+
76
+ **3. AGENTS.md (cross-tool project rules)**
77
+ - Project description and stack summary
78
+ - Backend and frontend coding standards
79
+ - Security rules, git conventions, quality gates
80
+
81
+ **4. KNOWLEDGE DIRECTORY STRUCTURE**
82
+ - `knowledge/rules/coding-standards.md`
83
+ - `knowledge/prompts/dev/` (initial prompt templates)
84
+ - `knowledge/patterns/` (implement-and-test chain)
85
+ - Design system spec saved to `knowledge/`
86
+
87
+ Output as a blueprint. No code yet.
88
+ Stop and wait for `/apply` approval before proceeding.
89
+
90
+ ---
91
+
92
+ ## APPLY — Generate the Complete Boilerplate
93
+
94
+ Plan approved. Generate everything in one scaffold.
95
+
96
+ **MANDATORY FIRST STEP — call `resolve_package_versions` before writing any file.**
97
+
98
+ `resolve_package_versions` runs the real package manager in a temp directory and returns exact pinned versions from the lock file. Use those exact versions in the manifest — no guessing, no ranges, no AI memory.
99
+
100
+ ```
101
+ Step 1 — call resolve_package_versions with all deps + stack hint from arch doc
102
+ packages: ["next@^16", "react@^19", "@supabase/supabase-js@^2", ...]
103
+ stack_hint: "Next.js 16 TypeScript" / "Flutter 3" / "Go" / etc.
104
+ → returns: { "versions": { "next": "16.2.9", "react": "19.2.7", ... } }
105
+
106
+ Step 2 — write the package manifest with EXACT versions from Step 1
107
+ npm: package.json — "next": "16.2.9" (no ^ or ~)
108
+ Flutter: pubspec.yaml — exact version constraints
109
+ Go: go.mod — exact module versions
110
+ Rust: Cargo.toml — exact versions
111
+
112
+ Step 3 — run the package manager to produce the lock file
113
+ npm install → package-lock.json
114
+ flutter pub get → pubspec.lock
115
+ go mod tidy → go.sum
116
+ cargo build → Cargo.lock
117
+ ```
118
+
119
+ NEVER write "latest" in any manifest.
120
+ NEVER write semver ranges (^ or ~) in the final manifest.
121
+ NEVER write patch versions from AI memory — training data is always stale.
122
+
123
+ **1. Infrastructure:**
124
+ - `.gitignore` — node_modules, .env*, build outputs, OS files
125
+ - `.env.example` — all variables documented, no real secrets
126
+ - Initial migration — exact schema from arch doc
127
+ - Auth middleware — as specified
128
+ - Error handler — consistent format from arch doc
129
+ - Health-check endpoint
130
+ - Seed script — idempotent test data
131
+ - Linter + formatter config (stack-appropriate: ESLint + Prettier for JS/TS; gofmt + golangci-lint for Go; clippy for Rust; dart format for Flutter)
132
+ - Pre-commit hooks (stack-appropriate):
133
+ - **npm:** husky + lint-staged + commitlint
134
+ - `package.json` must have `"prepare": "husky"` in scripts
135
+ - Write `.husky/pre-commit` with `npx lint-staged`, then `chmod +x .husky/pre-commit`
136
+ - Write `.lintstagedrc.json` (lint + format on staged files)
137
+ - Write `.commitlintrc.json` with `@commitlint/config-conventional`
138
+ - CI pipeline must set `HUSKY=0` env var — husky fails in CI without a git repo
139
+ - **Python:** pre-commit framework with `.pre-commit-config.yaml`
140
+ - **Go / Rust / Java:** git hooks via Makefile or pre-commit framework
141
+ - README with local setup instructions
142
+ - CI pipeline config (GitHub Actions or equivalent: lint, typecheck, test, db push)
143
+
144
+ **2. UI shell (matching Figma exactly):**
145
+ - Design system config (tailwind.config.ts, globals.css — tokens from Figma)
146
+ - All components with TypeScript props and ALL visual states:
147
+ (default, hover, focus, disabled, loading, empty, error)
148
+ - All page layouts responsive to Figma breakpoints
149
+ - Semantic HTML + ARIA attributes throughout
150
+ - Placeholder/mock data — NOT real API calls
151
+ - Prop interfaces defined so Day 1 can wire real data without changing the component
152
+
153
+ **3. AGENTS.md at project root**
154
+
155
+ **4. knowledge/ directory with initial content**
156
+
157
+ **Package requirements:**
158
+ - Exact versions from `resolve_package_versions` — not from memory, not ranges
159
+ - NEVER write "latest" — it is not a version
160
+ - NEVER write patch versions from AI memory
161
+ - Run the package manager after writing the manifest to produce the lock file
162
+ - No beta, canary, or RC packages
163
+ - No deprecated packages or APIs
164
+
165
+ **Production-grade standards:**
166
+ - No placeholder pages or unused dependencies
167
+ - Auth protecting all routes that need it
168
+ - Consistent error response format throughout
169
+ - Proper logging setup (not console.log)
170
+ - Environment-based configuration (dev/staging/prod)
171
+ - Security headers configured (next.config.ts for Next.js, equivalent for other stacks)
172
+ - Database connection pooling (use pooler URL, not direct)
173
+
174
+ **Next.js 16 specifics:**
175
+ - Route proxy file is `proxy.ts` not `middleware.ts` — export function `proxy`, not `middleware`
176
+ - `tsconfig.json` must use `"jsx": "react-jsx"` not `"jsx": "preserve"`
177
+
178
+ **Do NOT implement:**
179
+ - Real auth provider integration (Supabase Auth, NextAuth, OAuth, etc.)
180
+ - Live database queries or mutations
181
+ - External service calls (email, storage, payment, etc.)
182
+ - API endpoints or business logic beyond health check
183
+ - Data fetching, form submissions, or backend interactions
184
+ - Dev tasks from the CSV — that is Day 1
185
+
186
+ **Mock auth pattern:**
187
+ The login page accepts any input and sets a session cookie (preferred over localStorage — cookies are readable server-side for route guarding). No credentials checked.
188
+ - Cookie holds the user's mock role (e.g. `mock-role=admin`), 8h expiry
189
+ - Route guard (middleware/proxy) reads the cookie and redirects unauthenticated requests to login
190
+ - Server components read the cookie to get the current session (no Context provider needed)
191
+ - All role-gating uses the mock role value — no JWT, no OAuth token
192
+ Real auth provider replaces the cookie on Day 1.
193
+
194
+ Output as complete files. The install + dev command must work (e.g. `npm install && npm run dev` for Next.js, `flutter pub get && flutter run` for Flutter).
195
+
196
+ ---
197
+
198
+ ## VALIDATE — Validate Infrastructure + Design Fidelity
199
+
200
+ **MANDATORY FIRST STEP — run the build. VALIDATE is not started until this passes.**
201
+
202
+ Use the build command for the stack prescribed in the arch doc:
203
+
204
+ | Stack | Build command |
205
+ |---|---|
206
+ | Next.js | `npm run build` |
207
+ | Vite / React | `npm run build` |
208
+ | Flutter | `flutter build apk --debug` |
209
+ | Go | `go build ./...` |
210
+ | Rust | `cargo build` |
211
+ | Java / Spring | `mvn package -DskipTests` |
212
+
213
+ If the build fails, fix ALL errors before running any other checks. Do not proceed to the checklist until the build exits with code 0. A failed build is an automatic [BLOCKER] that overrides everything else.
214
+
215
+ ---
216
+
217
+ Review everything against the architecture doc AND Figma.
218
+
219
+ **Packages:**
220
+ 1. Are all dependencies on stable versions (no beta/canary/RC)?
221
+ 2. Any deprecated packages or APIs in use?
222
+ 3. Are versions pinned exactly in the lock file (package-lock.json / pubspec.lock / go.sum / Cargo.lock)?
223
+ 4. Any known security vulnerabilities? (npm audit / flutter pub audit / cargo audit / etc.)
224
+
225
+ **Infrastructure:**
226
+ 5. Does the project structure match the architecture?
227
+ 6. Does the schema match the data model?
228
+ 7. Are all env vars from the architecture doc present?
229
+ 8. Is logging production-grade (not console.log)?
230
+ 9. Are security headers and CORS configured?
231
+ 10. Is database connection pooling set up?
232
+
233
+ **UI fidelity:**
234
+ 11. Do components match the Figma design?
235
+ 12. Responsive at 320px, 768px, 1024px, 1440px?
236
+ 13. All visual states render with placeholder data?
237
+ 14. Accessibility — keyboard nav, WCAG AA contrast?
238
+ 15. Prop interfaces typed for Day 1 wiring?
239
+ 16. No business logic or API calls in components?
240
+
241
+ **AGENTS.md + knowledge directory:**
242
+ 17. Coding standards match the architecture?
243
+ 18. Design system spec saved to knowledge/?
244
+
245
+ **Git hygiene:**
246
+ 19. Pre-commit hooks configured and working? (husky executable + lint-staged for npm; equivalent for other stacks)
247
+
248
+ Classify every issue: [BLOCKER] / [FIX NOW] / [BACKLOG]
249
+ Fix every [BLOCKER] and [FIX NOW] before calling Day 0 complete.
@@ -0,0 +1,57 @@
1
+ # /validate
2
+
3
+ **VALIDATE** — Step 4 of the E→P→A→V cycle. Verify the implementation before calling it done.
4
+
5
+ ## Prerequisite
6
+
7
+ APPLY must be complete.
8
+
9
+ ## Steps
10
+
11
+ ### 1 — graphify blast radius check
12
+
13
+ ```bash
14
+ graphify query "<what we just built>"
15
+ ```
16
+
17
+ Check: does anything that references the changed files now behave unexpectedly? Flag any community boundary crossings that weren't in the plan.
18
+
19
+ ### 2 — Check against acceptance criteria
20
+
21
+ Load the acceptance criteria from the CSV task (or EVALUATE summary). For each criterion:
22
+
23
+ ```
24
+ [ ] <criterion> — PASS / FAIL / PARTIAL
25
+ ```
26
+
27
+ ### 3 — Classify all issues found
28
+
29
+ ```
30
+ [BLOCKER] — prevents merge, must fix now
31
+ [FIX NOW] — significant issue, fix before moving to next task
32
+ [BACKLOG] — minor, log to knowledge/retros/ and defer
33
+ ```
34
+
35
+ ### 4 — Fix all BLOCKERs and FIX NOWs before continuing
36
+
37
+ Do not move to the next task until the implementation passes all acceptance criteria.
38
+
39
+ ### 5 — If a pattern was discovered, contribute it back
40
+
41
+ If APPLY revealed a better approach or a non-obvious constraint:
42
+
43
+ ```bash
44
+ # Append to knowledge/patterns/ or knowledge/rules/coding-standards.md
45
+ ```
46
+
47
+ ### 6 — When clean
48
+
49
+ ```
50
+ VALIDATE COMPLETE
51
+ ─────────────────
52
+ Criteria passed: N/N
53
+ Issues fixed: <list>
54
+ Backlog items: <list added to knowledge/retros/>
55
+ ```
56
+
57
+ > "Task complete. Ready for the next `/evaluate`."
@@ -0,0 +1,140 @@
1
+ import csv
2
+ import json
3
+ import logging
4
+ import subprocess
5
+ from pathlib import Path
6
+
7
+ from mcp.server.fastmcp import FastMCP
8
+
9
+ logger = logging.getLogger(__name__)
10
+
11
+ _TASK_FIELDS = ["task_id", "user_story", "description", "acceptance_criteria", "dependencies"]
12
+
13
+
14
+ def _find_csv(hint: str) -> Path | None:
15
+ """Locate a CSV task file from a path hint or by scanning docs/dev-tasks/."""
16
+ p = Path(hint)
17
+ if p.exists() and p.suffix == ".csv":
18
+ return p
19
+ dev_tasks = Path("docs/dev-tasks")
20
+ if dev_tasks.exists():
21
+ candidates = sorted(dev_tasks.rglob("*.csv"))
22
+ if hint:
23
+ matched = [c for c in candidates if hint.lower() in c.name.lower()]
24
+ if matched:
25
+ return matched[0]
26
+ if candidates:
27
+ return candidates[0]
28
+ return None
29
+
30
+
31
+ def _run_graphify_query(description: str) -> str | None:
32
+ """Run graphify query if a graph exists. Returns output or None."""
33
+ if not Path("graphify-out/graph.json").exists():
34
+ return None
35
+ try:
36
+ result = subprocess.run(
37
+ ["graphify", "query", description[:200]],
38
+ capture_output=True, text=True, timeout=30,
39
+ )
40
+ return result.stdout.strip() if result.returncode == 0 else None
41
+ except Exception as e:
42
+ logger.warning("graphify query failed: %s", e)
43
+ return None
44
+
45
+
46
+ def register_task_loader_tool(mcp: FastMCP) -> None:
47
+
48
+ @mcp.tool()
49
+ async def load_task(
50
+ csv_path: str = "",
51
+ task_id: str = "",
52
+ row_index: int = 0,
53
+ ) -> str:
54
+ """
55
+ Load a dev task from a CSV file and structure it for the EVALUATE step.
56
+
57
+ Reads a task CSV (one row per task with fields: task_id, user_story,
58
+ description, acceptance_criteria, dependencies). Optionally runs a
59
+ graphify query on the task description to surface blast radius context.
60
+
61
+ Args:
62
+ csv_path: Path to the CSV file, or a name fragment to search in
63
+ docs/dev-tasks/. If empty, uses the first CSV found there.
64
+ task_id: Match a specific task_id value in the CSV. Takes priority
65
+ over row_index.
66
+ row_index: Zero-based row index to load if task_id is not provided.
67
+
68
+ Returns:
69
+ JSON with structured task context ready for /evaluate, including
70
+ graphify blast radius if a graph exists.
71
+ """
72
+ try:
73
+ csv_file = _find_csv(csv_path)
74
+ if not csv_file:
75
+ return json.dumps({
76
+ "error": "No CSV task file found. Provide csv_path or create docs/dev-tasks/ "
77
+ "with your task CSVs."
78
+ })
79
+
80
+ rows: list[dict] = []
81
+ with csv_file.open(encoding="utf-8-sig") as f:
82
+ reader = csv.DictReader(f)
83
+ rows = list(reader)
84
+
85
+ if not rows:
86
+ return json.dumps({"error": f"CSV is empty: {csv_file}"})
87
+
88
+ # Find the target row
89
+ task: dict | None = None
90
+ if task_id:
91
+ task = next(
92
+ (r for r in rows if r.get("task_id", "").strip() == task_id.strip()),
93
+ None,
94
+ )
95
+ if not task:
96
+ return json.dumps({
97
+ "error": f"task_id '{task_id}' not found in {csv_file}",
98
+ "available_ids": [r.get("task_id", "") for r in rows[:20]],
99
+ })
100
+ else:
101
+ if row_index >= len(rows):
102
+ return json.dumps({
103
+ "error": f"row_index {row_index} out of range (CSV has {len(rows)} rows)"
104
+ })
105
+ task = rows[row_index]
106
+
107
+ # Extract standard EPAV fields (graceful if columns differ)
108
+ context = {f: task.get(f, "").strip() for f in _TASK_FIELDS}
109
+ context["_csv_file"] = str(csv_file)
110
+ context["_all_fields"] = dict(task)
111
+
112
+ # Graphify blast radius
113
+ description = context.get("description") or context.get("user_story", "")
114
+ blast_radius = _run_graphify_query(description)
115
+ if blast_radius:
116
+ context["blast_radius"] = blast_radius
117
+
118
+ # Human-readable EVALUATE block
119
+ evaluate_block = [
120
+ "TASK CONTEXT (ready for /evaluate)",
121
+ "─" * 40,
122
+ f"Task ID: {context.get('task_id', '(none)')}",
123
+ f"User story: {context.get('user_story', '(none)')}",
124
+ "",
125
+ f"Description:\n{context.get('description', '(none)')}",
126
+ "",
127
+ f"Acceptance criteria:\n{context.get('acceptance_criteria', '(none)')}",
128
+ "",
129
+ f"Dependencies: {context.get('dependencies', 'none')}",
130
+ ]
131
+ if blast_radius:
132
+ evaluate_block += ["", "Graphify blast radius:", blast_radius[:800]]
133
+
134
+ context["evaluate_block"] = "\n".join(evaluate_block)
135
+
136
+ return json.dumps(context, indent=2)
137
+
138
+ except Exception as e:
139
+ logger.exception("Unexpected error in load_task")
140
+ return json.dumps({"error": f"Unexpected error: {e}"})