@comfanion/workflow 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. package/README.md +185 -0
  2. package/bin/cli.js +406 -0
  3. package/package.json +50 -0
  4. package/src/build-info.json +16 -0
  5. package/src/opencode/ARCHITECTURE.md +255 -0
  6. package/src/opencode/FLOW.yaml +900 -0
  7. package/src/opencode/agents/analyst.md +141 -0
  8. package/src/opencode/agents/architect.md +177 -0
  9. package/src/opencode/agents/change-manager.md +263 -0
  10. package/src/opencode/agents/dev.md +171 -0
  11. package/src/opencode/agents/module-docs.md +628 -0
  12. package/src/opencode/agents/pm.md +157 -0
  13. package/src/opencode/agents/researcher.md +254 -0
  14. package/src/opencode/agents/sm.md +184 -0
  15. package/src/opencode/agents/workflow-orchestrator.md +249 -0
  16. package/src/opencode/checklists/architecture-checklist.md +166 -0
  17. package/src/opencode/checklists/code-review-checklist.md +151 -0
  18. package/src/opencode/checklists/prd-checklist.md +140 -0
  19. package/src/opencode/checklists/requirements-checklist.md +86 -0
  20. package/src/opencode/checklists/story-checklist.md +137 -0
  21. package/src/opencode/commands/architecture.md +68 -0
  22. package/src/opencode/commands/archive.md +146 -0
  23. package/src/opencode/commands/change.md +169 -0
  24. package/src/opencode/commands/clarify.md +132 -0
  25. package/src/opencode/commands/code-review.md +96 -0
  26. package/src/opencode/commands/coding-standards.md +102 -0
  27. package/src/opencode/commands/dev-story.md +80 -0
  28. package/src/opencode/commands/diagram.md +152 -0
  29. package/src/opencode/commands/epics.md +52 -0
  30. package/src/opencode/commands/help.md +139 -0
  31. package/src/opencode/commands/jira-sync.md +58 -0
  32. package/src/opencode/commands/module-docs.md +158 -0
  33. package/src/opencode/commands/prd.md +63 -0
  34. package/src/opencode/commands/quick.md +166 -0
  35. package/src/opencode/commands/requirements.md +49 -0
  36. package/src/opencode/commands/research.md +113 -0
  37. package/src/opencode/commands/sprint-plan.md +59 -0
  38. package/src/opencode/commands/stories.md +61 -0
  39. package/src/opencode/commands/validate.md +84 -0
  40. package/src/opencode/commands/workflow-status.md +150 -0
  41. package/src/opencode/config.yaml +223 -0
  42. package/src/opencode/opencode.json +36 -0
  43. package/src/opencode/skills/acceptance-criteria/SKILL.md +212 -0
  44. package/src/opencode/skills/adr-writing/SKILL.md +241 -0
  45. package/src/opencode/skills/architecture-design/SKILL.md +183 -0
  46. package/src/opencode/skills/architecture-validation/SKILL.md +199 -0
  47. package/src/opencode/skills/archiving/SKILL.md +191 -0
  48. package/src/opencode/skills/changelog/SKILL.md +280 -0
  49. package/src/opencode/skills/code-review/SKILL.md +193 -0
  50. package/src/opencode/skills/coding-standards/SKILL.md +430 -0
  51. package/src/opencode/skills/diagram-creation/SKILL.md +273 -0
  52. package/src/opencode/skills/doc-todo/SKILL.md +325 -0
  53. package/src/opencode/skills/epic-writing/SKILL.md +291 -0
  54. package/src/opencode/skills/jira-integration/SKILL.md +560 -0
  55. package/src/opencode/skills/methodologies/SKILL.md +376 -0
  56. package/src/opencode/skills/module-documentation/SKILL.md +214 -0
  57. package/src/opencode/skills/prd-validation/SKILL.md +164 -0
  58. package/src/opencode/skills/prd-writing/SKILL.md +104 -0
  59. package/src/opencode/skills/requirements-gathering/SKILL.md +132 -0
  60. package/src/opencode/skills/requirements-validation/SKILL.md +141 -0
  61. package/src/opencode/skills/research-methodology/SKILL.md +140 -0
  62. package/src/opencode/skills/sprint-planning/SKILL.md +217 -0
  63. package/src/opencode/skills/story-writing/SKILL.md +574 -0
  64. package/src/opencode/skills/test-design/SKILL.md +313 -0
  65. package/src/opencode/skills/translation/SKILL.md +411 -0
  66. package/src/opencode/templates/CHANGELOG.md +82 -0
  67. package/src/opencode/templates/adr-template.md +115 -0
  68. package/src/opencode/templates/architecture-template.md +362 -0
  69. package/src/opencode/templates/change-proposal-template.md +186 -0
  70. package/src/opencode/templates/epic-template.md +151 -0
  71. package/src/opencode/templates/git-workflow-template.md +384 -0
  72. package/src/opencode/templates/integration-tests-template.md +265 -0
  73. package/src/opencode/templates/jira-cache-template.yaml +103 -0
  74. package/src/opencode/templates/module-index-template.md +139 -0
  75. package/src/opencode/templates/module-test-cases-template.md +230 -0
  76. package/src/opencode/templates/prd-acceptance-criteria-template.md +124 -0
  77. package/src/opencode/templates/prd-template.md +479 -0
  78. package/src/opencode/templates/requirements-template.md +132 -0
  79. package/src/opencode/templates/sprint-status-template.yaml +84 -0
  80. package/src/opencode/templates/story-template.md +437 -0
  81. package/src/opencode/templates/testing-standards-template.md +359 -0
  82. package/src/opencode/workflows/dev-story/instructions.md +529 -0
  83. package/src/repo-structure/.gitattributes +64 -0
  84. package/src/repo-structure/CONTRIBUTING.md +182 -0
  85. package/src/repo-structure/README.md +77 -0
  86. package/src/repo-structure/docs/README.md +62 -0
  87. package/src/repo-structure/docs/api/README.md +43 -0
  88. package/src/repo-structure/docs/architecture/README.md +36 -0
  89. package/src/repo-structure/docs/architecture/adr/README.md +53 -0
  90. package/src/repo-structure/docs/architecture/diagrams/README.md +59 -0
  91. package/src/repo-structure/docs/coding-standards/README.md +52 -0
  92. package/src/repo-structure/docs/confluence/README.md +43 -0
  93. package/src/repo-structure/docs/requirements/README.md +28 -0
  94. package/src/repo-structure/docs/sprint-artifacts/README.md +76 -0
  95. package/src/repo-structure/docs/sprint-artifacts/backlog/README.md +24 -0
package/README.md ADDED
@@ -0,0 +1,185 @@
1
+ # create-opencode-workflow
2
+
3
+ Initialize OpenCode Workflow system for AI-assisted development.
4
+
5
+ ## Quick Start
6
+
7
+ ```bash
8
+ npx create-opencode-workflow init
9
+ ```
10
+
11
+ ## Installation
12
+
13
+ ### Option 1: NPX (recommended)
14
+
15
+ ```bash
16
+ npx create-opencode-workflow init
17
+ ```
18
+
19
+ ### Option 2: Global Install
20
+
21
+ ```bash
22
+ npm install -g create-opencode-workflow
23
+ create-opencode-workflow init
24
+ ```
25
+
26
+ ## Commands
27
+
28
+ ### `init`
29
+
30
+ Initialize `.opencode/` in current project.
31
+
32
+ ```bash
33
+ npx create-opencode-workflow init
34
+ ```
35
+
36
+ **Interactive prompts:**
37
+
38
+ 1. **Your name** - For personalized agent communication
39
+ 2. **Communication language** - Ukrainian or English
40
+ 3. **Development methodology** - TDD or STUB
41
+ 4. **Jira integration** - Enable/disable
42
+ 5. **Repository structure** - Create full repo structure (README, CONTRIBUTING, etc.)
43
+
44
+ **Flags:**
45
+
46
+ ```bash
47
+ # Skip prompts, use defaults
48
+ npx create-opencode-workflow init -y
49
+
50
+ # With specific options
51
+ npx create-opencode-workflow init --tdd --jira --full
52
+ ```
53
+
54
+ | Flag | Description |
55
+ |------|-------------|
56
+ | `-y, --yes` | Skip prompts, use defaults |
57
+ | `--tdd` | Use TDD methodology |
58
+ | `--stub` | Use STUB methodology |
59
+ | `--jira` | Enable Jira integration |
60
+ | `--full` | Create full repository structure |
61
+
62
+ ### `update`
63
+
64
+ Update `.opencode/` to latest version while preserving your `config.yaml`.
65
+
66
+ ```bash
67
+ npx create-opencode-workflow update
68
+ ```
69
+
70
+ ### `doctor`
71
+
72
+ Check installation health.
73
+
74
+ ```bash
75
+ npx create-opencode-workflow doctor
76
+ ```
77
+
78
+ ### `config`
79
+
80
+ Show current configuration.
81
+
82
+ ```bash
83
+ npx create-opencode-workflow config
84
+ ```
85
+
86
+ ## What Gets Created
87
+
88
+ ### `.opencode/` (always)
89
+
90
+ ```
91
+ .opencode/
92
+ ├── config.yaml # Your configuration
93
+ ├── FLOW.yaml # Workflow definition (v3.0)
94
+ ├── agents/ # Agent personas
95
+ │ ├── analyst.md # Mary - Requirements
96
+ │ ├── pm.md # John - PRD
97
+ │ ├── architect.md # Winston - Architecture
98
+ │ ├── sm.md # Sarah - Sprint Management
99
+ │ └── dev.md # Amelia - Development
100
+ ├── skills/ # Knowledge modules
101
+ ├── templates/ # Document templates
102
+ ├── workflows/ # Workflow instructions
103
+ ├── checklists/ # Validation checklists
104
+ └── commands/ # Slash commands
105
+ ```
106
+
107
+ ### `docs/` (always)
108
+
109
+ ```
110
+ docs/
111
+ ├── sprint-artifacts/ # Epics, stories, sprints
112
+ │ └── backlog/
113
+ ├── requirements/ # Requirements documents
114
+ ├── architecture/ # Architecture docs
115
+ │ ├── adr/ # Architecture Decision Records
116
+ │ └── diagrams/
117
+ ├── api/ # API documentation
118
+ ├── coding-standards/ # Coding standards
119
+ └── confluence/ # Translations (Ukrainian)
120
+ ```
121
+
122
+ ### Repository files (with `--full`)
123
+
124
+ ```
125
+ README.md # Project readme
126
+ CONTRIBUTING.md # Git workflow, commit conventions
127
+ CHANGELOG.md # Change history
128
+ .gitignore # Git ignore patterns
129
+ .gitattributes # Git attributes
130
+ ```
131
+
132
+ ## Methodologies
133
+
134
+ ### TDD (Test-Driven Development)
135
+
136
+ ```
137
+ 1. Write failing test
138
+ 2. Write minimal code to pass
139
+ 3. Refactor
140
+ 4. Repeat
141
+ ```
142
+
143
+ ### STUB (Stub-First Development)
144
+
145
+ ```
146
+ 1. Write interface/stub with TODO
147
+ 2. Write tests against stub
148
+ 3. Implement stub
149
+ 4. Remove TODOs
150
+ ```
151
+
152
+ ## Jira Integration
153
+
154
+ If enabled, set credentials:
155
+
156
+ ```bash
157
+ export JIRA_EMAIL="your-email@company.com"
158
+ export JIRA_API_TOKEN="your-api-token"
159
+ ```
160
+
161
+ ## Development
162
+
163
+ ### Building
164
+
165
+ ```bash
166
+ cd .opencode/cli
167
+ npm run build
168
+ ```
169
+
170
+ ### Testing locally
171
+
172
+ ```bash
173
+ node bin/cli.js init
174
+ ```
175
+
176
+ ### Publishing
177
+
178
+ ```bash
179
+ npm run build
180
+ npm publish
181
+ ```
182
+
183
+ ## License
184
+
185
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,406 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import chalk from 'chalk';
5
+ import inquirer from 'inquirer';
6
+ import ora from 'ora';
7
+ import fs from 'fs-extra';
8
+ import path from 'path';
9
+ import { fileURLToPath } from 'url';
10
+
11
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
12
+ const PACKAGE_DIR = path.join(__dirname, '..');
13
+ const OPENCODE_SRC = path.join(PACKAGE_DIR, 'src', 'opencode');
14
+ const REPO_TEMPLATES_SRC = path.join(PACKAGE_DIR, 'src', 'repo-structure');
15
+
16
+ const program = new Command();
17
+
18
+ program
19
+ .name('create-opencode-workflow')
20
+ .description('Initialize OpenCode Workflow system for AI-assisted development')
21
+ .version('3.0.0');
22
+
23
+ program
24
+ .command('init')
25
+ .description('Initialize .opencode/ in current project')
26
+ .option('-y, --yes', 'Skip prompts, use defaults')
27
+ .option('--jira', 'Enable Jira integration')
28
+ .option('--tdd', 'Use TDD methodology')
29
+ .option('--stub', 'Use STUB methodology')
30
+ .option('--full', 'Create full repo structure')
31
+ .action(async (options) => {
32
+ console.log(chalk.blue.bold('\n🚀 OpenCode Workflow v3.0\n'));
33
+
34
+ let config = {
35
+ user_name: 'Developer',
36
+ communication_language: 'Ukrainian',
37
+ methodology: 'tdd',
38
+ jira_enabled: false,
39
+ create_repo_structure: false,
40
+ project_name: path.basename(process.cwd())
41
+ };
42
+
43
+ if (!options.yes) {
44
+ const answers = await inquirer.prompt([
45
+ {
46
+ type: 'input',
47
+ name: 'user_name',
48
+ message: 'Your name:',
49
+ default: config.user_name
50
+ },
51
+ {
52
+ type: 'list',
53
+ name: 'communication_language',
54
+ message: 'Communication language:',
55
+ choices: ['Ukrainian', 'English'],
56
+ default: 'Ukrainian'
57
+ },
58
+ {
59
+ type: 'list',
60
+ name: 'methodology',
61
+ message: 'Development methodology:',
62
+ choices: [
63
+ { name: 'TDD - Test-Driven Development (write tests first)', value: 'tdd' },
64
+ { name: 'STUB - Stub-First Development (write stubs, then implement)', value: 'stub' }
65
+ ],
66
+ default: options.tdd ? 'tdd' : (options.stub ? 'stub' : 'tdd')
67
+ },
68
+ {
69
+ type: 'confirm',
70
+ name: 'jira_enabled',
71
+ message: 'Enable Jira integration?',
72
+ default: options.jira || false
73
+ },
74
+ {
75
+ type: 'input',
76
+ name: 'jira_url',
77
+ message: 'Jira URL:',
78
+ when: (answers) => answers.jira_enabled,
79
+ default: 'https://your-domain.atlassian.net'
80
+ },
81
+ {
82
+ type: 'input',
83
+ name: 'jira_project',
84
+ message: 'Jira project key:',
85
+ when: (answers) => answers.jira_enabled,
86
+ default: 'PROJ'
87
+ },
88
+ {
89
+ type: 'confirm',
90
+ name: 'create_repo_structure',
91
+ message: 'Create full repository structure (README, CONTRIBUTING, .gitignore, docs/)?',
92
+ default: options.full || false
93
+ }
94
+ ]);
95
+
96
+ config = { ...config, ...answers };
97
+ } else {
98
+ // Apply CLI flags for non-interactive mode
99
+ if (options.tdd) config.methodology = 'tdd';
100
+ if (options.stub) config.methodology = 'stub';
101
+ if (options.jira) config.jira_enabled = true;
102
+ if (options.full) config.create_repo_structure = true;
103
+ }
104
+
105
+ const spinner = ora('Initializing OpenCode Workflow...').start();
106
+
107
+ try {
108
+ const targetDir = path.join(process.cwd(), '.opencode');
109
+
110
+ // Check if already exists
111
+ if (await fs.pathExists(targetDir)) {
112
+ spinner.warn(chalk.yellow('.opencode/ already exists'));
113
+ const { overwrite } = await inquirer.prompt([{
114
+ type: 'confirm',
115
+ name: 'overwrite',
116
+ message: 'Overwrite existing .opencode/?',
117
+ default: false
118
+ }]);
119
+
120
+ if (!overwrite) {
121
+ console.log(chalk.yellow('\nAborted. Use `update` command to update existing installation.\n'));
122
+ process.exit(0);
123
+ }
124
+ }
125
+
126
+ spinner.start('Copying OpenCode Workflow files...');
127
+
128
+ // Copy .opencode structure
129
+ await fs.copy(OPENCODE_SRC, targetDir, { overwrite: true });
130
+
131
+ // Update config.yaml with user values
132
+ spinner.text = 'Configuring...';
133
+ const configPath = path.join(targetDir, 'config.yaml');
134
+ let configContent = await fs.readFile(configPath, 'utf8');
135
+
136
+ configContent = configContent
137
+ .replace(/user_name: ".*"/, `user_name: "${config.user_name}"`)
138
+ .replace(/communication_language: ".*"/, `communication_language: "${config.communication_language}"`)
139
+ .replace(/project_name: ".*"/, `project_name: "${config.project_name}"`)
140
+ .replace(/methodology: (tdd|stub)/, `methodology: ${config.methodology}`);
141
+
142
+ // Jira config
143
+ if (config.jira_enabled) {
144
+ configContent = configContent
145
+ .replace(/enabled: false\s+# Jira/, `enabled: true # Jira`)
146
+ .replace(/base_url: ".*"/, `base_url: "${config.jira_url}"`)
147
+ .replace(/project_key: ".*"/, `project_key: "${config.jira_project}"`);
148
+ }
149
+
150
+ await fs.writeFile(configPath, configContent);
151
+
152
+ // Create docs structure (always)
153
+ spinner.text = 'Creating docs structure...';
154
+ await fs.ensureDir(path.join(process.cwd(), 'docs'));
155
+ await fs.ensureDir(path.join(process.cwd(), 'docs/sprint-artifacts'));
156
+ await fs.ensureDir(path.join(process.cwd(), 'docs/sprint-artifacts/backlog'));
157
+ await fs.ensureDir(path.join(process.cwd(), 'docs/requirements'));
158
+ await fs.ensureDir(path.join(process.cwd(), 'docs/architecture'));
159
+ await fs.ensureDir(path.join(process.cwd(), 'docs/architecture/adr'));
160
+ await fs.ensureDir(path.join(process.cwd(), 'docs/architecture/diagrams'));
161
+ await fs.ensureDir(path.join(process.cwd(), 'docs/api'));
162
+ await fs.ensureDir(path.join(process.cwd(), 'docs/confluence'));
163
+ await fs.ensureDir(path.join(process.cwd(), 'docs/coding-standards'));
164
+
165
+ // Create full repo structure if requested
166
+ if (config.create_repo_structure) {
167
+ spinner.text = 'Creating repository structure...';
168
+
169
+ // Copy repo-structure templates (skip if files already exist)
170
+ const repoFiles = [
171
+ { src: 'README.md', dest: 'README.md' },
172
+ { src: 'CONTRIBUTING.md', dest: 'CONTRIBUTING.md' },
173
+ { src: '.gitignore', dest: '.gitignore' },
174
+ { src: '.gitattributes', dest: '.gitattributes' },
175
+ { src: 'docs/README.md', dest: 'docs/README.md' },
176
+ { src: 'docs/requirements/README.md', dest: 'docs/requirements/README.md' },
177
+ { src: 'docs/architecture/README.md', dest: 'docs/architecture/README.md' },
178
+ { src: 'docs/architecture/adr/README.md', dest: 'docs/architecture/adr/README.md' },
179
+ { src: 'docs/architecture/diagrams/README.md', dest: 'docs/architecture/diagrams/README.md' },
180
+ { src: 'docs/api/README.md', dest: 'docs/api/README.md' },
181
+ { src: 'docs/sprint-artifacts/README.md', dest: 'docs/sprint-artifacts/README.md' },
182
+ { src: 'docs/sprint-artifacts/backlog/README.md', dest: 'docs/sprint-artifacts/backlog/README.md' },
183
+ { src: 'docs/confluence/README.md', dest: 'docs/confluence/README.md' },
184
+ { src: 'docs/coding-standards/README.md', dest: 'docs/coding-standards/README.md' }
185
+ ];
186
+
187
+ for (const file of repoFiles) {
188
+ const destPath = path.join(process.cwd(), file.dest);
189
+ if (!await fs.pathExists(destPath)) {
190
+ const srcPath = path.join(REPO_TEMPLATES_SRC, file.src);
191
+ if (await fs.pathExists(srcPath)) {
192
+ await fs.copy(srcPath, destPath);
193
+ }
194
+ }
195
+ }
196
+ }
197
+
198
+ // Create CHANGELOG.md if not exists
199
+ const changelogPath = path.join(process.cwd(), 'CHANGELOG.md');
200
+ if (!await fs.pathExists(changelogPath)) {
201
+ const changelogTemplate = path.join(targetDir, 'templates/CHANGELOG.md');
202
+ if (await fs.pathExists(changelogTemplate)) {
203
+ await fs.copy(changelogTemplate, changelogPath);
204
+ }
205
+ }
206
+
207
+ spinner.succeed(chalk.green('OpenCode Workflow initialized!'));
208
+
209
+ // Show summary
210
+ console.log(chalk.yellow('\n📁 Created structure:'));
211
+ console.log(`
212
+ ${chalk.cyan('.opencode/')}
213
+ ├── config.yaml # Your configuration
214
+ ├── FLOW.yaml # Workflow definition
215
+ ├── agents/ # Agent personas (analyst, pm, architect, sm, dev)
216
+ ├── skills/ # Knowledge modules
217
+ ├── templates/ # Document templates
218
+ ├── workflows/ # Workflow instructions
219
+ └── checklists/ # Validation checklists
220
+
221
+ ${chalk.cyan('docs/')}
222
+ ├── sprint-artifacts/ # Epics, stories, sprints
223
+ │ └── backlog/ # Backlog items
224
+ ├── requirements/ # Requirements documents
225
+ ├── architecture/ # Architecture docs
226
+ │ ├── adr/ # Architecture Decision Records
227
+ │ └── diagrams/ # System diagrams
228
+ ├── api/ # API documentation
229
+ ├── coding-standards/ # Coding standards
230
+ └── confluence/ # Translations (Ukrainian)
231
+ `);
232
+
233
+ if (config.create_repo_structure) {
234
+ console.log(chalk.yellow('📄 Repository files created:'));
235
+ console.log(`
236
+ README.md # Project readme
237
+ CONTRIBUTING.md # Git workflow, commit conventions
238
+ CHANGELOG.md # Change history
239
+ .gitignore # Git ignore patterns
240
+ .gitattributes # Git attributes
241
+ `);
242
+ }
243
+
244
+ console.log(chalk.blue('\n⚙️ Configuration:'));
245
+ console.log(`
246
+ Methodology: ${chalk.cyan(config.methodology.toUpperCase())}
247
+ Language: ${chalk.cyan(config.communication_language)}
248
+ Jira: ${config.jira_enabled ? chalk.green('Enabled') : chalk.gray('Disabled')}
249
+ `);
250
+
251
+ console.log(chalk.blue('🎯 Next steps:'));
252
+ console.log(`
253
+ 1. Review ${chalk.cyan('.opencode/config.yaml')}
254
+ 2. Start with: ${chalk.cyan('/requirements')} or ${chalk.cyan('/prd')}
255
+ 3. Use agents: ${chalk.cyan('@analyst')}, ${chalk.cyan('@pm')}, ${chalk.cyan('@architect')}
256
+ `);
257
+
258
+ if (config.jira_enabled) {
259
+ console.log(chalk.yellow('⚠️ Set Jira credentials:'));
260
+ console.log(`
261
+ export JIRA_EMAIL="your-email@company.com"
262
+ export JIRA_API_TOKEN="your-api-token"
263
+ `);
264
+ }
265
+
266
+ } catch (error) {
267
+ spinner.fail(chalk.red('Failed to initialize'));
268
+ console.error(error);
269
+ process.exit(1);
270
+ }
271
+ });
272
+
273
+ program
274
+ .command('update')
275
+ .description('Update .opencode/ to latest version (preserves config.yaml)')
276
+ .action(async () => {
277
+ const spinner = ora('Updating OpenCode Workflow...').start();
278
+
279
+ try {
280
+ const targetDir = path.join(process.cwd(), '.opencode');
281
+
282
+ if (!await fs.pathExists(targetDir)) {
283
+ spinner.fail(chalk.red('.opencode/ not found. Run `init` first.'));
284
+ process.exit(1);
285
+ }
286
+
287
+ const configPath = path.join(targetDir, 'config.yaml');
288
+
289
+ // Backup config
290
+ const configBackup = await fs.readFile(configPath, 'utf8');
291
+
292
+ // Copy new files
293
+ await fs.copy(OPENCODE_SRC, targetDir, { overwrite: true });
294
+
295
+ // Restore config
296
+ await fs.writeFile(configPath, configBackup);
297
+
298
+ spinner.succeed(chalk.green('OpenCode Workflow updated!'));
299
+ console.log(chalk.yellow('\n✅ Your config.yaml was preserved.\n'));
300
+
301
+ } catch (error) {
302
+ spinner.fail(chalk.red('Failed to update'));
303
+ console.error(error);
304
+ process.exit(1);
305
+ }
306
+ });
307
+
308
+ program
309
+ .command('doctor')
310
+ .description('Check OpenCode Workflow installation')
311
+ .action(async () => {
312
+ console.log(chalk.blue.bold('\n🩺 OpenCode Workflow Health Check\n'));
313
+
314
+ const checks = [
315
+ { name: '.opencode/', path: '.opencode', required: true },
316
+ { name: 'config.yaml', path: '.opencode/config.yaml', required: true },
317
+ { name: 'FLOW.yaml', path: '.opencode/FLOW.yaml', required: true },
318
+ { name: 'agents/', path: '.opencode/agents', required: true },
319
+ { name: 'skills/', path: '.opencode/skills', required: true },
320
+ { name: 'templates/', path: '.opencode/templates', required: true },
321
+ { name: 'docs/', path: 'docs', required: true },
322
+ { name: 'docs/sprint-artifacts/', path: 'docs/sprint-artifacts', required: true },
323
+ { name: 'docs/requirements/', path: 'docs/requirements', required: true },
324
+ { name: 'docs/architecture/', path: 'docs/architecture', required: true },
325
+ { name: 'CHANGELOG.md', path: 'CHANGELOG.md', required: false },
326
+ { name: 'README.md', path: 'README.md', required: false },
327
+ { name: 'CONTRIBUTING.md', path: 'CONTRIBUTING.md', required: false },
328
+ ];
329
+
330
+ let hasErrors = false;
331
+
332
+ console.log(chalk.cyan('Core files:'));
333
+ for (const check of checks.filter(c => c.required)) {
334
+ const exists = await fs.pathExists(path.join(process.cwd(), check.path));
335
+ if (exists) {
336
+ console.log(chalk.green(` ✅ ${check.name}`));
337
+ } else {
338
+ console.log(chalk.red(` ❌ ${check.name} - missing`));
339
+ hasErrors = true;
340
+ }
341
+ }
342
+
343
+ console.log(chalk.cyan('\nOptional files:'));
344
+ for (const check of checks.filter(c => !c.required)) {
345
+ const exists = await fs.pathExists(path.join(process.cwd(), check.path));
346
+ if (exists) {
347
+ console.log(chalk.green(` ✅ ${check.name}`));
348
+ } else {
349
+ console.log(chalk.gray(` ○ ${check.name} - not created`));
350
+ }
351
+ }
352
+
353
+ // Check config values
354
+ console.log(chalk.cyan('\nConfiguration:'));
355
+ try {
356
+ const configPath = path.join(process.cwd(), '.opencode/config.yaml');
357
+ const configContent = await fs.readFile(configPath, 'utf8');
358
+
359
+ const methodologyMatch = configContent.match(/methodology: (tdd|stub)/);
360
+ if (methodologyMatch) {
361
+ console.log(chalk.green(` ✅ Methodology: ${methodologyMatch[1].toUpperCase()}`));
362
+ }
363
+
364
+ const jiraMatch = configContent.match(/enabled: (true|false)\s+# Jira/);
365
+ if (jiraMatch) {
366
+ const jiraEnabled = jiraMatch[1] === 'true';
367
+ console.log(jiraEnabled
368
+ ? chalk.green(' ✅ Jira: Enabled')
369
+ : chalk.gray(' ○ Jira: Disabled'));
370
+ }
371
+ } catch (e) {
372
+ console.log(chalk.yellow(' ⚠️ Could not read config'));
373
+ }
374
+
375
+ // Check Jira env vars
376
+ console.log(chalk.cyan('\nEnvironment:'));
377
+ if (process.env.JIRA_EMAIL && process.env.JIRA_API_TOKEN) {
378
+ console.log(chalk.green(' ✅ Jira credentials configured'));
379
+ } else {
380
+ console.log(chalk.gray(' ○ Jira credentials not set'));
381
+ }
382
+
383
+ console.log('');
384
+
385
+ if (hasErrors) {
386
+ console.log(chalk.yellow('💡 Run `npx create-opencode-workflow init` to fix missing files.\n'));
387
+ } else {
388
+ console.log(chalk.green.bold('✅ All checks passed!\n'));
389
+ }
390
+ });
391
+
392
+ program
393
+ .command('config')
394
+ .description('Show current configuration')
395
+ .action(async () => {
396
+ try {
397
+ const configPath = path.join(process.cwd(), '.opencode/config.yaml');
398
+ const content = await fs.readFile(configPath, 'utf8');
399
+ console.log(chalk.blue.bold('\n📋 Current Configuration:\n'));
400
+ console.log(content);
401
+ } catch (error) {
402
+ console.log(chalk.red('\n❌ .opencode/config.yaml not found. Run `init` first.\n'));
403
+ }
404
+ });
405
+
406
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,50 @@
1
+ {
2
+ "name": "@comfanion/workflow",
3
+ "version": "3.0.0",
4
+ "description": "Initialize OpenCode Workflow system for AI-assisted development",
5
+ "type": "module",
6
+ "bin": {
7
+ "comfanion-workflow": "./bin/cli.js",
8
+ "opencode-workflow": "./bin/cli.js"
9
+ },
10
+ "files": [
11
+ "bin/",
12
+ "src/"
13
+ ],
14
+ "scripts": {
15
+ "build": "node scripts/build.js",
16
+ "prepublishOnly": "npm run build",
17
+ "test": "node bin/cli.js --help"
18
+ },
19
+ "keywords": [
20
+ "opencode",
21
+ "claude",
22
+ "ai",
23
+ "workflow",
24
+ "development",
25
+ "prd",
26
+ "architecture",
27
+ "tdd",
28
+ "agile"
29
+ ],
30
+ "author": "OpenCode Team",
31
+ "license": "MIT",
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://gitlab.com/comfanion/workflow.git"
35
+ },
36
+ "homepage": "https://gitlab.com/comfanion/workflow#readme",
37
+ "bugs": {
38
+ "url": "https://gitlab.com/comfanion/workflow/-/issues"
39
+ },
40
+ "engines": {
41
+ "node": ">=18"
42
+ },
43
+ "dependencies": {
44
+ "chalk": "^5.3.0",
45
+ "commander": "^11.0.0",
46
+ "fs-extra": "^11.1.0",
47
+ "inquirer": "^9.2.0",
48
+ "ora": "^7.0.0"
49
+ }
50
+ }
@@ -0,0 +1,16 @@
1
+ {
2
+ "version": "3.0.0",
3
+ "buildDate": "2026-01-23T15:07:21.915Z",
4
+ "files": [
5
+ "config.yaml",
6
+ "FLOW.yaml",
7
+ "ARCHITECTURE.md",
8
+ "agents",
9
+ "skills",
10
+ "templates",
11
+ "workflows",
12
+ "checklists",
13
+ "commands",
14
+ "opencode.json"
15
+ ]
16
+ }