@spec-wave/cli 0.5.2 → 0.5.5

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@spec-wave/cli",
3
- "version": "0.5.2",
3
+ "version": "0.5.5",
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": {
@@ -75,6 +75,7 @@ export async function generatePlan({ issueNumber }) {
75
75
  git(`git config user.name "spec-wave[bot]"`);
76
76
  git(`git add "${filePath}"`);
77
77
  git(`git commit -m "docs: generate plan.md for ${slug} [spec-wave]"`);
78
+ git('git pull --rebase');
78
79
  git('git push');
79
80
 
80
81
  // Remove trigger label
@@ -84,7 +85,7 @@ export async function generatePlan({ issueNumber }) {
84
85
  await commentOnIssue(
85
86
  token, owner, repo, parseInt(issueNumber, 10),
86
87
  `📋 **plan.md gerado automaticamente!**\n\n` +
87
- `📄 Arquivo: [\`${filePath}\`](${filePath})\n\n` +
88
+ `📄 Arquivo: [\`${filePath}\`](https://github.com/${owner}/${repo}/blob/main/${filePath})\n\n` +
88
89
  `Revise o plano e, quando estiver pronto, valide a Feature: mova o card para **✅ Ready** ou use:\n` +
89
90
  `\`\`\`\ngh issue edit ${issueNumber} --add-label "spec-wave:ready"\n\`\`\``
90
91
  );
@@ -68,6 +68,7 @@ export async function generateSpec({ issueNumber }) {
68
68
  git(`git config user.name "spec-wave[bot]"`);
69
69
  git(`git add "${filePath}"`);
70
70
  git(`git commit -m "docs: generate spec.md for ${slug} [spec-wave]"`);
71
+ git('git pull --rebase');
71
72
  git('git push');
72
73
 
73
74
  // Remove trigger label
@@ -77,7 +78,7 @@ export async function generateSpec({ issueNumber }) {
77
78
  await commentOnIssue(
78
79
  token, owner, repo, parseInt(issueNumber, 10),
79
80
  `📋 **spec.md gerado automaticamente!**\n\n` +
80
- `📄 Arquivo: [\`${filePath}\`](${filePath})\n\n` +
81
+ `📄 Arquivo: [\`${filePath}\`](https://github.com/${owner}/${repo}/blob/main/${filePath})\n\n` +
81
82
  `Revise a especificação e, quando estiver pronto, gere o plano técnico: mova o card para **📋 Plan** ou use:\n` +
82
83
  `\`\`\`\ngh issue edit ${issueNumber} --add-label "spec-wave:plan"\n\`\`\``
83
84
  );
@@ -2,54 +2,9 @@ import { existsSync, readFileSync } from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import { resolveToken } from '../api/auth.mjs';
4
4
  import { getIssue, removeLabel, addLabel, commentOnIssue } from '../api/github-rest.mjs';
5
- import { addProjectItem, setItemSingleSelect, getSingleSelectField } from '../api/github-graphql.mjs';
6
5
  import { slugify } from '../lib/slugify.mjs';
7
6
  import { CONFIG_FILE, REQUIRED_PLAN_SECTIONS, REQUIRED_SPEC_SECTIONS } from '../config.mjs';
8
7
 
9
- // Opção nativa do campo Status do GitHub Projects (Todo / In Progress / Done).
10
- const DONE_STAGE = 'Done';
11
-
12
- // Resolve um campo SINGLE_SELECT pelo nome: usa o .spec-wave.json, cai para o
13
- // formato legado (etapaFieldId/stageOptions) e, por fim, consulta o Project.
14
- async function resolveField(token, project, name) {
15
- if (project.fields && project.fields[name]) return project.fields[name];
16
- if (name === 'Etapa' && project.etapaFieldId) {
17
- return { id: project.etapaFieldId, options: project.stageOptions || {} };
18
- }
19
- return await getSingleSelectField(token, project.id, name);
20
- }
21
-
22
- // Move o item da issue para a Etapa "🎉 Done" no board. Best-effort: loga e
23
- // segue se o .spec-wave.json não tiver o Project ou o campo não for encontrado.
24
- async function moveToDone(token, issue) {
25
- const configPath = path.join(process.cwd(), CONFIG_FILE);
26
- if (!existsSync(configPath)) {
27
- console.warn(`${CONFIG_FILE} não encontrado — status do board não atualizado.`);
28
- return;
29
- }
30
- let project;
31
- try {
32
- project = (JSON.parse(readFileSync(configPath, 'utf-8')).project) || {};
33
- } catch (err) {
34
- console.warn(`${CONFIG_FILE} corrompido (${err.message}) — status do board não atualizado.`);
35
- return;
36
- }
37
- if (!project.id) {
38
- console.warn(`Project não configurado no ${CONFIG_FILE} — status do board não atualizado.`);
39
- return;
40
- }
41
- // addProjectItem é idempotente: retorna o item existente se a issue já está no board.
42
- const itemId = await addProjectItem(token, project.id, issue.node_id);
43
- const field = await resolveField(token, project, 'Status');
44
- const optionId = field?.options?.[DONE_STAGE];
45
- if (field?.id && optionId) {
46
- await setItemSingleSelect(token, project.id, itemId, field.id, optionId);
47
- console.log(`Status do board atualizado para "${DONE_STAGE}".`);
48
- } else {
49
- console.warn(`Etapa "${DONE_STAGE}" não encontrada no Project — status do board não atualizado.`);
50
- }
51
- }
52
-
53
8
  export async function validate({ issueNumber }) {
54
9
  const token = await resolveToken();
55
10
  const [envOwner, envRepo] = (process.env.GITHUB_REPOSITORY || '').split('/');
@@ -114,23 +69,14 @@ export async function validate({ issueNumber }) {
114
69
  process.exit(1);
115
70
  }
116
71
 
117
- // Validação passou: adiciona label plan-approved e move board para Done.
72
+ // Validação passou: adiciona label plan-approved.
118
73
  await addLabel(token, owner, repo, parseInt(issueNumber, 10), 'spec-wave:plan-approved');
119
74
 
120
- let doneOk = false;
121
- try {
122
- await moveToDone(token, issue);
123
- doneOk = !!DONE_STAGE;
124
- } catch (err) {
125
- console.warn(`Falha ao atualizar status do board: ${err.message}`);
126
- }
127
-
128
75
  await commentOnIssue(
129
76
  token, owner, repo, parseInt(issueNumber, 10),
130
77
  `✅ **Validação concluída com sucesso!**\n\n` +
131
78
  `- [\`${specPath}\`](${specPath}) ✓\n` +
132
79
  `- [\`${planPath}\`](${planPath}) ✓\n\n` +
133
- (doneOk ? `Status movido para **${DONE_STAGE}**. ` : '') +
134
80
  `A Feature está pronta para decomposição. Use:\n` +
135
81
  `\`\`\`\ngh issue edit ${issueNumber} --add-label "spec-wave:decompose"\n\`\`\``
136
82
  );