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,127 @@
1
+ ---
2
+ type: task
3
+ name: generate-enc-dec-html
4
+ agent: nodejs-agent
5
+ ---
6
+
7
+ # File: enc_dec.html
8
+
9
+ ## Purpose
10
+ A standalone browser-based tool for testing AES-256-CBC encryption and
11
+ decryption using the exact same KEY and IV configured for this service.
12
+ Used exclusively by developers during development and debugging to
13
+ manually encrypt values before sending them as API request bodies, or
14
+ to decrypt API responses for inspection. This file is gitignored and
15
+ never served by the Express app.
16
+
17
+ Only generated when `client_type == "reactjs"`. Not generated for
18
+ `client_type == "app"`.
19
+
20
+ ---
21
+
22
+ ## Key Detail — Pre-filled KEY and IV
23
+
24
+ This is the most important aspect of this file. The KEY and IV values
25
+ hardcoded into the JavaScript must be the exact values from
26
+ `context.current_init.encryption_key` and
27
+ `context.current_init.encryption_iv` collected during
28
+ `@initialize-project`.
29
+
30
+ The agent reads these values from context and writes them literally into
31
+ the JavaScript functions. Every time this file is generated it will have
32
+ the correct credentials for this specific service instance. This is what
33
+ makes the tool useful — the developer does not need to manually copy keys.
34
+
35
+ ---
36
+
37
+ ## HTML Structure
38
+
39
+ Single HTML file. No external CSS files. No server-side logic. All
40
+ styling is inline in a style block in head.
41
+
42
+ ### Head section
43
+ - `<title>` — use `<service_name> — Encryption & Decryption` where
44
+ service_name comes from `context.current_init.service_name`
45
+ - Load crypto-js from CDN:
46
+ `https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.2.0/crypto-js.min.js`
47
+ This is loaded as a script tag before the closing body tag.
48
+
49
+ ### Body section layout
50
+ - `<h1>` heading: `<SERVICE_NAME> — CryptoJS Encryption & Decryption`
51
+ using the service name from context in uppercase.
52
+ - A `<label>` for the input area with text "Plaintext / Ciphertext:"
53
+ - A `<textarea>` with id `"plaintext"`, 10 rows, 100 cols.
54
+ - Two `<button>` elements:
55
+ - First button: text "Encrypt", calls `encrypt()` on click
56
+ - Second button: text "Decrypt", calls `decrypt()` on click
57
+ - A "Clear" button that clears the textarea and both result divs.
58
+ - Two result boxes each with a visible border, padding, and
59
+ `overflow-wrap: break-word` so long cipher strings don't overflow:
60
+ - Box 1: heading "Encrypted Data:", result div with id `"encryptedData"`
61
+ - Box 2: heading "Decrypted Data:", result div with id `"decryptedData"`
62
+
63
+ ### CSS (inline in head style block)
64
+ - Buttons: background color `#9c8cc3`, font-weight 800, padding 10px,
65
+ border-radius 5px. Cursor pointer.
66
+ - Result boxes (class `box`): border `1px solid black`, padding 5px,
67
+ margin-top 25px, `overflow-wrap: break-word`.
68
+ - Body: font-family sans-serif, padding 20px, max-width 900px.
69
+
70
+ ---
71
+
72
+ ## JavaScript Functions
73
+
74
+ All functions are in a single script block before the closing body tag,
75
+ after the crypto-js CDN script tag.
76
+
77
+ ### Module-level key constants
78
+ At the top of the script block, define the KEY and IV as constants.
79
+ These are the pre-filled values from context:
80
+ ```
81
+ const ENCRYPTION_KEY = CryptoJS.enc.Utf8.parse("<context.current_init.encryption_key>");
82
+ const ENCRYPTION_IV = CryptoJS.enc.Utf8.parse("<context.current_init.encryption_iv>");
83
+ ```
84
+
85
+ Both parsed using `CryptoJS.enc.Utf8.parse` — consistent with how
86
+ `utilities/encryption.js` parses them for `client_type == "reactjs"`.
87
+
88
+ ### encrypt()
89
+ 1. Clear the decryptedData div.
90
+ 2. Read value from the plaintext textarea. Store as `plaintext`.
91
+ 3. Clear the plaintext textarea.
92
+ 4. If plaintext is empty — alert "Please enter text to encrypt." Return.
93
+ 5. Call `CryptoJS.AES.encrypt(plaintext, ENCRYPTION_KEY, { iv: ENCRYPTION_IV })`.
94
+ Call `.toString()` on the result to get the Base64 cipher string.
95
+ 6. Display the cipher string in the encryptedData div.
96
+
97
+ ### decrypt()
98
+ 1. Clear the encryptedData div.
99
+ 2. Read value from the plaintext textarea. Store as `ciphertext`.
100
+ 3. Clear the plaintext textarea.
101
+ 4. If ciphertext is empty — alert "Please enter ciphertext to decrypt." Return.
102
+ 5. Strip surrounding double-quote characters from ciphertext using:
103
+ `ciphertext.replace(/^"(.*)"$/, '$1')`
104
+ This handles the case where the developer pastes a JSON-encoded
105
+ string that has surrounding quotes.
106
+ 6. Call `CryptoJS.AES.decrypt(ciphertext, ENCRYPTION_KEY, { iv: ENCRYPTION_IV })`.
107
+ Call `.toString(CryptoJS.enc.Utf8)` to get the plaintext string.
108
+ 7. If the result is empty string — display "Decryption failed. Check
109
+ that the input is a valid cipher string." in the decryptedData div.
110
+ Return.
111
+ 8. Display the decrypted string in the decryptedData div.
112
+
113
+ ### clearAll()
114
+ 1. Set textarea value to empty string.
115
+ 2. Set encryptedData div innerText to empty string.
116
+ 3. Set decryptedData div innerText to empty string.
117
+
118
+ ---
119
+
120
+ ## What This File Does NOT Do
121
+
122
+ - Does not make any HTTP requests
123
+ - Does not import or use any Node.js modules
124
+ - Does not connect to the service in any way
125
+ - Does not store or transmit the KEY or IV anywhere
126
+ - Does not handle files or binary data — text only
127
+ - Is never served by Express — opened directly in browser by developer
@@ -0,0 +1,145 @@
1
+ ---
2
+ type: task
3
+ name: generate-enc-dec-php
4
+ agent: nodejs-agent
5
+ ---
6
+
7
+ # File: enc_dec.php
8
+
9
+ ## Purpose
10
+ A PHP-based tool for testing AES-256-CBC encryption and decryption using
11
+ the exact same KEY and IV configured for this service. Used exclusively
12
+ by developers during development. Runs as a PHP web page — the developer
13
+ opens it in a browser via a local PHP server or any server with PHP
14
+ installed. This file is gitignored and never part of the Node.js app.
15
+
16
+ Only generated when `client_type == "app"`. Not generated for
17
+ `client_type == "reactjs"`.
18
+
19
+ ---
20
+
21
+ ## Key Detail — Pre-filled KEY and IV
22
+
23
+ Same principle as enc_dec.html. The KEY and IV hardcoded into the PHP
24
+ must be the exact values from `context.current_init.encryption_key` and
25
+ `context.current_init.encryption_iv`.
26
+
27
+ The cryptlib PHP equivalent uses `openssl_encrypt` and `openssl_decrypt`
28
+ with AES-256-CBC. The key must be hashed with SHA-256 first to produce
29
+ a 32-byte key — this is how cryptlib derives its key from the raw KEY
30
+ string, and the PHP side must match exactly.
31
+
32
+ Key derivation in PHP:
33
+ `$secret = hash('sha256', '<context.current_init.encryption_key>')`
34
+
35
+ IV used directly as a plain string:
36
+ `$iv = '<context.current_init.encryption_iv>'`
37
+
38
+ ---
39
+
40
+ ## File Structure
41
+
42
+ The file is a single `.php` file that contains both HTML and PHP. The
43
+ HTML form renders first, then the PHP at the bottom processes the
44
+ submitted form and outputs results below the form.
45
+
46
+ ---
47
+
48
+ ## HTML Section (before closing body tag)
49
+
50
+ ### Head section
51
+ - `<meta charset="utf-8">`
52
+ - `<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">`
53
+ - `<title>` — `<service_name> — Encryption & Decryption` using service
54
+ name from context.
55
+ - CSS style block with:
56
+ - Body: font-family sans-serif, padding 20px, max-width 900px
57
+ - `#container`: max-width 900px, margin auto
58
+ - Labels: font-weight bold
59
+ - Textarea: width 100%, box-sizing border-box
60
+ - Submit buttons: padding 8px 16px, cursor pointer, margin-right 8px
61
+ - Result headings: cursor pointer, color #333, font-size 16px
62
+ - Result paragraphs: background #f5f5f5, padding 10px, word-break
63
+ break-all, border 1px solid #ddd
64
+
65
+ ### Body section
66
+ - `<div id="container">`
67
+ - `<h1>` heading: `<SERVICE_NAME> — Encryption & Decryption`
68
+ - `<div id="body">`
69
+ - HTML form with:
70
+ - `action="enc_dec.php"` method POST
71
+ - `enctype="multipart/form-data"`
72
+ - Label: "Text or Ciphertext"
73
+ - Textarea: `name="data"`, `id="data"`, `required`, 90 cols, 10 rows
74
+ - Submit button: `name="type"` `value="encrypt"` — text "Encrypt"
75
+ - Submit button: `name="type"` `value="decrypt"` — text "Decrypt"
76
+ - Reset button: `name="reset"` `value="Clear"` — text "Clear"
77
+
78
+ ### JavaScript section (before closing body tag)
79
+ Two JavaScript functions for click-to-copy functionality:
80
+
81
+ `CopyToClipboard(containerid)`:
82
+ Handles both IE (document.selection) and modern browsers
83
+ (window.getSelection). Selects the content of the element with the
84
+ given id and executes the browser copy command.
85
+
86
+ `clearContents(containerid)`:
87
+ Sets the value of the element with the given id to empty string.
88
+
89
+ ---
90
+
91
+ ## PHP Section (after closing html tag)
92
+
93
+ The PHP block processes the form submission. It runs after the HTML
94
+ has been sent to the browser.
95
+
96
+ ### Constants
97
+ ```
98
+ $encryptionMethod = 'AES-256-CBC';
99
+ $secret = hash('sha256', '<context.current_init.encryption_key>');
100
+ $iv = '<context.current_init.encryption_iv>';
101
+ ```
102
+
103
+ Note on key derivation: `hash('sha256', key)` produces a 64-character
104
+ hex string. PHP's `openssl_encrypt` with AES-256 requires a 32-byte
105
+ key. When passing a hex string, openssl uses the raw bytes — which for
106
+ a 64-char hex string gives 32 bytes. This is the correct behavior and
107
+ matches how cryptlib derives its key via `getHashSha256`.
108
+
109
+ ### Form processing
110
+ Check: `isset($_REQUEST['type']) && isset($_REQUEST['data']) && $_REQUEST['data'] != ''`
111
+
112
+ If not set or empty — output nothing. The page just shows the form.
113
+
114
+ **If type == "encrypt"**:
115
+ 1. Trim the input: `$plaintext = trim($_REQUEST['data'])`
116
+ 2. Encrypt: `$encrypt_value = openssl_encrypt($plaintext, $encryptionMethod, $secret, 0, $iv)`
117
+ 3. Output a result div containing:
118
+ - `<h2>` with `onclick="CopyToClipboard('p1')"` — text "COPY ENCRYPTED"
119
+ - `<p id="p1">` — the encrypted value wrapped in `htmlspecialchars()`
120
+ - `<h2>` with `onclick="CopyToClipboard('p2')"` — text "COPY ORIGINAL"
121
+ - `<p id="p2">` — the original input wrapped in `htmlspecialchars()`
122
+
123
+ **If type == "decrypt"**:
124
+ 1. Get ciphertext: `$enc = $_REQUEST['data']`
125
+ 2. Decrypt: `$decrypt_value = openssl_decrypt($enc, $encryptionMethod, $secret, 0, $iv)`
126
+ 3. Attempt JSON decode: `json_decode($decrypt_value)`
127
+ 4. Output a result div containing:
128
+ - `<h2>` with `onclick="CopyToClipboard('p1')"` — text "COPY ENCRYPTED"
129
+ - `<p id="p1">` — the original cipher input wrapped in `htmlspecialchars()`
130
+ - `<h2>` with `onclick="CopyToClipboard('p2')"` — text "COPY DECRYPTED"
131
+ - `<p id="p2">` — the decrypted value wrapped in `htmlspecialchars()`
132
+ - `<h2>` — text "JSON PARSED"
133
+ - `<pre>` — `htmlspecialchars(print_r(json_decode($decrypt_value), true))`
134
+ This shows the decoded JSON structure if the decrypted value is
135
+ valid JSON, making it easy to inspect API response structures.
136
+
137
+ ---
138
+
139
+ ## What This File Does NOT Do
140
+
141
+ - Does not connect to the Node.js service
142
+ - Does not use any PHP libraries beyond built-in openssl functions
143
+ - Does not store or log any encrypted or decrypted values
144
+ - Is not part of the Node.js application in any way
145
+ - Is never required or imported by any JS file
@@ -0,0 +1,159 @@
1
+ ---
2
+ type: task
3
+ name: generate-encryption
4
+ agent: nodejs-agent
5
+ ---
6
+
7
+ # File: utilities/encryption.js
8
+
9
+ ## Purpose
10
+ Single source of truth for all encryption and decryption operations in the
11
+ service. All other files that need to encrypt or decrypt call this module.
12
+ No other file in the service imports crypto-js or cryptlib directly.
13
+ The active library is determined once at module load from context — the
14
+ rest of the codebase never needs to know which library is active.
15
+
16
+ ---
17
+
18
+ ## Dependencies to Import
19
+
20
+ Read `context.services[<name>].client_type` to determine which library
21
+ to import:
22
+
23
+ - If `client_type == "reactjs"`:
24
+ Import `crypto-js` as `CryptoJS`
25
+
26
+ - If `client_type == "app"`:
27
+ Import `cryptlib`
28
+
29
+ No other crypto imports. Never import both.
30
+
31
+ ---
32
+
33
+ ## Module-Level Constants
34
+
35
+ ### key
36
+ Derived once at module load from `process.env.KEY`.
37
+
38
+ - If `client_type == "reactjs"`:
39
+ Parse using `CryptoJS.enc.Utf8.parse(process.env.KEY)`.
40
+ Result is a CryptoJS WordArray. Store as `key`.
41
+
42
+ - If `client_type == "app"`:
43
+ Derive using `cryptlib.getHashSha256(process.env.KEY, 32)`.
44
+ Result is a 32-byte derived key string. Store as `key`.
45
+
46
+ ### iv
47
+ Derived once at module load from `process.env.IV`.
48
+
49
+ - If `client_type == "reactjs"`:
50
+ Parse using `CryptoJS.enc.Utf8.parse(process.env.IV)`.
51
+ Result is a CryptoJS WordArray. Store as `iv`.
52
+
53
+ - If `client_type == "app"`:
54
+ Use `process.env.IV` directly as a plain string. Store as `iv`.
55
+
56
+ Both `key` and `iv` are module-level constants. They are never re-derived
57
+ on each function call. If `.env` values are missing at startup the module
58
+ will fail at load time — this is intentional and correct behavior.
59
+
60
+ ---
61
+
62
+ ## Functions
63
+
64
+ ---
65
+
66
+ ### encrypt(data)
67
+
68
+ **Purpose**: Takes any JavaScript value, serializes it, and returns an
69
+ AES-256-CBC encrypted cipher string. Called by `response.js` when
70
+ `ENCRYPTED_TRANSPORT` is true, and by any model function that needs to
71
+ encrypt a value before storing (e.g. passwords).
72
+
73
+ **Parameters**:
74
+ - `data` — any value: object, array, string, number. Never assume type.
75
+
76
+ **Flow**:
77
+
78
+ 1. Call `JSON.stringify(data)` to serialize the input to a string.
79
+ This handles all types uniformly including nested objects and arrays.
80
+
81
+ 2. Encrypt the serialized string:
82
+
83
+ - If `client_type == "reactjs"`:
84
+ Call `CryptoJS.AES.encrypt(serialized, key, { iv, mode: CryptoJS.mode.CBC })`.
85
+ Call `.toString()` on the result to get the Base64 cipher string.
86
+
87
+ - If `client_type == "app"`:
88
+ Call `cryptlib.encrypt(serialized, key, iv)`.
89
+ Result is already a string.
90
+
91
+ 3. Return the cipher string.
92
+
93
+ 4. This function is synchronous. Do not make it async — there is no I/O.
94
+ Callers that use await on it will still work, but the function itself
95
+ should not be declared async.
96
+
97
+ ---
98
+
99
+ ### decrypt(cipherText)
100
+
101
+ **Purpose**: Takes an AES-256-CBC cipher string and returns the original
102
+ JavaScript value. Called by `headerValidator.js` for API key, token, and
103
+ request body decryption. Called by any route that receives encrypted input.
104
+
105
+ **Parameters**:
106
+ - `cipherText` — encrypted string produced by `encrypt()` or by the
107
+ client-side counterpart (crypto-js in browser or cryptlib in app).
108
+
109
+ **Flow**:
110
+
111
+ 1. Validate input: if `cipherText` is null, undefined, empty string, or
112
+ not a string type — return `null` immediately without attempting
113
+ decryption. Do not throw.
114
+
115
+ 2. Decrypt the cipher string:
116
+
117
+ - If `client_type == "reactjs"`:
118
+ Call `CryptoJS.AES.decrypt(cipherText, key, { iv, mode: CryptoJS.mode.CBC })`.
119
+ Call `.toString(CryptoJS.enc.Utf8)` on the result to get the
120
+ plain UTF-8 string.
121
+
122
+ - If `client_type == "app"`:
123
+ Call `cryptlib.decrypt(cipherText, key, iv)`.
124
+ Result is a plain string.
125
+
126
+ 3. Call `JSON.parse()` on the decrypted string to restore the original
127
+ JavaScript value.
128
+
129
+ 4. Return the parsed value.
130
+
131
+ 5. Wrap steps 2–4 in a try/catch. On any error — return `null`.
132
+ Never throw from this function. Callers check for null return.
133
+ Never log inside this function — logging is the caller's responsibility.
134
+
135
+ 6. This function is synchronous. Do not make it async.
136
+
137
+ ---
138
+
139
+ ## Export
140
+ ```
141
+ module.exports = { encrypt, decrypt }
142
+ ```
143
+
144
+ No default export. Named exports only. Every file that imports this
145
+ module destructures exactly what it needs:
146
+ `const { encrypt, decrypt } = require('../utilities/encryption')`
147
+
148
+ ---
149
+
150
+ ## What This File Does NOT Do
151
+
152
+ - Does not read `req` or `res` — no Express objects
153
+ - Does not log — callers handle logging
154
+ - Does not throw — returns null on failure
155
+ - Does not conditionally skip encryption based on ENCRYPTED_TRANSPORT —
156
+ that decision belongs to `response.js`. This file always encrypts
157
+ when called.
158
+ - Does not import both crypto libraries — only the one matching
159
+ client_type is imported
@@ -0,0 +1,68 @@
1
+ ---
2
+ type: task
3
+ name: generate-fast-defaults
4
+ ---
5
+
6
+ This task auto-populates all non-essential context values silently
7
+ when `context.current_init.init_mode == "fast"`. It runs after the
8
+ essential questions are collected and before show-init-summary.
9
+
10
+ This task only runs for `project_type == "nodejs"`.
11
+ For `project_type == "reactjs"` — security values are inherited from
12
+ the linked backend via ask-linked-service and are never generated here.
13
+ The port and package defaults below still apply to reactjs.
14
+
15
+ ## Values to Auto-Generate
16
+
17
+ ### Database Config (nodejs only, if not already set)
18
+ - `context.db.host` → set to `"localhost"` if not already in context
19
+ - `context.db.port` → set based on `context.db.type`:
20
+ - postgresql → `5432`
21
+ - mysql → `3306`
22
+ - mongodb → `27017`
23
+
24
+ ### Service Port
25
+ - Scan all port values in `context.services`
26
+ - Find the highest port currently in use
27
+ - Set `context.current_init.port` → highest + 1
28
+ - If no services exist yet → set to `1001`
29
+ - Ensure the result does not conflict with any existing port
30
+
31
+ ### Package Info
32
+ - `context.current_init.package_name` → same value as
33
+ `context.current_init.service_name`
34
+ - `context.current_init.author` → empty string `""`
35
+
36
+ ### Security Values (nodejs only — never run for reactjs)
37
+ Generate all three using cryptographically random characters from the
38
+ set: `ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`
39
+
40
+ - `context.current_init.api_key` → 32 random characters
41
+ - `context.current_init.encryption_key` → exactly 32 random characters
42
+ - `context.current_init.encryption_iv` → first 16 characters of
43
+ `context.current_init.encryption_key`
44
+ Always derived from the key — never randomly generated.
45
+ Since encryption_key is always 32 characters, the first 16
46
+ characters are always exactly 16. No separate validation needed.
47
+
48
+ Validate after generation:
49
+ - encryption_key must be exactly 32 characters — regenerate if not
50
+ - encryption_iv must equal the first 16 characters of encryption_key —
51
+ re-derive if not
52
+
53
+ ### Redis Config (nodejs only — skip for reactjs)
54
+ - `context.current_init.redis_host` → `"localhost"`
55
+ - `context.current_init.redis_port` → `6379`
56
+
57
+ ## Important Rules
58
+
59
+ - Never overwrite a value that was already explicitly set by a
60
+ previous ask-* task in this session.
61
+ - Check each key before setting: if it already has a non-empty value
62
+ in `context.current_init` → skip it.
63
+ - This task is silent — it does not print anything to the user.
64
+ All auto-generated values will be visible in show-init-summary
65
+ where the user can review and change them.
66
+
67
+ Do not ask any question. Do not produce any output.
68
+ Store all values and return.
@@ -0,0 +1,79 @@
1
+ ---
2
+ type: task
3
+ name: generate-gitignore
4
+ agent: nodejs-agent
5
+ ---
6
+
7
+ # File: .gitignore
8
+
9
+ ## Purpose
10
+ Defines which files and directories Git should never track. Generated
11
+ once during `@initialize-project`. Ensures sensitive files (env,
12
+ keys, credentials), generated files (node_modules, logs), and
13
+ development tools (demo encryption files) are never committed.
14
+
15
+ ---
16
+
17
+ ## Contents
18
+
19
+ ### Always include (every NodeJS service)
20
+ ```
21
+ # Dependencies
22
+ node_modules/
23
+
24
+ # Environment variables
25
+ .env
26
+
27
+ # RSA keys and credentials
28
+ pem/
29
+
30
+ # Uploaded files and static assets
31
+ images/
32
+
33
+ # Log files
34
+ logger/logs/
35
+
36
+ # OS files
37
+ .DS_Store
38
+ Thumbs.db
39
+
40
+ # IDE files
41
+ .vscode/
42
+ .idea/
43
+ *.swp
44
+ *.swo
45
+
46
+ # codeninja MCP server dependencies (auto-installed by codeninja init)
47
+ .codeninja/node_modules/
48
+ ```
49
+
50
+ ### Include when `client_type == "reactjs"`
51
+ ```
52
+ # Encryption demo tool
53
+ enc_dec.html
54
+ ```
55
+
56
+ ### Include when `client_type == "app"`
57
+ ```
58
+ # Encryption demo tool
59
+ enc_dec.php
60
+ ```
61
+
62
+ ### Include when `client_type == "app"` (Firebase credentials)
63
+ ```
64
+ # Firebase service account
65
+ pem/service-file.json
66
+ ```
67
+
68
+ Note: `pem/` already covers this since the whole directory is ignored,
69
+ but the explicit line makes the intent clear to developers.
70
+
71
+ ---
72
+
73
+ ## What This File Does NOT Do
74
+
75
+ - Does not ignore `.env.example` — that file should be committed
76
+ so other developers know what variables are needed
77
+ - Does not ignore test files
78
+ - Does not ignore the document/ swagger folder
79
+ - Does not ignore database migration files