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.
- package/.gitattributes +11 -0
- package/README.md +293 -0
- package/agent/database-agent.md +504 -0
- package/agent/designs/README.md +10 -0
- package/agent/global-agent.md +236 -0
- package/agent/nodejs-agent.md +406 -0
- package/agent/reactjs-agent.md +260 -0
- package/cli.js +352 -0
- package/commands/audit.workflow.md +111 -0
- package/commands/create-api.workflow.md +99 -0
- package/commands/db-add-index.workflow.md +97 -0
- package/commands/db-create-table.workflow.md +132 -0
- package/commands/db-drop-table.workflow.md +103 -0
- package/commands/db-modify-table.workflow.md +159 -0
- package/commands/db-seed.workflow.md +99 -0
- package/commands/db-sync.workflow.md +100 -0
- package/commands/design.workflow.md +66 -0
- package/commands/initialize-project.workflow.md +500 -0
- package/commands/integrate-api.workflow.md +448 -0
- package/commands/modularize.workflow.md +329 -0
- package/commands/refactor.workflow.md +70 -0
- package/commands/sync.workflow.md +962 -0
- package/commands/test.workflow.md +40 -0
- package/commands/validate-page.workflow.md +543 -0
- package/mcp-server.js +842 -0
- package/package.json +24 -0
- package/tasks/README.md +283 -0
- package/tasks/add-health-route.task.md +103 -0
- package/tasks/ask-api-integration-scope.task.md +34 -0
- package/tasks/ask-api-key.task.md +23 -0
- package/tasks/ask-api-version.task.md +28 -0
- package/tasks/ask-client-type.task.md +24 -0
- package/tasks/ask-column-enum-values.task.md +51 -0
- package/tasks/ask-column-is-enum.task.md +39 -0
- package/tasks/ask-column-name.task.md +39 -0
- package/tasks/ask-column-position.task.md +39 -0
- package/tasks/ask-column-type.task.md +59 -0
- package/tasks/ask-database-config.task.md +66 -0
- package/tasks/ask-database-host.task.md +16 -0
- package/tasks/ask-database-name.task.md +18 -0
- package/tasks/ask-database-port.task.md +23 -0
- package/tasks/ask-database-type.task.md +30 -0
- package/tasks/ask-database-user.task.md +14 -0
- package/tasks/ask-design-description.task.md +16 -0
- package/tasks/ask-design-target.task.md +24 -0
- package/tasks/ask-encrypted-transport.task.md +25 -0
- package/tasks/ask-encryption-iv.task.md +23 -0
- package/tasks/ask-encryption-key.task.md +23 -0
- package/tasks/ask-feature-name.task.md +20 -0
- package/tasks/ask-http-method.task.md +21 -0
- package/tasks/ask-index-columns.task.md +46 -0
- package/tasks/ask-index-file-placement.task.md +33 -0
- package/tasks/ask-index-sort-order.task.md +37 -0
- package/tasks/ask-index-type.task.md +42 -0
- package/tasks/ask-init-mode.task.md +28 -0
- package/tasks/ask-linked-service.task.md +57 -0
- package/tasks/ask-modify-operation.task.md +36 -0
- package/tasks/ask-modularize-scope.task.md +31 -0
- package/tasks/ask-module-name.task.md +30 -0
- package/tasks/ask-new-column-name.task.md +21 -0
- package/tasks/ask-new-table-name.task.md +22 -0
- package/tasks/ask-old-column-name.task.md +22 -0
- package/tasks/ask-package-author.task.md +16 -0
- package/tasks/ask-package-name.task.md +23 -0
- package/tasks/ask-page-path.task.md +40 -0
- package/tasks/ask-primary-table.task.md +30 -0
- package/tasks/ask-project-figma.task.md +71 -0
- package/tasks/ask-project-info-doc.task.md +57 -0
- package/tasks/ask-project-scope-of-work.task.md +57 -0
- package/tasks/ask-project-type.task.md +24 -0
- package/tasks/ask-react-target-service.task.md +32 -0
- package/tasks/ask-redis-config.task.md +42 -0
- package/tasks/ask-redis-host.task.md +16 -0
- package/tasks/ask-redis-port.task.md +18 -0
- package/tasks/ask-refactor-type.task.md +26 -0
- package/tasks/ask-requires-auth.task.md +22 -0
- package/tasks/ask-response-mode.task.md +38 -0
- package/tasks/ask-route-description.task.md +20 -0
- package/tasks/ask-route-path.task.md +29 -0
- package/tasks/ask-seed-row-values.task.md +42 -0
- package/tasks/ask-seed-rows-count.task.md +22 -0
- package/tasks/ask-service-description.task.md +16 -0
- package/tasks/ask-service-name.task.md +27 -0
- package/tasks/ask-service-port.task.md +24 -0
- package/tasks/ask-supported-languages.task.md +40 -0
- package/tasks/ask-table-file-number.task.md +36 -0
- package/tasks/ask-table-indexes.task.md +47 -0
- package/tasks/ask-table-name.task.md +32 -0
- package/tasks/ask-table-needs-soft-delete.task.md +29 -0
- package/tasks/ask-table-needs-status.task.md +30 -0
- package/tasks/ask-table-purpose.task.md +28 -0
- package/tasks/ask-table-seed-data.task.md +44 -0
- package/tasks/ask-target-service.task.md +32 -0
- package/tasks/ask-test-type.task.md +20 -0
- package/tasks/ask-validation-library.task.md +38 -0
- package/tasks/detect-repository-state.task.md +92 -0
- package/tasks/generate-app.task.md +146 -0
- package/tasks/generate-common.task.md +330 -0
- package/tasks/generate-constants.task.md +123 -0
- package/tasks/generate-database.task.md +168 -0
- package/tasks/generate-docker-compose.task.md +298 -0
- package/tasks/generate-dockerfile.task.md +126 -0
- package/tasks/generate-dockerignore.task.md +123 -0
- package/tasks/generate-enc-dec-html.task.md +127 -0
- package/tasks/generate-enc-dec-php.task.md +145 -0
- package/tasks/generate-encryption.task.md +159 -0
- package/tasks/generate-fast-defaults.task.md +68 -0
- package/tasks/generate-gitignore.task.md +79 -0
- package/tasks/generate-headerValidator.task.md +377 -0
- package/tasks/generate-ide-configs.task.md +114 -0
- package/tasks/generate-ioRedis.task.md +120 -0
- package/tasks/generate-language-en.task.md +155 -0
- package/tasks/generate-logging.task.md +257 -0
- package/tasks/generate-model.task.md +180 -0
- package/tasks/generate-notification.task.md +251 -0
- package/tasks/generate-package-json.task.md +114 -0
- package/tasks/generate-rateLimiter.task.md +125 -0
- package/tasks/generate-react-api-client.task.md +169 -0
- package/tasks/generate-react-api-handler.task.md +102 -0
- package/tasks/generate-react-app-jsx.task.md +56 -0
- package/tasks/generate-react-dockerfile.task.md +175 -0
- package/tasks/generate-react-env.task.md +58 -0
- package/tasks/generate-react-gitignore.task.md +49 -0
- package/tasks/generate-react-htaccess.task.md +54 -0
- package/tasks/generate-react-index-html.task.md +53 -0
- package/tasks/generate-react-index-jsx.task.md +51 -0
- package/tasks/generate-react-package-json.task.md +77 -0
- package/tasks/generate-react-welcome-page.task.md +71 -0
- package/tasks/generate-readme.task.md +160 -0
- package/tasks/generate-response.task.md +202 -0
- package/tasks/generate-route-manager.task.md +173 -0
- package/tasks/generate-route.task.md +203 -0
- package/tasks/generate-swagger.task.md +290 -0
- package/tasks/generate-tbl-user-deviceinfo.task.md +75 -0
- package/tasks/generate-template.task.md +129 -0
- package/tasks/generate-validator.task.md +122 -0
- package/tasks/show-db-table-summary.task.md +66 -0
- package/tasks/show-final-summary.task.md +108 -0
- package/tasks/show-init-summary.task.md +257 -0
- 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,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.
|