@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 +14 -2
- package/package.json +1 -1
- package/src/commands/init.mjs +1 -1
- package/src/commands/initiative.mjs +8 -0
- package/src/commands/issue.mjs +6 -1
- package/src/config.mjs +2 -0
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
package/src/commands/init.mjs
CHANGED
|
@@ -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 (
|
|
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
|
+
}
|
package/src/commands/issue.mjs
CHANGED
|
@@ -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
|
|
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' },
|