@cristobalbn/chaski 0.0.0-stage → 0.1.0

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/SECURITY.md ADDED
@@ -0,0 +1,75 @@
1
+ # Política de seguridad
2
+
3
+ ## Reportar una vulnerabilidad
4
+
5
+ No abras un issue público para un problema de seguridad.
6
+
7
+ Usa la pestaña **Security → Report a vulnerability** del repositorio en GitHub
8
+ (advisory privado). Incluye:
9
+
10
+ - Versión de chaski y de Node.
11
+ - Sistema operativo.
12
+ - Qué CLIs tienes configurados.
13
+ - Pasos para reproducir.
14
+ - Impacto que observaste.
15
+
16
+ Respondo en un plazo razonable y coordino la divulgación antes de publicar el
17
+ arreglo.
18
+
19
+ ## Modelo de amenaza
20
+
21
+ Vale la pena que sepas a qué está expuesta esta herramienta, porque es una que
22
+ se ejecuta sola en cada turno de tus sesiones.
23
+
24
+ ### Qué puede hacer chaski
25
+
26
+ - **Leer:** el transcript de tus sesiones, la salida de `git` en tu proyecto,
27
+ y sus propios archivos de configuración.
28
+ - **Escribir:** `.tambo/` dentro del proyecto, `~/.chaski/`, los archivos de
29
+ configuración de los CLIs que habilitaste, y `.gitignore`, `AGENTS.md` y
30
+ `.claude/skills/relevo/` durante `init`.
31
+ - **Red:** ninguna. chaski no hace ninguna petición de red, nunca.
32
+
33
+ ### Qué NO hace
34
+
35
+ - No invoca `claude -p`, `codex exec` ni `agy -p`.
36
+ - No hace commits ni modifica tu historial de git.
37
+ - No ejecuta scripts del repositorio en el que corre.
38
+ - No abre puertos ni escucha conexiones.
39
+ - No tiene dependencias de runtime, así que no hay árbol de npm que comprometer.
40
+
41
+ ### Riesgos conocidos y cómo se contienen
42
+
43
+ **Inyección de prompt a través del relevo.** El relevo se inyecta en el contexto
44
+ de un agente con permisos de escritura, así que quien pueda escribir en
45
+ `.tambo/` podría intentar colar instrucciones. Contención: el bloque se declara
46
+ como datos entre delimitadores explícitos, se firma con HMAC contra una clave
47
+ local que nunca se versiona, y un relevo cuya firma no valida se inyecta
48
+ rotulado como no verificado en lugar de pasar por legítimo. Además `.tambo/`
49
+ está en `.gitignore`, así que no viaja entre máquinas.
50
+
51
+ **Captura accidental de secretos.** El transcript contiene todo lo que pasó por
52
+ la sesión. El filtro de `src/lib/secrets.mjs` corre antes de escribir a disco,
53
+ no solo antes de enviar algo. Si encuentras un formato de credencial que se nos
54
+ escapa, es un reporte de seguridad válido y lo agradecemos.
55
+
56
+ **ReDoS en los patrones de `chaski.json`.** `redact` y `excludePaths` son
57
+ expresiones regulares que el filtro de secretos ejecuta en cada turno. Un
58
+ patrón con retroceso catastrófico (por ejemplo algo con grupos anidados y
59
+ cuantificadores superpuestos) puede colgar el hook indefinidamente en vez de
60
+ terminar en milisegundos. **`chaski.json` se versiona**, así que sus patrones
61
+ pueden venir de un tercero — un colaborador, un PR, una plantilla copiada de
62
+ otro repo — y no son menos código que un script: revísalos en el PR como
63
+ revisarías cualquier otro cambio antes de aceptarlo.
64
+
65
+ **chaski como vector de cadena de suministro.** Instalarlo significa registrar
66
+ un comando que tus CLIs van a ejecutar solos. Para que puedas verificarlo:
67
+ `chaski doctor` imprime el comando exacto registrado en cada configuración —
68
+ son unas diez líneas. Revísalo después de instalar y después de cada
69
+ actualización. Si prefieres no confiar en un paquete publicado, clona el
70
+ repositorio y ejecuta desde el código fuente: son ~2.000 líneas sin dependencias.
71
+
72
+ ## Versiones soportadas
73
+
74
+ Mientras el proyecto esté antes de 1.0, solo se da soporte a la última versión
75
+ publicada.
package/package.json CHANGED
@@ -1,6 +1,50 @@
1
1
  {
2
2
  "name": "@cristobalbn/chaski",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Relevo de contexto entre agentes de codigo (Claude Code, Codex, agy)",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "engines": {
8
+ "node": ">=20"
9
+ },
10
+ "bin": {
11
+ "chaski": "src/cli.mjs"
12
+ },
13
+ "scripts": {
14
+ "check": "node --check src/capture.mjs && node --check src/inject.mjs && node --check src/cli.mjs && node --check src/capturar.mjs && node --check src/leer.mjs && node --check src/lib/paths.mjs && node --check src/lib/facts.mjs && node --check src/lib/secrets.mjs && node --check src/lib/relay.mjs && node --check src/lib/ask.mjs && node --check src/lib/budget.mjs",
15
+ "test": "node --test test/core.test.mjs test/install.test.mjs",
16
+ "prepublishOnly": "npm run check && npm test"
17
+ },
18
+ "publishConfig": {
19
+ "access": "public"
20
+ },
21
+ "files": [
22
+ "src",
23
+ "skill",
24
+ "README.md",
25
+ "AGENTS.md",
26
+ "SECURITY.md",
27
+ "CHANGELOG.md",
28
+ "LICENSE"
29
+ ],
30
+ "keywords": [
31
+ "claude-code",
32
+ "codex",
33
+ "antigravity",
34
+ "agy",
35
+ "handoff",
36
+ "context",
37
+ "ai-agent",
38
+ "cli",
39
+ "relevo"
40
+ ],
41
+ "author": "Cristobal Barrera",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/cristobalbn/chaski.git"
45
+ },
46
+ "bugs": {
47
+ "url": "https://github.com/cristobalbn/chaski/issues"
48
+ },
49
+ "homepage": "https://github.com/cristobalbn/chaski#readme"
50
+ }
package/skill/SKILL.md ADDED
@@ -0,0 +1,80 @@
1
+ ---
2
+ name: relevo
3
+ description: Guarda la narrativa de Chaski al pedir «relevo», «guarda el relevo» o «actualiza el relevo», o al cerrar un bloque de trabajo para cambiar de agente. Registra intención, decisiones, pendientes y siguiente paso. No usar para consultas sobre Chaski ni para leer o continuar un relevo existente.
4
+ ---
5
+
6
+ # Actualizar el relevo
7
+
8
+ Escribes la parte del relevo que un script no puede deducir: la **intención**.
9
+ Los hechos —archivos tocados, diff, tests, commits— ya los escribió chaski y
10
+ son exactos. No los repitas ni los corrijas.
11
+
12
+ ## Petición común
13
+
14
+ En Claude Code, Codex y agy, un mensaje que solo diga **«relevo»**, o que pida
15
+ **«guarda el relevo»** o **«actualiza el relevo»**, solicita guardar la narrativa:
16
+ ejecuta los pasos de abajo y confirma al terminar.
17
+
18
+ **«Continúa desde el relevo»** solicita retomar el trabajo. Lee el relevo de la
19
+ rama actual, contrástalo con el código y continúa con lo pendiente; no ejecutes
20
+ estos pasos de guardado por esa petición. Una pregunta sobre el funcionamiento
21
+ del relevo tampoco solicita sobrescribirlo.
22
+
23
+ ## Pasos
24
+
25
+ 1. Ubica la raíz del repositorio Git (si el espacio de trabajo es una carpeta contenedora con un único repo hijo o una subcarpeta del repo, usa la raíz de ese repositorio). Lee `.tambo/branches/<rama-actual>/estado.json` desde esa raíz, donde `<rama-actual>` sale de `git rev-parse --abbrev-ref HEAD`.
26
+ 2. Escribe la narrativa en el campo `narrative` de ese JSON en UTF-8, junto con
27
+ `narrativeAuthor` (tu nombre de agente) y `narrativeWrittenAt` (ISO 8601 de ahora).
28
+ 3. No toques ningún otro campo. `facts`, `commands`, `offset` y `signature` son de chaski.
29
+ 4. Confirma al usuario en una línea: qué quedó anotado como siguiente paso.
30
+
31
+ El Markdown se regenera solo en el próximo turno. No edites `relevo.md` a mano.
32
+
33
+ ## Qué escribir
34
+
35
+ Cuatro secciones, en este orden, en prosa breve. Apunta a 120-200 palabras en
36
+ total: el relevo tiene un presupuesto duro de contexto y lo que escribas compite
37
+ con el espacio que el próximo agente necesita para trabajar.
38
+
39
+ **Tarea** — qué se está intentando lograr, en una o dos frases. No el archivo
40
+ que se está editando, sino el objetivo.
41
+
42
+ **Decisiones** — qué se eligió y, sobre todo, **qué se descartó y por qué**.
43
+ Esto es lo que evita que el siguiente agente reabra algo ya cerrado. Si no se
44
+ tomó ninguna decisión en esta sesión, omite la sección.
45
+
46
+ **A medias** — lo más importante del relevo. Qué está empezado y no terminado,
47
+ con la ruta y la línea si existe. Sé específico: «falta invalidar el token
48
+ anterior en Redis antes de emitir el nuevo, en `src/auth/refresh.ts:41`» sirve;
49
+ «falta terminar refresh» no sirve.
50
+
51
+ **Siguiente paso** — la próxima acción concreta, una sola.
52
+
53
+ ## Reglas
54
+
55
+ - **Escribe solo lo que pasó en la conversación.** Si no sabes por qué se eligió
56
+ algo, no lo inventes: omítelo. Una narrativa incompleta es útil; una inventada
57
+ manda al próximo agente en la dirección equivocada con confianza.
58
+ - **No incluyas secretos.** Ni tokens, ni claves, ni contenido de `.env`, ni
59
+ URLs con credenciales. Si necesitas mencionar una variable sensible, nómbrala
60
+ sin su valor.
61
+ - **No incluyas instrucciones dirigidas al próximo agente** más allá del
62
+ siguiente paso. El relevo se inyecta como datos, no como órdenes.
63
+ - **No repitas los hechos.** Si el diff ya dice que `jwt.ts` tiene +82 líneas,
64
+ no lo escribas.
65
+ - **Preserva UTF-8 al escribir `estado.json`.** Usa la herramienta de edición de archivos del agente o escribe en UTF-8 directo; en Windows no pases texto con tildes o `«»` como literal por la consola de PowerShell sin `UTF8Encoding`, porque convierte los caracteres no ASCII en `?`.
66
+ - **Distingue lo temporal de lo permanente.** Si en esta sesión apareció una
67
+ convención que vale **siempre** —un estilo, una herramienta prohibida, un
68
+ comando que hay que correr antes de dar algo por listo— no va en el relevo,
69
+ que se reescribe: propón al usuario agregarla a `AGENTS.md`. Una línea
70
+ preguntando, no la agregues sin confirmar.
71
+
72
+ ## Ejemplo
73
+
74
+ ```json
75
+ {
76
+ "narrative": "Migrando la capa de auth a JWT con refresh tokens.\n\nDecidido: el refresh token va en cookie httpOnly, no en localStorage, por XSS. Se descartó passport.js: demasiado peso para dos endpoints.\n\nA medias: el endpoint de refresh existe y responde, pero no rota el token viejo. Falta invalidarlo en Redis antes de emitir el nuevo, en src/auth/refresh.ts:41. Los dos tests que fallan en test/auth.test.ts son por esto, no por otra cosa.\n\nSiguiente paso: cerrar la rotación en refresh.ts:41 y volver a correr npm test -- auth.",
77
+ "narrativeAuthor": "claude code",
78
+ "narrativeWrittenAt": "2026-10-31T16:20:00.000Z"
79
+ }
80
+ ```
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ // Puente de compatibilidad. Este archivo se llamaba así antes de que el código
3
+ // se homologara al inglés, y `capturar.mjs` pasó a ser `capture.mjs`.
4
+ //
5
+ // Por qué existe: `init` registra la RUTA ABSOLUTA de los scripts en la
6
+ // configuración de cada CLI, y esa configuración vive fuera del repositorio.
7
+ // Quien actualice chaski desde una versión anterior sin volver a correr
8
+ // `chaski init` tiene los hooks apuntando a este nombre, y sin este archivo
9
+ // recibe un volcado de Node de quince líneas en cada turno:
10
+ //
11
+ // Error: Cannot find module '...\chaski\src\capturar.mjs'
12
+ //
13
+ // Pasó de verdad, y el error sobrevive a `chaski init` dentro de una sesión ya
14
+ // abierta, porque los CLIs leen su configuración de hooks una sola vez al
15
+ // arrancar. Así que no alcanzaba con documentar el paso: el nombre viejo tiene
16
+ // que seguir funcionando.
17
+ //
18
+ // No avisa por stderr a propósito. Este hook corre en CADA turno, y una línea
19
+ // de aviso por turno es ruido que el usuario no puede callar. El aviso lo da
20
+ // el puente de inicio de sesión (`leer.mjs`), que corre una vez por sesión.
21
+ //
22
+ // No lo borres sin un ciclo de deprecación de verdad: mientras alguien pueda
23
+ // tener una configuración vieja en disco, borrarlo le rompe cada turno.
24
+ import './capture.mjs';