@comfanion/workflow 3.5.1 → 3.7.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/bin/cli.js CHANGED
@@ -18,7 +18,7 @@ const program = new Command();
18
18
  program
19
19
  .name('create-opencode-workflow')
20
20
  .description('Initialize OpenCode Workflow system for AI-assisted development')
21
- .version('3.5.1');
21
+ .version('3.7.0');
22
22
 
23
23
  program
24
24
  .command('init')
@@ -29,16 +29,81 @@ program
29
29
  .option('--stub', 'Use STUB methodology')
30
30
  .option('--full', 'Create full repo structure')
31
31
  .action(async (options) => {
32
- console.log(chalk.blue.bold('\nšŸš€ OpenCode Workflow v3.5\n'));
32
+ console.log(chalk.blue.bold('\nšŸš€ OpenCode Workflow v3.7\n'));
33
33
 
34
+ const targetDir = path.join(process.cwd(), '.opencode');
35
+ const existingConfigPath = path.join(targetDir, 'config.yaml');
36
+
37
+ // Default config
34
38
  let config = {
35
39
  user_name: 'Developer',
36
40
  communication_language: 'Ukrainian',
37
41
  methodology: 'tdd',
38
42
  jira_enabled: false,
43
+ jira_url: 'https://your-domain.atlassian.net',
44
+ jira_project: 'PROJ',
39
45
  create_repo_structure: false,
40
46
  project_name: path.basename(process.cwd())
41
47
  };
48
+
49
+ // Check if .opencode/ already exists
50
+ let isUpdate = false;
51
+ if (await fs.pathExists(targetDir)) {
52
+ // Try to read existing config
53
+ if (await fs.pathExists(existingConfigPath)) {
54
+ try {
55
+ const existingContent = await fs.readFile(existingConfigPath, 'utf8');
56
+
57
+ // Parse existing values
58
+ const nameMatch = existingContent.match(/user_name:\s*"([^"]+)"/);
59
+ const langMatch = existingContent.match(/communication_language:\s*"([^"]+)"/);
60
+ const methMatch = existingContent.match(/methodology:\s*(tdd|stub)/);
61
+ const jiraMatch = existingContent.match(/jira:[\s\S]*?enabled:\s*(true|false)/);
62
+ const jiraUrlMatch = existingContent.match(/base_url:\s*"([^"]+)"/);
63
+ const jiraProjMatch = existingContent.match(/project_key:\s*"([^"]+)"/);
64
+
65
+ if (nameMatch) config.user_name = nameMatch[1];
66
+ if (langMatch) config.communication_language = langMatch[1];
67
+ if (methMatch) config.methodology = methMatch[1];
68
+ if (jiraMatch) config.jira_enabled = jiraMatch[1] === 'true';
69
+ if (jiraUrlMatch) config.jira_url = jiraUrlMatch[1];
70
+ if (jiraProjMatch) config.jira_project = jiraProjMatch[1];
71
+
72
+ isUpdate = true;
73
+ } catch (e) {
74
+ // Could not parse, use defaults
75
+ }
76
+ }
77
+
78
+ console.log(chalk.yellow('.opencode/ already exists'));
79
+
80
+ if (isUpdate) {
81
+ console.log(chalk.gray(` Found config: ${config.user_name}, ${config.communication_language}, ${config.methodology.toUpperCase()}\n`));
82
+ }
83
+
84
+ const { action } = await inquirer.prompt([{
85
+ type: 'list',
86
+ name: 'action',
87
+ message: 'What would you like to do?',
88
+ choices: [
89
+ { name: 'Update files only (keep my settings)', value: 'update' },
90
+ { name: 'Reconfigure (change settings)', value: 'reconfigure' },
91
+ { name: 'Cancel', value: 'cancel' }
92
+ ],
93
+ default: 'update'
94
+ }]);
95
+
96
+ if (action === 'cancel') {
97
+ console.log(chalk.yellow('\nAborted.\n'));
98
+ process.exit(0);
99
+ }
100
+
101
+ if (action === 'update') {
102
+ // Use existing config, skip prompts
103
+ options.yes = true;
104
+ }
105
+ // If 'reconfigure', continue to prompts with existing values as defaults
106
+ }
42
107
 
43
108
  if (!options.yes) {
44
109
  const answers = await inquirer.prompt([
@@ -53,7 +118,7 @@ program
53
118
  name: 'communication_language',
54
119
  message: 'Communication language:',
55
120
  choices: ['Ukrainian', 'English'],
56
- default: 'Ukrainian'
121
+ default: config.communication_language
57
122
  },
58
123
  {
59
124
  type: 'list',
@@ -63,27 +128,27 @@ program
63
128
  { name: 'TDD - Test-Driven Development (write tests first)', value: 'tdd' },
64
129
  { name: 'STUB - Stub-First Development (write stubs, then implement)', value: 'stub' }
65
130
  ],
66
- default: options.tdd ? 'tdd' : (options.stub ? 'stub' : 'tdd')
131
+ default: options.tdd ? 'tdd' : (options.stub ? 'stub' : config.methodology)
67
132
  },
68
133
  {
69
134
  type: 'confirm',
70
135
  name: 'jira_enabled',
71
136
  message: 'Enable Jira integration?',
72
- default: options.jira || false
137
+ default: options.jira || config.jira_enabled
73
138
  },
74
139
  {
75
140
  type: 'input',
76
141
  name: 'jira_url',
77
142
  message: 'Jira URL:',
78
143
  when: (answers) => answers.jira_enabled,
79
- default: 'https://your-domain.atlassian.net'
144
+ default: config.jira_url
80
145
  },
81
146
  {
82
147
  type: 'input',
83
148
  name: 'jira_project',
84
149
  message: 'Jira project key:',
85
150
  when: (answers) => answers.jira_enabled,
86
- default: 'PROJ'
151
+ default: config.jira_project
87
152
  },
88
153
  {
89
154
  type: 'confirm',
@@ -105,35 +170,18 @@ program
105
170
  const spinner = ora('Initializing OpenCode Workflow...').start();
106
171
 
107
172
  try {
108
- const targetDir = path.join(process.cwd(), '.opencode');
109
-
110
- // Check if already exists
111
- let existingConfig = null;
173
+ // If updating, create backup and remove old directory
112
174
  if (await fs.pathExists(targetDir)) {
113
- spinner.warn(chalk.yellow('.opencode/ already exists'));
114
- const { overwrite } = await inquirer.prompt([{
115
- type: 'confirm',
116
- name: 'overwrite',
117
- message: 'Overwrite existing .opencode/?',
118
- default: false
119
- }]);
120
-
121
- if (!overwrite) {
122
- console.log(chalk.yellow('\nAborted. Use `update` command to update existing installation.\n'));
123
- process.exit(0);
124
- }
125
-
126
- // Create backup and remove old directory
127
175
  const timestamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19);
128
176
  const backupDir = path.join(process.cwd(), `.opencode.backup-${timestamp}`);
129
177
 
130
- spinner.start('Creating backup...');
178
+ spinner.text = 'Creating backup...';
131
179
  await fs.copy(targetDir, backupDir);
132
180
 
133
181
  spinner.text = 'Removing old .opencode/...';
134
182
  await fs.remove(targetDir);
135
183
 
136
- console.log(chalk.yellow(`\nšŸ“¦ Backup created: ${chalk.cyan(`.opencode.backup-${timestamp}/`)}`));
184
+ console.log(chalk.yellow(`\nšŸ“¦ Backup: ${chalk.cyan(`.opencode.backup-${timestamp}/`)}`));
137
185
  }
138
186
 
139
187
  spinner.start('Copying OpenCode Workflow files...');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comfanion/workflow",
3
- "version": "3.5.1",
3
+ "version": "3.7.0",
4
4
  "description": "Initialize OpenCode Workflow system for AI-assisted development",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "version": "3.0.0",
3
- "buildDate": "2026-01-23T16:26:53.487Z",
3
+ "buildDate": "2026-01-23T16:40:58.918Z",
4
4
  "files": [
5
5
  "config.yaml",
6
6
  "FLOW.yaml",
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: "Strategic Business Analyst - Requirements gathering, validation, research"
3
- mode: primary
2
+ description: "Business Analyst - Use for: gathering requirements, validating requirements, brainstorming. Has skills: requirements-gathering, requirements-validation"
3
+ mode: all
4
4
  tools:
5
5
  write: true
6
6
  edit: true
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: "Solution Architect - System design, module docs, ADRs, coding standards, API design"
3
- mode: primary
2
+ description: "Solution Architect - Use for: system architecture, module documentation, ADRs, coding standards, API design. Has skills: architecture-design, architecture-validation, adr-writing, module-documentation, coding-standards"
3
+ mode: all
4
4
  tools:
5
5
  write: true
6
6
  edit: true
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: "Change Manager - Manages change proposals with delta tracking"
3
- mode: primary
2
+ description: "Change Manager - Use for: change proposals, document updates with delta tracking, reviewing changes before merge"
3
+ mode: all
4
4
  tools:
5
5
  write: true
6
6
  edit: true
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: "Senior Developer - Story implementation, TDD, code review"
3
- mode: primary
2
+ description: "Senior Developer - Use for: implementing stories, TDD development, code review, running tests. Has skills: code-review, test-design"
3
+ mode: all
4
4
  tools:
5
5
  write: true
6
6
  edit: true
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: "Product Manager - PRD, epics, stories, sprint planning, Jira sync"
3
- mode: primary
2
+ description: "Product Manager - Use for: creating PRD, writing epics, writing stories, sprint planning, Jira sync. Has skills: prd-writing, epic-writing, story-writing, sprint-planning, jira-integration"
3
+ mode: all
4
4
  tools:
5
5
  write: true
6
6
  edit: true
@@ -1,6 +1,6 @@
1
1
  ---
2
- description: "Research Specialist - Technical, market, and domain research with structured documentation"
3
- mode: primary
2
+ description: "Research Specialist - Use for: technical research, market research, domain research, competitive analysis. Has skills: research-methodology, methodologies"
3
+ mode: all
4
4
  tools:
5
5
  write: true
6
6
  edit: true
@@ -6,7 +6,7 @@
6
6
  # PROJECT CONFIGURATION
7
7
  # =============================================================================
8
8
  project_name: "ai-wf"
9
- version: "3.5.1"
9
+ version: "3.7.0"
10
10
 
11
11
  # =============================================================================
12
12
  # USER CONFIGURATION
@@ -11,17 +11,10 @@
11
11
  "agent": {
12
12
  "build": {
13
13
  "mode": "primary",
14
- "description": "Default development agent with full tool access",
15
- "model": "anthropic/claude-sonnet-4-20250514"
14
+ "description": "Default development agent - use @pm, @architect, @analyst, @dev for specialized tasks"
16
15
  },
17
16
  "plan": {
18
- "mode": "primary",
19
- "description": "Planning agent - analyzes without making changes",
20
- "model": "anthropic/claude-sonnet-4-20250514",
21
- "permission": {
22
- "edit": "ask",
23
- "bash": "ask"
24
- }
17
+ "disable": true
25
18
  }
26
19
  },
27
20