@dynamicworks/br-openspec 1.3.1 → 2.0.1

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.
Files changed (72) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +210 -210
  3. package/README.pt-BR.md +212 -212
  4. package/bin/openspec.js +2 -2
  5. package/dist/commands/feedback.js +4 -4
  6. package/dist/commands/schema.js +60 -60
  7. package/dist/core/artifact-graph/instruction-loader.js +4 -4
  8. package/dist/core/artifact-graph/schema.js +5 -4
  9. package/dist/core/command-generation/adapters/amazon-q.js +5 -5
  10. package/dist/core/command-generation/adapters/antigravity.js +5 -5
  11. package/dist/core/command-generation/adapters/auggie.js +6 -6
  12. package/dist/core/command-generation/adapters/bob.js +6 -6
  13. package/dist/core/command-generation/adapters/claude.js +8 -8
  14. package/dist/core/command-generation/adapters/cline.js +5 -5
  15. package/dist/core/command-generation/adapters/codebuddy.js +7 -7
  16. package/dist/core/command-generation/adapters/codex.js +6 -6
  17. package/dist/core/command-generation/adapters/continue.js +7 -7
  18. package/dist/core/command-generation/adapters/costrict.js +6 -6
  19. package/dist/core/command-generation/adapters/crush.js +8 -8
  20. package/dist/core/command-generation/adapters/cursor.js +8 -8
  21. package/dist/core/command-generation/adapters/factory.js +6 -6
  22. package/dist/core/command-generation/adapters/gemini.js +5 -5
  23. package/dist/core/command-generation/adapters/github-copilot.js +5 -5
  24. package/dist/core/command-generation/adapters/iflow.js +8 -8
  25. package/dist/core/command-generation/adapters/junie.js +5 -5
  26. package/dist/core/command-generation/adapters/kilocode.js +1 -1
  27. package/dist/core/command-generation/adapters/kiro.js +5 -5
  28. package/dist/core/command-generation/adapters/lingma.js +8 -8
  29. package/dist/core/command-generation/adapters/opencode.js +5 -5
  30. package/dist/core/command-generation/adapters/pi.js +5 -5
  31. package/dist/core/command-generation/adapters/qoder.js +8 -8
  32. package/dist/core/command-generation/adapters/qwen.js +5 -5
  33. package/dist/core/command-generation/adapters/roocode.js +5 -5
  34. package/dist/core/command-generation/adapters/windsurf.js +8 -8
  35. package/dist/core/completions/factory.js +3 -2
  36. package/dist/core/completions/generators/bash-generator.js +41 -41
  37. package/dist/core/completions/generators/fish-generator.js +7 -7
  38. package/dist/core/completions/generators/powershell-generator.js +29 -29
  39. package/dist/core/completions/generators/zsh-generator.js +33 -33
  40. package/dist/core/completions/installers/fish-installer.js +13 -12
  41. package/dist/core/completions/installers/powershell-installer.js +16 -17
  42. package/dist/core/completions/installers/zsh-installer.js +1 -1
  43. package/dist/core/completions/templates/bash-templates.js +18 -18
  44. package/dist/core/completions/templates/fish-templates.js +32 -32
  45. package/dist/core/completions/templates/powershell-templates.js +19 -19
  46. package/dist/core/completions/templates/zsh-templates.js +30 -30
  47. package/dist/core/parsers/change-parser.js +7 -6
  48. package/dist/core/project-config.js +12 -13
  49. package/dist/core/shared/skill-generation.js +12 -12
  50. package/dist/core/specs-apply.js +37 -38
  51. package/dist/core/templates/workflows/apply-change.js +288 -288
  52. package/dist/core/templates/workflows/archive-change.js +251 -251
  53. package/dist/core/templates/workflows/bulk-archive-change.js +472 -472
  54. package/dist/core/templates/workflows/continue-change.js +212 -212
  55. package/dist/core/templates/workflows/explore.js +443 -443
  56. package/dist/core/templates/workflows/feedback.js +97 -97
  57. package/dist/core/templates/workflows/ff-change.js +178 -178
  58. package/dist/core/templates/workflows/propose.js +196 -196
  59. package/dist/core/templates/workflows/sync-specs.js +252 -252
  60. package/dist/core/templates/workflows/upstream-sync.js +93 -93
  61. package/dist/core/tools-manager.js +2 -2
  62. package/dist/messages/index.d.ts +111 -0
  63. package/dist/messages/index.js +1115 -977
  64. package/dist/utils/change-metadata.js +8 -7
  65. package/dist/utils/change-utils.js +12 -11
  66. package/package.json +82 -84
  67. package/schemas/spec-driven/schema.yaml +153 -153
  68. package/schemas/spec-driven/templates/design.md +19 -19
  69. package/schemas/spec-driven/templates/proposal.md +23 -23
  70. package/schemas/spec-driven/templates/spec.md +8 -8
  71. package/schemas/spec-driven/templates/tasks.md +9 -9
  72. package/scripts/postinstall.js +83 -83
@@ -4,6 +4,7 @@ import * as yaml from 'yaml';
4
4
  import { ChangeMetadataSchema } from '../core/artifact-graph/types.js';
5
5
  import { listSchemas } from '../core/artifact-graph/resolver.js';
6
6
  import { readProjectConfig } from '../core/project-config.js';
7
+ import { CHANGE_METADATA_MESSAGES } from '../messages/index.js';
7
8
  const METADATA_FILENAME = '.openspec.yaml';
8
9
  /**
9
10
  * Error thrown when change metadata validation fails.
@@ -29,7 +30,7 @@ export class ChangeMetadataError extends Error {
29
30
  export function validateSchemaName(schemaName, projectRoot) {
30
31
  const availableSchemas = listSchemas(projectRoot);
31
32
  if (!availableSchemas.includes(schemaName)) {
32
- throw new Error(`Unknown schema '${schemaName}'. Available: ${availableSchemas.join(', ')}`);
33
+ throw new Error(CHANGE_METADATA_MESSAGES.unknownSchema(schemaName, availableSchemas.join(', ')));
33
34
  }
34
35
  return schemaName;
35
36
  }
@@ -48,7 +49,7 @@ export function writeChangeMetadata(changeDir, metadata, projectRoot) {
48
49
  // Validate with Zod
49
50
  const parseResult = ChangeMetadataSchema.safeParse(metadata);
50
51
  if (!parseResult.success) {
51
- throw new ChangeMetadataError(`Invalid metadata: ${parseResult.error.message}`, metaPath);
52
+ throw new ChangeMetadataError(CHANGE_METADATA_MESSAGES.invalidMetadata(parseResult.error.message), metaPath);
52
53
  }
53
54
  // Write YAML file
54
55
  const content = yaml.stringify(parseResult.data);
@@ -57,7 +58,7 @@ export function writeChangeMetadata(changeDir, metadata, projectRoot) {
57
58
  }
58
59
  catch (err) {
59
60
  const ioError = err instanceof Error ? err : new Error(String(err));
60
- throw new ChangeMetadataError(`Failed to write metadata: ${ioError.message}`, metaPath, ioError);
61
+ throw new ChangeMetadataError(CHANGE_METADATA_MESSAGES.failedToWriteMetadata(ioError.message), metaPath, ioError);
61
62
  }
62
63
  }
63
64
  /**
@@ -79,7 +80,7 @@ export function readChangeMetadata(changeDir, projectRoot) {
79
80
  }
80
81
  catch (err) {
81
82
  const ioError = err instanceof Error ? err : new Error(String(err));
82
- throw new ChangeMetadataError(`Failed to read metadata: ${ioError.message}`, metaPath, ioError);
83
+ throw new ChangeMetadataError(CHANGE_METADATA_MESSAGES.failedToReadMetadata(ioError.message), metaPath, ioError);
83
84
  }
84
85
  let parsed;
85
86
  try {
@@ -87,17 +88,17 @@ export function readChangeMetadata(changeDir, projectRoot) {
87
88
  }
88
89
  catch (err) {
89
90
  const parseError = err instanceof Error ? err : new Error(String(err));
90
- throw new ChangeMetadataError(`Invalid YAML in metadata file: ${parseError.message}`, metaPath, parseError);
91
+ throw new ChangeMetadataError(CHANGE_METADATA_MESSAGES.invalidYaml(parseError.message), metaPath, parseError);
91
92
  }
92
93
  // Validate with Zod
93
94
  const parseResult = ChangeMetadataSchema.safeParse(parsed);
94
95
  if (!parseResult.success) {
95
- throw new ChangeMetadataError(`Invalid metadata: ${parseResult.error.message}`, metaPath);
96
+ throw new ChangeMetadataError(CHANGE_METADATA_MESSAGES.invalidMetadata(parseResult.error.message), metaPath);
96
97
  }
97
98
  // Validate that the schema exists
98
99
  const availableSchemas = listSchemas(projectRoot);
99
100
  if (!availableSchemas.includes(parseResult.data.schema)) {
100
- throw new ChangeMetadataError(`Unknown schema '${parseResult.data.schema}'. Available: ${availableSchemas.join(', ')}`, metaPath);
101
+ throw new ChangeMetadataError(CHANGE_METADATA_MESSAGES.unknownSchema(parseResult.data.schema, availableSchemas.join(', ')), metaPath);
101
102
  }
102
103
  return parseResult.data;
103
104
  }
@@ -2,6 +2,7 @@ import path from 'path';
2
2
  import { FileSystemUtils } from './file-system.js';
3
3
  import { writeChangeMetadata, validateSchemaName } from './change-metadata.js';
4
4
  import { readProjectConfig } from '../core/project-config.js';
5
+ import { CHANGE_UTILS_MESSAGES } from '../messages/index.js';
5
6
  const DEFAULT_SCHEMA = 'spec-driven';
6
7
  /**
7
8
  * Validates that a change name follows kebab-case conventions.
@@ -24,35 +25,35 @@ export function validateChangeName(name) {
24
25
  // optionally followed by hyphen + lowercase letters/numbers (repeatable)
25
26
  const kebabCasePattern = /^[a-z][a-z0-9]*(-[a-z0-9]+)*$/;
26
27
  if (!name) {
27
- return { valid: false, error: 'Change name cannot be empty' };
28
+ return { valid: false, error: CHANGE_UTILS_MESSAGES.nameEmpty };
28
29
  }
29
30
  if (!kebabCasePattern.test(name)) {
30
31
  // Provide specific error messages for common mistakes
31
32
  if (/[A-Z]/.test(name)) {
32
- return { valid: false, error: 'Change name must be lowercase (use kebab-case)' };
33
+ return { valid: false, error: CHANGE_UTILS_MESSAGES.nameMustBeLowercase };
33
34
  }
34
35
  if (/\s/.test(name)) {
35
- return { valid: false, error: 'Change name cannot contain spaces (use hyphens instead)' };
36
+ return { valid: false, error: CHANGE_UTILS_MESSAGES.nameNoSpaces };
36
37
  }
37
38
  if (/_/.test(name)) {
38
- return { valid: false, error: 'Change name cannot contain underscores (use hyphens instead)' };
39
+ return { valid: false, error: CHANGE_UTILS_MESSAGES.nameNoUnderscores };
39
40
  }
40
41
  if (name.startsWith('-')) {
41
- return { valid: false, error: 'Change name cannot start with a hyphen' };
42
+ return { valid: false, error: CHANGE_UTILS_MESSAGES.nameNoStartHyphen };
42
43
  }
43
44
  if (name.endsWith('-')) {
44
- return { valid: false, error: 'Change name cannot end with a hyphen' };
45
+ return { valid: false, error: CHANGE_UTILS_MESSAGES.nameNoEndHyphen };
45
46
  }
46
47
  if (/--/.test(name)) {
47
- return { valid: false, error: 'Change name cannot contain consecutive hyphens' };
48
+ return { valid: false, error: CHANGE_UTILS_MESSAGES.nameNoConsecutiveHyphens };
48
49
  }
49
50
  if (/[^a-z0-9-]/.test(name)) {
50
- return { valid: false, error: 'Change name can only contain lowercase letters, numbers, and hyphens' };
51
+ return { valid: false, error: CHANGE_UTILS_MESSAGES.nameOnlyAllowedChars };
51
52
  }
52
53
  if (/^[0-9]/.test(name)) {
53
- return { valid: false, error: 'Change name must start with a letter' };
54
+ return { valid: false, error: CHANGE_UTILS_MESSAGES.nameMustStartWithLetter };
54
55
  }
55
- return { valid: false, error: 'Change name must follow kebab-case convention (e.g., add-auth, refactor-db)' };
56
+ return { valid: false, error: CHANGE_UTILS_MESSAGES.nameKebabCase };
56
57
  }
57
58
  return { valid: true };
58
59
  }
@@ -106,7 +107,7 @@ export async function createChange(projectRoot, name, options = {}) {
106
107
  const changeDir = path.join(projectRoot, 'openspec', 'changes', name);
107
108
  // Check if change already exists
108
109
  if (await FileSystemUtils.directoryExists(changeDir)) {
109
- throw new Error(`Change '${name}' already exists at ${changeDir}`);
110
+ throw new Error(CHANGE_UTILS_MESSAGES.changeAlreadyExists(name, changeDir));
110
111
  }
111
112
  // Create the directory (including parent directories if needed)
112
113
  await FileSystemUtils.createDirectory(changeDir);
package/package.json CHANGED
@@ -1,84 +1,82 @@
1
- {
2
- "name": "@dynamicworks/br-openspec",
3
- "version": "1.3.1",
4
- "description": "AI-native system for spec-driven development",
5
- "keywords": [
6
- "openspec",
7
- "specs",
8
- "cli",
9
- "ai",
10
- "development"
11
- ],
12
- "homepage": "https://github.com/dynamicworks-com-br/BR-OpenSpec",
13
- "repository": {
14
- "type": "git",
15
- "url": "https://github.com/dynamicworks-com-br/BR-OpenSpec"
16
- },
17
- "license": "MIT",
18
- "author": "BR-OpenSpec Contributors",
19
- "type": "module",
20
- "publishConfig": {
21
- "access": "public"
22
- },
23
- "exports": {
24
- ".": {
25
- "types": "./dist/index.d.ts",
26
- "default": "./dist/index.js"
27
- }
28
- },
29
- "bin": {
30
- "openspec": "./bin/openspec.js"
31
- },
32
- "files": [
33
- "dist",
34
- "bin",
35
- "schemas",
36
- "scripts/postinstall.js",
37
- "!dist/**/*.test.js",
38
- "!dist/**/__tests__",
39
- "!dist/**/*.map"
40
- ],
41
- "scripts": {
42
- "lint": "eslint src/",
43
- "build": "node build.js",
44
- "dev": "tsc --watch",
45
- "dev:cli": "node build.js && node bin/openspec.js",
46
- "test": "vitest run",
47
- "test:watch": "vitest",
48
- "test:ui": "vitest --ui",
49
- "test:coverage": "vitest --coverage",
50
- "test:postinstall": "node scripts/postinstall.js",
51
- "prepare": "node build.js",
52
- "prepublishOnly": "node build.js",
53
- "postinstall": "node scripts/postinstall.js",
54
- "check:pack-version": "node scripts/pack-version-check.mjs",
55
- "release": "pnpm run release:ci",
56
- "release:ci": "pnpm run check:pack-version && pnpm exec changeset publish",
57
- "changeset": "changeset"
58
- },
59
- "engines": {
60
- "node": ">=20.19.0"
61
- },
62
- "devDependencies": {
63
- "@changesets/changelog-github": "^0.5.2",
64
- "@changesets/cli": "^2.27.7",
65
- "@types/node": "^24.2.0",
66
- "@vitest/coverage-v8": "^3.2.4",
67
- "@vitest/ui": "^3.2.4",
68
- "eslint": "^9.39.2",
69
- "typescript": "^5.9.3",
70
- "typescript-eslint": "^8.50.1",
71
- "vitest": "^3.2.4"
72
- },
73
- "dependencies": {
74
- "@inquirer/core": "^10.2.2",
75
- "@inquirer/prompts": "^7.8.0",
76
- "chalk": "^5.5.0",
77
- "commander": "^14.0.0",
78
- "fast-glob": "^3.3.3",
79
- "ora": "^8.2.0",
80
- "posthog-node": "^5.20.0",
81
- "yaml": "^2.8.3",
82
- "zod": "^4.0.17"
83
- }
84
- }
1
+ {
2
+ "name": "@dynamicworks/br-openspec",
3
+ "version": "2.0.1",
4
+ "description": "AI-native system for spec-driven development",
5
+ "keywords": [
6
+ "openspec",
7
+ "specs",
8
+ "cli",
9
+ "ai",
10
+ "development"
11
+ ],
12
+ "homepage": "https://github.com/dynamicworks-com-br/BR-OpenSpec",
13
+ "repository": {
14
+ "type": "git",
15
+ "url": "https://github.com/dynamicworks-com-br/BR-OpenSpec"
16
+ },
17
+ "license": "MIT",
18
+ "author": "BR-OpenSpec Contributors",
19
+ "type": "module",
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "exports": {
24
+ ".": {
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
+ }
28
+ },
29
+ "bin": {
30
+ "openspec": "./bin/openspec.js"
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "bin",
35
+ "schemas",
36
+ "scripts/postinstall.js",
37
+ "!dist/**/*.test.js",
38
+ "!dist/**/__tests__",
39
+ "!dist/**/*.map"
40
+ ],
41
+ "engines": {
42
+ "node": ">=20.19.0"
43
+ },
44
+ "devDependencies": {
45
+ "@changesets/changelog-github": "^0.5.2",
46
+ "@changesets/cli": "^2.27.7",
47
+ "@types/node": "^24.2.0",
48
+ "@vitest/coverage-v8": "^3.2.4",
49
+ "@vitest/ui": "^3.2.4",
50
+ "eslint": "^9.39.2",
51
+ "typescript": "^5.9.3",
52
+ "typescript-eslint": "^8.50.1",
53
+ "vitest": "^3.2.4"
54
+ },
55
+ "dependencies": {
56
+ "@inquirer/core": "^10.2.2",
57
+ "@inquirer/prompts": "^7.8.0",
58
+ "chalk": "^5.5.0",
59
+ "commander": "^14.0.0",
60
+ "fast-glob": "^3.3.3",
61
+ "ora": "^8.2.0",
62
+ "posthog-node": "^5.20.0",
63
+ "yaml": "^2.8.3",
64
+ "zod": "^4.0.17"
65
+ },
66
+ "scripts": {
67
+ "lint": "eslint src/",
68
+ "build": "node build.js",
69
+ "dev": "tsc --watch",
70
+ "dev:cli": "node build.js && node bin/openspec.js",
71
+ "test": "vitest run",
72
+ "test:watch": "vitest",
73
+ "test:ui": "vitest --ui",
74
+ "test:coverage": "vitest --coverage",
75
+ "test:postinstall": "node scripts/postinstall.js",
76
+ "postinstall": "node scripts/postinstall.js",
77
+ "check:pack-version": "node scripts/pack-version-check.mjs",
78
+ "release": "pnpm run release:ci",
79
+ "release:ci": "pnpm run check:pack-version && pnpm exec changeset publish",
80
+ "changeset": "changeset"
81
+ }
82
+ }
@@ -1,153 +1,153 @@
1
- name: spec-driven
2
- version: 1
3
- description: Fluxo de trabalho BR-OpenSpec padrão - proposta → specs → design → tarefas
4
- artifacts:
5
- - id: proposal
6
- generates: proposal.md
7
- description: Initial proposal document outlining the change
8
- template: proposal.md
9
- instruction: |
10
- Create the proposal document that establishes WHY this change is needed.
11
-
12
- Sections:
13
- - **Why**: 1-2 sentences on the problem or opportunity. What problem does this solve? Why now?
14
- - **What Changes**: Bullet list of changes. Be specific about new capabilities, modifications, or removals. Mark breaking changes with **BREAKING**.
15
- - **Capabilities**: Identify which specs will be created or modified:
16
- - **New Capabilities**: List capabilities being introduced. Each becomes a new `specs/<name>/spec.md`. Use kebab-case names (e.g., `user-auth`, `data-export`).
17
- - **Modified Capabilities**: List existing capabilities whose REQUIREMENTS are changing. Only include if spec-level behavior changes (not just implementation details). Each needs a delta spec file. Check `openspec/specs/` for existing spec names. Leave empty if no requirement changes.
18
- - **Impact**: Affected code, APIs, dependencies, or systems.
19
-
20
- IMPORTANT: The Capabilities section is critical. It creates the contract between
21
- proposal and specs phases. Research existing specs before filling this in.
22
- Each capability listed here will need a corresponding spec file.
23
-
24
- Keep it concise (1-2 pages). Focus on the "why" not the "how" -
25
- implementation details belong in design.md.
26
-
27
- This is the foundation - specs, design, and tasks all build on this.
28
- requires: []
29
-
30
- - id: specs
31
- generates: "specs/**/*.md"
32
- description: Detailed specifications for the change
33
- template: spec.md
34
- instruction: |
35
- Create specification files that define WHAT the system should do.
36
-
37
- Create one spec file per capability listed in the proposal's Capabilities section.
38
- - New capabilities: use the exact kebab-case name from the proposal (specs/<capability>/spec.md).
39
- - Modified capabilities: use the existing spec folder name from openspec/specs/<capability>/ when creating the delta spec at specs/<capability>/spec.md.
40
-
41
- Delta operations (use ## headers):
42
- - **ADDED Requirements**: New capabilities
43
- - **MODIFIED Requirements**: Changed behavior - MUST include full updated content
44
- - **REMOVED Requirements**: Deprecated features - MUST include **Reason** and **Migration**
45
- - **RENAMED Requirements**: Name changes only - use FROM:/TO: format
46
-
47
- Format requirements:
48
- - Each requirement: `### Requirement: <name>` followed by description
49
- - Use SHALL/MUST for normative requirements (avoid should/may)
50
- - Each scenario: `#### Scenario: <name>` with WHEN/THEN format
51
- - **CRITICAL**: Scenarios MUST use exactly 4 hashtags (`####`). Using 3 hashtags or bullets will fail silently.
52
- - Every requirement MUST have at least one scenario.
53
-
54
- MODIFIED requirements workflow:
55
- 1. Locate the existing requirement in openspec/specs/<capability>/spec.md
56
- 2. Copy the ENTIRE requirement block (from `### Requirement:` through all scenarios)
57
- 3. Paste under `## MODIFIED Requirements` and edit to reflect new behavior
58
- 4. Ensure header text matches exactly (whitespace-insensitive)
59
-
60
- Common pitfall: Using MODIFIED with partial content loses detail at archive time.
61
- If adding new concerns without changing existing behavior, use ADDED instead.
62
-
63
- Example:
64
- ```
65
- ## ADDED Requirements
66
-
67
- ### Requirement: User can export data
68
- The system SHALL allow users to export their data in CSV format.
69
-
70
- #### Scenario: Successful export
71
- - **WHEN** user clicks "Export" button
72
- - **THEN** system downloads a CSV file with all user data
73
-
74
- ## REMOVED Requirements
75
-
76
- ### Requirement: Legacy export
77
- **Reason**: Replaced by new export system
78
- **Migration**: Use new export endpoint at /api/v2/export
79
- ```
80
-
81
- Specs should be testable - each scenario is a potential test case.
82
- requires:
83
- - proposal
84
-
85
- - id: design
86
- generates: design.md
87
- description: Technical design document with implementation details
88
- template: design.md
89
- instruction: |
90
- Create the design document that explains HOW to implement the change.
91
-
92
- When to include design.md (create only if any apply):
93
- - Cross-cutting change (multiple services/modules) or new architectural pattern
94
- - New external dependency or significant data model changes
95
- - Security, performance, or migration complexity
96
- - Ambiguity that benefits from technical decisions before coding
97
-
98
- Sections:
99
- - **Context**: Background, current state, constraints, stakeholders
100
- - **Goals / Non-Goals**: What this design achieves and explicitly excludes
101
- - **Decisions**: Key technical choices with rationale (why X over Y?). Include alternatives considered for each decision.
102
- - **Risks / Trade-offs**: Known limitations, things that could go wrong. Format: [Risk] → Mitigation
103
- - **Migration Plan**: Steps to deploy, rollback strategy (if applicable)
104
- - **Open Questions**: Outstanding decisions or unknowns to resolve
105
-
106
- Focus on architecture and approach, not line-by-line implementation.
107
- Reference the proposal for motivation and specs for requirements.
108
-
109
- Good design docs explain the "why" behind technical decisions.
110
- requires:
111
- - proposal
112
-
113
- - id: tasks
114
- generates: tasks.md
115
- description: Implementation checklist with trackable tasks
116
- template: tasks.md
117
- instruction: |
118
- Create the task list that breaks down the implementation work.
119
-
120
- **IMPORTANT: Follow the template below exactly.** The apply phase parses
121
- checkbox format to track progress. Tasks not using `- [ ]` won't be tracked.
122
-
123
- Guidelines:
124
- - Group related tasks under ## numbered headings
125
- - Each task MUST be a checkbox: `- [ ] X.Y Task description`
126
- - Tasks should be small enough to complete in one session
127
- - Order tasks by dependency (what must be done first?)
128
-
129
- Example:
130
- ```
131
- ## 1. Setup
132
-
133
- - [ ] 1.1 Create new module structure
134
- - [ ] 1.2 Add dependencies to package.json
135
-
136
- ## 2. Core Implementation
137
-
138
- - [ ] 2.1 Implement data export function
139
- - [ ] 2.2 Add CSV formatting utilities
140
- ```
141
-
142
- Reference specs for what needs to be built, design for how to build it.
143
- Each task should be verifiable - you know when it's done.
144
- requires:
145
- - specs
146
- - design
147
-
148
- apply:
149
- requires: [tasks]
150
- tracks: tasks.md
151
- instruction: |
152
- Read context files, work through pending tasks, mark complete as you go.
153
- Pause if you hit blockers or need clarification.
1
+ name: spec-driven
2
+ version: 1
3
+ description: Fluxo de trabalho BR-OpenSpec padrão - proposta → specs → design → tarefas
4
+ artifacts:
5
+ - id: proposal
6
+ generates: proposal.md
7
+ description: Initial proposal document outlining the change
8
+ template: proposal.md
9
+ instruction: |
10
+ Create the proposal document that establishes WHY this change is needed.
11
+
12
+ Sections:
13
+ - **Why**: 1-2 sentences on the problem or opportunity. What problem does this solve? Why now?
14
+ - **What Changes**: Bullet list of changes. Be specific about new capabilities, modifications, or removals. Mark breaking changes with **BREAKING**.
15
+ - **Capabilities**: Identify which specs will be created or modified:
16
+ - **New Capabilities**: List capabilities being introduced. Each becomes a new `specs/<name>/spec.md`. Use kebab-case names (e.g., `user-auth`, `data-export`).
17
+ - **Modified Capabilities**: List existing capabilities whose REQUIREMENTS are changing. Only include if spec-level behavior changes (not just implementation details). Each needs a delta spec file. Check `openspec/specs/` for existing spec names. Leave empty if no requirement changes.
18
+ - **Impact**: Affected code, APIs, dependencies, or systems.
19
+
20
+ IMPORTANT: The Capabilities section is critical. It creates the contract between
21
+ proposal and specs phases. Research existing specs before filling this in.
22
+ Each capability listed here will need a corresponding spec file.
23
+
24
+ Keep it concise (1-2 pages). Focus on the "why" not the "how" -
25
+ implementation details belong in design.md.
26
+
27
+ This is the foundation - specs, design, and tasks all build on this.
28
+ requires: []
29
+
30
+ - id: specs
31
+ generates: "specs/**/*.md"
32
+ description: Detailed specifications for the change
33
+ template: spec.md
34
+ instruction: |
35
+ Create specification files that define WHAT the system should do.
36
+
37
+ Create one spec file per capability listed in the proposal's Capabilities section.
38
+ - New capabilities: use the exact kebab-case name from the proposal (specs/<capability>/spec.md).
39
+ - Modified capabilities: use the existing spec folder name from openspec/specs/<capability>/ when creating the delta spec at specs/<capability>/spec.md.
40
+
41
+ Delta operations (use ## headers):
42
+ - **ADDED Requirements**: New capabilities
43
+ - **MODIFIED Requirements**: Changed behavior - MUST include full updated content
44
+ - **REMOVED Requirements**: Deprecated features - MUST include **Reason** and **Migration**
45
+ - **RENAMED Requirements**: Name changes only - use FROM:/TO: format
46
+
47
+ Format requirements:
48
+ - Each requirement: `### Requirement: <name>` followed by description
49
+ - Use SHALL/MUST for normative requirements (avoid should/may)
50
+ - Each scenario: `#### Scenario: <name>` with WHEN/THEN format
51
+ - **CRITICAL**: Scenarios MUST use exactly 4 hashtags (`####`). Using 3 hashtags or bullets will fail silently.
52
+ - Every requirement MUST have at least one scenario.
53
+
54
+ MODIFIED requirements workflow:
55
+ 1. Locate the existing requirement in openspec/specs/<capability>/spec.md
56
+ 2. Copy the ENTIRE requirement block (from `### Requirement:` through all scenarios)
57
+ 3. Paste under `## MODIFIED Requirements` and edit to reflect new behavior
58
+ 4. Ensure header text matches exactly (whitespace-insensitive)
59
+
60
+ Common pitfall: Using MODIFIED with partial content loses detail at archive time.
61
+ If adding new concerns without changing existing behavior, use ADDED instead.
62
+
63
+ Example:
64
+ ```
65
+ ## ADDED Requirements
66
+
67
+ ### Requirement: User can export data
68
+ The system SHALL allow users to export their data in CSV format.
69
+
70
+ #### Scenario: Successful export
71
+ - **WHEN** user clicks "Export" button
72
+ - **THEN** system downloads a CSV file with all user data
73
+
74
+ ## REMOVED Requirements
75
+
76
+ ### Requirement: Legacy export
77
+ **Reason**: Replaced by new export system
78
+ **Migration**: Use new export endpoint at /api/v2/export
79
+ ```
80
+
81
+ Specs should be testable - each scenario is a potential test case.
82
+ requires:
83
+ - proposal
84
+
85
+ - id: design
86
+ generates: design.md
87
+ description: Technical design document with implementation details
88
+ template: design.md
89
+ instruction: |
90
+ Create the design document that explains HOW to implement the change.
91
+
92
+ When to include design.md (create only if any apply):
93
+ - Cross-cutting change (multiple services/modules) or new architectural pattern
94
+ - New external dependency or significant data model changes
95
+ - Security, performance, or migration complexity
96
+ - Ambiguity that benefits from technical decisions before coding
97
+
98
+ Sections:
99
+ - **Context**: Background, current state, constraints, stakeholders
100
+ - **Goals / Non-Goals**: What this design achieves and explicitly excludes
101
+ - **Decisions**: Key technical choices with rationale (why X over Y?). Include alternatives considered for each decision.
102
+ - **Risks / Trade-offs**: Known limitations, things that could go wrong. Format: [Risk] → Mitigation
103
+ - **Migration Plan**: Steps to deploy, rollback strategy (if applicable)
104
+ - **Open Questions**: Outstanding decisions or unknowns to resolve
105
+
106
+ Focus on architecture and approach, not line-by-line implementation.
107
+ Reference the proposal for motivation and specs for requirements.
108
+
109
+ Good design docs explain the "why" behind technical decisions.
110
+ requires:
111
+ - proposal
112
+
113
+ - id: tasks
114
+ generates: tasks.md
115
+ description: Implementation checklist with trackable tasks
116
+ template: tasks.md
117
+ instruction: |
118
+ Create the task list that breaks down the implementation work.
119
+
120
+ **IMPORTANT: Follow the template below exactly.** The apply phase parses
121
+ checkbox format to track progress. Tasks not using `- [ ]` won't be tracked.
122
+
123
+ Guidelines:
124
+ - Group related tasks under ## numbered headings
125
+ - Each task MUST be a checkbox: `- [ ] X.Y Task description`
126
+ - Tasks should be small enough to complete in one session
127
+ - Order tasks by dependency (what must be done first?)
128
+
129
+ Example:
130
+ ```
131
+ ## 1. Setup
132
+
133
+ - [ ] 1.1 Create new module structure
134
+ - [ ] 1.2 Add dependencies to package.json
135
+
136
+ ## 2. Core Implementation
137
+
138
+ - [ ] 2.1 Implement data export function
139
+ - [ ] 2.2 Add CSV formatting utilities
140
+ ```
141
+
142
+ Reference specs for what needs to be built, design for how to build it.
143
+ Each task should be verifiable - you know when it's done.
144
+ requires:
145
+ - specs
146
+ - design
147
+
148
+ apply:
149
+ requires: [tasks]
150
+ tracks: tasks.md
151
+ instruction: |
152
+ Read context files, work through pending tasks, mark complete as you go.
153
+ Pause if you hit blockers or need clarification.
@@ -1,19 +1,19 @@
1
- ## Context
2
-
3
- <!-- Background and current state -->
4
-
5
- ## Goals / Non-Goals
6
-
7
- **Goals:**
8
- <!-- What this design aims to achieve -->
9
-
10
- **Non-Goals:**
11
- <!-- What is explicitly out of scope -->
12
-
13
- ## Decisions
14
-
15
- <!-- Key design decisions and rationale -->
16
-
17
- ## Risks / Trade-offs
18
-
19
- <!-- Known risks and trade-offs -->
1
+ ## Context
2
+
3
+ <!-- Background and current state -->
4
+
5
+ ## Goals / Non-Goals
6
+
7
+ **Goals:**
8
+ <!-- What this design aims to achieve -->
9
+
10
+ **Non-Goals:**
11
+ <!-- What is explicitly out of scope -->
12
+
13
+ ## Decisions
14
+
15
+ <!-- Key design decisions and rationale -->
16
+
17
+ ## Risks / Trade-offs
18
+
19
+ <!-- Known risks and trade-offs -->