@wizdear/atlas-code 0.2.5 → 0.2.6
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/README.md +1 -1
- package/dist/agent-factory.d.ts +2 -4
- package/dist/agent-factory.d.ts.map +1 -1
- package/dist/agent-factory.js +9 -12
- package/dist/agent-factory.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +64 -16
- package/dist/cli.js.map +1 -1
- package/dist/discovery.d.ts +0 -2
- package/dist/discovery.d.ts.map +1 -1
- package/dist/discovery.js +0 -1
- package/dist/discovery.js.map +1 -1
- package/dist/extension.d.ts.map +1 -1
- package/dist/extension.js +23 -64
- package/dist/extension.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/orchestrator.d.ts +0 -2
- package/dist/orchestrator.d.ts.map +1 -1
- package/dist/orchestrator.js +0 -1
- package/dist/orchestrator.js.map +1 -1
- package/dist/pipeline.d.ts +0 -5
- package/dist/pipeline.d.ts.map +1 -1
- package/dist/pipeline.js +0 -3
- package/dist/pipeline.js.map +1 -1
- package/dist/planner.d.ts +0 -2
- package/dist/planner.d.ts.map +1 -1
- package/dist/planner.js +0 -6
- package/dist/planner.js.map +1 -1
- package/dist/roles/cicd.d.ts +1 -1
- package/dist/roles/cicd.d.ts.map +1 -1
- package/dist/roles/cicd.js +5 -0
- package/dist/roles/cicd.js.map +1 -1
- package/dist/roles/reviewer.d.ts +1 -1
- package/dist/roles/reviewer.d.ts.map +1 -1
- package/dist/roles/reviewer.js +7 -1
- package/dist/roles/reviewer.js.map +1 -1
- package/dist/roles/standards-enricher.d.ts +1 -1
- package/dist/roles/standards-enricher.d.ts.map +1 -1
- package/dist/roles/standards-enricher.js +8 -0
- package/dist/roles/standards-enricher.js.map +1 -1
- package/dist/roles/tester.d.ts +1 -1
- package/dist/roles/tester.d.ts.map +1 -1
- package/dist/roles/tester.js +7 -0
- package/dist/roles/tester.js.map +1 -1
- package/dist/standards.d.ts +37 -11
- package/dist/standards.d.ts.map +1 -1
- package/dist/standards.js +71 -90
- package/dist/standards.js.map +1 -1
- package/dist/step-executor.d.ts +13 -2
- package/dist/step-executor.d.ts.map +1 -1
- package/dist/step-executor.js +125 -29
- package/dist/step-executor.js.map +1 -1
- package/dist/store.d.ts +0 -10
- package/dist/store.d.ts.map +1 -1
- package/dist/store.js +0 -41
- package/dist/store.js.map +1 -1
- package/dist/system-architect.d.ts +0 -2
- package/dist/system-architect.d.ts.map +1 -1
- package/dist/system-architect.js +0 -6
- package/dist/system-architect.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -184,7 +184,10 @@ function splitArgs(input) {
|
|
|
184
184
|
// ─── Standard Templates ──────────────────────────────────────────────────────
|
|
185
185
|
/** 14 standard file templates generated by /vibe init */
|
|
186
186
|
export const STANDARD_TEMPLATES = {
|
|
187
|
-
"coding-style.md":
|
|
187
|
+
"coding-style.md": `---
|
|
188
|
+
description: Naming conventions, formatting rules, import ordering
|
|
189
|
+
---
|
|
190
|
+
# Coding Style
|
|
188
191
|
|
|
189
192
|
<!-- Customize: adjust these defaults to match your project's conventions. -->
|
|
190
193
|
|
|
@@ -208,7 +211,10 @@ export const STANDARD_TEMPLATES = {
|
|
|
208
211
|
- Use standard module imports following the project's conventions
|
|
209
212
|
- Group imports: external packages first, then internal modules, separated by a blank line
|
|
210
213
|
`,
|
|
211
|
-
"coding-conventions.md":
|
|
214
|
+
"coding-conventions.md": `---
|
|
215
|
+
description: Error handling, dependency injection, comments, constants, function design
|
|
216
|
+
---
|
|
217
|
+
# Coding Conventions
|
|
212
218
|
|
|
213
219
|
<!-- Customize: adjust these defaults to match your project's conventions. -->
|
|
214
220
|
|
|
@@ -242,7 +248,10 @@ export const STANDARD_TEMPLATES = {
|
|
|
242
248
|
- Explicit return types or type hints for public functions where the language supports it
|
|
243
249
|
- No side effects in functions named as queries (get*, is*, has*)
|
|
244
250
|
`,
|
|
245
|
-
"tech-stack.md":
|
|
251
|
+
"tech-stack.md": `---
|
|
252
|
+
description: Languages, frameworks, build tools, runtime, package manager
|
|
253
|
+
---
|
|
254
|
+
# Tech Stack
|
|
246
255
|
|
|
247
256
|
<!-- This file is populated during project initialization or discovery. -->
|
|
248
257
|
<!-- Update it when the tech stack changes. -->
|
|
@@ -262,7 +271,10 @@ export const STANDARD_TEMPLATES = {
|
|
|
262
271
|
## Package Manager
|
|
263
272
|
<!-- e.g., npm, pnpm, yarn -->
|
|
264
273
|
`,
|
|
265
|
-
"architecture-principles.md":
|
|
274
|
+
"architecture-principles.md": `---
|
|
275
|
+
description: Separation of concerns, integration boundaries, testability, dependency direction
|
|
276
|
+
---
|
|
277
|
+
# Architecture Principles
|
|
266
278
|
|
|
267
279
|
<!-- Customize: adjust these defaults to match your project's architecture. -->
|
|
268
280
|
|
|
@@ -308,7 +320,10 @@ All external dependencies must be abstracted behind interfaces (ports) with swap
|
|
|
308
320
|
- Higher-level modules must not depend on lower-level implementation details
|
|
309
321
|
- Depend on abstractions (interfaces), not concretions
|
|
310
322
|
`,
|
|
311
|
-
"design-guide.md":
|
|
323
|
+
"design-guide.md": `---
|
|
324
|
+
description: API design, data modeling, component design
|
|
325
|
+
---
|
|
326
|
+
# Design Guide
|
|
312
327
|
|
|
313
328
|
<!-- Customize: adjust these defaults to match your project's design approach. -->
|
|
314
329
|
|
|
@@ -332,7 +347,10 @@ All external dependencies must be abstracted behind interfaces (ports) with swap
|
|
|
332
347
|
- Keep interfaces small and focused (Interface Segregation)
|
|
333
348
|
- Design for extension — new behavior via new implementations, not modification of existing code
|
|
334
349
|
`,
|
|
335
|
-
"api-design.md":
|
|
350
|
+
"api-design.md": `---
|
|
351
|
+
description: REST API conventions, language-specific API patterns
|
|
352
|
+
---
|
|
353
|
+
# API Design
|
|
336
354
|
|
|
337
355
|
<!-- Customize: adjust these defaults to match your project's API conventions. -->
|
|
338
356
|
|
|
@@ -352,7 +370,10 @@ All external dependencies must be abstracted behind interfaces (ports) with swap
|
|
|
352
370
|
- Use tagged unions, discriminated unions, or enums for complex state where the language supports it
|
|
353
371
|
- Prefer async/await patterns for asynchronous operations
|
|
354
372
|
`,
|
|
355
|
-
"testing-standards.md":
|
|
373
|
+
"testing-standards.md": `---
|
|
374
|
+
description: Test layers, test scope by change type, unit/integration/E2E rules, mock adapters
|
|
375
|
+
---
|
|
376
|
+
# Testing Standards
|
|
356
377
|
|
|
357
378
|
<!-- Customize: adjust these defaults to match your project's testing approach. -->
|
|
358
379
|
|
|
@@ -396,7 +417,10 @@ All external dependencies must be abstracted behind interfaces (ports) with swap
|
|
|
396
417
|
- All tests must use mock/in-memory adapters — never depend on real external systems
|
|
397
418
|
- Mock adapters must faithfully implement the interface contract
|
|
398
419
|
`,
|
|
399
|
-
"documentation.md":
|
|
420
|
+
"documentation.md": `---
|
|
421
|
+
description: Code documentation, README structure, commit messages
|
|
422
|
+
---
|
|
423
|
+
# Documentation
|
|
400
424
|
|
|
401
425
|
<!-- Customize: adjust these defaults to match your project's documentation approach. -->
|
|
402
426
|
|
|
@@ -421,7 +445,10 @@ Every project must have a README.md containing:
|
|
|
421
445
|
- First line: imperative mood, under 72 characters
|
|
422
446
|
- Body: explain "why" when the change is non-obvious
|
|
423
447
|
`,
|
|
424
|
-
"git-workflow.md":
|
|
448
|
+
"git-workflow.md": `---
|
|
449
|
+
description: Branching strategy, commit conventions, merging rules
|
|
450
|
+
---
|
|
451
|
+
# Git Workflow
|
|
425
452
|
|
|
426
453
|
<!-- Customize: adjust these defaults to match your project's Git workflow. -->
|
|
427
454
|
|
|
@@ -444,7 +471,10 @@ Every project must have a README.md containing:
|
|
|
444
471
|
- Delete feature branches after merge (or keep for traceability — choose one convention)
|
|
445
472
|
- Never force-push to shared branches
|
|
446
473
|
`,
|
|
447
|
-
"security-policy.md":
|
|
474
|
+
"security-policy.md": `---
|
|
475
|
+
description: Secrets management, input validation, authentication, dependency security
|
|
476
|
+
---
|
|
477
|
+
# Security Policy
|
|
448
478
|
|
|
449
479
|
<!-- Customize: adjust these defaults to match your project's security requirements. -->
|
|
450
480
|
|
|
@@ -472,7 +502,10 @@ Every project must have a README.md containing:
|
|
|
472
502
|
- Update vulnerable dependencies promptly
|
|
473
503
|
- Evaluate new dependencies for security track record before adding
|
|
474
504
|
`,
|
|
475
|
-
"dependency-policy.md":
|
|
505
|
+
"dependency-policy.md": `---
|
|
506
|
+
description: Dependency evaluation criteria, version management
|
|
507
|
+
---
|
|
508
|
+
# Dependency Policy
|
|
476
509
|
|
|
477
510
|
<!-- Customize: adjust these defaults to match your project's dependency approach. -->
|
|
478
511
|
|
|
@@ -493,7 +526,10 @@ Prefer standard library / platform APIs over third-party packages when feasible.
|
|
|
493
526
|
- Update dependencies regularly — do not let them go stale
|
|
494
527
|
- Test after updating — run the full test suite before committing dependency updates
|
|
495
528
|
`,
|
|
496
|
-
"performance-guidelines.md":
|
|
529
|
+
"performance-guidelines.md": `---
|
|
530
|
+
description: Performance principles, data structures, resource management
|
|
531
|
+
---
|
|
532
|
+
# Performance Guidelines
|
|
497
533
|
|
|
498
534
|
<!-- Customize: adjust these defaults to match your project's performance needs. -->
|
|
499
535
|
|
|
@@ -514,7 +550,10 @@ Prefer standard library / platform APIs over third-party packages when feasible.
|
|
|
514
550
|
- Use connection pooling for databases and HTTP clients
|
|
515
551
|
- Set reasonable timeouts for all external calls
|
|
516
552
|
`,
|
|
517
|
-
"accessibility.md":
|
|
553
|
+
"accessibility.md": `---
|
|
554
|
+
description: WCAG compliance, keyboard navigation, screen readers, visual design
|
|
555
|
+
---
|
|
556
|
+
# Accessibility
|
|
518
557
|
|
|
519
558
|
<!-- Customize: adjust these defaults if your project has a UI. -->
|
|
520
559
|
<!-- If your project has no user-facing UI, this file can be left as-is. -->
|
|
@@ -542,7 +581,10 @@ Prefer standard library / platform APIs over third-party packages when feasible.
|
|
|
542
581
|
- Do not convey information by color alone
|
|
543
582
|
- Support user font size preferences
|
|
544
583
|
`,
|
|
545
|
-
"observability.md":
|
|
584
|
+
"observability.md": `---
|
|
585
|
+
description: Structured logging, metrics, distributed tracing
|
|
586
|
+
---
|
|
587
|
+
# Observability
|
|
546
588
|
|
|
547
589
|
<!-- Customize: adjust these defaults to match your project's observability needs. -->
|
|
548
590
|
|
|
@@ -565,7 +607,10 @@ Prefer standard library / platform APIs over third-party packages when feasible.
|
|
|
565
607
|
- Instrument key operations: incoming requests, outgoing calls, database queries
|
|
566
608
|
- Use consistent span naming conventions
|
|
567
609
|
`,
|
|
568
|
-
"logging.md":
|
|
610
|
+
"logging.md": `---
|
|
611
|
+
description: Logging principles, log levels, log format, logger injection
|
|
612
|
+
---
|
|
613
|
+
# Logging
|
|
569
614
|
|
|
570
615
|
<!-- Define your logging standards. -->
|
|
571
616
|
|
|
@@ -581,7 +626,10 @@ Prefer standard library / platform APIs over third-party packages when feasible.
|
|
|
581
626
|
## Injection Pattern
|
|
582
627
|
<!-- Logger injection approach (callbacks, DI, etc.) -->
|
|
583
628
|
`,
|
|
584
|
-
".artifact-standards.md":
|
|
629
|
+
".artifact-standards.md": `---
|
|
630
|
+
description: Format and structure rules for all feature artifacts
|
|
631
|
+
---
|
|
632
|
+
# Artifact Standards
|
|
585
633
|
|
|
586
634
|
Standards for all artifacts generated by agents under \\\`.vibe/features/{featureId}/\\\`.
|
|
587
635
|
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["// ─── Command Types ───────────────────────────────────────────────────────────\n\n/** Parsed vibe command */\nexport type VibeCommand =\n\t| { type: \"auto\"; requirement: string }\n\t| { type: \"new\"; requirement: string }\n\t| { type: \"enhance\"; featureId?: string; requirement: string }\n\t| { type: \"fix\"; description: string; issueRef?: string }\n\t| { type: \"refactor\"; featureId?: string; purpose: string }\n\t| { type: \"status\"; featureId?: string }\n\t| { type: \"pause\"; featureId: string }\n\t| { type: \"resume\"; featureId?: string }\n\t| { type: \"steer\"; featureId: string; feedback: string }\n\t| { type: \"log\"; featureId: string }\n\t| { type: \"analyze\" }\n\t| { type: \"config\" }\n\t| { type: \"init\" }\n\t| { type: \"reset\" }\n\t| { type: \"recover\" }\n\t| { type: \"help\" };\n\n/** Available subcommands */\nexport const VIBE_SUBCOMMANDS = [\n\t\"new\",\n\t\"enhance\",\n\t\"fix\",\n\t\"refactor\",\n\t\"status\",\n\t\"pause\",\n\t\"resume\",\n\t\"steer\",\n\t\"log\",\n\t\"analyze\",\n\t\"config\",\n\t\"init\",\n\t\"reset\",\n\t\"recover\",\n] as const;\n\n// ─── Parsing ─────────────────────────────────────────────────────────────────\n\n/**\n * Parse /vibe command arguments.\n *\n * Format:\n * - /vibe new \"requirement\"\n * - /vibe enhance <featureId> \"requirement\"\n * - /vibe fix \"description\" --issue N\n * - /vibe refactor <featureId> \"purpose\"\n * - /vibe status [featureId]\n * - /vibe pause <featureId>\n * - /vibe resume <featureId>\n * - /vibe steer <featureId> \"feedback\"\n * - /vibe log <featureId>\n * - /vibe config\n * - /vibe init\n * - /vibe reset\n * - /vibe recover\n */\nexport function parseVibeCommand(args: string): VibeCommand {\n\tconst trimmed = args.trim();\n\n\tif (!trimmed) {\n\t\treturn { type: \"help\" };\n\t}\n\n\tconst parts = splitArgs(trimmed);\n\tconst subcommand = parts[0];\n\n\tswitch (subcommand) {\n\t\tcase \"new\": {\n\t\t\tconst requirement = parts.slice(1).join(\" \");\n\t\t\tif (!requirement) {\n\t\t\t\tthrow new Error(\"Usage: /vibe new <requirement>\");\n\t\t\t}\n\t\t\treturn { type: \"new\", requirement };\n\t\t}\n\n\t\tcase \"enhance\": {\n\t\t\tif (parts.length < 2) {\n\t\t\t\tthrow new Error(\"Usage: /vibe enhance [featureId] <requirement>\");\n\t\t\t}\n\t\t\tif (isFeatureId(parts[1])) {\n\t\t\t\tconst featureId = parts[1];\n\t\t\t\tconst requirement = parts.slice(2).join(\" \");\n\t\t\t\tif (!requirement) {\n\t\t\t\t\tthrow new Error(\"Usage: /vibe enhance [featureId] <requirement>\");\n\t\t\t\t}\n\t\t\t\treturn { type: \"enhance\", featureId, requirement };\n\t\t\t}\n\t\t\tconst requirement = parts.slice(1).join(\" \");\n\t\t\treturn { type: \"enhance\", requirement };\n\t\t}\n\n\t\tcase \"fix\": {\n\t\t\tconst issueIdx = parts.indexOf(\"--issue\");\n\t\t\tlet issueRef: string | undefined;\n\t\t\tlet descParts: string[];\n\n\t\t\tif (issueIdx !== -1) {\n\t\t\t\tissueRef = parts[issueIdx + 1];\n\t\t\t\tdescParts = [...parts.slice(1, issueIdx), ...parts.slice(issueIdx + 2)];\n\t\t\t} else {\n\t\t\t\tdescParts = parts.slice(1);\n\t\t\t}\n\n\t\t\tconst description = descParts.join(\" \");\n\t\t\tif (!description) {\n\t\t\t\tthrow new Error(\"Usage: /vibe fix <description> [--issue N]\");\n\t\t\t}\n\t\t\treturn { type: \"fix\", description, issueRef };\n\t\t}\n\n\t\tcase \"refactor\": {\n\t\t\tif (parts.length < 2) {\n\t\t\t\tthrow new Error(\"Usage: /vibe refactor [featureId] <purpose>\");\n\t\t\t}\n\t\t\tif (isFeatureId(parts[1])) {\n\t\t\t\tconst featureId = parts[1];\n\t\t\t\tconst purpose = parts.slice(2).join(\" \");\n\t\t\t\tif (!purpose) {\n\t\t\t\t\tthrow new Error(\"Usage: /vibe refactor [featureId] <purpose>\");\n\t\t\t\t}\n\t\t\t\treturn { type: \"refactor\", featureId, purpose };\n\t\t\t}\n\t\t\tconst purpose = parts.slice(1).join(\" \");\n\t\t\treturn { type: \"refactor\", purpose };\n\t\t}\n\n\t\tcase \"status\": {\n\t\t\tconst featureId = parts[1];\n\t\t\treturn { type: \"status\", featureId };\n\t\t}\n\n\t\tcase \"pause\": {\n\t\t\tif (!parts[1]) {\n\t\t\t\tthrow new Error(\"Usage: /vibe pause <featureId>\");\n\t\t\t}\n\t\t\treturn { type: \"pause\", featureId: parts[1] };\n\t\t}\n\n\t\tcase \"resume\": {\n\t\t\treturn { type: \"resume\", featureId: parts[1] };\n\t\t}\n\n\t\tcase \"steer\": {\n\t\t\tif (parts.length < 3) {\n\t\t\t\tthrow new Error(\"Usage: /vibe steer <featureId> <feedback>\");\n\t\t\t}\n\t\t\tconst featureId = parts[1];\n\t\t\tconst feedback = parts.slice(2).join(\" \");\n\t\t\treturn { type: \"steer\", featureId, feedback };\n\t\t}\n\n\t\tcase \"log\": {\n\t\t\tif (!parts[1]) {\n\t\t\t\tthrow new Error(\"Usage: /vibe log <featureId>\");\n\t\t\t}\n\t\t\treturn { type: \"log\", featureId: parts[1] };\n\t\t}\n\n\t\tcase \"analyze\":\n\t\t\treturn { type: \"analyze\" };\n\n\t\tcase \"config\":\n\t\t\treturn { type: \"config\" };\n\n\t\tcase \"init\":\n\t\t\treturn { type: \"init\" };\n\n\t\tcase \"reset\":\n\t\t\treturn { type: \"reset\" };\n\n\t\tcase \"recover\":\n\t\t\treturn { type: \"recover\" };\n\n\t\tdefault: {\n\t\t\t// Text that is not a subcommand is treated as auto mode\n\t\t\tconst requirement = parts.join(\" \");\n\t\t\treturn { type: \"auto\", requirement };\n\t\t}\n\t}\n}\n\n/** featureId prefix list. Used to identify featureId tokens. */\nconst FEATURE_ID_PREFIXES = [\"feat-\", \"fix-\", \"enhance-\", \"refactor-\"];\n\n/** Check if a token is a featureId. */\nfunction isFeatureId(token: string): boolean {\n\treturn FEATURE_ID_PREFIXES.some((prefix) => token.startsWith(prefix));\n}\n\n/** Split by whitespace, preserving spaces inside quotes. */\nfunction splitArgs(input: string): string[] {\n\tconst result: string[] = [];\n\tlet current = \"\";\n\tlet inQuote = false;\n\tlet quoteChar = \"\";\n\n\tfor (const ch of input) {\n\t\tif (inQuote) {\n\t\t\tif (ch === quoteChar) {\n\t\t\t\tinQuote = false;\n\t\t\t} else {\n\t\t\t\tcurrent += ch;\n\t\t\t}\n\t\t} else if (ch === '\"' || ch === \"'\") {\n\t\t\tinQuote = true;\n\t\t\tquoteChar = ch;\n\t\t} else if (ch === \" \") {\n\t\t\tif (current) {\n\t\t\t\tresult.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t} else {\n\t\t\tcurrent += ch;\n\t\t}\n\t}\n\n\tif (current) {\n\t\tresult.push(current);\n\t}\n\n\treturn result;\n}\n\n// ─── Standard Templates ──────────────────────────────────────────────────────\n\n/** 14 standard file templates generated by /vibe init */\nexport const STANDARD_TEMPLATES: Record<string, string> = {\n\t\"coding-style.md\": `# Coding Style\n\n<!-- Customize: adjust these defaults to match your project's conventions. -->\n\n## Formatting\n\n- Use consistent indentation (tabs or spaces — pick one and enforce it)\n- Keep line length reasonable (80-120 characters)\n- Use trailing commas in multi-line structures for cleaner diffs\n\n## Naming\n\n- Files: follow the project's convention (e.g., kebab-case \\`user-service.ts\\`, snake_case \\`user_service.py\\`)\n- Classes/interfaces: PascalCase (\\`UserService\\`, \\`AuthProvider\\`)\n- Functions/variables: follow the language convention (e.g., camelCase for JS/TS/Java, snake_case for Python/Rust)\n- Constants: UPPER_SNAKE_CASE (\\`MAX_RETRIES\\`, \\`DEFAULT_TIMEOUT\\`)\n- Booleans: prefix with \\`is\\`, \\`has\\`, \\`can\\`, \\`should\\` (\\`isActive\\`, \\`hasPermission\\`)\n- No abbreviations unless universally understood (\\`id\\`, \\`url\\` are OK; \\`usr\\`, \\`cfg\\` are not)\n\n## Imports\n\n- Use standard module imports following the project's conventions\n- Group imports: external packages first, then internal modules, separated by a blank line\n`,\n\t\"coding-conventions.md\": `# Coding Conventions\n\n<!-- Customize: adjust these defaults to match your project's conventions. -->\n\n## Error Handling\n\n- Handle errors explicitly — no silent failures, no empty catch blocks\n- Use typed errors when the language supports it\n- Validate inputs at module boundaries (public APIs, request handlers)\n- Fail fast: detect invalid state early and report clearly\n\n## Dependency Injection\n\n- Business logic depends on interfaces (ports), never on concrete implementations (adapters)\n- Wire concrete adapters in a single composition root (factory function or module)\n- Swapping an adapter (e.g., in-memory → database) should require changing only the composition root\n\n## Comments\n\n- Documentation comments for all public APIs (e.g., JSDoc, docstrings, GoDoc)\n- Explain \"why\", not \"what\" — the code shows what, comments explain intent\n- No commented-out code in committed files\n\n## Constants\n\n- No magic numbers or strings — use named constants\n- Group related constants in a dedicated module or object\n\n## Functions\n\n- Keep functions small and focused — one responsibility per function\n- Explicit return types or type hints for public functions where the language supports it\n- No side effects in functions named as queries (get*, is*, has*)\n`,\n\t\"tech-stack.md\": `# Tech Stack\n\n<!-- This file is populated during project initialization or discovery. -->\n<!-- Update it when the tech stack changes. -->\n\n## Languages\n<!-- e.g., TypeScript 5.x, Python 3.12, Go 1.22 -->\n\n## Frameworks\n<!-- e.g., React 19, Express 5, FastAPI -->\n\n## Build Tools\n<!-- e.g., Vite, esbuild, webpack -->\n\n## Runtime\n<!-- e.g., Node.js 20, Deno, Bun -->\n\n## Package Manager\n<!-- e.g., npm, pnpm, yarn -->\n`,\n\t\"architecture-principles.md\": `# Architecture Principles\n\n<!-- Customize: adjust these defaults to match your project's architecture. -->\n\n## Separation of Concerns\n\n- Each module has a single, well-defined responsibility\n- UI, business logic, and data access are separate layers\n- Cross-cutting concerns (logging, auth) are injected, not hard-wired\n\n## Integration Boundary Principle\n\nAll external dependencies must be abstracted behind interfaces (ports) with swappable adapter implementations.\n\n### What counts as an external dependency\n\n- Data persistence (databases, file systems, localStorage)\n- Authentication / authorization providers\n- Third-party service calls (payment, email, SMS, push notifications)\n- File / media / blob storage\n- Time / scheduling / cron services\n- Message queues / event buses\n\n### Required pattern\n\n1. **Interface (port)**: an interface or abstract type defining the contract, using the project's language idiom (e.g., TypeScript interface, Python Protocol/ABC, Go interface). Named descriptively: \\`TodoRepository\\`, \\`AuthProvider\\`, \\`NotificationService\\`.\n2. **Mock/in-memory adapter**: a default implementation that works without any external system. Named with prefix: \\`InMemory*\\`, \\`Stub*\\`, \\`Console*\\`, \\`Fake*\\`.\n3. **Composition root**: a single location (factory function, module, or DI container) where concrete adapters are wired. Swapping an adapter means changing only this location.\n\n### Why\n\n- Apps work immediately with mock adapters — no infrastructure setup needed\n- Tests run without external dependencies\n- Real adapters can be swapped in later without touching business logic\n\n## Testability\n\n- Every component must be independently testable\n- Dependencies are injected, not instantiated internally\n- No global mutable state\n\n## Dependency Direction\n\n- Higher-level modules must not depend on lower-level implementation details\n- Depend on abstractions (interfaces), not concretions\n`,\n\t\"design-guide.md\": `# Design Guide\n\n<!-- Customize: adjust these defaults to match your project's design approach. -->\n\n## API Design\n\n- APIs expose clear contracts — input types, output types, error types\n- Use consistent naming: \\`getX\\`, \\`createX\\`, \\`updateX\\`, \\`deleteX\\`\n- Return typed results, not raw primitives where context matters\n- Document error conditions and edge cases in documentation comments\n\n## Data Modeling\n\n- Define explicit types for all domain entities — no implicit shapes\n- Nullable fields must be explicitly typed (e.g., \\`field: string | null\\` in TS, \\`Optional[str]\\` in Python)\n- Validate data at boundaries (API handlers, file reads, user input)\n- Separate internal models from external representations (DTOs)\n\n## Component Design\n\n- Prefer composition over inheritance\n- Keep interfaces small and focused (Interface Segregation)\n- Design for extension — new behavior via new implementations, not modification of existing code\n`,\n\t\"api-design.md\": `# API Design\n\n<!-- Customize: adjust these defaults to match your project's API conventions. -->\n\n## REST API\n\n- Resource-oriented URLs: \\`/users\\`, \\`/users/:id\\`, \\`/users/:id/posts\\`\n- Use standard HTTP methods: GET (read), POST (create), PUT/PATCH (update), DELETE (remove)\n- Consistent status codes: 200 (OK), 201 (Created), 400 (Bad Request), 404 (Not Found), 500 (Internal Error)\n- Return JSON with consistent envelope: \\`{ data, error, meta }\\`\n- Version APIs when breaking changes are unavoidable: \\`/api/v1/...\\`\n\n## Language-Specific API Conventions\n\n- Small, focused functions — one purpose per function\n- Explicit return types or type hints for all public functions\n- Avoid untyped or loosely-typed constructs (e.g., \\`any\\` in TS, \\`Any\\` in Python) — use narrow types\n- Use tagged unions, discriminated unions, or enums for complex state where the language supports it\n- Prefer async/await patterns for asynchronous operations\n`,\n\t\"testing-standards.md\": `# Testing Standards\n\n<!-- Customize: adjust these defaults to match your project's testing approach. -->\n\n## Test Layers\n\n| Layer | Role | Scope |\n|-------|------|-------|\n| **Unit** | Verify isolated module logic | Single function/class, all dependencies mocked |\n| **Integration** | Verify module wiring and interaction | Multiple modules, external boundaries mocked |\n| **E2E** | Verify end-to-end user workflow | Full application, real or simulated environment |\n\n## Change Type → Test Scope\n\n| What changed | Unit | Integration | E2E / Manual |\n|--------------|:----:|:-----------:|:------------:|\n| Internal logic (algorithm, validation) | Required | — | — |\n| Public API / interface signature | Required | Required if callers exist | — |\n| Module wiring (callbacks, DI, factory) | — | Required | — |\n| User-facing workflow | Required for logic | Required for wiring | Required |\n\n## Unit Test Rules\n\n- Test one module in isolation — mock all dependencies\n- Cover edge cases: empty input, invalid state, boundary values\n- Tests must be deterministic — no dependency on external state, time, or network\n- No meaningless tests that always pass\n\n## Integration Test Rules\n\n- Mock external boundaries (database, network, file system) but use real internal modules\n- Verify callback wiring: A creates B with callback → trigger callback → verify side effect\n- Verify argument passing and state flow across modules\n\n## E2E / Manual Verification\n\n- Required for TUI rendering, prompt effectiveness, cross-terminal behavior\n- Document what was checked and the result in test reports\n\n## Mock Adapters\n\n- All tests must use mock/in-memory adapters — never depend on real external systems\n- Mock adapters must faithfully implement the interface contract\n`,\n\t\"documentation.md\": `# Documentation\n\n<!-- Customize: adjust these defaults to match your project's documentation approach. -->\n\n## Code Documentation\n\n- Documentation comments for all public APIs (e.g., JSDoc, Python docstrings, GoDoc, Javadoc)\n- Include parameter descriptions, return types, and thrown errors/exceptions\n- Explain complex algorithms or non-obvious design decisions inline\n\n## README\n\nEvery project must have a README.md containing:\n- **Purpose**: what the project does and why\n- **Setup**: how to install and configure\n- **Usage**: how to run and use\n- **Architecture**: high-level overview of structure and key decisions\n- **Contributing**: how to develop and test\n\n## Commit Messages\n\n- Use conventional commits: \\`feat:\\`, \\`fix:\\`, \\`refactor:\\`, \\`docs:\\`, \\`test:\\`\n- First line: imperative mood, under 72 characters\n- Body: explain \"why\" when the change is non-obvious\n`,\n\t\"git-workflow.md\": `# Git Workflow\n\n<!-- Customize: adjust these defaults to match your project's Git workflow. -->\n\n## Branching\n\n- \\`main\\` (or \\`master\\`): stable, always deployable\n- Feature branches: \\`feat/description\\`, \\`fix/description\\`, \\`refactor/description\\`\n- Branch from the latest main, keep branches short-lived\n\n## Commits\n\n- Use conventional commits: \\`feat:\\`, \\`fix:\\`, \\`refactor:\\`, \\`docs:\\`, \\`test:\\`, \\`chore:\\`\n- Atomic commits: each commit is a single logical change\n- First line: imperative mood, under 72 characters\n\n## Merging\n\n- Merge feature branches with \\`--no-ff\\` to preserve branch history\n- Resolve conflicts in the feature branch before merging\n- Delete feature branches after merge (or keep for traceability — choose one convention)\n- Never force-push to shared branches\n`,\n\t\"security-policy.md\": `# Security Policy\n\n<!-- Customize: adjust these defaults to match your project's security requirements. -->\n\n## Secrets Management\n\n- No secrets, API keys, or credentials in source code or version control\n- Use environment variables or secret management services\n- Add sensitive file patterns to \\`.gitignore\\`\n\n## Input Validation\n\n- Validate all external input at system boundaries (API handlers, file reads, user input)\n- Sanitize data before rendering to prevent XSS\n- Use parameterized queries to prevent SQL injection\n\n## Authentication & Authorization\n\n- Use established libraries — do not implement custom crypto\n- Apply least privilege: grant minimum permissions required\n- Expire sessions and tokens with reasonable timeouts\n\n## Dependencies\n\n- Regularly scan dependencies for known vulnerabilities\n- Update vulnerable dependencies promptly\n- Evaluate new dependencies for security track record before adding\n`,\n\t\"dependency-policy.md\": `# Dependency Policy\n\n<!-- Customize: adjust these defaults to match your project's dependency approach. -->\n\n## Adding Dependencies\n\nBefore adding a dependency, evaluate:\n- **Necessity**: can this be implemented in a few lines without the dependency?\n- **Maintenance**: is the package actively maintained? When was the last release?\n- **Size**: what is the install size and dependency tree depth?\n- **License**: is the license compatible with your project?\n- **Security**: does it have known vulnerabilities?\n\nPrefer standard library / platform APIs over third-party packages when feasible.\n\n## Version Management\n\n- Pin exact versions or use lock files (\\`package-lock.json\\`, \\`pnpm-lock.yaml\\`)\n- Update dependencies regularly — do not let them go stale\n- Test after updating — run the full test suite before committing dependency updates\n`,\n\t\"performance-guidelines.md\": `# Performance Guidelines\n\n<!-- Customize: adjust these defaults to match your project's performance needs. -->\n\n## Principles\n\n- Do not optimize prematurely — write clear code first, optimize when measured\n- Profile before optimizing — identify actual bottlenecks, not guessed ones\n- Use async I/O where appropriate — avoid blocking the event loop or main thread with synchronous operations\n\n## Data Structures\n\n- Choose appropriate data structures for the access pattern (Map for lookups, Array for iteration)\n- Avoid unnecessary copying of large data structures\n\n## Resource Management\n\n- Close resources (file handles, connections, streams) when done\n- Use connection pooling for databases and HTTP clients\n- Set reasonable timeouts for all external calls\n`,\n\t\"accessibility.md\": `# Accessibility\n\n<!-- Customize: adjust these defaults if your project has a UI. -->\n<!-- If your project has no user-facing UI, this file can be left as-is. -->\n\n## Standards\n\n- Follow WCAG 2.1 Level AA guidelines for web applications\n- Use semantic HTML elements (\\`<button>\\`, \\`<nav>\\`, \\`<main>\\`, not \\`<div>\\` for everything)\n- Provide text alternatives for non-text content (images, icons)\n\n## Keyboard Navigation\n\n- All interactive elements must be keyboard-accessible\n- Focus order must follow a logical reading sequence\n- Visible focus indicators on all interactive elements\n\n## Screen Readers\n\n- Use ARIA attributes when semantic HTML is insufficient\n- Test with at least one screen reader\n\n## Visual Design\n\n- Minimum 4.5:1 contrast ratio for normal text\n- Do not convey information by color alone\n- Support user font size preferences\n`,\n\t\"observability.md\": `# Observability\n\n<!-- Customize: adjust these defaults to match your project's observability needs. -->\n\n## Logging\n\n- Use structured logging (JSON or key-value pairs) — not free-form text\n- Include context: timestamp, level, module, request ID where applicable\n- Log at appropriate levels: ERROR for failures, WARN for recoverable issues, INFO for state changes, DEBUG for troubleshooting\n\n## Metrics\n\n<!-- Define key metrics for your application. Examples: -->\n- Request latency (p50, p95, p99)\n- Error rate\n- Resource utilization (memory, CPU, connections)\n\n## Tracing\n\n- Propagate trace/correlation IDs across service boundaries\n- Instrument key operations: incoming requests, outgoing calls, database queries\n- Use consistent span naming conventions\n`,\n\t\"logging.md\": `# Logging\n\n<!-- Define your logging standards. -->\n\n## Principles\n<!-- Basic principles such as no direct console.* calls -->\n\n## Log Levels\n<!-- Criteria for debug, info, warn, error usage -->\n\n## Log Format\n<!-- Log format rules -->\n\n## Injection Pattern\n<!-- Logger injection approach (callbacks, DI, etc.) -->\n`,\n\t\".artifact-standards.md\": `# Artifact Standards\n\nStandards for all artifacts generated by agents under \\\\\\`.vibe/features/{featureId}/\\\\\\`.\n\n## Artifact List\n\n| File | Creator | Workflow | Required |\n|---|---|---|---|\n| \\\\\\`spec.md\\\\\\` | Planner | all | required |\n| \\\\\\`design.md\\\\\\` | Architect | all | required |\n| \\\\\\`impact-report.md\\\\\\` | Analyzer | enhancement, refactor | conditional |\n| \\\\\\`diagnosis.md\\\\\\` | Diagnostician | bugfix | conditional |\n| \\\\\\`review.md\\\\\\` | Reviewer | all | required |\n| \\\\\\`test-report.md\\\\\\` | Tester | all | required |\n| \\\\\\`regression-report.md\\\\\\` | Tester | enhancement, bugfix, refactor | conditional |\n| \\\\\\`retry-log.md\\\\\\` | Pipeline Engine | on retry | conditional |\n| \\\\\\`status.json\\\\\\` | Pipeline Engine / VibeStore | all | required |\n\n---\n\n## spec.md (Planner)\n\nDefines the purpose, scope, and requirements of a feature.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: {Title}\n\n## Purpose\n\nDescribe the problem this feature solves and why it exists in 1-3 sentences.\n\n## Dependencies\n\n- \\\\\\\\\\\\\\`feat-xxx\\\\\\\\\\\\\\`: reason for dependency\n- (if none, write \"None\")\n\n## Requirements\n\n### {Requirement Group 1}\n\n- Describe as specific, verifiable items\n- Each item must be independently testable\n\n### {Requirement Group 2}\n\n- ...\n\n## Implementation Location\n\n- \\\\\\\\\\\\\\`src/xxx\\\\\\\\\\\\\\`: role description\n\n## Acceptance Criteria\n\n- List conditions that can be verified by tests\n- No vague expressions (e.g., \"should work well\")\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Describe **what** needs to be done, not **how** to implement it\n- Acceptance criteria must be directly convertible to test cases by the Tester\n- Dependencies must match the \\\\\\`dependencyGraph\\\\\\` in \\\\\\`plan.json\\\\\\`\n- File paths are relative to the package root\n\n---\n\n## design.md (Architect)\n\nConverts spec requirements into concrete technical design.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Design Document\n\n## Overview\n\nSummarize the core design direction in 1-3 sentences.\n\n## Dependencies\n\n- \\\\\\\\\\\\\\`./types\\\\\\\\\\\\\\`: types used\n- \\\\\\\\\\\\\\`./store\\\\\\\\\\\\\\`: modules used\n- (include external packages)\n\n## API Design\n\n### {Component/Class/Module}\n\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\n// Public interface definition (signatures + documentation comments)\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\n\n### {Additional Type Definitions}\n\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\n// Types to add\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\n\n## File Structure\n\n| File | Content |\n|---|---|\n| \\\\\\\\\\\\\\`src/xxx\\\\\\\\\\\\\\` | role description |\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | test description |\n\n## Design Decisions\n\n1. **Decision title**: chosen direction and rationale. If alternatives existed, explain why they were rejected.\n\n## Test Strategy\n\n- What level of testing is needed (unit/integration)\n- Mocking strategy\n- Edge case list\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- API signatures must be specified as code in the project's language (natural language descriptions alone are insufficient)\n- File paths are relative to the package root\n- All requirements from spec.md must be reflected in the design\n- Clearly describe integration points with existing code\n\n---\n\n## impact-report.md (Analyzer)\n\nAnalyzes the impact of changes on the existing codebase. Generated for enhancement and refactor workflows.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Impact Report\n\n## Change Summary\n\nDescribe the purpose and scope of the change in 1-3 sentences.\n\n## Affected Files\n\n| File | Change Type | Impact | Description |\n|---|---|---|---|\n| \\\\\\\\\\\\\\`src/xxx\\\\\\\\\\\\\\` | modify | HIGH | public API signature change |\n| \\\\\\\\\\\\\\`src/yyy\\\\\\\\\\\\\\` | modify | LOW | import path change only |\n\nChange types: \\\\\\\\\\\\\\`create\\\\\\\\\\\\\\`, \\\\\\\\\\\\\\`modify\\\\\\\\\\\\\\`, \\\\\\\\\\\\\\`delete\\\\\\\\\\\\\\`\nImpact levels: \\\\\\\\\\\\\\`HIGH\\\\\\\\\\\\\\`, \\\\\\\\\\\\\\`MEDIUM\\\\\\\\\\\\\\`, \\\\\\\\\\\\\\`LOW\\\\\\\\\\\\\\`\n\n## Affected Tests\n\n| Test File | Impact Reason |\n|---|---|\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | directly tests the changed API |\n\n## Compatibility\n\n### Backward Compatibility\n\n- Whether existing API is preserved\n- List of breaking changes (if any)\n\n### Impact on Dependent Features\n\n- How this change affects other features\n\n## Risk Assessment\n\n| Risk | Level | Mitigation |\n|---|---|---|\n| {risk description} | HIGH/MEDIUM/LOW | {mitigation strategy} |\n\n## Recommendations\n\n- Regression test targets\n- Areas requiring additional review\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Read-only analysis. May suggest code modifications but must not modify code directly\n- List all affected files without omissions\n- Risk level must be one of \\\\\\`HIGH\\\\\\`, \\\\\\`MEDIUM\\\\\\`, \\\\\\`LOW\\\\\\`\n\n---\n\n## diagnosis.md (Diagnostician)\n\nAnalyzes bug causes and proposes fix strategies. Generated for bugfix workflows.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Diagnosis\n\n## Bug Summary\n\nDescribe reported symptoms in 1-3 sentences.\n\n## Reproduction Steps\n\n1. Step-by-step reproduction method\n2. ...\n\n## Reproduction Results\n\n- Expected behavior: ...\n- Actual behavior: ...\n- Error message/log (if available):\n\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\nerror output\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\n\n## Root Cause Analysis\n\n### Root Cause\n\nDescribe the cause concretely. Include code paths and line numbers.\n\n### Impact Scope\n\n- Other features/code affected by this bug\n\n## Fix Strategy\n\n### Recommended Fix\n\n- Files to modify and change details\n- Scope of changes (minimal invasiveness principle)\n\n### Alternatives (if any)\n\n- Alternatives and reasons for rejection\n\n## Risk Assessment\n\n| Risk | Level | Description |\n|---|---|---|\n| Side effects of fix | HIGH/MEDIUM/LOW | description |\n| Recurrence likelihood | HIGH/MEDIUM/LOW | description |\n\n## Recommended Regression Tests\n\n- Proposed test cases to verify this bug\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Read-only. Cannot modify code, but may run reproduction tests\n- Diagnosis must be based on code analysis, not speculation\n- Fix strategy must be specific enough for the Developer to implement directly\n\n---\n\n## review.md (Reviewer)\n\nVerifies the quality of implementation and tests, and issues approval/change request verdicts.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Review\n\n## Review Scope\n\n| File | Change |\n|---|---|\n| \\\\\\\\\\\\\\`src/xxx\\\\\\\\\\\\\\` | change summary |\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | change summary |\n\n## Checklist\n\n- [x] spec.md requirements met\n - [x] {specific item}\n- [x] design.md compliance\n - [x] {specific item}\n- [x] Type safety: no loosely-typed constructs\n- [x] Import conventions followed\n- [x] Project lint/check passes\n- [x] Tests pass ({N} tests)\n\n## Code Review\n\n### {Perspective 1} (e.g., architecture, error handling, performance)\n\nEvaluation content. Reference specific files/lines.\n\n### Improvements (non-blocking)\n\n- Items not requiring immediate fix but worth improving later\n\n### Issues (blocking) — only if present\n\n- Items that must be fixed. Specify file paths and concrete details.\n\n## Standards Compliance\n\n| Standard | Status | Notes |\n|---|---|---|\n| coding-style | PASS | |\n| coding-conventions | PASS | |\n| {standard name} | WARN/FAIL | {file path} - {violation details} |\n\nOverall: PASS / WARN / FAIL\n\n## Verdict: APPROVED / CHANGES_REQUESTED\n\n(If CHANGES_REQUESTED, refer to blocking issues list)\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Read-only. Cannot modify code\n- Standards Compliance is included only when loaded standards are available\n- If Overall is \\\\\\`FAIL\\\\\\`, verdict must be \\\\\\`CHANGES_REQUESTED\\\\\\`\n- If no blocking issues exist, verdict is \\\\\\`APPROVED\\\\\\`\n- Checklist items correspond 1:1 to acceptance criteria in spec.md\n\n---\n\n## test-report.md (Tester)\n\nRecords test execution results.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Test Report\n\n## Execution Environment\n\n- **Framework**: {test framework and version, e.g., Vitest, pytest, go test}\n- **Runner**: {command used to run tests}\n- **Working directory**: {project root or relevant subdirectory}\n\n## Result Summary\n\n| Item | Value |\n|---|---|\n| Test files | {N} passed ({N}) |\n| Test cases | {N} passed ({N}) |\n| Failures | {N} |\n| Duration | {N}ms |\n\n## Test Details\n\n### {describe block name} ({passed}/{total} passed)\n\n| Test | Result |\n|---|---|\n| {test name} | PASS |\n| {test name} | FAIL — {failure reason summary} |\n\n## Coverage Analysis\n\n- [x] {covered functionality}\n- [ ] {uncovered functionality} — {reason}\n\nEdge case coverage:\n- [x] {edge case}\n\n## Acceptance Criteria Fulfillment\n\n| Criterion | Status |\n|---|---|\n| {acceptance criterion from spec.md} | PASS/FAIL |\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Record actual execution results. No estimates\n- Failed tests must include failure reasons\n- Acceptance criteria table corresponds 1:1 to spec.md acceptance criteria\n- Explicitly note missing coverage areas\n\n---\n\n## regression-report.md (Tester)\n\nVerifies no regressions in existing functionality. Generated for enhancement, bugfix, and refactor workflows.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Regression Report\n\n## Target\n\n- **Changed feature**: {featureId}\n- **Reference**: impact-report.md / diagnosis.md\n\n## Execution Environment\n\n- **Framework**: {test framework and version}\n- **Working directory**: {project root or relevant subdirectory}\n\n## Regression Test Scope\n\n| Test File | Target Functionality | Selection Reason |\n|---|---|---|\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | {functionality} | identified as affected file in impact-report.md |\n\n## Results\n\n| Test File | Result | Failed Items |\n|---|---|---|\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | PASS | — |\n| \\\\\\\\\\\\\\`test/yyy\\\\\\\\\\\\\\` | FAIL | {test name}: {failure reason} |\n\n## New Regression Tests\n\nTests added due to the change:\n\n| Test File | Test Name | Verification Target |\n|---|---|---|\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | {test name} | {what it verifies} |\n\n## Verdict: PASS / FAIL\n\n(If FAIL, include failed tests and impact analysis)\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Determine test scope by referencing impact-report.md or diagnosis.md\n- Run both existing tests and new regression tests\n- Record actual execution results. No estimates\n\n---\n\n## retry-log.md (Pipeline Engine)\n\nRecords retry history. Automatically generated when retries occur due to test failures, review change requests, etc.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Retry Log\n\n## Retry History\n\n### Attempt {N} — {timestamp}\n\n- **Step**: {testing/reviewing/regression}\n- **Result**: FAIL\n- **Reason**: {failure cause summary}\n- **Action**: {changes made for the next attempt}\n\n### Attempt {N+1} — {timestamp}\n\n- **Step**: {step}\n- **Result**: PASS\n- **Reason**: —\n\n## Summary\n\n| Item | Value |\n|---|---|\n| Total attempts | {N} |\n| Final result | PASS/FAIL |\n| Max retry limit reached | Yes/No |\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Record each attempt in chronological order\n- Reference test-report.md or review.md for failure reasons\n- Indicate when max retry limit (from \\\\\\`config.json\\\\\\` retry settings) is reached\n\n---\n\n## status.json (Pipeline Engine / VibeStore)\n\nTracks the current state of a feature.\n\n### Format\n\n\\\\\\`\\\\\\`\\\\\\`json\n{\n \"status\": \"implementing\",\n \"updatedAt\": \"2026-03-05T16:35:00+09:00\",\n \"phase\": \"develop\",\n \"error\": null\n}\n\\\\\\`\\\\\\`\\\\\\`\n\n### Fields\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| \\\\\\`status\\\\\\` | \\\\\\`FeatureStatusValue\\\\\\` | required | \\\\\\`planned\\\\\\`, \\\\\\`designing\\\\\\`, \\\\\\`implementing\\\\\\`, \\\\\\`testing\\\\\\`, \\\\\\`reviewing\\\\\\`, \\\\\\`done\\\\\\`, \\\\\\`blocked\\\\\\`, \\\\\\`failed\\\\\\` |\n| \\\\\\`updatedAt\\\\\\` | \\\\\\`string\\\\\\` (ISO 8601) | required | timestamp of last status change |\n| \\\\\\`phase\\\\\\` | \\\\\\`string\\\\\\` | optional | current pipeline step (plan, design, develop, test, review, etc.) |\n| \\\\\\`error\\\\\\` | \\\\\\`string \\\\\\\\| null\\\\\\` | optional | failure/block reason |\n\n### Rules\n\n- Do not edit directly. Change only through \\\\\\`VibeStore.updateFeatureStatus()\\\\\\`\n- Only state transitions defined in \\\\\\`VALID_TRANSITIONS\\\\\\` are allowed\n- \\\\\\`updatedAt\\\\\\` must be in ISO 8601 format with UTC offset\n\n---\n\n## Common Rules\n\n1. **File paths**: use relative paths from the project root (e.g., \\\\\\`src/store\\\\\\`, \\\\\\`test/store\\\\\\`)\n2. **Writing style**: technical documentation style. Concise and direct. No emojis.\n3. **Code blocks**: language tag required (e.g., \\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`python, \\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`typescript, \\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`json, \\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`markdown)\n4. **Table alignment**: Markdown table separators use \\\\\\`|---|\\\\\\` format\n5. **Cross-references**: reference other artifacts by filename (e.g., \"see acceptance criteria in spec.md\")\n6. **Version control**: artifacts are tracked by git within the feature directory. Overwrite history is tracked via commit history.\n7. **Encoding**: UTF-8, LF line endings\n8. **Language**: all artifacts must be written in English. This includes headings, prose, table content, and technical descriptions.\n`,\n};\n"]}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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","sourcesContent":["// ─── Command Types ───────────────────────────────────────────────────────────\n\n/** Parsed vibe command */\nexport type VibeCommand =\n\t| { type: \"auto\"; requirement: string }\n\t| { type: \"new\"; requirement: string }\n\t| { type: \"enhance\"; featureId?: string; requirement: string }\n\t| { type: \"fix\"; description: string; issueRef?: string }\n\t| { type: \"refactor\"; featureId?: string; purpose: string }\n\t| { type: \"status\"; featureId?: string }\n\t| { type: \"pause\"; featureId: string }\n\t| { type: \"resume\"; featureId?: string }\n\t| { type: \"steer\"; featureId: string; feedback: string }\n\t| { type: \"log\"; featureId: string }\n\t| { type: \"analyze\" }\n\t| { type: \"config\" }\n\t| { type: \"init\" }\n\t| { type: \"reset\" }\n\t| { type: \"recover\" }\n\t| { type: \"help\" };\n\n/** Available subcommands */\nexport const VIBE_SUBCOMMANDS = [\n\t\"new\",\n\t\"enhance\",\n\t\"fix\",\n\t\"refactor\",\n\t\"status\",\n\t\"pause\",\n\t\"resume\",\n\t\"steer\",\n\t\"log\",\n\t\"analyze\",\n\t\"config\",\n\t\"init\",\n\t\"reset\",\n\t\"recover\",\n] as const;\n\n// ─── Parsing ─────────────────────────────────────────────────────────────────\n\n/**\n * Parse /vibe command arguments.\n *\n * Format:\n * - /vibe new \"requirement\"\n * - /vibe enhance <featureId> \"requirement\"\n * - /vibe fix \"description\" --issue N\n * - /vibe refactor <featureId> \"purpose\"\n * - /vibe status [featureId]\n * - /vibe pause <featureId>\n * - /vibe resume <featureId>\n * - /vibe steer <featureId> \"feedback\"\n * - /vibe log <featureId>\n * - /vibe config\n * - /vibe init\n * - /vibe reset\n * - /vibe recover\n */\nexport function parseVibeCommand(args: string): VibeCommand {\n\tconst trimmed = args.trim();\n\n\tif (!trimmed) {\n\t\treturn { type: \"help\" };\n\t}\n\n\tconst parts = splitArgs(trimmed);\n\tconst subcommand = parts[0];\n\n\tswitch (subcommand) {\n\t\tcase \"new\": {\n\t\t\tconst requirement = parts.slice(1).join(\" \");\n\t\t\tif (!requirement) {\n\t\t\t\tthrow new Error(\"Usage: /vibe new <requirement>\");\n\t\t\t}\n\t\t\treturn { type: \"new\", requirement };\n\t\t}\n\n\t\tcase \"enhance\": {\n\t\t\tif (parts.length < 2) {\n\t\t\t\tthrow new Error(\"Usage: /vibe enhance [featureId] <requirement>\");\n\t\t\t}\n\t\t\tif (isFeatureId(parts[1])) {\n\t\t\t\tconst featureId = parts[1];\n\t\t\t\tconst requirement = parts.slice(2).join(\" \");\n\t\t\t\tif (!requirement) {\n\t\t\t\t\tthrow new Error(\"Usage: /vibe enhance [featureId] <requirement>\");\n\t\t\t\t}\n\t\t\t\treturn { type: \"enhance\", featureId, requirement };\n\t\t\t}\n\t\t\tconst requirement = parts.slice(1).join(\" \");\n\t\t\treturn { type: \"enhance\", requirement };\n\t\t}\n\n\t\tcase \"fix\": {\n\t\t\tconst issueIdx = parts.indexOf(\"--issue\");\n\t\t\tlet issueRef: string | undefined;\n\t\t\tlet descParts: string[];\n\n\t\t\tif (issueIdx !== -1) {\n\t\t\t\tissueRef = parts[issueIdx + 1];\n\t\t\t\tdescParts = [...parts.slice(1, issueIdx), ...parts.slice(issueIdx + 2)];\n\t\t\t} else {\n\t\t\t\tdescParts = parts.slice(1);\n\t\t\t}\n\n\t\t\tconst description = descParts.join(\" \");\n\t\t\tif (!description) {\n\t\t\t\tthrow new Error(\"Usage: /vibe fix <description> [--issue N]\");\n\t\t\t}\n\t\t\treturn { type: \"fix\", description, issueRef };\n\t\t}\n\n\t\tcase \"refactor\": {\n\t\t\tif (parts.length < 2) {\n\t\t\t\tthrow new Error(\"Usage: /vibe refactor [featureId] <purpose>\");\n\t\t\t}\n\t\t\tif (isFeatureId(parts[1])) {\n\t\t\t\tconst featureId = parts[1];\n\t\t\t\tconst purpose = parts.slice(2).join(\" \");\n\t\t\t\tif (!purpose) {\n\t\t\t\t\tthrow new Error(\"Usage: /vibe refactor [featureId] <purpose>\");\n\t\t\t\t}\n\t\t\t\treturn { type: \"refactor\", featureId, purpose };\n\t\t\t}\n\t\t\tconst purpose = parts.slice(1).join(\" \");\n\t\t\treturn { type: \"refactor\", purpose };\n\t\t}\n\n\t\tcase \"status\": {\n\t\t\tconst featureId = parts[1];\n\t\t\treturn { type: \"status\", featureId };\n\t\t}\n\n\t\tcase \"pause\": {\n\t\t\tif (!parts[1]) {\n\t\t\t\tthrow new Error(\"Usage: /vibe pause <featureId>\");\n\t\t\t}\n\t\t\treturn { type: \"pause\", featureId: parts[1] };\n\t\t}\n\n\t\tcase \"resume\": {\n\t\t\treturn { type: \"resume\", featureId: parts[1] };\n\t\t}\n\n\t\tcase \"steer\": {\n\t\t\tif (parts.length < 3) {\n\t\t\t\tthrow new Error(\"Usage: /vibe steer <featureId> <feedback>\");\n\t\t\t}\n\t\t\tconst featureId = parts[1];\n\t\t\tconst feedback = parts.slice(2).join(\" \");\n\t\t\treturn { type: \"steer\", featureId, feedback };\n\t\t}\n\n\t\tcase \"log\": {\n\t\t\tif (!parts[1]) {\n\t\t\t\tthrow new Error(\"Usage: /vibe log <featureId>\");\n\t\t\t}\n\t\t\treturn { type: \"log\", featureId: parts[1] };\n\t\t}\n\n\t\tcase \"analyze\":\n\t\t\treturn { type: \"analyze\" };\n\n\t\tcase \"config\":\n\t\t\treturn { type: \"config\" };\n\n\t\tcase \"init\":\n\t\t\treturn { type: \"init\" };\n\n\t\tcase \"reset\":\n\t\t\treturn { type: \"reset\" };\n\n\t\tcase \"recover\":\n\t\t\treturn { type: \"recover\" };\n\n\t\tdefault: {\n\t\t\t// Text that is not a subcommand is treated as auto mode\n\t\t\tconst requirement = parts.join(\" \");\n\t\t\treturn { type: \"auto\", requirement };\n\t\t}\n\t}\n}\n\n/** featureId prefix list. Used to identify featureId tokens. */\nconst FEATURE_ID_PREFIXES = [\"feat-\", \"fix-\", \"enhance-\", \"refactor-\"];\n\n/** Check if a token is a featureId. */\nfunction isFeatureId(token: string): boolean {\n\treturn FEATURE_ID_PREFIXES.some((prefix) => token.startsWith(prefix));\n}\n\n/** Split by whitespace, preserving spaces inside quotes. */\nfunction splitArgs(input: string): string[] {\n\tconst result: string[] = [];\n\tlet current = \"\";\n\tlet inQuote = false;\n\tlet quoteChar = \"\";\n\n\tfor (const ch of input) {\n\t\tif (inQuote) {\n\t\t\tif (ch === quoteChar) {\n\t\t\t\tinQuote = false;\n\t\t\t} else {\n\t\t\t\tcurrent += ch;\n\t\t\t}\n\t\t} else if (ch === '\"' || ch === \"'\") {\n\t\t\tinQuote = true;\n\t\t\tquoteChar = ch;\n\t\t} else if (ch === \" \") {\n\t\t\tif (current) {\n\t\t\t\tresult.push(current);\n\t\t\t\tcurrent = \"\";\n\t\t\t}\n\t\t} else {\n\t\t\tcurrent += ch;\n\t\t}\n\t}\n\n\tif (current) {\n\t\tresult.push(current);\n\t}\n\n\treturn result;\n}\n\n// ─── Standard Templates ──────────────────────────────────────────────────────\n\n/** 14 standard file templates generated by /vibe init */\nexport const STANDARD_TEMPLATES: Record<string, string> = {\n\t\"coding-style.md\": `---\ndescription: Naming conventions, formatting rules, import ordering\n---\n# Coding Style\n\n<!-- Customize: adjust these defaults to match your project's conventions. -->\n\n## Formatting\n\n- Use consistent indentation (tabs or spaces — pick one and enforce it)\n- Keep line length reasonable (80-120 characters)\n- Use trailing commas in multi-line structures for cleaner diffs\n\n## Naming\n\n- Files: follow the project's convention (e.g., kebab-case \\`user-service.ts\\`, snake_case \\`user_service.py\\`)\n- Classes/interfaces: PascalCase (\\`UserService\\`, \\`AuthProvider\\`)\n- Functions/variables: follow the language convention (e.g., camelCase for JS/TS/Java, snake_case for Python/Rust)\n- Constants: UPPER_SNAKE_CASE (\\`MAX_RETRIES\\`, \\`DEFAULT_TIMEOUT\\`)\n- Booleans: prefix with \\`is\\`, \\`has\\`, \\`can\\`, \\`should\\` (\\`isActive\\`, \\`hasPermission\\`)\n- No abbreviations unless universally understood (\\`id\\`, \\`url\\` are OK; \\`usr\\`, \\`cfg\\` are not)\n\n## Imports\n\n- Use standard module imports following the project's conventions\n- Group imports: external packages first, then internal modules, separated by a blank line\n`,\n\t\"coding-conventions.md\": `---\ndescription: Error handling, dependency injection, comments, constants, function design\n---\n# Coding Conventions\n\n<!-- Customize: adjust these defaults to match your project's conventions. -->\n\n## Error Handling\n\n- Handle errors explicitly — no silent failures, no empty catch blocks\n- Use typed errors when the language supports it\n- Validate inputs at module boundaries (public APIs, request handlers)\n- Fail fast: detect invalid state early and report clearly\n\n## Dependency Injection\n\n- Business logic depends on interfaces (ports), never on concrete implementations (adapters)\n- Wire concrete adapters in a single composition root (factory function or module)\n- Swapping an adapter (e.g., in-memory → database) should require changing only the composition root\n\n## Comments\n\n- Documentation comments for all public APIs (e.g., JSDoc, docstrings, GoDoc)\n- Explain \"why\", not \"what\" — the code shows what, comments explain intent\n- No commented-out code in committed files\n\n## Constants\n\n- No magic numbers or strings — use named constants\n- Group related constants in a dedicated module or object\n\n## Functions\n\n- Keep functions small and focused — one responsibility per function\n- Explicit return types or type hints for public functions where the language supports it\n- No side effects in functions named as queries (get*, is*, has*)\n`,\n\t\"tech-stack.md\": `---\ndescription: Languages, frameworks, build tools, runtime, package manager\n---\n# Tech Stack\n\n<!-- This file is populated during project initialization or discovery. -->\n<!-- Update it when the tech stack changes. -->\n\n## Languages\n<!-- e.g., TypeScript 5.x, Python 3.12, Go 1.22 -->\n\n## Frameworks\n<!-- e.g., React 19, Express 5, FastAPI -->\n\n## Build Tools\n<!-- e.g., Vite, esbuild, webpack -->\n\n## Runtime\n<!-- e.g., Node.js 20, Deno, Bun -->\n\n## Package Manager\n<!-- e.g., npm, pnpm, yarn -->\n`,\n\t\"architecture-principles.md\": `---\ndescription: Separation of concerns, integration boundaries, testability, dependency direction\n---\n# Architecture Principles\n\n<!-- Customize: adjust these defaults to match your project's architecture. -->\n\n## Separation of Concerns\n\n- Each module has a single, well-defined responsibility\n- UI, business logic, and data access are separate layers\n- Cross-cutting concerns (logging, auth) are injected, not hard-wired\n\n## Integration Boundary Principle\n\nAll external dependencies must be abstracted behind interfaces (ports) with swappable adapter implementations.\n\n### What counts as an external dependency\n\n- Data persistence (databases, file systems, localStorage)\n- Authentication / authorization providers\n- Third-party service calls (payment, email, SMS, push notifications)\n- File / media / blob storage\n- Time / scheduling / cron services\n- Message queues / event buses\n\n### Required pattern\n\n1. **Interface (port)**: an interface or abstract type defining the contract, using the project's language idiom (e.g., TypeScript interface, Python Protocol/ABC, Go interface). Named descriptively: \\`TodoRepository\\`, \\`AuthProvider\\`, \\`NotificationService\\`.\n2. **Mock/in-memory adapter**: a default implementation that works without any external system. Named with prefix: \\`InMemory*\\`, \\`Stub*\\`, \\`Console*\\`, \\`Fake*\\`.\n3. **Composition root**: a single location (factory function, module, or DI container) where concrete adapters are wired. Swapping an adapter means changing only this location.\n\n### Why\n\n- Apps work immediately with mock adapters — no infrastructure setup needed\n- Tests run without external dependencies\n- Real adapters can be swapped in later without touching business logic\n\n## Testability\n\n- Every component must be independently testable\n- Dependencies are injected, not instantiated internally\n- No global mutable state\n\n## Dependency Direction\n\n- Higher-level modules must not depend on lower-level implementation details\n- Depend on abstractions (interfaces), not concretions\n`,\n\t\"design-guide.md\": `---\ndescription: API design, data modeling, component design\n---\n# Design Guide\n\n<!-- Customize: adjust these defaults to match your project's design approach. -->\n\n## API Design\n\n- APIs expose clear contracts — input types, output types, error types\n- Use consistent naming: \\`getX\\`, \\`createX\\`, \\`updateX\\`, \\`deleteX\\`\n- Return typed results, not raw primitives where context matters\n- Document error conditions and edge cases in documentation comments\n\n## Data Modeling\n\n- Define explicit types for all domain entities — no implicit shapes\n- Nullable fields must be explicitly typed (e.g., \\`field: string | null\\` in TS, \\`Optional[str]\\` in Python)\n- Validate data at boundaries (API handlers, file reads, user input)\n- Separate internal models from external representations (DTOs)\n\n## Component Design\n\n- Prefer composition over inheritance\n- Keep interfaces small and focused (Interface Segregation)\n- Design for extension — new behavior via new implementations, not modification of existing code\n`,\n\t\"api-design.md\": `---\ndescription: REST API conventions, language-specific API patterns\n---\n# API Design\n\n<!-- Customize: adjust these defaults to match your project's API conventions. -->\n\n## REST API\n\n- Resource-oriented URLs: \\`/users\\`, \\`/users/:id\\`, \\`/users/:id/posts\\`\n- Use standard HTTP methods: GET (read), POST (create), PUT/PATCH (update), DELETE (remove)\n- Consistent status codes: 200 (OK), 201 (Created), 400 (Bad Request), 404 (Not Found), 500 (Internal Error)\n- Return JSON with consistent envelope: \\`{ data, error, meta }\\`\n- Version APIs when breaking changes are unavoidable: \\`/api/v1/...\\`\n\n## Language-Specific API Conventions\n\n- Small, focused functions — one purpose per function\n- Explicit return types or type hints for all public functions\n- Avoid untyped or loosely-typed constructs (e.g., \\`any\\` in TS, \\`Any\\` in Python) — use narrow types\n- Use tagged unions, discriminated unions, or enums for complex state where the language supports it\n- Prefer async/await patterns for asynchronous operations\n`,\n\t\"testing-standards.md\": `---\ndescription: Test layers, test scope by change type, unit/integration/E2E rules, mock adapters\n---\n# Testing Standards\n\n<!-- Customize: adjust these defaults to match your project's testing approach. -->\n\n## Test Layers\n\n| Layer | Role | Scope |\n|-------|------|-------|\n| **Unit** | Verify isolated module logic | Single function/class, all dependencies mocked |\n| **Integration** | Verify module wiring and interaction | Multiple modules, external boundaries mocked |\n| **E2E** | Verify end-to-end user workflow | Full application, real or simulated environment |\n\n## Change Type → Test Scope\n\n| What changed | Unit | Integration | E2E / Manual |\n|--------------|:----:|:-----------:|:------------:|\n| Internal logic (algorithm, validation) | Required | — | — |\n| Public API / interface signature | Required | Required if callers exist | — |\n| Module wiring (callbacks, DI, factory) | — | Required | — |\n| User-facing workflow | Required for logic | Required for wiring | Required |\n\n## Unit Test Rules\n\n- Test one module in isolation — mock all dependencies\n- Cover edge cases: empty input, invalid state, boundary values\n- Tests must be deterministic — no dependency on external state, time, or network\n- No meaningless tests that always pass\n\n## Integration Test Rules\n\n- Mock external boundaries (database, network, file system) but use real internal modules\n- Verify callback wiring: A creates B with callback → trigger callback → verify side effect\n- Verify argument passing and state flow across modules\n\n## E2E / Manual Verification\n\n- Required for TUI rendering, prompt effectiveness, cross-terminal behavior\n- Document what was checked and the result in test reports\n\n## Mock Adapters\n\n- All tests must use mock/in-memory adapters — never depend on real external systems\n- Mock adapters must faithfully implement the interface contract\n`,\n\t\"documentation.md\": `---\ndescription: Code documentation, README structure, commit messages\n---\n# Documentation\n\n<!-- Customize: adjust these defaults to match your project's documentation approach. -->\n\n## Code Documentation\n\n- Documentation comments for all public APIs (e.g., JSDoc, Python docstrings, GoDoc, Javadoc)\n- Include parameter descriptions, return types, and thrown errors/exceptions\n- Explain complex algorithms or non-obvious design decisions inline\n\n## README\n\nEvery project must have a README.md containing:\n- **Purpose**: what the project does and why\n- **Setup**: how to install and configure\n- **Usage**: how to run and use\n- **Architecture**: high-level overview of structure and key decisions\n- **Contributing**: how to develop and test\n\n## Commit Messages\n\n- Use conventional commits: \\`feat:\\`, \\`fix:\\`, \\`refactor:\\`, \\`docs:\\`, \\`test:\\`\n- First line: imperative mood, under 72 characters\n- Body: explain \"why\" when the change is non-obvious\n`,\n\t\"git-workflow.md\": `---\ndescription: Branching strategy, commit conventions, merging rules\n---\n# Git Workflow\n\n<!-- Customize: adjust these defaults to match your project's Git workflow. -->\n\n## Branching\n\n- \\`main\\` (or \\`master\\`): stable, always deployable\n- Feature branches: \\`feat/description\\`, \\`fix/description\\`, \\`refactor/description\\`\n- Branch from the latest main, keep branches short-lived\n\n## Commits\n\n- Use conventional commits: \\`feat:\\`, \\`fix:\\`, \\`refactor:\\`, \\`docs:\\`, \\`test:\\`, \\`chore:\\`\n- Atomic commits: each commit is a single logical change\n- First line: imperative mood, under 72 characters\n\n## Merging\n\n- Merge feature branches with \\`--no-ff\\` to preserve branch history\n- Resolve conflicts in the feature branch before merging\n- Delete feature branches after merge (or keep for traceability — choose one convention)\n- Never force-push to shared branches\n`,\n\t\"security-policy.md\": `---\ndescription: Secrets management, input validation, authentication, dependency security\n---\n# Security Policy\n\n<!-- Customize: adjust these defaults to match your project's security requirements. -->\n\n## Secrets Management\n\n- No secrets, API keys, or credentials in source code or version control\n- Use environment variables or secret management services\n- Add sensitive file patterns to \\`.gitignore\\`\n\n## Input Validation\n\n- Validate all external input at system boundaries (API handlers, file reads, user input)\n- Sanitize data before rendering to prevent XSS\n- Use parameterized queries to prevent SQL injection\n\n## Authentication & Authorization\n\n- Use established libraries — do not implement custom crypto\n- Apply least privilege: grant minimum permissions required\n- Expire sessions and tokens with reasonable timeouts\n\n## Dependencies\n\n- Regularly scan dependencies for known vulnerabilities\n- Update vulnerable dependencies promptly\n- Evaluate new dependencies for security track record before adding\n`,\n\t\"dependency-policy.md\": `---\ndescription: Dependency evaluation criteria, version management\n---\n# Dependency Policy\n\n<!-- Customize: adjust these defaults to match your project's dependency approach. -->\n\n## Adding Dependencies\n\nBefore adding a dependency, evaluate:\n- **Necessity**: can this be implemented in a few lines without the dependency?\n- **Maintenance**: is the package actively maintained? When was the last release?\n- **Size**: what is the install size and dependency tree depth?\n- **License**: is the license compatible with your project?\n- **Security**: does it have known vulnerabilities?\n\nPrefer standard library / platform APIs over third-party packages when feasible.\n\n## Version Management\n\n- Pin exact versions or use lock files (\\`package-lock.json\\`, \\`pnpm-lock.yaml\\`)\n- Update dependencies regularly — do not let them go stale\n- Test after updating — run the full test suite before committing dependency updates\n`,\n\t\"performance-guidelines.md\": `---\ndescription: Performance principles, data structures, resource management\n---\n# Performance Guidelines\n\n<!-- Customize: adjust these defaults to match your project's performance needs. -->\n\n## Principles\n\n- Do not optimize prematurely — write clear code first, optimize when measured\n- Profile before optimizing — identify actual bottlenecks, not guessed ones\n- Use async I/O where appropriate — avoid blocking the event loop or main thread with synchronous operations\n\n## Data Structures\n\n- Choose appropriate data structures for the access pattern (Map for lookups, Array for iteration)\n- Avoid unnecessary copying of large data structures\n\n## Resource Management\n\n- Close resources (file handles, connections, streams) when done\n- Use connection pooling for databases and HTTP clients\n- Set reasonable timeouts for all external calls\n`,\n\t\"accessibility.md\": `---\ndescription: WCAG compliance, keyboard navigation, screen readers, visual design\n---\n# Accessibility\n\n<!-- Customize: adjust these defaults if your project has a UI. -->\n<!-- If your project has no user-facing UI, this file can be left as-is. -->\n\n## Standards\n\n- Follow WCAG 2.1 Level AA guidelines for web applications\n- Use semantic HTML elements (\\`<button>\\`, \\`<nav>\\`, \\`<main>\\`, not \\`<div>\\` for everything)\n- Provide text alternatives for non-text content (images, icons)\n\n## Keyboard Navigation\n\n- All interactive elements must be keyboard-accessible\n- Focus order must follow a logical reading sequence\n- Visible focus indicators on all interactive elements\n\n## Screen Readers\n\n- Use ARIA attributes when semantic HTML is insufficient\n- Test with at least one screen reader\n\n## Visual Design\n\n- Minimum 4.5:1 contrast ratio for normal text\n- Do not convey information by color alone\n- Support user font size preferences\n`,\n\t\"observability.md\": `---\ndescription: Structured logging, metrics, distributed tracing\n---\n# Observability\n\n<!-- Customize: adjust these defaults to match your project's observability needs. -->\n\n## Logging\n\n- Use structured logging (JSON or key-value pairs) — not free-form text\n- Include context: timestamp, level, module, request ID where applicable\n- Log at appropriate levels: ERROR for failures, WARN for recoverable issues, INFO for state changes, DEBUG for troubleshooting\n\n## Metrics\n\n<!-- Define key metrics for your application. Examples: -->\n- Request latency (p50, p95, p99)\n- Error rate\n- Resource utilization (memory, CPU, connections)\n\n## Tracing\n\n- Propagate trace/correlation IDs across service boundaries\n- Instrument key operations: incoming requests, outgoing calls, database queries\n- Use consistent span naming conventions\n`,\n\t\"logging.md\": `---\ndescription: Logging principles, log levels, log format, logger injection\n---\n# Logging\n\n<!-- Define your logging standards. -->\n\n## Principles\n<!-- Basic principles such as no direct console.* calls -->\n\n## Log Levels\n<!-- Criteria for debug, info, warn, error usage -->\n\n## Log Format\n<!-- Log format rules -->\n\n## Injection Pattern\n<!-- Logger injection approach (callbacks, DI, etc.) -->\n`,\n\t\".artifact-standards.md\": `---\ndescription: Format and structure rules for all feature artifacts\n---\n# Artifact Standards\n\nStandards for all artifacts generated by agents under \\\\\\`.vibe/features/{featureId}/\\\\\\`.\n\n## Artifact List\n\n| File | Creator | Workflow | Required |\n|---|---|---|---|\n| \\\\\\`spec.md\\\\\\` | Planner | all | required |\n| \\\\\\`design.md\\\\\\` | Architect | all | required |\n| \\\\\\`impact-report.md\\\\\\` | Analyzer | enhancement, refactor | conditional |\n| \\\\\\`diagnosis.md\\\\\\` | Diagnostician | bugfix | conditional |\n| \\\\\\`review.md\\\\\\` | Reviewer | all | required |\n| \\\\\\`test-report.md\\\\\\` | Tester | all | required |\n| \\\\\\`regression-report.md\\\\\\` | Tester | enhancement, bugfix, refactor | conditional |\n| \\\\\\`retry-log.md\\\\\\` | Pipeline Engine | on retry | conditional |\n| \\\\\\`status.json\\\\\\` | Pipeline Engine / VibeStore | all | required |\n\n---\n\n## spec.md (Planner)\n\nDefines the purpose, scope, and requirements of a feature.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: {Title}\n\n## Purpose\n\nDescribe the problem this feature solves and why it exists in 1-3 sentences.\n\n## Dependencies\n\n- \\\\\\\\\\\\\\`feat-xxx\\\\\\\\\\\\\\`: reason for dependency\n- (if none, write \"None\")\n\n## Requirements\n\n### {Requirement Group 1}\n\n- Describe as specific, verifiable items\n- Each item must be independently testable\n\n### {Requirement Group 2}\n\n- ...\n\n## Implementation Location\n\n- \\\\\\\\\\\\\\`src/xxx\\\\\\\\\\\\\\`: role description\n\n## Acceptance Criteria\n\n- List conditions that can be verified by tests\n- No vague expressions (e.g., \"should work well\")\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Describe **what** needs to be done, not **how** to implement it\n- Acceptance criteria must be directly convertible to test cases by the Tester\n- Dependencies must match the \\\\\\`dependencyGraph\\\\\\` in \\\\\\`plan.json\\\\\\`\n- File paths are relative to the package root\n\n---\n\n## design.md (Architect)\n\nConverts spec requirements into concrete technical design.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Design Document\n\n## Overview\n\nSummarize the core design direction in 1-3 sentences.\n\n## Dependencies\n\n- \\\\\\\\\\\\\\`./types\\\\\\\\\\\\\\`: types used\n- \\\\\\\\\\\\\\`./store\\\\\\\\\\\\\\`: modules used\n- (include external packages)\n\n## API Design\n\n### {Component/Class/Module}\n\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\n// Public interface definition (signatures + documentation comments)\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\n\n### {Additional Type Definitions}\n\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\n// Types to add\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\n\n## File Structure\n\n| File | Content |\n|---|---|\n| \\\\\\\\\\\\\\`src/xxx\\\\\\\\\\\\\\` | role description |\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | test description |\n\n## Design Decisions\n\n1. **Decision title**: chosen direction and rationale. If alternatives existed, explain why they were rejected.\n\n## Test Strategy\n\n- What level of testing is needed (unit/integration)\n- Mocking strategy\n- Edge case list\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- API signatures must be specified as code in the project's language (natural language descriptions alone are insufficient)\n- File paths are relative to the package root\n- All requirements from spec.md must be reflected in the design\n- Clearly describe integration points with existing code\n\n---\n\n## impact-report.md (Analyzer)\n\nAnalyzes the impact of changes on the existing codebase. Generated for enhancement and refactor workflows.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Impact Report\n\n## Change Summary\n\nDescribe the purpose and scope of the change in 1-3 sentences.\n\n## Affected Files\n\n| File | Change Type | Impact | Description |\n|---|---|---|---|\n| \\\\\\\\\\\\\\`src/xxx\\\\\\\\\\\\\\` | modify | HIGH | public API signature change |\n| \\\\\\\\\\\\\\`src/yyy\\\\\\\\\\\\\\` | modify | LOW | import path change only |\n\nChange types: \\\\\\\\\\\\\\`create\\\\\\\\\\\\\\`, \\\\\\\\\\\\\\`modify\\\\\\\\\\\\\\`, \\\\\\\\\\\\\\`delete\\\\\\\\\\\\\\`\nImpact levels: \\\\\\\\\\\\\\`HIGH\\\\\\\\\\\\\\`, \\\\\\\\\\\\\\`MEDIUM\\\\\\\\\\\\\\`, \\\\\\\\\\\\\\`LOW\\\\\\\\\\\\\\`\n\n## Affected Tests\n\n| Test File | Impact Reason |\n|---|---|\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | directly tests the changed API |\n\n## Compatibility\n\n### Backward Compatibility\n\n- Whether existing API is preserved\n- List of breaking changes (if any)\n\n### Impact on Dependent Features\n\n- How this change affects other features\n\n## Risk Assessment\n\n| Risk | Level | Mitigation |\n|---|---|---|\n| {risk description} | HIGH/MEDIUM/LOW | {mitigation strategy} |\n\n## Recommendations\n\n- Regression test targets\n- Areas requiring additional review\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Read-only analysis. May suggest code modifications but must not modify code directly\n- List all affected files without omissions\n- Risk level must be one of \\\\\\`HIGH\\\\\\`, \\\\\\`MEDIUM\\\\\\`, \\\\\\`LOW\\\\\\`\n\n---\n\n## diagnosis.md (Diagnostician)\n\nAnalyzes bug causes and proposes fix strategies. Generated for bugfix workflows.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Diagnosis\n\n## Bug Summary\n\nDescribe reported symptoms in 1-3 sentences.\n\n## Reproduction Steps\n\n1. Step-by-step reproduction method\n2. ...\n\n## Reproduction Results\n\n- Expected behavior: ...\n- Actual behavior: ...\n- Error message/log (if available):\n\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\nerror output\n\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\n\n## Root Cause Analysis\n\n### Root Cause\n\nDescribe the cause concretely. Include code paths and line numbers.\n\n### Impact Scope\n\n- Other features/code affected by this bug\n\n## Fix Strategy\n\n### Recommended Fix\n\n- Files to modify and change details\n- Scope of changes (minimal invasiveness principle)\n\n### Alternatives (if any)\n\n- Alternatives and reasons for rejection\n\n## Risk Assessment\n\n| Risk | Level | Description |\n|---|---|---|\n| Side effects of fix | HIGH/MEDIUM/LOW | description |\n| Recurrence likelihood | HIGH/MEDIUM/LOW | description |\n\n## Recommended Regression Tests\n\n- Proposed test cases to verify this bug\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Read-only. Cannot modify code, but may run reproduction tests\n- Diagnosis must be based on code analysis, not speculation\n- Fix strategy must be specific enough for the Developer to implement directly\n\n---\n\n## review.md (Reviewer)\n\nVerifies the quality of implementation and tests, and issues approval/change request verdicts.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Review\n\n## Review Scope\n\n| File | Change |\n|---|---|\n| \\\\\\\\\\\\\\`src/xxx\\\\\\\\\\\\\\` | change summary |\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | change summary |\n\n## Checklist\n\n- [x] spec.md requirements met\n - [x] {specific item}\n- [x] design.md compliance\n - [x] {specific item}\n- [x] Type safety: no loosely-typed constructs\n- [x] Import conventions followed\n- [x] Project lint/check passes\n- [x] Tests pass ({N} tests)\n\n## Code Review\n\n### {Perspective 1} (e.g., architecture, error handling, performance)\n\nEvaluation content. Reference specific files/lines.\n\n### Improvements (non-blocking)\n\n- Items not requiring immediate fix but worth improving later\n\n### Issues (blocking) — only if present\n\n- Items that must be fixed. Specify file paths and concrete details.\n\n## Standards Compliance\n\n| Standard | Status | Notes |\n|---|---|---|\n| coding-style | PASS | |\n| coding-conventions | PASS | |\n| {standard name} | WARN/FAIL | {file path} - {violation details} |\n\nOverall: PASS / WARN / FAIL\n\n## Verdict: APPROVED / CHANGES_REQUESTED\n\n(If CHANGES_REQUESTED, refer to blocking issues list)\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Read-only. Cannot modify code\n- Standards Compliance is included only when loaded standards are available\n- If Overall is \\\\\\`FAIL\\\\\\`, verdict must be \\\\\\`CHANGES_REQUESTED\\\\\\`\n- If no blocking issues exist, verdict is \\\\\\`APPROVED\\\\\\`\n- Checklist items correspond 1:1 to acceptance criteria in spec.md\n\n---\n\n## test-report.md (Tester)\n\nRecords test execution results.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Test Report\n\n## Execution Environment\n\n- **Framework**: {test framework and version, e.g., Vitest, pytest, go test}\n- **Runner**: {command used to run tests}\n- **Working directory**: {project root or relevant subdirectory}\n\n## Result Summary\n\n| Item | Value |\n|---|---|\n| Test files | {N} passed ({N}) |\n| Test cases | {N} passed ({N}) |\n| Failures | {N} |\n| Duration | {N}ms |\n\n## Test Details\n\n### {describe block name} ({passed}/{total} passed)\n\n| Test | Result |\n|---|---|\n| {test name} | PASS |\n| {test name} | FAIL — {failure reason summary} |\n\n## Coverage Analysis\n\n- [x] {covered functionality}\n- [ ] {uncovered functionality} — {reason}\n\nEdge case coverage:\n- [x] {edge case}\n\n## Acceptance Criteria Fulfillment\n\n| Criterion | Status |\n|---|---|\n| {acceptance criterion from spec.md} | PASS/FAIL |\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Record actual execution results. No estimates\n- Failed tests must include failure reasons\n- Acceptance criteria table corresponds 1:1 to spec.md acceptance criteria\n- Explicitly note missing coverage areas\n\n---\n\n## regression-report.md (Tester)\n\nVerifies no regressions in existing functionality. Generated for enhancement, bugfix, and refactor workflows.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Regression Report\n\n## Target\n\n- **Changed feature**: {featureId}\n- **Reference**: impact-report.md / diagnosis.md\n\n## Execution Environment\n\n- **Framework**: {test framework and version}\n- **Working directory**: {project root or relevant subdirectory}\n\n## Regression Test Scope\n\n| Test File | Target Functionality | Selection Reason |\n|---|---|---|\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | {functionality} | identified as affected file in impact-report.md |\n\n## Results\n\n| Test File | Result | Failed Items |\n|---|---|---|\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | PASS | — |\n| \\\\\\\\\\\\\\`test/yyy\\\\\\\\\\\\\\` | FAIL | {test name}: {failure reason} |\n\n## New Regression Tests\n\nTests added due to the change:\n\n| Test File | Test Name | Verification Target |\n|---|---|---|\n| \\\\\\\\\\\\\\`test/xxx\\\\\\\\\\\\\\` | {test name} | {what it verifies} |\n\n## Verdict: PASS / FAIL\n\n(If FAIL, include failed tests and impact analysis)\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Determine test scope by referencing impact-report.md or diagnosis.md\n- Run both existing tests and new regression tests\n- Record actual execution results. No estimates\n\n---\n\n## retry-log.md (Pipeline Engine)\n\nRecords retry history. Automatically generated when retries occur due to test failures, review change requests, etc.\n\n### Required Sections\n\n\\\\\\`\\\\\\`\\\\\\`markdown\n# {featureId}: Retry Log\n\n## Retry History\n\n### Attempt {N} — {timestamp}\n\n- **Step**: {testing/reviewing/regression}\n- **Result**: FAIL\n- **Reason**: {failure cause summary}\n- **Action**: {changes made for the next attempt}\n\n### Attempt {N+1} — {timestamp}\n\n- **Step**: {step}\n- **Result**: PASS\n- **Reason**: —\n\n## Summary\n\n| Item | Value |\n|---|---|\n| Total attempts | {N} |\n| Final result | PASS/FAIL |\n| Max retry limit reached | Yes/No |\n\\\\\\`\\\\\\`\\\\\\`\n\n### Rules\n\n- Record each attempt in chronological order\n- Reference test-report.md or review.md for failure reasons\n- Indicate when max retry limit (from \\\\\\`config.json\\\\\\` retry settings) is reached\n\n---\n\n## status.json (Pipeline Engine / VibeStore)\n\nTracks the current state of a feature.\n\n### Format\n\n\\\\\\`\\\\\\`\\\\\\`json\n{\n \"status\": \"implementing\",\n \"updatedAt\": \"2026-03-05T16:35:00+09:00\",\n \"phase\": \"develop\",\n \"error\": null\n}\n\\\\\\`\\\\\\`\\\\\\`\n\n### Fields\n\n| Field | Type | Required | Description |\n|---|---|---|---|\n| \\\\\\`status\\\\\\` | \\\\\\`FeatureStatusValue\\\\\\` | required | \\\\\\`planned\\\\\\`, \\\\\\`designing\\\\\\`, \\\\\\`implementing\\\\\\`, \\\\\\`testing\\\\\\`, \\\\\\`reviewing\\\\\\`, \\\\\\`done\\\\\\`, \\\\\\`blocked\\\\\\`, \\\\\\`failed\\\\\\` |\n| \\\\\\`updatedAt\\\\\\` | \\\\\\`string\\\\\\` (ISO 8601) | required | timestamp of last status change |\n| \\\\\\`phase\\\\\\` | \\\\\\`string\\\\\\` | optional | current pipeline step (plan, design, develop, test, review, etc.) |\n| \\\\\\`error\\\\\\` | \\\\\\`string \\\\\\\\| null\\\\\\` | optional | failure/block reason |\n\n### Rules\n\n- Do not edit directly. Change only through \\\\\\`VibeStore.updateFeatureStatus()\\\\\\`\n- Only state transitions defined in \\\\\\`VALID_TRANSITIONS\\\\\\` are allowed\n- \\\\\\`updatedAt\\\\\\` must be in ISO 8601 format with UTC offset\n\n---\n\n## Common Rules\n\n1. **File paths**: use relative paths from the project root (e.g., \\\\\\`src/store\\\\\\`, \\\\\\`test/store\\\\\\`)\n2. **Writing style**: technical documentation style. Concise and direct. No emojis.\n3. **Code blocks**: language tag required (e.g., \\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`python, \\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`typescript, \\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`json, \\\\\\\\\\\\\\`\\\\\\\\\\\\\\`\\\\\\\\\\\\\\`markdown)\n4. **Table alignment**: Markdown table separators use \\\\\\`|---|\\\\\\` format\n5. **Cross-references**: reference other artifacts by filename (e.g., \"see acceptance criteria in spec.md\")\n6. **Version control**: artifacts are tracked by git within the feature directory. Overwrite history is tracked via commit history.\n7. **Encoding**: UTF-8, LF line endings\n8. **Language**: all artifacts must be written in English. This includes headings, prose, table content, and technical descriptions.\n`,\n};\n"]}
|
package/dist/discovery.d.ts
CHANGED
|
@@ -24,8 +24,6 @@ export interface DiscoveryOptions {
|
|
|
24
24
|
onMessage?: (message: string) => void;
|
|
25
25
|
/** User feedback on rejection. Applied when regenerating existing requirements.md. */
|
|
26
26
|
feedback?: string;
|
|
27
|
-
/** Lightweight skill index. Included in the agent system prompt. */
|
|
28
|
-
availableSkills?: string;
|
|
29
27
|
/** Callback invoked when the agent is created. Used for abort wiring, etc. */
|
|
30
28
|
onAgentCreated?: (agent: Agent) => void;
|
|
31
29
|
/** Callback invoked when the agent finishes execution. */
|
package/dist/discovery.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAgB,MAAM,6BAA6B,CAAC;AACnF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,iEAAiE;AACjE,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,0EAA0E;AAC1E,eAAO,MAAM,eAAe,4BAA4B,CAAC;AAIzD,kCAAkC;AAClC,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrE,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,qEAAqE;IACrE,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,kDAAkD;IAClD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACxC,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,iCAAiC;AACjC,MAAM,WAAW,eAAe;IAC/B,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACpH;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMhE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAuJtF","sourcesContent":["import type { Agent, AgentEvent, AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { GetApiKeyFn } from \"./agent-factory.js\";\nimport { createRoleAgent, filterSerializableMessages, runAgentWithHistory } from \"./agent-factory.js\";\nimport { getSystemPromptForRole } from \"./roles/index.js\";\nimport { aggregateUsage, extractArtifactContent } from \"./step-executor.js\";\nimport type { VibeStore } from \"./store.js\";\nimport type { VibeConfig } from \"./types.js\";\n\n// ─── Markers ─────────────────────────────────────────────────────────────────\n\n/** Marker indicating the Discovery Agent has output questions */\nexport const QUESTION_MARKER = \"[QUESTIONS]\";\n\n/** Marker indicating the Discovery Agent has completed requirements.md */\nexport const COMPLETE_MARKER = \"[REQUIREMENTS_COMPLETE]\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Discovery execution options */\nexport interface DiscoveryOptions {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\trequirement: string;\n\t/** Function to receive user input. Returns undefined to cancel. */\n\trequestUserInput: (questions: string) => Promise<string | undefined>;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Agent event callback. Used for progress display, etc. */\n\tonAgentEvent?: (event: AgentEvent) => void;\n\t/** Callback to relay agent messages externally */\n\tonMessage?: (message: string) => void;\n\t/** User feedback on rejection. Applied when regenerating existing requirements.md. */\n\tfeedback?: string;\n\t/** Lightweight skill index. Included in the agent system prompt. */\n\tavailableSkills?: string;\n\t/** Callback invoked when the agent is created. Used for abort wiring, etc. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Callback invoked when the agent finishes execution. */\n\tonAgentFinished?: () => void;\n}\n\n/** Discovery execution result */\nexport interface DiscoveryResult {\n\t/** Whether requirements.md was generated */\n\tcompleted: boolean;\n\t/** Number of question rounds performed */\n\trounds: number;\n\t/** Aggregated token usage across all LLM calls */\n\tusage?: { input: number; output: number; cacheRead: number; cacheWrite: number; totalTokens: number; cost: number };\n}\n\n// ─── Discovery Runner ────────────────────────────────────────────────────────\n\n/**\n * Extracts question text before the question marker from the response.\n * Returns null if no marker is found.\n */\nexport function extractQuestions(response: string): string | null {\n\tconst idx = response.indexOf(QUESTION_MARKER);\n\tif (idx === -1) {\n\t\treturn null;\n\t}\n\treturn response.substring(0, idx).trim();\n}\n\n/**\n * Checks whether the response indicates requirements completion.\n */\nexport function isRequirementsComplete(response: string): boolean {\n\treturn response.includes(COMPLETE_MARKER);\n}\n\n/**\n * Runs the Discovery Agent interactively.\n *\n * 1. Load project-context.md if it exists\n * 2. Create Agent (discovery role)\n * 3. Pass requirements + project-context as the initial prompt\n * 4. If [QUESTIONS] marker in response → request user input → call agent.prompt() again\n * 5. If [REQUIREMENTS_COMPLETE] or maxRounds reached → extract requirements.md → save\n */\nexport async function runDiscovery(options: DiscoveryOptions): Promise<DiscoveryResult> {\n\tconst {\n\t\tstore,\n\t\tconfig,\n\t\tprojectRoot,\n\t\trequirement,\n\t\trequestUserInput,\n\t\tgetApiKey,\n\t\tmodel,\n\t\tonAgentEvent,\n\t\tonMessage,\n\t\tfeedback,\n\t} = options;\n\tconst maxRounds = config.discovery.maxQuestionRounds;\n\n\t// 1. Load project-context.md\n\tlet projectContext: string | undefined;\n\tif (await store.hasProjectContext()) {\n\t\tprojectContext = await store.readProjectContext();\n\t}\n\n\t// 2. Check for previous checkpoint (restore on restart)\n\tlet initialMessages: AgentMessage[] | undefined;\n\tlet rounds = 0;\n\n\tconst previousCheckpoint = await store.loadGlobalAgentHistory(\"discovery\", \"discovery\");\n\tif (previousCheckpoint) {\n\t\tinitialMessages = previousCheckpoint.messages;\n\t\trounds = (previousCheckpoint.metadata?.rounds as number) ?? 0;\n\t\tonMessage?.(`[Discovery] Resuming from previous session (round ${rounds})`);\n\t}\n\n\t// 3. System prompt + Agent creation\n\tconst systemPrompt = getSystemPromptForRole(\"discovery\");\n\tconst agent = await createRoleAgent({\n\t\trole: \"discovery\",\n\t\tsystemPrompt,\n\t\tconfig,\n\t\tprojectRoot,\n\t\tmodel,\n\t\tgetApiKey,\n\t\tinitialMessages,\n\t\tavailableSkills: options.availableSkills,\n\t});\n\n\t// Notify external code that the agent has been created (for abort wiring)\n\toptions.onAgentCreated?.(agent);\n\n\t// 4. Build initial prompt (guide to continue from checkpoint on restore)\n\tlet initialPrompt: string;\n\tif (feedback) {\n\t\t// If reject feedback exists, regenerate requirements.md incorporating the feedback\n\t\tinitialPrompt =\n\t\t\t`The previous requirements.md was rejected with the following feedback:\\n\\n${feedback}\\n\\n` +\n\t\t\t\"Please revise the requirements based on this feedback. Ask additional questions if needed, \" +\n\t\t\t\"then output the revised requirements.md followed by [REQUIREMENTS_COMPLETE].\";\n\t} else if (previousCheckpoint) {\n\t\tinitialPrompt =\n\t\t\t\"Continue the requirements discovery from where we left off. If you have more questions, ask them. If you have enough information, write requirements.md.\";\n\t} else {\n\t\tinitialPrompt = buildDiscoveryPrompt(requirement, projectContext, config.discovery.skipIfClear);\n\t}\n\n\t// 5. Conversation loop\n\ttry {\n\t\tconst eventOptions = onAgentEvent ? { onEvent: onAgentEvent } : undefined;\n\t\tlet result = await runAgentWithHistory(agent, initialPrompt, eventOptions);\n\t\tlet response = result.text;\n\n\t\twhile (rounds < maxRounds) {\n\t\t\tonMessage?.(response);\n\n\t\t\t// Save checkpoint (every round)\n\t\t\tawait store.saveGlobalAgentHistory({\n\t\t\t\trole: \"discovery\",\n\t\t\t\taction: \"discovery\",\n\t\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\tmetadata: { rounds },\n\t\t\t});\n\n\t\t\t// Check requirements completion\n\t\t\tif (isRequirementsComplete(response)) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Check for question marker\n\t\t\tconst questions = extractQuestions(response);\n\t\t\tif (!questions) {\n\t\t\t\t// No marker and not complete — treat the entire response as requirements\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Request user input\n\t\t\tconst userAnswer = await requestUserInput(questions);\n\t\t\tif (userAnswer === undefined) {\n\t\t\t\t// User cancelled — checkpoint already saved\n\t\t\t\treturn { completed: false, rounds };\n\t\t\t}\n\n\t\t\trounds++;\n\n\t\t\t// Pass the answer to the agent\n\t\t\tresult = await runAgentWithHistory(agent, userAnswer, eventOptions);\n\t\t\tresponse = result.text;\n\t\t}\n\n\t\t// After maxRounds reached or loop exit: force completion if no completion marker\n\t\tconst hasQuestionMarker = response.includes(QUESTION_MARKER);\n\t\tif (\n\t\t\t!isRequirementsComplete(response) &&\n\t\t\t(hasQuestionMarker || !extractArtifactContent(response, \"requirements.md\", false))\n\t\t) {\n\t\t\tonMessage?.(\"[Discovery] Finalizing requirements...\");\n\t\t\tresult = await runAgentWithHistory(\n\t\t\t\tagent,\n\t\t\t\t\"Please finalize the requirements.md now with the information gathered so far. Output the document in a ```requirements.md code block followed by [REQUIREMENTS_COMPLETE].\",\n\t\t\t\teventOptions,\n\t\t\t);\n\t\t\tresponse = result.text;\n\t\t\tonMessage?.(response);\n\t\t}\n\n\t\t// Save final checkpoint\n\t\tawait store.saveGlobalAgentHistory({\n\t\t\trole: \"discovery\",\n\t\t\taction: \"discovery\",\n\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tmetadata: { rounds, completed: true },\n\t\t});\n\n\t\t// 6. Extract and save requirements.md\n\t\tconst usage = aggregateUsage(result.messages);\n\t\tconst content = extractArtifactContent(response, \"requirements.md\", true);\n\t\tif (content) {\n\t\t\tawait store.writeRequirements(content);\n\t\t\treturn { completed: true, rounds, usage };\n\t\t}\n\n\t\treturn { completed: false, rounds, usage };\n\t} catch (error) {\n\t\t// Interruption by agent.abort(): \"Request was aborted\" error\n\t\tconst msg = error instanceof Error ? error.message : String(error);\n\t\tif (msg.includes(\"aborted\")) {\n\t\t\treturn { completed: false, rounds };\n\t\t}\n\t\tthrow error;\n\t} finally {\n\t\toptions.onAgentFinished?.();\n\t}\n}\n\n// ─── Prompt Builder ──────────────────────────────────────────────────────────\n\nfunction buildDiscoveryPrompt(requirement: string, projectContext?: string, skipIfClear?: boolean): string {\n\tconst parts: string[] = [];\n\n\tparts.push(\"## User Requirement\");\n\tparts.push(\"\");\n\tparts.push(requirement);\n\n\tif (projectContext) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Project Context\");\n\t\tparts.push(\"\");\n\t\tparts.push(projectContext);\n\t}\n\n\tparts.push(\"\");\n\tparts.push(\"## Instructions\");\n\tparts.push(\"\");\n\n\tif (skipIfClear) {\n\t\tparts.push(\n\t\t\t\"If the requirement above is already clear and specific enough to implement, \" +\n\t\t\t\t\"skip questions and write requirements.md immediately. \" +\n\t\t\t\t\"Only ask questions if there are genuine ambiguities or missing information.\",\n\t\t);\n\t} else {\n\t\tparts.push(\"Analyze the requirement and ask clarifying questions if needed.\");\n\t}\n\n\tparts.push(\"\");\n\tparts.push(\n\t\t\"Remember: end with [QUESTIONS] if you have questions, or output ```requirements.md ... ``` followed by [REQUIREMENTS_COMPLETE] when done.\",\n\t);\n\n\treturn parts.join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"discovery.d.ts","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,UAAU,EAAgB,MAAM,6BAA6B,CAAC;AACnF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAItD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAI7C,iEAAiE;AACjE,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C,0EAA0E;AAC1E,eAAO,MAAM,eAAe,4BAA4B,CAAC;AAIzD,kCAAkC;AAClC,MAAM,WAAW,gBAAgB;IAChC,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,UAAU,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IACrE,SAAS,CAAC,EAAE,WAAW,CAAC;IACxB,qEAAqE;IACrE,KAAK,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,4DAA4D;IAC5D,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;IAC3C,kDAAkD;IAClD,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,sFAAsF;IACtF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACxC,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,IAAI,CAAC;CAC7B;AAED,iCAAiC;AACjC,MAAM,WAAW,eAAe;IAC/B,4CAA4C;IAC5C,SAAS,EAAE,OAAO,CAAC;IACnB,0CAA0C;IAC1C,MAAM,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,KAAK,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CACpH;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMhE;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEhE;AAED;;;;;;;;GAQG;AACH,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC,CAsJtF","sourcesContent":["import type { Agent, AgentEvent, AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { GetApiKeyFn } from \"./agent-factory.js\";\nimport { createRoleAgent, filterSerializableMessages, runAgentWithHistory } from \"./agent-factory.js\";\nimport { getSystemPromptForRole } from \"./roles/index.js\";\nimport { aggregateUsage, extractArtifactContent } from \"./step-executor.js\";\nimport type { VibeStore } from \"./store.js\";\nimport type { VibeConfig } from \"./types.js\";\n\n// ─── Markers ─────────────────────────────────────────────────────────────────\n\n/** Marker indicating the Discovery Agent has output questions */\nexport const QUESTION_MARKER = \"[QUESTIONS]\";\n\n/** Marker indicating the Discovery Agent has completed requirements.md */\nexport const COMPLETE_MARKER = \"[REQUIREMENTS_COMPLETE]\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Discovery execution options */\nexport interface DiscoveryOptions {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\trequirement: string;\n\t/** Function to receive user input. Returns undefined to cancel. */\n\trequestUserInput: (questions: string) => Promise<string | undefined>;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Agent event callback. Used for progress display, etc. */\n\tonAgentEvent?: (event: AgentEvent) => void;\n\t/** Callback to relay agent messages externally */\n\tonMessage?: (message: string) => void;\n\t/** User feedback on rejection. Applied when regenerating existing requirements.md. */\n\tfeedback?: string;\n\t/** Callback invoked when the agent is created. Used for abort wiring, etc. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Callback invoked when the agent finishes execution. */\n\tonAgentFinished?: () => void;\n}\n\n/** Discovery execution result */\nexport interface DiscoveryResult {\n\t/** Whether requirements.md was generated */\n\tcompleted: boolean;\n\t/** Number of question rounds performed */\n\trounds: number;\n\t/** Aggregated token usage across all LLM calls */\n\tusage?: { input: number; output: number; cacheRead: number; cacheWrite: number; totalTokens: number; cost: number };\n}\n\n// ─── Discovery Runner ────────────────────────────────────────────────────────\n\n/**\n * Extracts question text before the question marker from the response.\n * Returns null if no marker is found.\n */\nexport function extractQuestions(response: string): string | null {\n\tconst idx = response.indexOf(QUESTION_MARKER);\n\tif (idx === -1) {\n\t\treturn null;\n\t}\n\treturn response.substring(0, idx).trim();\n}\n\n/**\n * Checks whether the response indicates requirements completion.\n */\nexport function isRequirementsComplete(response: string): boolean {\n\treturn response.includes(COMPLETE_MARKER);\n}\n\n/**\n * Runs the Discovery Agent interactively.\n *\n * 1. Load project-context.md if it exists\n * 2. Create Agent (discovery role)\n * 3. Pass requirements + project-context as the initial prompt\n * 4. If [QUESTIONS] marker in response → request user input → call agent.prompt() again\n * 5. If [REQUIREMENTS_COMPLETE] or maxRounds reached → extract requirements.md → save\n */\nexport async function runDiscovery(options: DiscoveryOptions): Promise<DiscoveryResult> {\n\tconst {\n\t\tstore,\n\t\tconfig,\n\t\tprojectRoot,\n\t\trequirement,\n\t\trequestUserInput,\n\t\tgetApiKey,\n\t\tmodel,\n\t\tonAgentEvent,\n\t\tonMessage,\n\t\tfeedback,\n\t} = options;\n\tconst maxRounds = config.discovery.maxQuestionRounds;\n\n\t// 1. Load project-context.md\n\tlet projectContext: string | undefined;\n\tif (await store.hasProjectContext()) {\n\t\tprojectContext = await store.readProjectContext();\n\t}\n\n\t// 2. Check for previous checkpoint (restore on restart)\n\tlet initialMessages: AgentMessage[] | undefined;\n\tlet rounds = 0;\n\n\tconst previousCheckpoint = await store.loadGlobalAgentHistory(\"discovery\", \"discovery\");\n\tif (previousCheckpoint) {\n\t\tinitialMessages = previousCheckpoint.messages;\n\t\trounds = (previousCheckpoint.metadata?.rounds as number) ?? 0;\n\t\tonMessage?.(`[Discovery] Resuming from previous session (round ${rounds})`);\n\t}\n\n\t// 3. System prompt + Agent creation\n\tconst systemPrompt = getSystemPromptForRole(\"discovery\");\n\tconst agent = await createRoleAgent({\n\t\trole: \"discovery\",\n\t\tsystemPrompt,\n\t\tconfig,\n\t\tprojectRoot,\n\t\tmodel,\n\t\tgetApiKey,\n\t\tinitialMessages,\n\t});\n\n\t// Notify external code that the agent has been created (for abort wiring)\n\toptions.onAgentCreated?.(agent);\n\n\t// 4. Build initial prompt (guide to continue from checkpoint on restore)\n\tlet initialPrompt: string;\n\tif (feedback) {\n\t\t// If reject feedback exists, regenerate requirements.md incorporating the feedback\n\t\tinitialPrompt =\n\t\t\t`The previous requirements.md was rejected with the following feedback:\\n\\n${feedback}\\n\\n` +\n\t\t\t\"Please revise the requirements based on this feedback. Ask additional questions if needed, \" +\n\t\t\t\"then output the revised requirements.md followed by [REQUIREMENTS_COMPLETE].\";\n\t} else if (previousCheckpoint) {\n\t\tinitialPrompt =\n\t\t\t\"Continue the requirements discovery from where we left off. If you have more questions, ask them. If you have enough information, write requirements.md.\";\n\t} else {\n\t\tinitialPrompt = buildDiscoveryPrompt(requirement, projectContext, config.discovery.skipIfClear);\n\t}\n\n\t// 5. Conversation loop\n\ttry {\n\t\tconst eventOptions = onAgentEvent ? { onEvent: onAgentEvent } : undefined;\n\t\tlet result = await runAgentWithHistory(agent, initialPrompt, eventOptions);\n\t\tlet response = result.text;\n\n\t\twhile (rounds < maxRounds) {\n\t\t\tonMessage?.(response);\n\n\t\t\t// Save checkpoint (every round)\n\t\t\tawait store.saveGlobalAgentHistory({\n\t\t\t\trole: \"discovery\",\n\t\t\t\taction: \"discovery\",\n\t\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\tmetadata: { rounds },\n\t\t\t});\n\n\t\t\t// Check requirements completion\n\t\t\tif (isRequirementsComplete(response)) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Check for question marker\n\t\t\tconst questions = extractQuestions(response);\n\t\t\tif (!questions) {\n\t\t\t\t// No marker and not complete — treat the entire response as requirements\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Request user input\n\t\t\tconst userAnswer = await requestUserInput(questions);\n\t\t\tif (userAnswer === undefined) {\n\t\t\t\t// User cancelled — checkpoint already saved\n\t\t\t\treturn { completed: false, rounds };\n\t\t\t}\n\n\t\t\trounds++;\n\n\t\t\t// Pass the answer to the agent\n\t\t\tresult = await runAgentWithHistory(agent, userAnswer, eventOptions);\n\t\t\tresponse = result.text;\n\t\t}\n\n\t\t// After maxRounds reached or loop exit: force completion if no completion marker\n\t\tconst hasQuestionMarker = response.includes(QUESTION_MARKER);\n\t\tif (\n\t\t\t!isRequirementsComplete(response) &&\n\t\t\t(hasQuestionMarker || !extractArtifactContent(response, \"requirements.md\", false))\n\t\t) {\n\t\t\tonMessage?.(\"[Discovery] Finalizing requirements...\");\n\t\t\tresult = await runAgentWithHistory(\n\t\t\t\tagent,\n\t\t\t\t\"Please finalize the requirements.md now with the information gathered so far. Output the document in a ```requirements.md code block followed by [REQUIREMENTS_COMPLETE].\",\n\t\t\t\teventOptions,\n\t\t\t);\n\t\t\tresponse = result.text;\n\t\t\tonMessage?.(response);\n\t\t}\n\n\t\t// Save final checkpoint\n\t\tawait store.saveGlobalAgentHistory({\n\t\t\trole: \"discovery\",\n\t\t\taction: \"discovery\",\n\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tmetadata: { rounds, completed: true },\n\t\t});\n\n\t\t// 6. Extract and save requirements.md\n\t\tconst usage = aggregateUsage(result.messages);\n\t\tconst content = extractArtifactContent(response, \"requirements.md\", true);\n\t\tif (content) {\n\t\t\tawait store.writeRequirements(content);\n\t\t\treturn { completed: true, rounds, usage };\n\t\t}\n\n\t\treturn { completed: false, rounds, usage };\n\t} catch (error) {\n\t\t// Interruption by agent.abort(): \"Request was aborted\" error\n\t\tconst msg = error instanceof Error ? error.message : String(error);\n\t\tif (msg.includes(\"aborted\")) {\n\t\t\treturn { completed: false, rounds };\n\t\t}\n\t\tthrow error;\n\t} finally {\n\t\toptions.onAgentFinished?.();\n\t}\n}\n\n// ─── Prompt Builder ──────────────────────────────────────────────────────────\n\nfunction buildDiscoveryPrompt(requirement: string, projectContext?: string, skipIfClear?: boolean): string {\n\tconst parts: string[] = [];\n\n\tparts.push(\"## User Requirement\");\n\tparts.push(\"\");\n\tparts.push(requirement);\n\n\tif (projectContext) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Project Context\");\n\t\tparts.push(\"\");\n\t\tparts.push(projectContext);\n\t}\n\n\tparts.push(\"\");\n\tparts.push(\"## Instructions\");\n\tparts.push(\"\");\n\n\tif (skipIfClear) {\n\t\tparts.push(\n\t\t\t\"If the requirement above is already clear and specific enough to implement, \" +\n\t\t\t\t\"skip questions and write requirements.md immediately. \" +\n\t\t\t\t\"Only ask questions if there are genuine ambiguities or missing information.\",\n\t\t);\n\t} else {\n\t\tparts.push(\"Analyze the requirement and ask clarifying questions if needed.\");\n\t}\n\n\tparts.push(\"\");\n\tparts.push(\n\t\t\"Remember: end with [QUESTIONS] if you have questions, or output ```requirements.md ... ``` followed by [REQUIREMENTS_COMPLETE] when done.\",\n\t);\n\n\treturn parts.join(\"\\n\");\n}\n"]}
|
package/dist/discovery.js
CHANGED
package/dist/discovery.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent, AgentEvent, AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { GetApiKeyFn } from \"./agent-factory.js\";\nimport { createRoleAgent, filterSerializableMessages, runAgentWithHistory } from \"./agent-factory.js\";\nimport { getSystemPromptForRole } from \"./roles/index.js\";\nimport { aggregateUsage, extractArtifactContent } from \"./step-executor.js\";\nimport type { VibeStore } from \"./store.js\";\nimport type { VibeConfig } from \"./types.js\";\n\n// ─── Markers ─────────────────────────────────────────────────────────────────\n\n/** Marker indicating the Discovery Agent has output questions */\nexport const QUESTION_MARKER = \"[QUESTIONS]\";\n\n/** Marker indicating the Discovery Agent has completed requirements.md */\nexport const COMPLETE_MARKER = \"[REQUIREMENTS_COMPLETE]\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Discovery execution options */\nexport interface DiscoveryOptions {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\trequirement: string;\n\t/** Function to receive user input. Returns undefined to cancel. */\n\trequestUserInput: (questions: string) => Promise<string | undefined>;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Agent event callback. Used for progress display, etc. */\n\tonAgentEvent?: (event: AgentEvent) => void;\n\t/** Callback to relay agent messages externally */\n\tonMessage?: (message: string) => void;\n\t/** User feedback on rejection. Applied when regenerating existing requirements.md. */\n\tfeedback?: string;\n\t/** Lightweight skill index. Included in the agent system prompt. */\n\tavailableSkills?: string;\n\t/** Callback invoked when the agent is created. Used for abort wiring, etc. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Callback invoked when the agent finishes execution. */\n\tonAgentFinished?: () => void;\n}\n\n/** Discovery execution result */\nexport interface DiscoveryResult {\n\t/** Whether requirements.md was generated */\n\tcompleted: boolean;\n\t/** Number of question rounds performed */\n\trounds: number;\n\t/** Aggregated token usage across all LLM calls */\n\tusage?: { input: number; output: number; cacheRead: number; cacheWrite: number; totalTokens: number; cost: number };\n}\n\n// ─── Discovery Runner ────────────────────────────────────────────────────────\n\n/**\n * Extracts question text before the question marker from the response.\n * Returns null if no marker is found.\n */\nexport function extractQuestions(response: string): string | null {\n\tconst idx = response.indexOf(QUESTION_MARKER);\n\tif (idx === -1) {\n\t\treturn null;\n\t}\n\treturn response.substring(0, idx).trim();\n}\n\n/**\n * Checks whether the response indicates requirements completion.\n */\nexport function isRequirementsComplete(response: string): boolean {\n\treturn response.includes(COMPLETE_MARKER);\n}\n\n/**\n * Runs the Discovery Agent interactively.\n *\n * 1. Load project-context.md if it exists\n * 2. Create Agent (discovery role)\n * 3. Pass requirements + project-context as the initial prompt\n * 4. If [QUESTIONS] marker in response → request user input → call agent.prompt() again\n * 5. If [REQUIREMENTS_COMPLETE] or maxRounds reached → extract requirements.md → save\n */\nexport async function runDiscovery(options: DiscoveryOptions): Promise<DiscoveryResult> {\n\tconst {\n\t\tstore,\n\t\tconfig,\n\t\tprojectRoot,\n\t\trequirement,\n\t\trequestUserInput,\n\t\tgetApiKey,\n\t\tmodel,\n\t\tonAgentEvent,\n\t\tonMessage,\n\t\tfeedback,\n\t} = options;\n\tconst maxRounds = config.discovery.maxQuestionRounds;\n\n\t// 1. Load project-context.md\n\tlet projectContext: string | undefined;\n\tif (await store.hasProjectContext()) {\n\t\tprojectContext = await store.readProjectContext();\n\t}\n\n\t// 2. Check for previous checkpoint (restore on restart)\n\tlet initialMessages: AgentMessage[] | undefined;\n\tlet rounds = 0;\n\n\tconst previousCheckpoint = await store.loadGlobalAgentHistory(\"discovery\", \"discovery\");\n\tif (previousCheckpoint) {\n\t\tinitialMessages = previousCheckpoint.messages;\n\t\trounds = (previousCheckpoint.metadata?.rounds as number) ?? 0;\n\t\tonMessage?.(`[Discovery] Resuming from previous session (round ${rounds})`);\n\t}\n\n\t// 3. System prompt + Agent creation\n\tconst systemPrompt = getSystemPromptForRole(\"discovery\");\n\tconst agent = await createRoleAgent({\n\t\trole: \"discovery\",\n\t\tsystemPrompt,\n\t\tconfig,\n\t\tprojectRoot,\n\t\tmodel,\n\t\tgetApiKey,\n\t\tinitialMessages,\n\t\tavailableSkills: options.availableSkills,\n\t});\n\n\t// Notify external code that the agent has been created (for abort wiring)\n\toptions.onAgentCreated?.(agent);\n\n\t// 4. Build initial prompt (guide to continue from checkpoint on restore)\n\tlet initialPrompt: string;\n\tif (feedback) {\n\t\t// If reject feedback exists, regenerate requirements.md incorporating the feedback\n\t\tinitialPrompt =\n\t\t\t`The previous requirements.md was rejected with the following feedback:\\n\\n${feedback}\\n\\n` +\n\t\t\t\"Please revise the requirements based on this feedback. Ask additional questions if needed, \" +\n\t\t\t\"then output the revised requirements.md followed by [REQUIREMENTS_COMPLETE].\";\n\t} else if (previousCheckpoint) {\n\t\tinitialPrompt =\n\t\t\t\"Continue the requirements discovery from where we left off. If you have more questions, ask them. If you have enough information, write requirements.md.\";\n\t} else {\n\t\tinitialPrompt = buildDiscoveryPrompt(requirement, projectContext, config.discovery.skipIfClear);\n\t}\n\n\t// 5. Conversation loop\n\ttry {\n\t\tconst eventOptions = onAgentEvent ? { onEvent: onAgentEvent } : undefined;\n\t\tlet result = await runAgentWithHistory(agent, initialPrompt, eventOptions);\n\t\tlet response = result.text;\n\n\t\twhile (rounds < maxRounds) {\n\t\t\tonMessage?.(response);\n\n\t\t\t// Save checkpoint (every round)\n\t\t\tawait store.saveGlobalAgentHistory({\n\t\t\t\trole: \"discovery\",\n\t\t\t\taction: \"discovery\",\n\t\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\tmetadata: { rounds },\n\t\t\t});\n\n\t\t\t// Check requirements completion\n\t\t\tif (isRequirementsComplete(response)) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Check for question marker\n\t\t\tconst questions = extractQuestions(response);\n\t\t\tif (!questions) {\n\t\t\t\t// No marker and not complete — treat the entire response as requirements\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Request user input\n\t\t\tconst userAnswer = await requestUserInput(questions);\n\t\t\tif (userAnswer === undefined) {\n\t\t\t\t// User cancelled — checkpoint already saved\n\t\t\t\treturn { completed: false, rounds };\n\t\t\t}\n\n\t\t\trounds++;\n\n\t\t\t// Pass the answer to the agent\n\t\t\tresult = await runAgentWithHistory(agent, userAnswer, eventOptions);\n\t\t\tresponse = result.text;\n\t\t}\n\n\t\t// After maxRounds reached or loop exit: force completion if no completion marker\n\t\tconst hasQuestionMarker = response.includes(QUESTION_MARKER);\n\t\tif (\n\t\t\t!isRequirementsComplete(response) &&\n\t\t\t(hasQuestionMarker || !extractArtifactContent(response, \"requirements.md\", false))\n\t\t) {\n\t\t\tonMessage?.(\"[Discovery] Finalizing requirements...\");\n\t\t\tresult = await runAgentWithHistory(\n\t\t\t\tagent,\n\t\t\t\t\"Please finalize the requirements.md now with the information gathered so far. Output the document in a ```requirements.md code block followed by [REQUIREMENTS_COMPLETE].\",\n\t\t\t\teventOptions,\n\t\t\t);\n\t\t\tresponse = result.text;\n\t\t\tonMessage?.(response);\n\t\t}\n\n\t\t// Save final checkpoint\n\t\tawait store.saveGlobalAgentHistory({\n\t\t\trole: \"discovery\",\n\t\t\taction: \"discovery\",\n\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tmetadata: { rounds, completed: true },\n\t\t});\n\n\t\t// 6. Extract and save requirements.md\n\t\tconst usage = aggregateUsage(result.messages);\n\t\tconst content = extractArtifactContent(response, \"requirements.md\", true);\n\t\tif (content) {\n\t\t\tawait store.writeRequirements(content);\n\t\t\treturn { completed: true, rounds, usage };\n\t\t}\n\n\t\treturn { completed: false, rounds, usage };\n\t} catch (error) {\n\t\t// Interruption by agent.abort(): \"Request was aborted\" error\n\t\tconst msg = error instanceof Error ? error.message : String(error);\n\t\tif (msg.includes(\"aborted\")) {\n\t\t\treturn { completed: false, rounds };\n\t\t}\n\t\tthrow error;\n\t} finally {\n\t\toptions.onAgentFinished?.();\n\t}\n}\n\n// ─── Prompt Builder ──────────────────────────────────────────────────────────\n\nfunction buildDiscoveryPrompt(requirement: string, projectContext?: string, skipIfClear?: boolean): string {\n\tconst parts: string[] = [];\n\n\tparts.push(\"## User Requirement\");\n\tparts.push(\"\");\n\tparts.push(requirement);\n\n\tif (projectContext) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Project Context\");\n\t\tparts.push(\"\");\n\t\tparts.push(projectContext);\n\t}\n\n\tparts.push(\"\");\n\tparts.push(\"## Instructions\");\n\tparts.push(\"\");\n\n\tif (skipIfClear) {\n\t\tparts.push(\n\t\t\t\"If the requirement above is already clear and specific enough to implement, \" +\n\t\t\t\t\"skip questions and write requirements.md immediately. \" +\n\t\t\t\t\"Only ask questions if there are genuine ambiguities or missing information.\",\n\t\t);\n\t} else {\n\t\tparts.push(\"Analyze the requirement and ask clarifying questions if needed.\");\n\t}\n\n\tparts.push(\"\");\n\tparts.push(\n\t\t\"Remember: end with [QUESTIONS] if you have questions, or output ```requirements.md ... ``` followed by [REQUIREMENTS_COMPLETE] when done.\",\n\t);\n\n\treturn parts.join(\"\\n\");\n}\n"]}
|
|
1
|
+
{"version":3,"file":"discovery.js","sourceRoot":"","sources":["../src/discovery.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Agent, AgentEvent, AgentMessage } from \"@mariozechner/pi-agent-core\";\nimport type { Model } from \"@mariozechner/pi-ai\";\nimport type { GetApiKeyFn } from \"./agent-factory.js\";\nimport { createRoleAgent, filterSerializableMessages, runAgentWithHistory } from \"./agent-factory.js\";\nimport { getSystemPromptForRole } from \"./roles/index.js\";\nimport { aggregateUsage, extractArtifactContent } from \"./step-executor.js\";\nimport type { VibeStore } from \"./store.js\";\nimport type { VibeConfig } from \"./types.js\";\n\n// ─── Markers ─────────────────────────────────────────────────────────────────\n\n/** Marker indicating the Discovery Agent has output questions */\nexport const QUESTION_MARKER = \"[QUESTIONS]\";\n\n/** Marker indicating the Discovery Agent has completed requirements.md */\nexport const COMPLETE_MARKER = \"[REQUIREMENTS_COMPLETE]\";\n\n// ─── Types ───────────────────────────────────────────────────────────────────\n\n/** Discovery execution options */\nexport interface DiscoveryOptions {\n\tstore: VibeStore;\n\tconfig: VibeConfig;\n\tprojectRoot: string;\n\trequirement: string;\n\t/** Function to receive user input. Returns undefined to cancel. */\n\trequestUserInput: (questions: string) => Promise<string | undefined>;\n\tgetApiKey?: GetApiKeyFn;\n\t/** Model to use. Uses the Agent's default model if not specified. */\n\tmodel?: Model<any>;\n\t/** Agent event callback. Used for progress display, etc. */\n\tonAgentEvent?: (event: AgentEvent) => void;\n\t/** Callback to relay agent messages externally */\n\tonMessage?: (message: string) => void;\n\t/** User feedback on rejection. Applied when regenerating existing requirements.md. */\n\tfeedback?: string;\n\t/** Callback invoked when the agent is created. Used for abort wiring, etc. */\n\tonAgentCreated?: (agent: Agent) => void;\n\t/** Callback invoked when the agent finishes execution. */\n\tonAgentFinished?: () => void;\n}\n\n/** Discovery execution result */\nexport interface DiscoveryResult {\n\t/** Whether requirements.md was generated */\n\tcompleted: boolean;\n\t/** Number of question rounds performed */\n\trounds: number;\n\t/** Aggregated token usage across all LLM calls */\n\tusage?: { input: number; output: number; cacheRead: number; cacheWrite: number; totalTokens: number; cost: number };\n}\n\n// ─── Discovery Runner ────────────────────────────────────────────────────────\n\n/**\n * Extracts question text before the question marker from the response.\n * Returns null if no marker is found.\n */\nexport function extractQuestions(response: string): string | null {\n\tconst idx = response.indexOf(QUESTION_MARKER);\n\tif (idx === -1) {\n\t\treturn null;\n\t}\n\treturn response.substring(0, idx).trim();\n}\n\n/**\n * Checks whether the response indicates requirements completion.\n */\nexport function isRequirementsComplete(response: string): boolean {\n\treturn response.includes(COMPLETE_MARKER);\n}\n\n/**\n * Runs the Discovery Agent interactively.\n *\n * 1. Load project-context.md if it exists\n * 2. Create Agent (discovery role)\n * 3. Pass requirements + project-context as the initial prompt\n * 4. If [QUESTIONS] marker in response → request user input → call agent.prompt() again\n * 5. If [REQUIREMENTS_COMPLETE] or maxRounds reached → extract requirements.md → save\n */\nexport async function runDiscovery(options: DiscoveryOptions): Promise<DiscoveryResult> {\n\tconst {\n\t\tstore,\n\t\tconfig,\n\t\tprojectRoot,\n\t\trequirement,\n\t\trequestUserInput,\n\t\tgetApiKey,\n\t\tmodel,\n\t\tonAgentEvent,\n\t\tonMessage,\n\t\tfeedback,\n\t} = options;\n\tconst maxRounds = config.discovery.maxQuestionRounds;\n\n\t// 1. Load project-context.md\n\tlet projectContext: string | undefined;\n\tif (await store.hasProjectContext()) {\n\t\tprojectContext = await store.readProjectContext();\n\t}\n\n\t// 2. Check for previous checkpoint (restore on restart)\n\tlet initialMessages: AgentMessage[] | undefined;\n\tlet rounds = 0;\n\n\tconst previousCheckpoint = await store.loadGlobalAgentHistory(\"discovery\", \"discovery\");\n\tif (previousCheckpoint) {\n\t\tinitialMessages = previousCheckpoint.messages;\n\t\trounds = (previousCheckpoint.metadata?.rounds as number) ?? 0;\n\t\tonMessage?.(`[Discovery] Resuming from previous session (round ${rounds})`);\n\t}\n\n\t// 3. System prompt + Agent creation\n\tconst systemPrompt = getSystemPromptForRole(\"discovery\");\n\tconst agent = await createRoleAgent({\n\t\trole: \"discovery\",\n\t\tsystemPrompt,\n\t\tconfig,\n\t\tprojectRoot,\n\t\tmodel,\n\t\tgetApiKey,\n\t\tinitialMessages,\n\t});\n\n\t// Notify external code that the agent has been created (for abort wiring)\n\toptions.onAgentCreated?.(agent);\n\n\t// 4. Build initial prompt (guide to continue from checkpoint on restore)\n\tlet initialPrompt: string;\n\tif (feedback) {\n\t\t// If reject feedback exists, regenerate requirements.md incorporating the feedback\n\t\tinitialPrompt =\n\t\t\t`The previous requirements.md was rejected with the following feedback:\\n\\n${feedback}\\n\\n` +\n\t\t\t\"Please revise the requirements based on this feedback. Ask additional questions if needed, \" +\n\t\t\t\"then output the revised requirements.md followed by [REQUIREMENTS_COMPLETE].\";\n\t} else if (previousCheckpoint) {\n\t\tinitialPrompt =\n\t\t\t\"Continue the requirements discovery from where we left off. If you have more questions, ask them. If you have enough information, write requirements.md.\";\n\t} else {\n\t\tinitialPrompt = buildDiscoveryPrompt(requirement, projectContext, config.discovery.skipIfClear);\n\t}\n\n\t// 5. Conversation loop\n\ttry {\n\t\tconst eventOptions = onAgentEvent ? { onEvent: onAgentEvent } : undefined;\n\t\tlet result = await runAgentWithHistory(agent, initialPrompt, eventOptions);\n\t\tlet response = result.text;\n\n\t\twhile (rounds < maxRounds) {\n\t\t\tonMessage?.(response);\n\n\t\t\t// Save checkpoint (every round)\n\t\t\tawait store.saveGlobalAgentHistory({\n\t\t\t\trole: \"discovery\",\n\t\t\t\taction: \"discovery\",\n\t\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\t\ttimestamp: new Date().toISOString(),\n\t\t\t\tmetadata: { rounds },\n\t\t\t});\n\n\t\t\t// Check requirements completion\n\t\t\tif (isRequirementsComplete(response)) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Check for question marker\n\t\t\tconst questions = extractQuestions(response);\n\t\t\tif (!questions) {\n\t\t\t\t// No marker and not complete — treat the entire response as requirements\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Request user input\n\t\t\tconst userAnswer = await requestUserInput(questions);\n\t\t\tif (userAnswer === undefined) {\n\t\t\t\t// User cancelled — checkpoint already saved\n\t\t\t\treturn { completed: false, rounds };\n\t\t\t}\n\n\t\t\trounds++;\n\n\t\t\t// Pass the answer to the agent\n\t\t\tresult = await runAgentWithHistory(agent, userAnswer, eventOptions);\n\t\t\tresponse = result.text;\n\t\t}\n\n\t\t// After maxRounds reached or loop exit: force completion if no completion marker\n\t\tconst hasQuestionMarker = response.includes(QUESTION_MARKER);\n\t\tif (\n\t\t\t!isRequirementsComplete(response) &&\n\t\t\t(hasQuestionMarker || !extractArtifactContent(response, \"requirements.md\", false))\n\t\t) {\n\t\t\tonMessage?.(\"[Discovery] Finalizing requirements...\");\n\t\t\tresult = await runAgentWithHistory(\n\t\t\t\tagent,\n\t\t\t\t\"Please finalize the requirements.md now with the information gathered so far. Output the document in a ```requirements.md code block followed by [REQUIREMENTS_COMPLETE].\",\n\t\t\t\teventOptions,\n\t\t\t);\n\t\t\tresponse = result.text;\n\t\t\tonMessage?.(response);\n\t\t}\n\n\t\t// Save final checkpoint\n\t\tawait store.saveGlobalAgentHistory({\n\t\t\trole: \"discovery\",\n\t\t\taction: \"discovery\",\n\t\t\tmessages: filterSerializableMessages(result.messages),\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tmetadata: { rounds, completed: true },\n\t\t});\n\n\t\t// 6. Extract and save requirements.md\n\t\tconst usage = aggregateUsage(result.messages);\n\t\tconst content = extractArtifactContent(response, \"requirements.md\", true);\n\t\tif (content) {\n\t\t\tawait store.writeRequirements(content);\n\t\t\treturn { completed: true, rounds, usage };\n\t\t}\n\n\t\treturn { completed: false, rounds, usage };\n\t} catch (error) {\n\t\t// Interruption by agent.abort(): \"Request was aborted\" error\n\t\tconst msg = error instanceof Error ? error.message : String(error);\n\t\tif (msg.includes(\"aborted\")) {\n\t\t\treturn { completed: false, rounds };\n\t\t}\n\t\tthrow error;\n\t} finally {\n\t\toptions.onAgentFinished?.();\n\t}\n}\n\n// ─── Prompt Builder ──────────────────────────────────────────────────────────\n\nfunction buildDiscoveryPrompt(requirement: string, projectContext?: string, skipIfClear?: boolean): string {\n\tconst parts: string[] = [];\n\n\tparts.push(\"## User Requirement\");\n\tparts.push(\"\");\n\tparts.push(requirement);\n\n\tif (projectContext) {\n\t\tparts.push(\"\");\n\t\tparts.push(\"## Project Context\");\n\t\tparts.push(\"\");\n\t\tparts.push(projectContext);\n\t}\n\n\tparts.push(\"\");\n\tparts.push(\"## Instructions\");\n\tparts.push(\"\");\n\n\tif (skipIfClear) {\n\t\tparts.push(\n\t\t\t\"If the requirement above is already clear and specific enough to implement, \" +\n\t\t\t\t\"skip questions and write requirements.md immediately. \" +\n\t\t\t\t\"Only ask questions if there are genuine ambiguities or missing information.\",\n\t\t);\n\t} else {\n\t\tparts.push(\"Analyze the requirement and ask clarifying questions if needed.\");\n\t}\n\n\tparts.push(\"\");\n\tparts.push(\n\t\t\"Remember: end with [QUESTIONS] if you have questions, or output ```requirements.md ... ``` followed by [REQUIREMENTS_COMPLETE] when done.\",\n\t);\n\n\treturn parts.join(\"\\n\");\n}\n"]}
|