@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.
- package/README.md +185 -0
- package/bin/cli.js +406 -0
- package/package.json +50 -0
- package/src/build-info.json +16 -0
- package/src/opencode/ARCHITECTURE.md +255 -0
- package/src/opencode/FLOW.yaml +900 -0
- package/src/opencode/agents/analyst.md +141 -0
- package/src/opencode/agents/architect.md +177 -0
- package/src/opencode/agents/change-manager.md +263 -0
- package/src/opencode/agents/dev.md +171 -0
- package/src/opencode/agents/module-docs.md +628 -0
- package/src/opencode/agents/pm.md +157 -0
- package/src/opencode/agents/researcher.md +254 -0
- package/src/opencode/agents/sm.md +184 -0
- package/src/opencode/agents/workflow-orchestrator.md +249 -0
- package/src/opencode/checklists/architecture-checklist.md +166 -0
- package/src/opencode/checklists/code-review-checklist.md +151 -0
- package/src/opencode/checklists/prd-checklist.md +140 -0
- package/src/opencode/checklists/requirements-checklist.md +86 -0
- package/src/opencode/checklists/story-checklist.md +137 -0
- package/src/opencode/commands/architecture.md +68 -0
- package/src/opencode/commands/archive.md +146 -0
- package/src/opencode/commands/change.md +169 -0
- package/src/opencode/commands/clarify.md +132 -0
- package/src/opencode/commands/code-review.md +96 -0
- package/src/opencode/commands/coding-standards.md +102 -0
- package/src/opencode/commands/dev-story.md +80 -0
- package/src/opencode/commands/diagram.md +152 -0
- package/src/opencode/commands/epics.md +52 -0
- package/src/opencode/commands/help.md +139 -0
- package/src/opencode/commands/jira-sync.md +58 -0
- package/src/opencode/commands/module-docs.md +158 -0
- package/src/opencode/commands/prd.md +63 -0
- package/src/opencode/commands/quick.md +166 -0
- package/src/opencode/commands/requirements.md +49 -0
- package/src/opencode/commands/research.md +113 -0
- package/src/opencode/commands/sprint-plan.md +59 -0
- package/src/opencode/commands/stories.md +61 -0
- package/src/opencode/commands/validate.md +84 -0
- package/src/opencode/commands/workflow-status.md +150 -0
- package/src/opencode/config.yaml +223 -0
- package/src/opencode/opencode.json +36 -0
- package/src/opencode/skills/acceptance-criteria/SKILL.md +212 -0
- package/src/opencode/skills/adr-writing/SKILL.md +241 -0
- package/src/opencode/skills/architecture-design/SKILL.md +183 -0
- package/src/opencode/skills/architecture-validation/SKILL.md +199 -0
- package/src/opencode/skills/archiving/SKILL.md +191 -0
- package/src/opencode/skills/changelog/SKILL.md +280 -0
- package/src/opencode/skills/code-review/SKILL.md +193 -0
- package/src/opencode/skills/coding-standards/SKILL.md +430 -0
- package/src/opencode/skills/diagram-creation/SKILL.md +273 -0
- package/src/opencode/skills/doc-todo/SKILL.md +325 -0
- package/src/opencode/skills/epic-writing/SKILL.md +291 -0
- package/src/opencode/skills/jira-integration/SKILL.md +560 -0
- package/src/opencode/skills/methodologies/SKILL.md +376 -0
- package/src/opencode/skills/module-documentation/SKILL.md +214 -0
- package/src/opencode/skills/prd-validation/SKILL.md +164 -0
- package/src/opencode/skills/prd-writing/SKILL.md +104 -0
- package/src/opencode/skills/requirements-gathering/SKILL.md +132 -0
- package/src/opencode/skills/requirements-validation/SKILL.md +141 -0
- package/src/opencode/skills/research-methodology/SKILL.md +140 -0
- package/src/opencode/skills/sprint-planning/SKILL.md +217 -0
- package/src/opencode/skills/story-writing/SKILL.md +574 -0
- package/src/opencode/skills/test-design/SKILL.md +313 -0
- package/src/opencode/skills/translation/SKILL.md +411 -0
- package/src/opencode/templates/CHANGELOG.md +82 -0
- package/src/opencode/templates/adr-template.md +115 -0
- package/src/opencode/templates/architecture-template.md +362 -0
- package/src/opencode/templates/change-proposal-template.md +186 -0
- package/src/opencode/templates/epic-template.md +151 -0
- package/src/opencode/templates/git-workflow-template.md +384 -0
- package/src/opencode/templates/integration-tests-template.md +265 -0
- package/src/opencode/templates/jira-cache-template.yaml +103 -0
- package/src/opencode/templates/module-index-template.md +139 -0
- package/src/opencode/templates/module-test-cases-template.md +230 -0
- package/src/opencode/templates/prd-acceptance-criteria-template.md +124 -0
- package/src/opencode/templates/prd-template.md +479 -0
- package/src/opencode/templates/requirements-template.md +132 -0
- package/src/opencode/templates/sprint-status-template.yaml +84 -0
- package/src/opencode/templates/story-template.md +437 -0
- package/src/opencode/templates/testing-standards-template.md +359 -0
- package/src/opencode/workflows/dev-story/instructions.md +529 -0
- package/src/repo-structure/.gitattributes +64 -0
- package/src/repo-structure/CONTRIBUTING.md +182 -0
- package/src/repo-structure/README.md +77 -0
- package/src/repo-structure/docs/README.md +62 -0
- package/src/repo-structure/docs/api/README.md +43 -0
- package/src/repo-structure/docs/architecture/README.md +36 -0
- package/src/repo-structure/docs/architecture/adr/README.md +53 -0
- package/src/repo-structure/docs/architecture/diagrams/README.md +59 -0
- package/src/repo-structure/docs/coding-standards/README.md +52 -0
- package/src/repo-structure/docs/confluence/README.md +43 -0
- package/src/repo-structure/docs/requirements/README.md +28 -0
- package/src/repo-structure/docs/sprint-artifacts/README.md +76 -0
- 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
|
+
}
|