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,59 @@
1
+ ---
2
+ type: task
3
+ name: ask-column-type
4
+ ---
5
+
6
+ Read `context.current_db.columns` — get the column name just added.
7
+ Let col = last column in the array.
8
+
9
+ Agent auto-detects suggested type based on column name pattern:
10
+
11
+ | Pattern | Suggested Type |
12
+ |----------------------|-----------------------------------------------------------|
13
+ | `*_id` | BIGINT NOT NULL DEFAULT 0 |
14
+ | `is_*` | BOOLEAN NOT NULL DEFAULT FALSE |
15
+ | `*_at` | TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP |
16
+ | `status` | INTEGER NOT NULL DEFAULT 0 CHECK (status IN (0, 1)) |
17
+ | `*_count`, `*_total` | BIGINT NOT NULL DEFAULT 0 |
18
+ | `*_price`, `*_amount`, `*_fee` | NUMERIC(18,8) NOT NULL DEFAULT 0.00000000 |
19
+ | `*_percentage`, `*_rate` | NUMERIC(6,2) NOT NULL DEFAULT 0.00 |
20
+ | `*_volume` | NUMERIC(20,8) NOT NULL DEFAULT 0.00000000 |
21
+ | `email` | VARCHAR(132) NOT NULL DEFAULT '' |
22
+ | `phone` | VARCHAR(16) NOT NULL DEFAULT '' |
23
+ | `password` | TEXT NOT NULL DEFAULT '' |
24
+ | `*_image`, `*_icon`, `*_url` | VARCHAR(255) NOT NULL DEFAULT '' |
25
+ | `*_name` (person) | VARCHAR(64) NOT NULL DEFAULT '' |
26
+ | `*_name` (entity) | VARCHAR(256) NOT NULL DEFAULT '' |
27
+ | `symbol` | VARCHAR(32) NOT NULL DEFAULT '' |
28
+ | `timezone` | VARCHAR(64) NOT NULL DEFAULT '' |
29
+ | `token`, `uuid` | TEXT NOT NULL DEFAULT '' |
30
+ | `payload`, `metadata`, `*_result`, `content` | JSON NOT NULL DEFAULT '{}' |
31
+ | `strategy` | VARCHAR(256) NOT NULL DEFAULT '' |
32
+ | `description`, `*_text`, `*_html` | TEXT NOT NULL DEFAULT '' |
33
+ | `version` | VARCHAR(64) NOT NULL DEFAULT '' |
34
+ | `ip` | VARCHAR(45) NOT NULL DEFAULT '' (supports IPv6) |
35
+ | default | VARCHAR(255) NOT NULL DEFAULT '' |
36
+
37
+ Display:
38
+ "Suggested type for '[col_name]': [suggested_type]"
39
+ "Press enter to accept or choose a different type."
40
+
41
+ Present quick options if suggestion might not fit:
42
+ 1. Use suggested: [suggested_type]
43
+ 2. VARCHAR with custom length
44
+ 3. TEXT
45
+ 4. INTEGER
46
+ 5. BIGINT
47
+ 6. BOOLEAN
48
+ 7. NUMERIC (custom precision)
49
+ 8. TIMESTAMPTZ
50
+ 9. JSON
51
+ 10. Enter manually
52
+
53
+ Wait for user selection or enter.
54
+
55
+ Validate manual entry: must be valid PostgreSQL type syntax.
56
+
57
+ Store result in: `context.current_db.columns[last].type`
58
+
59
+ Do not ask any other question in this task.
@@ -0,0 +1,66 @@
1
+ ---
2
+ type: task
3
+ name: ask-database-config
4
+ ---
5
+
6
+ ## Purpose
7
+ Collects all database connection details in a single grouped display.
8
+ Only called in manual init mode. In fast mode, these values are
9
+ auto-populated by generate-fast-defaults.
10
+
11
+ Read `context.db.type` to determine the correct port default.
12
+
13
+ ## Display
14
+
15
+ Show this grouped prompt:
16
+ ```
17
+ DATABASE CONNECTION
18
+ ───────────────────────────────────────────
19
+ Database name : [cursor — required]
20
+ Database host : localhost
21
+ Database port : [5432 / 3306 / 27017 based on db type]
22
+ Database user : [cursor — required]
23
+ Database password: (leave blank — added to .env manually)
24
+ ───────────────────────────────────────────
25
+ Press ENTER on any field to accept the shown default.
26
+ Name and user are required — no default exists for them.
27
+ ```
28
+
29
+ ## Field Rules
30
+
31
+ ### Database name
32
+ - Required — no default
33
+ - Validate: lowercase, no spaces, underscores allowed
34
+ - Example: ledgersystem, myapp_db
35
+ - Store in: `context.db.name`
36
+
37
+ ### Database host
38
+ - Default: `localhost`
39
+ - If user presses enter → use "localhost"
40
+ - Store in: `context.db.host`
41
+
42
+ ### Database port
43
+ - Default: determined by `context.db.type`:
44
+ - postgresql → 5432
45
+ - mysql → 3306
46
+ - mongodb → 27017
47
+ - If user presses enter → use the type default
48
+ - Validate: must be a valid port number (1–65535)
49
+ - Store in: `context.db.port`
50
+
51
+ ### Database user
52
+ - Required — no default
53
+ - Store in: `context.db.user`
54
+
55
+ ### Database password
56
+ - Not collected here — intentionally left out
57
+ - The .env file will have `DB_PASSWORD=` blank
58
+ - Developer fills it in manually after generation
59
+ - This is a security practice — passwords are never stored in context
60
+
61
+ ## After Collection
62
+
63
+ Inform user:
64
+ "Database config saved. Host: [host]:[port], DB: [name], User: [user]"
65
+
66
+ Do not ask any other question in this task.
@@ -0,0 +1,16 @@
1
+ ---
2
+ type: task
3
+ name: ask-database-host
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Enter the database host."
9
+
10
+ Show default: localhost
11
+
12
+ If user presses enter without input → use "localhost".
13
+
14
+ Store result in: `context.db.host`
15
+
16
+ Do not ask any other question in this task.
@@ -0,0 +1,18 @@
1
+ ---
2
+ type: task
3
+ name: ask-database-name
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Enter the database name."
9
+
10
+ Example: ledgersystem, myapp_db
11
+
12
+ Wait for user input.
13
+
14
+ Validate: lowercase, no spaces, underscores allowed.
15
+
16
+ Store result in: `context.db.name`
17
+
18
+ Do not ask any other question in this task.
@@ -0,0 +1,23 @@
1
+ ---
2
+ type: task
3
+ name: ask-database-port
4
+ ---
5
+
6
+ Read `context.db.type` to determine the suggested default:
7
+ - postgresql → 5432
8
+ - mysql → 3306
9
+ - mongodb → 27017
10
+
11
+ Ask the user exactly this question:
12
+
13
+ "Enter the database port."
14
+
15
+ Show suggested default based on db type.
16
+
17
+ If user presses enter without input → use the suggested default.
18
+
19
+ Validate: must be a valid port number (1–65535).
20
+
21
+ Store result in: `context.db.port`
22
+
23
+ Do not ask any other question in this task.
@@ -0,0 +1,30 @@
1
+ ---
2
+ type: task
3
+ name: ask-database-type
4
+ ---
5
+
6
+ Check `context.db.type` first.
7
+
8
+ If `context.db.type` already exists:
9
+ Inform user: "Your project is already using [db_type]."
10
+ Ask: "Do you want to use the same database for this service?"
11
+ - If yes → store existing value → return
12
+ - If no → continue asking
13
+
14
+ Ask the user exactly this question:
15
+
16
+ "Which database will this service use?"
17
+
18
+ Present options:
19
+ 1. PostgreSQL
20
+ 2. MySQL
21
+ 3. MongoDB
22
+
23
+ Wait for user selection.
24
+
25
+ Store result as:
26
+ - PostgreSQL → `context.db.type = "postgresql"`
27
+ - MySQL → `context.db.type = "mysql"`
28
+ - MongoDB → `context.db.type = "mongodb"`
29
+
30
+ Do not ask any other question in this task.
@@ -0,0 +1,14 @@
1
+ ---
2
+ type: task
3
+ name: ask-database-user
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Enter the database username."
9
+
10
+ Wait for user input.
11
+
12
+ Store result in: `context.db.user`
13
+
14
+ Do not ask any other question in this task.
@@ -0,0 +1,16 @@
1
+ ---
2
+ type: task
3
+ name: ask-design-description
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Describe what this feature or design should do."
9
+
10
+ Example: "Allow users to register, login, and manage sessions using JWT tokens."
11
+
12
+ Wait for user input. Accept free text.
13
+
14
+ Store result in: `context.current_design.description`
15
+
16
+ Do not ask any other question in this task.
@@ -0,0 +1,24 @@
1
+ ---
2
+ type: task
3
+ name: ask-design-target
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "What would you like to design?"
9
+
10
+ Present options:
11
+ 1. New feature (end-to-end: DB + API + frontend)
12
+ 2. New API endpoint only
13
+ 3. Database schema change
14
+ 4. Full new module (controller + service + model + routes)
15
+
16
+ Wait for user selection.
17
+
18
+ Store result in: `context.current_design.type`
19
+ - Option 1 → "feature"
20
+ - Option 2 → "api"
21
+ - Option 3 → "db_change"
22
+ - Option 4 → "module"
23
+
24
+ Do not ask any other question in this task.
@@ -0,0 +1,25 @@
1
+ ---
2
+ type: task
3
+ name: ask-encrypted-transport
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Should request and response bodies be AES encrypted in transit?"
9
+
10
+ Show guidance:
11
+ "If yes — all API responses will be encrypted using AES-256-CBC before
12
+ sending. The client must decrypt them. API key and IV will still be
13
+ collected and used for password encryption regardless of this choice."
14
+
15
+ Present options:
16
+ 1. Yes — encrypt request and response bodies
17
+ 2. No — plain JSON transport (encryption only used for passwords)
18
+
19
+ Wait for user selection.
20
+
21
+ Store result in: `context.current_init.encrypted_transport`
22
+ - Option 1 → true
23
+ - Option 2 → false
24
+
25
+ Do not ask any other question in this task.
@@ -0,0 +1,23 @@
1
+ ---
2
+ type: task
3
+ name: ask-encryption-iv
4
+ ---
5
+
6
+ Generate a secure suggested value: exactly first 16 alphanumeric characters of `context.current_init.encryption_key`.
7
+
8
+ Ask the user exactly this question:
9
+
10
+ "Enter the AES-256-CBC initialization vector (must be exactly 16 characters)."
11
+
12
+ Show: "Suggested (auto-generated): [generated_value]"
13
+ Show: "Press enter to use the suggested value, or type your own."
14
+
15
+ If user presses enter without input → use the generated value.
16
+
17
+ Validate:
18
+ - MUST be exactly 16 characters
19
+ - If not 16 characters → reject and explain: "AES-256-CBC IV requires exactly 16 characters. Please try again."
20
+
21
+ Store result in: `context.current_init.encryption_iv`
22
+
23
+ Do not ask any other question in this task.
@@ -0,0 +1,23 @@
1
+ ---
2
+ type: task
3
+ name: ask-encryption-key
4
+ ---
5
+
6
+ Generate a secure suggested value: exactly 32 random alphanumeric characters.
7
+
8
+ Ask the user exactly this question:
9
+
10
+ "Enter the AES-256 encryption key (must be exactly 32 characters)."
11
+
12
+ Show: "Suggested (auto-generated): [generated_value]"
13
+ Show: "Press enter to use the suggested value, or type your own."
14
+
15
+ If user presses enter without input → use the generated value.
16
+
17
+ Validate:
18
+ - MUST be exactly 32 characters
19
+ - If not 32 characters → reject and explain: "AES-256 requires exactly 32 characters. Please try again."
20
+
21
+ Store result in: `context.current_init.encryption_key`
22
+
23
+ Do not ask any other question in this task.
@@ -0,0 +1,20 @@
1
+ ---
2
+ type: task
3
+ name: ask-feature-name
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Enter a name for this feature or design."
9
+
10
+ Example: user-authentication, product-catalog, invoice-generation
11
+
12
+ Wait for user input.
13
+
14
+ Validate:
15
+ - Lowercase, hyphens allowed, no spaces
16
+ - This will become the filename: .codeninja/agent/designs/<name>.design.md
17
+
18
+ Store result in: `context.current_design.feature_name`
19
+
20
+ Do not ask any other question in this task.
@@ -0,0 +1,21 @@
1
+ ---
2
+ type: task
3
+ name: ask-http-method
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Which HTTP method will this endpoint use?"
9
+
10
+ Present options:
11
+ 1. GET
12
+ 2. POST
13
+ 3. PUT
14
+ 4. PATCH
15
+ 5. DELETE
16
+
17
+ Wait for user selection.
18
+
19
+ Store result in: `context.current_api.method`
20
+
21
+ Do not ask any other question in this task.
@@ -0,0 +1,46 @@
1
+ ---
2
+ type: task
3
+ name: ask-index-columns
4
+ ---
5
+
6
+ Read `context.current_db.table_name` and `context.db.schema.tables[<table>].columns`
7
+ to list available columns.
8
+
9
+ Display current columns:
10
+ "Columns in '[table_name]':
11
+ 1. id
12
+ 2. user_id
13
+ 3. email
14
+ 4. status
15
+ 5. is_deleted
16
+ 6. created_at
17
+ ..."
18
+
19
+ Ask the user exactly this question:
20
+
21
+ "Which column should this index cover?"
22
+
23
+ Wait for user selection (select one column number).
24
+
25
+ Store first column in: `context.current_db.index_columns = [<col>]`
26
+
27
+ Then ask:
28
+
29
+ "Is this a single-column index or a compound index (multiple columns)?"
30
+
31
+ Present options:
32
+ 1. Single column — done
33
+ 2. Compound — add another column
34
+
35
+ If compound:
36
+ Repeat: "Add the next column to this index (or 'done' to finish)."
37
+ Show remaining columns not yet selected.
38
+ Append each selection to `context.current_db.index_columns[]`
39
+ Until user selects 'done' or all columns are selected.
40
+
41
+ Note on compound index order:
42
+ "Tip: Put the most selective column first (e.g. email before is_deleted)."
43
+
44
+ Store final list in: `context.current_db.index_columns[]`
45
+
46
+ Do not ask any other question in this task.
@@ -0,0 +1,33 @@
1
+ ---
2
+ type: task
3
+ name: ask-index-file-placement
4
+ ---
5
+
6
+ Read `context.current_db.table_name` and check if that table's setup file
7
+ already exists in `database/<db_type>/migrations/`.
8
+
9
+ Auto-suggest based on context:
10
+ - If table was JUST created in this session → suggest option 1 (table's own file)
11
+ - If table already existed before this session → suggest option 2 (shared index file)
12
+
13
+ Ask the user exactly this question:
14
+
15
+ "Where should this index be defined?"
16
+
17
+ Present options:
18
+ 1. In the table's own setup file
19
+ (e.g. 7-setup-tbl-user-bots.sql)
20
+ → Best for: indexes tightly coupled to this table's structure
21
+
22
+ 2. In the shared index file (111-setup-database-indexes.sql)
23
+ → Best for: indexes added after initial setup, cross-service use
24
+
25
+ Show suggestion: "Suggested: [option] — [reason]"
26
+
27
+ Wait for user selection.
28
+
29
+ Store result in: `context.current_db.index_file`
30
+ - Option 1 → "table_file"
31
+ - Option 2 → "shared_file"
32
+
33
+ Do not ask any other question in this task.
@@ -0,0 +1,37 @@
1
+ ---
2
+ type: task
3
+ name: ask-index-sort-order
4
+ ---
5
+
6
+ Read `context.current_db.index_columns` to check which columns are in the index.
7
+
8
+ Auto-detect: if any column in index_columns ends in `_at` or is named `time`
9
+ or `event_time` → strongly suggest DESC for that column.
10
+
11
+ If no timestamp-like columns in index → skip this task entirely and
12
+ set `context.current_db.index_desc_columns = []`.
13
+
14
+ Ask the user exactly this question:
15
+
16
+ "Should any column in this index be sorted in descending order (DESC)?"
17
+
18
+ Show suggestion if applicable:
19
+ "Suggested: '[col_name]' DESC — common for timestamp columns used in
20
+ ORDER BY ... DESC queries."
21
+
22
+ Present options:
23
+ 1. Yes — one or more columns should be DESC
24
+ 2. No — all columns ascending (default)
25
+
26
+ Wait for user selection.
27
+
28
+ If Yes:
29
+ For each column in `context.current_db.index_columns`:
30
+ Ask: "Should '[col]' be ASC or DESC?"
31
+ Options: 1. ASC (default) 2. DESC
32
+ Store per-column sort direction.
33
+
34
+ Store result in: `context.current_db.index_desc_columns[]`
35
+ (list of column names that should be DESC)
36
+
37
+ Do not ask any other question in this task.
@@ -0,0 +1,42 @@
1
+ ---
2
+ type: task
3
+ name: ask-index-type
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "Is this a standard index or a partial index?"
9
+
10
+ Present options:
11
+ 1. Standard index — covers all rows in the table
12
+ 2. Partial index — only indexes rows matching a WHERE condition
13
+
14
+ Show guidance:
15
+ "Partial indexes are useful when queries always filter by a specific condition.
16
+ Example: WHERE is_deleted = FALSE — if you never query deleted records,
17
+ a partial index on active records only is smaller and faster."
18
+
19
+ Wait for user selection.
20
+
21
+ Store result in: `context.current_db.index_type`
22
+ - Option 1 → "standard"
23
+ - Option 2 → "partial"
24
+
25
+ If "partial":
26
+ Ask the user exactly this question:
27
+
28
+ "Enter the WHERE condition for this partial index."
29
+
30
+ Examples:
31
+ WHERE is_deleted = FALSE
32
+ WHERE status = 0
33
+ WHERE botstatus = 'Running'
34
+
35
+ Wait for input.
36
+
37
+ Validate: must start with WHERE or be a valid SQL condition.
38
+ (Agent can prepend WHERE if user forgets it.)
39
+
40
+ Store result in: `context.current_db.index_where_clause`
41
+
42
+ Do not ask any other question in this task.
@@ -0,0 +1,28 @@
1
+ ---
2
+ type: task
3
+ name: ask-init-mode
4
+ ---
5
+
6
+ Ask the user exactly this question:
7
+
8
+ "How would you like to set up this service?"
9
+
10
+ Present options:
11
+ 1. Fast setup — I'll auto-generate secure values for keys, ports,
12
+ and config. You only answer the essentials (9 questions).
13
+ 2. Manual setup — Walk me through every value one at a time
14
+ (22 questions).
15
+
16
+ Wait for user selection.
17
+
18
+ Store result in: `context.current_init.init_mode`
19
+ - Option 1 → "fast"
20
+ - Option 2 → "manual"
21
+
22
+ Show guidance based on selection:
23
+ - If fast → "Great. I'll generate secure defaults for all technical
24
+ config. You'll see everything in the summary before any files
25
+ are created — you can change any value there."
26
+ - If manual → "Understood. I'll ask you each value individually."
27
+
28
+ Do not ask any other question in this task.
@@ -0,0 +1,57 @@
1
+ ---
2
+ type: task
3
+ name: ask-linked-service
4
+ ---
5
+
6
+ Read `context.services` and filter for services where `type == "nodejs"`.
7
+
8
+ ## If no NodeJS services exist
9
+
10
+ Inform the user:
11
+
12
+ "A ReactJS frontend cannot be initialized without a linked NodeJS backend
13
+ service. No NodeJS services are registered in this project yet.
14
+
15
+ Please run @initialize-project and select NodeJS first, then come back to
16
+ initialize your ReactJS frontend."
17
+
18
+ Abort the workflow. Do not proceed.
19
+
20
+ ## If exactly one NodeJS service exists
21
+
22
+ Inform the user:
23
+ "Your ReactJS app will be linked to: [service_name] (port [port])"
24
+
25
+ Store automatically:
26
+ - `context.current_init.linked_service = <service_name>`
27
+ - `context.current_init.linked_service_port = <port>`
28
+ - `context.current_init.encryption_key = context.services[service_name].encryption_key`
29
+ - `context.current_init.encryption_iv = context.services[service_name].encryption_iv`
30
+ - `context.current_init.api_key = context.services[service_name].api_key`
31
+
32
+ Return without asking. Proceed to next step.
33
+
34
+ ## If multiple NodeJS services exist
35
+
36
+ Ask the user exactly this question:
37
+
38
+ "Which backend NodeJS service will this ReactJS app connect to?"
39
+
40
+ List only NodeJS services (skip reactjs and database-only entries):
41
+ 1. [service_name] — port [port] — [description]
42
+ 2. [service_name] — port [port] — [description]
43
+
44
+ Wait for user selection.
45
+
46
+ After selection, store:
47
+ - `context.current_init.linked_service = <selected_service_name>`
48
+ - `context.current_init.linked_service_port = <selected_port>`
49
+ - `context.current_init.encryption_key = context.services[selected].encryption_key`
50
+ - `context.current_init.encryption_iv = context.services[selected].encryption_iv`
51
+ - `context.current_init.api_key = context.services[selected].api_key`
52
+
53
+ Confirm to user:
54
+ "Linked to: [service_name]. Encryption keys and API key will be inherited
55
+ automatically — you will not be asked for them."
56
+
57
+ Do not ask any other question in this task.
@@ -0,0 +1,36 @@
1
+ ---
2
+ type: task
3
+ name: ask-modify-operation
4
+ ---
5
+
6
+ Read `context.current_db.table_name` to show context.
7
+
8
+ Ask the user exactly this question:
9
+
10
+ "What modification do you want to make to '[table_name]'?"
11
+
12
+ Present options:
13
+ 1. Add a new column
14
+ 2. Rename a column
15
+ 3. Drop a column
16
+ 4. Change a column's data type
17
+ 5. Add a CHECK constraint to an existing column
18
+ 6. Add a new index → (routes to @db:add-index)
19
+
20
+ Wait for user selection.
21
+
22
+ Store result in: `context.current_db.modify_operation`
23
+ - Option 1 → "add_column"
24
+ - Option 2 → "rename_column"
25
+ - Option 3 → "drop_column"
26
+ - Option 4 → "change_type"
27
+ - Option 5 → "add_constraint"
28
+ - Option 6 → "add_index"
29
+
30
+ If option 6 selected:
31
+ Store: `context.current_db.modify_operation = "add_index"`
32
+ Inform user: "This will run the @db:add-index workflow."
33
+ Return to workflow — do not trigger the sub-workflow directly.
34
+ The calling workflow (db-modify-table) will handle the route.
35
+
36
+ Do not ask any other question in this task.