@nucleoabierto/teleprompter 0.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Gildardo Adrian Maravilla Jacome
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,88 @@
1
+ # Teleprompter
2
+
3
+ Instalador de paquetes de configuración para repositorios.
4
+
5
+ Teleprompter lleva un paquete —un directorio con un manifiesto
6
+ `teleprompter.json` y recursos como skills o archivos de configuración—
7
+ a un repositorio con trabajo previo. Calcula el plan completo antes de
8
+ escribir nada, resuelve las colisiones con lo que ya existe y deja un
9
+ registro auditable de la instalación en `teleprompter-lock.json`.
10
+
11
+ ## Requisitos
12
+
13
+ - Node.js 22 o superior.
14
+
15
+ ## Instalación
16
+
17
+ No hace falta instalar nada: el CLI se ejecuta directamente con `npx`:
18
+
19
+ ```sh
20
+ npx @nucleoabierto/teleprompter install <paquete> <destino>
21
+ ```
22
+
23
+ También puede instalarse como herramienta global:
24
+
25
+ ```sh
26
+ npm install -g @nucleoabierto/teleprompter
27
+ teleprompter install <paquete> <destino>
28
+ ```
29
+
30
+ ## Uso
31
+
32
+ `install` recibe el directorio del paquete y la raíz del repositorio
33
+ destino. Antes de escribir nada, el instalador verifica el manifiesto y
34
+ las precondiciones del paquete, calcula el plan completo y lo presenta
35
+ recurso a recurso:
36
+
37
+ ```text
38
+ $ teleprompter install ./mi-paquete ./mi-repo
39
+ verificado: mi-paquete@1.0.0
40
+ plan de instalación:
41
+ mkdir .agents/skills/
42
+ create .agents/skills/mi-skill/SKILL.md
43
+ identical .agents/skills/otro-skill/SKILL.md
44
+ conflict .agents/config.json
45
+ ```
46
+
47
+ El plan muestra `mkdir` para las rutas de precondición a crear y una
48
+ marca por recurso: `create`, `identical`, `conflict` o `managed-update`
49
+ (el destino contiene lo que una instalación anterior registró y el
50
+ paquete ofrece una versión igual o posterior). Cuando hay
51
+ colisiones —el destino existe con contenido distinto y no consta como
52
+ instalado por Teleprompter, o fue modificado desde la instalación— una
53
+ consola interactiva pregunta por cada
54
+ recurso; sin ella, la operación aborta sin escribir nada. Dos opciones
55
+ mutuamente excluyentes resuelven las colisiones por adelantado:
56
+
57
+ | Opción | Efecto |
58
+ |-----------|------------------------------------------------------|
59
+ | `--force` | El recurso del paquete sobrescribe cada colisión |
60
+ | `--skip` | Cada colisión se omite y la omisión queda registrada |
61
+
62
+ Independiente de ellas, `--dry-run` muestra el plan y termina sin
63
+ escribir nada.
64
+
65
+ Terminada la ejecución se escribe `teleprompter-lock.json` en la raíz
66
+ del destino: qué recursos instaló Teleprompter, con qué acción y con
67
+ qué hash.
68
+
69
+ ### Códigos de salida
70
+
71
+ | Código | Significado |
72
+ |--------|------------------------------------------------------|
73
+ | `0` | Éxito |
74
+ | `1` | Manifiesto inválido |
75
+ | `2` | Plan no ejecutable (precondiciones o colisiones) |
76
+ | `3` | Error de ejecución |
77
+ | `4` | Error de invocación (argumentos o rutas) |
78
+
79
+ ## Documentación
80
+
81
+ - [manual/](manual/README.md) — guía de uso y referencia completa de la
82
+ operación `install`.
83
+ - [docs/especificacion-paquete.md](docs/especificacion-paquete.md) —
84
+ cómo escribir el manifiesto `teleprompter.json` de un paquete propio.
85
+
86
+ ## Licencia
87
+
88
+ [MIT](LICENSE).
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ import { main } from '../src/cli.js';
3
+ import { createAsker } from '../src/prompt.js';
4
+
5
+ try {
6
+ process.exitCode = await main(process.argv.slice(2), {
7
+ interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY),
8
+ createAsker,
9
+ });
10
+ } catch (error) {
11
+ console.error(`error inesperado: ${error.message}`);
12
+ process.exitCode = 3;
13
+ }
@@ -0,0 +1,73 @@
1
+ # Paquete
2
+
3
+ ## Propósito
4
+
5
+ El formato declarativo en que se describe una pieza transferible de
6
+ configuración —qué contiene, dónde va cada recurso y qué exige el
7
+ destino— para que una instalación sea inspectable y repetible.
8
+
9
+ ## Referencia del modelo
10
+
11
+ - **Lenguaje ubicuo:**
12
+ - **Paquete:** un directorio con un manifiesto `teleprompter.json`
13
+ cuyo `name` coincide con el nombre del directorio.
14
+ - Ancla: `checkName` en `src/manifest.js`; `packages/ciclo-tareas/`
15
+ - Origen: épica `docs/epics/001-formato-paquete.md`
16
+ - **Manifiesto:** el JSON `teleprompter.json` con `name`, `version`,
17
+ `install` obligatorios y `format`, `description`, `license`,
18
+ `author`, `requires`, `personalization`, `metadata`, `collection`
19
+ opcionales.
20
+ - Ancla: `TOP_LEVEL_FIELDS` y `VALIDATORS` en `src/manifest.js`;
21
+ contrato en `docs/especificacion-paquete.md`
22
+ - **Colección:** un manifiesto con `collection: true` describe un
23
+ conjunto de paquetes y no es instalable.
24
+ - Ancla: `checkCollection` en `src/manifest.js`
25
+ - **Entrada install:** par `source` (ruta dentro del paquete que debe
26
+ existir) → `target` (ruta relativa dentro del destino).
27
+ - Ancla: `checkInstallEntry` en `src/manifest.js`
28
+ - **Precondición:** entrada `requires.paths` con `path` obligatorio y
29
+ `create` booleano opcional; `create: true` difiere la creación de
30
+ la ruta al plan en lugar de abortar.
31
+ - Ancla: `checkRequiresEntry` en `src/manifest.js` y
32
+ `checkRequires` en `src/requires.js`
33
+ - **Ruta segura:** ruta relativa sin segmentos `..`, ni absoluta
34
+ POSIX, ni absoluta Windows (`C:\`) ni UNC (`\\`).
35
+ - Ancla: `isSafeRelative` en `src/paths.js`
36
+ - **Entidades / estado:**
37
+ - El paquete es inmutable y sin estado: existe como directorio con
38
+ archivos más su manifiesto. La versión es semver explícita `x.y.z`
39
+ sin prefijos ni rangos.
40
+ - Ancla: `SEMVER_RE` en `src/manifest.js`
41
+ - **Invariantes:**
42
+ - Toda ruta del manifiesto es una ruta segura —nada puede escribirse
43
+ fuera de la raíz de destino ni leerse fuera del paquete.
44
+ - Ancla: `checkRelativePath` en `src/manifest.js`
45
+ - `name` es kebab-case, ≤64 caracteres, e igual al directorio que lo
46
+ contiene. Ancla: `NAME_RE` en `src/manifest.js`
47
+ - `install` es una lista no vacía de entradas bien formadas cuyo
48
+ `source` existe. Ancla: `checkInstall` en `src/manifest.js`
49
+ - `format`, si está presente, vale `teleprompter-package@1`.
50
+ Ancla: `KNOWN_FORMAT` en `src/manifest.js`
51
+ - **Operaciones:**
52
+ - Cargar y validar el manifiesto de un directorio de paquete:
53
+ `loadManifest` en `src/manifest.js` —devuelve errores, avisos y el
54
+ manifiesto; nunca lanza.
55
+
56
+ ## Explicación del dominio
57
+
58
+ - **Fronteras:**
59
+ - Dentro: la forma del manifiesto, la seguridad de rutas y las
60
+ precondiciones declaradas.
61
+ - Fuera: qué se hace con un paquete válido (dominio de instalación)
62
+ y el contenido de las instrucciones de personalización, que el
63
+ formato solo referencia.
64
+ - Relaciones: la instalación consume el resultado de la validación
65
+ del paquete sin revalidarlo.
66
+ - **Decisiones relevantes:**
67
+ - `docs/decisions/D001–D004` — manifiesto JSON puro, cardinalidad,
68
+ semver explícita, mapa `install`.
69
+
70
+ ## Estado de salud
71
+
72
+ - Última revisión: 2026-09-28
73
+ - Divergencias conocidas: Ninguna
@@ -0,0 +1,118 @@
1
+ # Instalación
2
+
3
+ ## Propósito
4
+
5
+ Llevar un paquete válido a un repositorio con trabajo previo sin
6
+ pisarlo: verificar, presentar un plan completo antes de escribir,
7
+ resolver colisiones con una política declarada y dejar registro de lo
8
+ instalado.
9
+
10
+ ## Referencia del modelo
11
+
12
+ - **Lenguaje ubicuo:**
13
+ - **Plan:** la lista completa de acciones calculada antes de tocar
14
+ el destino; incluye los `mkdir` de las precondiciones con
15
+ `create: true` y una entrada por recurso con su marca.
16
+ - Ancla: `buildPlan` en `src/plan.js`; contrato en
17
+ `docs/instalador.md` sección «El plan»
18
+ - Origen: tarea `docs/tasks/009-plan-de-instalacion.md`
19
+ - **Marca del plan:** estado de cada recurso —`create` (destino
20
+ libre), `identical` (contenido igual), `managed-update` (propio y
21
+ sin tocar, versión igual o posterior) o `conflict` (contenido
22
+ distinto ajeno o propio modificado).
23
+ - Ancla: `buildPlan` en `src/plan.js`
24
+ - **Resolución:** la decisión sobre un `conflict` —`overwrite` o
25
+ `skip`— por flag, por respuesta interactiva o por aborto.
26
+ - Ancla: `src/cli.js` (bucle de resolución) y `createAsker` en
27
+ `src/prompt.js`
28
+ - **Registro (lock):** `teleprompter-lock.json` en la raíz del
29
+ destino; por paquete guarda `version`, `installedAt` y `files`
30
+ con `target`, acción y `sha256` —las entradas `skip` no llevan
31
+ hash. Es la memoria que distingue lo propio de lo ajeno.
32
+ - Ancla: `readLock` y `isValidLock` en `src/lock.js`; D007
33
+ - **Propiedad:** un recurso es propio cuando el destino actual
34
+ hashea igual que lo que el registro anotó para él.
35
+ - Ancla: `recorded.get(target) === destHash` en `src/plan.js`
36
+ - **Entidades / estado:**
37
+ - `VerificationResult` — `kind: 'ok'|'manifest'|'requires'`, el
38
+ manifiesto validado, `warnings`, `errors`, `creates` y `failures`.
39
+ - Ancla: `verifyPackage` en `src/verify.js`
40
+ - `Plan` — `{ mkdirs, resources, conflicts }`; cada recurso lleva
41
+ `source`, `target`, `status` y, tras resolver, `resolution`.
42
+ - Ancla: `buildPlan` en `src/plan.js`
43
+ - Hash de recurso — SHA-256 sobre dominios separados (`file\n`,
44
+ `link\n`, `dir\n`) para que tipos distintos nunca colisionen;
45
+ los árboles ordenan sus entradas para que el digest sea
46
+ independiente del orden de lectura.
47
+ - Ancla: `hashPath` en `src/hash.js`
48
+ - **Invariantes:**
49
+ - El plan completo se calcula antes de escribir; un plan no
50
+ ejecutable aborta sin escribir nada —ni recursos ni registro
51
+ (D005). Ancla: `main` en `src/cli.js`
52
+ - «Existe» significa «hay una entrada en el directorio», sin seguir
53
+ enlaces: un enlace colgado ocupa su ruta.
54
+ Ancla: `hasEntry` en `src/paths.js`
55
+ - `--force` y `--skip` son mutuamente excluyentes; el error es de
56
+ invocación (código 4). Ancla: `parseArgs` en `src/cli.js`
57
+ - `managed-update` exige hash registrado coincidente **y** versión
58
+ del paquete ≥ versión registrada; un downgrade es `conflict`.
59
+ Ancla: `semverAtLeast` en `src/plan.js`
60
+ - Una respuesta interactiva que no es afirmativa significa `skip`:
61
+ el defecto ante trabajo ajeno es no sobrescribir.
62
+ Ancla: `createAsker` en `src/prompt.js`
63
+ - Un lock ilegible o con estructura inesperada degrada a «sin
64
+ historia» con aviso, nunca a crash.
65
+ Ancla: `readLock`/`isValidLock` en `src/lock.js`
66
+ - Ninguna escritura puede salir de la raíz por un enlace en la
67
+ cadena de padres: el ancestro existente más profundo debe
68
+ resolver a un directorio dentro del destino, en el plan y en la
69
+ ejecución. Ancla: `resolvesUnder` en `src/paths.js`
70
+ - Dos entradas `install` no pueden compartir `target`: el plan sería
71
+ ambiguo. Ancla: `checkInstall` en `src/manifest.js`
72
+ - Un recurso `identical` conserva su registro previo —el contenido
73
+ sigue siendo propio— pero no crea registro si nunca se escribió.
74
+ Ancla: `writeLock` en `src/lock.js`
75
+ - **Operaciones:**
76
+ - `teleprompter install <paquete> <destino> [--force|--skip]
77
+ [--dry-run]` — verifica, planea, resuelve, ejecuta y registra.
78
+ - Ancla: `bin/teleprompter.js` → `main` en `src/cli.js`
79
+ - Ejecutar el plan resuelto: `mkdirs` primero, luego cada recurso
80
+ según su acción; `overwrite` elimina el destino antes de escribir
81
+ —nunca a través de un enlace— y los enlaces se copian como
82
+ enlaces.
83
+ - Ancla: `executePlan` en `src/execute.js`
84
+ - Registrar la instalación: fusiona el lock preservando otros
85
+ paquetes; `identical` no se registra y `skip` va sin hash.
86
+ - Ancla: `writeLock` en `src/lock.js`
87
+ - Códigos de salida: 0 éxito, 1 manifiesto inválido, 2 plan no
88
+ ejecutable, 3 error de ejecución, 4 invocación.
89
+ - Ancla: `EXIT_*` en `src/cli.js`; contrato en
90
+ `docs/instalador.md` «Resultado y errores»
91
+
92
+ ## Explicación del dominio
93
+
94
+ - **Fronteras:**
95
+ - Dentro: verificación, plan, resolución de colisiones, ejecución y
96
+ registro de una instalación.
97
+ - Fuera: la forma del manifiesto (dominio del paquete), el contenido
98
+ de la personalización y la distribución del CLI.
99
+ - Relaciones: consume el dominio del paquete a través del resultado
100
+ estructurado de `verifyPackage`; la invocación (`bin/`) es una
101
+ capa delgada sin dominio.
102
+ - **Decisiones relevantes:**
103
+ - `docs/decisions/D005` — plan completo antes de escribir, aborto
104
+ total.
105
+ - `docs/decisions/D006` — política de colisiones: interactiva,
106
+ aborto sin consola, `--force`/`--skip` excluyentes.
107
+ - `docs/decisions/D007` — `teleprompter-lock.json` como memoria de
108
+ propiedad.
109
+ - `docs/decisions/D008` — implementación JavaScript vía `npx` como
110
+ `@nucleoabierto/teleprompter`.
111
+
112
+ ## Estado de salud
113
+
114
+ - Última revisión: 2026-09-28
115
+ - Divergencias conocidas: cuando un paquete sobrescribe un recurso
116
+ registrado por otro, la entrada del primero queda intacta aunque su
117
+ contenido ya no coincida —el plan siguiente lo marcará `conflict` en
118
+ el paquete viejo, que es conservador pero puede sorprender.
@@ -0,0 +1,9 @@
1
+ # Dominios
2
+
3
+ Documentación viva del modelo del producto: un documento por dominio,
4
+ anclado al código que lo materializa.
5
+
6
+ - [001 — Paquete](001-paquete.md): el formato declarativo del
7
+ manifiesto, sus rutas seguras y sus precondiciones.
8
+ - [002 — Instalación](002-instalacion.md): verificación, plan,
9
+ colisiones, ejecución y registro de una instalación.
@@ -0,0 +1,169 @@
1
+ # Especificación del formato de paquete
2
+
3
+ Un **paquete** es un directorio de configuración trasladable entre
4
+ repositorios: un agente o instalador lo inspecciona, verifica sus
5
+ precondiciones y copia sus recursos a las rutas que el manifiesto
6
+ declara. Este documento es el contrato completo: quien lo sigue puede
7
+ producir un paquete válido sin conocer nada más del sistema.
8
+
9
+ ## Un paquete
10
+
11
+ Un paquete es un directorio que contiene un manifiesto
12
+ `teleprompter.json` en su raíz y cualquier disposición de recursos:
13
+
14
+ ```text
15
+ mi-paquete/
16
+ ├── teleprompter.json # manifiesto (obligatorio)
17
+ └── <recursos> # archivos y subdirectorios libres
18
+ ```
19
+
20
+ No hay disposición fija para los recursos: el manifiesto declara, para
21
+ cada origen, dónde se instala en el repositorio destino.
22
+
23
+ ## El manifiesto `teleprompter.json`
24
+
25
+ El manifiesto es JSON puro: no ejecuta nada. Según el valor del campo
26
+ `collection`, el archivo describe un paquete (ausente o `false`) o una
27
+ colección (`true`, véase «Colecciones»). Primero el contrato de paquete.
28
+
29
+ ### Campos obligatorios
30
+
31
+ | Campo | Tipo | Regla |
32
+ |---|---|---|
33
+ | `name` | string | Identificador del paquete: minúsculas, números y guiones, máx. 64 caracteres, sin guiones al inicio ni al final. Debe coincidir con el nombre del directorio del paquete. |
34
+ | `version` | string | Versión semver explícita `x.y.z`. La autoridad de la versión es el manifiesto, no el VCS. |
35
+ | `install` | array | Lista no vacía de entradas `{ "source", "target" }`. Véase abajo. Un paquete sin `install` o con la lista vacía es inválido. |
36
+
37
+ Cada entrada de `install` declara una copia:
38
+
39
+ - `source` — ruta dentro del paquete, relativa a su raíz. Puede ser un
40
+ archivo o un directorio; un directorio se instala con todo su
41
+ contenido.
42
+ - `target` — ruta relativa a la raíz del repositorio destino donde se
43
+ instala.
44
+
45
+ La barra final en `source` y `target` es una convención legible para
46
+ marcar directorios, no un requisito del formato.
47
+
48
+ Ni `source` ni `target` admiten rutas absolutas ni `..`: el origen no
49
+ puede salir del paquete y el destino no puede salir del repositorio.
50
+
51
+ ### Campos opcionales
52
+
53
+ | Campo | Tipo | Descripción |
54
+ |---|---|---|
55
+ | `format` | string | Versión del formato del manifiesto: `"teleprompter-package@1"`. Su ausencia equivale a la primera versión del formato. |
56
+ | `description` | string | Descripción corta del paquete. |
57
+ | `license` | string | Identificador SPDX (`"MIT"`, `"Apache-2.0"`) o referencia a un archivo de licencia. |
58
+ | `author` | object | `{ "name": "...", "email": "...", "url": "..." }`. Solo `name` es obligatorio dentro del objeto. |
59
+ | `requires` | object | Precondiciones del repositorio destino, verificables antes de instalar. De momento solo la clave `paths`. |
60
+ | `personalization` | string | Ruta dentro del paquete al archivo o directorio con instrucciones de personalización. Solo declara que existe adaptación pendiente y dónde está documentada; no se instala salvo que también figure en `install`. |
61
+ | `metadata` | object | Mapa libre clave→valor para datos del autor que el instalador no interpreta. |
62
+
63
+ `requires.paths` es una lista de entradas `{ "path", "create"? }` sobre
64
+ rutas relativas a la raíz del destino (`path` no admite rutas absolutas
65
+ ni `..`):
66
+
67
+ - Si la ruta no existe y `create` es `false` o está ausente, la
68
+ instalación aborta.
69
+ - Si la ruta no existe y `create` es `true`, el instalador la crea
70
+ antes de instalar.
71
+
72
+ ### Campos desconocidos
73
+
74
+ Política mixta:
75
+
76
+ - **Nivel superior** del manifiesto (de paquete o de colección): el
77
+ campo desconocido se ignora y el validador emite un aviso.
78
+ - **Dentro de un objeto conocido** (`author`, `requires`, una entrada
79
+ de `requires.paths`, una entrada de `install`, una entrada de
80
+ `packages` en una colección): el campo desconocido es un error y el
81
+ manifiesto no es válido.
82
+
83
+ ## Colecciones
84
+
85
+ Un repositorio puede alojar un paquete o varios. Solo hay un nombre de
86
+ archivo que buscar —`teleprompter.json`— y un campo que discrimina qué
87
+ describe:
88
+
89
+ - `collection` ausente o `false` → el manifiesto describe un paquete.
90
+ - `collection: true` → el manifiesto describe una **colección**: un
91
+ índice de paquetes por ruta.
92
+
93
+ Un directorio es una cosa o la otra: la colección es un contenedor
94
+ puro, no instalable como paquete. Un manifiesto de colección admite los
95
+ campos `name`, `description`, `license`, `author`, `metadata` y
96
+ `format` —con la misma semántica que en un paquete, con una excepción:
97
+ el `name` de una colección es cosmético y no debe coincidir con el
98
+ nombre de ningún directorio— más:
99
+
100
+ | Campo | Tipo | Regla |
101
+ |---|---|---|
102
+ | `collection` | boolean | Obligatorio y `true`. Es el discriminador. |
103
+ | `packages` | array | Obligatorio. Lista de entradas `{ "path": "..." }` con la ruta relativa al directorio de cada paquete; `path` no admite rutas absolutas ni `..`. |
104
+
105
+ La entrada solo declara la ruta: el `name` y la `version` de cada
106
+ paquete se leen de su propio `teleprompter.json`, nunca del índice.
107
+ Los campos propios de paquete (`version`, `install`, `requires`,
108
+ `personalization`) en un manifiesto de colección son un error.
109
+
110
+ ## Ejemplo completo
111
+
112
+ Estructura de un paquete con tres recursos:
113
+
114
+ ```text
115
+ ciclo-tareas/
116
+ ├── teleprompter.json
117
+ └── skills/
118
+ ├── crear-tareas/
119
+ ├── ejecutar-tareas/
120
+ └── commit/
121
+ ```
122
+
123
+ Su manifiesto:
124
+
125
+ ```json
126
+ {
127
+ "format": "teleprompter-package@1",
128
+ "name": "ciclo-tareas",
129
+ "version": "1.0.0",
130
+ "description": "Ciclo de tareas del proyecto: creación, ejecución con revisión dual y commit",
131
+ "license": "MIT",
132
+ "install": [
133
+ {
134
+ "source": "skills/crear-tareas/",
135
+ "target": ".agents/skills/crear-tareas/"
136
+ },
137
+ {
138
+ "source": "skills/ejecutar-tareas/",
139
+ "target": ".agents/skills/ejecutar-tareas/"
140
+ },
141
+ {
142
+ "source": "skills/commit/",
143
+ "target": ".agents/skills/commit/"
144
+ }
145
+ ],
146
+ "requires": {
147
+ "paths": [{ "path": ".agents/skills/", "create": true }]
148
+ },
149
+ "metadata": { "origin": "teleprompter" }
150
+ }
151
+ ```
152
+
153
+ ## Lista de verificación de un paquete válido
154
+
155
+ 1. `teleprompter.json` en la raíz del directorio del paquete, JSON
156
+ válido.
157
+ 2. `name` en kebab-case, igual al nombre del directorio.
158
+ 3. `version` semver `x.y.z`.
159
+ 4. `install` no vacío; cada entrada tiene solo `source` y `target`;
160
+ cada `source` existe dentro del paquete; ninguna ruta es absoluta ni
161
+ contiene `..`.
162
+ 5. `source` y `personalization` apuntan dentro del paquete; `target` y
163
+ `requires.paths[].path` son relativos a la raíz del destino; ninguna
164
+ de estas rutas es absoluta ni contiene `..`.
165
+ 6. Los campos opcionales presentes pertenecen al contrato; dentro de
166
+ objetos conocidos no hay campos desconocidos (a nivel superior, un
167
+ campo desconocido solo genera un aviso, no invalida el manifiesto).
168
+ 7. En una colección: `collection: true`, `packages` con rutas válidas
169
+ y ningún campo propio de paquete.
@@ -0,0 +1,69 @@
1
+ # Instalar un paquete
2
+
3
+ El usuario ejecuta `teleprompter install <paquete> <destino>` para
4
+ llevar los recursos de un paquete a un repositorio existente, con el
5
+ plan completo visible antes de escribir y un registro de lo instalado.
6
+ Qué es un paquete y qué garantiza la instalación están definidos en
7
+ [dominio de paquete](https://github.com/nucleoabierto/teleprompter/blob/master/docs/domains/001-paquete.md) y
8
+ [dominio de instalación](https://github.com/nucleoabierto/teleprompter/blob/master/docs/domains/002-instalacion.md); la
9
+ mecánica detallada, en la [referencia](referencia-install.md).
10
+
11
+ ## Escenarios
12
+
13
+ - **Un paquete se instala de principio a fin con el binario real.** —
14
+ módulo `test/e2e.test.js`, «the reference package installs end to end
15
+ through the real binary»
16
+ - **El plan se presenta antes de escribir, con una marca por recurso.**
17
+ En un destino vacío todo es `create`. — módulo `test/plan.test.js`,
18
+ «plan marks every resource create on an empty destination»
19
+ - **Reinstalar es inocuo:** lo que ya coincide se marca `identical` y
20
+ no se escribe. — módulos `test/plan.test.js` («plan marks identical
21
+ when the destination already holds the same content») y
22
+ `test/execute.test.js` («reinstalling the same package reports
23
+ identical and keeps the recorded entry»)
24
+ - **Lo instalado por Teleprompter se actualiza sin preguntar** cuando
25
+ el paquete trae una versión igual o posterior y el destino sigue
26
+ siendo lo que el registro anotó. — módulo `test/plan.test.js`, «plan
27
+ marks managed-update when the destination still holds what the lock
28
+ recorded»
29
+ - **Lo modificado a mano es una colisión,** aunque el registro lo
30
+ reconozca como instalado. — módulo `test/plan.test.js`, «plan marks
31
+ conflict when a recorded resource was modified locally»
32
+ - **Las colisiones se resuelven una a una en consola interactiva.** —
33
+ módulo `test/plan.test.js`, «an interactive console resolves each
34
+ conflict per answer»
35
+ - **Sin forma de preguntar ni opciones de resolución, las colisiones
36
+ abortan la operación sin escribir.** — módulo `test/plan.test.js`,
37
+ «an interactive console without an asker reports conflicts and
38
+ aborts»
39
+ - **`--force` y `--skip` resuelven todas las colisiones por adelantado**
40
+ y son mutuamente excluyentes. — módulos `test/plan.test.js`
41
+ («--force resolves every conflict as overwrite», «--skip resolves
42
+ every conflict as skip») y `test/cli.test.js` («main exits with usage
43
+ error on unknown or mutually exclusive flags»)
44
+ - **`--dry-run` muestra el plan y termina sin escribir ni registrar.**
45
+ — módulo `test/plan.test.js`, «--dry-run prints the plan and exits
46
+ without writing»
47
+ - **Un manifiesto inválido aborta con código 1 sin tocar el destino.**
48
+ — módulo `test/cli.test.js`, «main exits 1 on an invalid manifest
49
+ without writing to the destination»
50
+ - **Una precondición incumplida aborta con código 2 sin escribir;** con
51
+ `create: true` la ruta se crea como parte del plan. — módulo
52
+ `test/cli.test.js` («main exits 2 on an unmet precondition without
53
+ writing», «main passes when a missing precondition path allows
54
+ creation»)
55
+ - **Un error de invocación —argumentos ausentes, de más o rutas que no
56
+ son directorios— sale con código 4.** — módulo `test/cli.test.js`,
57
+ «main exits with usage error on missing, wrong, or excess arguments»
58
+ - **Cada instalación escribe `teleprompter-lock.json`** con los
59
+ recursos instalados, sus acciones y sus hashes, y conserva lo
60
+ registrado por otros paquetes. — módulo `test/execute.test.js`
61
+ («install copies every resource and writes the lock on an empty
62
+ destination», «writeLock preserves records belonging to other
63
+ packages»)
64
+ - **Un error a mitad de ejecución sale con código 3 e informa de lo ya
65
+ aplicado.** — módulo `test/execute.test.js`, «a mid-execution error
66
+ exits 3 and reports what was applied»
67
+ - **Si el paquete declara personalización, la salida informa de dónde
68
+ están las instrucciones.** — módulo `test/execute.test.js`, «install
69
+ reports the personalization instructions location»
@@ -0,0 +1,27 @@
1
+ # Manual de Teleprompter
2
+
3
+ Documentación de usuario del instalador Teleprompter. Para una primera
4
+ instalación, empezar por la guía de uso.
5
+
6
+ ## Guías
7
+
8
+ - [Guía de uso](guia-de-uso.md) — instalar un paquete paso a paso, con
9
+ el paquete de referencia del repositorio como ejemplo.
10
+
11
+ ## Referencia
12
+
13
+ - [Referencia de `install`](referencia-install.md) — la operación
14
+ completa: fases, marcas del plan, resolución de colisiones, registro
15
+ y códigos de salida.
16
+
17
+ ## Funcionalidades
18
+
19
+ - [001 — Instalar un paquete](001-instalar-un-paquete.md) — qué hace
20
+ `install` y los escenarios que la suite de pruebas verifica.
21
+
22
+ ## Documentos relacionados
23
+
24
+ - [docs/domains/](../docs/domains/README.md) — el modelo del producto:
25
+ qué es un paquete y qué es una instalación.
26
+ - [docs/especificacion-paquete.md](../docs/especificacion-paquete.md) —
27
+ cómo escribir el manifiesto `teleprompter.json` de un paquete propio.