codeninja 3.2.0 → 4.0.1
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/README.md +15 -4
- package/agent/database-agent.md +24 -1
- package/agent/nodejs-agent.md +79 -0
- package/cli.js +27 -7
- package/commands/audit.workflow.md +4 -1
- package/commands/db-create-table.workflow.md +1 -1
- package/commands/initialize-project.workflow.md +21 -0
- package/ide/antigravity/.agents/personas/database-architect.md +431 -153
- package/ide/antigravity/.agents/personas/global-orchestrator.md +202 -85
- package/ide/antigravity/.agents/personas/nodejs-backend.md +368 -133
- package/ide/antigravity/.agents/personas/reactjs-frontend.md +182 -101
- package/ide/antigravity/.agents/skills/api-builder/SKILL.md +58 -0
- package/ide/antigravity/.agents/skills/code-intelligence/SKILL.md +22 -0
- package/ide/antigravity/.agents/skills/database/SKILL.md +32 -0
- package/ide/antigravity/.agents/skills/mcp-and-context/SKILL.md +76 -82
- package/ide/antigravity/.agents/skills/reactjs/SKILL.md +36 -0
- package/ide/antigravity/.agents/workflows/codeninja-api.md +76 -83
- package/ide/antigravity/.agents/workflows/codeninja-audit.md +82 -44
- package/ide/antigravity/.agents/workflows/codeninja-db-create.md +107 -94
- package/ide/antigravity/.agents/workflows/codeninja-db-drop.md +89 -67
- package/ide/antigravity/.agents/workflows/codeninja-db-index.md +86 -54
- package/ide/antigravity/.agents/workflows/codeninja-db-modify.md +126 -68
- package/ide/antigravity/.agents/workflows/codeninja-db-seed.md +87 -59
- package/ide/antigravity/.agents/workflows/codeninja-db-sync.md +77 -41
- package/ide/antigravity/.agents/workflows/codeninja-debug.md +35 -21
- package/ide/antigravity/.agents/workflows/codeninja-design.md +49 -35
- package/ide/antigravity/.agents/workflows/codeninja-explain.md +41 -20
- package/ide/antigravity/.agents/workflows/codeninja-init.md +479 -289
- package/ide/antigravity/.agents/workflows/codeninja-integrate-api.md +253 -136
- package/ide/antigravity/.agents/workflows/codeninja-modularize.md +250 -132
- package/ide/antigravity/.agents/workflows/codeninja-optimize.md +71 -29
- package/ide/antigravity/.agents/workflows/codeninja-refactor.md +50 -42
- package/ide/antigravity/.agents/workflows/codeninja-review.md +38 -21
- package/ide/antigravity/.agents/workflows/codeninja-sync.md +922 -141
- package/ide/antigravity/.agents/workflows/codeninja-test.md +34 -49
- package/ide/antigravity/.agents/workflows/codeninja-validate-page.md +449 -151
- package/ide/claude-code/.claude/CLAUDE.md +99 -0
- package/ide/claude-code/.claude/agents/database-agent.md +535 -0
- package/ide/claude-code/.claude/agents/nodejs-agent.md +493 -0
- package/ide/claude-code/.claude/agents/reactjs-agent.md +267 -0
- package/ide/claude-code/.claude/commands/codeninja-api.md +104 -0
- package/ide/claude-code/.claude/commands/codeninja-audit.md +119 -0
- package/ide/claude-code/.claude/commands/codeninja-db-create.md +138 -0
- package/ide/claude-code/.claude/commands/codeninja-db-drop.md +109 -0
- package/ide/claude-code/.claude/commands/codeninja-db-index.md +103 -0
- package/ide/claude-code/.claude/commands/codeninja-db-modify.md +165 -0
- package/ide/claude-code/.claude/commands/codeninja-db-seed.md +104 -0
- package/ide/claude-code/.claude/commands/codeninja-db-sync.md +106 -0
- package/ide/claude-code/.claude/commands/codeninja-debug.md +99 -0
- package/ide/claude-code/.claude/commands/codeninja-design.md +68 -0
- package/ide/claude-code/.claude/commands/codeninja-explain.md +61 -0
- package/ide/claude-code/.claude/commands/codeninja-init.md +529 -0
- package/ide/claude-code/.claude/commands/codeninja-integrate-api.md +453 -0
- package/ide/claude-code/.claude/commands/codeninja-modularize.md +334 -0
- package/ide/claude-code/.claude/commands/codeninja-optimize.md +129 -0
- package/ide/claude-code/.claude/commands/codeninja-refactor.md +76 -0
- package/ide/claude-code/.claude/commands/codeninja-review.md +87 -0
- package/ide/claude-code/.claude/commands/codeninja-sync.md +964 -0
- package/ide/claude-code/.claude/commands/codeninja-test.md +45 -0
- package/ide/claude-code/.claude/commands/codeninja-validate-page.md +548 -0
- package/ide/cursor/.cursor/rules/01-global-orchestrator.mdc +12 -13
- package/ide/cursor/.cursor/rules/02-mcp-and-context.mdc +47 -31
- package/ide/cursor/.cursor/rules/03-api-builder.mdc +32 -110
- package/ide/cursor/.cursor/rules/04-nodejs-generation.mdc +58 -0
- package/ide/cursor/.cursor/rules/05-database.mdc +54 -0
- package/ide/cursor/.cursor/rules/06-reactjs.mdc +36 -0
- package/ide/cursor/.cursor/rules/07-reactjs-generation.mdc +49 -0
- package/ide/cursor/.cursor/rules/08-code-intelligence.mdc +56 -0
- package/ide/cursor/.cursor/rules/09-workflow-steps.mdc +53 -0
- package/ide/vscode/.github/copilot-instructions.md +67 -382
- package/ide/vscode/.vscode/instructions/code-intelligence.instructions.md +58 -0
- package/ide/vscode/.vscode/instructions/database.instructions.md +55 -0
- package/ide/vscode/.vscode/instructions/nodejs.instructions.md +77 -0
- package/ide/vscode/.vscode/instructions/reactjs.instructions.md +42 -0
- package/package.json +2 -2
- package/tasks/ask-hashing-library.task.md +31 -0
- package/tasks/ask-language-type.task.md +26 -0
- package/tasks/ask-new-module-name.task.md +13 -0
- package/tasks/ask-new-service-name.task.md +13 -0
- package/tasks/ask-old-module-name.task.md +15 -0
- package/tasks/ask-old-service-name.task.md +13 -0
- package/tasks/ask-orm-type.task.md +26 -0
- package/tasks/collect-seed-data.task.md +19 -0
- package/tasks/generate-app.task.md +42 -0
- package/tasks/generate-common.task.md +13 -0
- package/tasks/generate-constants.task.md +13 -0
- package/tasks/generate-database.task.md +32 -0
- package/tasks/generate-encryption.task.md +28 -0
- package/tasks/generate-fast-defaults.task.md +7 -0
- package/tasks/generate-hashing.task.md +180 -0
- package/tasks/generate-headerValidator.task.md +13 -0
- package/tasks/generate-ioRedis.task.md +20 -0
- package/tasks/generate-language-en.task.md +12 -0
- package/tasks/generate-logging.task.md +12 -0
- package/tasks/generate-model.task.md +74 -6
- package/tasks/generate-notification.task.md +12 -0
- package/tasks/generate-package-json.task.md +69 -0
- package/tasks/generate-prisma-client.task.md +56 -0
- package/tasks/generate-prisma-schema.task.md +71 -0
- package/tasks/generate-rateLimiter.task.md +20 -0
- package/tasks/generate-readme.task.md +24 -0
- package/tasks/generate-response.task.md +27 -0
- package/tasks/generate-route-manager.task.md +32 -0
- package/tasks/generate-route.task.md +37 -0
- package/tasks/generate-swagger.task.md +8 -0
- package/tasks/generate-template.task.md +12 -0
- package/tasks/generate-tsconfig.task.md +38 -0
- package/tasks/generate-validator.task.md +31 -0
- package/ide/cursor/.cursor/rules/04-database.mdc +0 -90
- package/ide/cursor/.cursor/rules/05-reactjs.mdc +0 -147
- package/ide/cursor/.cursor/rules/06-code-intelligence.mdc +0 -112
|
@@ -0,0 +1,964 @@
|
|
|
1
|
+
This command runs when user types /codeninja:sync
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
type: workflow
|
|
5
|
+
name: sync
|
|
6
|
+
description: >
|
|
7
|
+
Scans the entire repository and builds or rebuilds context.json from
|
|
8
|
+
what actually exists on disk. Works on both agent-initialized projects
|
|
9
|
+
and pre-existing legacy projects with completely different structures.
|
|
10
|
+
Always writes context.json — creates it if missing. Safe to run at any time.
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Workflow: @sync
|
|
14
|
+
|
|
15
|
+
## Goal
|
|
16
|
+
Make context.json an accurate, complete reflection of the current
|
|
17
|
+
repository — whether the project was initialized by this agent or
|
|
18
|
+
existed long before this system was introduced.
|
|
19
|
+
|
|
20
|
+
ALWAYS write context.json at the end of every sync run.
|
|
21
|
+
If context.json does not exist → create it from scratch using the
|
|
22
|
+
empty schema from write-context.task.md and populate it from scan results.
|
|
23
|
+
Never skip the write step even if nothing changed.
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Two Operating Modes
|
|
28
|
+
|
|
29
|
+
Sync detects which mode to use automatically. Do not ask the user.
|
|
30
|
+
|
|
31
|
+
### Mode A — Agent-Initialized Project
|
|
32
|
+
Indicators: `.codeninja/context/context.json` exists AND has
|
|
33
|
+
`context_version > 0` AND `context.services` has at least one entry.
|
|
34
|
+
|
|
35
|
+
In this mode: trust context.json as a baseline, scan for drift and
|
|
36
|
+
gaps, merge new findings into existing context without overwriting
|
|
37
|
+
known-good values.
|
|
38
|
+
|
|
39
|
+
### Mode B — Legacy / No-Context Project
|
|
40
|
+
Indicators: context.json is missing OR `context_version == 0` OR
|
|
41
|
+
`context.services` is empty.
|
|
42
|
+
|
|
43
|
+
In this mode: treat every discovery as new. Build context.json
|
|
44
|
+
entirely from what is found on disk. Make no assumptions about
|
|
45
|
+
structure — the project may follow completely different conventions
|
|
46
|
+
from the agent's own generated patterns. Be inventive and read deeply.
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Core Rules (apply to both modes)
|
|
51
|
+
|
|
52
|
+
- ALWAYS write context.json at the end — no exceptions
|
|
53
|
+
- NEVER delete existing context entries — only add or update
|
|
54
|
+
- NEVER assume a file will be in a specific location — scan first
|
|
55
|
+
- NEVER assume a project follows agent conventions — verify everything
|
|
56
|
+
- Preserve all existing `change_log` entries — append only
|
|
57
|
+
- Report all findings in the sync report at the end
|
|
58
|
+
- If a value conflicts with what is already in context → list it and
|
|
59
|
+
ask user to confirm which to keep — one conflict at a time — before
|
|
60
|
+
writing context
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## Step-by-Step Execution
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
### Phase 0 — Determine Mode and Prepare
|
|
69
|
+
|
|
70
|
+
0a. Check if `.codeninja/context/` directory exists.
|
|
71
|
+
If not → create it now. Do not fail on missing directory.
|
|
72
|
+
|
|
73
|
+
0b. Attempt to read context.json via MCP tool `context_read`.
|
|
74
|
+
If it returns the empty schema (context_version == 0) or fails →
|
|
75
|
+
set mode = B and prepare a fresh empty schema in memory.
|
|
76
|
+
If it returns data with context_version > 0 and populated services →
|
|
77
|
+
set mode = A and load all existing values as the working baseline.
|
|
78
|
+
|
|
79
|
+
0c. Run task: `detect-repository-state`
|
|
80
|
+
This scans root for service folders, database folder, and
|
|
81
|
+
React apps regardless of mode.
|
|
82
|
+
|
|
83
|
+
0d. Determine sync report counters — initialize all to zero:
|
|
84
|
+
services_synced, routes_discovered, routes_new,
|
|
85
|
+
db_tables_synced, db_tables_new, gaps_filled, unchanged,
|
|
86
|
+
legacy_inferences
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
### Phase 1 — Repository Structure Discovery
|
|
91
|
+
|
|
92
|
+
This phase maps every part of the repository before any context
|
|
93
|
+
is written. Read first, write later.
|
|
94
|
+
|
|
95
|
+
#### 1a — Find all service-like directories
|
|
96
|
+
|
|
97
|
+
Scan every directory at repository root. A directory is a candidate
|
|
98
|
+
service if it contains ANY of these signals:
|
|
99
|
+
- `package.json` (Node/React project)
|
|
100
|
+
- `app.js` or `index.js` (Node entry points)
|
|
101
|
+
- `src/` directory (could be React or modern Node)
|
|
102
|
+
- `composer.json` (PHP project — record but do not deep-scan)
|
|
103
|
+
- `requirements.txt` or `pyproject.toml` (Python — record, note unsupported)
|
|
104
|
+
- `Gemfile` (Ruby — record, note unsupported)
|
|
105
|
+
- `pom.xml` or `build.gradle` (Java — record, note unsupported)
|
|
106
|
+
|
|
107
|
+
For each candidate directory: record name and what signal triggered it.
|
|
108
|
+
|
|
109
|
+
Skip: `.codeninja/`, `node_modules/`, `.git/`, `dist/`, `build/`,
|
|
110
|
+
`.next/`, `.nuxt/`, `coverage/`, `.cache/`
|
|
111
|
+
|
|
112
|
+
#### 1b — Classify each candidate
|
|
113
|
+
|
|
114
|
+
For each candidate directory, determine its tech type:
|
|
115
|
+
|
|
116
|
+
**NodeJS detection (check in order):**
|
|
117
|
+
1. `package.json` exists → read it
|
|
118
|
+
2. Check `dependencies` for: express, fastify, koa, hapi, nestjs
|
|
119
|
+
3. Check for `app.js`, `server.js`, `index.js` at root of directory
|
|
120
|
+
4. Check for `src/app.js` or `src/index.js`
|
|
121
|
+
→ If any match: classify as `nodejs`
|
|
122
|
+
|
|
123
|
+
**ReactJS detection (check in order):**
|
|
124
|
+
1. `package.json` exists → read it
|
|
125
|
+
2. Check `dependencies` or `devDependencies` for: react, react-dom
|
|
126
|
+
3. Check for `src/App.jsx`, `src/App.js`, `src/App.tsx`
|
|
127
|
+
4. Check for `src/index.jsx`, `src/index.js`, `src/main.jsx`
|
|
128
|
+
5. Check for `public/index.html`
|
|
129
|
+
→ If any match: classify as `reactjs`
|
|
130
|
+
Note: If both express AND react are in the same package.json →
|
|
131
|
+
classify as `nodejs` and note the React dependency as unusual.
|
|
132
|
+
|
|
133
|
+
**Unknown:** Record the folder, note what was found, do not classify.
|
|
134
|
+
|
|
135
|
+
#### 1c — Find the database directory
|
|
136
|
+
|
|
137
|
+
Search for database files using ALL of the following patterns —
|
|
138
|
+
not just the agent's convention of `database/` at root:
|
|
139
|
+
|
|
140
|
+
- `database/` at repository root (agent convention)
|
|
141
|
+
- `db/` at repository root
|
|
142
|
+
- `<service_name>/database/` inside any service folder
|
|
143
|
+
(misplaced — flag it)
|
|
144
|
+
- `<service_name>/db/` inside any service folder
|
|
145
|
+
(misplaced — flag it)
|
|
146
|
+
- `migrations/` at repository root or inside any service
|
|
147
|
+
- `schema/` at repository root or inside any service
|
|
148
|
+
- `sql/` at repository root or inside any service
|
|
149
|
+
- Any `.sql` files anywhere in the repo
|
|
150
|
+
- For MongoDB: `models/` directories containing Mongoose schema
|
|
151
|
+
files (files with `mongoose.Schema` or `new Schema(`)
|
|
152
|
+
- For MongoDB: any `*.model.js` files with Schema definitions
|
|
153
|
+
|
|
154
|
+
Record all database locations found. The agent's expected location
|
|
155
|
+
is `database/<db_type>/migrations/` — anything else is noted in
|
|
156
|
+
the report as non-standard but still scanned.
|
|
157
|
+
|
|
158
|
+
#### 1d — Find shared infrastructure
|
|
159
|
+
|
|
160
|
+
Scan for files that exist outside service folders and may be shared:
|
|
161
|
+
- `docker-compose.yml` or `docker-compose.yaml`
|
|
162
|
+
- `Dockerfile` at root
|
|
163
|
+
- `.env` at root (shared environment)
|
|
164
|
+
- `nginx.conf` or `nginx/`
|
|
165
|
+
- `kubernetes/` or `k8s/`
|
|
166
|
+
- `scripts/` at root
|
|
167
|
+
- `docs/` or `documentation/`
|
|
168
|
+
- `README.md` at root
|
|
169
|
+
|
|
170
|
+
Record all found. These do not create service entries but inform
|
|
171
|
+
the project_info summary.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
### Phase 2 — Deep Scan Each NodeJS Service
|
|
176
|
+
|
|
177
|
+
For each directory classified as `nodejs` in Phase 1:
|
|
178
|
+
|
|
179
|
+
#### 2a — Identity and Package
|
|
180
|
+
|
|
181
|
+
Read `package.json` → extract:
|
|
182
|
+
- `name` → candidate for service_name
|
|
183
|
+
- `version`
|
|
184
|
+
- `description`
|
|
185
|
+
- `author`
|
|
186
|
+
- `main` → note actual entry point
|
|
187
|
+
- `scripts` → note start script key and value
|
|
188
|
+
- All `dependencies` → full list
|
|
189
|
+
- All `devDependencies` → full list
|
|
190
|
+
|
|
191
|
+
If `package.json` not found → use directory name as service_name.
|
|
192
|
+
|
|
193
|
+
#### 2b — Find the Entry Point
|
|
194
|
+
|
|
195
|
+
The entry point is NOT always `app.js`. Check in this order:
|
|
196
|
+
1. `package.json` `main` field
|
|
197
|
+
2. `package.json` `scripts.start` → extract filename from `node <file>`
|
|
198
|
+
3. `app.js` at service root
|
|
199
|
+
4. `server.js` at service root
|
|
200
|
+
5. `index.js` at service root
|
|
201
|
+
6. `src/app.js`
|
|
202
|
+
7. `src/index.js`
|
|
203
|
+
|
|
204
|
+
Read the entry point file → extract:
|
|
205
|
+
- Port: scan for `process.env.PORT`, `.listen(`, `PORT =`
|
|
206
|
+
- Middleware registrations (look for `app.use(`)
|
|
207
|
+
- Route registrations (look for `app.use('/', `, `require(`)
|
|
208
|
+
- Any `dotenv` or `dotenv.config()` call
|
|
209
|
+
|
|
210
|
+
#### 2c — Find Environment Config
|
|
211
|
+
|
|
212
|
+
Search for `.env` file in this order:
|
|
213
|
+
1. `<service>/.env`
|
|
214
|
+
2. `<service>/.env.local`
|
|
215
|
+
3. `<service>/.env.development`
|
|
216
|
+
4. `.env` at repository root
|
|
217
|
+
|
|
218
|
+
If found → read all key=value pairs. Extract:
|
|
219
|
+
- PORT → service port
|
|
220
|
+
- PROJECT_NAME or APP_NAME or SERVICE_NAME → service name hint
|
|
221
|
+
- API_KEY or APIKEY → api_key
|
|
222
|
+
- KEY, ENCRYPTION_KEY, SECRET_KEY, APP_KEY → encryption_key
|
|
223
|
+
- IV, ENCRYPTION_IV, SECRET_IV → encryption_iv
|
|
224
|
+
- ENCRYPTED_TRANSPORT → encrypted_transport (parse as boolean)
|
|
225
|
+
- SUPPORTED_LANGUAGES, LANGUAGES → parse as array
|
|
226
|
+
- DB_HOST, DATABASE_HOST, PGHOST, MYSQL_HOST → db host
|
|
227
|
+
- DB_PORT, DATABASE_PORT, PGPORT, MYSQL_PORT → db port
|
|
228
|
+
- DB_NAME, DATABASE_NAME, PGDATABASE, MYSQL_DATABASE → db name
|
|
229
|
+
- DB_USER, DATABASE_USER, PGUSER, MYSQL_USER → db user
|
|
230
|
+
- DB_PASSWORD, DATABASE_PASSWORD, PGPASSWORD → note exists (never store value)
|
|
231
|
+
- REDIS_HOST, REDIS_URL → redis host
|
|
232
|
+
- REDIS_PORT → redis port
|
|
233
|
+
|
|
234
|
+
If `.env` not found → also check `.env.example` for key names
|
|
235
|
+
(even if values are blank, it documents what the service expects).
|
|
236
|
+
|
|
237
|
+
#### 2d — Find Route Definitions
|
|
238
|
+
|
|
239
|
+
Routes may live in many structures. Scan all of these:
|
|
240
|
+
|
|
241
|
+
**Agent-convention structure:**
|
|
242
|
+
- `modules/v1/<ModuleName>/route.js`
|
|
243
|
+
- `modules/v2/<ModuleName>/route.js`
|
|
244
|
+
|
|
245
|
+
**Common legacy structures:**
|
|
246
|
+
- `routes/<n>.js` or `routes/<n>.route.js`
|
|
247
|
+
- `routes/v1/<n>.js`
|
|
248
|
+
- `src/routes/<n>.js`
|
|
249
|
+
- `api/routes/<n>.js`
|
|
250
|
+
- `controllers/<n>.js` (routes may be defined here in some patterns)
|
|
251
|
+
- `src/controllers/<n>.js`
|
|
252
|
+
- Any file named `*.router.js`, `*.routes.js`, `route.js`, `router.js`
|
|
253
|
+
|
|
254
|
+
For each route file found → extract:
|
|
255
|
+
- HTTP method: `router.get`, `router.post`, `router.put`,
|
|
256
|
+
`router.patch`, `router.delete`, `app.get`, `app.post`, etc.
|
|
257
|
+
- Route path: the string argument (e.g. `/login`, `/users/:id`)
|
|
258
|
+
- Handler name or comment if present
|
|
259
|
+
- Version prefix if detectable from folder or router mount path
|
|
260
|
+
|
|
261
|
+
Also read the entry point for `app.use('/v1', ...)` style mounts to
|
|
262
|
+
determine base prefix for routes.
|
|
263
|
+
|
|
264
|
+
#### 2e — Determine Encryption Library and Client Type
|
|
265
|
+
|
|
266
|
+
Scan for encryption setup. Do NOT assume a specific file location:
|
|
267
|
+
- Search all `.js` files for: `require('crypto-js')`,
|
|
268
|
+
`require("crypto-js")`, `import CryptoJS`
|
|
269
|
+
- Search for: `require('cryptlib')`, `require("cryptlib")`,
|
|
270
|
+
`import cryptlib`
|
|
271
|
+
- Search for: `require('crypto')` (Node built-in AES — different approach)
|
|
272
|
+
- Search for: `CryptoJS.AES`, `cryptlib.encrypt`, `crypto.createCipheriv`
|
|
273
|
+
|
|
274
|
+
Also check for the encryption/decryption pattern inline in other files:
|
|
275
|
+
- `headerValidator.js`, `common.js`, `app.js`, any middleware file
|
|
276
|
+
may contain the encrypt/decrypt logic directly in older projects
|
|
277
|
+
|
|
278
|
+
Map findings to client_type:
|
|
279
|
+
- crypto-js found → `client_type = "reactjs"`
|
|
280
|
+
- cryptlib found → `client_type = "app"`
|
|
281
|
+
- Node crypto with AES → `client_type = "app"` (note: custom implementation)
|
|
282
|
+
- Nothing found → `client_type = null` (record as unknown)
|
|
283
|
+
|
|
284
|
+
Also look for encrypted transport pattern:
|
|
285
|
+
- Any middleware that calls `decrypt(req.body)` or similar before
|
|
286
|
+
passing to handlers → `encrypted_transport = true`
|
|
287
|
+
- Check ENCRYPTED_TRANSPORT in .env as backup
|
|
288
|
+
- If neither found → `encrypted_transport = false`
|
|
289
|
+
|
|
290
|
+
#### 2f — Detect DB Driver and Type
|
|
291
|
+
|
|
292
|
+
Scan `package.json` dependencies AND all `require()`/`import`
|
|
293
|
+
statements across the service for:
|
|
294
|
+
- `pg` or `pg-pool` or `postgres` → `db_type = "postgresql"`
|
|
295
|
+
- `mysql` or `mysql2` → `db_type = "mysql"`
|
|
296
|
+
- `mongoose` or `mongodb` → `db_type = "mongodb"`
|
|
297
|
+
- `better-sqlite3` or `sqlite3` → `db_type = "sqlite"` (note: not fully supported)
|
|
298
|
+
- `knex` or `sequelize` or `typeorm` or `prisma` →
|
|
299
|
+
note ORM found, attempt to infer underlying DB from config files
|
|
300
|
+
|
|
301
|
+
Also check `config/database.js`, `config/db.js`, `database.js`,
|
|
302
|
+
`src/config/database.js`, `db/index.js`, `src/db/index.js` for
|
|
303
|
+
connection config strings that reveal the DB type.
|
|
304
|
+
|
|
305
|
+
#### 2g — Detect Middleware Stack
|
|
306
|
+
|
|
307
|
+
Do NOT assume agent-convention filenames. Instead, scan for
|
|
308
|
+
middleware by behavior:
|
|
309
|
+
|
|
310
|
+
Scan `app.use(` calls in the entry point AND any route manager /
|
|
311
|
+
router index files. Also scan all files in:
|
|
312
|
+
- `middleware/`
|
|
313
|
+
- `middlewares/`
|
|
314
|
+
- `src/middleware/`
|
|
315
|
+
- Any file named `*middleware*`, `*validator*`, `*auth*`, `*guard*`
|
|
316
|
+
|
|
317
|
+
For each middleware file found, classify by behavior:
|
|
318
|
+
- Reads `api-key` or `x-api-key` header and validates it →
|
|
319
|
+
record as `api_key_validator`
|
|
320
|
+
- Reads `Authorization` header or verifies JWT →
|
|
321
|
+
record as `auth_validator`
|
|
322
|
+
- Calls `req.ip` and tracks request counts →
|
|
323
|
+
record as `rate_limiter`
|
|
324
|
+
- Extracts language from header (Accept-Language, lang, language) →
|
|
325
|
+
record as `language_extractor`
|
|
326
|
+
- Decrypts `req.body` using AES or similar →
|
|
327
|
+
record as `decrypt_request`
|
|
328
|
+
|
|
329
|
+
In legacy projects the functions above may all be in a single file
|
|
330
|
+
(e.g. `common.js`, `headerValidator.js`, `app.js` directly).
|
|
331
|
+
Classify by the behavior found, not by the filename.
|
|
332
|
+
|
|
333
|
+
#### 2h — Detect Language / i18n Setup
|
|
334
|
+
|
|
335
|
+
Scan for any of these i18n patterns:
|
|
336
|
+
- `languages/` directory with `*.js` files → read all filenames
|
|
337
|
+
- `locales/` directory with `*.json` files → read all filenames
|
|
338
|
+
- `i18n/` directory
|
|
339
|
+
- `localizify` in package.json → agent convention confirmed
|
|
340
|
+
- `i18next`, `vue-i18n`, `react-intl` in package.json → note library
|
|
341
|
+
- Any `require('../languages/')` or `require('./locales/')` references
|
|
342
|
+
|
|
343
|
+
For `languages/` files → extract language code from filename
|
|
344
|
+
(e.g. `en.js`, `ar.js`, `fr.js`) → build `supported_languages[]`
|
|
345
|
+
|
|
346
|
+
#### 2i — Read Config Files (wherever they are)
|
|
347
|
+
|
|
348
|
+
Do NOT look only in `config/`. Search for configuration across:
|
|
349
|
+
- `config/*.js` (agent convention)
|
|
350
|
+
- `src/config/*.js`
|
|
351
|
+
- `settings.js`, `settings/index.js`
|
|
352
|
+
- `constants.js`, `src/constants.js`, `config/constants.js`
|
|
353
|
+
- `common.js`, `config/common.js`
|
|
354
|
+
|
|
355
|
+
From these files extract:
|
|
356
|
+
- Any hardcoded port references
|
|
357
|
+
- Any API version declarations (v1, v2)
|
|
358
|
+
- Any service name or project name constants
|
|
359
|
+
- Any feature flags
|
|
360
|
+
|
|
361
|
+
#### 2j — Detect Redis Usage
|
|
362
|
+
|
|
363
|
+
Scan for Redis client setup anywhere:
|
|
364
|
+
- `require('ioredis')`, `require('redis')`, `require("ioredis")`
|
|
365
|
+
- `new Redis(`, `redis.createClient(`
|
|
366
|
+
- Check extracted .env values for REDIS_HOST, REDIS_PORT
|
|
367
|
+
|
|
368
|
+
#### 2k — Classify Service vs Agent-Initialized
|
|
369
|
+
|
|
370
|
+
After all scans for this service, determine:
|
|
371
|
+
|
|
372
|
+
**Agent-initialized** if ALL of these are true:
|
|
373
|
+
- `modules/v1/` directory exists
|
|
374
|
+
- `utilities/` directory exists with at least encryption.js and response.js
|
|
375
|
+
- `middleware/` directory exists with headerValidator.js
|
|
376
|
+
- `.codeninja/context/context.json` has an entry for this service
|
|
377
|
+
|
|
378
|
+
**Legacy** if ANY of the above is false.
|
|
379
|
+
|
|
380
|
+
Record the classification. Legacy services get a note in the sync
|
|
381
|
+
report. Neither classification affects how the service is synced —
|
|
382
|
+
both are fully scanned and registered in context.
|
|
383
|
+
|
|
384
|
+
---
|
|
385
|
+
|
|
386
|
+
### Phase 3 — Deep Scan Each ReactJS Service
|
|
387
|
+
|
|
388
|
+
For each directory classified as `reactjs` in Phase 1:
|
|
389
|
+
|
|
390
|
+
#### 3a — Identity and Package
|
|
391
|
+
|
|
392
|
+
Read `package.json` → extract name, description, version, scripts.
|
|
393
|
+
Note all dependencies.
|
|
394
|
+
|
|
395
|
+
#### 3b — Find Entry and Port
|
|
396
|
+
|
|
397
|
+
Look for dev server port in:
|
|
398
|
+
- `package.json` `scripts.start` (e.g. `PORT=3001 react-scripts start`)
|
|
399
|
+
- `.env` → `PORT` or `REACT_APP_PORT`
|
|
400
|
+
- `vite.config.js` or `vite.config.ts` → `server.port`
|
|
401
|
+
- `webpack.config.js` → `devServer.port`
|
|
402
|
+
- Default: 3000
|
|
403
|
+
|
|
404
|
+
#### 3c — Find API Integration
|
|
405
|
+
|
|
406
|
+
Determine what backend this React app talks to:
|
|
407
|
+
- `.env` → look for keys containing: BASE_URL, API_URL, API_BASE,
|
|
408
|
+
REACT_APP_BASE_URL, VITE_API_URL, VUE_APP_API_URL
|
|
409
|
+
- Extract hostname/port from those values
|
|
410
|
+
- Match the port against all known NodeJS services in current scan
|
|
411
|
+
to identify the `linked_service`
|
|
412
|
+
- Also scan `src/api/`, `src/services/`, `src/utils/`, `src/helpers/`
|
|
413
|
+
for axios/fetch base URL declarations (e.g. `baseURL:`, `axios.create(`,
|
|
414
|
+
`fetch('http`, `const API_URL =`, `const BASE_URL =`)
|
|
415
|
+
|
|
416
|
+
#### 3d — Find Page / Route Structure
|
|
417
|
+
|
|
418
|
+
Scan for React Router or equivalent:
|
|
419
|
+
- `src/App.jsx`, `src/App.js`, `src/App.tsx` → extract `<Route` declarations
|
|
420
|
+
- `src/router/`, `src/routes/` → extract route configs
|
|
421
|
+
- `src/pages/` → list subdirectories as page names
|
|
422
|
+
- `src/views/` → list subdirectories as view names
|
|
423
|
+
- `src/screens/` → list subdirectories (common in React Native style)
|
|
424
|
+
|
|
425
|
+
#### 3e — Find Encryption Setup
|
|
426
|
+
|
|
427
|
+
Scan for crypto-js usage in src/:
|
|
428
|
+
- Any `require('crypto-js')` or `import CryptoJS`
|
|
429
|
+
- Any `CryptoJS.AES.encrypt` / `CryptoJS.AES.decrypt` calls
|
|
430
|
+
- Check for these in: api/, utils/, services/, config/ subdirs
|
|
431
|
+
- In legacy React: may be in a standalone `utils/encryption.js` or
|
|
432
|
+
`helpers/crypto.js` or even inline in an axios interceptor
|
|
433
|
+
|
|
434
|
+
#### 3f — Classify as Agent-Initialized or Legacy
|
|
435
|
+
|
|
436
|
+
**Agent-initialized** if ALL true:
|
|
437
|
+
- `src/api/apiClient.js` exists
|
|
438
|
+
- `src/api/apiHandler.js` exists
|
|
439
|
+
- `.env` has REACT_APP_KEY, REACT_APP_IV, REACT_APP_API_KEY
|
|
440
|
+
|
|
441
|
+
**Legacy** if any of the above is false.
|
|
442
|
+
|
|
443
|
+
---
|
|
444
|
+
|
|
445
|
+
### Phase 4 — Deep Scan Database
|
|
446
|
+
|
|
447
|
+
For each database location found in Phase 1c:
|
|
448
|
+
|
|
449
|
+
#### 4a — Determine Database Type
|
|
450
|
+
|
|
451
|
+
If not already determined from service scans:
|
|
452
|
+
- Check folder name: `postgresql/`, `postgres/`, `mysql/`, `mongodb/`
|
|
453
|
+
- Check file extensions: `.sql` → relational; `.js` with Schema → MongoDB
|
|
454
|
+
- Check first SQL file header comments
|
|
455
|
+
- Check for `CREATE TABLE` → SQL-based
|
|
456
|
+
- Check for `mongoose.Schema` or `new Schema(` → MongoDB
|
|
457
|
+
|
|
458
|
+
#### 4b — Parse SQL Migration Files
|
|
459
|
+
|
|
460
|
+
For SQL databases, scan ALL `.sql` files regardless of naming convention.
|
|
461
|
+
Do NOT require the agent's `N-setup-tbl-*.sql` naming pattern.
|
|
462
|
+
|
|
463
|
+
For each `.sql` file found, parse for:
|
|
464
|
+
|
|
465
|
+
**CREATE TABLE statements:**
|
|
466
|
+
- Extract table name (remove schema prefix if present, e.g. `public.`)
|
|
467
|
+
- Extract all column definitions:
|
|
468
|
+
- Column name
|
|
469
|
+
- Data type (normalize to lowercase)
|
|
470
|
+
- Constraints (NOT NULL, DEFAULT, CHECK, UNIQUE)
|
|
471
|
+
- PRIMARY KEY columns
|
|
472
|
+
- Extract inline index definitions
|
|
473
|
+
- Note any seed INSERT statements in the same file
|
|
474
|
+
|
|
475
|
+
**ALTER TABLE statements:**
|
|
476
|
+
- ADD COLUMN → record column addition with table name
|
|
477
|
+
- RENAME COLUMN → record rename (from → to) with table name
|
|
478
|
+
- DROP COLUMN → record column removal with table name
|
|
479
|
+
- ADD CONSTRAINT → record constraint addition
|
|
480
|
+
- Modify type → record type change
|
|
481
|
+
|
|
482
|
+
**CREATE INDEX statements:**
|
|
483
|
+
- Extract index name, table name, columns
|
|
484
|
+
|
|
485
|
+
**DROP TABLE statements:**
|
|
486
|
+
- Record that the table was dropped
|
|
487
|
+
|
|
488
|
+
Apply changes in file sort order:
|
|
489
|
+
- Try numeric prefix first: `1-*.sql`, `2-*.sql`, etc.
|
|
490
|
+
- Try timestamp prefix: `20240101_*.sql`
|
|
491
|
+
- Try V-prefix Flyway style: `V1__*.sql`, `V2__*.sql`
|
|
492
|
+
- If no order can be determined → process alphabetically and note it
|
|
493
|
+
|
|
494
|
+
Build the final effective schema state from all migrations in order.
|
|
495
|
+
The last state is what goes into `context.db.schema.tables`.
|
|
496
|
+
|
|
497
|
+
#### 4c — Parse MongoDB Schema Files
|
|
498
|
+
|
|
499
|
+
For MongoDB, scan ALL files for mongoose Schema definitions.
|
|
500
|
+
|
|
501
|
+
For each Schema found → extract:
|
|
502
|
+
- Model name (from `mongoose.model('ModelName', schema)`)
|
|
503
|
+
- All field definitions with types and constraints
|
|
504
|
+
- Indexes defined with `schema.index()`
|
|
505
|
+
|
|
506
|
+
Convert model name to snake_case for context key.
|
|
507
|
+
Example: `UserBot` → stored as `user_bots`
|
|
508
|
+
|
|
509
|
+
#### 4d — Find Non-Standard Schema Definitions
|
|
510
|
+
|
|
511
|
+
For legacy projects that define schema in code rather than files:
|
|
512
|
+
|
|
513
|
+
Scan ALL JavaScript files for ORM model definitions:
|
|
514
|
+
- Sequelize: `sequelize.define('model', {...})` or `DataTypes.*` in object
|
|
515
|
+
- TypeORM: `@Entity()`, `@Column()` decorators
|
|
516
|
+
- Prisma: check `prisma/schema.prisma`
|
|
517
|
+
- Knex: check migration files in any `migrations/` folder
|
|
518
|
+
|
|
519
|
+
For each found → extract model/table name and column list as best
|
|
520
|
+
as possible. Note in sync report that schema was inferred from ORM
|
|
521
|
+
definitions, not raw SQL.
|
|
522
|
+
|
|
523
|
+
#### 4e — Infer Schema From Query Patterns (last resort)
|
|
524
|
+
|
|
525
|
+
If no migration files, schema files, or ORM models are found, but
|
|
526
|
+
a database driver IS present in the service:
|
|
527
|
+
|
|
528
|
+
Scan all model files (`*_model.js`, `*Model.js`, `*model.js`,
|
|
529
|
+
files in `models/` directories) for SQL query strings:
|
|
530
|
+
- `SELECT * FROM <table>` → table name hint
|
|
531
|
+
- `INSERT INTO <table>` → table name hint
|
|
532
|
+
- Column names in SELECT lists → column hints
|
|
533
|
+
- Column names in WHERE clauses → column hints
|
|
534
|
+
|
|
535
|
+
This is low-confidence data. Tag all values inferred this way as
|
|
536
|
+
`confidence: "low"` and list them clearly in the sync report as
|
|
537
|
+
requiring manual verification.
|
|
538
|
+
|
|
539
|
+
---
|
|
540
|
+
|
|
541
|
+
### Phase 5 — Infer Cross-Service Relationships
|
|
542
|
+
|
|
543
|
+
After scanning all services individually, look for connections:
|
|
544
|
+
|
|
545
|
+
#### 5a — ReactJS → NodeJS linking
|
|
546
|
+
|
|
547
|
+
For each ReactJS service:
|
|
548
|
+
- Take the extracted API base URL port from Phase 3c
|
|
549
|
+
- Find the NodeJS service whose port matches
|
|
550
|
+
- Set `linked_service` to that service's name
|
|
551
|
+
- If no match found → note as "unlinked frontend" in sync report
|
|
552
|
+
|
|
553
|
+
#### 5b — Shared Database
|
|
554
|
+
|
|
555
|
+
Check if multiple services share the same DB connection config
|
|
556
|
+
(same host, port, name) → they share a database. Note this in report.
|
|
557
|
+
|
|
558
|
+
#### 5c — Port Inventory
|
|
559
|
+
|
|
560
|
+
Build a complete port registry across all services found.
|
|
561
|
+
Check for port conflicts (two services on the same port).
|
|
562
|
+
If conflict found → flag in sync report as requires manual resolution.
|
|
563
|
+
|
|
564
|
+
#### 5d — Shared Utilities or Libraries
|
|
565
|
+
|
|
566
|
+
Check if any service directories import from each other or from a
|
|
567
|
+
shared `lib/`, `shared/`, or `common/` directory at repository root.
|
|
568
|
+
Note shared dependencies in the sync report — they may indicate
|
|
569
|
+
a monorepo pattern that context should record.
|
|
570
|
+
|
|
571
|
+
#### 5e — Environment Variable Cross-References
|
|
572
|
+
|
|
573
|
+
If multiple services have `.env` files, check whether any service
|
|
574
|
+
references another service's port in its config
|
|
575
|
+
(e.g. one service's REDIS_HOST pointing to another service's host).
|
|
576
|
+
Record these links as `service_dependencies` in context.
|
|
577
|
+
|
|
578
|
+
---
|
|
579
|
+
|
|
580
|
+
### Phase 6 — Conflict Resolution
|
|
581
|
+
|
|
582
|
+
Before writing context, check for conflicts between scan results
|
|
583
|
+
and existing context (Mode A only — skip in Mode B):
|
|
584
|
+
|
|
585
|
+
For each discovered value that differs from an existing context value:
|
|
586
|
+
- Collect all conflicts into a list
|
|
587
|
+
- Show the user a conflict summary with current vs discovered values
|
|
588
|
+
- Ask user to confirm which to keep, ONE conflict at a time
|
|
589
|
+
- Do not write context until all conflicts are resolved
|
|
590
|
+
|
|
591
|
+
Example conflict:
|
|
592
|
+
"Port for service 'auth' in context.json: 1001
|
|
593
|
+
Port found in auth/.env on disk: 1002
|
|
594
|
+
Which is correct? (context / disk)"
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
### Phase 7 — Build Context Updates
|
|
599
|
+
|
|
600
|
+
Construct the full delta object to pass to context_write:
|
|
601
|
+
|
|
602
|
+
#### 7a — For each service found:
|
|
603
|
+
|
|
604
|
+
If service is NEW (not in context.services):
|
|
605
|
+
- Build full service entry from Phase 2 or Phase 3 scan results
|
|
606
|
+
- Set `sync_origin = "legacy"` if classified as legacy,
|
|
607
|
+
`sync_origin = "agent"` if agent-initialized
|
|
608
|
+
- Increment `services_synced` and `services_new` counters
|
|
609
|
+
|
|
610
|
+
If service is EXISTING (already in context.services):
|
|
611
|
+
- Only update fields that were empty/null in context AND found on disk
|
|
612
|
+
- Never overwrite a populated context value unless user confirmed it
|
|
613
|
+
in Phase 6
|
|
614
|
+
- Record what was filled in for the report
|
|
615
|
+
- Increment `services_synced` counter
|
|
616
|
+
|
|
617
|
+
Fields to sync per NodeJS service:
|
|
618
|
+
- name, port, description, author, package_name
|
|
619
|
+
- client_type, encrypted_transport, supported_languages
|
|
620
|
+
- encryption_key (if found in .env and not already in context)
|
|
621
|
+
- encryption_iv (if found in .env and not already in context)
|
|
622
|
+
- api_key (if found in .env and not already in context)
|
|
623
|
+
- redis_host, redis_port
|
|
624
|
+
- entry_point (actual path if different from app.js)
|
|
625
|
+
- tech_stack.dependencies (full list from package.json)
|
|
626
|
+
- middleware_stack (list of detected middleware types)
|
|
627
|
+
- sync_origin, last_synced_at = ISO now
|
|
628
|
+
|
|
629
|
+
Fields to sync per ReactJS service:
|
|
630
|
+
- name, port, description
|
|
631
|
+
- linked_service, linked_service_port
|
|
632
|
+
- tech_stack.dependencies
|
|
633
|
+
- sync_origin, last_synced_at = ISO now
|
|
634
|
+
|
|
635
|
+
#### 7b — For each route found:
|
|
636
|
+
|
|
637
|
+
If route is NEW (not in context.api_routes):
|
|
638
|
+
- Add to api_routes[] with: service, method, path, version, module
|
|
639
|
+
- Increment `routes_discovered` and `routes_new` counters
|
|
640
|
+
|
|
641
|
+
If route ALREADY in context.api_routes:
|
|
642
|
+
- Increment `routes_discovered` counter only
|
|
643
|
+
|
|
644
|
+
#### 7c — For database:
|
|
645
|
+
|
|
646
|
+
If db.type was empty in context:
|
|
647
|
+
- Set db.type, db.name, db.host, db.port, db.user from scan results
|
|
648
|
+
|
|
649
|
+
For each table found during scan:
|
|
650
|
+
- If NEW → add to context.db.schema.tables with full column list
|
|
651
|
+
Increment `db_tables_new`
|
|
652
|
+
- If EXISTING → merge any new columns found on disk that are not
|
|
653
|
+
in context (may happen if migration was added manually)
|
|
654
|
+
- Increment `db_tables_synced` counter
|
|
655
|
+
|
|
656
|
+
#### 7d — Set top-level context fields:
|
|
657
|
+
|
|
658
|
+
- If `project_name` is empty → set to first service name found
|
|
659
|
+
- If `initialized_at` is empty → set to ISO now
|
|
660
|
+
- Set `last_command` = "sync"
|
|
661
|
+
- Set `last_updated_at` = ISO now
|
|
662
|
+
- Set `last_command_at` = ISO now
|
|
663
|
+
|
|
664
|
+
---
|
|
665
|
+
|
|
666
|
+
### Phase 8 — Write Context
|
|
667
|
+
|
|
668
|
+
Call MCP tool `context_write` with:
|
|
669
|
+
- `updates` = full delta object from Phase 7
|
|
670
|
+
- `operation` = "sync"
|
|
671
|
+
|
|
672
|
+
This ALWAYS runs — even if nothing changed.
|
|
673
|
+
context.json is always written at the end of @sync.
|
|
674
|
+
|
|
675
|
+
If context.json did not exist before → this creates it for the first time.
|
|
676
|
+
After context_write succeeds → call `context_clear_scratchpad` for
|
|
677
|
+
any stale `current_*` keys found in Phase 0.
|
|
678
|
+
|
|
679
|
+
---
|
|
680
|
+
|
|
681
|
+
### Phase 9 — Drift Detection (Mode A only)
|
|
682
|
+
|
|
683
|
+
This phase only runs when mode = A (agent-initialized project with
|
|
684
|
+
existing context). Skip entirely for Mode B — legacy projects have
|
|
685
|
+
no expected structure to drift from.
|
|
686
|
+
|
|
687
|
+
Drift detection is read-only. Nothing is modified. Findings are
|
|
688
|
+
informational only.
|
|
689
|
+
|
|
690
|
+
For each service in context.services where `sync_origin == "agent"`
|
|
691
|
+
(or sync_origin is absent, meaning it predates this sync versioning):
|
|
692
|
+
|
|
693
|
+
#### Check 1 — route_manager.js middleware order
|
|
694
|
+
|
|
695
|
+
Read: `<service>/modules/v1/route_manager.js`
|
|
696
|
+
Expected: middleware registered in this exact order:
|
|
697
|
+
1. rateLimiter
|
|
698
|
+
2. extractLanguage
|
|
699
|
+
3. validateApiKey
|
|
700
|
+
4. validateToken
|
|
701
|
+
5. decryptRequest (only if encrypted_transport == true)
|
|
702
|
+
|
|
703
|
+
How to check:
|
|
704
|
+
Scan all `router.use('/', ...)` lines in order.
|
|
705
|
+
Extract the middleware name from each line.
|
|
706
|
+
Compare the extracted order against the expected order above.
|
|
707
|
+
|
|
708
|
+
Drift conditions:
|
|
709
|
+
- Any middleware is missing → DRIFT: "Missing middleware: [name]"
|
|
710
|
+
- Any middleware appears in wrong position → DRIFT:
|
|
711
|
+
"[name] appears at position [n], expected position [m]"
|
|
712
|
+
- decryptRequest present when encrypted_transport == false → DRIFT:
|
|
713
|
+
"decryptRequest registered but encrypted_transport is false"
|
|
714
|
+
- decryptRequest absent when encrypted_transport == true → DRIFT:
|
|
715
|
+
"decryptRequest missing but encrypted_transport is true"
|
|
716
|
+
- asyncHandler not wrapping any middleware → DRIFT:
|
|
717
|
+
"asyncHandler wrapper missing on [middleware_name]"
|
|
718
|
+
|
|
719
|
+
---
|
|
720
|
+
|
|
721
|
+
#### Check 2 — encryption.js library consistency
|
|
722
|
+
|
|
723
|
+
Read: `<service>/utilities/encryption.js`
|
|
724
|
+
Expected: imports only the library matching context.services[<n>].client_type
|
|
725
|
+
- client_type == "reactjs" → should import crypto-js, not cryptlib
|
|
726
|
+
- client_type == "app" → should import cryptlib, not crypto-js
|
|
727
|
+
|
|
728
|
+
Drift conditions:
|
|
729
|
+
- File imports cryptlib but context says client_type == "reactjs" →
|
|
730
|
+
DRIFT: "encryption.js uses cryptlib but client_type is reactjs"
|
|
731
|
+
- File imports crypto-js but context says client_type == "app" →
|
|
732
|
+
DRIFT: "encryption.js uses crypto-js but client_type is app"
|
|
733
|
+
- File imports both libraries → DRIFT:
|
|
734
|
+
"encryption.js imports both crypto-js and cryptlib — only one should be active"
|
|
735
|
+
- Neither library found → DRIFT:
|
|
736
|
+
"encryption.js does not import any encryption library"
|
|
737
|
+
|
|
738
|
+
---
|
|
739
|
+
|
|
740
|
+
#### Check 3 — response.js encrypted_transport flag
|
|
741
|
+
|
|
742
|
+
Read: `<service>/utilities/response.js`
|
|
743
|
+
Expected: reads ENCRYPTED_TRANSPORT from process.env
|
|
744
|
+
|
|
745
|
+
Drift conditions:
|
|
746
|
+
- ENCRYPTED_TRANSPORT not referenced → DRIFT:
|
|
747
|
+
"response.js does not check ENCRYPTED_TRANSPORT — all responses
|
|
748
|
+
may be unencrypted regardless of config"
|
|
749
|
+
- res.json( appears directly → DRIFT:
|
|
750
|
+
"response.js calls res.json() directly — responses bypass the encryption wrapper"
|
|
751
|
+
|
|
752
|
+
---
|
|
753
|
+
|
|
754
|
+
#### Check 4 — headerValidator.js decryptRequest presence
|
|
755
|
+
|
|
756
|
+
Read: `<service>/middleware/headerValidator.js`
|
|
757
|
+
Expected based on context.services[<n>].encrypted_transport:
|
|
758
|
+
- true → decryptRequest function must be defined and exported
|
|
759
|
+
- false → decryptRequest must NOT be present
|
|
760
|
+
|
|
761
|
+
Drift conditions:
|
|
762
|
+
- Function present but encrypted_transport == false → DRIFT:
|
|
763
|
+
"headerValidator.js defines decryptRequest but encrypted_transport
|
|
764
|
+
is false — dead code"
|
|
765
|
+
- Function absent but encrypted_transport == true → DRIFT:
|
|
766
|
+
"headerValidator.js is missing decryptRequest but encrypted_transport
|
|
767
|
+
is true — request bodies will not be decrypted"
|
|
768
|
+
|
|
769
|
+
---
|
|
770
|
+
|
|
771
|
+
#### Check 5 — language file key parity
|
|
772
|
+
|
|
773
|
+
Read: all files in `<service>/languages/`
|
|
774
|
+
Expected: every language file has the same set of keys as en.js
|
|
775
|
+
|
|
776
|
+
Drift conditions:
|
|
777
|
+
- Any language file has fewer keys than en.js → DRIFT:
|
|
778
|
+
"[lang].js is missing [n] keys that exist in en.js: [list]"
|
|
779
|
+
- Any language file has extra keys → DRIFT:
|
|
780
|
+
"[lang].js has [n] extra keys not in en.js: [list]"
|
|
781
|
+
|
|
782
|
+
---
|
|
783
|
+
|
|
784
|
+
#### Check 6 — package.json dependencies vs expected
|
|
785
|
+
|
|
786
|
+
Read: `<service>/package.json` dependencies
|
|
787
|
+
|
|
788
|
+
Required packages always:
|
|
789
|
+
express, dotenv, localizify, moment, jsonwebtoken, ioredis,
|
|
790
|
+
nodemailer, firebase-admin, validatorjs, pg-format,
|
|
791
|
+
express-rate-limit, rand-token
|
|
792
|
+
|
|
793
|
+
Required by client_type:
|
|
794
|
+
- reactjs → crypto-js must be present
|
|
795
|
+
- app → cryptlib must be present
|
|
796
|
+
|
|
797
|
+
Required by db_type:
|
|
798
|
+
- postgresql → pg must be present
|
|
799
|
+
- mysql → mysql2 must be present
|
|
800
|
+
- mongodb → mongoose must be present
|
|
801
|
+
|
|
802
|
+
Drift conditions:
|
|
803
|
+
- Required package missing → DRIFT:
|
|
804
|
+
"package.json is missing required dependency: [package_name]"
|
|
805
|
+
- Wrong encryption package present → DRIFT:
|
|
806
|
+
"package.json has [wrong_package] but client_type is [type]"
|
|
807
|
+
|
|
808
|
+
---
|
|
809
|
+
|
|
810
|
+
#### Check 7 — model files pattern compliance
|
|
811
|
+
|
|
812
|
+
For each module in context.services[<n>].modules:
|
|
813
|
+
Read: `<service>/modules/v1/<ModuleName>/<module>_model.js`
|
|
814
|
+
|
|
815
|
+
Drift conditions:
|
|
816
|
+
- express imported → DRIFT:
|
|
817
|
+
"[module]_model.js imports express — model files must not use Express objects"
|
|
818
|
+
- res.json or res.status found → DRIFT:
|
|
819
|
+
"[module]_model.js calls res.json/res.status directly"
|
|
820
|
+
|
|
821
|
+
---
|
|
822
|
+
|
|
823
|
+
## Drift Report Format
|
|
824
|
+
|
|
825
|
+
After all checks complete, append to the sync report:
|
|
826
|
+
```
|
|
827
|
+
Drift Analysis
|
|
828
|
+
─────────────────────────────────────────
|
|
829
|
+
Files checked : [n]
|
|
830
|
+
Clean : [n] (no drift detected)
|
|
831
|
+
Drift found : [n] files
|
|
832
|
+
─────────────────────────────────────────
|
|
833
|
+
[If drift found:]
|
|
834
|
+
|
|
835
|
+
⚠ DRIFT DETECTED — manual review recommended
|
|
836
|
+
|
|
837
|
+
[service_name]/modules/v1/route_manager.js
|
|
838
|
+
→ Missing middleware: decryptRequest
|
|
839
|
+
|
|
840
|
+
[service_name]/utilities/encryption.js
|
|
841
|
+
→ encryption.js uses cryptlib but client_type is reactjs
|
|
842
|
+
─────────────────────────────────────────
|
|
843
|
+
NOTE: Drift is informational only. No files were modified.
|
|
844
|
+
Run @audit for deeper code quality analysis.
|
|
845
|
+
─────────────────────────────────────────
|
|
846
|
+
```
|
|
847
|
+
|
|
848
|
+
If no drift found:
|
|
849
|
+
```
|
|
850
|
+
Drift Analysis : ✓ All [n] files match expected structure
|
|
851
|
+
```
|
|
852
|
+
|
|
853
|
+
---
|
|
854
|
+
|
|
855
|
+
### Phase 10 — Sync Report
|
|
856
|
+
|
|
857
|
+
Display the full sync report.
|
|
858
|
+
|
|
859
|
+
```
|
|
860
|
+
┌─────────────────────────────────────────────────┐
|
|
861
|
+
│ @sync Complete │
|
|
862
|
+
└─────────────────────────────────────────────────┘
|
|
863
|
+
|
|
864
|
+
Mode : [Agent Project / Legacy Project]
|
|
865
|
+
─────────────────────────────────────────────────
|
|
866
|
+
Services scanned : [n] ([x] new, [y] updated, [z] unchanged)
|
|
867
|
+
Routes found : [n] ([x] new to context)
|
|
868
|
+
DB tables found : [n] ([x] new to context)
|
|
869
|
+
Gaps filled : [n]
|
|
870
|
+
Legacy inferences: [n] (values derived from code analysis)
|
|
871
|
+
─────────────────────────────────────────────────
|
|
872
|
+
[If Mode B or any legacy services found:]
|
|
873
|
+
|
|
874
|
+
⚙ Legacy Services Detected
|
|
875
|
+
─────────────────────────────────────────────────
|
|
876
|
+
[service_name] ([tech_type])
|
|
877
|
+
Entry point : [actual entry point file]
|
|
878
|
+
Port : [port or "not found — check manually"]
|
|
879
|
+
Routes found : [n] (from [location(s)])
|
|
880
|
+
DB driver : [driver or "not detected"]
|
|
881
|
+
Encryption : [library or "not detected"]
|
|
882
|
+
client_type : [value or "could not determine — set manually"]
|
|
883
|
+
Languages : [list or "none detected"]
|
|
884
|
+
Middleware : [list of detected types]
|
|
885
|
+
⚠ Values inferred from code — review and correct if needed
|
|
886
|
+
|
|
887
|
+
[Repeat per legacy service]
|
|
888
|
+
─────────────────────────────────────────────────
|
|
889
|
+
[If any low-confidence values were inferred:]
|
|
890
|
+
|
|
891
|
+
⚠ Low-Confidence Values (verify before using)
|
|
892
|
+
[service_name].port = [value] — inferred from [source]
|
|
893
|
+
[service_name].client_type = [value] — inferred from [source]
|
|
894
|
+
[list any others]
|
|
895
|
+
To correct: update context.json directly or re-run @sync
|
|
896
|
+
after adding a .env file with the correct values.
|
|
897
|
+
─────────────────────────────────────────────────
|
|
898
|
+
[If any misplaced database/ folders found:]
|
|
899
|
+
|
|
900
|
+
⚠ Misplaced Database Folder
|
|
901
|
+
Found: [path inside service folder]
|
|
902
|
+
Expected: [repo_root]/database/
|
|
903
|
+
Scanned and added to context — consider moving to repo root.
|
|
904
|
+
─────────────────────────────────────────────────
|
|
905
|
+
[If any port conflicts found:]
|
|
906
|
+
|
|
907
|
+
⚠ Port Conflicts
|
|
908
|
+
Port [port] is used by both: [service_a] and [service_b]
|
|
909
|
+
Review and update .env files to resolve before starting services.
|
|
910
|
+
─────────────────────────────────────────────────
|
|
911
|
+
[If any unlinked React frontends:]
|
|
912
|
+
|
|
913
|
+
⚠ Unlinked Frontend
|
|
914
|
+
[service_name] — no matching backend found for API URL: [url]
|
|
915
|
+
Set context.services.[service_name].linked_service manually
|
|
916
|
+
or re-run @sync after the backend is initialized.
|
|
917
|
+
─────────────────────────────────────────────────
|
|
918
|
+
[If non-JS projects found:]
|
|
919
|
+
|
|
920
|
+
ℹ Unsupported Tech Detected (recorded only, not parsed)
|
|
921
|
+
[folder_name] — [detected_tech]
|
|
922
|
+
─────────────────────────────────────────────────
|
|
923
|
+
[If Mode A — drift analysis section:]
|
|
924
|
+
|
|
925
|
+
[Drift report as formatted above]
|
|
926
|
+
─────────────────────────────────────────────────
|
|
927
|
+
Context updated : .codeninja/context/context.json ✓
|
|
928
|
+
─────────────────────────────────────────────────
|
|
929
|
+
```
|
|
930
|
+
|
|
931
|
+
After the report, run task: `show-final-summary`
|
|
932
|
+
|
|
933
|
+
---
|
|
934
|
+
|
|
935
|
+
## Inference Confidence Levels
|
|
936
|
+
|
|
937
|
+
When recording legacy-inferred values in context, tag each with:
|
|
938
|
+
|
|
939
|
+
**HIGH** — value read directly from a config file (.env, package.json,
|
|
940
|
+
explicit constant). Treat as fact.
|
|
941
|
+
|
|
942
|
+
**MEDIUM** — value inferred from code patterns (port from `.listen(PORT)`
|
|
943
|
+
where PORT came from a variable, not a literal).
|
|
944
|
+
Usable but should be confirmed.
|
|
945
|
+
|
|
946
|
+
**LOW** — value guessed from folder name, comment, or single ambiguous
|
|
947
|
+
occurrence. Always listed in the sync report. User should confirm.
|
|
948
|
+
|
|
949
|
+
Store as: `context.services[<n>].<field>_confidence = "high"|"medium"|"low"`
|
|
950
|
+
|
|
951
|
+
---
|
|
952
|
+
|
|
953
|
+
## What Sync Never Does
|
|
954
|
+
|
|
955
|
+
- Never modifies any source file — read only outside of context.json
|
|
956
|
+
- Never deletes service folders, SQL files, or any project files
|
|
957
|
+
- Never removes existing context entries
|
|
958
|
+
- Never overwrites a HIGH-confidence context value with a MEDIUM or
|
|
959
|
+
LOW inferred value without user confirmation
|
|
960
|
+
- Never assumes a value is correct if two files disagree on it —
|
|
961
|
+
flag the conflict and ask
|
|
962
|
+
- Never silently skips a directory — if it cannot be classified,
|
|
963
|
+
record it as unknown and mention it in the report
|
|
964
|
+
- Never runs drift detection on legacy services — only agent-initialized
|