clckernel 1.2.8 → 1.2.10
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/README.es.md +107 -22
- package/README.md +107 -22
- package/package.json +1 -1
- package/src/adapters/agent-os.js +24 -0
- package/src/generator.js +40 -62
- package/src/index.js +9 -2
- package/src/updater.js +92 -0
- package/tools/check_test_calendar_sync.js +111 -0
package/README.es.md
CHANGED
|
@@ -17,6 +17,19 @@ Los agentes de programación con IA (Cursor, Claude Code, Windsurf, Copilot) cod
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
+
## 📋 Tabla de Contenidos
|
|
21
|
+
- [🎯 Casos de Uso](#-casos-de-uso)
|
|
22
|
+
- [🏛️ El Proceso Unificado de IA (AIUP)](#️-el-proceso-unificado-de-ia-aiup)
|
|
23
|
+
- [⚡ Guía Paso a Paso (Ciclo Completo)](#-guía-paso-a-paso-ciclo-completo)
|
|
24
|
+
- [🎮 Interfaz Universal de Comandos](#-interfaz-universal-de-comandos)
|
|
25
|
+
- [🔄 Actualización de Proyectos Existentes](#-actualización-de-proyectos-existentes)
|
|
26
|
+
- [🌐 Ecosistemas Soportados y Arquetipos](#-ecosistemas-soportados-y-arquetipos)
|
|
27
|
+
- [🧩 Herramientas Complementarias (Opcionales)](#-herramientas-complementarias-opcionales)
|
|
28
|
+
- [📄 Licencia](#-licencia)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
<a id="casos-de-uso"></a>
|
|
20
33
|
## 🎯 Casos de Uso
|
|
21
34
|
|
|
22
35
|
| Caso de Uso | Problema que Resuelve | Cómo lo Resuelve CLC Kernel |
|
|
@@ -28,6 +41,7 @@ Los agentes de programación con IA (Cursor, Claude Code, Windsurf, Copilot) cod
|
|
|
28
41
|
|
|
29
42
|
---
|
|
30
43
|
|
|
44
|
+
<a id="aiup"></a>
|
|
31
45
|
## 🏛️ El Proceso Unificado de IA (AIUP)
|
|
32
46
|
|
|
33
47
|
```
|
|
@@ -48,6 +62,97 @@ Los agentes de programación con IA (Cursor, Claude Code, Windsurf, Copilot) cod
|
|
|
48
62
|
|
|
49
63
|
---
|
|
50
64
|
|
|
65
|
+
<a id="guia-paso-a-paso"></a>
|
|
66
|
+
## ⚡ Guía Paso a Paso (Ciclo Completo)
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
[1. Terminal] [2. Chat del LLM] [3. Bucle TDD] [4. Git Commit]
|
|
70
|
+
npx clckernel ───► clckernel start ───► "Feature X con harness" ───► Hooks Pre-commit
|
|
71
|
+
(Bootstrap) (Setup Interactivo) (SDD -> HIT -> Tests) (Guardián AST & Secretos)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 1️⃣ Paso 1: Inicializar el Repositorio (Terminal)
|
|
75
|
+
```bash
|
|
76
|
+
npx clckernel start
|
|
77
|
+
```
|
|
78
|
+
Detecta el framework, genera `AGENTS.md`, crea symlinks dinámicos para todos los IDEs (`CLAUDE.md`, `GEMINI.md`, `.cursorrules`), provisiona hooks pre-commit e instala verificadores AST en `tools/`.
|
|
79
|
+
|
|
80
|
+
### 2️⃣ Paso 2: Inicializar en el Chat del IDE (CLI Conversacional)
|
|
81
|
+
Abrí Cursor, Claude Code, Gemini CLI, Windsurf o Copilot y escribí:
|
|
82
|
+
> `clckernel start`
|
|
83
|
+
|
|
84
|
+
El agente escanea tu código en silencio, propone un plan de gobernanza adaptado a tu stack y genera `.clckernel.yaml`.
|
|
85
|
+
|
|
86
|
+
### 3️⃣ Paso 3: Desarrollar con el Arnés AIUP
|
|
87
|
+
Al solicitar una funcionalidad o corrección, indicá al agente:
|
|
88
|
+
> *"Implementa el endpoint de autenticación. **Usa el harness de CLC Kernel**."*
|
|
89
|
+
|
|
90
|
+
El agente ejecutará de forma autónoma el ciclo AIUP completo:
|
|
91
|
+
1. **Investigación y Causa Raíz:** Inspecciona el código base y dependencias.
|
|
92
|
+
2. **Especificación SDD Local:** Redacta contratos de API y planes de prueba en `sdds/{cambio}/spec.md`.
|
|
93
|
+
3. **Revisión HIT:** Solicita tu revisión y aprobación de los contratos propuestos.
|
|
94
|
+
4. **Fase Roja TDD:** Escribe un test de regresión que falle demostrando el requerimiento.
|
|
95
|
+
5. **Implementación Verde:** Escribe el código mínimo necesario respetando el aislamiento de capas.
|
|
96
|
+
6. **Compuerta de Auditoría AST:** Ejecuta `node tools/audit.js` y emite el resumen de verificación.
|
|
97
|
+
|
|
98
|
+
### 4️⃣ Paso 4: Verificación Determinística de Guards (Git Commit)
|
|
99
|
+
```bash
|
|
100
|
+
git add .
|
|
101
|
+
git commit -m "feat(auth): add user authentication endpoint"
|
|
102
|
+
```
|
|
103
|
+
Los hooks pre-commit ejecutan automáticamente los escáneres AST (Clean Architecture, Fuga de Secretos, Scope Guard, Idempotencia de Migraciones). Cualquier violación **bloquea físicamente** el commit.
|
|
104
|
+
|
|
105
|
+
### 5️⃣ Paso 5: Auditar la Salud del Repositorio en Cualquier Momento (Doctor)
|
|
106
|
+
```bash
|
|
107
|
+
npx clckernel doctor
|
|
108
|
+
```
|
|
109
|
+
Audita el 100% de cumplimiento en `AGENTS.md`, `sdds/`, `tools/`, runners de pruebas activos y hooks de Git.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
<a id="interfaz-universal-de-comandos"></a>
|
|
114
|
+
## 🎮 Interfaz Universal de Comandos (Todos los LLMs y Agentes)
|
|
115
|
+
|
|
116
|
+
CLC Kernel provee una gramática de comandos determinista soportada de forma nativa por **Claude Code, Cursor, Codeium/Windsurf, Copilot, Gemini y Antigravity**:
|
|
117
|
+
|
|
118
|
+
| Comando | Categoría | Protocolo de Ejecución Obligatorio |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| `clckernel feature <nombre>` | Funcionalidad | Ciclo AIUP completo: Investigación -> Spec Local (`sdds/{nombre}/spec.md`) -> Revisión HIT -> Fase Roja TDD -> Implementación Verde -> Auditoría. |
|
|
121
|
+
| `clckernel fix <descripción>` | Corrección | Análisis de causa raíz (sin editar código) -> Test de regresión que falle -> Corrección quirúrgica limpia -> Compuerta de auditoría. |
|
|
122
|
+
| `clckernel test` | Verificación | Ejecuta la suite de pruebas en el runner nativo del stack y confirma estado verde limpio. |
|
|
123
|
+
| `clckernel audit` | Verificación | Ejecuta `node tools/audit.js` o `python tools/audit.py` y emite el Resumen Educativo. |
|
|
124
|
+
| `clckernel doctor` | Diagnóstico | Valida hooks pre-commit de Git, symlinks espejo para IDEs e integridad del motor AST. |
|
|
125
|
+
| `clckernel commit <mensaje>` | Control de Versiones | Auditoría pre-flight, verificación de scope diff vs SDD y commit con Conventional Commits (cero atribución de IA). |
|
|
126
|
+
| `clckernel guard create <nombre>` | Salvaguardas | Genera el scaffold de un nuevo script de guard AST en el lenguaje nativo del stack en `tools/guards/`. |
|
|
127
|
+
| `clckernel update` | Mantenimiento | Actualización no destructiva: refresca herramientas core, skills y symlinks de IDEs sin sobreescribir SDDs, guards personalizados ni `.clckernel.yaml`. |
|
|
128
|
+
| `clckernel start` | Configuración | Detecta el stack automáticamente, propone el ciclo de vida AIUP y genera `.clckernel.yaml`. |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
<a id="actualizacion-de-proyectos-existentes"></a>
|
|
133
|
+
## 🔄 Actualización de Proyectos Existentes (No Destructiva)
|
|
134
|
+
|
|
135
|
+
Cuando se publican nuevas versiones de CLC Kernel con nuevos guards AST, playbooks actualizados o reglas optimizadas para IDEs, podés actualizar tu repositorio de forma segura sin perder tu trabajo:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
npx clckernel update
|
|
139
|
+
```
|
|
140
|
+
O directamente desde el chat de tu agente IA:
|
|
141
|
+
```bash
|
|
142
|
+
clckernel update
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 🔒 La Garantía de Actualización No Destructiva:
|
|
146
|
+
- **Refresca y Actualiza:** Orquestadores centrales (`tools/audit.js`, `tools/audit.py`), guards AST nativos, Skills de agentes (`.agents/skills/`) y symlinks de IDEs (`CLAUDE.md`, `GEMINI.md`, `.cursorrules`, Copilot, Antigravity).
|
|
147
|
+
- **100% Preservado:**
|
|
148
|
+
- `sdds/`: Todas las especificaciones locales, planes y recibos de verificación permanecen intactos.
|
|
149
|
+
- `tools/guards/`: Todos los guards AST personalizados creados por el equipo se conservan sin modificaciones.
|
|
150
|
+
- `.clckernel.yaml`: Todas las configuraciones y umbrales personalizados se mantienen.
|
|
151
|
+
- El código fuente de la aplicación y modelos de dominio jamás se tocan.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
<a id="ecosistemas-soportados"></a>
|
|
51
156
|
## 🌐 Ecosistemas Soportados y Arquetipos
|
|
52
157
|
|
|
53
158
|
| Ecosistema | Firma de Detección | Test Runner | Salvaguardas Nativas |
|
|
@@ -64,28 +169,7 @@ Los agentes de programación con IA (Cursor, Claude Code, Windsurf, Copilot) cod
|
|
|
64
169
|
|
|
65
170
|
---
|
|
66
171
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
### 1. Inicializar en Terminal
|
|
70
|
-
```bash
|
|
71
|
-
npx clckernel start
|
|
72
|
-
```
|
|
73
|
-
Detecta el framework, genera `AGENTS.md`, crea symlinks para todos los IDEs, provisiona hooks pre-commit e instala verificadores AST en `tools/`.
|
|
74
|
-
|
|
75
|
-
### 2. Verificar Estado de Salud
|
|
76
|
-
```bash
|
|
77
|
-
npx clckernel doctor
|
|
78
|
-
```
|
|
79
|
-
Audita hooks de Git, test runners activos y la integridad del motor AST.
|
|
80
|
-
|
|
81
|
-
### 3. Desarrollar con Gobernanza
|
|
82
|
-
En el chat del IDE (Cursor, Claude Code, Gemini CLI, Windsurf):
|
|
83
|
-
> *"Implementa el endpoint de autenticación. **Usa el harness de CLC Kernel**."*
|
|
84
|
-
|
|
85
|
-
El agente ejecutará el ciclo AIUP completo: **Especificación SDD -> Aprobación HIT -> Test Rojo -> Implementación Verde -> Auditoría AST**.
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
172
|
+
<a id="herramientas-complementarias"></a>
|
|
89
173
|
## 🧩 Herramientas Complementarias (Opcionales)
|
|
90
174
|
|
|
91
175
|
CLC Kernel se enfoca estrictamente en gobernanza y opera con **cero dependencias foráneas**. Se integra de forma modular con:
|
|
@@ -95,5 +179,6 @@ CLC Kernel se enfoca estrictamente en gobernanza y opera con **cero dependencias
|
|
|
95
179
|
|
|
96
180
|
---
|
|
97
181
|
|
|
182
|
+
<a id="licencia"></a>
|
|
98
183
|
## 📄 Licencia
|
|
99
184
|
MIT © [CarlosLeonCode](https://github.com/carlosleoncode)
|
package/README.md
CHANGED
|
@@ -17,6 +17,19 @@ AI coding agents (Cursor, Claude Code, Windsurf, Copilot) code fast, but without
|
|
|
17
17
|
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
+
## 📋 Table of Contents
|
|
21
|
+
- [🎯 Use Cases](#-use-cases)
|
|
22
|
+
- [🏛️ The AI Unified Process (AIUP)](#️-the-ai-unified-process-aiup)
|
|
23
|
+
- [⚡ Step-by-Step Guide (Full Lifecycle)](#-step-by-step-guide-full-lifecycle)
|
|
24
|
+
- [🎮 Universal Command Interface](#-universal-command-interface)
|
|
25
|
+
- [🔄 Updating an Existing Project](#-updating-an-existing-project)
|
|
26
|
+
- [🌐 Supported Stacks & Archetypes](#-supported-stacks--archetypes)
|
|
27
|
+
- [🧩 Optional Ecosystem Companions](#-optional-ecosystem-companions)
|
|
28
|
+
- [📄 License](#-license)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
<a id="use-cases"></a>
|
|
20
33
|
## 🎯 Use Cases
|
|
21
34
|
|
|
22
35
|
| Use Case | Problem It Solves | How CLC Kernel Solves It |
|
|
@@ -28,6 +41,7 @@ AI coding agents (Cursor, Claude Code, Windsurf, Copilot) code fast, but without
|
|
|
28
41
|
|
|
29
42
|
---
|
|
30
43
|
|
|
44
|
+
<a id="aiup"></a>
|
|
31
45
|
## 🏛️ The AI Unified Process (AIUP)
|
|
32
46
|
|
|
33
47
|
```
|
|
@@ -48,6 +62,97 @@ AI coding agents (Cursor, Claude Code, Windsurf, Copilot) code fast, but without
|
|
|
48
62
|
|
|
49
63
|
---
|
|
50
64
|
|
|
65
|
+
<a id="step-by-step-guide"></a>
|
|
66
|
+
## ⚡ Step-by-Step Guide (Full Lifecycle)
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
[1. Terminal] [2. AI Chat] [3. TDD Loop] [4. Git Commit]
|
|
70
|
+
npx clckernel ───► clckernel start ───► "Feature X with harness" ───► Pre-commit Hooks
|
|
71
|
+
(Bootstrap) (Interactive Setup) (SDD -> HIT -> Tests) (AST & Secret Guard)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 1️⃣ Step 1: Bootstrap the Repository (Terminal)
|
|
75
|
+
```bash
|
|
76
|
+
npx clckernel start
|
|
77
|
+
```
|
|
78
|
+
Auto-detects your framework, generates `AGENTS.md`, creates dynamic IDE symlinks (`CLAUDE.md`, `GEMINI.md`, `.cursorrules`), provisions pre-commit hooks, and creates native AST checks in `tools/`.
|
|
79
|
+
|
|
80
|
+
### 2️⃣ Step 2: Initialize in Your AI Chat (Conversational CLI)
|
|
81
|
+
Open Cursor, Claude Code, Gemini CLI, Windsurf, or Copilot and type:
|
|
82
|
+
> `clckernel start`
|
|
83
|
+
|
|
84
|
+
The agent scans your codebase silently, proposes an AIUP governance plan tailored to your framework, and generates `.clckernel.yaml`.
|
|
85
|
+
|
|
86
|
+
### 3️⃣ Step 3: Develop with the AIUP Harness
|
|
87
|
+
When requesting features or bugfixes, instruct your agent:
|
|
88
|
+
> *"Add user authentication endpoint. **Follow the CLC Kernel harness**."*
|
|
89
|
+
|
|
90
|
+
The agent autonomously executes the complete AIUP cycle:
|
|
91
|
+
1. **Research & Root Cause Analysis:** Inspects codebase and dependencies.
|
|
92
|
+
2. **Local SDD Spec:** Writes API contracts and test plans in `sdds/{change}/spec.md`.
|
|
93
|
+
3. **HIT Review:** Requests your review and approval on proposed contracts.
|
|
94
|
+
4. **TDD Red Phase:** Writes a failing regression test proving the requirement.
|
|
95
|
+
5. **Clean Implementation (Green Phase):** Writes minimal code to pass tests while respecting layer isolation.
|
|
96
|
+
6. **AST Audit Gate:** Runs `node tools/audit.js` and outputs the verification summary.
|
|
97
|
+
|
|
98
|
+
### 4️⃣ Step 4: Deterministic Guard Verification (Git Commit)
|
|
99
|
+
```bash
|
|
100
|
+
git add .
|
|
101
|
+
git commit -m "feat(auth): add user authentication endpoint"
|
|
102
|
+
```
|
|
103
|
+
Pre-commit hooks automatically execute AST scanners (Clean Architecture, Secret Leaks, Scope Guard, Migration Idempotency). Any non-compliant commit is **physically blocked** before touching Git history.
|
|
104
|
+
|
|
105
|
+
### 5️⃣ Step 5: Verify Repository Health Anytime (Doctor)
|
|
106
|
+
```bash
|
|
107
|
+
npx clckernel doctor
|
|
108
|
+
```
|
|
109
|
+
Audits 100% compliance across `AGENTS.md`, `sdds/`, `tools/`, active test runners, and Git hooks.
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
<a id="universal-command-interface"></a>
|
|
114
|
+
## 🎮 Universal Command Interface (All LLMs & Agents)
|
|
115
|
+
|
|
116
|
+
CLC Kernel provides a deterministic command grammar supported natively by **Claude Code, Cursor, Codeium/Windsurf, Copilot, Gemini, and Antigravity**:
|
|
117
|
+
|
|
118
|
+
| Command | Category | Mandatory Execution Protocol |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| `clckernel feature <name>` | Feature | Full AIUP cycle: Research -> Local Spec (`sdds/{name}/spec.md`) -> HIT review -> TDD Red Phase -> Green Implementation -> Audit. |
|
|
121
|
+
| `clckernel fix <issue>` | Bug Fix | Root-cause analysis (no direct code edits) -> Failing regression test -> Surgical clean fix -> Audit gate. |
|
|
122
|
+
| `clckernel test` | Verification | Runs repository test suite in the native stack runner and confirms clean pass. |
|
|
123
|
+
| `clckernel audit` | Verification | Runs `node tools/audit.js` or `python tools/audit.py` and emits the Educational Summary. |
|
|
124
|
+
| `clckernel doctor` | Diagnostics | Checks Git pre-commit hooks, IDE mirror symlinks, and AST engine integrity. |
|
|
125
|
+
| `clckernel commit <message>` | Version Control | Pre-flight audit, verifies diff vs SDD scope, and commits with Conventional Commits (zero AI attribution). |
|
|
126
|
+
| `clckernel guard create <name>` | Safeguards | Scaffolds a new AST guard script in the stack's native language in `tools/guards/`. |
|
|
127
|
+
| `clckernel update` | Maintenance | Non-destructive update: refreshes core tools, skills & IDE symlinks without overwriting SDDs, custom guards, or `.clckernel.yaml`. |
|
|
128
|
+
| `clckernel start` | Setup | Auto-detects stack, proposes AIUP lifecycle, and generates `.clckernel.yaml`. |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
<a id="updating-an-existing-project"></a>
|
|
133
|
+
## 🔄 Updating an Existing Project (Non-Destructive)
|
|
134
|
+
|
|
135
|
+
When new versions of CLC Kernel are released with new AST guards, upgraded playbooks, or improved IDE rules, update your project safely without losing your work:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
npx clckernel update
|
|
139
|
+
```
|
|
140
|
+
Or from your AI agent chat:
|
|
141
|
+
```bash
|
|
142
|
+
clckernel update
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### 🔒 The Non-Destructive Update Guarantee:
|
|
146
|
+
- **Refreshes & Upgrades:** Core orchestrators (`tools/audit.js`, `tools/audit.py`), built-in AST guards, Agent Skills (`.agents/skills/`), and IDE symlinks (`CLAUDE.md`, `GEMINI.md`, `.cursorrules`, Copilot, Antigravity).
|
|
147
|
+
- **100% Preserved:**
|
|
148
|
+
- `sdds/`: All local specifications, plans, and verification receipts remain intact.
|
|
149
|
+
- `tools/guards/`: All team-authored custom AST guards are preserved without modification.
|
|
150
|
+
- `.clckernel.yaml`: All custom thresholds and active safeguard selections are preserved.
|
|
151
|
+
- Application source code and domain models are never touched.
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
<a id="supported-stacks"></a>
|
|
51
156
|
## 🌐 Supported Stacks & Archetypes
|
|
52
157
|
|
|
53
158
|
| Ecosystem | Detection Signature | Test Runner | Native Safeguards |
|
|
@@ -64,28 +169,7 @@ AI coding agents (Cursor, Claude Code, Windsurf, Copilot) code fast, but without
|
|
|
64
169
|
|
|
65
170
|
---
|
|
66
171
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
### 1. Initialize in Terminal
|
|
70
|
-
```bash
|
|
71
|
-
npx clckernel start
|
|
72
|
-
```
|
|
73
|
-
Auto-detects your framework, generates `AGENTS.md`, creates IDE rule symlinks, provisions pre-commit hooks, and creates native AST checks in `tools/`.
|
|
74
|
-
|
|
75
|
-
### 2. Verify Health
|
|
76
|
-
```bash
|
|
77
|
-
npx clckernel doctor
|
|
78
|
-
```
|
|
79
|
-
Audits Git hooks, active test runners, and AST engine integrity.
|
|
80
|
-
|
|
81
|
-
### 3. Develop with Agentic Governance
|
|
82
|
-
In your IDE chat (Cursor, Claude Code, Gemini CLI, Windsurf):
|
|
83
|
-
> *"Implement authentication endpoint. **Follow the CLC Kernel harness**."*
|
|
84
|
-
|
|
85
|
-
The agent executes the full AIUP loop: **SDD Spec -> HIT Review -> Failing Test (Red) -> Implementation (Green) -> AST Audit**.
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
172
|
+
<a id="ecosystem-companions"></a>
|
|
89
173
|
## 🧩 Optional Ecosystem Companions
|
|
90
174
|
|
|
91
175
|
CLC Kernel focuses strictly on governance and runs with **zero foreign dependencies**. It seamlessly integrates with companion tools:
|
|
@@ -95,5 +179,6 @@ CLC Kernel focuses strictly on governance and runs with **zero foreign dependenc
|
|
|
95
179
|
|
|
96
180
|
---
|
|
97
181
|
|
|
182
|
+
<a id="license"></a>
|
|
98
183
|
## 📄 License
|
|
99
184
|
MIT © [CarlosLeonCode](https://github.com/carlosleoncode)
|
package/package.json
CHANGED
package/src/adapters/agent-os.js
CHANGED
|
@@ -95,6 +95,13 @@ class AgentOSAdapter extends BaseAdapter {
|
|
|
95
95
|
command: 'node tools/check_domain_data.js',
|
|
96
96
|
description: 'Domain deliverables schema and clean state integrity'
|
|
97
97
|
},
|
|
98
|
+
{
|
|
99
|
+
name: 'check_test_calendar_sync',
|
|
100
|
+
language: 'node',
|
|
101
|
+
path: 'tools/check_test_calendar_sync.js',
|
|
102
|
+
command: 'node tools/check_test_calendar_sync.js',
|
|
103
|
+
description: 'Test calendar harness synchronization and parity check'
|
|
104
|
+
},
|
|
98
105
|
{
|
|
99
106
|
name: 'scan_secrets',
|
|
100
107
|
language: 'node',
|
|
@@ -146,6 +153,23 @@ When operating as domain agents for end-users and non-technical operators:
|
|
|
146
153
|
|
|
147
154
|
---
|
|
148
155
|
|
|
156
|
+
## 🎮 Universal Command Interface (All LLMs & Agents)
|
|
157
|
+
When given a command matching \`clckernel <action>\` or \`/clckernel <action>\`, execute the deterministic state machine below:
|
|
158
|
+
|
|
159
|
+
| Command | Lifecycle Phase | Mandatory Execution Protocol |
|
|
160
|
+
|---|---|---|
|
|
161
|
+
| \`clckernel feature <name>\` | New Feature | 1. Research affected layers.<br>2. Author local spec in \`sdds/{name}/spec.md\`.<br>3. Present HIT review to user and wait for approval.<br>4. Write failing test (Red Phase).<br>5. Implement clean code (Green Phase).<br>6. Run \`node tools/audit.js\` (or \`audit.py\`). |
|
|
162
|
+
| \`clckernel fix <issue>\` | Bug Fix | 1. Investigate root cause (no code edits).<br>2. Reproduce with failing test (Red Phase).<br>3. Minimal surgical fix respecting Clean Arch (Green Phase).<br>4. Run audit gate without skipping. |
|
|
163
|
+
| \`clckernel test\` | Verification | Run test suite and verify clean pass (exit code 0). |
|
|
164
|
+
| \`clckernel audit\` | Verification | Run \`node tools/audit.js\` or \`python tools/audit.py\` and output the Educational Summary. |
|
|
165
|
+
| \`clckernel doctor\` | Diagnostics | Check git pre-commit hooks, IDE symlinks, and AST engine integrity. |
|
|
166
|
+
| \`clckernel commit <message>\` | Version Control | Run full audit, verify tests pass, ensure no changes outside SDD scope, and commit with conventional commits (never add AI attribution). |
|
|
167
|
+
| \`clckernel guard create <name>\` | Safeguards | Scaffold a new AST guard in the stack's native language in \`tools/guards/\`. |
|
|
168
|
+
| \`clckernel update\` | Maintenance | Non-destructive update: refresh core tools, playbooks & symlinks (preserves SDDs & custom guards). |
|
|
169
|
+
| \`clckernel start\` | Setup | Scan codebase, propose governance plan, and materialize \`.clckernel.yaml\`. |
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
149
173
|
## 🛡️ Core AI Safeguards
|
|
150
174
|
${this.getSafeguards().map(s => `- ${s}`).join('\n')}
|
|
151
175
|
`;
|
package/src/generator.js
CHANGED
|
@@ -325,6 +325,21 @@ ${isFront ? `- UI Component Reuse First (components/ui/ & semantic tokens)
|
|
|
325
325
|
- Database Efficiency & N+1 Performance Guard
|
|
326
326
|
- Database Migration Idempotency Guard
|
|
327
327
|
- Memory Guard (Engram / Graphify)`}
|
|
328
|
+
|
|
329
|
+
## 3. Universal Command Interface (All LLMs & Agents)
|
|
330
|
+
When given a command matching \`clckernel <action>\` or \`/clckernel <action>\`, execute the deterministic state machine below:
|
|
331
|
+
|
|
332
|
+
| Command | Lifecycle Phase | Mandatory Execution Protocol |
|
|
333
|
+
|---|---|---|
|
|
334
|
+
| \`clckernel feature <name>\` | New Feature | 1. Research affected layers.<br>2. Author local spec in \`sdds/{name}/spec.md\`.<br>3. Present HIT review to user and wait for approval.<br>4. Write failing test (Red Phase).<br>5. Implement clean code (Green Phase).<br>6. Run \`node tools/audit.js\` (or \`audit.py\`). |
|
|
335
|
+
| \`clckernel fix <issue>\` | Bug Fix | 1. Investigate root cause (no code edits).<br>2. Reproduce with failing test (Red Phase).<br>3. Minimal surgical fix respecting Clean Arch (Green Phase).<br>4. Run audit gate without skipping. |
|
|
336
|
+
| \`clckernel test\` | Verification | Run test suite (\`${config.testRunner || 'npm test'}\`) and verify clean pass (exit code 0). |
|
|
337
|
+
| \`clckernel audit\` | Verification | Run \`node tools/audit.js\` or \`python tools/audit.py\` and output the Educational Summary. |
|
|
338
|
+
| \`clckernel doctor\` | Diagnostics | Check git pre-commit hooks, IDE symlinks, and AST engine integrity. |
|
|
339
|
+
| \`clckernel commit <message>\` | Version Control | Run full audit, verify tests pass, ensure no changes outside SDD scope, and commit with conventional commits (never add AI attribution). |
|
|
340
|
+
| \`clckernel guard create <name>\` | Safeguards | Scaffold a new AST guard in the stack's native language in \`tools/guards/\`. |
|
|
341
|
+
| \`clckernel update\` | Maintenance | Non-destructive update: refresh core tools, playbooks & symlinks (preserves SDDs & custom guards). |
|
|
342
|
+
| \`clckernel start\` | Setup | Scan codebase, propose governance plan, and materialize \`.clckernel.yaml\`. |
|
|
328
343
|
`;
|
|
329
344
|
fs.writeFileSync(path.join(targetDir, 'AGENTS.md'), agentsContent, 'utf-8');
|
|
330
345
|
}
|
|
@@ -372,68 +387,31 @@ function installAgenticCLI(targetDir) {
|
|
|
372
387
|
// 1. Crear el Directorio de Skills
|
|
373
388
|
const skillDir = path.join(targetDir, '.agents', 'skills', 'clckernel_cli');
|
|
374
389
|
const legacySkillDir = path.join(targetDir, '.agents', 'skills', 'clc_forge_cli');
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
### Phase 1: Silent Discovery
|
|
401
|
-
Scan the current project using your file-reading capabilities. Identify the primary tech stack by looking for signature files (e.g., \`package.json\`, \`Gemfile\`, \`Cargo.toml\`, \`go.mod\`).
|
|
402
|
-
*Golden Rule: Do not assume the language. Read the files to establish context.*
|
|
403
|
-
|
|
404
|
-
### Phase 2: Interview & Proposal
|
|
405
|
-
Introduce yourself as CLC Kernel and state the detected stack.
|
|
406
|
-
Propose a standard governance plan for that ecosystem (SDD + TDD + stack-specific Safeguards).
|
|
407
|
-
ASK the user directly:
|
|
408
|
-
1. "Should we activate these standard phases, or do you want to define custom ones?"
|
|
409
|
-
2. "Do you have any specific security needs that require a custom Guard?"
|
|
410
|
-
**STOP.** Wait for the user's response.
|
|
411
|
-
|
|
412
|
-
### Phase 3: Materialization
|
|
413
|
-
Based on user approval, generate and write the \`.clckernel.yaml\` file in the project root.
|
|
414
|
-
|
|
415
|
-
---
|
|
416
|
-
|
|
417
|
-
## 🛠️ INTENT: \`clckernel create_guard\`
|
|
418
|
-
1. Ask the user what behavior they want to audit or block. **STOP.** Wait for technical details.
|
|
419
|
-
2. Based on the detected stack, write the linter/guard script in the **NATIVE ECOSYSTEM LANGUAGE** (Ruby for Rails, Go \`ast\` for Golang, Python \`ast\` for FastAPI, JS for Node). Save it in \`tools/guards/\`.
|
|
420
|
-
3. Update the \`.clckernel.yaml\` file to include the new Guard.
|
|
421
|
-
|
|
422
|
-
---
|
|
423
|
-
|
|
424
|
-
## 🗑️ INTENT: \`clckernel remove_guard\`
|
|
425
|
-
1. Ask which guard to remove and if the script should be deleted. **STOP.** Wait for response.
|
|
426
|
-
2. Update \`.clckernel.yaml\` and delete the script from \`tools/guards/\` if requested.
|
|
427
|
-
|
|
428
|
-
---
|
|
429
|
-
|
|
430
|
-
## 🔄 INTENT: \`clckernel add_phase\` / \`clckernel remove_phase\`
|
|
431
|
-
1. Ask for details of the lifecycle phase to add or remove. **STOP.** Wait for response.
|
|
432
|
-
2. Update the \`execution_phases\` block in \`.clckernel.yaml\`, preserving the logical sequence.
|
|
433
|
-
`;
|
|
434
|
-
|
|
435
|
-
fs.writeFileSync(path.join(skillDir, 'SKILL.md'), skillContent, 'utf-8');
|
|
436
|
-
fs.writeFileSync(path.join(legacySkillDir, 'SKILL.md'), skillContent, 'utf-8');
|
|
390
|
+
const skillRefDir = path.join(skillDir, 'reference');
|
|
391
|
+
const legacySkillRefDir = path.join(legacySkillDir, 'reference');
|
|
392
|
+
fs.mkdirSync(skillRefDir, { recursive: true });
|
|
393
|
+
fs.mkdirSync(legacySkillRefDir, { recursive: true });
|
|
394
|
+
|
|
395
|
+
// 2. Inyectar el SKILL.md Maestro y Playbooks de Referencia
|
|
396
|
+
const bundledSkillDir = path.join(__dirname, '..', '.agents', 'skills', 'clckernel_cli');
|
|
397
|
+
const bundledSkillFile = path.join(bundledSkillDir, 'SKILL.md');
|
|
398
|
+
const bundledRefDir = path.join(bundledSkillDir, 'reference');
|
|
399
|
+
|
|
400
|
+
if (fs.existsSync(bundledSkillFile)) {
|
|
401
|
+
fs.copyFileSync(bundledSkillFile, path.join(skillDir, 'SKILL.md'));
|
|
402
|
+
fs.copyFileSync(bundledSkillFile, path.join(legacySkillDir, 'SKILL.md'));
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
if (fs.existsSync(bundledRefDir)) {
|
|
406
|
+
const playbooks = fs.readdirSync(bundledRefDir);
|
|
407
|
+
for (const pb of playbooks) {
|
|
408
|
+
const srcPb = path.join(bundledRefDir, pb);
|
|
409
|
+
if (fs.statSync(srcPb).isFile()) {
|
|
410
|
+
fs.copyFileSync(srcPb, path.join(skillRefDir, pb));
|
|
411
|
+
fs.copyFileSync(srcPb, path.join(legacySkillRefDir, pb));
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}
|
|
437
415
|
|
|
438
416
|
// 3. Crear Symlinks Dinámicos al AGENTS.md (El Single Source of Truth)
|
|
439
417
|
const sourceFile = 'AGENTS.md';
|
package/src/index.js
CHANGED
|
@@ -14,16 +14,23 @@ async function runCli() {
|
|
|
14
14
|
const command = args[0];
|
|
15
15
|
|
|
16
16
|
let targetDir = process.cwd();
|
|
17
|
-
if (command && !command.startsWith('-') && command !== 'doctor') {
|
|
17
|
+
if (command && !command.startsWith('-') && command !== 'doctor' && command !== 'update') {
|
|
18
18
|
targetDir = path.resolve(command);
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
if (command === 'doctor' || args.includes('--doctor')) {
|
|
22
|
-
if (args[1]) targetDir = path.resolve(args[1]);
|
|
22
|
+
if (args[1] && args[1] !== '--doctor') targetDir = path.resolve(args[1]);
|
|
23
23
|
runDoctor(targetDir);
|
|
24
24
|
return;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
if (command === 'update' || args.includes('--update')) {
|
|
28
|
+
if (args[1] && args[1] !== '--update') targetDir = path.resolve(args[1]);
|
|
29
|
+
const { runUpdate } = require('./updater');
|
|
30
|
+
await runUpdate(targetDir);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
27
34
|
// 1. Print Pro ASCII Banner
|
|
28
35
|
printBanner();
|
|
29
36
|
|
package/src/updater.js
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLC Kernel — Non-Destructive Harness Updater
|
|
3
|
+
* Safely updates core AST tools, skills, playbooks, and IDE symlinks in an existing
|
|
4
|
+
* project while guaranteeing 100% preservation of:
|
|
5
|
+
* - Local specifications (sdds/)
|
|
6
|
+
* - Custom AST guards (tools/guards/)
|
|
7
|
+
* - Project configuration and custom thresholds (.clckernel.yaml / .clc-forge.yaml)
|
|
8
|
+
* - Application source code and domain models
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const fs = require('fs');
|
|
12
|
+
const path = require('path');
|
|
13
|
+
const { autoDetectStack } = require('./detector');
|
|
14
|
+
const { generateHarness } = require('./generator');
|
|
15
|
+
|
|
16
|
+
function updateHarness(targetDir = process.cwd(), options = {}) {
|
|
17
|
+
const resolvedDir = path.resolve(targetDir);
|
|
18
|
+
|
|
19
|
+
if (!fs.existsSync(resolvedDir)) {
|
|
20
|
+
throw new Error(`Target directory "${resolvedDir}" does not exist.`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// 1. Detect Stack
|
|
24
|
+
const detected = autoDetectStack(resolvedDir);
|
|
25
|
+
|
|
26
|
+
// 2. Identify existing preserved assets
|
|
27
|
+
const preserved = {
|
|
28
|
+
sdds: fs.existsSync(path.join(resolvedDir, 'sdds')),
|
|
29
|
+
customGuards: fs.existsSync(path.join(resolvedDir, 'tools', 'guards')),
|
|
30
|
+
configYaml: fs.existsSync(path.join(resolvedDir, '.clckernel.yaml')) || fs.existsSync(path.join(resolvedDir, '.clc-forge.yaml')),
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
// 3. Run harness generation (refreshes tools, hooks, skills, and symlinks)
|
|
34
|
+
generateHarness(resolvedDir, detected);
|
|
35
|
+
|
|
36
|
+
// 4. Ensure AGENTS.md includes the update command in the command table
|
|
37
|
+
const agentsPath = path.join(resolvedDir, 'AGENTS.md');
|
|
38
|
+
if (fs.existsSync(agentsPath)) {
|
|
39
|
+
let agentsContent = fs.readFileSync(agentsPath, 'utf-8');
|
|
40
|
+
if (!agentsContent.includes('clckernel update')) {
|
|
41
|
+
if (agentsContent.includes('| `clckernel start`')) {
|
|
42
|
+
agentsContent = agentsContent.replace(
|
|
43
|
+
'| `clckernel start`',
|
|
44
|
+
'| `clckernel update` | Maintenance | Non-destructive update: refresh core tools, playbooks & symlinks (preserves SDDs & custom guards). |\n| `clckernel start`'
|
|
45
|
+
);
|
|
46
|
+
fs.writeFileSync(agentsPath, agentsContent, 'utf-8');
|
|
47
|
+
} else if (agentsContent.includes('## 3. Universal Command Interface')) {
|
|
48
|
+
agentsContent += '\n| `clckernel update` | Maintenance | Non-destructive update: refresh core tools, playbooks & symlinks (preserves SDDs & custom guards). |\n';
|
|
49
|
+
fs.writeFileSync(agentsPath, agentsContent, 'utf-8');
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return {
|
|
55
|
+
success: true,
|
|
56
|
+
targetDir: resolvedDir,
|
|
57
|
+
preserved,
|
|
58
|
+
refreshed: {
|
|
59
|
+
tools: true,
|
|
60
|
+
skills: true,
|
|
61
|
+
symlinks: true,
|
|
62
|
+
hooks: true,
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
async function runUpdate(targetDir = process.cwd()) {
|
|
68
|
+
const { colors, printBanner } = require('./ui');
|
|
69
|
+
printBanner();
|
|
70
|
+
|
|
71
|
+
console.log(`\n${colors.cyan}🔄 Actualizando CLC Kernel en:${colors.reset} ${targetDir}\n`);
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
const result = updateHarness(targetDir);
|
|
75
|
+
|
|
76
|
+
console.log(`${colors.green}✔ Salvaguardas estándar actualizadas en tools/${colors.reset}`);
|
|
77
|
+
console.log(`${colors.green}✔ Playbooks y Skills agénticos actualizados en .agents/skills/${colors.reset}`);
|
|
78
|
+
console.log(`${colors.green}✔ Enlaces simbióticos de IDEs actualizados (Cursor, Claude, Copilot, Antigravity)${colors.reset}`);
|
|
79
|
+
console.log(`${colors.green}✔ Hooks de git sincronizados${colors.reset}`);
|
|
80
|
+
console.log(`\n${colors.bold}🔒 ACTIVOS PRESERVADOS AL 100%:${colors.reset}`);
|
|
81
|
+
console.log(` • ${colors.emerald}sdds/${colors.reset} (Especificaciones locales intactas)`);
|
|
82
|
+
console.log(` • ${colors.emerald}tools/guards/${colors.reset} (Reglas y salvaguardas personalizadas intactas)`);
|
|
83
|
+
console.log(` • ${colors.emerald}.clckernel.yaml${colors.reset} (Configuraciones de equipo intactas)\n`);
|
|
84
|
+
console.log(`${colors.green}✨ ¡Proyecto actualizado con éxito a la última versión de CLC Kernel!${colors.reset}\n`);
|
|
85
|
+
return result;
|
|
86
|
+
} catch (err) {
|
|
87
|
+
console.error(`\n❌ Error actualizando el arnés: ${err.message}`);
|
|
88
|
+
process.exit(1);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
module.exports = { updateHarness, runUpdate };
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Test Calendar Parity & Auto-Sync Guard
|
|
4
|
+
* Ensures that any modification made to the calendar engine (templates/content-calendar/)
|
|
5
|
+
* is immediately synchronized to the test calendar harness (tests/).
|
|
6
|
+
* Self-contained: uses only Node.js built-ins.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} targetDir - Directory to scan (defaults to cwd)
|
|
9
|
+
* @returns {{ exitCode: number, skipped: boolean, name: string, data: object }}
|
|
10
|
+
*/
|
|
11
|
+
const check = async function checkTestCalendarSync(targetDir) {
|
|
12
|
+
const fs = require('fs');
|
|
13
|
+
const path = require('path');
|
|
14
|
+
|
|
15
|
+
const dir = targetDir || process.cwd();
|
|
16
|
+
const templateDir = path.join(dir, 'templates', 'content-calendar');
|
|
17
|
+
const testDir = path.join(dir, 'tests');
|
|
18
|
+
|
|
19
|
+
if (!fs.existsSync(templateDir) || !fs.existsSync(testDir)) {
|
|
20
|
+
return {
|
|
21
|
+
exitCode: 0,
|
|
22
|
+
skipped: true,
|
|
23
|
+
name: 'check_test_calendar_sync',
|
|
24
|
+
data: { violations: [], message: 'No templates/content-calendar or tests/ directory found' }
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const syncPairs = [
|
|
29
|
+
{ src: path.join(templateDir, 'index.html'), dest: path.join(testDir, 'index.html'), label: 'index.html' },
|
|
30
|
+
{ src: path.join(templateDir, 'data.js'), dest: path.join(testDir, 'data.js'), label: 'data.js' },
|
|
31
|
+
{ src: path.join(templateDir, 'data.js'), dest: path.join(testDir, 'mock-data.js'), label: 'mock-data.js' }
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
const syncedFiles = [];
|
|
35
|
+
const violations = [];
|
|
36
|
+
|
|
37
|
+
for (const pair of syncPairs) {
|
|
38
|
+
if (!fs.existsSync(pair.src)) continue;
|
|
39
|
+
|
|
40
|
+
let needsSync = false;
|
|
41
|
+
if (!fs.existsSync(pair.dest)) {
|
|
42
|
+
needsSync = true;
|
|
43
|
+
} else {
|
|
44
|
+
const srcBuf = fs.readFileSync(pair.src);
|
|
45
|
+
const destBuf = fs.readFileSync(pair.dest);
|
|
46
|
+
if (!srcBuf.equals(destBuf)) {
|
|
47
|
+
needsSync = true;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
if (needsSync) {
|
|
52
|
+
try {
|
|
53
|
+
fs.copyFileSync(pair.src, pair.dest);
|
|
54
|
+
syncedFiles.push(pair.label);
|
|
55
|
+
} catch (err) {
|
|
56
|
+
violations.push({
|
|
57
|
+
file: pair.label,
|
|
58
|
+
message: `Failed to synchronize ${pair.label}: ${err.message}`
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Also verify mock-content.json has channelProfiles if data.js has it
|
|
65
|
+
const dataJsPath = path.join(templateDir, 'data.js');
|
|
66
|
+
const mockContentPath = path.join(testDir, 'mock-content.json');
|
|
67
|
+
if (fs.existsSync(dataJsPath) && fs.existsSync(mockContentPath)) {
|
|
68
|
+
try {
|
|
69
|
+
const dataJsContent = fs.readFileSync(dataJsPath, 'utf-8');
|
|
70
|
+
if (dataJsContent.includes('"channelProfiles"') && !fs.readFileSync(mockContentPath, 'utf-8').includes('"channelProfiles"')) {
|
|
71
|
+
// Hydrate channelProfiles from data.js
|
|
72
|
+
const match = dataJsContent.match(/"channelProfiles":\s*\{[\s\S]*?\n\s{4}\}/);
|
|
73
|
+
if (match) {
|
|
74
|
+
let mockJson = fs.readFileSync(mockContentPath, 'utf-8');
|
|
75
|
+
mockJson = mockJson.replace(/"pillarMix":\s*\{[\s\S]*?\n\s{4}\}/, (m) => `${m},\n ${match[0]}`);
|
|
76
|
+
fs.writeFileSync(mockContentPath, mockJson, 'utf-8');
|
|
77
|
+
syncedFiles.push('mock-content.json');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
} catch (e) {
|
|
81
|
+
// non-fatal
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const exitCode = violations.length > 0 ? 1 : 0;
|
|
86
|
+
const message = violations.length > 0
|
|
87
|
+
? `Failed to sync ${violations.length} test calendar files`
|
|
88
|
+
: (syncedFiles.length > 0
|
|
89
|
+
? `Auto-synchronized ${syncedFiles.length} test calendar file(s): ${syncedFiles.join(', ')}`
|
|
90
|
+
: 'Test calendar is 100% in sync with templates/content-calendar');
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
exitCode,
|
|
94
|
+
skipped: false,
|
|
95
|
+
name: 'check_test_calendar_sync',
|
|
96
|
+
data: {
|
|
97
|
+
violations,
|
|
98
|
+
syncedFiles,
|
|
99
|
+
message
|
|
100
|
+
}
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
module.exports = check;
|
|
105
|
+
|
|
106
|
+
if (require.main === module) {
|
|
107
|
+
check(process.argv[2]).then(result => {
|
|
108
|
+
console.log(JSON.stringify(result, null, 2));
|
|
109
|
+
process.exit(result.exitCode);
|
|
110
|
+
});
|
|
111
|
+
}
|