create-agentic-pdlc 3.1.0 → 3.1.2

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.
Files changed (2) hide show
  1. package/bin/cli.js +62 -11
  2. package/package.json +1 -1
package/bin/cli.js CHANGED
@@ -75,7 +75,11 @@ const i18n = {
75
75
  update_sentinel_ask: t(" Activate? CodeRabbit applies 'architecture-violation' label when violations are detected. (Y/n): ", " Ativar? CodeRabbit aplica a label 'architecture-violation' quando detecta violações. (S/n): ", " ¿Activar? CodeRabbit aplica la etiqueta 'architecture-violation' cuando detecta violaciones. (S/n): "),
76
76
  configuring_protection: t('[3/3] Configuring branch protection...', '[3/3] Configurando proteção de branch...', '[3/3] Configurando protección de rama...'),
77
77
  protection_ok: t('✅ Branch protection set — required checks: PDLC Stage Gate, QA Gate.', '✅ Proteção de branch configurada — checks obrigatórios: PDLC Stage Gate, QA Gate.', '✅ Protección de rama configurada — checks requeridos: PDLC Stage Gate, QA Gate.'),
78
- protection_warn: t('⚠️ Branch protection could not be set automatically.\n Set required checks manually: Settings → Branches → main → Required status checks.\n Required: "PDLC Stage Gate" and "QA Gate"', '⚠️ Proteção de branch não pôde ser configurada automaticamente.\n Configure manualmente: Settings → Branches → main → Required status checks.\n Obrigatórios: "PDLC Stage Gate" e "QA Gate"', '⚠️ No se pudo configurar la protección de rama automáticamente.\n Configúralo en: Settings → Branches → main → Required status checks.\n Requeridos: "PDLC Stage Gate" y "QA Gate"'),
78
+ protection_warn: t(
79
+ '⚠️ Branch protection requires admin access — could not be set automatically.\n\n What it does: prevents PRs from merging unless these CI checks pass:\n • "PDLC Stage Gate" — blocks merge if the linked issue lacks spec:approved\n • "QA Gate" — blocks merge if automated QA checks failed\n\n Without it: the workflow still runs, but PRs can be merged without approval.\n\n To enable: Settings → Branches → main → Required status checks\n Add: "PDLC Stage Gate" and "QA Gate"',
80
+ '⚠️ Proteção de branch requer acesso de admin — não pôde ser configurada automaticamente.\n\n O que faz: impede que PRs sejam mergeados sem que esses checks de CI passem:\n • "PDLC Stage Gate" — bloqueia merge se a issue não tiver spec:approved\n • "QA Gate" — bloqueia merge se os checks automáticos de QA falharem\n\n Sem ela: o workflow continua funcionando, mas PRs podem ser mergeados sem aprovação.\n\n Para ativar: Settings → Branches → main → Required status checks\n Adicionar: "PDLC Stage Gate" e "QA Gate"',
81
+ '⚠️ La protección de rama requiere acceso de administrador — no se pudo configurar automáticamente.\n\n Qué hace: impide que los PRs se fusionen sin que pasen estos checks de CI:\n • "PDLC Stage Gate" — bloquea el merge si la issue no tiene spec:approved\n • "QA Gate" — bloquea el merge si los checks automáticos de QA fallaron\n\n Sin ella: el flujo sigue funcionando, pero los PRs se pueden fusionar sin aprobación.\n\n Para activar: Settings → Branches → main → Required status checks\n Agregar: "PDLC Stage Gate" y "QA Gate"'
82
+ ),
79
83
  issue_templates_copied: t(
80
84
  '✅ Issue templates copied to .github/ISSUE_TEMPLATE/',
81
85
  '✅ Issue templates copiados para .github/ISSUE_TEMPLATE/',
@@ -91,6 +95,21 @@ const i18n = {
91
95
  '⚠️ Não foi possível configurar vars.PROJECT_ID — o token pode não ter permissão variables:write.\n Configure manualmente: repo Settings → Secrets and variables → Variables → PROJECT_ID = ',
92
96
  '⚠️ No se pudo configurar vars.PROJECT_ID — el token puede no tener permiso variables:write.\n Configura manualmente: repo Settings → Secrets and variables → Variables → PROJECT_ID = '
93
97
  ),
98
+ gh_not_installed: t(
99
+ '\n⚠️ GitHub CLI (gh) is not installed. Skipping label creation.',
100
+ '\n⚠️ GitHub CLI (gh) não está instalado. Pulando criação de labels.',
101
+ '\n⚠️ GitHub CLI (gh) no está instalado. Omitiendo creación de etiquetas.'
102
+ ),
103
+ repo_context_missing: t(
104
+ '\n⚠️ Repository owner or name missing in cli-context.json. Automatic label creation will be skipped.',
105
+ '\n⚠️ Dono ou nome do repositório ausente em cli-context.json. Criação automática de labels será pulada.',
106
+ '\n⚠️ Propietario o nombre del repositorio faltante en cli-context.json. Se omitirá la creación automática de etiquetas.'
107
+ ),
108
+ protection_private_repo: t(
109
+ '⚠️ GitHub allows Branch Protection only for public repos (or a paid plan).\n 👌 Don\'t worry, the workflow still runs smoothly, but PRs can be merged without approval.',
110
+ '⚠️ O GitHub permite Branch Protection apenas para repos públicos (ou plano pago).\n 👌 Sem problemas, o workflow continua funcionando normalmente, mas PRs podem ser mergeados sem aprovação.',
111
+ '⚠️ GitHub permite Branch Protection solo para repos públicos (o un plan de pago).\n 👌 No te preocupes, el workflow sigue funcionando normalmente, pero los PRs pueden fusionarse sin aprobación.'
112
+ ),
94
113
  };
95
114
 
96
115
  const cyan = '\x1b[36m';
@@ -100,19 +119,23 @@ const yellow = '\x1b[33m';
100
119
  const red = '\x1b[31m';
101
120
 
102
121
  const PDLC_LABELS = [
103
- { name: 'stage:exploration', color: '9b59b6', description: 'Issue is being evaluated' },
104
122
  { name: 'stage:brainstorming', color: 'e84393', description: 'Proposed approaches awaiting PM gate' },
105
123
  { name: 'stage:detailing', color: '3498db', description: 'Technical spec is being written' },
106
124
  { name: 'stage:development', color: 'e67e22', description: 'Agent is implementing the spec' },
107
- { name: 'stage:testing', color: '8e44ad', description: 'Agent is testing the implementation' },
108
125
  { name: 'spec:approved', color: '0e8a16', description: 'Spec approved — agent can implement' },
109
126
  { name: 'pr:in-review', color: 'e4e669', description: 'PR awaiting code review' },
110
127
  { name: 'pr:approved', color: '0e8a16', description: 'PR approved, ready for merge' },
111
128
  { name: 'architecture-violation', color: 'd93f0b', description: 'Invariant violation detected by CI' },
112
- { name: 'qa:approved', color: '0e8a16', description: 'QA Agent approved the implementation' },
113
- { name: 'qa:needs-work', color: 'd93f0b', description: 'QA Agent found issues' },
114
- { name: 'infra:qa-broken', color: 'F97316', description: 'QA Agent failed to run — manual review required' },
115
- { name: 'jules', color: '5319e7', description: 'Jules AI Agent' }
129
+ ];
130
+
131
+ const JULES_LABELS = [
132
+ { name: 'jules', color: '5319e7', description: 'Jules AI Agent' },
133
+ ];
134
+
135
+ const QA_LABELS = [
136
+ { name: 'qa:approved', color: '0e8a16', description: 'QA Agent approved the implementation' },
137
+ { name: 'qa:needs-work', color: 'd93f0b', description: 'QA Agent found issues' },
138
+ { name: 'infra:qa-broken',color: 'F97316', description: 'QA Agent failed to run — manual review required' },
116
139
  ];
117
140
 
118
141
  function buildBoardUrl(repoOwner, projectNumber, isOrg) {
@@ -227,10 +250,17 @@ function installHook(sourceDir, targetDir) {
227
250
  async function setBranchProtection(repo, requiredChecks) {
228
251
  console.log(`\n${cyan}${i18n.configuring_protection}${reset}`);
229
252
  try {
230
- const defaultBranch = execFileSync(
231
- 'gh', ['api', `repos/${repo}`, '--jq', '.default_branch'],
253
+ const repoInfo = JSON.parse(execFileSync(
254
+ 'gh', ['api', `repos/${repo}`, '--jq', '{private: .private, default_branch: .default_branch}'],
232
255
  { stdio: ['ignore', 'pipe', 'ignore'], encoding: 'utf8' }
233
- ).trim() || 'main';
256
+ ).trim());
257
+
258
+ if (repoInfo.private) {
259
+ console.log(` ${yellow}${i18n.protection_private_repo}${reset}`);
260
+ return;
261
+ }
262
+
263
+ const defaultBranch = repoInfo.default_branch || 'main';
234
264
 
235
265
  const protectionPayload = JSON.stringify({
236
266
  required_status_checks: { strict: false, contexts: requiredChecks },
@@ -293,6 +323,19 @@ function scaffoldLiteTemplates(sourceDir, targetDir) {
293
323
  }
294
324
  }
295
325
 
326
+ function createLabelsForRepo(labels, repo) {
327
+ for (const label of labels) {
328
+ try {
329
+ execFileSync('gh', ['label', 'create', label.name, '--color', label.color, '--description', label.description, '--repo', repo, '--force'], { stdio: 'ignore' });
330
+ } catch (err) {
331
+ if (err.code === 'ENOENT') {
332
+ console.warn(i18n.gh_not_installed);
333
+ break;
334
+ }
335
+ }
336
+ }
337
+ }
338
+
296
339
  function setActionsVariable(repo, name, value, execFn = execFileSync) {
297
340
  try {
298
341
  execFn('gh', [
@@ -753,6 +796,10 @@ async function runUpdate() {
753
796
  return;
754
797
  }
755
798
 
799
+ const repo = ctx.repoOwner && ctx.repoName ? `${ctx.repoOwner}/${ctx.repoName}` : null;
800
+ if (!repo) {
801
+ console.warn(`${yellow}${i18n.repo_context_missing}${reset}`);
802
+ }
756
803
  const paPath = path.join(targetDir, '.github', 'workflows', 'project-automation.yml');
757
804
  const atPath = path.join(targetDir, '.github', 'workflows', 'agent-trigger.yml');
758
805
  const results = [];
@@ -761,11 +808,14 @@ async function runUpdate() {
761
808
  console.log(`\n${cyan}${i18n.update_jules_header}${reset}`);
762
809
  const choice = (await askQuestion(i18n.update_jules_ask)).trim().toLowerCase();
763
810
  if (choice === 'a' || choice === '') {
811
+ if (repo) createLabelsForRepo(JULES_LABELS, repo);
764
812
  configureJules(atPath, '@google-labs-jules', 'jules');
765
813
  results.push(t('✅ Jules configured (@google-labs-jules)', '✅ Jules configurado (@google-labs-jules)', '✅ Jules configurado (@google-labs-jules)'));
766
814
  } else if (choice === 'b') {
767
815
  const handle = (await askQuestion(i18n.update_jules_ask_handle)).trim();
768
- configureJules(atPath, handle, handle.replace('@', '').toLowerCase());
816
+ const labelName = handle.replace('@', '').toLowerCase();
817
+ if (repo) createLabelsForRepo([{ name: labelName, color: '5319e7', description: `${handle} AI Agent` }], repo);
818
+ configureJules(atPath, handle, labelName);
769
819
  results.push(t(`✅ Agent configured (${handle})`, `✅ Agente configurado (${handle})`, `✅ Agente configurado (${handle})`));
770
820
  } else {
771
821
  results.push(t('⏭ Jules — skipped', '⏭ Jules — pulado', '⏭ Jules — omitido'));
@@ -776,6 +826,7 @@ async function runUpdate() {
776
826
  console.log(`\n${cyan}${i18n.update_qa_header}${reset}`);
777
827
  const answer = (await askQuestion(i18n.update_qa_ask)).trim().toLowerCase();
778
828
  if (!['n', 'no', 'não', 'nao'].includes(answer)) {
829
+ if (repo) createLabelsForRepo(QA_LABELS, repo);
779
830
  activateQaAgent(paPath);
780
831
  results.push(t(
781
832
  '✅ QA Agent configured — Variant B activated (uses GITHUB_TOKEN, no extra secrets needed)',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-agentic-pdlc",
3
- "version": "3.1.0",
3
+ "version": "3.1.2",
4
4
  "description": "Agentic PDLC Framework - Conversational setup for your AI coding assistants",
5
5
  "type": "commonjs",
6
6
  "bin": {