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,29 @@
1
+ ---
2
+ type: task
3
+ name: ask-route-path
4
+ ---
5
+
6
+ Read `context.current_api.module_name` to suggest a default path.
7
+ Suggested default: /[module_name_lowercase]
8
+
9
+ Ask the user exactly this question:
10
+
11
+ "Enter the route path for this endpoint."
12
+
13
+ Show suggested default: /[module_name_lowercase]
14
+
15
+ Examples:
16
+ /products
17
+ /products/:id
18
+ /orders/:orderId/items
19
+
20
+ Wait for user input.
21
+
22
+ Validate:
23
+ - Must start with /
24
+ - Use :paramName for URL parameters
25
+ - Check against `context.api_routes` — must not be an exact duplicate of method+path in same service
26
+
27
+ Store result in: `context.current_api.route_path`
28
+
29
+ Do not ask any other question in this task.
@@ -0,0 +1,42 @@
1
+ ---
2
+ type: task
3
+ name: ask-seed-row-values
4
+ ---
5
+
6
+ Read `context.current_db.columns` to know what columns exist.
7
+ Read `context.current_db.seed_rows` to know which row number we are on.
8
+
9
+ Let current_row = length of seed_rows + 1.
10
+ Let total_rows = context.current_db.seed_count.
11
+
12
+ Display: "Entering values for row [current_row] of [total_rows]"
13
+
14
+ For each column in `context.current_db.columns`
15
+ (SKIP: `id` — auto-generated, `created_at` — auto-set):
16
+
17
+ Ask the user exactly this question:
18
+ "[col_name] ([type]):"
19
+
20
+ Show additional context if available:
21
+ - If column has CHECK constraint → show: "Allowed: [values]"
22
+ - If column has DEFAULT → show: "Default: [default] (press enter to use)"
23
+ - If column is `password` → warn: "⚠ Enter encrypted/hashed value only. Never plaintext."
24
+ - If column is BOOLEAN → show: "Enter: true or false"
25
+ - If column is a NUMERIC → show expected format: "Example: 0.00000000"
26
+
27
+ Wait for user input.
28
+
29
+ If user presses enter on a column with a DEFAULT → use the DEFAULT value.
30
+
31
+ Validate:
32
+ - CHECK constraint values → must match allowed list
33
+ - BOOLEAN → must be true/false
34
+ - INTEGER → must be numeric
35
+ - NUMERIC → must match precision format
36
+
37
+ Store: value for this column in current row
38
+
39
+ After all columns collected for this row:
40
+ Append complete row object to `context.current_db.seed_rows[]`
41
+
42
+ Do not ask any other question in this task beyond column value collection.
@@ -0,0 +1,22 @@
1
+ ---
2
+ type: task
3
+ name: ask-seed-rows-count
4
+ ---
5
+
6
+ Read `context.current_db.table_name` to show context.
7
+
8
+ Ask the user exactly this question:
9
+
10
+ "How many rows do you want to seed into '[table_name]'?"
11
+
12
+ Wait for user input.
13
+
14
+ Validate:
15
+ - Must be a positive integer
16
+ - Maximum 500 rows per seed operation (for performance)
17
+ - If more than 500 → inform: "For large datasets, consider importing a CSV
18
+ directly into the database. Seed files work best for small reference data."
19
+
20
+ Store result in: `context.current_db.seed_count`
21
+
22
+ Do not ask any other question in this task.
@@ -0,0 +1,16 @@
1
+ ---
2
+ type: task
3
+ name: ask-service-description
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Enter a short description for this service."
9
+
10
+ Example: "Handles authentication and authorization"
11
+
12
+ Wait for user input.
13
+
14
+ Store result in: `context.current_init.description`
15
+
16
+ Do not ask any other question in this task.
@@ -0,0 +1,27 @@
1
+ ---
2
+ type: task
3
+ name: ask-service-name
4
+ ---
5
+
6
+ Read `context.services` to get list of already initialized services.
7
+
8
+ If services exist, show them to the user:
9
+ "Existing services: [list]"
10
+
11
+ Ask the user exactly this question:
12
+
13
+ "Enter a name for this service."
14
+
15
+ Example: auth, ledger, payments, notifications
16
+
17
+ Wait for user input.
18
+
19
+ Validate:
20
+ - Lowercase only
21
+ - No spaces (hyphens or underscores allowed)
22
+ - Must NOT already exist in `context.services`
23
+ - If duplicate → inform user and ask again
24
+
25
+ Store result in: `context.current_init.service_name`
26
+
27
+ Do not ask any other question in this task.
@@ -0,0 +1,24 @@
1
+ ---
2
+ type: task
3
+ name: ask-service-port
4
+ ---
5
+
6
+ Read `context.services` and collect all ports already in use.
7
+
8
+ If ports are in use, show them:
9
+ "Ports already in use: [list]"
10
+
11
+ Ask the user exactly this question:
12
+
13
+ "Enter the port number for this service."
14
+
15
+ Wait for user input.
16
+
17
+ Validate:
18
+ - Must be a valid port number (1024–65535)
19
+ - Must NOT conflict with any port already in `context.services`
20
+ - If conflict → inform user and ask again
21
+
22
+ Store result in: `context.current_init.port`
23
+
24
+ Do not ask any other question in this task.
@@ -0,0 +1,40 @@
1
+ ---
2
+ type: task
3
+ name: ask-supported-languages
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Which languages should this service support?"
9
+
10
+ Show guidance:
11
+ "Enter language codes separated by commas. A separate language file will
12
+ be created for each one under languages/. The first language in the list
13
+ will be used as the default fallback."
14
+
15
+ Example input: en
16
+ Example input: en, ar
17
+ Example input: en, ar, fr, de
18
+
19
+ Wait for user input.
20
+
21
+ Parse input:
22
+ - Split by comma
23
+ - Trim whitespace from each code
24
+ - Convert to lowercase
25
+ - Remove duplicates
26
+
27
+ Validate:
28
+ - Must have at least one language
29
+ - Each code should be 2-5 characters (ISO 639-1 or locale codes)
30
+ - If user enters something like "english" → inform them to use
31
+ the language code format (e.g. "en") and ask again
32
+
33
+ Store result in: `context.current_init.supported_languages`
34
+ as an array: ["en", "ar", "fr"]
35
+
36
+ Inform user:
37
+ "Default language will be: [first_in_list]
38
+ Language files to be created: [en.js, ar.js, ...]"
39
+
40
+ Do not ask any other question in this task.
@@ -0,0 +1,36 @@
1
+ ---
2
+ type: task
3
+ name: ask-table-file-number
4
+ ---
5
+
6
+ Scan the `database/<db_type>/migrations/` directory (from context.db.type).
7
+
8
+ Read all existing filenames and extract their numeric prefixes.
9
+ Find the highest existing number.
10
+
11
+ Suggest: highest_number + 1
12
+
13
+ Special rule: if the file being created is a shared index file, always suggest 111
14
+ (or the next available number above 100 if 111 is taken).
15
+
16
+ Display to user:
17
+
18
+ "Existing migration files: [list filenames in order]"
19
+ "Next available number: [suggested_number]"
20
+
21
+ Ask the user exactly this question:
22
+
23
+ "Enter the file number for this migration."
24
+
25
+ Show suggested default: [suggested_number]
26
+
27
+ If user presses enter without input → use suggested value.
28
+
29
+ Validate:
30
+ - Must be a positive integer
31
+ - Must not already be in use by an existing file
32
+ - If conflict → inform user and ask again
33
+
34
+ Store result in: `context.current_db.file_number`
35
+
36
+ Do not ask any other question in this task.
@@ -0,0 +1,47 @@
1
+ ---
2
+ type: task
3
+ name: ask-table-indexes
4
+ ---
5
+
6
+ Read `context.current_db.columns` to analyze the columns defined so far.
7
+ Read `context.current_db.needs_status` and `context.current_db.needs_soft_delete`.
8
+
9
+ Agent auto-generates suggested indexes based on rules from database-agent.md:
10
+
11
+ 1. For every column ending in `_id` → suggest: `idx_<table>_<col_name>`
12
+ 2. If both `status` and `is_deleted` exist → suggest compound: `idx_<table>_status_is_deleted`
13
+ 3. If `created_at` exists on an event/log table → suggest: `idx_<table>_created_at` with DESC
14
+ 4. If `email` exists → suggest: `idx_<table>_email`
15
+ 5. If `symbol` exists → suggest: `idx_<table>_symbol`
16
+
17
+ Display to user:
18
+
19
+ "Suggested indexes based on your columns:
20
+ ✓ idx_<table>_<col1> ON (<col1>)
21
+ ✓ idx_<table>_<col2> ON (<col2>)
22
+ ✓ idx_<table>_status_is_deleted ON (status, is_deleted)"
23
+
24
+ Ask the user exactly this question:
25
+
26
+ "Accept all suggested indexes?"
27
+
28
+ Present options:
29
+ 1. Yes — use all suggested indexes
30
+ 2. Remove some — I want to deselect specific ones
31
+ 3. Add more — I want to add additional indexes
32
+ 4. Start from scratch — define indexes manually
33
+
34
+ Wait for user selection.
35
+
36
+ If "Remove some":
37
+ List indexes with checkboxes
38
+ Ask which to remove — one at a time
39
+
40
+ If "Add more":
41
+ Ask: "Describe the additional index (which column or columns?)"
42
+ Repeat until user is done
43
+
44
+ Store final list in: `context.current_db.indexes[]`
45
+ Each entry: `{ name: "idx_...", columns: [...], desc: true/false, where: null }`
46
+
47
+ Do not ask any other question in this task beyond index selection.
@@ -0,0 +1,32 @@
1
+ ---
2
+ type: task
3
+ name: ask-table-name
4
+ ---
5
+
6
+ Read `context.db.schema.tables` to get list of available tables.
7
+
8
+ If tables exist in context:
9
+ Ask the user exactly this question:
10
+
11
+ "Which table are you working with?"
12
+
13
+ List all tables from context.db.schema.tables.
14
+
15
+ Wait for user selection.
16
+
17
+ If no tables exist:
18
+ Ask the user exactly this question:
19
+
20
+ "Enter the table name."
21
+
22
+ Wait for user input.
23
+ Validate: snake_case, plural form recommended (e.g. users, products, orders)
24
+
25
+ If called from a @refactor workflow → store in: `context.current_refactor.table_name`
26
+ If called from any @db:* workflow → store in: `context.current_db.table_name`
27
+
28
+ Agent determines caller from `context.last_command`:
29
+ - "refactor" → use current_refactor
30
+ - any other value → use current_db
31
+
32
+ Do not ask any other question in this task.
@@ -0,0 +1,29 @@
1
+ ---
2
+ type: task
3
+ name: ask-table-needs-soft-delete
4
+ ---
5
+
6
+ Read `context.current_db.needs_status` — if true, auto-suggest YES for soft delete.
7
+
8
+ Agent determines recommendation:
9
+ - If table has status column → strongly recommend YES (soft delete pairs with status)
10
+ - Event/log tables → recommend NO (events are immutable, never "deleted")
11
+ - Reference data tables → depends on whether admin can deactivate records
12
+
13
+ Ask the user exactly this question:
14
+
15
+ "Should this table support soft delete? (is_deleted column instead of hard DELETE)"
16
+
17
+ Show recommendation: "Suggested: [YES/NO] — [reason]"
18
+
19
+ Present options:
20
+ 1. Yes — add is_deleted BOOLEAN NOT NULL DEFAULT FALSE
21
+ 2. No — records in this table will be hard deleted or never deleted
22
+
23
+ Wait for user selection.
24
+
25
+ Store result in: `context.current_db.needs_soft_delete`
26
+ - Option 1 → true
27
+ - Option 2 → false
28
+
29
+ Do not ask any other question in this task.
@@ -0,0 +1,30 @@
1
+ ---
2
+ type: task
3
+ name: ask-table-needs-status
4
+ ---
5
+
6
+ Read `context.current_db.table_purpose` to inform the suggestion.
7
+
8
+ Agent determines a recommendation based on table type:
9
+ - User/entity tables (users, admins, bots, products) → recommend YES
10
+ - Event/log/audit tables (notifications, patterns, chart events) → recommend NO
11
+ - Reference/lookup tables (country, strategy modules) → recommend NO (use is_deleted only if needed)
12
+ - Join/pivot tables → recommend NO
13
+
14
+ Ask the user exactly this question:
15
+
16
+ "Should this table include a 'status' column? (0 = Active, 1 = Inactive)"
17
+
18
+ Show recommendation: "Suggested: [YES/NO] — [reason based on table purpose]"
19
+
20
+ Present options:
21
+ 1. Yes — add status INTEGER NOT NULL DEFAULT 0 CHECK (status IN (0,1))
22
+ 2. No — this table does not need a status column
23
+
24
+ Wait for user selection.
25
+
26
+ Store result in: `context.current_db.needs_status`
27
+ - Option 1 → true
28
+ - Option 2 → false
29
+
30
+ Do not ask any other question in this task.
@@ -0,0 +1,28 @@
1
+ ---
2
+ type: task
3
+ name: ask-table-purpose
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Describe what this table will store and what it is used for."
9
+
10
+ Example: "Stores registered users of the platform including their profile,
11
+ contact details, and authentication information."
12
+
13
+ Example: "Tracks trading bot configurations created by users, including
14
+ their strategy settings and current running status."
15
+
16
+ Wait for user input. Accept free text.
17
+
18
+ Validate: must be at least 10 characters (not too vague).
19
+
20
+ Store result in: `context.current_db.table_purpose`
21
+
22
+ The agent uses this description to:
23
+ - Suggest appropriate column names and types
24
+ - Determine whether standard columns (status, is_deleted) are appropriate
25
+ - Suggest relevant indexes
26
+ - Write the comment header line in the SQL file
27
+
28
+ Do not ask any other question in this task.
@@ -0,0 +1,44 @@
1
+ ---
2
+ type: task
3
+ name: ask-table-seed-data
4
+ ---
5
+
6
+ Read `context.current_db.table_purpose` to determine suggestion.
7
+
8
+ Agent evaluates:
9
+ - Reference/master data tables (country, app_content, strategy_modules, admin) → suggest YES
10
+ - User-generated data tables → suggest NO
11
+ - Event/log tables → suggest NO
12
+
13
+ Ask the user exactly this question:
14
+
15
+ "Does this table need initial seed data?"
16
+
17
+ Show recommendation: "Suggested: [YES/NO] — [reason based on table type]"
18
+
19
+ Examples of seed data:
20
+ - tbl_admin → default admin user record
21
+ - tbl_app_content → About Us, Privacy Policy, Terms of Use entries
22
+ - tbl_strategy_modules → strategy type entries
23
+
24
+ Present options:
25
+ 1. Yes — this table needs initial data
26
+ 2. No — no seed data needed
27
+
28
+ Wait for user selection.
29
+
30
+ Store result in: `context.current_db.needs_seed`
31
+ - Option 1 → true
32
+ - Option 2 → false
33
+
34
+ If true:
35
+ Ask: "Will this seed data be added directly in the table setup file,
36
+ or in a separate seed file in seeds/?"
37
+
38
+ Present options:
39
+ 1. In the table setup file (for permanent reference/master data)
40
+ 2. In a separate seeds/ file (for development/testing data)
41
+
42
+ Store: `context.current_db.seed_location` = "inline" | "seeds_file"
43
+
44
+ Do not ask any other question in this task beyond seed location if applicable.
@@ -0,0 +1,32 @@
1
+ ---
2
+ type: task
3
+ name: ask-target-service
4
+ ---
5
+
6
+ Read `context.services` and list all initialized services.
7
+
8
+ If no services exist:
9
+ Inform user: "No services have been initialized yet. Run @initialize-project first."
10
+ Abort task.
11
+
12
+ If only one service exists:
13
+ Inform user: "Using service: [service_name]"
14
+ Store automatically: `context.current_action.service_name = <only_service>`
15
+ Return without asking.
16
+
17
+ If multiple services exist:
18
+ Ask the user exactly this question:
19
+
20
+ "Which service would you like to target?"
21
+
22
+ List all services with their type and port:
23
+ Example:
24
+ 1. auth (nodejs, port 1001)
25
+ 2. ledger (nodejs, port 1002)
26
+ 3. frontend (reactjs, port 3000)
27
+
28
+ Wait for user selection.
29
+
30
+ Store result in: `context.current_action.service_name`
31
+
32
+ Do not ask any other question in this task.
@@ -0,0 +1,20 @@
1
+ ---
2
+ type: task
3
+ name: ask-test-type
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "What would you like to do?"
9
+
10
+ Present options:
11
+ 1. Generate new test file for a module
12
+ 2. Run existing tests for a service
13
+
14
+ Wait for user selection.
15
+
16
+ Store result in: `context.current_test.type`
17
+ - Option 1 → "generate"
18
+ - Option 2 → "run"
19
+
20
+ Do not ask any other question in this task.
@@ -0,0 +1,38 @@
1
+ ---
2
+ type: task
3
+ name: ask-validation-library
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Which validation library would you like to use for this page?"
9
+
10
+ Present options:
11
+ 1. Yup — schema-based validation, works well with React (recommended)
12
+ 2. Parsley — jQuery-based, good for legacy HTML forms
13
+ 3. React Hook Form — built-in validation with minimal re-renders
14
+ 4. Validator.js — lightweight utility functions, no form binding
15
+ 5. Custom — I'll write plain validation functions (no library)
16
+
17
+ Wait for user selection.
18
+
19
+ Store result in: `context.current_action.validation_library`
20
+ - Option 1 → "yup"
21
+ - Option 2 → "parsley"
22
+ - Option 3 → "react-hook-form"
23
+ - Option 4 → "validatorjs"
24
+ - Option 5 → "custom"
25
+
26
+ Show confirmation based on selection:
27
+ - yup → "Yup will be added to package.json. Validation schema will be
28
+ built alongside the form."
29
+ - parsley → "Parsley will be loaded via CDN or installed as a package.
30
+ Fields will receive data-parsley-* attributes."
31
+ - react-hook-form → "React Hook Form will be added to package.json.
32
+ The form will use useForm() hook with register() on each field."
33
+ - validatorjs → "Validator.js will be added to package.json. Each
34
+ field will be validated using validator utility functions."
35
+ - custom → "No library will be installed. Validation logic will be
36
+ written as plain JavaScript functions in the component."
37
+
38
+ Do not ask any other question in this task.
@@ -0,0 +1,92 @@
1
+ ---
2
+ type: task
3
+ name: detect-repository-state
4
+ ---
5
+
6
+ ## Purpose
7
+ Inspects the repository to establish baseline state. Designed to be
8
+ fast on repeat activations by checking context_version before doing
9
+ any filesystem scanning.
10
+
11
+ ---
12
+
13
+ ## Step 0 — Check context directory exists
14
+
15
+ Check if `.codeninja/context/` directory exists on disk.
16
+ If it does not exist → create it now.
17
+ This ensures write-context never fails due to a missing directory,
18
+ even on the very first run before any context has been written.
19
+
20
+ ## Step 1 — Check context.json first
21
+
22
+ Attempt to read `.codeninja/context/context.json`.
23
+
24
+ If the file does not exist:
25
+ This is a fresh repository — must do full scan.
26
+ Set: `context.has_context_file = false`
27
+ Proceed to Step 2 (full scan).
28
+
29
+ If the file exists:
30
+ Read `context_version` and `last_command_at` from it.
31
+ Set: `context.has_context_file = true`
32
+
33
+ Check `last_command_at`:
34
+ - If less than 60 seconds ago → the agent just ran a command.
35
+ The repository state has not changed externally.
36
+ Skip filesystem scan entirely.
37
+ Set all repository_state values from context directly:
38
+ `context.repository_state = "existing"`
39
+ `context.detected_services = [keys from context.services]`
40
+ `context.detected_db = (context.db.type != "")`
41
+ Return immediately. Do not scan filesystem.
42
+
43
+ - If more than 60 seconds ago → enough time has passed that the
44
+ developer may have made changes manually.
45
+ Proceed to Step 2 (full scan).
46
+
47
+ ---
48
+
49
+ ## Step 2 — Full Filesystem Scan
50
+
51
+ Only runs on first activation or when time threshold exceeded.
52
+
53
+ Check for:
54
+ - Any folders with `package.json` or `app.js`
55
+ - Any `database/` folder
56
+ - Any `src/main.jsx` or `src/index.jsx` (React apps)
57
+
58
+ Set context values:
59
+ - `context.repository_state` = "empty" | "existing"
60
+ - `context.detected_services` = [] (list of folder names that look
61
+ like services — folders containing app.js or package.json)
62
+ - `context.detected_db` = true | false (database/ folder exists)
63
+
64
+ ---
65
+
66
+ ## Step 3 — External Modification Check
67
+
68
+ If `has_context_file` is true AND full scan ran:
69
+ Compare `context.detected_services` from scan against
70
+ `Object.keys(context.services)` from context.json.
71
+
72
+ If they differ:
73
+ Inform user:
74
+ "⚠ Repository has changed since last agent run.
75
+ Services on disk: [detected_services list]
76
+ Services in context: [context.services keys]
77
+ Consider running @sync to bring context up to date."
78
+
79
+ ---
80
+
81
+ ## Step 4 — Missing Context Warning
82
+
83
+ If `has_context_file` is false AND `repository_state` is "existing":
84
+ Inform user:
85
+ "Repository has files but no context.json found.
86
+ Run @sync to build context from existing code."
87
+
88
+ ---
89
+
90
+ ## Return
91
+
92
+ Return: `repository_state`