viepilot 2.4.0 → 2.15.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/CHANGELOG.md +206 -0
- package/README.md +16 -13
- package/docs/brainstorm/session-2026-04-11.md +194 -0
- package/docs/skills-reference.md +58 -0
- package/docs/user/features/interactive-prompts.md +83 -0
- package/docs/user/features/proposal.md +196 -0
- package/lib/google-slides-exporter.cjs +80 -0
- package/lib/proposal-generator.cjs +249 -0
- package/lib/screenshot-artifact.cjs +142 -0
- package/lib/viepilot-config.cjs +32 -1
- package/package.json +8 -1
- package/skills/vp-audit/SKILL.md +11 -0
- package/skills/vp-brainstorm/SKILL.md +21 -0
- package/skills/vp-crystallize/SKILL.md +64 -0
- package/skills/vp-docs/SKILL.md +16 -6
- package/skills/vp-proposal/SKILL.md +175 -0
- package/skills/vp-request/SKILL.md +22 -0
- package/templates/proposal/docx/project-detail.docx +0 -0
- package/templates/proposal/pptx/general.pptx +0 -0
- package/templates/proposal/pptx/product-pitch.pptx +0 -0
- package/templates/proposal/pptx/project-proposal-creative.pptx +0 -0
- package/templates/proposal/pptx/project-proposal-enterprise.pptx +0 -0
- package/templates/proposal/pptx/project-proposal-modern-tech.pptx +0 -0
- package/templates/proposal/pptx/project-proposal.pptx +0 -0
- package/templates/proposal/pptx/tech-architecture.pptx +0 -0
- package/workflows/brainstorm.md +26 -0
- package/workflows/crystallize.md +700 -1
- package/workflows/documentation.md +26 -11
- package/workflows/evolve.md +36 -0
- package/workflows/proposal.md +807 -0
- package/workflows/request.md +35 -0
package/workflows/crystallize.md
CHANGED
|
@@ -2,6 +2,14 @@
|
|
|
2
2
|
Convert brainstorm sessions into structured artifacts for autonomous AI execution.
|
|
3
3
|
</purpose>
|
|
4
4
|
|
|
5
|
+
## Adapter Compatibility
|
|
6
|
+
|
|
7
|
+
| Feature | Claude Code (terminal) | Cursor (Agent/Skills) | Codex CLI | Antigravity (native) |
|
|
8
|
+
|---------|----------------------|-----------------------|-----------|----------------------|
|
|
9
|
+
| Interactive prompts | ✅ `AskUserQuestion` tool | ❌ text fallback | ❌ text fallback | ❌ text fallback |
|
|
10
|
+
|
|
11
|
+
When `AskUserQuestion` is not available, each prompt block falls back to the plain-text numbered list shown below it — no configuration needed.
|
|
12
|
+
|
|
5
13
|
## ViePilot Skill Scope Policy (BUG-004)
|
|
6
14
|
|
|
7
15
|
- Default behavior: only use and suggest skills under `vp-*`.
|
|
@@ -80,7 +88,7 @@ Ask the user for project information:
|
|
|
80
88
|
|
|
81
89
|
9. Lead developer email?
|
|
82
90
|
|
|
83
|
-
10.
|
|
91
|
+
10. Git remote host / username? (optional — e.g. github.com/johndoe, gitlab.com/org, bitbucket.org/team)
|
|
84
92
|
```
|
|
85
93
|
|
|
86
94
|
### Repository Info
|
|
@@ -92,6 +100,15 @@ Ask the user for project information:
|
|
|
92
100
|
```
|
|
93
101
|
|
|
94
102
|
### License & Year
|
|
103
|
+
|
|
104
|
+
> **Adapter-aware prompt (question 13):**
|
|
105
|
+
> - **Claude Code (terminal):** use `AskUserQuestion` tool — spec:
|
|
106
|
+
> - question: "Which license for this project?"
|
|
107
|
+
> - header: "License"
|
|
108
|
+
> - options: [{ label: "MIT", description: "Permissive — most common open-source choice" }, { label: "Apache-2.0", description: "Permissive with patent grant — preferred for enterprise OSS" }, { label: "GPL-3.0", description: "Copyleft — derivative works must stay open-source" }, { label: "Proprietary", description: "All rights reserved — no public redistribution" }]
|
|
109
|
+
> - multiSelect: false
|
|
110
|
+
> - **Cursor / Codex / Antigravity / other:** use text list below
|
|
111
|
+
|
|
95
112
|
```
|
|
96
113
|
13. License?
|
|
97
114
|
Options: MIT, Apache-2.0, GPL-3.0, BSD-3-Clause, Proprietary
|
|
@@ -104,6 +121,671 @@ Ask the user for project information:
|
|
|
104
121
|
Store all metadata for template generation.
|
|
105
122
|
</step>
|
|
106
123
|
|
|
124
|
+
<step name="brownfield_detection">
|
|
125
|
+
## Step 0-B: Brownfield Mode Detection (FEAT-018)
|
|
126
|
+
|
|
127
|
+
**Trigger brownfield mode when ANY of the following is true:**
|
|
128
|
+
- `--brownfield` flag passed explicitly, OR
|
|
129
|
+
- `docs/brainstorm/` directory does not exist or is empty (no `session-*.md` files) **AND** `.viepilot/` directory does not yet exist
|
|
130
|
+
|
|
131
|
+
**If NEITHER condition is met** (greenfield path): skip this entire step; proceed to Step 1.
|
|
132
|
+
|
|
133
|
+
**If brownfield triggered AND `.viepilot/` already exists:**
|
|
134
|
+
- Warn: "`.viepilot/` already exists. Re-running brownfield mode will overwrite artifacts."
|
|
135
|
+
|
|
136
|
+
> **Adapter-aware prompt:**
|
|
137
|
+
> - **Claude Code (terminal):** use `AskUserQuestion` tool — spec:
|
|
138
|
+
> - question: "`.viepilot/` already exists. Re-running brownfield mode will overwrite artifacts. Continue?"
|
|
139
|
+
> - header: "Overwrite?"
|
|
140
|
+
> - options: [{ label: "Yes, continue", description: "Overwrite existing .viepilot/ artifacts with new scan results" }, { label: "No, abort", description: "Stop here — keep existing artifacts unchanged" }]
|
|
141
|
+
> - multiSelect: false
|
|
142
|
+
> - **Cursor / Codex / Antigravity / other:** use text prompt below
|
|
143
|
+
>
|
|
144
|
+
> Ask: "Continue? (y/n)" — abort if n.
|
|
145
|
+
|
|
146
|
+
**When brownfield mode is active:**
|
|
147
|
+
1. Run the full 12-category codebase scanner (Signal Categories 1–12 below).
|
|
148
|
+
2. Produce a structured **Scan Report** (see schema at end of this step).
|
|
149
|
+
3. Classify every field as DETECTED / ASSUMED / MISSING per Gap Detection Rules.
|
|
150
|
+
4. Present Scan Report summary to user; interactively fill every MISSING MUST-DETECT field.
|
|
151
|
+
5. User confirms ASSUMED fields (may accept all or override individually).
|
|
152
|
+
6. After confirmation: proceed to Step 0-C (brainstorm stub generation).
|
|
153
|
+
7. Then skip Step 1 (`analyze_brainstorm`); continue from Step 0 (metadata collection) → Step 2 onward using the confirmed Scan Report as input.
|
|
154
|
+
|
|
155
|
+
---
|
|
156
|
+
|
|
157
|
+
### Signal Category 1 — Build Manifest & Package Identity
|
|
158
|
+
|
|
159
|
+
Probe the following files in order of priority (first match per language wins):
|
|
160
|
+
|
|
161
|
+
| Language / Platform | Files to probe |
|
|
162
|
+
|---------------------|----------------|
|
|
163
|
+
| Node.js | `package.json` |
|
|
164
|
+
| Java / Maven | `pom.xml` |
|
|
165
|
+
| Java / Gradle | `build.gradle`, `build.gradle.kts`, `settings.gradle` |
|
|
166
|
+
| Python | `pyproject.toml`, `setup.py`, `setup.cfg`, `requirements.txt`, `Pipfile` |
|
|
167
|
+
| Rust | `Cargo.toml` |
|
|
168
|
+
| Go | `go.mod` |
|
|
169
|
+
| PHP | `composer.json` |
|
|
170
|
+
| Ruby | `Gemfile`, `*.gemspec` |
|
|
171
|
+
| .NET | `*.csproj`, `*.sln`, `global.json` |
|
|
172
|
+
| Elixir / Erlang | `mix.exs` |
|
|
173
|
+
| Swift | `Package.swift` |
|
|
174
|
+
|
|
175
|
+
**Fields to extract per manifest:**
|
|
176
|
+
- `project_name` — package name / artifactId / module name
|
|
177
|
+
- `current_version` — version field
|
|
178
|
+
- `primary_language` — derived from manifest type
|
|
179
|
+
- `runtime_version` — engines/node, java.version, python_requires, go version
|
|
180
|
+
- `entry_points` — main, bin, spring-boot:run target, etc.
|
|
181
|
+
- `raw_dependencies[]` — full dependency list (used by Signal Category 2)
|
|
182
|
+
- `raw_dev_dependencies[]` — dev/test deps
|
|
183
|
+
|
|
184
|
+
**Monorepo detection** (check before single-manifest scan):
|
|
185
|
+
- npm workspaces: `package.json` → `"workspaces"` field + `packages/*/package.json`
|
|
186
|
+
- Nx / Turborepo: `nx.json`, `turbo.json` + `apps/*/` and `libs/*/`
|
|
187
|
+
- Maven multi-module: `pom.xml` with `<modules>`
|
|
188
|
+
- Gradle multi-project: `settings.gradle` with `include`
|
|
189
|
+
- Cargo workspace: `Cargo.toml` with `[workspace]`
|
|
190
|
+
- Go workspace: `go.work`
|
|
191
|
+
|
|
192
|
+
If monorepo detected → scan each module separately; aggregate into `modules[]` in Scan Report.
|
|
193
|
+
|
|
194
|
+
**Git Submodule Detection** (run after monorepo check):
|
|
195
|
+
- Check for `.gitmodules` file at repo root
|
|
196
|
+
- If present: parse all `[submodule "name"]` blocks → extract `name`, `path`, `url`
|
|
197
|
+
- For each submodule path:
|
|
198
|
+
- If path exists on disk (initialized):
|
|
199
|
+
- Run Signal Cat 1 (manifest scan) on `{path}/`
|
|
200
|
+
- Run Signal Cat 2 (framework) on `{path}/`
|
|
201
|
+
- Run Signal Cat 4 (DB signals) on `{path}/`
|
|
202
|
+
- Record `initialized: true`
|
|
203
|
+
- If path absent (not initialized):
|
|
204
|
+
- Record `initialized: false`, `primary_language: MISSING`
|
|
205
|
+
- Add open question: "Submodule '{name}' not initialized — run `git submodule update --init {path}` to scan it"
|
|
206
|
+
- Add each submodule to `modules[]` with `type: submodule`
|
|
207
|
+
|
|
208
|
+
> **SAFETY RULE**: Never run `git submodule update`, `git submodule init`, or any git network command during scan. Read the local filesystem only.
|
|
209
|
+
|
|
210
|
+
**Polyrepo / Multi-Repo Detection** (run after submodule check):
|
|
211
|
+
|
|
212
|
+
Scan the following signals to determine if this repo is part of a larger multi-repo system:
|
|
213
|
+
|
|
214
|
+
| Signal Source | Pattern | Interpretation |
|
|
215
|
+
|--------------|---------|----------------|
|
|
216
|
+
| `docker-compose.yml` / `docker-compose*.yml` | `build: ../path` or `context: ../path` (value starts with `../`) | Sibling repo used as build context |
|
|
217
|
+
| `docker-compose.yml` | Multiple services with external `image:` and no local `build:` | External microservices — possible sibling repos |
|
|
218
|
+
| `package.json` | `"dependencies"` or `"devDependencies"` value matching `"file:../..."` | Local `file:` sibling repo dependency |
|
|
219
|
+
| `.github/workflows/*.yml` / `.gitlab-ci.yml` / `ci/*.yml` | `git clone` steps, or `uses: org/other-repo/.github/workflows/` referencing a different repo | CI clones or calls a sibling repo |
|
|
220
|
+
| `README.md` / `CONTRIBUTING.md` | Lines containing a repo URL whose path differs from the current repo's remote | Related repo link in docs |
|
|
221
|
+
| `Makefile` / `justfile` | Targets containing `cd ../` followed by build/test commands | Cross-repo build orchestration |
|
|
222
|
+
|
|
223
|
+
For each match: record `{ source, hint, inferred_repo }` in `polyrepo_hints[]`.
|
|
224
|
+
Deduplicate by `inferred_repo` name.
|
|
225
|
+
If `polyrepo_hints` is empty → skip this section entirely (no empty array in clean single-repo Scan Reports).
|
|
226
|
+
|
|
227
|
+
**Interactive prompt** (fire when `polyrepo_hints` non-empty):
|
|
228
|
+
|
|
229
|
+
> **Adapter-aware prompt:**
|
|
230
|
+
> - **Claude Code (terminal):** use `AskUserQuestion` tool — spec:
|
|
231
|
+
> - question: "Polyrepo signals detected — this repo may be part of a multi-repo system. Would you like to provide related repo URLs?"
|
|
232
|
+
> - header: "Polyrepo?"
|
|
233
|
+
> - options: [{ label: "Yes, I'll list them", description: "Provide sibling repo URLs — improves system-level context accuracy" }, { label: "Skip for now", description: "Continue without related repos — affected fields will be marked ASSUMED" }]
|
|
234
|
+
> - multiSelect: false
|
|
235
|
+
> - **Cursor / Codex / Antigravity / other:** use text prompt below
|
|
236
|
+
|
|
237
|
+
```
|
|
238
|
+
⚠️ Polyrepo signals detected:
|
|
239
|
+
{list polyrepo_hints}
|
|
240
|
+
|
|
241
|
+
This repo appears to be part of a multi-repo system.
|
|
242
|
+
Would you like to list related repos? (optional — press Enter to skip)
|
|
243
|
+
Format: one URL per line, e.g. https://github.com/org/api-service [backend]
|
|
244
|
+
```
|
|
245
|
+
- User-supplied repos → stored in `related_repos[]` as `{ url, role }`
|
|
246
|
+
- If user skips → `related_repos: []`; system-level context fields set to **ASSUMED** tier
|
|
247
|
+
|
|
248
|
+
**Gap-fill rule for polyrepo:**
|
|
249
|
+
- `polyrepo_hints` non-empty AND `related_repos` empty → system-level fields (e.g. `deployment_topology`) = ASSUMED (not MISSING; single-repo scan is still valid)
|
|
250
|
+
- `related_repos` populated → system-level fields = DETECTED for user-supplied context
|
|
251
|
+
|
|
252
|
+
If no manifest found → `primary_language` = MISSING; user must provide.
|
|
253
|
+
|
|
254
|
+
---
|
|
255
|
+
|
|
256
|
+
### Signal Category 2 — Framework & Library Detection
|
|
257
|
+
|
|
258
|
+
Infer from `raw_dependencies[]` + `raw_dev_dependencies[]`:
|
|
259
|
+
|
|
260
|
+
**Backend frameworks:**
|
|
261
|
+
| Signal pattern | Framework |
|
|
262
|
+
|---------------|-----------|
|
|
263
|
+
| `spring-boot-starter-*` | Spring Boot |
|
|
264
|
+
| `express`, `fastify`, `koa`, `hapi` | Node.js HTTP |
|
|
265
|
+
| `nestjs/core` | NestJS |
|
|
266
|
+
| `fastapi`, `flask`, `django` | Python HTTP |
|
|
267
|
+
| `gin-gonic/gin`, `gofiber/fiber`, `labstack/echo` | Go HTTP |
|
|
268
|
+
| `rails`, `sinatra` | Ruby |
|
|
269
|
+
| `laravel/framework`, `slim/slim` | PHP |
|
|
270
|
+
| `actix-web`, `axum`, `rocket` | Rust HTTP |
|
|
271
|
+
| `phoenix` (mix.exs) | Elixir |
|
|
272
|
+
| `Microsoft.AspNetCore.*` | .NET ASP.NET Core |
|
|
273
|
+
|
|
274
|
+
**Frontend frameworks:**
|
|
275
|
+
| Signal pattern | Framework |
|
|
276
|
+
|---------------|-----------|
|
|
277
|
+
| `react`, `react-dom` | React |
|
|
278
|
+
| `vue` | Vue.js |
|
|
279
|
+
| `@angular/core` | Angular |
|
|
280
|
+
| `svelte` | Svelte |
|
|
281
|
+
| `next` | Next.js |
|
|
282
|
+
| `nuxt` | Nuxt.js |
|
|
283
|
+
| `remix` | Remix |
|
|
284
|
+
| `astro` | Astro |
|
|
285
|
+
| `solid-js` | SolidJS |
|
|
286
|
+
|
|
287
|
+
**ORM / Database clients:**
|
|
288
|
+
| Signal pattern | ORM / DB |
|
|
289
|
+
|---------------|----------|
|
|
290
|
+
| `mybatis-spring-boot-starter`, `mybatis` | MyBatis |
|
|
291
|
+
| `spring-boot-starter-data-jpa`, `hibernate-*` | Hibernate / JPA |
|
|
292
|
+
| `typeorm` | TypeORM |
|
|
293
|
+
| `prisma` | Prisma |
|
|
294
|
+
| `sequelize` | Sequelize |
|
|
295
|
+
| `sqlalchemy`, `alembic` | SQLAlchemy |
|
|
296
|
+
| `gorm.io/gorm` | GORM |
|
|
297
|
+
| `mongoose` | Mongoose (MongoDB) |
|
|
298
|
+
| `pg`, `mysql2`, `mariadb`, `better-sqlite3` | Raw SQL clients |
|
|
299
|
+
| `redis`, `ioredis` | Redis client |
|
|
300
|
+
|
|
301
|
+
**Message broker clients:**
|
|
302
|
+
| Signal pattern | Broker |
|
|
303
|
+
|---------------|--------|
|
|
304
|
+
| `spring-kafka`, `kafka-clients` | Apache Kafka |
|
|
305
|
+
| `amqplib`, `spring-rabbit` | RabbitMQ |
|
|
306
|
+
| `@aws-sdk/client-sqs` | AWS SQS |
|
|
307
|
+
| `nats` | NATS |
|
|
308
|
+
| `bullmq`, `bull` | Redis-based queue |
|
|
309
|
+
|
|
310
|
+
**Auth libraries:**
|
|
311
|
+
| Signal pattern | Auth mechanism |
|
|
312
|
+
|---------------|----------------|
|
|
313
|
+
| `spring-security`, `spring-boot-starter-security` | Spring Security |
|
|
314
|
+
| `jsonwebtoken`, `jose`, `passport-jwt` | JWT |
|
|
315
|
+
| `passport` | OAuth / multi-strategy |
|
|
316
|
+
| `keycloak-*`, `keycloak-connect` | Keycloak |
|
|
317
|
+
| `next-auth`, `@auth/core` | NextAuth |
|
|
318
|
+
| `authlib`, `python-jose`, `djangorestframework-simplejwt` | Python auth |
|
|
319
|
+
|
|
320
|
+
**Test frameworks:**
|
|
321
|
+
| Signal pattern | Framework |
|
|
322
|
+
|---------------|-----------|
|
|
323
|
+
| `jest`, `@jest/core` | Jest |
|
|
324
|
+
| `vitest` | Vitest |
|
|
325
|
+
| `mocha` | Mocha |
|
|
326
|
+
| `jasmine` | Jasmine |
|
|
327
|
+
| `junit`, `spring-boot-starter-test` | JUnit |
|
|
328
|
+
| `pytest` | pytest |
|
|
329
|
+
| `rspec-rails`, `rspec` | RSpec |
|
|
330
|
+
| `cypress` | Cypress E2E |
|
|
331
|
+
| `playwright` | Playwright E2E |
|
|
332
|
+
| `@testing-library/*` | Testing Library |
|
|
333
|
+
| `testify` | Testify (Go) |
|
|
334
|
+
|
|
335
|
+
Rule: If zero backend AND zero frontend frameworks detected → add entry to `open_questions[]` and ask user.
|
|
336
|
+
|
|
337
|
+
---
|
|
338
|
+
|
|
339
|
+
### Signal Category 3 — Architecture Layer Inference (Directory Structure)
|
|
340
|
+
|
|
341
|
+
Glob the following path patterns; presence implies the corresponding layer:
|
|
342
|
+
|
|
343
|
+
| Pattern(s) | Inferred layer |
|
|
344
|
+
|------------|----------------|
|
|
345
|
+
| `src/main/java/**`, `src/main/kotlin/**` | Java/Kotlin Maven standard layout |
|
|
346
|
+
| `src/controllers/`, `app/controllers/`, `**/controller/**` | MVC — Controller layer |
|
|
347
|
+
| `src/api/`, `api/`, `routes/`, `src/routes/` | API / Router layer |
|
|
348
|
+
| `src/services/`, `services/`, `**/service/**` | Service / Business logic layer |
|
|
349
|
+
| `src/repositories/`, `repositories/`, `**/repository/**`, `**/dao/**` | Repository / DAO layer |
|
|
350
|
+
| `src/models/`, `models/`, `**/model/**`, `**/entity/**` | Domain models / Entities |
|
|
351
|
+
| `src/middleware/`, `middleware/` | Middleware layer |
|
|
352
|
+
| `src/utils/`, `utils/`, `helpers/`, `common/` | Utilities / Shared |
|
|
353
|
+
| `frontend/`, `client/`, `web/`, `src/client/` | Frontend module |
|
|
354
|
+
| `backend/`, `server/`, `src/server/` | Backend module |
|
|
355
|
+
| `packages/`, `apps/`, `libs/` | Monorepo layout |
|
|
356
|
+
| `infrastructure/`, `infra/`, `terraform/`, `helm/`, `k8s/`, `kubernetes/` | Infrastructure / IaC |
|
|
357
|
+
| `scripts/`, `bin/`, `tools/` | Developer tooling |
|
|
358
|
+
| `public/`, `static/`, `assets/` | Static assets |
|
|
359
|
+
| `docs/`, `documentation/` | Documentation |
|
|
360
|
+
| `config/`, `configs/`, `settings/` | Configuration |
|
|
361
|
+
| `tests/`, `test/`, `__tests__/`, `spec/`, `e2e/` | Test suite root |
|
|
362
|
+
| `migrations/`, `db/migrate/`, `alembic/` | Database migrations |
|
|
363
|
+
|
|
364
|
+
Output: `architecture_layers[]` — each with `{ layer, evidence_path }`.
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
### Signal Category 4 — Database Schema Signals
|
|
369
|
+
|
|
370
|
+
Probe for migration/schema evidence:
|
|
371
|
+
|
|
372
|
+
| Pattern | Evidence type |
|
|
373
|
+
|---------|---------------|
|
|
374
|
+
| `db/migrate/*.rb` | Rails ActiveRecord migrations |
|
|
375
|
+
| `migrations/*.sql`, `migrations/*.js`, `migrations/*.ts` | Generic migrations |
|
|
376
|
+
| `src/main/resources/db/migration/V*.sql` | Flyway |
|
|
377
|
+
| `db/changelog*.xml`, `db/changelog*.yaml` | Liquibase |
|
|
378
|
+
| `alembic/versions/*.py` | SQLAlchemy Alembic |
|
|
379
|
+
| `src/migrations/**` | TypeORM / Sequelize migrations |
|
|
380
|
+
| `prisma/schema.prisma` | Prisma schema |
|
|
381
|
+
| `**/schema.sql`, `**/init.sql`, `**/seed.sql` | Raw SQL schema / seed |
|
|
382
|
+
| `docker-compose.yml` → service names | Implied DB types (postgres, mysql, mongo, redis…) |
|
|
383
|
+
|
|
384
|
+
Output: `database_signals[]` — each with `{ type, evidence_path, migration_tool }`.
|
|
385
|
+
|
|
386
|
+
Rule: If none found but ORM dep exists → `database_signals` = ASSUMED with rationale note.
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
### Signal Category 5 — API Contract Files
|
|
391
|
+
|
|
392
|
+
| File pattern | Contract type |
|
|
393
|
+
|-------------|---------------|
|
|
394
|
+
| `openapi.yaml`, `openapi.json`, `swagger.yaml`, `swagger.json` | OpenAPI / Swagger |
|
|
395
|
+
| `api-docs.yaml`, `api.yaml`, `api-spec.yaml`, `api/*.yaml` | OpenAPI (alternate) |
|
|
396
|
+
| `*.proto`, `proto/**/*.proto` | gRPC / Protocol Buffers |
|
|
397
|
+
| `schema.graphql`, `**/*.graphql` | GraphQL |
|
|
398
|
+
| `src/main/resources/static/v3/api-docs*` | Spring Swagger (generated) |
|
|
399
|
+
| `postman_collection.json`, `*.postman_collection.json` | Postman |
|
|
400
|
+
| `insomnia.yaml`, `.insomnia/` | Insomnia |
|
|
401
|
+
|
|
402
|
+
`api_style` inference:
|
|
403
|
+
- REST → if OpenAPI/Swagger file found
|
|
404
|
+
- gRPC → if `*.proto` found (set `mixed` if REST also found)
|
|
405
|
+
- GraphQL → if `schema.graphql` / `*.graphql` found
|
|
406
|
+
- ASSUMED REST → if REST framework detected but no contract file found
|
|
407
|
+
- MISSING → if api_style still unknown after all signals; user prompted
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
### Signal Category 6 — Infrastructure & Deployment Configuration
|
|
412
|
+
|
|
413
|
+
| File pattern | Deployment signal |
|
|
414
|
+
|-------------|------------------|
|
|
415
|
+
| `Dockerfile` | Containerized — read `FROM` for base image |
|
|
416
|
+
| `docker-compose.yml`, `docker-compose*.yml` | Service topology (list all services) |
|
|
417
|
+
| `.github/workflows/*.yml` | GitHub Actions CI/CD |
|
|
418
|
+
| `.gitlab-ci.yml` | GitLab CI |
|
|
419
|
+
| `Jenkinsfile` | Jenkins pipeline |
|
|
420
|
+
| `.circleci/config.yml` | CircleCI |
|
|
421
|
+
| `bitbucket-pipelines.yml` | Bitbucket Pipelines |
|
|
422
|
+
| `k8s/**/*.yaml`, `kubernetes/**/*.yaml` | Kubernetes manifests |
|
|
423
|
+
| `helm/**`, `Chart.yaml` | Helm charts |
|
|
424
|
+
| `terraform/**/*.tf` | Terraform IaC |
|
|
425
|
+
| `pulumi/**`, `Pulumi.yaml` | Pulumi IaC |
|
|
426
|
+
| `ansible/**`, `playbook.yml` | Ansible |
|
|
427
|
+
| `nginx.conf`, `nginx/**` | Nginx reverse proxy |
|
|
428
|
+
| `serverless.yml`, `serverless.ts` | Serverless Framework |
|
|
429
|
+
| `fly.toml` | Fly.io |
|
|
430
|
+
| `vercel.json`, `.vercel/` | Vercel |
|
|
431
|
+
| `netlify.toml` | Netlify |
|
|
432
|
+
| `render.yaml` | Render |
|
|
433
|
+
|
|
434
|
+
Output: `deployment_signals[]` — each with `{ platform, file_path, notes }`.
|
|
435
|
+
|
|
436
|
+
Rule: If no deployment signal found → `deployment_signals` = MISSING; user prompted.
|
|
437
|
+
|
|
438
|
+
---
|
|
439
|
+
|
|
440
|
+
### Signal Category 7 — Environment & Configuration Shape
|
|
441
|
+
|
|
442
|
+
| File pattern | Purpose |
|
|
443
|
+
|-------------|---------|
|
|
444
|
+
| `.env.example`, `.env.sample`, `.env.template` | Required env key shape |
|
|
445
|
+
| `application.properties`, `application.yml`, `application-*.yml` | Spring Boot config |
|
|
446
|
+
| `config/database.yml` | Rails DB config |
|
|
447
|
+
| `config/settings.py`, `config/*.py` | Django / Python config |
|
|
448
|
+
| `appsettings.json`, `appsettings.*.json` | .NET config |
|
|
449
|
+
| `config/config.exs`, `config/runtime.exs` | Elixir config |
|
|
450
|
+
| `config.yaml`, `config.yml` (project root or config/) | Generic config |
|
|
451
|
+
|
|
452
|
+
**Rule:** Read `.env.example` / `.env.sample` / `.env.template` to extract key names into `config_keys[]`.
|
|
453
|
+
**SAFETY: Never read `.env` (live secrets file) — scanner explicitly skips it.**
|
|
454
|
+
|
|
455
|
+
---
|
|
456
|
+
|
|
457
|
+
### Signal Category 8 — Test Coverage Signals
|
|
458
|
+
|
|
459
|
+
| File pattern | Test framework |
|
|
460
|
+
|-------------|----------------|
|
|
461
|
+
| `jest.config.js`, `jest.config.ts`, `jest.config.mjs` | Jest |
|
|
462
|
+
| `vitest.config.ts`, `vitest.config.js` | Vitest |
|
|
463
|
+
| `.mocharc.js`, `.mocharc.yaml` | Mocha |
|
|
464
|
+
| `pytest.ini`, `setup.cfg [tool:pytest]`, `pyproject.toml [tool.pytest.ini_options]` | pytest |
|
|
465
|
+
| `karma.conf.js` | Karma |
|
|
466
|
+
| `cypress.config.js`, `cypress.config.ts`, `cypress.json` | Cypress |
|
|
467
|
+
| `playwright.config.ts`, `playwright.config.js` | Playwright |
|
|
468
|
+
| `phpunit.xml`, `phpunit.xml.dist` | PHPUnit |
|
|
469
|
+
|
|
470
|
+
**Coverage indicators:** presence of `coverage/`, `htmlcov/`, `.nyc_output/`, `target/site/jacoco/` → `has_coverage_reports = true`.
|
|
471
|
+
|
|
472
|
+
Output: `test_frameworks[]`, `test_root_dirs[]`, `has_coverage_reports`.
|
|
473
|
+
|
|
474
|
+
Rule: If no test signals found → `test_frameworks` = MISSING; note added to generated `SYSTEM-RULES.md` quality gates section.
|
|
475
|
+
|
|
476
|
+
---
|
|
477
|
+
|
|
478
|
+
### Signal Category 9 — Code Quality & Tooling
|
|
479
|
+
|
|
480
|
+
| File pattern | Tool |
|
|
481
|
+
|-------------|------|
|
|
482
|
+
| `.eslintrc*`, `eslint.config.*` | ESLint |
|
|
483
|
+
| `.prettierrc*`, `prettier.config.*` | Prettier |
|
|
484
|
+
| `sonar-project.properties`, `sonar-project.yml` | SonarQube |
|
|
485
|
+
| `.pre-commit-config.yaml` | pre-commit hooks |
|
|
486
|
+
| `checkstyle.xml` | Checkstyle (Java) |
|
|
487
|
+
| `.pylintrc`, `pylint.cfg` | Pylint |
|
|
488
|
+
| `.flake8`, `setup.cfg [flake8]` | Flake8 |
|
|
489
|
+
| `mypy.ini`, `pyproject.toml [tool.mypy]` | mypy |
|
|
490
|
+
| `rustfmt.toml`, `.rustfmt.toml` | rustfmt |
|
|
491
|
+
| `.golangci.yml` | golangci-lint |
|
|
492
|
+
| `.editorconfig` | EditorConfig |
|
|
493
|
+
| `commitlint.config.js`, `.commitlintrc*` | Conventional Commits enforcement |
|
|
494
|
+
| `.husky/` | Husky git hooks |
|
|
495
|
+
| `lint-staged.config.*`, `package.json "lint-staged"` | lint-staged |
|
|
496
|
+
|
|
497
|
+
Output: `quality_tools[]` — used to populate `SYSTEM-RULES.md` quality gates section.
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
### Signal Category 10 — Documentation Files
|
|
502
|
+
|
|
503
|
+
| File | Priority |
|
|
504
|
+
|------|----------|
|
|
505
|
+
| `README.md` | MUST-READ — extract: project name, description, quickstart |
|
|
506
|
+
| `CHANGELOG.md`, `HISTORY.md`, `RELEASES.md` | SHOULD-READ — extract: version history, latest changes |
|
|
507
|
+
| `CONTRIBUTING.md` | SHOULD-READ — extract: contribution rules |
|
|
508
|
+
| `ARCHITECTURE.md`, `docs/architecture*.md` | SHOULD-READ — extract: any existing arch notes |
|
|
509
|
+
| `docs/adr/`, `ADR/`, `decisions/` | SHOULD-READ — Architecture Decision Records |
|
|
510
|
+
| `docs/**/*.md` (top 10 by mtime) | NICE-TO-READ — project-specific docs |
|
|
511
|
+
| `LICENSE` | MUST-READ — extract license type |
|
|
512
|
+
|
|
513
|
+
Output: `docs_extracted[]` — each with `{ file, summary, key_facts[] }`.
|
|
514
|
+
|
|
515
|
+
Rule: If `README.md` absent → `project_name` elevated to MISSING (must ask user).
|
|
516
|
+
|
|
517
|
+
---
|
|
518
|
+
|
|
519
|
+
### Signal Category 11 — Git History & Version Signals
|
|
520
|
+
|
|
521
|
+
Run the following git commands (read-only):
|
|
522
|
+
|
|
523
|
+
| Command | Purpose |
|
|
524
|
+
|---------|---------|
|
|
525
|
+
| `git log --oneline -100` | Commit message patterns (Conventional Commits? Jira refs? free-form?) |
|
|
526
|
+
| `git tag --sort=-version:refname \| head -20` | Version history + tag naming convention |
|
|
527
|
+
| `git log --format="%H %s" --diff-filter=A -- "*.md" \| head -20` | When key docs were added |
|
|
528
|
+
| `git branch -a \| head -20` | Branch naming convention |
|
|
529
|
+
| `git log --stat -3` | Most recently changed files |
|
|
530
|
+
| `git shortlog -sn --no-merges \| head -10` | Top contributors |
|
|
531
|
+
| `git remote get-url origin` | Repository URL |
|
|
532
|
+
|
|
533
|
+
Extract: `commit_convention` (Conventional Commits / Jira-ref / free-form / mixed), `version_pattern` (semver / calver / custom), `latest_tag`, `active_branches[]`, `top_contributors[]`, `repo_url`.
|
|
534
|
+
|
|
535
|
+
Rule: If not a git repo → all git fields = MISSING; user warned.
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
### Signal Category 12 — File Extension Language Survey
|
|
540
|
+
|
|
541
|
+
Glob source file extensions to detect secondary languages:
|
|
542
|
+
|
|
543
|
+
```
|
|
544
|
+
Glob: src/**/*.{ts,tsx,js,jsx,py,java,kt,go,rs,rb,php,cs,swift,ex,exs,scala,clj,elm,dart}
|
|
545
|
+
(also check project root if no src/ directory)
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
Count files per extension → `language_distribution{}` (e.g. `{ ts: 142, java: 38, sql: 12 }`).
|
|
549
|
+
|
|
550
|
+
Rule: `secondary_languages[]` = languages with ≥5 files that are not `primary_language`.
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
### Scan Report Schema (finalized)
|
|
555
|
+
|
|
556
|
+
After running all 12 signal categories, produce this structured Scan Report:
|
|
557
|
+
|
|
558
|
+
```yaml
|
|
559
|
+
# ViePilot Brownfield Scan Report
|
|
560
|
+
project_name: string # from manifest or README
|
|
561
|
+
current_version: string # from manifest or latest git tag
|
|
562
|
+
primary_language: string # from manifest
|
|
563
|
+
secondary_languages: [] # from file extension survey
|
|
564
|
+
runtime_version: string # node/java/python/go version
|
|
565
|
+
frameworks:
|
|
566
|
+
backend: []
|
|
567
|
+
frontend: []
|
|
568
|
+
orm: []
|
|
569
|
+
auth: []
|
|
570
|
+
message_broker: []
|
|
571
|
+
build_tool: string
|
|
572
|
+
package_manager: string
|
|
573
|
+
monorepo: bool
|
|
574
|
+
gap_tier: DETECTED | ASSUMED | MISSING # root rollup = worst tier across all modules
|
|
575
|
+
modules: # if monorepo or submodules detected
|
|
576
|
+
- name: string # workspace package name or submodule name
|
|
577
|
+
type: workspace | submodule | root # workspace = monorepo member; submodule = git submodule
|
|
578
|
+
path: string # repo-relative path
|
|
579
|
+
submodule_url: string | null # remote URL from .gitmodules (null if not submodule)
|
|
580
|
+
initialized: bool # true if path exists on disk (submodules only)
|
|
581
|
+
primary_language: string
|
|
582
|
+
framework: string | null
|
|
583
|
+
module_purpose: string # inferred from dir name + manifest description
|
|
584
|
+
entry_point: string | null # main entry file path
|
|
585
|
+
gap_tier: DETECTED | ASSUMED | MISSING
|
|
586
|
+
must_detect_status: # evidence record per MUST-DETECT field
|
|
587
|
+
primary_language: { value: string, source: string, tier: string }
|
|
588
|
+
framework: { value: string, source: string, tier: string }
|
|
589
|
+
module_purpose: { value: string, source: string, tier: string }
|
|
590
|
+
entry_point: { value: string, source: string, tier: string }
|
|
591
|
+
open_questions: [] # per-module open questions
|
|
592
|
+
polyrepo_hints: # present only when polyrepo signals detected
|
|
593
|
+
- source: string # e.g. docker-compose.yml
|
|
594
|
+
hint: string # raw signal text
|
|
595
|
+
inferred_repo: string # guessed sibling repo name
|
|
596
|
+
related_repos: # present only when user supplied input after prompt
|
|
597
|
+
- url: string
|
|
598
|
+
role: string # backend | frontend | shared-library | infra | etc.
|
|
599
|
+
architecture_layers: [] # { layer, evidence_path }
|
|
600
|
+
module_dependencies: [] # { from, to, type, evidence_path } — Gap D (Phase 78)
|
|
601
|
+
dependency_cycles: [] # cycle paths detected — Gap D (Phase 78)
|
|
602
|
+
database_signals: [] # { type, evidence_path, migration_tool }
|
|
603
|
+
api_contracts: [] # { style, file_path }
|
|
604
|
+
api_style: string # REST | GraphQL | gRPC | mixed | unknown
|
|
605
|
+
deployment_signals: [] # { platform, file_path }
|
|
606
|
+
test_frameworks: []
|
|
607
|
+
test_root_dirs: []
|
|
608
|
+
has_coverage_reports: bool
|
|
609
|
+
quality_tools: []
|
|
610
|
+
config_keys: [] # from .env.example (key names only — no values)
|
|
611
|
+
commit_convention: string # conventional | jira | free-form | mixed
|
|
612
|
+
version_pattern: string # semver | calver | custom
|
|
613
|
+
latest_tag: string
|
|
614
|
+
repo_url: string
|
|
615
|
+
top_contributors: []
|
|
616
|
+
docs_extracted: [] # { file, summary, key_facts[] }
|
|
617
|
+
language_distribution: {} # { ts: 142, java: 38, ... }
|
|
618
|
+
open_questions: [] # root-level open questions (includes rollup from modules)
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
---
|
|
622
|
+
|
|
623
|
+
### Gap Detection Rules
|
|
624
|
+
|
|
625
|
+
Every field in Scan Report is classified as:
|
|
626
|
+
|
|
627
|
+
| Status | Meaning | Required action |
|
|
628
|
+
|--------|---------|-----------------|
|
|
629
|
+
| **DETECTED** | Inferred from codebase with high confidence | Show for confirmation — no user action required |
|
|
630
|
+
| **ASSUMED** | Inferred with low confidence or indirect signal | Show to user with rationale; user may correct |
|
|
631
|
+
| **MISSING** | Not found anywhere in codebase | **Must ask user** before generating artifacts |
|
|
632
|
+
|
|
633
|
+
**MUST-DETECT fields** (MISSING = hard blocker — cannot generate artifacts until user fills):
|
|
634
|
+
- `project_name`
|
|
635
|
+
- `primary_language`
|
|
636
|
+
- At least one entry in `frameworks.backend` OR `frameworks.frontend`
|
|
637
|
+
- `current_version`
|
|
638
|
+
|
|
639
|
+
**SHOULD-DETECT fields** (MISSING = warning — document assumption, continue with user acknowledgment):
|
|
640
|
+
- `api_style`
|
|
641
|
+
- At least one entry in `database_signals` (if ORM dep found)
|
|
642
|
+
- `test_frameworks`
|
|
643
|
+
- `commit_convention`
|
|
644
|
+
- `deployment_signals`
|
|
645
|
+
|
|
646
|
+
**NICE-TO-DETECT fields** (MISSING = note only — generate with placeholder):
|
|
647
|
+
- `auth` frameworks, `message_broker`, `config_keys`, `top_contributors`, `has_coverage_reports`
|
|
648
|
+
|
|
649
|
+
**Assumption documentation rule:** For every ASSUMED or MISSING field that proceeds without user fill, append to `open_questions[]` and insert a `> ⚠️ Assumed: {rationale}` callout in the relevant `.viepilot/` artifact section.
|
|
650
|
+
|
|
651
|
+
---
|
|
652
|
+
|
|
653
|
+
### Per-Module Gap Detection
|
|
654
|
+
|
|
655
|
+
Applies to every entry in `modules[]` (monorepo workspace members, git submodules, and root if single-repo). Each module is assessed independently.
|
|
656
|
+
|
|
657
|
+
**Per-module MUST-DETECT fields:**
|
|
658
|
+
|
|
659
|
+
| Field | Source signals | Tier if absent |
|
|
660
|
+
|-------|---------------|----------------|
|
|
661
|
+
| `primary_language` | Manifest extension, file survey (Signal Cat 12), `tsconfig.json`, `pyproject.toml` | MISSING — must ask user |
|
|
662
|
+
| `framework` | Signal Cat 2 dep patterns scanned on module path | ASSUMED if no dep match; MISSING if no manifest found |
|
|
663
|
+
| `module_purpose` | Manifest `description` field, directory name convention, README first line | ASSUMED (infer from dir name); MISSING if none of the above |
|
|
664
|
+
| `entry_point` | `main` in `package.json`; `src/index.*`; `cmd/main.go`; `*Application.java` | ASSUMED if standard path exists; MISSING otherwise |
|
|
665
|
+
|
|
666
|
+
**Gap tier assignment per module:**
|
|
667
|
+
```
|
|
668
|
+
DETECTED — all MUST-DETECT fields sourced directly from file evidence (no inference)
|
|
669
|
+
ASSUMED — ≥1 MUST-DETECT field inferred by convention (no direct file evidence, but plausible)
|
|
670
|
+
MISSING — ≥1 MUST-DETECT field has no evidence and cannot be inferred
|
|
671
|
+
```
|
|
672
|
+
|
|
673
|
+
**`must_detect_status` evidence conventions:**
|
|
674
|
+
- `source: "tsconfig.json"` — read from a specific file
|
|
675
|
+
- `source: "inferred"` — derived by directory name / naming convention (tier = ASSUMED)
|
|
676
|
+
- `source: "absent"` — no evidence found (tier = MISSING)
|
|
677
|
+
- `source: "user"` — provided by user during gap-filling (tier = DETECTED)
|
|
678
|
+
|
|
679
|
+
**Root gap tier rollup:**
|
|
680
|
+
```
|
|
681
|
+
root gap_tier = worst tier across all modules
|
|
682
|
+
Priority order: MISSING > ASSUMED > DETECTED
|
|
683
|
+
```
|
|
684
|
+
If any module is MISSING → root `gap_tier` = MISSING → artifact generation blocked until resolved.
|
|
685
|
+
If all modules are DETECTED or ASSUMED → root `gap_tier` matches the worst module tier.
|
|
686
|
+
|
|
687
|
+
**Scan summary printout** (show after all modules scanned):
|
|
688
|
+
```
|
|
689
|
+
Module scan summary:
|
|
690
|
+
┌─────────────────┬──────────────────┬────────────┬──────────────┬───────────┐
|
|
691
|
+
│ Module │ Path │ Language │ Framework │ Gap Tier │
|
|
692
|
+
├─────────────────┼──────────────────┼────────────┼──────────────┼───────────┤
|
|
693
|
+
│ api-service │ apps/api │ TypeScript │ NestJS │ DETECTED │
|
|
694
|
+
│ web-client │ apps/web │ TypeScript │ React │ DETECTED │
|
|
695
|
+
│ shared-lib │ libs/shared │ TypeScript │ — │ ASSUMED │
|
|
696
|
+
│ legacy-worker │ services/worker │ MISSING │ MISSING │ MISSING │
|
|
697
|
+
└─────────────────┴──────────────────┴────────────┴──────────────┴───────────┘
|
|
698
|
+
Root gap tier: MISSING (worst across modules)
|
|
699
|
+
```
|
|
700
|
+
|
|
701
|
+
---
|
|
702
|
+
|
|
703
|
+
### Interactive Gap-Filling (Step 0-B-ii)
|
|
704
|
+
|
|
705
|
+
After scanner completes:
|
|
706
|
+
|
|
707
|
+
1. Display Scan Report summary table to user (field | value | status).
|
|
708
|
+
2. **Per-module MISSING fields** — for each module with `gap_tier: MISSING`, pause and ask per field:
|
|
709
|
+
```
|
|
710
|
+
⛔ Module '{name}' (path: {path}) has MISSING required fields:
|
|
711
|
+
- {field}: no evidence found
|
|
712
|
+
Please provide {field}:
|
|
713
|
+
```
|
|
714
|
+
Record answer as `{ value: user_input, source: "user", tier: DETECTED }`.
|
|
715
|
+
Do NOT proceed to artifact generation until all MISSING module fields are filled.
|
|
716
|
+
3. For each root-level MUST-DETECT field that is MISSING → **pause and ask user to provide value**.
|
|
717
|
+
4. Present ASSUMED fields (root + per-module) in a confirmation table → user may accept all with "y" or override individually.
|
|
718
|
+
5. Capture all user responses; update Scan Report fields accordingly.
|
|
719
|
+
6. All remaining unresolved items → `open_questions[]` (roll up per-module `open_questions[]` into root).
|
|
720
|
+
|
|
721
|
+
---
|
|
722
|
+
|
|
723
|
+
### Brownfield Brainstorm Stub Generation (Step 0-C)
|
|
724
|
+
|
|
725
|
+
After gap-filling is complete, write:
|
|
726
|
+
|
|
727
|
+
**Path:** `docs/brainstorm/session-brownfield-import.md`
|
|
728
|
+
|
|
729
|
+
**Content:**
|
|
730
|
+
```markdown
|
|
731
|
+
# Brownfield Import — {project_name}
|
|
732
|
+
|
|
733
|
+
## Meta
|
|
734
|
+
- **Import date**: {scan_date}
|
|
735
|
+
- **Import source**: `vp-crystallize --brownfield`
|
|
736
|
+
- **Scanner version**: FEAT-018
|
|
737
|
+
|
|
738
|
+
## Scan Report
|
|
739
|
+
|
|
740
|
+
\`\`\`yaml
|
|
741
|
+
{full confirmed Scan Report YAML}
|
|
742
|
+
\`\`\`
|
|
743
|
+
```
|
|
744
|
+
|
|
745
|
+
**Purpose:** This stub allows `vp-audit` and other ViePilot tools to not error on missing brainstorm session files. The presence of `session-brownfield-import.md` is treated as a valid brownfield import.
|
|
746
|
+
|
|
747
|
+
---
|
|
748
|
+
|
|
749
|
+
### Safety Rules
|
|
750
|
+
|
|
751
|
+
The brownfield scanner MUST:
|
|
752
|
+
|
|
753
|
+
```
|
|
754
|
+
NEVER read:
|
|
755
|
+
.env (live secrets)
|
|
756
|
+
*.key, *.pem, *.p12, *.jks, id_rsa, id_ed25519
|
|
757
|
+
|
|
758
|
+
ALWAYS skip these directories:
|
|
759
|
+
node_modules/
|
|
760
|
+
.git/
|
|
761
|
+
target/
|
|
762
|
+
build/
|
|
763
|
+
dist/
|
|
764
|
+
__pycache__/
|
|
765
|
+
.venv/
|
|
766
|
+
vendor/
|
|
767
|
+
|
|
768
|
+
NEVER write any files until the user has confirmed the Scan Report.
|
|
769
|
+
|
|
770
|
+
NEVER overwrite existing .viepilot/ without explicit user confirmation (y/n prompt).
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
---
|
|
774
|
+
|
|
775
|
+
### TRACKER.md Continuity Annotation
|
|
776
|
+
|
|
777
|
+
When generating TRACKER.md in Step 9 (brownfield mode only), append:
|
|
778
|
+
|
|
779
|
+
```markdown
|
|
780
|
+
## Brownfield Import
|
|
781
|
+
- **Import date**: {scan_date}
|
|
782
|
+
- **Imported version**: {current_version}
|
|
783
|
+
- **Note**: Project history pre-dates ViePilot adoption.
|
|
784
|
+
- **Scan Report**: `docs/brainstorm/session-brownfield-import.md`
|
|
785
|
+
```
|
|
786
|
+
|
|
787
|
+
</step>
|
|
788
|
+
|
|
107
789
|
<step name="analyze_brainstorm">
|
|
108
790
|
## Step 1: Analyze Brainstorm
|
|
109
791
|
|
|
@@ -159,6 +841,14 @@ Check if `.viepilot/ui-direction/` exists and contains any session artifacts.
|
|
|
159
841
|
|
|
160
842
|
If `ui_scope_detected = true` **AND** artifacts are missing → **STOP** and present:
|
|
161
843
|
|
|
844
|
+
> **Adapter-aware prompt:**
|
|
845
|
+
> - **Claude Code (terminal):** use `AskUserQuestion` tool — spec:
|
|
846
|
+
> - question: "UI Direction artifacts missing. The brainstorm indicates UI scope but `.viepilot/ui-direction/` has no artifacts. How to proceed?"
|
|
847
|
+
> - header: "UI Direction"
|
|
848
|
+
> - options: [{ label: "Return to /vp-brainstorm --ui (Recommended)", description: "Create UI direction artifacts first for best results" }, { label: "Continue with assumptions", description: "Record assumptions in ARCHITECTURE.md and proceed without visual direction" }]
|
|
849
|
+
> - multiSelect: false
|
|
850
|
+
> - **Cursor / Codex / Antigravity / other:** use text menu below
|
|
851
|
+
|
|
162
852
|
```
|
|
163
853
|
⚠️ UI Direction artifacts missing
|
|
164
854
|
|
|
@@ -324,6 +1014,15 @@ If `.viepilot/architect/` exists with at least one session directory:
|
|
|
324
1014
|
|
|
325
1015
|
If `.viepilot/architect/` does **not** exist but brainstorm shows complex architecture (≥5 services/components detected):
|
|
326
1016
|
- Suggest (soft prompt — not a hard block):
|
|
1017
|
+
|
|
1018
|
+
> **Adapter-aware prompt:**
|
|
1019
|
+
> - **Claude Code (terminal):** use `AskUserQuestion` tool — spec:
|
|
1020
|
+
> - question: "Complex architecture detected (≥5 services/components). Would you like to create architecture visualizations first with /vp-brainstorm --architect?"
|
|
1021
|
+
> - header: "Architect?"
|
|
1022
|
+
> - options: [{ label: "Yes, go to architect mode", description: "Create visual architecture diagrams before crystallizing (recommended for complex systems)" }, { label: "No, continue now", description: "Continue crystallize with text-only brainstorm — no visual diagrams" }]
|
|
1023
|
+
> - multiSelect: false
|
|
1024
|
+
> - **Cursor / Codex / Antigravity / other:** use text menu below
|
|
1025
|
+
|
|
327
1026
|
```
|
|
328
1027
|
💡 Would you like to return to /vp-brainstorm --architect to create visualizations first?
|
|
329
1028
|
1. Yes — return to architect mode
|