@laxture/vibe-pm 0.1.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/LICENSE +190 -0
- package/README.md +120 -0
- package/README.zh-CN.md +119 -0
- package/dist/core/commands.d.ts +17 -0
- package/dist/core/config.d.ts +12 -0
- package/dist/core/index.d.ts +8 -0
- package/dist/core/logger.d.ts +23 -0
- package/dist/core/plugin.d.ts +2 -0
- package/dist/core/types.d.ts +42 -0
- package/dist/docs/template/_coding_style/general.md +114 -0
- package/dist/docs/template/_coding_style/go.md +158 -0
- package/dist/docs/template/_coding_style/java.md +154 -0
- package/dist/docs/template/_coding_style/python.md +195 -0
- package/dist/docs/template/_coding_style/rust.md +161 -0
- package/dist/docs/template/_coding_style/sql.md +321 -0
- package/dist/docs/template/_coding_style/typescript.md +237 -0
- package/dist/docs/template/agents-template.md +38 -0
- package/dist/docs/template/bug-fix/flow.md +189 -0
- package/dist/docs/template/constitution-template.md +119 -0
- package/dist/docs/template/design-spec/flow.md +194 -0
- package/dist/docs/template/dictionary-template.md +40 -0
- package/dist/docs/template/large-refactor/flow.md +242 -0
- package/dist/docs/template/large-refactor/regulations/migration-checklist.md +28 -0
- package/dist/docs/template/research/flow.md +161 -0
- package/dist/docs/template/side-job/flow.md +147 -0
- package/dist/docs/template/spec-driven-dev/flow.md +420 -0
- package/dist/docs/template/spec-template.md +190 -0
- package/dist/engine/errors.d.ts +28 -0
- package/dist/engine/flow-engine.d.ts +32 -0
- package/dist/engine/index.d.ts +3 -0
- package/dist/i18n/index.d.ts +2 -0
- package/dist/i18n/loader.d.ts +23 -0
- package/dist/i18n/prompts-en-US.d.ts +47 -0
- package/dist/i18n/prompts-zh-CN.d.ts +50 -0
- package/dist/i18n/types.d.ts +51 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +4886 -0
- package/dist/integration/dcp.d.ts +7 -0
- package/dist/integration/index.d.ts +1 -0
- package/dist/memory/errors.d.ts +11 -0
- package/dist/memory/index.d.ts +3 -0
- package/dist/memory/memory-system.d.ts +80 -0
- package/dist/memory/types.d.ts +157 -0
- package/dist/template/index.d.ts +3 -0
- package/dist/template/template-manager.d.ts +26 -0
- package/dist/template/types.d.ts +16 -0
- package/dist/token/backends/anthropic.d.ts +5 -0
- package/dist/token/backends/llama.d.ts +7 -0
- package/dist/token/backends/tiktoken.d.ts +7 -0
- package/dist/token/index.d.ts +3 -0
- package/dist/token/model-registry.d.ts +9 -0
- package/dist/token/token-counter.d.ts +17 -0
- package/dist/token/types.d.ts +39 -0
- package/dist/tui/components/collapsible.d.ts +9 -0
- package/dist/tui/components/empty-state.d.ts +7 -0
- package/dist/tui/data/task-status.d.ts +16 -0
- package/dist/tui/data/token-data.d.ts +16 -0
- package/dist/tui/index.d.ts +13 -0
- package/dist/tui/index.js +3293 -0
- package/dist/tui/slots/sidebar-content.d.ts +10 -0
- package/dist/tui/tui-plugin.d.ts +9 -0
- package/dist/tui/types.d.ts +63 -0
- package/package.json +63 -0
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
# SQL Coding Style
|
|
2
|
+
|
|
3
|
+
> This project uses SQLite (bun:sqlite) as the embedded database. The following conventions are adapted for SQLite characteristics while remaining compatible with general SQL best practices.
|
|
4
|
+
|
|
5
|
+
## General Formatting
|
|
6
|
+
|
|
7
|
+
- Use UTF-8 encoding consistently; line endings use LF
|
|
8
|
+
- SQL keywords **MUST be UPPERCASE** (`SELECT`, `FROM`, `WHERE`, `INSERT`, etc.)
|
|
9
|
+
- Indentation uses 2 spaces
|
|
10
|
+
- Recommended line length: no more than 100 characters
|
|
11
|
+
|
|
12
|
+
```sql
|
|
13
|
+
SELECT t.id,
|
|
14
|
+
t.name,
|
|
15
|
+
t.created_at
|
|
16
|
+
FROM tasks AS t
|
|
17
|
+
WHERE t.status = 'active'
|
|
18
|
+
AND t.created_at > ?
|
|
19
|
+
ORDER BY t.created_at DESC;
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Naming Conventions
|
|
23
|
+
|
|
24
|
+
### Database Name / Schema Name
|
|
25
|
+
|
|
26
|
+
- Use `snake_case`, all lowercase
|
|
27
|
+
- Example: `vibe_pm`
|
|
28
|
+
|
|
29
|
+
### Table Names
|
|
30
|
+
|
|
31
|
+
- Use `snake_case`, plural form (represents collections)
|
|
32
|
+
- Example: `tasks`, `task_steps`, `flow_definitions`
|
|
33
|
+
- No pinyin; use consistent English nouns
|
|
34
|
+
- Avoid SQL keywords (e.g. `order`, `group`, `select`) to avoid quoting
|
|
35
|
+
|
|
36
|
+
### Column Names
|
|
37
|
+
|
|
38
|
+
- Use `snake_case`, all lowercase
|
|
39
|
+
- Example: `session_id`, `created_at`, `is_active`
|
|
40
|
+
- Boolean columns use interrogative prefixes: `is_active`, `has_plan`, `can_proceed`
|
|
41
|
+
- Primary keys uniformly use `id`
|
|
42
|
+
- Foreign key format: `{referenced_table}_id` (e.g. `task_id` references `tasks.id`)
|
|
43
|
+
|
|
44
|
+
### Constraint Naming
|
|
45
|
+
|
|
46
|
+
Constraint names should be clear to facilitate quick identification during debugging:
|
|
47
|
+
|
|
48
|
+
| Constraint Type | Naming Format | Example |
|
|
49
|
+
|---------|---------|------|
|
|
50
|
+
| Primary Key | `{table}_{column}_pkey` | `tasks_id_pkey` |
|
|
51
|
+
| Unique Constraint | `{table}_{column1}_{column2}_uk` | `tasks_session_id_flow_uk` |
|
|
52
|
+
| Foreign Key | `{table}_{referenced_table}_fk` | `task_steps_task_fk` |
|
|
53
|
+
| Index | `idx_{table}_{column1}_{column2}` | `idx_tasks_status_created_at` |
|
|
54
|
+
|
|
55
|
+
```sql
|
|
56
|
+
-- Primary key constraint
|
|
57
|
+
CREATE TABLE tasks (
|
|
58
|
+
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
59
|
+
session_id TEXT NOT NULL,
|
|
60
|
+
CONSTRAINT tasks_session_id_flow_uk UNIQUE (session_id, flow)
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
-- Foreign key constraint
|
|
64
|
+
CREATE TABLE task_steps (
|
|
65
|
+
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
66
|
+
task_id INTEGER NOT NULL
|
|
67
|
+
REFERENCES tasks (id) ON DELETE CASCADE,
|
|
68
|
+
CONSTRAINT task_steps_task_fk FOREIGN KEY (task_id) REFERENCES tasks (id)
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
-- Indexes
|
|
72
|
+
CREATE INDEX idx_tasks_session_id ON tasks (session_id);
|
|
73
|
+
CREATE INDEX idx_tasks_status_created_at ON tasks (status, created_at);
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## DDL Conventions
|
|
77
|
+
|
|
78
|
+
### Primary Keys
|
|
79
|
+
|
|
80
|
+
- Use `INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT` (SQLite recommended approach)
|
|
81
|
+
- **No composite primary keys**; define `UNIQUE` constraints when a compound unique requirement exists
|
|
82
|
+
- In SQLite, `INTEGER PRIMARY KEY` automatically becomes a rowid alias, achieving optimal performance
|
|
83
|
+
|
|
84
|
+
```sql
|
|
85
|
+
-- ✅ Recommended
|
|
86
|
+
CREATE TABLE tasks (
|
|
87
|
+
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
88
|
+
...
|
|
89
|
+
);
|
|
90
|
+
|
|
91
|
+
-- ❌ Avoid
|
|
92
|
+
CREATE TABLE tasks (
|
|
93
|
+
id TEXT PRIMARY KEY, -- TEXT primary key has no rowid optimization
|
|
94
|
+
...
|
|
95
|
+
);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
### Foreign Keys
|
|
99
|
+
|
|
100
|
+
- Foreign key column type must match the referenced column type
|
|
101
|
+
- Add `ON DELETE CASCADE` when child table records should be deleted along with the parent
|
|
102
|
+
- Foreign key constraints are disabled by default; execute `PRAGMA foreign_keys = ON` when connecting
|
|
103
|
+
|
|
104
|
+
```sql
|
|
105
|
+
-- When parent record is deleted, related child records are also deleted
|
|
106
|
+
task_id INTEGER NOT NULL
|
|
107
|
+
REFERENCES tasks (id) ON DELETE CASCADE
|
|
108
|
+
|
|
109
|
+
-- Parent record protection — deletion forbidden when child records exist (default behavior)
|
|
110
|
+
flow_id INTEGER NOT NULL
|
|
111
|
+
REFERENCES flows (id)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### NOT NULL and DEFAULT
|
|
115
|
+
|
|
116
|
+
- Generally set columns to `NOT NULL` unless `NULL` carries specific business meaning
|
|
117
|
+
- `DEFAULT` and `NOT NULL` have different semantics; do not conflate them
|
|
118
|
+
|
|
119
|
+
```sql
|
|
120
|
+
-- ✅ Column does not allow null, no default value (must be provided on insert)
|
|
121
|
+
session_id TEXT NOT NULL
|
|
122
|
+
|
|
123
|
+
-- ✅ Column does not allow null, has default value
|
|
124
|
+
status TEXT NOT NULL DEFAULT 'pending'
|
|
125
|
+
|
|
126
|
+
-- ✅ Column allows null, no default value (NULL has business meaning)
|
|
127
|
+
closed_at TEXT -- NULL means not yet closed
|
|
128
|
+
|
|
129
|
+
-- ✅ Column allows null, has default value
|
|
130
|
+
priority TEXT DEFAULT 'medium'
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Type Selection
|
|
134
|
+
|
|
135
|
+
SQLite uses type affinity; explicitly using standard type names is recommended:
|
|
136
|
+
|
|
137
|
+
| Scenario | Recommended Type | Notes |
|
|
138
|
+
|------|---------|------|
|
|
139
|
+
| Primary key / auto-increment ID | `INTEGER` | Leverages rowid optimization |
|
|
140
|
+
| Boolean | `INTEGER NOT NULL DEFAULT 0` | 0 = false, 1 = true |
|
|
141
|
+
| Short text / enum | `TEXT` | All character data |
|
|
142
|
+
| Long text / JSON | `TEXT` | Use with `json_extract()` / `json_set()` |
|
|
143
|
+
| Timestamp | `TEXT` | ISO 8601 format, e.g. `2026-06-26T00:00:00Z` |
|
|
144
|
+
| Float | `REAL` | IEEE 754 double precision |
|
|
145
|
+
| Binary | `BLOB` | File content / serialized data |
|
|
146
|
+
| Array / list | `TEXT` (store as JSON) | SQLite has no native arrays; use JSON arrays |
|
|
147
|
+
|
|
148
|
+
```sql
|
|
149
|
+
-- JSON array column
|
|
150
|
+
tags TEXT NOT NULL DEFAULT '[]', -- JSON array, default empty
|
|
151
|
+
-- Query: SELECT * FROM tasks WHERE json_extract(tags, '$[0]') = 'urgent';
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Audit Columns
|
|
155
|
+
|
|
156
|
+
Every business table should include the following audit columns:
|
|
157
|
+
|
|
158
|
+
```sql
|
|
159
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
|
160
|
+
modified_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
### Common Operational Columns
|
|
164
|
+
|
|
165
|
+
| Column | Type | Description |
|
|
166
|
+
|------|------|------|
|
|
167
|
+
| `deleted` | `INTEGER NOT NULL DEFAULT 0` | Soft delete flag, 0=normal 1=deleted |
|
|
168
|
+
| `seq` | `INTEGER NOT NULL DEFAULT 0` | Sort order, used with reorder interfaces |
|
|
169
|
+
| `tags` | `TEXT NOT NULL DEFAULT '[]'` | Tags in JSON array format, for easy filtering |
|
|
170
|
+
|
|
171
|
+
### Table Creation Conventions
|
|
172
|
+
|
|
173
|
+
- Use `CREATE TABLE IF NOT EXISTS` instead of `DROP + CREATE`
|
|
174
|
+
- Prefer `STRICT` mode for new projects (SQLite 3.37+)
|
|
175
|
+
|
|
176
|
+
```sql
|
|
177
|
+
-- SQLite 3.37+ STRICT mode (recommended)
|
|
178
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
179
|
+
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
180
|
+
session_id TEXT NOT NULL,
|
|
181
|
+
flow TEXT NOT NULL,
|
|
182
|
+
status TEXT NOT NULL DEFAULT 'running',
|
|
183
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
|
184
|
+
modified_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
|
185
|
+
deleted INTEGER NOT NULL DEFAULT 0,
|
|
186
|
+
CONSTRAINT tasks_session_id_flow_uk UNIQUE (session_id, flow)
|
|
187
|
+
) STRICT;
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
## DML Conventions
|
|
191
|
+
|
|
192
|
+
### Keywords and Formatting
|
|
193
|
+
|
|
194
|
+
- Break clauses onto new lines to maintain alignment and improve readability
|
|
195
|
+
- Do not use single-letter abbreviations for aliases (except `SELECT COUNT(*) FROM (...) AS c`)
|
|
196
|
+
|
|
197
|
+
```sql
|
|
198
|
+
-- ✅ Recommended: clear aliases
|
|
199
|
+
SELECT t.id,
|
|
200
|
+
t.session_id,
|
|
201
|
+
t.flow,
|
|
202
|
+
t.status
|
|
203
|
+
FROM tasks AS t
|
|
204
|
+
LEFT JOIN task_steps AS ts ON ts.task_id = t.id
|
|
205
|
+
WHERE t.status = 'running';
|
|
206
|
+
|
|
207
|
+
-- ❌ Avoid: meaningless short aliases
|
|
208
|
+
SELECT a.id, a.nm, a.st
|
|
209
|
+
FROM tasks AS a;
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Parameterized Queries
|
|
213
|
+
|
|
214
|
+
- **Strictly prohibit** string concatenation to construct SQL; always use parameterized queries
|
|
215
|
+
- Use `?` as parameter placeholders (bun:sqlite style)
|
|
216
|
+
|
|
217
|
+
```typescript
|
|
218
|
+
// ✅ Parameterized query
|
|
219
|
+
db.query('SELECT * FROM tasks WHERE session_id = ? AND status = ?', [
|
|
220
|
+
sessionId,
|
|
221
|
+
status,
|
|
222
|
+
]);
|
|
223
|
+
|
|
224
|
+
// ❌ String concatenation
|
|
225
|
+
db.query(`SELECT * FROM tasks WHERE session_id = '${sessionId}'`);
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
### Inline SQL
|
|
229
|
+
|
|
230
|
+
- When constructing SQL in code, preserve newlines and indentation for easier debugging
|
|
231
|
+
|
|
232
|
+
```typescript
|
|
233
|
+
const sql = [
|
|
234
|
+
'SELECT t.id, t.session_id, t.flow',
|
|
235
|
+
' FROM tasks AS t',
|
|
236
|
+
' WHERE t.status = ?',
|
|
237
|
+
' AND t.created_at > ?',
|
|
238
|
+
' ORDER BY t.created_at DESC',
|
|
239
|
+
].join('\n');
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### INSERT Statements
|
|
243
|
+
|
|
244
|
+
- Explicitly specify column names; do not rely on column order
|
|
245
|
+
|
|
246
|
+
```sql
|
|
247
|
+
-- ✅ Explicit column names
|
|
248
|
+
INSERT INTO tasks (session_id, flow, status)
|
|
249
|
+
VALUES (?, ?, 'running');
|
|
250
|
+
|
|
251
|
+
-- ❌ Omitting column names (fragile, order-dependent)
|
|
252
|
+
INSERT INTO tasks VALUES (?, ?, 'running');
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
### Batch Operations
|
|
256
|
+
|
|
257
|
+
- Wrap batch inserts in transactions for significantly improved performance
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
const insert = db.prepare('INSERT INTO tasks (session_id, flow) VALUES (?, ?)');
|
|
261
|
+
const insertMany = db.transaction((items: Array<{ sessionId: string; flow: string }>) => {
|
|
262
|
+
for (const item of items) {
|
|
263
|
+
insert.run(item.sessionId, item.flow);
|
|
264
|
+
}
|
|
265
|
+
});
|
|
266
|
+
insertMany(items);
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
## Migration Conventions
|
|
270
|
+
|
|
271
|
+
- Migration scripts follow the naming pattern `V{sequence}__{description}.sql`
|
|
272
|
+
- Use `CREATE TABLE IF NOT EXISTS` for table creation instead of DROP then CREATE
|
|
273
|
+
- Add columns using `ALTER TABLE ... ADD COLUMN` (SQLite limitation: no DROP COLUMN / ALTER COLUMN support)
|
|
274
|
+
- Migrations already applied in production **must not be modified**; create a new migration when changes are needed
|
|
275
|
+
|
|
276
|
+
## SQLite-Specific Best Practices
|
|
277
|
+
|
|
278
|
+
| Item | Recommendation | Notes |
|
|
279
|
+
|------|------|------|
|
|
280
|
+
| WAL Mode | Enable | `PRAGMA journal_mode=WAL;` improves concurrent read performance |
|
|
281
|
+
| Foreign Keys | Enable | `PRAGMA foreign_keys=ON;` must be executed per connection |
|
|
282
|
+
| Busy Timeout | Set | `PRAGMA busy_timeout=5000;` avoids SQLITE_BUSY |
|
|
283
|
+
| Strict Mode | Enable (3.37+) | `STRICT` tables disallow implicit type conversion |
|
|
284
|
+
| Connection Pool | Single connection | SQLite writes are serial; multiple connections provide no benefit; single connection + WAL is optimal |
|
|
285
|
+
|
|
286
|
+
## Anti-Patterns
|
|
287
|
+
|
|
288
|
+
| Anti-Pattern | Why It's Bad |
|
|
289
|
+
|--------|-----------|
|
|
290
|
+
| `SELECT *` | Column changes make code fragile; wastes IO |
|
|
291
|
+
| String concatenation for SQL | SQL injection risk |
|
|
292
|
+
| Querying large tables without indexes | Full table scan, poor performance |
|
|
293
|
+
| `DROP TABLE + CREATE TABLE` instead of ALTER | Risk of data loss |
|
|
294
|
+
| Composite primary keys | Complex foreign key references; poor ORM support |
|
|
295
|
+
| Column names using SQL keywords | Must be quoted; error-prone |
|
|
296
|
+
| Storing numbers/booleans as `TEXT` | Sorting/comparison behavior does not match expectations |
|
|
297
|
+
|
|
298
|
+
## Example: Complete Table Creation
|
|
299
|
+
|
|
300
|
+
```sql
|
|
301
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
302
|
+
-- Primary key
|
|
303
|
+
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
|
|
304
|
+
-- Business columns
|
|
305
|
+
session_id TEXT NOT NULL,
|
|
306
|
+
flow TEXT NOT NULL,
|
|
307
|
+
summary TEXT NOT NULL DEFAULT '',
|
|
308
|
+
status TEXT NOT NULL DEFAULT 'running',
|
|
309
|
+
-- Timestamps
|
|
310
|
+
created_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
|
311
|
+
modified_at TEXT NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%SZ', 'now')),
|
|
312
|
+
-- Soft delete
|
|
313
|
+
deleted INTEGER NOT NULL DEFAULT 0,
|
|
314
|
+
-- Constraints
|
|
315
|
+
CONSTRAINT tasks_session_id_flow_uk UNIQUE (session_id, flow)
|
|
316
|
+
) STRICT;
|
|
317
|
+
|
|
318
|
+
-- Indexes
|
|
319
|
+
CREATE INDEX idx_tasks_session_id ON tasks (session_id);
|
|
320
|
+
CREATE INDEX idx_tasks_status ON tasks (status) WHERE deleted = 0;
|
|
321
|
+
```
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# TypeScript Coding Style
|
|
2
|
+
|
|
3
|
+
## General Formatting
|
|
4
|
+
|
|
5
|
+
- Use UTF-8 encoding, LF line endings
|
|
6
|
+
- Use Prettier for automatic code formatting (run on save)
|
|
7
|
+
- Use 2-space indentation, no tabs
|
|
8
|
+
- Recommended max line length of 100 characters
|
|
9
|
+
- Keep one blank line at end of file
|
|
10
|
+
|
|
11
|
+
## File Organization
|
|
12
|
+
|
|
13
|
+
### Naming
|
|
14
|
+
|
|
15
|
+
- TypeScript source files use `kebab-case` or `camelCase`, consistent with the module they belong to
|
|
16
|
+
- Directory names use `kebab-case`
|
|
17
|
+
- Test file naming: `*.test.ts` or `*.spec.ts`, co-located with the file under test
|
|
18
|
+
|
|
19
|
+
### Import Grouping
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
// 1. Node built-in modules
|
|
23
|
+
import * as fs from 'node:fs';
|
|
24
|
+
import * as path from 'node:path';
|
|
25
|
+
|
|
26
|
+
// 2. Third-party libraries
|
|
27
|
+
import axios from 'axios';
|
|
28
|
+
import { z } from 'zod';
|
|
29
|
+
|
|
30
|
+
// 3. Project-internal modules (relative paths or aliases)
|
|
31
|
+
import { TaskState } from '../state/task-state';
|
|
32
|
+
import { FlowParser } from './flow-parser';
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### File Structure
|
|
36
|
+
|
|
37
|
+
- Each file should ideally have one primary export
|
|
38
|
+
- Auxiliary types/functions use named exports
|
|
39
|
+
- Modules expose a clear public API
|
|
40
|
+
|
|
41
|
+
## Naming Conventions
|
|
42
|
+
|
|
43
|
+
### Variables
|
|
44
|
+
|
|
45
|
+
- Use `camelCase`
|
|
46
|
+
- Short names for short scopes: `i`, `item`, `ctx`
|
|
47
|
+
- Descriptive names for long scopes: `taskConfig`, `messageCount`
|
|
48
|
+
- Boolean variables prefixed with a question word: `isActive`, `hasPlan`, `canProceed`
|
|
49
|
+
- No Hungarian notation
|
|
50
|
+
|
|
51
|
+
### Constants
|
|
52
|
+
|
|
53
|
+
- `UPPER_SNAKE_CASE` (module-level) / `camelCase` (within functions)
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
const DEFAULT_LANGUAGE = 'zh-CN';
|
|
57
|
+
const MAX_RETRY_COUNT = 3;
|
|
58
|
+
|
|
59
|
+
function process() {
|
|
60
|
+
const timeoutMs = 5000;
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Functions
|
|
65
|
+
|
|
66
|
+
- Use `camelCase`
|
|
67
|
+
- Start with a verb: `getTask`, `findFlow`, `createPlan`, `parseSpec`
|
|
68
|
+
- Event handler functions: `handleXxx` or `onXxx`
|
|
69
|
+
|
|
70
|
+
### Types & Interfaces
|
|
71
|
+
|
|
72
|
+
- Use `PascalCase`
|
|
73
|
+
- Do not prefix interface names with `I`
|
|
74
|
+
- Do not prefix type aliases with `T`
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
interface TaskState {
|
|
78
|
+
sessionId: string;
|
|
79
|
+
flow: string;
|
|
80
|
+
currentStep: string;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
type StepTransition = {
|
|
84
|
+
from: string;
|
|
85
|
+
to: string;
|
|
86
|
+
condition: string;
|
|
87
|
+
};
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### Classes
|
|
91
|
+
|
|
92
|
+
- Use `PascalCase`, singular form
|
|
93
|
+
- Public methods first, private methods last
|
|
94
|
+
|
|
95
|
+
### Enums
|
|
96
|
+
|
|
97
|
+
Use `PascalCase`, members use `PascalCase`
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
enum TaskStatus {
|
|
101
|
+
Running = 'running',
|
|
102
|
+
Completed = 'completed',
|
|
103
|
+
Closed = 'closed',
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Type Safety
|
|
108
|
+
|
|
109
|
+
### Prohibited
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// ❌ Do not use any
|
|
113
|
+
function process(data: any): any { }
|
|
114
|
+
|
|
115
|
+
// ❌ Do not use @ts-ignore / @ts-expect-error
|
|
116
|
+
// @ts-ignore
|
|
117
|
+
const x = something;
|
|
118
|
+
|
|
119
|
+
// ❌ Do not use empty catch blocks
|
|
120
|
+
try { } catch (e) { }
|
|
121
|
+
|
|
122
|
+
// ❌ Do not abuse non-null assertions
|
|
123
|
+
const x = data!.value!;
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Recommended
|
|
127
|
+
|
|
128
|
+
```typescript
|
|
129
|
+
// ✅ Use unknown instead of any
|
|
130
|
+
function process(data: unknown): Result {
|
|
131
|
+
if (!isValidData(data)) throw new TypeError('Invalid data');
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// ✅ Type guards
|
|
135
|
+
function isValidData(data: unknown): data is ValidData {
|
|
136
|
+
return typeof data === 'object' && data !== null && 'id' in data;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
// ✅ Explicit error handling
|
|
140
|
+
try {
|
|
141
|
+
await riskyOperation();
|
|
142
|
+
} catch (e) {
|
|
143
|
+
logger.error('Operation failed', { error: String(e) });
|
|
144
|
+
throw new OperationError('Failed', { cause: e });
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Function Design
|
|
149
|
+
|
|
150
|
+
### Parameters
|
|
151
|
+
|
|
152
|
+
- Use an object parameter when there are more than 3 parameters
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
// ❌
|
|
156
|
+
function createTask(name: string, flow: string, step: string, startAt: Date): Task { }
|
|
157
|
+
|
|
158
|
+
// ✅
|
|
159
|
+
function createTask(params: {
|
|
160
|
+
name: string;
|
|
161
|
+
flow: string;
|
|
162
|
+
step: string;
|
|
163
|
+
startAt: Date;
|
|
164
|
+
}): Task { }
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Return Values
|
|
168
|
+
|
|
169
|
+
- Prefer concrete return types over `undefined | null`
|
|
170
|
+
- For "empty" scenarios, use the `Result<T, E>` pattern or `Option<T>`
|
|
171
|
+
|
|
172
|
+
## Async Handling
|
|
173
|
+
|
|
174
|
+
- Consistently use `async/await`, avoid raw Promises
|
|
175
|
+
- Async functions return `Promise<T>` with explicit types
|
|
176
|
+
- Top-level async uses IIFE or `.catch()` as a safety net
|
|
177
|
+
|
|
178
|
+
```typescript
|
|
179
|
+
async function loadTask(sessionId: string): Promise<Task | null> {
|
|
180
|
+
const data = await db.query('SELECT * FROM tasks WHERE session_id = ?', [sessionId]);
|
|
181
|
+
return data ? Task.fromRow(data) : null;
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
## Error Handling
|
|
186
|
+
|
|
187
|
+
- All errors must be handled explicitly (propagate / wrap / handle / abort)
|
|
188
|
+
- Validate at system boundaries (user input, external APIs)
|
|
189
|
+
- Do not add "impossible" error handling in internal logic
|
|
190
|
+
|
|
191
|
+
```typescript
|
|
192
|
+
try {
|
|
193
|
+
await riskyOperation();
|
|
194
|
+
} catch (e) {
|
|
195
|
+
logger.error('Operation failed', { error: String(e) });
|
|
196
|
+
throw new OperationError('Failed to complete operation', { cause: e });
|
|
197
|
+
}
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Logging
|
|
201
|
+
|
|
202
|
+
- Use the project's unified logging module (not raw `console.log`)
|
|
203
|
+
- Log messages in English
|
|
204
|
+
- Log info/debug on critical paths
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
logger.info('Task created', { sessionId, flow });
|
|
208
|
+
logger.error('Failed to load task', { sessionId, error: String(e) });
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## Comments & Documentation
|
|
212
|
+
|
|
213
|
+
- Code comments in English
|
|
214
|
+
- Public APIs use JSDoc comments
|
|
215
|
+
- Add explanatory comments for complex logic
|
|
216
|
+
|
|
217
|
+
## Placeholder Code
|
|
218
|
+
|
|
219
|
+
```typescript
|
|
220
|
+
// TODO(username): Need to integrate API — expected v1.1
|
|
221
|
+
// FIXME(username): Possible data race under concurrency — needs locking
|
|
222
|
+
// HACK(username): Temporary workaround — replace after v1.0
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
## Export Conventions
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
// Primary export
|
|
229
|
+
export class FlowParser { }
|
|
230
|
+
|
|
231
|
+
// Auxiliary types/functions use named exports
|
|
232
|
+
export interface FlowDefinition { }
|
|
233
|
+
export function parseFlow(path: string): FlowDefinition { }
|
|
234
|
+
|
|
235
|
+
// Internal implementation — not exported
|
|
236
|
+
function validateStep(step: unknown): step is StepDefinition { }
|
|
237
|
+
```
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# ${Project Name}
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
### Main Features
|
|
6
|
+
|
|
7
|
+
## Interaction Requirements
|
|
8
|
+
- **Thinking**: Express reasoning in {speaking language}
|
|
9
|
+
- **Reply**: Reply in {speaking language}
|
|
10
|
+
|
|
11
|
+
## Tech Stack
|
|
12
|
+
|
|
13
|
+
* **{language}**: {optional note}
|
|
14
|
+
* **{framework}**: {usage}
|
|
15
|
+
|
|
16
|
+
## Development Environment
|
|
17
|
+
|
|
18
|
+
### Local Setup
|
|
19
|
+
|
|
20
|
+
* {local development environment, e.g., database}
|
|
21
|
+
|
|
22
|
+
### Development Commands
|
|
23
|
+
|
|
24
|
+
* {compile command}
|
|
25
|
+
* {build command}
|
|
26
|
+
* {run command}
|
|
27
|
+
|
|
28
|
+
## Development Design Principles
|
|
29
|
+
|
|
30
|
+
### Supreme Principle
|
|
31
|
+
|
|
32
|
+
### Design Principles
|
|
33
|
+
|
|
34
|
+
### Development Principles
|
|
35
|
+
|
|
36
|
+
### ANTI-PATTERNS
|
|
37
|
+
|
|
38
|
+
### Notes
|