@nucleoabierto/teleprompter 0.1.1 → 0.2.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/README.md CHANGED
@@ -17,25 +17,42 @@ registro auditable de la instalación en `teleprompter-lock.json`.
17
17
  No hace falta instalar nada: el CLI se ejecuta directamente con `npx`:
18
18
 
19
19
  ```sh
20
- npx @nucleoabierto/teleprompter install <paquete> <destino>
20
+ npx @nucleoabierto/teleprompter user/repo
21
21
  ```
22
22
 
23
23
  También puede instalarse como herramienta global:
24
24
 
25
25
  ```sh
26
26
  npm install -g @nucleoabierto/teleprompter
27
- teleprompter install <paquete> <destino>
27
+ teleprompter user/repo
28
28
  ```
29
29
 
30
30
  ## Uso
31
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
32
+ El primer argumento es el origen del paquete. `user/repo` descarga el
33
+ tarball público del repositorio de GitHub —sin git ni credenciales—
34
+ y usa la raíz del árbol como paquete; la referencia se elige con
35
+ `user/repo@ref` o `--ref <ref>` (la rama por defecto si no se indica).
36
+ Para un paquete local se usa `--path <directorio>`, que no procesa el
37
+ argumento `user/repo`. El segundo argumento posicional es el destino
38
+ de la copia —la raíz del repositorio donde instalar— y por defecto es
39
+ el directorio de trabajo:
40
+
41
+ ```sh
42
+ teleprompter nucleoabierto/mi-paquete # remoto, destino: pwd
43
+ teleprompter nucleoabierto/mi-paquete ./destino
44
+ teleprompter nucleoabierto/mi-paquete@v1.2.0 ./destino
45
+ teleprompter --path ./mi-paquete ./destino # local
46
+ teleprompter install nucleoabierto/mi-paquete # alias
47
+ ```
48
+
49
+ Antes de escribir nada, el instalador verifica el manifiesto y
34
50
  las precondiciones del paquete, calcula el plan completo y lo presenta
35
51
  recurso a recurso:
36
52
 
37
53
  ```text
38
- $ teleprompter install ./mi-paquete ./mi-repo
54
+ $ teleprompter nucleoabierto/mi-paquete ./mi-repo
55
+ obteniendo: nucleoabierto/mi-paquete
39
56
  verificado: mi-paquete@1.0.0
40
57
  plan de instalación:
41
58
  mkdir .agents/skills/
@@ -63,8 +80,21 @@ Independiente de ellas, `--dry-run` muestra el plan y termina sin
63
80
  escribir nada.
64
81
 
65
82
  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.
83
+ del destino: qué recursos instaló Teleprompter, con qué acción, con
84
+ qué hash y desde qué origen. Si el paquete declara instrucciones de
85
+ personalización, su contenido se entrega tal cual al final del
86
+ resultado y queda consultable después —desde la raíz del destino— con
87
+ `teleprompter guide [<paquete>]`. El propio registro se consulta con
88
+ `teleprompter list`, que muestra una entrada por paquete instalado:
89
+ nombre, versión, fecha de instalación y recursos escritos.
90
+ `teleprompter check` confronta el registro con el disco e informa por
91
+ cada recurso si sigue intacto, fue modificado, ya no existe o no
92
+ puede verificarse. Y `teleprompter update <paquete>` lleva un paquete
93
+ instalado a la versión que publica su origen —el registrado en la
94
+ instalación, o uno explícito con `--path`/`user/repo[@ref]`—:
95
+ calcula el plan de actualización recurso a recurso, sobrescribe lo
96
+ intacto, pregunta por lo editado y retira lo que la versión nueva ya
97
+ no trae.
68
98
 
69
99
  ### Códigos de salida
70
100
 
@@ -75,6 +105,7 @@ qué hash.
75
105
  | `2` | Plan no ejecutable (precondiciones o colisiones) |
76
106
  | `3` | Error de ejecución |
77
107
  | `4` | Error de invocación (argumentos o rutas) |
108
+ | `5` | Error de obtención del repositorio remoto |
78
109
 
79
110
  ## Documentación
80
111
 
@@ -4,6 +4,8 @@ import { createAsker } from '../src/prompt.js';
4
4
 
5
5
  try {
6
6
  process.exitCode = await main(process.argv.slice(2), {
7
+ cwd: process.cwd(),
8
+ fetch,
7
9
  interactive: Boolean(process.stdin.isTTY && process.stdout.isTTY),
8
10
  createAsker,
9
11
  });
@@ -33,6 +33,12 @@ destino— para que una instalación sea inspectable y repetible.
33
33
  - **Ruta segura:** ruta relativa sin segmentos `..`, ni absoluta
34
34
  POSIX, ni absoluta Windows (`C:\`) ni UNC (`\\`).
35
35
  - Ancla: `isSafeRelative` en `src/paths.js`
36
+ - **Guía de personalización:** el archivo que `personalization`
37
+ declara —debe existir dentro del paquete y ser un archivo—; su
38
+ contenido es texto libre del mantenedor dirigido a un agente,
39
+ nunca validado ni ejecutado.
40
+ - Ancla: `checkPersonalization` en `src/manifest.js`; origen:
41
+ épica `docs/epics/003-personalizacion-guiada.md`
36
42
  - **Entidades / estado:**
37
43
  - El paquete es inmutable y sin estado: existe como directorio con
38
44
  archivos más su manifiesto. La versión es semver explícita `x.y.z`
@@ -48,6 +54,9 @@ destino— para que una instalación sea inspectable y repetible.
48
54
  `source` existe. Ancla: `checkInstall` en `src/manifest.js`
49
55
  - `format`, si está presente, vale `teleprompter-package@1`.
50
56
  Ancla: `KNOWN_FORMAT` en `src/manifest.js`
57
+ - Ningún `target` es `teleprompter-lock.json` ni cae dentro de
58
+ `.teleprompter/`: son espacios reservados a la herramienta.
59
+ Ancla: `checkInstall` en `src/manifest.js`; D010
51
60
  - **Operaciones:**
52
61
  - Cargar y validar el manifiesto de un directorio de paquete:
53
62
  `loadManifest` en `src/manifest.js` —devuelve errores, avisos y el
@@ -66,8 +75,10 @@ destino— para que una instalación sea inspectable y repetible.
66
75
  - **Decisiones relevantes:**
67
76
  - `docs/decisions/D001–D004` — manifiesto JSON puro, cardinalidad,
68
77
  semver explícita, mapa `install`.
78
+ - `docs/decisions/D010` — `.teleprompter/` como namespace gestionado
79
+ para la guía de personalización.
69
80
 
70
81
  ## Estado de salud
71
82
 
72
- - Última revisión: 2026-09-28
83
+ - Última revisión: 2026-09-29
73
84
  - Divergencias conocidas: Ninguna
@@ -23,23 +23,56 @@ instalado.
23
23
  - Ancla: `buildPlan` en `src/plan.js`
24
24
  - **Resolución:** la decisión sobre un `conflict` —`overwrite` o
25
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`
26
+ - Ancla: `resolveConflicts` en `src/plan.js` (la asignación es
27
+ operación del plan), `settleConflicts` en `src/cli.js` (la
28
+ política) y `createAsker` en `src/prompt.js`
28
29
  - **Registro (lock):** `teleprompter-lock.json` en la raíz del
29
30
  destino; por paquete guarda `version`, `installedAt` y `files`
30
31
  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
32
+ hash— y `personalization` con la ruta gestionada de la guía
33
+ cuando el manifiesto la declara; `origin` registra de dónde vino
34
+ la instalación —`{type:'github',repo,ref?}` o
35
+ `{type:'path',path}` absoluta—, opcional en entradas escritas
36
+ antes del campo. Es la memoria que distingue lo propio de lo
37
+ ajeno.
38
+ - Ancla: `readLock`, `isValidLock`, `writeLock`, `lockEntry` y
39
+ `lockEntries` en `src/lock.js` —la forma del registro solo se
40
+ navega desde ese módulo— y `originOf` en `src/cli.js`;
41
+ D007, D014
33
42
  - **Propiedad:** un recurso es propio cuando el destino actual
34
43
  hashea igual que lo que el registro anotó para él.
35
44
  - Ancla: `recorded.get(target) === destHash` en `src/plan.js`
45
+ - **Deriva:** el estado de un recurso registrado al confrontarlo
46
+ con el disco —`intact` (el hash coincide), `modified` (difiere),
47
+ `missing` (la ruta ya no existe) o `unverifiable` (sin `sha256`
48
+ registrado, lectura fallida o ruta que escapa del destino); el
49
+ informe los presenta como `intacto`, `modificado`, `ausente` y
50
+ `no verificable`.
51
+ - Ancla: `classifyResource` en `src/drift.js`, que aplica el
52
+ nivel cadena de la defensa de rutas registradas
53
+ (`recordedChainSafe` en `src/paths.js`); contrato en
54
+ `docs/instalador.md` «La verificación del estado»
55
+ - **Plan de actualización:** el plan de una versión entrante
56
+ distinta de la registrada; además de las marcas de instalación
57
+ añade `update` (la versión cambió el recurso y el destino sigue
58
+ intacto) y `retire` (registrado, retirado por la versión e
59
+ intacto → eliminación), y marca los retirados con deriva como
60
+ `conflict` de eliminación —`overwrite` quita, `skip` conserva—.
61
+ Versión igual a la registrada → `upToDate`, sin plan.
62
+ - Ancla: `buildUpdatePlan` en `src/plan.js`; contrato en
63
+ `docs/instalador.md` «El plan de actualización»; D015
36
64
  - **Entidades / estado:**
37
65
  - `VerificationResult` — `kind: 'ok'|'manifest'|'requires'`, el
38
66
  manifiesto validado, `warnings`, `errors`, `creates` y `failures`.
39
67
  - Ancla: `verifyPackage` en `src/verify.js`
40
68
  - `Plan` — `{ mkdirs, resources, conflicts }`; cada recurso lleva
41
69
  `source`, `target`, `status` y, tras resolver, `resolution`.
42
- - Ancla: `buildPlan` en `src/plan.js`
70
+ - Ancla: `buildPlan` y `resolveConflicts` en `src/plan.js`
71
+ - `UpdatePlan` — `{ upToDate, mkdirs, resources, conflicts,
72
+ retired }`; `resources` incluye las entradas del manifiesto y
73
+ los retirados con deriva marcados `removal`, `retired` solo las
74
+ marcas `retire`.
75
+ - Ancla: `buildUpdatePlan` en `src/plan.js`
43
76
  - Hash de recurso — SHA-256 sobre dominios separados (`file\n`,
44
77
  `link\n`, `dir\n`) para que tipos distintos nunca colisionen;
45
78
  los árboles ordenan sus entradas para que el digest sea
@@ -48,7 +81,8 @@ instalado.
48
81
  - **Invariantes:**
49
82
  - El plan completo se calcula antes de escribir; un plan no
50
83
  ejecutable aborta sin escribir nada —ni recursos ni registro
51
- (D005). Ancla: `main` en `src/cli.js`
84
+ (D005). Ancla: `runInstall`/`runUpdate` y las fases
85
+ `settleConflicts`/`checkGuideDestination` en `src/cli.js`
52
86
  - «Existe» significa «hay una entrada en el directorio», sin seguir
53
87
  enlaces: un enlace colgado ocupa su ruta.
54
88
  Ancla: `hasEntry` en `src/paths.js`
@@ -69,23 +103,95 @@ instalado.
69
103
  ejecución. Ancla: `resolvesUnder` en `src/paths.js`
70
104
  - Dos entradas `install` no pueden compartir `target`: el plan sería
71
105
  ambiguo. Ancla: `checkInstall` en `src/manifest.js`
106
+ - `.teleprompter/` es propiedad de la herramienta, igual que el lock:
107
+ la guía declarada se copia ahí fuera del plan y sin detección de
108
+ colisiones, pero su destino se verifica escribible **antes** de
109
+ escribir nada —un escape hace el plan no ejecutable (D005)—.
110
+ Ancla: `installPersonalization` en `src/execute.js` y la
111
+ pre-verificación en `src/cli.js`; D010
72
112
  - Un recurso `identical` conserva su registro previo —el contenido
73
113
  sigue siendo propio— pero no crea registro si nunca se escribió.
74
114
  Ancla: `writeLock` en `src/lock.js`
115
+ - Un recurso retirado por la versión solo se elimina intacto —propio
116
+ y sin tocar—; modificado o no verificable exige decisión. Quedan
117
+ excluidos las entradas `skip` y el target de `personalization`
118
+ que el manifiesto **entrante** siga declarando. Si la versión
119
+ declara otra guía, la registrada se retira incluso modificada
120
+ —deja de ser la guía y un `keep` la dejaría huérfana para
121
+ `guide`; solo un `unverifiable` —ruta insegura— sigue siendo
122
+ decisión—; si la versión abandona el campo, la guía registrada se
123
+ retira como cualquier otro recurso (D015). Ancla:
124
+ `buildUpdatePlan` en `src/plan.js`
75
125
  - **Operaciones:**
76
- - `teleprompter install <paquete> <destino> [--force|--skip]
77
- [--dry-run]` — verifica, planea, resuelve, ejecuta y registra.
126
+ - `teleprompter [install] <user/repo[@ref]> [destino]` o
127
+ `teleprompter [install] --path <paquete> [destino]` — obtiene el
128
+ paquete (tarball público de GitHub o directorio local), verifica,
129
+ planea, resuelve, ejecuta y registra; el destino por defecto es el
130
+ directorio de trabajo.
78
131
  - Ancla: `bin/teleprompter.js` → `main` en `src/cli.js`
79
132
  - Ejecutar el plan resuelto: `mkdirs` primero, luego cada recurso
80
133
  según su acción; `overwrite` elimina el destino antes de escribir
81
134
  —nunca a través de un enlace— y los enlaces se copian como
82
- enlaces.
83
- - Ancla: `executePlan` en `src/execute.js`
135
+ enlaces. Un fallo a mitad lanza `ExecutionError`, que transporta
136
+ las acciones ya aplicadas y el error original como `cause`, para
137
+ que el informe muestre el estado parcial.
138
+ - Ancla: `executePlan` y `ExecutionError` en `src/execute.js`
84
139
  - Registrar la instalación: fusiona el lock preservando otros
85
- paquetes; `identical` no se registra y `skip` va sin hash.
140
+ paquetes; `identical` no se registra y `skip` va sin hash; la
141
+ guía gestionada se añade a `files` y al campo `personalization`
142
+ sin figurar entre las acciones del plan. La escritura es
143
+ atómica —temporal en el mismo directorio + `rename`—, así que un
144
+ corte a mitad deja el lock anterior o el nuevo, nunca uno
145
+ truncado.
86
146
  - Ancla: `writeLock` en `src/lock.js`
147
+ - Materializar y entregar la guía: `installPersonalization` copia
148
+ el archivo declarado a `.teleprompter/<paquete>/<archivo>` tras
149
+ ejecutar el plan, y el bloque final `personalización (<ruta>):`
150
+ entrega el contenido de la copia materializada —no el fuente,
151
+ que en origen remoto ya no existe—.
152
+ - Ancla: `installPersonalization` en `src/execute.js` y
153
+ `printGuide` en `src/cli.js`
154
+ - Consultar la guía: `teleprompter guide [<paquete>]` lee el campo
155
+ `personalization` del registro del directorio de trabajo y
156
+ muestra el mismo bloque; no hay destino ni opciones de
157
+ instalación. Sin guía que mostrar es código 4; la ruta
158
+ registrada insegura o el archivo ausente es código 3 —el lock
159
+ es dato versionado y se revalida antes de leer.
160
+ - Ancla: `showGuide` en `src/cli.js`, que aplica el nivel hoja de
161
+ la defensa de rutas registradas (`resolveRecordedPath` en
162
+ `src/paths.js`); D011
163
+ - Consultar el registro: `teleprompter list` lee el registro del
164
+ directorio de trabajo —sin argumentos ni opciones— y muestra una
165
+ entrada por paquete con `nombre@version`, `installedAt` y los
166
+ `target` escritos; las entradas `skip` no se listan —registran
167
+ una omisión— y no se exponen hashes ni acciones. Sin
168
+ instalaciones responde «no hay paquetes instalados» con código
169
+ 0: es una respuesta, no un fallo.
170
+ - Ancla: `showList` en `src/cli.js`; D012
171
+ - Calcular el plan de actualización: confronta la versión entrante
172
+ con el registro y el disco; devuelve `upToDate` si la versión es
173
+ la registrada, o el plan clasificado con los retirados según su
174
+ deriva —sin escribir nada—.
175
+ - Ancla: `buildUpdatePlan` en `src/plan.js`; D015
176
+ - Actualizar: `teleprompter update <paquete> [<origen>]` opera
177
+ sobre el directorio de trabajo —sin destino—; resuelve la fuente
178
+ del `origin` registrado salvo que la invocación lo sobrescriba
179
+ (`--path`, `user/repo[@ref]` o `--ref`), y luego ejecuta el flujo
180
+ de instalación con el plan de actualización. Los conflicts
181
+ `removal` preguntan por quitar y resuelven `remove`/`keep`; el
182
+ registro queda a la versión nueva con el origen efectivo.
183
+ - Ancla: `runUpdate` en `src/cli.js`; D016
184
+ - Verificar el estado de lo instalado: `teleprompter check`
185
+ confronta el registro del directorio de trabajo con el disco
186
+ —sin argumentos ni opciones— y muestra por paquete una marca de
187
+ deriva por recurso registrado; las entradas `skip` no se
188
+ verifican y encontrar deriva no es un fallo —la consulta siempre
189
+ termina con código 0—.
190
+ - Ancla: `showCheck` en `src/cli.js` y `classifyResource` en
191
+ `src/drift.js`; D013
87
192
  - Códigos de salida: 0 éxito, 1 manifiesto inválido, 2 plan no
88
- ejecutable, 3 error de ejecución, 4 invocación.
193
+ ejecutable, 3 error de ejecución, 4 invocación, 5 obtención del
194
+ repositorio remoto.
89
195
  - Ancla: `EXIT_*` en `src/cli.js`; contrato en
90
196
  `docs/instalador.md` «Resultado y errores»
91
197
 
@@ -108,10 +214,25 @@ instalado.
108
214
  propiedad.
109
215
  - `docs/decisions/D008` — implementación JavaScript vía `npx` como
110
216
  `@nucleoabierto/teleprompter`.
217
+ - `docs/decisions/D010` — `.teleprompter/` como ubicación gestionada
218
+ de la guía de personalización.
219
+ - `docs/decisions/D011` — `guide` como subcomando de consulta sobre
220
+ el directorio de trabajo.
221
+ - `docs/decisions/D012` — `list` como subcomando de consulta del
222
+ registro sobre el directorio de trabajo.
223
+ - `docs/decisions/D013` — `check` como subcomando de verificación
224
+ del estado de los recursos instalados.
225
+ - `docs/decisions/D014` — `origin` en el registro: la procedencia
226
+ reobtenible de cada instalación.
227
+ - `docs/decisions/D015` — vocabulario del plan de actualización y
228
+ política de retirados.
229
+ - `docs/decisions/D016` — `update` como subcomando: resolución del
230
+ origen y acciones `remove`/`keep`.
111
231
 
112
232
  ## Estado de salud
113
233
 
114
- - Última revisión: 2026-09-28
234
+ - Última revisión: 2026-10-01 (revisión de arquitectura
235
+ `docs/architecture-reviews/002-instalacion-tras-el-ciclo-de-vida.md`)
115
236
  - Divergencias conocidas: cuando un paquete sobrescribe un recurso
116
237
  registrado por otro, la entrada del primero queda intacta aunque su
117
238
  contenido ya no coincida —el plan siguiente lo marcará `conflict` en
@@ -6,4 +6,4 @@ anclado al código que lo materializa.
6
6
  - [001 — Paquete](001-paquete.md): el formato declarativo del
7
7
  manifiesto, sus rutas seguras y sus precondiciones.
8
8
  - [002 — Instalación](002-instalacion.md): verificación, plan,
9
- colisiones, ejecución y registro de una instalación.
9
+ colisiones, ejecución, registro y consulta de una instalación.
@@ -47,6 +47,8 @@ marcar directorios, no un requisito del formato.
47
47
 
48
48
  Ni `source` ni `target` admiten rutas absolutas ni `..`: el origen no
49
49
  puede salir del paquete y el destino no puede salir del repositorio.
50
+ Además, ningún `target` puede ser `teleprompter-lock.json` ni caer
51
+ dentro de `.teleprompter/`: son espacios reservados a la herramienta.
50
52
 
51
53
  ### Campos opcionales
52
54
 
@@ -57,12 +59,12 @@ puede salir del paquete y el destino no puede salir del repositorio.
57
59
  | `license` | string | Identificador SPDX (`"MIT"`, `"Apache-2.0"`) o referencia a un archivo de licencia. |
58
60
  | `author` | object | `{ "name": "...", "email": "...", "url": "..." }`. Solo `name` es obligatorio dentro del objeto. |
59
61
  | `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`. |
62
+ | `personalization` | string | Ruta dentro del paquete al archivo con las instrucciones de personalización. El archivo debe existir; su contenido es texto libre del mantenedor dirigido a un agente y nunca se valida ni se ejecuta. El instalador lo copia a `.teleprompter/<paquete>/<archivo>` en el destino, entrega su contenido tal cual al final de la instalación y recuerda su ubicación en `teleprompter-lock.json` —consultable después con `teleprompter guide`. |
61
63
  | `metadata` | object | Mapa libre clave→valor para datos del autor que el instalador no interpreta. |
62
64
 
63
65
  `requires.paths` es una lista de entradas `{ "path", "create"? }` sobre
64
66
  rutas relativas a la raíz del destino (`path` no admite rutas absolutas
65
- ni `..`):
67
+ ni `..`, ni puede caer dentro de `.teleprompter/`):
66
68
 
67
69
  - Si la ruta no existe y `create` es `false` o está ausente, la
68
70
  instalación aborta.
@@ -114,6 +116,7 @@ Estructura de un paquete con tres recursos:
114
116
  ```text
115
117
  ciclo-tareas/
116
118
  ├── teleprompter.json
119
+ ├── PERSONALIZE.md
117
120
  └── skills/
118
121
  ├── crear-tareas/
119
122
  ├── ejecutar-tareas/
@@ -146,6 +149,7 @@ Su manifiesto:
146
149
  "requires": {
147
150
  "paths": [{ "path": ".agents/skills/", "create": true }]
148
151
  },
152
+ "personalization": "PERSONALIZE.md",
149
153
  "metadata": { "origin": "teleprompter" }
150
154
  }
151
155
  ```
@@ -159,9 +163,12 @@ Su manifiesto:
159
163
  4. `install` no vacío; cada entrada tiene solo `source` y `target`;
160
164
  cada `source` existe dentro del paquete; ninguna ruta es absoluta ni
161
165
  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 `..`.
166
+ 5. `source` y `personalization` apuntan dentro del paquete —
167
+ `personalization` a un archivo existente cuyo enlace no resuelve
168
+ fuera del paquete—; `target` y `requires.paths[].path` son relativos
169
+ a la raíz del destino; ninguna de estas rutas es absoluta ni
170
+ contiene `..`, ningún `target` es `teleprompter-lock.json` y nada
171
+ cae dentro de `.teleprompter/`.
165
172
  6. Los campos opcionales presentes pertenecen al contrato; dentro de
166
173
  objetos conocidos no hay campos desconocidos (a nivel superior, un
167
174
  campo desconocido solo genera un aviso, no invalida el manifiesto).
@@ -1,6 +1,7 @@
1
1
  # Instalar un paquete
2
2
 
3
- El usuario ejecuta `teleprompter install <paquete> <destino>` para
3
+ El usuario ejecuta `teleprompter <user/repo> [destino]` —o
4
+ `teleprompter --path <paquete> [destino]` para un paquete local— para
4
5
  llevar los recursos de un paquete a un repositorio existente, con el
5
6
  plan completo visible antes de escribir y un registro de lo instalado.
6
7
  Qué es un paquete y qué garantiza la instalación están definidos en
@@ -10,6 +11,35 @@ mecánica detallada, en la [referencia](referencia-install.md).
10
11
 
11
12
  ## Escenarios
12
13
 
14
+ - **El paquete puede venir de un repositorio público de GitHub:**
15
+ `user/repo` descarga el tarball por HTTP —sin git— e instala la raíz
16
+ del árbol extraído. — módulo `test/cli.test.js`, «user/repo with OUT
17
+ installs into it»
18
+ - **`install` es un alias de la forma corta.** — módulo
19
+ `test/cli.test.js`, «install is an alias of the short form»
20
+ - **El destino por defecto es el directorio de trabajo.** — módulo
21
+ `test/cli.test.js`, «user/repo without OUT installs into the working
22
+ directory»
23
+ - **`--path` instala un paquete local sin peticiones HTTP.** — módulo
24
+ `test/cli.test.js`, «--path installs the local package without any
25
+ HTTP request»
26
+ - **La referencia se elige con `@ref` o `--ref`;** declarar ambas es un
27
+ error de invocación. — módulos `test/cli.test.js` («the ref reaches
28
+ the download URL via @ref or --ref», «declaring @ref and --ref at
29
+ once is a usage error») y `test/fetch.test.js` («fetchRepoTree asks
30
+ for the ref in the URL when given»)
31
+ - **Un repositorio inaccesible o una referencia inexistente abortan
32
+ con código 5 sin escribir nada.** — módulo `test/cli.test.js` («a
33
+ missing repository exits 5 and writes nothing», «a network failure
34
+ exits 5 and writes nothing»)
35
+ - **El temporal de extracción se elimina siempre:** tras éxito, error
36
+ y `--dry-run`. — módulos `test/cli.test.js` («a repo without
37
+ teleprompter.json exits 1 and cleans the temp dir», «--dry-run with
38
+ a remote origin writes nothing and cleans the temp dir») y
39
+ `test/fetch.test.js`
40
+ - **Un archivo hostil no escribe fuera del temporal** — las rutas con
41
+ `..` no se extraen. — módulo `test/fetch.test.js`, «fetchRepoTree
42
+ does not let a hostile entry escape the temp dir»
13
43
  - **Un paquete se instala de principio a fin con el binario real.** —
14
44
  módulo `test/e2e.test.js`, «the reference package installs end to end
15
45
  through the real binary»
@@ -64,6 +94,22 @@ mecánica detallada, en la [referencia](referencia-install.md).
64
94
  - **Un error a mitad de ejecución sale con código 3 e informa de lo ya
65
95
  aplicado.** — módulo `test/execute.test.js`, «a mid-execution error
66
96
  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»
97
+ - **Si el paquete declara personalización, la guía se copia a
98
+ `.teleprompter/<paquete>/` y su contenido se entrega tal cual al
99
+ final del resultado.** — módulos `test/execute.test.js` («install
100
+ materializes the personalization guide in the managed namespace»)
101
+ y `test/cli.test.js` («install delivers the declared guide verbatim
102
+ after the result»)
103
+ - **`--dry-run` no entrega la guía:** solo muestra el plan. — módulo
104
+ `test/cli.test.js`, «--dry-run shows the plan but never delivers
105
+ the guide»
106
+ - **`teleprompter guide [<paquete>]` relee la guía instalada** desde
107
+ el directorio de trabajo, sin reinstalar ni redescargar. — módulo
108
+ `test/cli.test.js` («guide prints the installed guide from the
109
+ working directory», «guide \<paquete\> shows only that package's
110
+ guide», «guide without a package shows every installed guide»)
111
+ - **La consulta distingue sus fallos:** sin guía que mostrar sale con
112
+ código 4; el archivo registrado ausente, con código 3. — módulo
113
+ `test/cli.test.js` («guide exits 4 without a lock, on unknown
114
+ packages, or without a guide», «guide exits 3 when the recorded
115
+ guide file is gone»)
@@ -0,0 +1,44 @@
1
+ # Listar los paquetes instalados
2
+
3
+ El usuario ejecuta `teleprompter list` desde la raíz del
4
+ repositorio destino para ver qué paquetes instaló Teleprompter —
5
+ nombre, versión, fecha y recursos escritos— sin abrir
6
+ `teleprompter-lock.json`. Qué contiene el registro está definido en
7
+ el [dominio de instalación](https://github.com/nucleoabierto/teleprompter/blob/master/docs/domains/002-instalacion.md); la
8
+ referencia completa del comando, en la
9
+ [referencia de `list`](referencia-list.md).
10
+
11
+ ## Escenarios
12
+
13
+ - **`list` muestra una entrada por paquete instalado** con su
14
+ `nombre@version`, el instante de la instalación y una línea por
15
+ recurso escrito. — módulo `test/cli.test.js` («list shows name,
16
+ version, date and written resources of a package», «list shows
17
+ one entry per installed package»)
18
+ - **La salida es lenguaje de producto:** los recursos se listan por
19
+ su ruta, sin hashes ni acciones internas del registro. — módulo
20
+ `test/cli.test.js`, «list shows recorded targets without hashes
21
+ or internal actions»
22
+ - **Los recursos omitidos por colisión no se listan:** el registro
23
+ anota la decisión, pero la herramienta no escribió nada ahí. —
24
+ módulo `test/cli.test.js`, «list does not list resources recorded
25
+ as skipped»
26
+ - **Una entrada sin fecha registrada se lista sin ella.** — módulo
27
+ `test/cli.test.js`, «list shows an entry without installedAt
28
+ without a date»
29
+ - **Un paquete con guía de personalización señala cómo consultarla**
30
+ con `guide`. — módulo `test/cli.test.js`, «list points to guide
31
+ for a package with personalization»
32
+ - **Sin instalaciones registradas responde «no hay paquetes
33
+ instalados»** con código 0 —es una respuesta, no un fallo—; un
34
+ registro corrupto añade un aviso y responde lo mismo. — módulo
35
+ `test/cli.test.js` («list answers that nothing is installed when
36
+ there is no lock», «list warns on a corrupt lock and answers
37
+ nothing installed»)
38
+ - **El listado no depende del origen de la instalación:** tras
39
+ instalar remoto o con `--path`, lee solo el registro del
40
+ directorio de trabajo. — módulo `test/cli.test.js`, «list reads
41
+ the working directory lock whatever the install origin»
42
+ - **`list` no admite argumentos ni opciones:** cualquiera es un
43
+ error de invocación con código 4. — módulo `test/cli.test.js`,
44
+ «list rejects arguments and install options»
@@ -0,0 +1,56 @@
1
+ # Verificar el estado de los recursos instalados
2
+
3
+ El usuario ejecuta `teleprompter check` desde la raíz del
4
+ repositorio destino para saber en qué estado quedó cada recurso que
5
+ Teleprompter escribió —intacto, modificado, ausente o no
6
+ verificable— confrontando el registro con el disco, sin abrir
7
+ `teleprompter-lock.json`. Qué contiene el registro está definido en
8
+ el [dominio de instalación](https://github.com/nucleoabierto/teleprompter/blob/master/docs/domains/002-instalacion.md); la
9
+ referencia completa del comando, en la
10
+ [referencia de `check`](referencia-check.md).
11
+
12
+ ## Escenarios
13
+
14
+ - **`check` muestra una entrada por paquete instalado** con su
15
+ `nombre@version` y una línea por recurso registrado con su marca
16
+ de estado. — módulo `test/cli.test.js` («check reports an
17
+ installed resource as intact», «check reports each state across
18
+ packages and resources»)
19
+ - **Un recurso editado tras la instalación se marca `modificado`**
20
+ y uno borrado, `ausente`. — módulo `test/cli.test.js` («check
21
+ reports an edited resource as modified», «check reports a deleted
22
+ resource as missing»)
23
+ - **La guía de personalización gestionada se verifica como un
24
+ recurso más,** porque está registrada en `files`. — módulo
25
+ `test/cli.test.js`, «check verifies the managed guide as a
26
+ recorded resource»
27
+ - **Los recursos omitidos por colisión no se verifican:** el
28
+ registro anota la decisión, pero la herramienta no escribió nada
29
+ ahí. — módulo `test/cli.test.js`, «check does not report resources
30
+ recorded as skipped»
31
+ - **Una entrada registrada sin hash se marca `no verificable`,** lo
32
+ mismo que un recurso presente que no se puede leer. — módulo
33
+ `test/cli.test.js` («check reports a recorded entry without
34
+ sha256 as unverifiable», «check reports an unreadable resource as
35
+ unverifiable»)
36
+ - **Una ruta registrada que escapa del destino no se lee** —el
37
+ registro es dato versionado, no memoria confiable— y se marca
38
+ `no verificable`. — módulo `test/cli.test.js`, «check marks
39
+ recorded paths that escape the destination as unverifiable»
40
+ - **La salida es lenguaje de producto:** marcas y rutas, sin hashes
41
+ ni acciones internas del registro. — módulo `test/cli.test.js`,
42
+ «check reports drift in product language, without hashes or
43
+ actions»
44
+ - **Un registro escrito a mano se clasifica igual** que uno
45
+ producido por una instalación real. — módulo `test/cli.test.js`,
46
+ «check reports a hand-written lock entry whose hash differs as
47
+ modified»
48
+ - **Sin instalaciones registradas responde «no hay paquetes
49
+ instalados»** con código 0 —es una respuesta, no un fallo—; un
50
+ registro corrupto añade un aviso y responde lo mismo. — módulo
51
+ `test/cli.test.js` («check answers that nothing is installed when
52
+ there is no lock», «check warns on a corrupt lock and answers
53
+ nothing installed»)
54
+ - **`check` no admite argumentos ni opciones:** cualquiera es un
55
+ error de invocación con código 4. — módulo `test/cli.test.js`,
56
+ «check rejects arguments and install options»
@@ -0,0 +1,34 @@
1
+ # Actualizar un paquete
2
+
3
+ `teleprompter update <paquete>` lleva un paquete instalado a la
4
+ versión que publica su origen —la registrada en `teleprompter-lock.json`,
5
+ o una indicada en la invocación—. Se ejecuta desde la raíz del
6
+ repositorio destino.
7
+
8
+ ## Escenarios que la suite verifica
9
+
10
+ - Un paquete instalado desde un `--path` se actualiza desde ese
11
+ origen sin indicarlo: lo que la versión cambió y sigue intacto se
12
+ sobrescribe, lo nuevo se crea, lo retirado e intacto se elimina, y
13
+ el registro queda a la versión nueva.
14
+ - Si la versión entrante coincide con la registrada, responde que el
15
+ paquete ya está en esa versión y no escribe nada.
16
+ - Pedir un paquete no instalado, o uno sin origen registrado y sin
17
+ origen explícito, es un error de invocación.
18
+ - `--path` o un `user/repo[@ref]` explícito sobrescriben el origen
19
+ registrado y quedan como el nuevo origen; `--ref` cambia solo el
20
+ ref de un origen de repositorio —con `--path` es un error—.
21
+ - Una edición local sobre un recurso que la versión también cambió
22
+ se decide caso a caso: la consola interactiva pregunta, `--force`
23
+ sobrescribe, `--skip` conserva, y sin consola la operación aborta
24
+ sin escribir.
25
+ - Un recurso retirado por la versión pero modificado localmente se
26
+ decide igual: quitar o conservar —conservarlo mantiene su registro
27
+ previo—.
28
+ - `--dry-run` muestra el plan de actualización completo sin escribir
29
+ nada.
30
+ - Si el origen publica un paquete con otro nombre, la invocación es
31
+ un error —no se actualiza nada—.
32
+
33
+ Véase la [referencia de `update`](referencia-update.md) para la
34
+ gramática completa y los códigos de salida.
package/manual/README.md CHANGED
@@ -13,11 +13,26 @@ instalación, empezar por la guía de uso.
13
13
  - [Referencia de `install`](referencia-install.md) — la operación
14
14
  completa: fases, marcas del plan, resolución de colisiones, registro
15
15
  y códigos de salida.
16
+ - [Referencia de `guide`](referencia-guide.md) — consultar las
17
+ instrucciones de personalización de los paquetes instalados.
18
+ - [Referencia de `list`](referencia-list.md) — listar los paquetes
19
+ instalados con su versión, fecha y recursos.
20
+ - [Referencia de `check`](referencia-check.md) — verificar el estado
21
+ de los recursos instalados: intactos, modificados, ausentes o no
22
+ verificables.
23
+ - [Referencia de `update`](referencia-update.md) — actualizar un
24
+ paquete instalado a la versión que publica su origen.
16
25
 
17
26
  ## Funcionalidades
18
27
 
19
28
  - [001 — Instalar un paquete](001-instalar-un-paquete.md) — qué hace
20
29
  `install` y los escenarios que la suite de pruebas verifica.
30
+ - [002 — Listar los paquetes instalados](002-listar-paquetes-instalados.md)
31
+ — qué muestra `list` y los escenarios que la suite verifica.
32
+ - [003 — Verificar el estado de los recursos instalados](003-verificar-recursos-instalados.md)
33
+ — qué informa `check` y los escenarios que la suite verifica.
34
+ - [004 — Actualizar un paquete](004-actualizar-un-paquete.md) — qué
35
+ hace `update` y los escenarios que la suite verifica.
21
36
 
22
37
  ## Documentos relacionados
23
38