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.
- package/bin/cli.js +62 -11
- 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(
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
{ name: 'jules',
|
|
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
|
|
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()
|
|
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
|
-
|
|
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)',
|