trackops 1.0.0 → 1.0.1
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.md +59 -6
- package/lib/control.js +1 -0
- package/lib/init.js +12 -10
- package/lib/opera.js +3 -3
- package/lib/server.js +141 -0
- package/lib/skills.js +1 -1
- package/package.json +16 -3
- package/templates/etapa/agent.md +2 -2
- package/templates/etapa/references/etapa-cycle.md +1 -1
- package/templates/opera/agent.md +1 -1
- package/templates/skills/project-starter-skill/SKILL.md +5 -3
- package/ui/css/base.css +266 -0
- package/ui/css/charts.css +327 -0
- package/ui/css/components.css +570 -0
- package/ui/css/panels.css +953 -0
- package/ui/css/tokens.css +227 -0
- package/ui/favicon.svg +5 -0
- package/ui/index.html +91 -351
- package/ui/js/api.js +203 -0
- package/ui/js/app.js +199 -0
- package/ui/js/console-logger.js +172 -0
- package/ui/js/icons.js +104 -0
- package/ui/js/onboarding.js +437 -0
- package/ui/js/router.js +125 -0
- package/ui/js/state.js +129 -0
- package/ui/js/theme.js +100 -0
- package/ui/js/time-tracker.js +248 -0
- package/ui/js/utils.js +172 -0
- package/ui/js/views/board.js +254 -0
- package/ui/js/views/execution.js +256 -0
- package/ui/js/views/flash.js +47 -0
- package/ui/js/views/insights.js +339 -0
- package/ui/js/views/overview.js +364 -0
- package/ui/js/views/settings.js +243 -0
- package/ui/js/views/sidebar.js +132 -0
- package/ui/js/views/skills.js +162 -0
- package/ui/js/views/tasks.js +405 -0
- package/ui/js/views/topbar.js +183 -0
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="docs/assets/
|
|
2
|
+
<img src="docs/assets/logo.svg" alt="TrackOps Logo" width="96" height="96" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<h1 align="center">TrackOps</h1>
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
<p align="center">
|
|
12
12
|
<a href="https://www.npmjs.com/package/trackops"><img src="https://img.shields.io/npm/v/trackops?color=D97706&style=flat-square" alt="npm" /></a>
|
|
13
13
|
<a href="LICENSE"><img src="https://img.shields.io/badge/licencia-MIT-22C55E?style=flat-square" alt="MIT" /></a>
|
|
14
|
+
<img src="https://img.shields.io/badge/estado-beta-F59E0B?style=flat-square" alt="Beta" />
|
|
14
15
|
<img src="https://img.shields.io/badge/dependencias-0-D97706?style=flat-square" alt="0 deps" />
|
|
15
16
|
<img src="https://img.shields.io/badge/node-%3E%3D18-333?style=flat-square" alt="Node 18+" />
|
|
16
17
|
</p>
|
|
@@ -25,6 +26,10 @@
|
|
|
25
26
|
|
|
26
27
|
## Español
|
|
27
28
|
|
|
29
|
+
> **Estado beta:** TrackOps ya es usable, pero sigue evolucionando rápido. La interfaz, los comandos y algunos flujos pueden cambiar entre versiones.
|
|
30
|
+
|
|
31
|
+
> **Descargo de responsabilidad:** Revisa siempre los archivos generados, los cambios automáticos y los resultados de tus agentes antes de usarlos en proyectos sensibles o en producción.
|
|
32
|
+
|
|
28
33
|
### El Problema: La IA es rápida. El caos también.
|
|
29
34
|
|
|
30
35
|
Escribir código con asistentes de IA (Cursor, Copilot, Claude Code, agentes autónomos) es increíblemente rápido. Pero a medida que el proyecto crece, **la IA pierde el contexto**, olvida las prioridades y el proyecto se convierte en una pesadilla de mantenimiento.
|
|
@@ -51,7 +56,7 @@ TrackOps es un **motor operativo local de código abierto** que actúa como puen
|
|
|
51
56
|
| **Integración Git nativa** | TrackOps sabe cuándo haces commit, merge o checkout, capturando la salud del repositorio de forma automática. |
|
|
52
57
|
| **Portfolio multi-proyecto** | Registra todos tus proyectos y navega entre ellos desde un solo dashboard. |
|
|
53
58
|
| **Framework OPERA** | Metodología de desarrollo con agentes IA en 5 fases: Orquestar, Probar, Estructurar, Refinar, Automatizar. |
|
|
54
|
-
| **Ecosistema de Skills** |
|
|
59
|
+
| **Ecosistema de Skills** | Integración nativa a un click con el marketplace **skills.sh**. Habilidades y agentes modulares que dotan a tu proyecto de capacidades automatizadas avanzadas e IA pre-entrenada para tu workflow. |
|
|
55
60
|
|
|
56
61
|
<br/>
|
|
57
62
|
|
|
@@ -64,6 +69,14 @@ npx trackops init # Inicializa el motor en tu proyecto
|
|
|
64
69
|
npx trackops dashboard # Levanta el centro de control web
|
|
65
70
|
```
|
|
66
71
|
|
|
72
|
+
Tras `init`, también quedan disponibles atajos npm para el proyecto:
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
npm run ops:status
|
|
76
|
+
npm run ops:dashboard
|
|
77
|
+
npm run ops:sync
|
|
78
|
+
```
|
|
79
|
+
|
|
67
80
|
El flujo desde consola en tu día a día:
|
|
68
81
|
|
|
69
82
|
```bash
|
|
@@ -73,6 +86,8 @@ npx trackops task start T-001 # Empieza a trabajar
|
|
|
73
86
|
npx trackops sync # Genera contexto Markdown para tu IA
|
|
74
87
|
```
|
|
75
88
|
|
|
89
|
+
Guía de uso paso a paso: [UserGUIDE.md](UserGUIDE.md)
|
|
90
|
+
|
|
76
91
|
<br/>
|
|
77
92
|
|
|
78
93
|
### Arquitectura de 3 Capas
|
|
@@ -120,7 +135,7 @@ Las fases son totalmente configurables por proyecto vía `project_control.json`.
|
|
|
120
135
|
|
|
121
136
|
| Comando | Descripción |
|
|
122
137
|
|---------|-------------|
|
|
123
|
-
| `trackops init [--with-opera] [--locale es\|en]` | Inicializar en el directorio actual |
|
|
138
|
+
| `trackops init [--with-opera] [--locale es\|en]` | Inicializar en el directorio actual. `--with-etapa` se mantiene solo como alias heredado. |
|
|
124
139
|
| `trackops status` | Estado: foco, fase, tareas, bloqueadores, repo |
|
|
125
140
|
| `trackops next` | Próximas tareas ejecutables priorizadas |
|
|
126
141
|
| `trackops sync` | Regenerar task_plan.md, progress.md, findings.md |
|
|
@@ -156,6 +171,8 @@ Las fases son totalmente configurables por proyecto vía `project_control.json`.
|
|
|
156
171
|
|
|
157
172
|
</details>
|
|
158
173
|
|
|
174
|
+
Antes de publicar una versión, ejecuta `npm run release:check`. La política mínima de versiones y publicación está en `docs/RELEASE.md`.
|
|
175
|
+
|
|
159
176
|
<br/>
|
|
160
177
|
|
|
161
178
|
### Estructura del Proyecto
|
|
@@ -171,6 +188,8 @@ mi-proyecto/
|
|
|
171
188
|
└── .agents/skills/ # Skills instaladas (OPERA)
|
|
172
189
|
```
|
|
173
190
|
|
|
191
|
+
**Higiene del repositorio del paquete:** este repositorio solo versiona archivos propios de `trackops` como producto. Los artefactos generados al ejecutar `trackops` u `OPERA` sobre un proyecto (`project_control.json`, `task_plan.md`, `progress.md`, `findings.md`, `genesis.md`, `.agent/`, `.agents/`, `.githooks/`) se consideran salidas de uso y no deben subirse a este repo.
|
|
192
|
+
|
|
174
193
|
<br/>
|
|
175
194
|
|
|
176
195
|
### Apoya el Proyecto
|
|
@@ -181,7 +200,16 @@ Si TrackOps te ha ayudado a recuperar el control de tus proyectos con IA:
|
|
|
181
200
|
|
|
182
201
|
1. **Dale una estrella en GitHub** — ayuda enormemente a la visibilidad.
|
|
183
202
|
2. **Comparte TrackOps** con tu equipo y en tus redes.
|
|
184
|
-
3. **
|
|
203
|
+
3. **Apoya con USDC en Polygon** para ayudar a mantener la documentación, las mejoras y el soporte del proyecto.
|
|
204
|
+
|
|
205
|
+
```text
|
|
206
|
+
Red: Polygon
|
|
207
|
+
Moneda: USDC
|
|
208
|
+
Dirección: 0x7B3d964247Dd309D13FF702649827947633e27F3
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
Envía solo `USDC` por la red `Polygon`. No envíes `BTC` ni activos de otras redes a esta dirección.
|
|
212
|
+
4. **Contribuye** — Pull Requests, reporte de bugs y nuevas Skills son siempre bienvenidos.
|
|
185
213
|
|
|
186
214
|
<br/>
|
|
187
215
|
|
|
@@ -189,6 +217,10 @@ Si TrackOps te ha ayudado a recuperar el control de tus proyectos con IA:
|
|
|
189
217
|
|
|
190
218
|
## English
|
|
191
219
|
|
|
220
|
+
> **Beta status:** TrackOps is already usable, but it is still evolving quickly. The interface, commands, and some flows may change between releases.
|
|
221
|
+
|
|
222
|
+
> **Disclaimer:** Always review generated files, automated changes, and agent output before using them in sensitive or production projects.
|
|
223
|
+
|
|
192
224
|
### The Problem: AI is fast. So is chaos.
|
|
193
225
|
|
|
194
226
|
Writing code with AI assistants (Cursor, Copilot, Claude Code, autonomous agents) is incredibly fast. But as the project grows, **the AI loses context**, forgets priorities, and the project becomes a maintenance nightmare.
|
|
@@ -228,6 +260,14 @@ npx trackops init # Initialize the engine in your project
|
|
|
228
260
|
npx trackops dashboard # Launch the web control center
|
|
229
261
|
```
|
|
230
262
|
|
|
263
|
+
After `init`, npm shortcuts are also ready to use inside the project:
|
|
264
|
+
|
|
265
|
+
```bash
|
|
266
|
+
npm run ops:status
|
|
267
|
+
npm run ops:dashboard
|
|
268
|
+
npm run ops:sync
|
|
269
|
+
```
|
|
270
|
+
|
|
231
271
|
Your daily workflow from the console:
|
|
232
272
|
|
|
233
273
|
```bash
|
|
@@ -237,6 +277,8 @@ npx trackops task start T-001 # Start working
|
|
|
237
277
|
npx trackops sync # Generate Markdown context for your AI
|
|
238
278
|
```
|
|
239
279
|
|
|
280
|
+
Step-by-step user guide: [UserGUIDE.md](UserGUIDE.md)
|
|
281
|
+
|
|
240
282
|
<br/>
|
|
241
283
|
|
|
242
284
|
### 3-Layer Architecture
|
|
@@ -284,7 +326,7 @@ Phases are fully configurable per project via `project_control.json`.
|
|
|
284
326
|
|
|
285
327
|
| Command | Description |
|
|
286
328
|
|---------|-------------|
|
|
287
|
-
| `trackops init [--with-opera] [--locale es\|en]` | Initialize in current directory |
|
|
329
|
+
| `trackops init [--with-opera] [--locale es\|en]` | Initialize in current directory. `--with-etapa` remains as a legacy alias only. |
|
|
288
330
|
| `trackops status` | State: focus, phase, tasks, blockers, repo |
|
|
289
331
|
| `trackops next` | Next prioritized executable tasks |
|
|
290
332
|
| `trackops sync` | Regenerate task_plan.md, progress.md, findings.md |
|
|
@@ -335,6 +377,8 @@ my-project/
|
|
|
335
377
|
└── .agents/skills/ # Installed skills (OPERA)
|
|
336
378
|
```
|
|
337
379
|
|
|
380
|
+
**Package repository hygiene:** this repository only versions files that belong to `trackops` as a product. Artifacts generated when running `trackops` or `OPERA` on a project (`project_control.json`, `task_plan.md`, `progress.md`, `findings.md`, `genesis.md`, `.agent/`, `.agents/`, `.githooks/`) are considered runtime output and must not be committed to this repo.
|
|
381
|
+
|
|
338
382
|
<br/>
|
|
339
383
|
|
|
340
384
|
### Support the Project
|
|
@@ -345,7 +389,16 @@ If TrackOps has helped you regain control of your AI-assisted projects:
|
|
|
345
389
|
|
|
346
390
|
1. **Star us on GitHub** — it helps enormously with visibility.
|
|
347
391
|
2. **Share TrackOps** with your team and on social media.
|
|
348
|
-
3. **
|
|
392
|
+
3. **Support with USDC on Polygon** to help maintain documentation, improvements, and project support.
|
|
393
|
+
|
|
394
|
+
```text
|
|
395
|
+
Network: Polygon
|
|
396
|
+
Asset: USDC
|
|
397
|
+
Address: 0x7B3d964247Dd309D13FF702649827947633e27F3
|
|
398
|
+
```
|
|
399
|
+
|
|
400
|
+
Send only `USDC` on `Polygon`. Do not send `BTC` or assets from other networks to this address.
|
|
401
|
+
4. **Contribute** — Pull Requests, bug reports, and new Skills are always welcome.
|
|
349
402
|
|
|
350
403
|
<br/>
|
|
351
404
|
|
package/lib/control.js
CHANGED
|
@@ -520,6 +520,7 @@ function cmdHelp() {
|
|
|
520
520
|
console.log("");
|
|
521
521
|
console.log("Commands:");
|
|
522
522
|
console.log(" init [--with-opera] [--locale es|en] [--name \"...\"]");
|
|
523
|
+
console.log(" Legacy alias available: --with-etapa");
|
|
523
524
|
console.log(" Initialize trackops in the current directory.");
|
|
524
525
|
console.log(" status");
|
|
525
526
|
console.log(" Show project state: focus, active phase, ready tasks, blockers, repo.");
|
package/lib/init.js
CHANGED
|
@@ -8,6 +8,16 @@ const { DEFAULT_PHASES, DEFAULT_LOCALE } = require("./config");
|
|
|
8
8
|
const registry = require("./registry");
|
|
9
9
|
const { t, setLocale } = require("./i18n");
|
|
10
10
|
|
|
11
|
+
const GENERATED_SCRIPT_COMMANDS = {
|
|
12
|
+
ops: "npx --yes trackops",
|
|
13
|
+
"ops:help": "npx --yes trackops help",
|
|
14
|
+
"ops:dashboard": "npx --yes trackops dashboard",
|
|
15
|
+
"ops:status": "npx --yes trackops status",
|
|
16
|
+
"ops:next": "npx --yes trackops next",
|
|
17
|
+
"ops:sync": "npx --yes trackops sync",
|
|
18
|
+
"ops:repo": "npx --yes trackops refresh-repo",
|
|
19
|
+
};
|
|
20
|
+
|
|
11
21
|
function nowIso() {
|
|
12
22
|
return new Date().toISOString();
|
|
13
23
|
}
|
|
@@ -99,15 +109,7 @@ function upsertScripts(root) {
|
|
|
99
109
|
try { pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8")); } catch (_e) { /* ignore */ }
|
|
100
110
|
}
|
|
101
111
|
pkg.scripts = pkg.scripts || {};
|
|
102
|
-
Object.assign(pkg.scripts,
|
|
103
|
-
ops: "trackops",
|
|
104
|
-
"ops:help": "trackops help",
|
|
105
|
-
"ops:dashboard": "trackops dashboard",
|
|
106
|
-
"ops:status": "trackops status",
|
|
107
|
-
"ops:next": "trackops next",
|
|
108
|
-
"ops:sync": "trackops sync",
|
|
109
|
-
"ops:repo": "trackops refresh-repo",
|
|
110
|
-
});
|
|
112
|
+
Object.assign(pkg.scripts, GENERATED_SCRIPT_COMMANDS);
|
|
111
113
|
fs.writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}\n`, "utf8");
|
|
112
114
|
}
|
|
113
115
|
|
|
@@ -115,7 +117,7 @@ function installHooks(root) {
|
|
|
115
117
|
const hooksDir = path.join(root, ".githooks");
|
|
116
118
|
fs.mkdirSync(hooksDir, { recursive: true });
|
|
117
119
|
|
|
118
|
-
const hookContent = "#!/bin/sh\nnpx trackops refresh-repo --quiet >/dev/null 2>&1 || true\n";
|
|
120
|
+
const hookContent = "#!/bin/sh\nnpx --yes trackops refresh-repo --quiet >/dev/null 2>&1 || true\n";
|
|
119
121
|
for (const hookName of ["post-commit", "post-checkout", "post-merge"]) {
|
|
120
122
|
const hookPath = path.join(hooksDir, hookName);
|
|
121
123
|
fs.writeFileSync(hookPath, hookContent, { mode: 0o755 });
|
package/lib/opera.js
CHANGED
|
@@ -68,8 +68,8 @@ function install(root, options) {
|
|
|
68
68
|
copyTemplate(routerTemplatePath, path.join(agentHubDir, "router.md"), { PROJECT_NAME: projectName });
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
// Create .
|
|
72
|
-
const skillsRegistryDir = path.join(root, ".
|
|
71
|
+
// Create .agents/skills/_registry.md
|
|
72
|
+
const skillsRegistryDir = path.join(root, ".agents", "skills");
|
|
73
73
|
fs.mkdirSync(skillsRegistryDir, { recursive: true });
|
|
74
74
|
const registryPath = path.join(skillsRegistryDir, "_registry.md");
|
|
75
75
|
const registryTemplatePath = path.join(TEMPLATES_DIR, "registry.md");
|
|
@@ -136,7 +136,7 @@ function status(root) {
|
|
|
136
136
|
const checks = [
|
|
137
137
|
[".agent/hub/agent.md", fs.existsSync(path.join(root, ".agent", "hub", "agent.md"))],
|
|
138
138
|
[".agent/hub/router.md", fs.existsSync(path.join(root, ".agent", "hub", "router.md"))],
|
|
139
|
-
[".
|
|
139
|
+
[".agents/skills/_registry.md", fs.existsSync(path.join(root, ".agents", "skills", "_registry.md"))],
|
|
140
140
|
["genesis.md", fs.existsSync(path.join(root, "genesis.md"))],
|
|
141
141
|
];
|
|
142
142
|
|
package/lib/server.js
CHANGED
|
@@ -21,8 +21,11 @@ const MIME_TYPES = {
|
|
|
21
21
|
".css": "text/css; charset=utf-8",
|
|
22
22
|
".html": "text/html; charset=utf-8",
|
|
23
23
|
".js": "text/javascript; charset=utf-8",
|
|
24
|
+
".mjs": "text/javascript; charset=utf-8",
|
|
24
25
|
".json": "application/json; charset=utf-8",
|
|
25
26
|
".svg": "image/svg+xml",
|
|
27
|
+
".woff2": "font/woff2",
|
|
28
|
+
".woff": "font/woff",
|
|
26
29
|
};
|
|
27
30
|
|
|
28
31
|
/* ── helpers ── */
|
|
@@ -404,6 +407,144 @@ async function handleApi(req, res, url) {
|
|
|
404
407
|
return;
|
|
405
408
|
}
|
|
406
409
|
|
|
410
|
+
/* ── Time Tracking ── */
|
|
411
|
+
|
|
412
|
+
if (req.method === "GET" && url.pathname === "/api/time") {
|
|
413
|
+
const project = resolveProjectEntry(url.searchParams.get("project"));
|
|
414
|
+
const api = loadControlApi(project.root);
|
|
415
|
+
const controlState = api.loadControl();
|
|
416
|
+
const entries = controlState.timeEntries || [];
|
|
417
|
+
sendJson(res, 200, { ok: true, entries });
|
|
418
|
+
return;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
if (req.method === "POST" && url.pathname === "/api/time/start") {
|
|
422
|
+
const body = await parseBody(req);
|
|
423
|
+
const project = resolveProjectEntry(body.projectId || body.project || url.searchParams.get("project"));
|
|
424
|
+
const api = loadControlApi(project.root);
|
|
425
|
+
const controlState = api.loadControl();
|
|
426
|
+
const entryId = `te-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 7)}`;
|
|
427
|
+
const entry = {
|
|
428
|
+
id: entryId,
|
|
429
|
+
taskId: String(body.taskId || "").trim(),
|
|
430
|
+
taskTitle: String(body.taskTitle || "").trim(),
|
|
431
|
+
startedAt: new Date().toISOString(),
|
|
432
|
+
stoppedAt: null,
|
|
433
|
+
durationMs: 0,
|
|
434
|
+
};
|
|
435
|
+
if (!controlState.timeEntries) controlState.timeEntries = [];
|
|
436
|
+
controlState.timeEntries.push(entry);
|
|
437
|
+
api.saveControl(controlState);
|
|
438
|
+
sendJson(res, 201, { ok: true, entry });
|
|
439
|
+
return;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
if (req.method === "POST" && url.pathname === "/api/time/stop") {
|
|
443
|
+
const body = await parseBody(req);
|
|
444
|
+
const project = resolveProjectEntry(body.projectId || body.project || url.searchParams.get("project"));
|
|
445
|
+
const api = loadControlApi(project.root);
|
|
446
|
+
const controlState = api.loadControl();
|
|
447
|
+
const entries = controlState.timeEntries || [];
|
|
448
|
+
const entry = entries.find(e => e.id === body.entryId);
|
|
449
|
+
if (!entry) { sendJson(res, 404, { ok: false, error: "Entry not found." }); return; }
|
|
450
|
+
entry.stoppedAt = new Date().toISOString();
|
|
451
|
+
entry.durationMs = new Date(entry.stoppedAt) - new Date(entry.startedAt);
|
|
452
|
+
api.saveControl(controlState);
|
|
453
|
+
sendJson(res, 200, { ok: true, entry });
|
|
454
|
+
return;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/* ── Skills Hub ── */
|
|
458
|
+
|
|
459
|
+
if (req.method === "GET" && url.pathname === "/api/skills/local") {
|
|
460
|
+
const project = resolveProjectEntry(url.searchParams.get("project"));
|
|
461
|
+
const agentsPath = path.join(project.root, ".agents", "skills");
|
|
462
|
+
const agentPathFallback = path.join(project.root, ".agent", "skills");
|
|
463
|
+
let skillsDir = fs.existsSync(agentsPath) ? agentsPath : (fs.existsSync(agentPathFallback) ? agentPathFallback : null);
|
|
464
|
+
|
|
465
|
+
const skills = [];
|
|
466
|
+
if (skillsDir) {
|
|
467
|
+
try {
|
|
468
|
+
const dirs = fs.readdirSync(skillsDir, { withFileTypes: true })
|
|
469
|
+
.filter(dirent => dirent.isDirectory())
|
|
470
|
+
.map(dirent => dirent.name);
|
|
471
|
+
|
|
472
|
+
for (const d of dirs) {
|
|
473
|
+
const skillMdPath = path.join(skillsDir, d, "SKILL.md");
|
|
474
|
+
let description = "";
|
|
475
|
+
let title = d;
|
|
476
|
+
if (fs.existsSync(skillMdPath)) {
|
|
477
|
+
const content = fs.readFileSync(skillMdPath, "utf-8");
|
|
478
|
+
// Parse basic YAML frontmatter for title/description if exists
|
|
479
|
+
const titleMatch = content.match(/title:\s*(.+)/i) || content.match(/name:\s*(.+)/i);
|
|
480
|
+
const descMatch = content.match(/description:\s*(.+)/i) || content.match(/desc:\s*(.+)/i);
|
|
481
|
+
if (titleMatch) title = titleMatch[1].replace(/['"]/g, '');
|
|
482
|
+
if (descMatch) description = descMatch[1].replace(/['"]/g, '');
|
|
483
|
+
}
|
|
484
|
+
skills.push({ id: d, title, description, path: skillMdPath });
|
|
485
|
+
}
|
|
486
|
+
} catch (err) {
|
|
487
|
+
console.error("Error reading skills dir:", err);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
sendJson(res, 200, { ok: true, skills });
|
|
491
|
+
return;
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
if (req.method === "GET" && url.pathname === "/api/skills/discover") {
|
|
495
|
+
// Mocked recommendations/catalog for skills.sh integration
|
|
496
|
+
// Ideally this calls a raw json from github
|
|
497
|
+
const catalog = [
|
|
498
|
+
{ id: "changelog-updater", title: "Changelog Updater", description: "Mantiene automatizado el CHANGELOG basado en commits.", url: "https://skills.sh/changelog-updater.md" },
|
|
499
|
+
{ id: "commiter", title: "Git Commiter", description: "Genera mensajes de commit strictos siguiendo Conventional Commits y Emojis.", url: "https://skills.sh/commiter.md" },
|
|
500
|
+
{ id: "project-starter-skill", title: "Project Starter", description: "Skill para inicializar proyectos usando el protocolo O.P.E.R.A.", url: "https://skills.sh/project-starter.md" },
|
|
501
|
+
{ id: "tdd-master", title: "TDD Master", description: "Fuerza el ciclo Red-Green-Refactor en las implementaciones.", url: "https://skills.sh/tdd-master.md" },
|
|
502
|
+
{ id: "e2e-tester", title: "E2E Tester", description: "Plantillas y comandos para frameworks de Test End-to-End.", url: "https://skills.sh/e2e-tester.md" }
|
|
503
|
+
];
|
|
504
|
+
// Simulate network wait
|
|
505
|
+
setTimeout(() => {
|
|
506
|
+
sendJson(res, 200, { ok: true, catalog });
|
|
507
|
+
}, 400);
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
if (req.method === "POST" && url.pathname === "/api/skills/install") {
|
|
512
|
+
const body = await parseBody(req);
|
|
513
|
+
const project = resolveProjectEntry(body.projectId || body.project || url.searchParams.get("project"));
|
|
514
|
+
const skillId = body.skillId;
|
|
515
|
+
|
|
516
|
+
if (!skillId) { sendJson(res, 400, { ok: false, error: "Missing skillId parameter" }); return; }
|
|
517
|
+
|
|
518
|
+
// Intentamos usar .agents primariamente
|
|
519
|
+
let agentsPath = path.join(project.root, ".agents");
|
|
520
|
+
if (!fs.existsSync(agentsPath) && fs.existsSync(path.join(project.root, ".agent"))) {
|
|
521
|
+
agentsPath = path.join(project.root, ".agent");
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const skillsDir = path.join(agentsPath, "skills");
|
|
525
|
+
if (!fs.existsSync(agentsPath)) fs.mkdirSync(agentsPath, { recursive: true });
|
|
526
|
+
if (!fs.existsSync(skillsDir)) fs.mkdirSync(skillsDir, { recursive: true });
|
|
527
|
+
|
|
528
|
+
const targetSkillDir = path.join(skillsDir, skillId);
|
|
529
|
+
if (!fs.existsSync(targetSkillDir)) fs.mkdirSync(targetSkillDir, { recursive: true });
|
|
530
|
+
|
|
531
|
+
const targetMdPath = path.join(targetSkillDir, "SKILL.md");
|
|
532
|
+
const templateContent = `---
|
|
533
|
+
name: ${skillId}
|
|
534
|
+
description: Skill instalada desde skills.sh
|
|
535
|
+
---
|
|
536
|
+
|
|
537
|
+
# ${skillId}
|
|
538
|
+
|
|
539
|
+
Instructions para el agente relativas a esta skill...
|
|
540
|
+
`;
|
|
541
|
+
|
|
542
|
+
fs.writeFileSync(targetMdPath, templateContent, "utf-8");
|
|
543
|
+
sendJson(res, 201, { ok: true, message: "Instalado correctamente", path: targetMdPath });
|
|
544
|
+
return;
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
|
|
407
548
|
sendJson(res, 404, { ok: false, error: "API route not found." });
|
|
408
549
|
} catch (error) {
|
|
409
550
|
sendJson(res, 500, { ok: false, error: error.message });
|
package/lib/skills.js
CHANGED
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "trackops",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "Operational project control with task management,
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Operational project control with task management, document generation, multi-project dashboard, and optional OPERA methodology",
|
|
5
5
|
"main": "lib/control.js",
|
|
6
6
|
"bin": {
|
|
7
7
|
"trackops": "bin/trackops.js"
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"task-management",
|
|
19
19
|
"dashboard",
|
|
20
20
|
"ops",
|
|
21
|
-
"
|
|
21
|
+
"opera",
|
|
22
22
|
"methodology",
|
|
23
23
|
"cli",
|
|
24
24
|
"devops",
|
|
@@ -38,9 +38,22 @@
|
|
|
38
38
|
"url": "https://github.com/Baxahaun/trackops/issues"
|
|
39
39
|
},
|
|
40
40
|
"homepage": "https://github.com/Baxahaun/trackops#readme",
|
|
41
|
+
"funding": "https://baxahaun.github.io/trackops/#support",
|
|
41
42
|
"license": "MIT",
|
|
42
43
|
"type": "commonjs",
|
|
43
44
|
"engines": {
|
|
44
45
|
"node": ">=18"
|
|
46
|
+
},
|
|
47
|
+
"scripts": {
|
|
48
|
+
"ops": "node bin/trackops.js",
|
|
49
|
+
"ops:help": "node bin/trackops.js help",
|
|
50
|
+
"ops:dashboard": "node bin/trackops.js dashboard",
|
|
51
|
+
"ops:status": "node bin/trackops.js status",
|
|
52
|
+
"ops:next": "node bin/trackops.js next",
|
|
53
|
+
"ops:sync": "node bin/trackops.js sync",
|
|
54
|
+
"ops:repo": "node bin/trackops.js refresh-repo",
|
|
55
|
+
"test": "node scripts/smoke-tests.js",
|
|
56
|
+
"test:smoke": "node scripts/smoke-tests.js",
|
|
57
|
+
"release:check": "npm test && npm pack --dry-run"
|
|
45
58
|
}
|
|
46
59
|
}
|
package/templates/etapa/agent.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Agente del Proyecto: {{PROJECT_NAME}}
|
|
2
2
|
|
|
3
3
|
## Identidad
|
|
4
|
-
Eres el agente principal del proyecto **{{PROJECT_NAME}}**.
|
|
4
|
+
Eres el agente principal del proyecto **{{PROJECT_NAME}}**. Este template existe por compatibilidad heredada y debe operar bajo el protocolo O.P.E.R.A. v3.0.
|
|
5
5
|
|
|
6
6
|
## Fuente de Verdad
|
|
7
7
|
Tu fuente de verdad es `genesis.md`. Antes de tomar cualquier decisión, consulta este archivo.
|
|
@@ -14,7 +14,7 @@ Para el seguimiento operativo y el estado del backlog, usa `project_control.json
|
|
|
14
14
|
- No edites manualmente `task_plan.md`, `progress.md` ni `findings.md`; se regeneran con `trackops sync`.
|
|
15
15
|
|
|
16
16
|
## Skills Disponibles
|
|
17
|
-
Consulta `.
|
|
17
|
+
Consulta `.agents/skills/_registry.md` para ver las skills instaladas.
|
|
18
18
|
También puedes buscar nuevas skills con `trackops skill catalog`.
|
|
19
19
|
|
|
20
20
|
## Ciclo de Trabajo
|
package/templates/opera/agent.md
CHANGED
|
@@ -14,7 +14,7 @@ Para el seguimiento operativo y el estado del backlog, usa `project_control.json
|
|
|
14
14
|
- No edites manualmente `task_plan.md`, `progress.md` ni `findings.md`; se regeneran con `trackops sync`.
|
|
15
15
|
|
|
16
16
|
## Skills Disponibles
|
|
17
|
-
Consulta `.
|
|
17
|
+
Consulta `.agents/skills/_registry.md` para ver las skills instaladas.
|
|
18
18
|
También puedes buscar nuevas skills con `trackops skill catalog`.
|
|
19
19
|
|
|
20
20
|
## Ciclo de Trabajo
|
|
@@ -156,10 +156,12 @@ proyecto/
|
|
|
156
156
|
│ ├── hub/
|
|
157
157
|
│ │ ├── agent.md # Instrucciones del agente
|
|
158
158
|
│ │ └── router.md # Enrutamiento a skills
|
|
159
|
-
│ └──
|
|
160
|
-
│
|
|
159
|
+
│ └── hub/
|
|
160
|
+
│ ├── agent.md # Instrucciones del agente
|
|
161
|
+
│ └── router.md # Enrutamiento a skills
|
|
161
162
|
├── .agents/
|
|
162
163
|
│ └── skills/
|
|
164
|
+
│ ├── _registry.md # Índice de skills instaladas
|
|
163
165
|
│ └── [skill-name]/
|
|
164
166
|
│ └── SKILL.md # Contenido de skills
|
|
165
167
|
├── genesis.md # 📜 La Constitución
|
|
@@ -191,7 +193,7 @@ proyecto/
|
|
|
191
193
|
- [ ] findings.md generado
|
|
192
194
|
- [ ] .agent/hub/agent.md configurado
|
|
193
195
|
- [ ] .agent/hub/router.md configurado
|
|
194
|
-
- [ ] .
|
|
196
|
+
- [ ] .agents/skills/_registry.md creado
|
|
195
197
|
- [ ] Skills base instaladas (commiter, changelog-updater)
|
|
196
198
|
- [ ] Repositorio GitHub creado
|
|
197
199
|
- [ ] README.md generado
|