codeninja 2.0.0 → 3.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.
Files changed (46) hide show
  1. package/README.md +122 -251
  2. package/agent/global-agent.md +8 -0
  3. package/cli.js +248 -223
  4. package/commands/debug.workflow.md +94 -0
  5. package/commands/explain.workflow.md +59 -0
  6. package/commands/optimize.workflow.md +124 -0
  7. package/commands/review.workflow.md +85 -0
  8. package/ide/antigravity/.agents/personas/database-architect.md +249 -0
  9. package/ide/antigravity/.agents/personas/global-orchestrator.md +144 -0
  10. package/ide/antigravity/.agents/personas/nodejs-backend.md +250 -0
  11. package/ide/antigravity/.agents/personas/reactjs-frontend.md +179 -0
  12. package/ide/antigravity/.agents/skills/api-builder/SKILL.md +179 -0
  13. package/ide/antigravity/.agents/skills/code-intelligence/SKILL.md +184 -0
  14. package/ide/antigravity/.agents/skills/database/SKILL.md +165 -0
  15. package/ide/antigravity/.agents/skills/mcp-and-context/SKILL.md +111 -0
  16. package/ide/antigravity/.agents/skills/reactjs/SKILL.md +211 -0
  17. package/ide/antigravity/.agents/workflows/codeninja-api.md +111 -0
  18. package/ide/antigravity/.agents/workflows/codeninja-audit.md +81 -0
  19. package/ide/antigravity/.agents/workflows/codeninja-db-create.md +124 -0
  20. package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +87 -0
  21. package/ide/antigravity/.agents/workflows/codeninja-db-index.md +70 -0
  22. package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +106 -0
  23. package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +76 -0
  24. package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +70 -0
  25. package/ide/antigravity/.agents/workflows/codeninja-debug.md +82 -0
  26. package/ide/antigravity/.agents/workflows/codeninja-design.md +54 -0
  27. package/ide/antigravity/.agents/workflows/codeninja-explain.md +40 -0
  28. package/ide/antigravity/.agents/workflows/codeninja-init.md +336 -0
  29. package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +336 -0
  30. package/ide/antigravity/.agents/workflows/codeninja-modularize.md +216 -0
  31. package/ide/antigravity/.agents/workflows/codeninja-optimize.md +84 -0
  32. package/ide/antigravity/.agents/workflows/codeninja-refactor.md +68 -0
  33. package/ide/antigravity/.agents/workflows/codeninja-review.md +70 -0
  34. package/ide/antigravity/.agents/workflows/codeninja-sync.md +183 -0
  35. package/ide/antigravity/.agents/workflows/codeninja-test.md +61 -0
  36. package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +250 -0
  37. package/ide/cursor/.cursor/mcp.json +8 -0
  38. package/ide/cursor/.cursor/rules/01-global-orchestrator.mdc +63 -0
  39. package/ide/cursor/.cursor/rules/02-mcp-and-context.mdc +38 -0
  40. package/ide/cursor/.cursor/rules/03-api-builder.mdc +124 -0
  41. package/ide/cursor/.cursor/rules/04-database.mdc +90 -0
  42. package/ide/cursor/.cursor/rules/05-reactjs.mdc +147 -0
  43. package/ide/cursor/.cursor/rules/06-code-intelligence.mdc +112 -0
  44. package/ide/vscode/.github/copilot-instructions.md +399 -0
  45. package/ide/vscode/.vscode/mcp.json +9 -0
  46. package/package.json +24 -23
@@ -0,0 +1,216 @@
1
+ ---
2
+ slash_command: /codeninja:modularize
3
+ personas: [global-orchestrator, reactjs-frontend]
4
+ skills: [mcp-and-context, reactjs, code-intelligence]
5
+ description: >
6
+ Scan ReactJS pages, extract repeated layout blocks into reusable components
7
+ under src/components/, and update each page to import and use them.
8
+ Layout structure only — never touches business logic, state, or API calls.
9
+ ---
10
+
11
+ # /codeninja:modularize
12
+
13
+ ## Before Running
14
+ 1. Call `context_check_stale`
15
+ 2. Call `context_read` — load `context.services` to find ReactJS services
16
+ 3. Call `service_scan` — verify ReactJS service exists on disk
17
+
18
+ ## Rules
19
+ - Read ALL target pages fully before creating any component
20
+ - NEVER create a component that already exists in `src/components/` — reuse it
21
+ - NEVER modify business logic, state, API calls, or event handlers in any page
22
+ - NEVER break existing imports or prop flows
23
+ - ONE confirmation before any file is written
24
+ - After writing files → call `context_write`
25
+
26
+ ---
27
+
28
+ ## Execution — Full Step-by-Step
29
+
30
+ ### Phase 1 — Target Selection
31
+
32
+ **Step 1.** Ask: "Which ReactJS service?" (list ReactJS services from `context.services`)
33
+ - Store: `context.current_action.service_name`
34
+
35
+ **Step 2.** Ask: "What scope?"
36
+ 1. All pages — scan every page in `src/pages/` and `src/views/`
37
+ 2. Specific page — I'll provide the path
38
+ - Store: `context.current_action.modularize_scope`
39
+ - If specific → also ask: "Page path?" → Store: `context.current_action.page_path`
40
+
41
+ ---
42
+
43
+ ### Phase 2 — Inventory Existing Components
44
+
45
+ Before scanning any pages, inventory what already exists:
46
+
47
+ **Step 1.** Scan `src/components/` in the target service.
48
+ For each subdirectory → record component name and file path.
49
+
50
+ **Step 2.** For each existing component:
51
+ - Read the file
52
+ - Identify structural role: header, footer, sidebar, navbar, modal wrapper, card shell, breadcrumbs, etc.
53
+ - Record: `{ name, path, role, props_accepted }`
54
+
55
+ Store this as the "existing components registry" — the source of truth for reuse decisions.
56
+
57
+ ---
58
+
59
+ ### Phase 3 — Scan Target Pages
60
+
61
+ #### If scope == "all":
62
+ Scan `src/pages/` — each subdirectory with `index.jsx` or `index.js` = one page.
63
+ Also scan `src/views/` if it exists.
64
+
65
+ #### If scope == "specific":
66
+ Pages list = [ context.current_action.page_path ]
67
+
68
+ For each page:
69
+
70
+ **Step 1.** Read the full file content.
71
+
72
+ **Step 2.** Identify all structural blocks (layout HTML — NOT business logic):
73
+ - Look for repeated layout patterns: `<header>`, `<nav>`, `<footer>`, `<aside>`, sidebar wrappers
74
+ - Look for structural patterns repeated across pages: top nav bars, breadcrumb areas, page wrappers
75
+ - Record each structural block as: `{ block_type, jsx_content, props_needed }`
76
+
77
+ **Step 3.** Cross-check against existing components registry:
78
+ - Does a component already exist that covers this block?
79
+ - If YES → mark as "reuse existing: <ComponentName>"
80
+ - If NO → mark as "new component needed: <ComponentName>"
81
+
82
+ ---
83
+
84
+ ### Phase 4 — Deduplicate Across Pages
85
+
86
+ After scanning all pages:
87
+
88
+ **Step 1.** Group blocks by structural similarity across pages.
89
+ - If the same header JSX appears in 3+ pages → one shared Header component
90
+ - If a sidebar appears in 2+ pages → one shared Sidebar component
91
+ - If a block appears in only 1 page → do NOT extract it (no duplication benefit)
92
+
93
+ **Step 2.** For each component to create, decide:
94
+ - Component name (PascalCase, descriptive: `PageHeader`, `AppSidebar`, `MainFooter`)
95
+ - Props needed (what varies between pages: title, navLinks, userName, etc.)
96
+ - File location: `src/components/<ComponentName>/index.jsx` and `<ComponentName>.module.css`
97
+
98
+ ---
99
+
100
+ ### Phase 5 — Show Extraction Plan
101
+
102
+ Display the plan before writing anything:
103
+
104
+ ```
105
+ ┌─────────────────────────────────────────────────────┐
106
+ │ MODULARIZE PLAN │
107
+ ├─────────────────────────────────────────────────────┤
108
+ │ Service : [service_name] │
109
+ │ Scope : [all pages | specific page] │
110
+ │ Pages : [n] scanned │
111
+ ├─────────────────────────────────────────────────────┤
112
+ │ COMPONENTS TO CREATE │
113
+ │ ✦ AppHeader — appears in [n] pages │
114
+ │ Props: title (string) │
115
+ │ File: src/components/AppHeader/index.jsx │
116
+ │ │
117
+ │ ✦ MainSidebar — appears in [n] pages │
118
+ │ Props: activeRoute (string) │
119
+ │ File: src/components/MainSidebar/index.jsx │
120
+ ├─────────────────────────────────────────────────────┤
121
+ │ COMPONENTS REUSED (already exist) │
122
+ │ ✓ Footer — src/components/Footer/index.jsx │
123
+ ├─────────────────────────────────────────────────────┤
124
+ │ PAGES TO UPDATE │
125
+ │ → src/pages/Dashboard/index.jsx │
126
+ │ → src/pages/Profile/index.jsx │
127
+ │ → src/pages/Settings/index.jsx │
128
+ └─────────────────────────────────────────────────────┘
129
+ ```
130
+
131
+ Ask: "Apply this plan? (yes / no / adjust)"
132
+ - If yes → proceed to Phase 6
133
+ - If no → abort, nothing written
134
+ - If adjust → ask what to change → re-display plan
135
+
136
+ ---
137
+
138
+ ### Phase 6 — Generate Components
139
+
140
+ For each new component:
141
+
142
+ **Step 1.** Generate `src/components/<ComponentName>/index.jsx`:
143
+ ```jsx
144
+ /**
145
+ * <ComponentName> — <one-line description of structural role>.
146
+ *
147
+ * @param {Object} props
148
+ * @param {string} props.<propName> - <description>
149
+ * @returns {JSX.Element}
150
+ */
151
+ function <ComponentName>({ <props> }) {
152
+ return (
153
+ <extracted JSX block, using props where values varied>
154
+ );
155
+ }
156
+
157
+ export default <ComponentName>;
158
+ ```
159
+
160
+ **Step 2.** Generate `src/components/<ComponentName>/<ComponentName>.module.css`:
161
+ - Extract any inline styles or className references that were in the original block
162
+ - Create CSS classes for them
163
+ - If no styles → empty file with a comment: `/* <ComponentName> styles */`
164
+
165
+ ---
166
+
167
+ ### Phase 7 — Update Pages
168
+
169
+ For each page that used the extracted block:
170
+
171
+ **Step 1.** Read the current page file.
172
+
173
+ **Step 2.** Apply changes surgically:
174
+ 1. Add import at top of file:
175
+ ```jsx
176
+ import <ComponentName> from '../../components/<ComponentName>';
177
+ ```
178
+ (adjust relative path based on page depth)
179
+
180
+ 2. Replace the extracted JSX block with the component:
181
+ ```jsx
182
+ <ComponentName <prop>={<value>} />
183
+ ```
184
+
185
+ 3. Remove any now-unused imports that were only used by the extracted block.
186
+
187
+ 4. Remove any CSS classes in the page's `.module.css` that are now handled by the component's own CSS file.
188
+
189
+ **Step 3.** Write the updated file.
190
+
191
+ ---
192
+
193
+ ### Phase 8 — Finalize
194
+
195
+ **Step 1.** Call `context_write`:
196
+ - Append to `context.services[<service_name>].components`:
197
+ `{ name, path, role, props_accepted, used_in: [list of page paths] }`
198
+ - Set `last_command` = "modularize"
199
+ - Append to `change_log`: `{ timestamp, command: "modularize", action: "Created [n] component(s) from [n] pages" }`
200
+
201
+ **Step 2.** Call `context_clear_scratchpad` with keys: ["current_action"]
202
+
203
+ **Step 3.** Show completion report:
204
+ ```
205
+ /codeninja:modularize Complete
206
+ ─────────────────────────────────────────
207
+ Components created : [n]
208
+ Components reused : [n]
209
+ Pages updated : [n]
210
+ ─────────────────────────────────────────
211
+ [list created files]
212
+ [list modified files]
213
+ ─────────────────────────────────────────
214
+ Next: /codeninja:validate-page to add validation
215
+ /codeninja:integrate-api to wire forms to backend
216
+ ```
@@ -0,0 +1,84 @@
1
+ ---
2
+ slash_command: /codeninja:optimize
3
+ personas: [global-orchestrator, nodejs-backend, database-architect]
4
+ skills: [mcp-and-context, api-builder, database, code-intelligence]
5
+ description: Analyse and improve performance using real project context.
6
+ ---
7
+
8
+ # /codeninja:optimize
9
+
10
+ ## Before Running
11
+ 1. Call `context_read` — load `context.db.schema`, `context.services`
12
+ 2. Call `context_check_stale`
13
+
14
+ ## Execution — Full Step-by-Step
15
+
16
+ ### Step 1 — Identify Target
17
+ If not specified, ask:
18
+ "What would you like to optimise?
19
+ (a) A slow API endpoint — paste the route path
20
+ (b) A heavy SQL query — paste the query or file path
21
+ (c) Overall service startup / memory usage
22
+ (d) Something else — describe it"
23
+
24
+ ### Step 2 — Load Context
25
+ 1. Call `fs_read` on the relevant files (route.js, _model.js)
26
+ 2. For DB queries: list existing indexes from `context.db.schema.<table>.indexes`
27
+
28
+ ### Step 3A — Database Query Analysis
29
+
30
+ For each query in the target:
31
+
32
+ **Check 1 — Missing Indexes**
33
+ Compare WHERE / JOIN / ORDER BY columns against existing indexes.
34
+ Generate `CREATE INDEX CONCURRENTLY` for missing ones.
35
+
36
+ **Check 2 — SELECT * Anti-Pattern**
37
+ Replace with explicit column list. Show before/after.
38
+
39
+ **Check 3 — N+1 Query Pattern**
40
+ Flag any loop calling a DB function per iteration. Suggest single query with IN or JOIN.
41
+
42
+ **Check 4 — Window Function Choice**
43
+ - `RANK()` → gaps after ties (wrong for leaderboards)
44
+ - `DENSE_RANK()` → no gaps (correct for leaderboards)
45
+ - `ROW_NUMBER()` → unique position (correct for pagination)
46
+
47
+ **Check 5 — Duplicate Row Prevention**
48
+ Flag duplicate rows from missing dedup. Suggest `MIN(id) GROUP BY user_id`.
49
+
50
+ **Check 6 — Functional Index Trap**
51
+ Flag `DATE(created_at) = '...'` → suggest range form for index usage.
52
+
53
+ **Check 7 — work_mem for Sort Operations**
54
+ If EXPLAIN shows external merge disk sort → suggest `SET work_mem = '64MB'`.
55
+
56
+ ### Step 3B — API Route Analysis
57
+
58
+ - Is heavy middleware on lightweight routes?
59
+ - Synchronous blocking in request path?
60
+ - Repeated DB lookups that could be cached in Redis?
61
+ - Pagination missing on list endpoints?
62
+
63
+ ### Step 4 — Output Recommendations
64
+
65
+ ```
66
+ [HIGH | MED | LOW] — Impact label
67
+
68
+ Target: what's being optimised
69
+ Root cause: why it's slow right now
70
+ Fix:
71
+ [exact SQL or code change]
72
+ Estimated gain: concrete estimate
73
+ Side effects: anything developer should know
74
+ ```
75
+
76
+ List all, highest impact first.
77
+
78
+ ### Step 5 — Offer to Apply
79
+ "I've found [N] optimisations. Want me to apply them?
80
+ I'll implement each one and show you the change before writing."
81
+
82
+ For index changes → generate `NNN_add_index_<n>.sql` migration file.
83
+ For code changes → edit the relevant model or route file surgically.
84
+ Always call `context_write` after applying index additions.
@@ -0,0 +1,68 @@
1
+ ---
2
+ slash_command: /codeninja:refactor
3
+ personas: [global-orchestrator, nodejs-backend, database-architect]
4
+ skills: [mcp-and-context, api-builder, database, code-intelligence]
5
+ description: Rename or restructure code with full context tracking.
6
+ ---
7
+
8
+ # /codeninja:refactor
9
+
10
+ ## Before Running
11
+ 1. Call `context_read`
12
+ 2. Call `context_check_stale`
13
+
14
+ ## Execution — Full Step-by-Step
15
+
16
+ **Step 1.** Ask: "What type of refactor?"
17
+ 1. Rename a DB column
18
+ 2. Rename a service
19
+ 3. Rename a table
20
+ 4. Rename a module
21
+ 5. Restructure files
22
+ - Store: `context.current_refactor.type`
23
+
24
+ **Step 2.** Ask: "Which service?" (if applicable — skip for DB-only refactors)
25
+
26
+ ---
27
+
28
+ ### If "Rename DB column":
29
+ - Ask: "Which table?" (list from context)
30
+ - Ask: "Which column to rename?" (list current columns)
31
+ - Ask: "New column name?" (snake_case)
32
+ - Delegate to database-agent:
33
+ - Generate ALTER TABLE migration file
34
+ - Update `context.db.schema.tables[<table>].columns`
35
+ - Append to `context.db.schema.change_log`
36
+ - Delegate to nodejs-agent:
37
+ - Find all references to old column name in service files
38
+ - Update model queries
39
+ - Update swagger_doc.json
40
+
41
+ ### If "Rename service":
42
+ - Ask: "Current service name?" (list from context)
43
+ - Ask: "New service name?"
44
+ - Update `context.services` key
45
+ - Append to `context.change_log`
46
+
47
+ ### If "Rename table":
48
+ - Ask: "Which table?" (list from context)
49
+ - Ask: "New table name?" (must start with tbl_, snake_case)
50
+ - Delegate to database-agent:
51
+ - Generate ALTER migration: `RENAME TABLE <old> TO <new>`
52
+ - Update `context.db.schema.tables` key
53
+ - Append to `context.db.schema.change_log`: `{ type: "table_renamed", from: "<old>", to: "<new>" }`
54
+ - Delegate to nodejs-agent:
55
+ - Find all references to old table name in model files
56
+ - Update queries in all affected services
57
+ - Append to top-level `context.change_log`
58
+
59
+ ### If "Rename module":
60
+ - Ask: "Current module name?"
61
+ - Ask: "New module name?"
62
+ - Delegate to nodejs-agent → rename files and update route_manager
63
+
64
+ ---
65
+
66
+ **Confirm:** "Apply refactor? (yes/no)"
67
+ If yes → make all changes → call `context_write` → call `context_clear_scratchpad` ["current_refactor"]
68
+ Show final summary.
@@ -0,0 +1,70 @@
1
+ ---
2
+ slash_command: /codeninja:review
3
+ personas: [global-orchestrator, nodejs-backend]
4
+ skills: [mcp-and-context, api-builder, code-intelligence]
5
+ description: Deep code review with severity-ranked findings and concrete fixes.
6
+ ---
7
+
8
+ # /codeninja:review
9
+
10
+ ## Before Running
11
+ 1. Call `context_read`
12
+ 2. Call `context_check_stale`
13
+
14
+ ## Execution — Full Step-by-Step
15
+
16
+ ### Step 1 — Identify Target
17
+ If not specified, ask: "Which file or module would you like reviewed?"
18
+
19
+ ### Step 2 — Load Context
20
+ 1. Call `fs_read` on the target file
21
+ 2. Read 1–2 similar modules from `context.services[<service>].modules` for pattern comparison
22
+ 3. Cross-reference `context.db.schema` for table/column accuracy
23
+
24
+ ### Step 3 — Run Review Checklist
25
+
26
+ #### Security (CRITICAL if failing)
27
+ - [ ] All POST/PUT/PATCH routes have validatorjs input validation
28
+ - [ ] API key middleware applied before any route logic
29
+ - [ ] JWT auth middleware present on protected routes
30
+ - [ ] No hardcoded secrets, keys, or passwords
31
+ - [ ] Parameterized queries only — no string concatenation in SQL
32
+ - [ ] Error responses don't leak stack traces or internal details
33
+
34
+ #### Architecture (WARNING if failing)
35
+ - [ ] 2-layer rule: no SQL in route.js, no res.json() in model.js
36
+ - [ ] route_manager.js registration matches route file
37
+ - [ ] swagger_doc.json has entry for this endpoint
38
+ - [ ] All user-facing strings in languages/en.js — none hardcoded in route.js
39
+
40
+ #### Code Quality (SUGGESTION if failing)
41
+ - [ ] JSDoc on every exported function
42
+ - [ ] No unused variables or dead imports
43
+ - [ ] No console.log — project logger used instead
44
+ - [ ] Async functions have try/catch blocks
45
+ - [ ] SELECT * not used — explicit column list
46
+
47
+ #### Database (WARNING if failing)
48
+ - [ ] Column names match context.db.schema exactly (snake_case)
49
+ - [ ] Foreign key columns indexed
50
+ - [ ] Transactions used where multiple writes occur together
51
+ - [ ] LIMIT clause on any query that could return unbounded rows
52
+
53
+ ### Step 4 — Output Findings
54
+
55
+ For each issue:
56
+ ```
57
+ [CRITICAL|WARNING|SUGGESTION]
58
+ File: path/to/file.js (~line N)
59
+ Issue: clear one-line description
60
+ Before: the current code
61
+ After: the corrected code
62
+ Why: one sentence explanation
63
+ ```
64
+
65
+ End with: `Review complete: X critical · Y warnings · Z suggestions`
66
+
67
+ ### Step 5 — Offer Auto-Fix
68
+ "Would you like me to apply any of these fixes?
69
+ - SUGGESTION-level: apply all at once
70
+ - WARNING/CRITICAL: one at a time, confirm each"
@@ -0,0 +1,183 @@
1
+ ---
2
+ slash_command: /codeninja:sync
3
+ personas: [global-orchestrator, nodejs-backend]
4
+ skills: [mcp-and-context, code-intelligence]
5
+ description: Scan the entire repository and rebuild context.json from what actually exists on disk.
6
+ ---
7
+
8
+ # /codeninja:sync
9
+
10
+ ## Before Running
11
+ 1. Call `context_read` — load current state (or detect empty)
12
+ 2. Call `service_scan` — discover all services on disk
13
+ 3. Call `context_check_stale`
14
+
15
+ ## Two Operating Modes (auto-detected — do NOT ask user)
16
+
17
+ ### Mode A — Agent-Initialized Project
18
+ Indicators: context.json exists AND `context_version > 0` AND `context.services` has entries.
19
+ → Trust context.json as baseline, scan for drift and gaps, merge new findings without overwriting.
20
+
21
+ ### Mode B — Legacy / No-Context Project
22
+ Indicators: context.json missing OR `context_version == 0` OR `context.services` is empty.
23
+ → Treat every discovery as new. Build context.json entirely from disk. No assumptions about structure.
24
+
25
+ ## Core Rules (both modes)
26
+ - ALWAYS write context.json at the end — no exceptions
27
+ - NEVER delete existing context entries — only add or update
28
+ - NEVER assume a file will be in a specific location — scan first
29
+ - Report all findings in the sync report at the end
30
+
31
+ ---
32
+
33
+ ## Execution — Full Step-by-Step
34
+
35
+ ### Phase 0 — Prepare
36
+
37
+ **Step 0a.** Check if `.codeninja/context/` exists. If not → create it.
38
+ **Step 0b.** Call `context_read`. If returns empty schema (version == 0) → set mode B, fresh schema.
39
+ **Step 0c.** Call `service_scan` — detect all service directories at repo root.
40
+ **Step 0d.** Init sync report counters: `services_synced`, `routes_discovered`, `routes_new`,
41
+ `db_tables_synced`, `db_tables_new`, `gaps_filled`, `unchanged`, `legacy_inferences`
42
+
43
+ ---
44
+
45
+ ### Phase 1 — Repository Structure Discovery
46
+
47
+ #### 1a — Find all service-like directories
48
+ Scan every directory at repository root. A directory is a candidate service if it contains ANY of:
49
+ - `package.json`
50
+ - `app.js` or `index.js`
51
+ - `src/` directory
52
+ - `composer.json` (PHP — record but do not deep-scan)
53
+
54
+ For each candidate service directory:
55
+ - Read `package.json` if present → extract name, version, dependencies
56
+ - Detect type: NodeJS vs ReactJS:
57
+ - ReactJS: has `react` in dependencies, has `src/App.jsx` or `src/App.js`
58
+ - NodeJS: has `express` in dependencies, has `app.js` with `require('express')`
59
+ - Unknown: record type as "unknown"
60
+ - Read `.env` if present (gitignored, may not exist) → extract PORT, DB_*, REDIS_*, KEY, IV, API_KEY
61
+ - Read `.env.example` if present → extract all keys defined
62
+
63
+ #### 1b — Detect service port
64
+ Priority order:
65
+ 1. PORT value from `.env`
66
+ 2. PORT value from `.env.example`
67
+ 3. `app.listen(PORT, ...)` call in `app.js` — extract default
68
+ 4. `context.services[<n>].port` if already recorded
69
+
70
+ #### 1c — Detect modules (NodeJS services)
71
+ For each NodeJS service:
72
+ - Scan `modules/` directory (may be `v1/`, `v2/`, etc.)
73
+ - Each subdirectory containing `route.js` = one module
74
+ - Read `route.js` — extract: HTTP method, route path, whether auth middleware is applied
75
+ - Record: `{ module_name, version, method, route_path, has_auth }`
76
+
77
+ #### 1d — Detect React pages (ReactJS services)
78
+ For each ReactJS service:
79
+ - Scan `src/pages/` — each subdirectory with `index.jsx` or `index.js` = one page
80
+ - Scan `src/views/` if it exists — same logic
81
+ - Detect linked backend:
82
+ - Read `src/api/apiClient.js` → extract `baseURL` → parse port → match against `context.services`
83
+ - Or read `.env` → `REACT_APP_BASE_URL` → parse port
84
+
85
+ ---
86
+
87
+ ### Phase 2 — Database Discovery
88
+
89
+ **Step 2a.** Scan for `database/` directory at repo root.
90
+ If found → read sub-directories to determine db type (postgresql, mysql, mongodb).
91
+
92
+ **Step 2b.** For each db type directory found:
93
+ - List all `.sql` files in `migrations/` sorted by numeric prefix
94
+ - Parse each setup file:
95
+ - Extract table name from `CREATE TABLE`
96
+ - Extract column names and types
97
+ - Extract CHECK constraints and COMMENT ON COLUMN
98
+ - Extract per-file CREATE INDEX statements
99
+ - Parse ALTER files: ADD COLUMN, RENAME COLUMN, DROP COLUMN, ADD CONSTRAINT
100
+ - Parse DROP files: mark table as dropped
101
+ - Parse `111-setup-database-indexes.sql`: extract CREATE INDEX, associate with tables
102
+ - Build the full schema state from all files in order
103
+
104
+ ---
105
+
106
+ ### Phase 3 — Context Assembly
107
+
108
+ #### Mode A — Merge with existing context
109
+
110
+ For each discovered service:
111
+ - If service already in `context.services` → check for drift:
112
+ - Port changed? → flag and ask user which to keep
113
+ - New modules found not in context → add them
114
+ - Modules in context not found on disk → flag as "missing on disk"
115
+ - If service NOT in context → add it as new entry
116
+
117
+ For DB schema:
118
+ - Add any tables not in context
119
+ - Add any columns not tracked
120
+ - Add any indexes not tracked
121
+ - For renames found in ALTER files → append to change_log if not already there
122
+
123
+ #### Mode B — Build from scratch
124
+
125
+ For each discovered service, build full entry:
126
+ ```json
127
+ {
128
+ "service_name": "<n>",
129
+ "type": "nodejs|reactjs",
130
+ "port": <n>,
131
+ "description": "<inferred from package.json description or service name>",
132
+ "modules": [...],
133
+ "linked_service": "<inferred from apiClient.js>",
134
+ "detected_by": "sync"
135
+ }
136
+ ```
137
+
138
+ For legacy projects that don't follow agent conventions:
139
+ - Record what IS found without imposing expected structure
140
+ - Set `legacy: true` flag on the service entry
141
+ - Note what is missing and suggest /codeninja:init to scaffold missing pieces
142
+
143
+ ---
144
+
145
+ ### Phase 4 — Drift Report and Confirmation
146
+
147
+ Before writing anything, present a drift report:
148
+
149
+ ```
150
+ SYNC REPORT
151
+ ════════════════════════════════════════════
152
+ Mode: A (agent-initialized) | B (legacy/fresh)
153
+ ────────────────────────────────────────────
154
+ Services discovered on disk: [n]
155
+ Services already in context: [n]
156
+ New services to add: [n]
157
+ Services with drift: [n]
158
+ ────────────────────────────────────────────
159
+ DB tables on disk: [n]
160
+ DB tables already in context: [n]
161
+ New tables to add: [n]
162
+ ────────────────────────────────────────────
163
+ DRIFT ITEMS (require confirmation):
164
+ ⚠ service [n]: port in context = 1001, found on disk = 1002
165
+ ⚠ module [n] in context but route.js not found on disk
166
+ ────────────────────────────────────────────
167
+ ```
168
+
169
+ For each DRIFT ITEM: ask user to confirm which value to keep — one at a time.
170
+
171
+ ---
172
+
173
+ ### Phase 5 — Write Context
174
+
175
+ **Step 5.** Call `context_write` with the fully assembled context object.
176
+ Set `last_command` = "sync"
177
+
178
+ **Step 6.** Show final sync summary with counts of what was added/updated.
179
+
180
+ **Step 7.** Suggest next steps based on findings:
181
+ - If new services found → "Run /codeninja:api to add API routes"
182
+ - If schema gaps found → "Run /codeninja:db:sync to rebuild DB schema"
183
+ - If legacy project → "Run /codeninja:init to scaffold missing baseline files"
@@ -0,0 +1,61 @@
1
+ ---
2
+ slash_command: /codeninja:test
3
+ personas: [global-orchestrator, nodejs-backend]
4
+ skills: [mcp-and-context, api-builder, code-intelligence]
5
+ description: Generate or run Jest + Supertest tests for a NodeJS module.
6
+ ---
7
+
8
+ # /codeninja:test
9
+
10
+ ## Before Running
11
+ 1. Call `context_read`
12
+ 2. Call `context_check_stale`
13
+
14
+ ## Execution — Full Step-by-Step
15
+
16
+ **Step 1.** Ask: "Which service?" (list from `context.services`)
17
+ - Store: `context.current_test.service_name`
18
+
19
+ **Step 2.** Ask: "Which module?" (list from `context.services[<n>].modules`)
20
+ - Store: `context.current_test.module_name`
21
+
22
+ **Step 3.** Ask: "Generate new tests or run existing tests?"
23
+ - Option 1: Generate new tests
24
+ - Option 2: Run existing tests
25
+ - Store: `context.current_test.type`
26
+
27
+ **Step 4.** If `generate`:
28
+ - Read `modules/<version>/<Module>/route.js` from disk
29
+ - Read `modules/<version>/<Module>/<module>_model.js` from disk
30
+ - Read `context.api_routes` for this module
31
+ - Delegate to nodejs-agent → generate `tests/<version>/<Module>.test.js`
32
+
33
+ Generated test file covers:
34
+ - 200 happy path for each endpoint
35
+ - 400 validation failures (missing required fields, wrong types)
36
+ - 401 missing or invalid API key header
37
+ - 401 missing or invalid auth token (for protected routes)
38
+ - 404 not found (where applicable)
39
+ - 500 simulated service error (mock DB failure)
40
+
41
+ Test structure:
42
+ ```javascript
43
+ const request = require('supertest');
44
+ const app = require('../../app');
45
+
46
+ describe('<Module> — POST /<path>', () => {
47
+ it('200 — happy path', async () => { ... });
48
+ it('400 — missing required field', async () => { ... });
49
+ it('401 — invalid api-key', async () => { ... });
50
+ it('401 — invalid auth token', async () => { ... });
51
+ it('404 — record not found', async () => { ... });
52
+ });
53
+ ```
54
+
55
+ **Step 5.** If `run`:
56
+ - Execute: `npm test` inside service directory
57
+ - Parse results and display pass/fail summary
58
+
59
+ **Step 6.** Call `context_write` → update `context.services[<n>].tests`
60
+
61
+ **Step 7.** Show final summary.