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