planflow-plugin 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 +21 -0
- package/README.md +93 -0
- package/bin/cli.js +169 -0
- package/bin/postinstall.js +87 -0
- package/commands/pfActivity/SKILL.md +725 -0
- package/commands/pfAssign/SKILL.md +623 -0
- package/commands/pfCloudLink/SKILL.md +192 -0
- package/commands/pfCloudList/SKILL.md +222 -0
- package/commands/pfCloudNew/SKILL.md +187 -0
- package/commands/pfCloudUnlink/SKILL.md +152 -0
- package/commands/pfComment/SKILL.md +227 -0
- package/commands/pfComments/SKILL.md +159 -0
- package/commands/pfConnectionStatus/SKILL.md +433 -0
- package/commands/pfDiscord/SKILL.md +740 -0
- package/commands/pfGithubBranch/SKILL.md +672 -0
- package/commands/pfGithubIssue/SKILL.md +963 -0
- package/commands/pfGithubLink/SKILL.md +859 -0
- package/commands/pfGithubPr/SKILL.md +1335 -0
- package/commands/pfGithubUnlink/SKILL.md +401 -0
- package/commands/pfLive/SKILL.md +185 -0
- package/commands/pfLogin/SKILL.md +249 -0
- package/commands/pfLogout/SKILL.md +155 -0
- package/commands/pfMyTasks/SKILL.md +198 -0
- package/commands/pfNotificationSettings/SKILL.md +619 -0
- package/commands/pfNotifications/SKILL.md +420 -0
- package/commands/pfNotificationsClear/SKILL.md +421 -0
- package/commands/pfReact/SKILL.md +232 -0
- package/commands/pfSlack/SKILL.md +659 -0
- package/commands/pfSyncPull/SKILL.md +210 -0
- package/commands/pfSyncPush/SKILL.md +299 -0
- package/commands/pfSyncStatus/SKILL.md +212 -0
- package/commands/pfTeamInvite/SKILL.md +161 -0
- package/commands/pfTeamList/SKILL.md +253 -0
- package/commands/pfTeamRemove/SKILL.md +115 -0
- package/commands/pfTeamRole/SKILL.md +160 -0
- package/commands/pfTestWebhooks/SKILL.md +722 -0
- package/commands/pfUnassign/SKILL.md +134 -0
- package/commands/pfWhoami/SKILL.md +258 -0
- package/commands/pfWorkload/SKILL.md +219 -0
- package/commands/planExportCsv/SKILL.md +106 -0
- package/commands/planExportGithub/SKILL.md +222 -0
- package/commands/planExportJson/SKILL.md +159 -0
- package/commands/planExportSummary/SKILL.md +158 -0
- package/commands/planNew/SKILL.md +641 -0
- package/commands/planNext/SKILL.md +1200 -0
- package/commands/planSettingsAutoSync/SKILL.md +199 -0
- package/commands/planSettingsLanguage/SKILL.md +201 -0
- package/commands/planSettingsReset/SKILL.md +237 -0
- package/commands/planSettingsShow/SKILL.md +482 -0
- package/commands/planSpec/SKILL.md +929 -0
- package/commands/planUpdate/SKILL.md +2518 -0
- package/commands/team/SKILL.md +740 -0
- package/locales/en.json +1499 -0
- package/locales/ka.json +1499 -0
- package/package.json +48 -0
- package/templates/PROJECT_PLAN.template.md +157 -0
- package/templates/backend-api.template.md +562 -0
- package/templates/frontend-spa.template.md +610 -0
- package/templates/fullstack.template.md +397 -0
- package/templates/ka/backend-api.template.md +562 -0
- package/templates/ka/frontend-spa.template.md +610 -0
- package/templates/ka/fullstack.template.md +397 -0
- package/templates/sections/architecture.md +21 -0
- package/templates/sections/overview.md +15 -0
- package/templates/sections/tasks.md +22 -0
- package/templates/sections/tech-stack.md +19 -0
|
@@ -0,0 +1,929 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: planSpec
|
|
3
|
+
description: Specification Analyzer
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Specification Analyzer
|
|
7
|
+
|
|
8
|
+
You are an expert project planning assistant. Your role is to analyze technical specification documents and create comprehensive project plans from them.
|
|
9
|
+
|
|
10
|
+
## Objective
|
|
11
|
+
|
|
12
|
+
Read and analyze a technical specification document, ask clarifying questions about missing information, and generate a detailed PROJECT_PLAN.md file based on the specification.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
/spec <path-to-specification-file>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Examples:
|
|
21
|
+
```bash
|
|
22
|
+
/spec ./TECHNICAL_SPEC.md
|
|
23
|
+
/spec requirements.md
|
|
24
|
+
/spec ~/Documents/project-spec.md
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Process
|
|
28
|
+
|
|
29
|
+
### Step 0: Load User Language & Translations
|
|
30
|
+
|
|
31
|
+
**CRITICAL: Execute this step FIRST, before any output to the user!**
|
|
32
|
+
|
|
33
|
+
Load user's language preference using hierarchical config (local → global → default) and translation file.
|
|
34
|
+
|
|
35
|
+
**Pseudo-code:**
|
|
36
|
+
```javascript
|
|
37
|
+
// Read config with hierarchy (v1.1.1+)
|
|
38
|
+
function getConfig() {
|
|
39
|
+
// Try local config first (project-specific)
|
|
40
|
+
const localConfigPath = "./.plan-config.json"
|
|
41
|
+
|
|
42
|
+
if (fileExists(localConfigPath)) {
|
|
43
|
+
try {
|
|
44
|
+
const content = readFile(localConfigPath)
|
|
45
|
+
const config = JSON.parse(content)
|
|
46
|
+
config._source = "local"
|
|
47
|
+
return config
|
|
48
|
+
} catch (error) {
|
|
49
|
+
// Corrupted local config, try global
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// Fall back to global config
|
|
54
|
+
const globalConfigPath = expandPath("~/.config/claude/plan-plugin-config.json")
|
|
55
|
+
|
|
56
|
+
if (fileExists(globalConfigPath)) {
|
|
57
|
+
try {
|
|
58
|
+
const content = readFile(globalConfigPath)
|
|
59
|
+
const config = JSON.parse(content)
|
|
60
|
+
config._source = "global"
|
|
61
|
+
return config
|
|
62
|
+
} catch (error) {
|
|
63
|
+
// Corrupted global config, use defaults
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Fall back to defaults
|
|
68
|
+
return {
|
|
69
|
+
"language": "en",
|
|
70
|
+
"_source": "default"
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const config = getConfig()
|
|
75
|
+
const language = config.language || "en"
|
|
76
|
+
|
|
77
|
+
// Cloud config (v1.2.0+)
|
|
78
|
+
const cloudConfig = config.cloud || {}
|
|
79
|
+
const isAuthenticated = !!cloudConfig.apiToken
|
|
80
|
+
const apiUrl = cloudConfig.apiUrl || "https://api.planflow.tools"
|
|
81
|
+
const autoSync = cloudConfig.autoSync || false
|
|
82
|
+
|
|
83
|
+
// Load translations
|
|
84
|
+
const translationPath = `locales/${language}.json`
|
|
85
|
+
const t = JSON.parse(readFile(translationPath))
|
|
86
|
+
|
|
87
|
+
// Now ready to use t.commands.spec.* for all user-facing text
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Instructions for Claude:**
|
|
91
|
+
|
|
92
|
+
1. Try to read **local** config first:
|
|
93
|
+
- file_path: `./.plan-config.json`
|
|
94
|
+
- If exists and valid: Use this language, mark `_source = "local"`
|
|
95
|
+
- If doesn't exist or corrupted: Continue to step 2
|
|
96
|
+
|
|
97
|
+
2. Try to read **global** config:
|
|
98
|
+
- file_path: `~/.config/claude/plan-plugin-config.json`
|
|
99
|
+
- If exists and valid: Use this language, mark `_source = "global"`
|
|
100
|
+
- If doesn't exist or corrupted: Continue to step 3
|
|
101
|
+
|
|
102
|
+
3. Use **default**:
|
|
103
|
+
- language = "en", `_source = "default"`
|
|
104
|
+
|
|
105
|
+
4. Use Read tool to load translations:
|
|
106
|
+
- file_path: `locales/{language}.json`
|
|
107
|
+
- Parse JSON and store as `t` variable
|
|
108
|
+
|
|
109
|
+
5. Fall back to English if translation file missing
|
|
110
|
+
|
|
111
|
+
### Step 1: Validate Arguments
|
|
112
|
+
|
|
113
|
+
**Check if specification file path is provided.**
|
|
114
|
+
|
|
115
|
+
**Pseudo-code:**
|
|
116
|
+
```javascript
|
|
117
|
+
const args = commandArgs // Arguments passed to the command
|
|
118
|
+
|
|
119
|
+
if (!args || args.trim() === "") {
|
|
120
|
+
// No file path provided
|
|
121
|
+
console.log(t.commands.spec.usageHint)
|
|
122
|
+
console.log(t.commands.spec.usageExample)
|
|
123
|
+
return // Exit the command
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const specFilePath = args.trim()
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
**Output if no argument:**
|
|
130
|
+
```
|
|
131
|
+
{t.commands.spec.usageHint}
|
|
132
|
+
{t.commands.spec.usageExample}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Step 2: Read Specification Document
|
|
136
|
+
|
|
137
|
+
**Read the specification file using the Read tool.**
|
|
138
|
+
|
|
139
|
+
**Pseudo-code:**
|
|
140
|
+
```javascript
|
|
141
|
+
try {
|
|
142
|
+
const specContent = readFile(specFilePath)
|
|
143
|
+
|
|
144
|
+
if (!specContent || specContent.trim() === "") {
|
|
145
|
+
console.log(t.commands.spec.fileNotFound.replace("{path}", specFilePath))
|
|
146
|
+
return
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Store spec content for analysis
|
|
150
|
+
const specification = specContent
|
|
151
|
+
|
|
152
|
+
} catch (error) {
|
|
153
|
+
console.log(t.commands.spec.fileNotFound.replace("{path}", specFilePath))
|
|
154
|
+
return
|
|
155
|
+
}
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Display reading progress:**
|
|
159
|
+
```
|
|
160
|
+
{t.commands.spec.welcome}
|
|
161
|
+
|
|
162
|
+
{t.commands.spec.intro}
|
|
163
|
+
|
|
164
|
+
{t.commands.spec.readingFile}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
**Error output if file not found:**
|
|
168
|
+
```
|
|
169
|
+
{t.commands.spec.fileNotFound.replace("{path}", specFilePath)}
|
|
170
|
+
{t.commands.spec.usageHint}
|
|
171
|
+
{t.commands.spec.usageExample}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
### Step 3: Analyze Document Structure
|
|
175
|
+
|
|
176
|
+
**Parse and analyze the specification document structure.**
|
|
177
|
+
|
|
178
|
+
**What to look for:**
|
|
179
|
+
|
|
180
|
+
1. **Headings (H1, H2, H3)**:
|
|
181
|
+
- `# Level 1` → Project name/title
|
|
182
|
+
- `## Level 2` → Main sections (Overview, Features, Requirements, etc.)
|
|
183
|
+
- `### Level 3` → Subsections
|
|
184
|
+
|
|
185
|
+
2. **Lists (Ordered & Unordered)**:
|
|
186
|
+
- Feature lists
|
|
187
|
+
- Requirements
|
|
188
|
+
- User stories
|
|
189
|
+
- Acceptance criteria
|
|
190
|
+
|
|
191
|
+
3. **Tables**:
|
|
192
|
+
- Technical requirements
|
|
193
|
+
- User roles/permissions
|
|
194
|
+
- API endpoints
|
|
195
|
+
|
|
196
|
+
4. **Code blocks**:
|
|
197
|
+
- Technical specifications
|
|
198
|
+
- API examples
|
|
199
|
+
- Database schemas
|
|
200
|
+
|
|
201
|
+
5. **Emphasis and Keywords**:
|
|
202
|
+
- Bold text for important items
|
|
203
|
+
- Keywords like "must", "should", "could" (MoSCoW)
|
|
204
|
+
|
|
205
|
+
**Pseudo-code:**
|
|
206
|
+
```javascript
|
|
207
|
+
function analyzeDocument(content) {
|
|
208
|
+
const analysis = {
|
|
209
|
+
projectName: null,
|
|
210
|
+
projectType: null,
|
|
211
|
+
features: [],
|
|
212
|
+
techStack: [],
|
|
213
|
+
users: [],
|
|
214
|
+
constraints: [],
|
|
215
|
+
sections: []
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Extract H1 as project name
|
|
219
|
+
const h1Match = content.match(/^#\s+(.+)$/m)
|
|
220
|
+
if (h1Match) {
|
|
221
|
+
analysis.projectName = h1Match[1]
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
// Extract all H2 sections
|
|
225
|
+
const h2Matches = content.matchAll(/^##\s+(.+)$/gm)
|
|
226
|
+
for (const match of h2Matches) {
|
|
227
|
+
analysis.sections.push(match[1])
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Look for feature lists
|
|
231
|
+
// (Items under "Features", "Functionality", "Requirements" sections)
|
|
232
|
+
|
|
233
|
+
// Look for tech mentions
|
|
234
|
+
const techKeywords = ["React", "Vue", "Angular", "Node.js", "Express",
|
|
235
|
+
"Django", "Flask", "PostgreSQL", "MySQL", "MongoDB",
|
|
236
|
+
"TypeScript", "Python", "Java", "Go", "Rust"]
|
|
237
|
+
for (const tech of techKeywords) {
|
|
238
|
+
if (content.includes(tech)) {
|
|
239
|
+
analysis.techStack.push(tech)
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Detect project type
|
|
244
|
+
if (content.includes("API") && content.includes("endpoint")) {
|
|
245
|
+
analysis.projectType = "Backend API"
|
|
246
|
+
} else if (content.includes("frontend") || content.includes("UI")) {
|
|
247
|
+
analysis.projectType = "Frontend SPA"
|
|
248
|
+
} else if (content.includes("web app") || content.includes("full-stack")) {
|
|
249
|
+
analysis.projectType = "Full-Stack"
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
return analysis
|
|
253
|
+
}
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
### Step 4: Extract Key Information
|
|
257
|
+
|
|
258
|
+
**Extract and categorize information from the specification.**
|
|
259
|
+
|
|
260
|
+
**Categories to extract:**
|
|
261
|
+
|
|
262
|
+
1. **PROJECT_NAME**:
|
|
263
|
+
- From first H1 heading
|
|
264
|
+
- From "Project Name:" or "Title:" field
|
|
265
|
+
- From filename if nothing else
|
|
266
|
+
|
|
267
|
+
2. **PROJECT_TYPE**:
|
|
268
|
+
- Explicit mention: "web app", "API", "mobile app", "CLI tool"
|
|
269
|
+
- Inferred from context and technologies
|
|
270
|
+
|
|
271
|
+
3. **FEATURES**:
|
|
272
|
+
- From "Features" or "Functionality" sections
|
|
273
|
+
- From bullet lists with feature descriptions
|
|
274
|
+
- From user stories (As a..., I want..., So that...)
|
|
275
|
+
|
|
276
|
+
4. **TECH_STACK**:
|
|
277
|
+
- Explicitly mentioned technologies
|
|
278
|
+
- Framework names
|
|
279
|
+
- Database types
|
|
280
|
+
- Cloud services
|
|
281
|
+
|
|
282
|
+
5. **USERS/ROLES**:
|
|
283
|
+
- From "Users", "Actors", "Roles" sections
|
|
284
|
+
- Mentioned user types (admin, customer, guest, etc.)
|
|
285
|
+
- From user stories
|
|
286
|
+
|
|
287
|
+
6. **CONSTRAINTS**:
|
|
288
|
+
- Deadlines or milestones
|
|
289
|
+
- Budget mentions
|
|
290
|
+
- Technical constraints (must use X, cannot use Y)
|
|
291
|
+
- Integration requirements
|
|
292
|
+
- Performance requirements
|
|
293
|
+
|
|
294
|
+
**Analysis Card:**
|
|
295
|
+
|
|
296
|
+
```
|
|
297
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
298
|
+
│ 📊 Specification Analysis │
|
|
299
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
300
|
+
│ │
|
|
301
|
+
│ {t.commands.spec.analysisComplete} │
|
|
302
|
+
│ │
|
|
303
|
+
│ ── Project Info ────────────────────────────────────────────────────────── │
|
|
304
|
+
│ │
|
|
305
|
+
│ 📋 Name: {extractedName} │
|
|
306
|
+
│ 📁 Type: {detectedType} │
|
|
307
|
+
│ │
|
|
308
|
+
│ ── Features Found ──────────────────────────────────────────────────────── │
|
|
309
|
+
│ │
|
|
310
|
+
│ • Feature 1 │
|
|
311
|
+
│ • Feature 2 │
|
|
312
|
+
│ • Feature 3 │
|
|
313
|
+
│ │
|
|
314
|
+
│ ── Tech Stack Mentioned ────────────────────────────────────────────────── │
|
|
315
|
+
│ │
|
|
316
|
+
│ • Technology 1 │
|
|
317
|
+
│ • Technology 2 │
|
|
318
|
+
│ │
|
|
319
|
+
│ ── Users Identified ────────────────────────────────────────────────────── │
|
|
320
|
+
│ │
|
|
321
|
+
│ • User role 1 │
|
|
322
|
+
│ • User role 2 │
|
|
323
|
+
│ │
|
|
324
|
+
│ ── Constraints Found ───────────────────────────────────────────────────── │
|
|
325
|
+
│ │
|
|
326
|
+
│ • Constraint 1 │
|
|
327
|
+
│ • Constraint 2 │
|
|
328
|
+
│ │
|
|
329
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
330
|
+
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Step 5: Identify Missing/Unclear Information
|
|
334
|
+
|
|
335
|
+
**Determine what information is missing or needs clarification.**
|
|
336
|
+
|
|
337
|
+
**Check for:**
|
|
338
|
+
|
|
339
|
+
1. **Tech Stack Completeness**:
|
|
340
|
+
- Frontend framework specified?
|
|
341
|
+
- Backend framework specified?
|
|
342
|
+
- Database specified?
|
|
343
|
+
- If not → needs clarification
|
|
344
|
+
|
|
345
|
+
2. **Authentication Requirements**:
|
|
346
|
+
- Is authentication mentioned?
|
|
347
|
+
- If users/roles exist but no auth specified → needs clarification
|
|
348
|
+
|
|
349
|
+
3. **Feature Priority**:
|
|
350
|
+
- Are features prioritized?
|
|
351
|
+
- What should be in MVP vs later phases?
|
|
352
|
+
|
|
353
|
+
4. **Deployment/Hosting**:
|
|
354
|
+
- Is hosting/deployment mentioned?
|
|
355
|
+
- Cloud provider specified?
|
|
356
|
+
|
|
357
|
+
**Pseudo-code:**
|
|
358
|
+
```javascript
|
|
359
|
+
function identifyMissingInfo(analysis) {
|
|
360
|
+
const missing = []
|
|
361
|
+
|
|
362
|
+
// Check tech stack
|
|
363
|
+
const hasFrontend = analysis.techStack.some(t =>
|
|
364
|
+
["React", "Vue", "Angular", "Svelte"].includes(t))
|
|
365
|
+
const hasBackend = analysis.techStack.some(t =>
|
|
366
|
+
["Node.js", "Express", "Django", "Flask", "Spring"].includes(t))
|
|
367
|
+
const hasDatabase = analysis.techStack.some(t =>
|
|
368
|
+
["PostgreSQL", "MySQL", "MongoDB", "SQLite"].includes(t))
|
|
369
|
+
|
|
370
|
+
if (!hasFrontend && analysis.projectType !== "Backend API") {
|
|
371
|
+
missing.push({
|
|
372
|
+
type: "techStack",
|
|
373
|
+
question: "frontend",
|
|
374
|
+
reason: t.commands.spec.missingTechStack
|
|
375
|
+
})
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
if (!hasBackend && analysis.projectType !== "Frontend SPA") {
|
|
379
|
+
missing.push({
|
|
380
|
+
type: "techStack",
|
|
381
|
+
question: "backend",
|
|
382
|
+
reason: t.commands.spec.missingTechStack
|
|
383
|
+
})
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
if (!hasDatabase && analysis.projectType !== "Frontend SPA") {
|
|
387
|
+
missing.push({
|
|
388
|
+
type: "techStack",
|
|
389
|
+
question: "database",
|
|
390
|
+
reason: t.commands.spec.missingTechStack
|
|
391
|
+
})
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Check authentication
|
|
395
|
+
const hasAuth = analysis.content.includes("auth") ||
|
|
396
|
+
analysis.content.includes("login") ||
|
|
397
|
+
analysis.content.includes("password")
|
|
398
|
+
|
|
399
|
+
if (analysis.users.length > 0 && !hasAuth) {
|
|
400
|
+
missing.push({
|
|
401
|
+
type: "authentication",
|
|
402
|
+
reason: t.commands.spec.missingAuth
|
|
403
|
+
})
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
// Check feature priority
|
|
407
|
+
const hasPriority = analysis.content.includes("MVP") ||
|
|
408
|
+
analysis.content.includes("priority") ||
|
|
409
|
+
analysis.content.includes("phase")
|
|
410
|
+
|
|
411
|
+
if (analysis.features.length > 3 && !hasPriority) {
|
|
412
|
+
missing.push({
|
|
413
|
+
type: "priority",
|
|
414
|
+
reason: t.commands.spec.missingPriority
|
|
415
|
+
})
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
// Check deployment
|
|
419
|
+
const hasDeployment = analysis.content.includes("deploy") ||
|
|
420
|
+
analysis.content.includes("hosting") ||
|
|
421
|
+
analysis.content.includes("AWS") ||
|
|
422
|
+
analysis.content.includes("Vercel")
|
|
423
|
+
|
|
424
|
+
if (!hasDeployment) {
|
|
425
|
+
missing.push({
|
|
426
|
+
type: "deployment",
|
|
427
|
+
reason: t.commands.spec.missingDeployment
|
|
428
|
+
})
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
return missing
|
|
432
|
+
}
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
**Display missing information:**
|
|
436
|
+
```
|
|
437
|
+
{t.commands.spec.missingInfo}
|
|
438
|
+
• {missing item 1}
|
|
439
|
+
• {missing item 2}
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Step 6: Ask Clarifying Questions
|
|
443
|
+
|
|
444
|
+
**Use AskUserQuestion to gather missing information.**
|
|
445
|
+
|
|
446
|
+
**Only ask questions for information that is missing or unclear.**
|
|
447
|
+
|
|
448
|
+
**Pseudo-code:**
|
|
449
|
+
```javascript
|
|
450
|
+
// Build questions based on missing information
|
|
451
|
+
const questions = []
|
|
452
|
+
|
|
453
|
+
// Tech Stack questions (if missing)
|
|
454
|
+
if (missing.includes("frontend")) {
|
|
455
|
+
questions.push({
|
|
456
|
+
question: t.commands.spec.selectTechStack + " (Frontend)",
|
|
457
|
+
header: "Frontend",
|
|
458
|
+
multiSelect: false,
|
|
459
|
+
options: [
|
|
460
|
+
// If a technology was mentioned in spec, mark it as recommended
|
|
461
|
+
{label: "React" + (specMentions("React") ? " (Recommended)" : ""),
|
|
462
|
+
description: specMentions("React") ? "Mentioned in specification" : "Popular component library"},
|
|
463
|
+
{label: "Vue.js", description: "Progressive framework"},
|
|
464
|
+
{label: "Next.js", description: "React with SSR/SSG"},
|
|
465
|
+
{label: "Angular", description: "Full-featured framework"}
|
|
466
|
+
]
|
|
467
|
+
})
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
if (missing.includes("backend")) {
|
|
471
|
+
questions.push({
|
|
472
|
+
question: t.commands.spec.selectTechStack + " (Backend)",
|
|
473
|
+
header: "Backend",
|
|
474
|
+
multiSelect: false,
|
|
475
|
+
options: [
|
|
476
|
+
{label: "Node.js/Express", description: "JavaScript runtime"},
|
|
477
|
+
{label: "Python/FastAPI", description: "Modern Python API"},
|
|
478
|
+
{label: "Python/Django", description: "Full-featured Python"},
|
|
479
|
+
{label: "Go", description: "High performance"}
|
|
480
|
+
]
|
|
481
|
+
})
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
if (missing.includes("database")) {
|
|
485
|
+
questions.push({
|
|
486
|
+
question: t.commands.spec.selectTechStack + " (Database)",
|
|
487
|
+
header: "Database",
|
|
488
|
+
multiSelect: false,
|
|
489
|
+
options: [
|
|
490
|
+
{label: "PostgreSQL", description: "Relational, full-featured"},
|
|
491
|
+
{label: "MySQL", description: "Relational, widely used"},
|
|
492
|
+
{label: "MongoDB", description: "Document database"},
|
|
493
|
+
{label: "SQLite", description: "File-based, simple"}
|
|
494
|
+
]
|
|
495
|
+
})
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
// Feature Priority question (if many features and no priority)
|
|
499
|
+
if (missing.includes("priority") && features.length > 3) {
|
|
500
|
+
questions.push({
|
|
501
|
+
question: t.commands.spec.selectPriority,
|
|
502
|
+
header: "MVP Features",
|
|
503
|
+
multiSelect: true, // Allow selecting multiple MVP features
|
|
504
|
+
options: features.slice(0, 4).map(f => ({
|
|
505
|
+
label: f.name,
|
|
506
|
+
description: f.description || "From specification"
|
|
507
|
+
}))
|
|
508
|
+
})
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Authentication question (if users exist but auth unclear)
|
|
512
|
+
if (missing.includes("authentication")) {
|
|
513
|
+
questions.push({
|
|
514
|
+
question: t.commands.spec.selectAuth,
|
|
515
|
+
header: "Auth",
|
|
516
|
+
multiSelect: false,
|
|
517
|
+
options: [
|
|
518
|
+
{label: "Email/Password", description: "Traditional authentication"},
|
|
519
|
+
{label: "OAuth (Google, GitHub)", description: "Social login"},
|
|
520
|
+
{label: "Both", description: "Email + OAuth options"},
|
|
521
|
+
{label: "None needed", description: "Public access only"}
|
|
522
|
+
]
|
|
523
|
+
})
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
// Hosting question (if not specified)
|
|
527
|
+
if (missing.includes("deployment")) {
|
|
528
|
+
questions.push({
|
|
529
|
+
question: t.commands.spec.selectHosting,
|
|
530
|
+
header: "Hosting",
|
|
531
|
+
multiSelect: false,
|
|
532
|
+
options: [
|
|
533
|
+
{label: "Vercel", description: "Great for Next.js/React"},
|
|
534
|
+
{label: "AWS", description: "Full cloud platform"},
|
|
535
|
+
{label: "Railway", description: "Simple deployment"},
|
|
536
|
+
{label: "Self-hosted", description: "Own infrastructure"}
|
|
537
|
+
]
|
|
538
|
+
})
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
// Ask questions (max 4 at a time as per AskUserQuestion limit)
|
|
542
|
+
if (questions.length > 0) {
|
|
543
|
+
console.log(t.commands.spec.clarifyingQuestions)
|
|
544
|
+
AskUserQuestion({ questions: questions.slice(0, 4) })
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
// If more than 4 questions, ask in batches
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
**Instructions for Claude:**
|
|
551
|
+
|
|
552
|
+
1. Analyze which information is actually missing from the spec
|
|
553
|
+
2. Only ask questions about missing items (don't ask about things already specified)
|
|
554
|
+
3. If a technology is mentioned in the spec, mark it as "Recommended" in options
|
|
555
|
+
4. Use `multiSelect: true` for feature priority selection
|
|
556
|
+
5. Limit to 4 questions maximum per AskUserQuestion call
|
|
557
|
+
|
|
558
|
+
### Step 6.5: Check for Existing PROJECT_PLAN.md
|
|
559
|
+
|
|
560
|
+
**Before generating, check if PROJECT_PLAN.md already exists.**
|
|
561
|
+
|
|
562
|
+
**Pseudo-code:**
|
|
563
|
+
```javascript
|
|
564
|
+
const planPath = "./PROJECT_PLAN.md"
|
|
565
|
+
let outputFileName = "PROJECT_PLAN.md"
|
|
566
|
+
|
|
567
|
+
if (fileExists(planPath)) {
|
|
568
|
+
// Plan already exists, ask user what to do
|
|
569
|
+
AskUserQuestion({
|
|
570
|
+
questions: [{
|
|
571
|
+
question: t.commands.spec.overwriteQuestion,
|
|
572
|
+
header: "Existing Plan",
|
|
573
|
+
multiSelect: false,
|
|
574
|
+
options: [
|
|
575
|
+
{
|
|
576
|
+
label: t.commands.spec.overwriteOption,
|
|
577
|
+
description: t.commands.spec.overwriteDesc
|
|
578
|
+
},
|
|
579
|
+
{
|
|
580
|
+
label: t.commands.spec.keepOption,
|
|
581
|
+
description: t.commands.spec.keepDesc
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
label: t.commands.spec.renameOption,
|
|
585
|
+
description: t.commands.spec.renameDesc
|
|
586
|
+
}
|
|
587
|
+
]
|
|
588
|
+
}]
|
|
589
|
+
})
|
|
590
|
+
|
|
591
|
+
// Handle response
|
|
592
|
+
if (answer === "keep") {
|
|
593
|
+
console.log(t.common.cancel)
|
|
594
|
+
return // Exit
|
|
595
|
+
} else if (answer === "rename") {
|
|
596
|
+
outputFileName = "PROJECT_PLAN_SPEC.md"
|
|
597
|
+
}
|
|
598
|
+
// If "overwrite", continue with default filename
|
|
599
|
+
}
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
**Display if plan exists:**
|
|
603
|
+
```
|
|
604
|
+
{t.commands.spec.planExists}
|
|
605
|
+
```
|
|
606
|
+
|
|
607
|
+
### Step 7: Select Template
|
|
608
|
+
|
|
609
|
+
**Choose the appropriate template based on project type and language.**
|
|
610
|
+
|
|
611
|
+
**Pseudo-code:**
|
|
612
|
+
```javascript
|
|
613
|
+
// Determine template based on project type
|
|
614
|
+
let templateName
|
|
615
|
+
if (projectType === "Full-Stack" || projectType === "Full-Stack Web App") {
|
|
616
|
+
templateName = "fullstack.template.md"
|
|
617
|
+
} else if (projectType === "Backend API") {
|
|
618
|
+
templateName = "backend-api.template.md"
|
|
619
|
+
} else if (projectType === "Frontend SPA") {
|
|
620
|
+
templateName = "frontend-spa.template.md"
|
|
621
|
+
} else {
|
|
622
|
+
templateName = "PROJECT_PLAN.template.md"
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
// Build path based on language
|
|
626
|
+
let templatePath
|
|
627
|
+
if (language === "ka") {
|
|
628
|
+
templatePath = `templates/ka/${templateName}`
|
|
629
|
+
} else {
|
|
630
|
+
templatePath = `templates/${templateName}`
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// Read template, fall back to default if not found
|
|
634
|
+
let template
|
|
635
|
+
try {
|
|
636
|
+
template = readFile(templatePath)
|
|
637
|
+
} catch {
|
|
638
|
+
// Fall back to generic template
|
|
639
|
+
template = readFile("templates/PROJECT_PLAN.template.md")
|
|
640
|
+
}
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Step 8: Generate PROJECT_PLAN.md
|
|
644
|
+
|
|
645
|
+
**Fill template with extracted and gathered information.**
|
|
646
|
+
|
|
647
|
+
**Display generating message:**
|
|
648
|
+
```
|
|
649
|
+
{t.commands.spec.generating}
|
|
650
|
+
```
|
|
651
|
+
|
|
652
|
+
**Template placeholders to fill:**
|
|
653
|
+
|
|
654
|
+
1. **Basic Information:**
|
|
655
|
+
- `{{PROJECT_NAME}}` → From spec or user input
|
|
656
|
+
- `{{DESCRIPTION}}` → From spec overview/description section
|
|
657
|
+
- `{{TARGET_USERS}}` → From extracted users/roles
|
|
658
|
+
- `{{PROJECT_TYPE}}` → Detected or selected
|
|
659
|
+
- `{{CREATED_DATE}}` → Current date (YYYY-MM-DD)
|
|
660
|
+
- `{{LAST_UPDATED}}` → Current date
|
|
661
|
+
- `{{STATUS}}` → "Planning"
|
|
662
|
+
- `{{PLUGIN_VERSION}}` → "1.1.1"
|
|
663
|
+
|
|
664
|
+
2. **Tech Stack:**
|
|
665
|
+
- `{{FRONTEND_FRAMEWORK}}` → From spec + user selection
|
|
666
|
+
- `{{BACKEND_FRAMEWORK}}` → From spec + user selection
|
|
667
|
+
- `{{DATABASE}}` → From spec + user selection
|
|
668
|
+
- `{{HOSTING}}` → From user selection or spec
|
|
669
|
+
|
|
670
|
+
3. **Features → Tasks:**
|
|
671
|
+
- Convert each feature into 1-3 tasks
|
|
672
|
+
- Assign complexity (Low/Medium/High)
|
|
673
|
+
- Set up dependencies
|
|
674
|
+
|
|
675
|
+
4. **Phases:**
|
|
676
|
+
- Phase 1: Foundation (setup, auth, basic structure)
|
|
677
|
+
- Phase 2: Core Features (MVP features selected by user)
|
|
678
|
+
- Phase 3: Advanced Features (remaining features)
|
|
679
|
+
- Phase 4: Testing & Deployment
|
|
680
|
+
|
|
681
|
+
5. **Additional Section - Specification Analysis:**
|
|
682
|
+
```markdown
|
|
683
|
+
## Original Specification Analysis
|
|
684
|
+
|
|
685
|
+
**Source Document:** {filename}
|
|
686
|
+
|
|
687
|
+
### Extracted Requirements
|
|
688
|
+
- Requirement 1
|
|
689
|
+
- Requirement 2
|
|
690
|
+
|
|
691
|
+
### Clarifications Made
|
|
692
|
+
- Frontend: {user choice} (not specified in original)
|
|
693
|
+
- MVP Features: {selected features}
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
**Task generation from features:**
|
|
697
|
+
```javascript
|
|
698
|
+
function generateTasks(features, phase) {
|
|
699
|
+
const tasks = []
|
|
700
|
+
let taskNum = 1
|
|
701
|
+
|
|
702
|
+
for (const feature of features) {
|
|
703
|
+
// Simple feature → 1 task
|
|
704
|
+
// Complex feature → 2-3 tasks
|
|
705
|
+
|
|
706
|
+
const complexity = estimateComplexity(feature)
|
|
707
|
+
|
|
708
|
+
if (complexity === "High") {
|
|
709
|
+
// Split into multiple tasks
|
|
710
|
+
tasks.push({
|
|
711
|
+
id: `T${phase}.${taskNum}`,
|
|
712
|
+
name: `Setup ${feature.name}`,
|
|
713
|
+
complexity: "Medium",
|
|
714
|
+
status: "TODO"
|
|
715
|
+
})
|
|
716
|
+
taskNum++
|
|
717
|
+
|
|
718
|
+
tasks.push({
|
|
719
|
+
id: `T${phase}.${taskNum}`,
|
|
720
|
+
name: `Implement ${feature.name} core logic`,
|
|
721
|
+
complexity: "High",
|
|
722
|
+
status: "TODO",
|
|
723
|
+
dependencies: [`T${phase}.${taskNum-1}`]
|
|
724
|
+
})
|
|
725
|
+
taskNum++
|
|
726
|
+
|
|
727
|
+
tasks.push({
|
|
728
|
+
id: `T${phase}.${taskNum}`,
|
|
729
|
+
name: `${feature.name} UI and integration`,
|
|
730
|
+
complexity: "Medium",
|
|
731
|
+
status: "TODO",
|
|
732
|
+
dependencies: [`T${phase}.${taskNum-1}`]
|
|
733
|
+
})
|
|
734
|
+
taskNum++
|
|
735
|
+
} else {
|
|
736
|
+
// Single task
|
|
737
|
+
tasks.push({
|
|
738
|
+
id: `T${phase}.${taskNum}`,
|
|
739
|
+
name: `Implement ${feature.name}`,
|
|
740
|
+
complexity: complexity,
|
|
741
|
+
status: "TODO"
|
|
742
|
+
})
|
|
743
|
+
taskNum++
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
|
|
747
|
+
return tasks
|
|
748
|
+
}
|
|
749
|
+
```
|
|
750
|
+
|
|
751
|
+
**Write the file:**
|
|
752
|
+
```javascript
|
|
753
|
+
const outputPath = `./${outputFileName}`
|
|
754
|
+
writeFile(outputPath, generatedContent)
|
|
755
|
+
```
|
|
756
|
+
|
|
757
|
+
### Step 9: Confirmation
|
|
758
|
+
|
|
759
|
+
**Show success message with statistics.**
|
|
760
|
+
|
|
761
|
+
**Pseudo-code:**
|
|
762
|
+
```javascript
|
|
763
|
+
const featureCount = extractedFeatures.length
|
|
764
|
+
const taskCount = generatedTasks.length
|
|
765
|
+
const phaseCount = 4
|
|
766
|
+
|
|
767
|
+
let output = t.commands.spec.success + "\n\n"
|
|
768
|
+
output += t.commands.spec.basedOn.replace("{filename}", specFilename) + "\n"
|
|
769
|
+
output += t.commands.spec.featuresExtracted.replace("{count}", featureCount) + "\n"
|
|
770
|
+
output += t.commands.spec.tasksGenerated.replace("{count}", taskCount) + "\n"
|
|
771
|
+
output += t.commands.spec.phasesCreated.replace("{count}", phaseCount) + "\n\n"
|
|
772
|
+
|
|
773
|
+
output += t.commands.spec.specIncluded + "\n"
|
|
774
|
+
output += t.commands.spec.reviewRecommended + "\n\n"
|
|
775
|
+
|
|
776
|
+
output += t.commands.new.nextSteps + "\n"
|
|
777
|
+
output += t.commands.new.reviewPlan + "\n"
|
|
778
|
+
output += t.commands.new.getNextTask + "\n"
|
|
779
|
+
output += t.commands.new.updateProgress
|
|
780
|
+
|
|
781
|
+
console.log(output)
|
|
782
|
+
```
|
|
783
|
+
|
|
784
|
+
**Example output (English):**
|
|
785
|
+
|
|
786
|
+
```
|
|
787
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
788
|
+
│ ✅ SUCCESS │
|
|
789
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
790
|
+
│ │
|
|
791
|
+
│ Project plan created from specification! │
|
|
792
|
+
│ │
|
|
793
|
+
│ ── Specification Analysis ──────────────────────────────────────────────── │
|
|
794
|
+
│ │
|
|
795
|
+
│ 📄 Based on: TECHNICAL_SPEC.md │
|
|
796
|
+
│ ✨ Features: 8 extracted │
|
|
797
|
+
│ 📋 Tasks: 15 generated │
|
|
798
|
+
│ 🎯 Phases: 4 created │
|
|
799
|
+
│ │
|
|
800
|
+
│ Specification analysis included in plan. │
|
|
801
|
+
│ │
|
|
802
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
803
|
+
│ │
|
|
804
|
+
│ 💡 {t.ui.labels.nextSteps} │
|
|
805
|
+
│ • Review the plan and adjust task details as needed │
|
|
806
|
+
│ • /planNext Get next task recommendation │
|
|
807
|
+
│ • /planUpdate T1.1 start │
|
|
808
|
+
│ │
|
|
809
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
810
|
+
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
811
|
+
```
|
|
812
|
+
|
|
813
|
+
**Example output (Georgian):**
|
|
814
|
+
|
|
815
|
+
```
|
|
816
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
817
|
+
│ ✅ წარმატება │
|
|
818
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
819
|
+
│ │
|
|
820
|
+
│ პროექტის გეგმა შეიქმნა სპეციფიკაციიდან! │
|
|
821
|
+
│ │
|
|
822
|
+
│ ── სპეციფიკაციის ანალიზი ───────────────────────────────────────────────── │
|
|
823
|
+
│ │
|
|
824
|
+
│ 📄 დაფუძნებული: TECHNICAL_SPEC.md │
|
|
825
|
+
│ ✨ ფუნქციები: 8 ამოღებული │
|
|
826
|
+
│ 📋 ამოცანები: 15 გენერირებული │
|
|
827
|
+
│ 🎯 ეტაპები: 4 შექმნილი │
|
|
828
|
+
│ │
|
|
829
|
+
│ სპეციფიკაციის ანალიზი ჩართულია გეგმაში. │
|
|
830
|
+
│ │
|
|
831
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
832
|
+
│ │
|
|
833
|
+
│ 💡 შემდეგი ნაბიჯები: │
|
|
834
|
+
│ • გადახედეთ გეგმას და საჭიროებისამებრ შეცვალეთ │
|
|
835
|
+
│ • /planNext შემდეგი ამოცანის მისაღებად │
|
|
836
|
+
│ • /planUpdate T1.1 start │
|
|
837
|
+
│ │
|
|
838
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
839
|
+
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
|
|
840
|
+
```
|
|
841
|
+
|
|
842
|
+
## Important Guidelines
|
|
843
|
+
|
|
844
|
+
1. **Preserve Spec Intent**: Don't change the meaning of requirements, only fill in gaps
|
|
845
|
+
2. **Ask Only What's Missing**: Don't ask questions about things clearly specified
|
|
846
|
+
3. **Smart Detection**: Recognize common patterns in specification documents
|
|
847
|
+
4. **Realistic Tasks**: Create actionable, specific tasks from features
|
|
848
|
+
5. **Clear Dependencies**: Show which tasks depend on others
|
|
849
|
+
6. **Include Traceability**: Link tasks back to original spec requirements
|
|
850
|
+
|
|
851
|
+
## Error Handling
|
|
852
|
+
|
|
853
|
+
**File Not Found Card:**
|
|
854
|
+
|
|
855
|
+
```
|
|
856
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
857
|
+
│ ❌ ERROR │
|
|
858
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
859
|
+
│ │
|
|
860
|
+
│ {t.commands.spec.fileNotFound.replace("{path}", specFilePath)} │
|
|
861
|
+
│ │
|
|
862
|
+
│ {t.commands.spec.usageHint} │
|
|
863
|
+
│ {t.commands.spec.usageExample} │
|
|
864
|
+
│ │
|
|
865
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
866
|
+
```
|
|
867
|
+
|
|
868
|
+
**Empty File Card:**
|
|
869
|
+
|
|
870
|
+
```
|
|
871
|
+
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
872
|
+
│ ⚠️ WARNING │
|
|
873
|
+
├──────────────────────────────────────────────────────────────────────────────┤
|
|
874
|
+
│ │
|
|
875
|
+
│ Specification file is empty. │
|
|
876
|
+
│ │
|
|
877
|
+
│ A minimal plan will be generated. │
|
|
878
|
+
│ Add content to your specification file for better results. │
|
|
879
|
+
│ │
|
|
880
|
+
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
881
|
+
```
|
|
882
|
+
|
|
883
|
+
**General Error Handling:**
|
|
884
|
+
- **Malformed markdown**: Do best effort parsing, note issues
|
|
885
|
+
- **User cancels**: Exit gracefully with message
|
|
886
|
+
- **Template missing**: Fall back to generic template
|
|
887
|
+
|
|
888
|
+
## Supported Specification Formats
|
|
889
|
+
|
|
890
|
+
The analyzer handles various common specification formats:
|
|
891
|
+
|
|
892
|
+
1. **Standard Markdown** (.md)
|
|
893
|
+
- H1/H2/H3 headings
|
|
894
|
+
- Bullet/numbered lists
|
|
895
|
+
- Code blocks
|
|
896
|
+
- Tables
|
|
897
|
+
|
|
898
|
+
2. **User Stories Format**
|
|
899
|
+
- "As a [user], I want [feature], so that [benefit]"
|
|
900
|
+
- Acceptance criteria lists
|
|
901
|
+
|
|
902
|
+
3. **Requirements Document**
|
|
903
|
+
- Numbered requirements (REQ-001, etc.)
|
|
904
|
+
- MoSCoW prioritization (Must, Should, Could, Won't)
|
|
905
|
+
|
|
906
|
+
4. **Technical Specification**
|
|
907
|
+
- API endpoint descriptions
|
|
908
|
+
- Database schemas
|
|
909
|
+
- System architecture
|
|
910
|
+
|
|
911
|
+
## Keywords for Detection
|
|
912
|
+
|
|
913
|
+
**Project Types:**
|
|
914
|
+
- "web app", "web application" → Full-Stack
|
|
915
|
+
- "API", "REST", "GraphQL", "backend" → Backend API
|
|
916
|
+
- "SPA", "single page", "frontend only" → Frontend SPA
|
|
917
|
+
- "mobile", "iOS", "Android" → Mobile App
|
|
918
|
+
- "CLI", "command line" → CLI Tool
|
|
919
|
+
|
|
920
|
+
**Technologies:**
|
|
921
|
+
- Frontend: React, Vue, Angular, Svelte, Next.js, Nuxt
|
|
922
|
+
- Backend: Node.js, Express, Django, Flask, FastAPI, Spring, Go
|
|
923
|
+
- Database: PostgreSQL, MySQL, MongoDB, Redis, SQLite
|
|
924
|
+
- Cloud: AWS, GCP, Azure, Vercel, Railway, Heroku
|
|
925
|
+
|
|
926
|
+
**Feature Indicators:**
|
|
927
|
+
- "user can", "users should be able to"
|
|
928
|
+
- "the system must", "the app will"
|
|
929
|
+
- Bullet points under "Features" or "Functionality"
|