@spec-wave/cli 0.3.1 → 0.4.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/spec-wave.mjs CHANGED
@@ -49,9 +49,9 @@ program
49
49
 
50
50
  program
51
51
  .command('issue')
52
- .description('Cria um work item (epic/feature/story/task...), opcionalmente como sub-issue, e adiciona ao board')
52
+ .description('Cria um work item (initiative/epic/feature/story/task...), opcionalmente como sub-issue, e adiciona ao board')
53
53
  .requiredOption('--title <title>', 'Título (sem o prefixo de tipo, ex.: [FEATURE])')
54
- .option('--type <type>', 'Tipo: epic, feature, story, task, bug, spike ou rfc', 'feature')
54
+ .option('--type <type>', 'Tipo: initiative, epic, feature, story, task, bug, spike ou rfc', 'feature')
55
55
  .option('--parent <n>', 'Número da issue pai (cria como sub-issue dela)')
56
56
  .option('--body <text>', 'Descrição')
57
57
  .option('--priority <p>', 'Prioridade: P0, P1, P2 ou P3')
@@ -61,6 +61,18 @@ program
61
61
  await issue(options).catch(err => { console.error(err.message); process.exit(1); });
62
62
  });
63
63
 
64
+ program
65
+ .command('initiative')
66
+ .description('Atalho de `issue --type initiative` (nó raiz que agrupa Epics)')
67
+ .requiredOption('--title <title>', 'Título da initiative (sem o prefixo [INITIATIVE])')
68
+ .option('--body <text>', 'Descrição da initiative')
69
+ .option('--priority <p>', 'Prioridade: P0, P1, P2 ou P3 (adiciona label)')
70
+ .option('--area <area>', 'Área: Frontend, Backend, Mobile, Infra, DevOps ou Data')
71
+ .action(async (options) => {
72
+ const { initiative } = await import('../src/commands/initiative.mjs');
73
+ await initiative(options).catch(err => { console.error(err.message); process.exit(1); });
74
+ });
75
+
64
76
  program
65
77
  .command('feature')
66
78
  .description('Atalho de `issue --type feature`')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spec-wave/cli",
3
- "version": "0.3.1",
3
+ "version": "0.4.0",
4
4
  "description": "Setup spec-driven GitHub workflow with Projects v2, labels, issue templates, and AI-powered Actions",
5
5
  "type": "module",
6
6
  "bin": {
@@ -122,7 +122,7 @@ export async function init(options) {
122
122
  labelSpinner.start('Criando labels...');
123
123
  try {
124
124
  await setupLabels(token, owner, repo, labelSpinner);
125
- labelSpinner.stop('Labels criadas (15 labels)');
125
+ labelSpinner.stop('Labels criadas (16 labels)');
126
126
  } catch (err) {
127
127
  labelSpinner.stop('');
128
128
  p.log.error(`Erro ao criar labels: ${err.message}`);
@@ -0,0 +1,8 @@
1
+ import { issue } from './issue.mjs';
2
+
3
+ // `initiative` é um atalho de `issue --type initiative`. A Initiative é o nó raiz
4
+ // da hierarquia (Initiative → Epic → Feature → Story → Task) e agrupa Epics.
5
+ // Toda a lógica vive em issue.mjs.
6
+ export async function initiative(options) {
7
+ return issue({ ...options, type: 'initiative' });
8
+ }
@@ -179,8 +179,13 @@ export async function issue(options) {
179
179
  }
180
180
 
181
181
  const parentLine = parent ? ` (sub-issue de #${parent.number})` : '';
182
+ const hints = {
183
+ Feature: `Próximo: \`/spec-wave plan ${created.number}\` para o planejamento técnico.`,
184
+ Initiative: `Próximo: crie Epics sob esta Initiative com \`spec-wave issue --type epic --parent ${created.number} --title "..."\`.`,
185
+ Epic: `Próximo: crie Features sob este Epic com \`spec-wave feature --parent ${created.number} --title "..."\`.`,
186
+ };
182
187
  p.outro(
183
188
  `${chalk.green('✓')} ${type} #${created.number} criado em "${INITIAL_STAGE}"${parentLine}.\n` +
184
- ` ${type === 'Feature' ? `Próximo: \`/spec-wave plan ${created.number}\` para o planejamento técnico.` : ''}`
189
+ ` ${hints[type] || ''}`
185
190
  );
186
191
  }
package/src/config.mjs CHANGED
@@ -53,6 +53,7 @@ export const CUSTOM_FIELDS = [
53
53
  name: 'Work Item Type',
54
54
  dataType: 'SINGLE_SELECT',
55
55
  options: [
56
+ { name: 'Initiative', color: 'PINK', description: 'Agrupamento estratégico de Epics' },
56
57
  { name: 'Epic', color: 'PURPLE', description: 'Objetivo estratégico' },
57
58
  { name: 'Feature', color: 'BLUE', description: 'Capacidade funcional' },
58
59
  { name: 'Story', color: 'GREEN', description: 'Necessidade do usuário' },
@@ -110,6 +111,7 @@ export const WORK_ITEM_TYPES = CUSTOM_FIELDS
110
111
  .options.map(o => o.name);
111
112
 
112
113
  export const TYPE_LABELS = [
114
+ { name: '[INITIATIVE]', color: 'C5DEF5', description: 'Agrupamento estratégico de Epics' },
113
115
  { name: '[EPIC]', color: '7B61FF', description: 'Objetivo estratégico' },
114
116
  { name: '[FEATURE]', color: '0075CA', description: 'Capacidade funcional' },
115
117
  { name: '[STORY]', color: '0E8A16', description: 'Necessidade do usuário' },