jorgex-stack 1.9.70 → 1.9.72
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 +17 -20
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +55 -60
- package/package.json +1 -1
- package/stack/agents/comment-fixer.md +2 -2
- package/stack/skills/diagnose/SKILL.md +6 -2
- package/stack/skills/lean-code/SKILL.md +4 -0
- package/stack/skills/mcp-builder/reference/python_mcp_server.md +7 -5
- package/stack/skills/xreview/SKILL.md +2 -2
- package/stack/system-prompt/AGENTS.md +4 -0
package/README.md
CHANGED
|
@@ -35,11 +35,8 @@ The skill never edits artifacts or creates tasks. During audit remediation, the
|
|
|
35
35
|
Install and run via npm without cloning the repository:
|
|
36
36
|
|
|
37
37
|
```bash
|
|
38
|
-
#
|
|
38
|
+
# Install (also reapplies mode, models, permissions and browser guidance to the configured runtimes).
|
|
39
39
|
pnpm dlx jorgex-stack install
|
|
40
|
-
|
|
41
|
-
# Already installed: apply the latest published stack while keeping the existing model selection
|
|
42
|
-
pnpm dlx jorgex-stack sync
|
|
43
40
|
```
|
|
44
41
|
|
|
45
42
|
For a fresh Engram installation, always consult the current published Stack and bypass only the `pnpm dlx` cache:
|
|
@@ -70,7 +67,7 @@ Runtime defaults are documented in [docs/references/permissions.md](docs/referen
|
|
|
70
67
|
|
|
71
68
|
### Modes: Human and Programmatic
|
|
72
69
|
|
|
73
|
-
`install`
|
|
70
|
+
`install` accepts two mutually-exclusive installation modes. The choice is global (not per runtime) and is saved in `~/.jorgex-stack/install-mode.json` on first run; subsequent `install` calls reuse it. Re-run `install` with `--mode` to switch.
|
|
74
71
|
|
|
75
72
|
| Mode | Audience | Final assistant response | Subagents |
|
|
76
73
|
|------|----------|--------------------------|-----------|
|
|
@@ -98,7 +95,7 @@ Flags:
|
|
|
98
95
|
|
|
99
96
|
- `--mode human` cannot be combined with `--subagent-concurrency`.
|
|
100
97
|
- Without `--mode`, the first run asks interactively; `--yes`, non-TTY, and `--target-dir` default to `human`.
|
|
101
|
-
- `pnpm dlx jorgex-stack
|
|
98
|
+
- `pnpm dlx jorgex-stack install` reuses the saved mode; pass `--mode` to change and save the preference.
|
|
102
99
|
|
|
103
100
|
Programmatic mode guarantees:
|
|
104
101
|
|
|
@@ -118,7 +115,7 @@ El canon de Stack y el paquete Pi mantienen una snapshot de 17 árboles de skill
|
|
|
118
115
|
|
|
119
116
|
Pi combines the **snapshot v2** package with a Stack-owned shared projection. Package resolution, verification, receipt and recovery behavior are documented in [docs/references/pi-runtime.md](docs/references/pi-runtime.md); historical pins are not a promise that personal Pi installations have migrated.
|
|
120
117
|
|
|
121
|
-
En Pi nuevo, Stack gestiona `jorgex-pi` y sus seis companions locales, y prepara el provider oficial `gentle-engram` en un stage aislado. Cuando el candidato Pi verificado declara el contrato nativo `mcp-native-v1`, `install` o `update` deliberado ejecuta la fase nativa (`runNativePiMcpPhase`) antes de la promoción del paquete: `mcp.json` pasa a ser la autoridad persistente de los servidores protegidos (`engram`, `context7`, `chrome-devtools`), no se instala `pi-mcp-adapter` y la autoridad granular vive en `pi-projection-receipt.json`. La fase nativa solo **prepara** (`NativeMcpPreparedWrite` con `created`/`removals`/`snapshot`/`backupRoot`); el handoff activo y `mcp.json` los escribe el ciclo de proyección (`runPiProjectionLifecycleSystem`), que aplica el handoff DevTools v3 contra la estampa `receipt.devtools.sha256` y, después del readback, invoca una sola vez `pendingNativeConfigWrite` (CAS de remociones y
|
|
118
|
+
En Pi nuevo, Stack gestiona `jorgex-pi` y sus seis companions locales, y prepara el provider oficial `gentle-engram` en un stage aislado. Cuando el candidato Pi verificado declara el contrato nativo `mcp-native-v1`, `install` o `update` deliberado ejecuta la fase nativa (`runNativePiMcpPhase`) antes de la promoción del paquete: `mcp.json` pasa a ser la autoridad persistente de los servidores protegidos (`engram`, `context7`, `chrome-devtools`), no se instala `pi-mcp-adapter` y la autoridad granular vive en `pi-projection-receipt.json`. La fase nativa solo **prepara** (`NativeMcpPreparedWrite` con `created`/`removals`/`snapshot`/`backupRoot`); el handoff activo y `mcp.json` los escribe el ciclo de proyección (`runPiProjectionLifecycleSystem`), que aplica el handoff DevTools v3 contra la estampa `receipt.devtools.sha256` y, después del readback, invoca una sola vez `pendingNativeConfigWrite` (CAS de remociones y creaciones con `restoreOwnedWrite`); sólo entonces publica el receipt y la autoridad final. Cada `install` o `update` deliberado resuelve el `latest` publicado, verifica lock/SRI/árbol y promociona solo el provider gentle en modo nativo (o los dos providers en modo legacy); conserva el enlace y receipt privados de `jorgex-pi`, el host Pi, las entradas npm ajenas y los datos de Engram. Con un receipt Stack válido, `install --agents pi` continúa por la actualización autenticada; el estado manual o ambiguo se bloquea. El [inventario de Pi](docs/references/pi-runtime.md#inventario-operativo-de-pi) distingue componentes obligatorios y opcionales, y la sección de [transporte nativo y autoridad granular](docs/references/pi-runtime.md#transporte-nativo-y-autoridad-granular) describe el contrato nativo verificable (no se infiere por versión del host ni por `testedVersions`); el opt-out explícito de DevTools retira el claim de la autoridad y, cuando la entrada sigue full-stamped, el `mcp.json` la elimina; cuando está personalizada la conserva y queda UNOWNED (no se reclama de vuelta por SHA idéntico y exige resolución manual).
|
|
122
119
|
|
|
123
120
|
The following command block is retained as historical reference for that transition:
|
|
124
121
|
|
|
@@ -130,7 +127,7 @@ pnpm dlx jorgex-stack@1.9.7 sync --agents pi
|
|
|
130
127
|
pnpm dlx jorgex-stack@1.9.7 uninstall --agents pi
|
|
131
128
|
```
|
|
132
129
|
|
|
133
|
-
For a deliberate managed install or update, Stack resolves the live published `latest` tag to an exact release, verifies its canonical tarball URL and SRI/bytes, and prepares it in an isolated stage before activation. The stage locks six direct dependencies, copies them byte-identically into the package-local runtime tree, and records those copies only in the tree inventory; the lock remains the verified lock, and the release id uses both lock and tree digests; it then runs the RPC smoke before and after promotion. Stack then backs up state and publishes only its owned package entry. Automatic restoration covers activation/verification failures; if projection or MCP configuration fails after the package is activated and verified, Stack blocks with the backup retained rather than claiming a full rollback. The schema 1 receipt records managed-package evidence for offline verification. `
|
|
130
|
+
For a deliberate managed install or update, Stack resolves the live published `latest` tag to an exact release, verifies its canonical tarball URL and SRI/bytes, and prepares it in an isolated stage before activation. The stage locks six direct dependencies, copies them byte-identically into the package-local runtime tree, and records those copies only in the tree inventory; the lock remains the verified lock, and the release id uses both lock and tree digests; it then runs the RPC smoke before and after promotion. Stack then backs up state and publishes only its owned package entry. Automatic restoration covers activation/verification failures; if projection or MCP configuration fails after the package is activated and verified, Stack blocks with the backup retained rather than claiming a full rollback. The schema 1 receipt records managed-package evidence for offline verification. `models`, `doctor` and `uninstall` do not acquire a new version; they require an authenticated receipt/artifact, with explicit legacy recovery paths where applicable. Deliberate `install`/`update` can resolve and download Pi and its providers; browser acquisition requires explicit opt-in or a persisted preference. `update --check` does not download. `--target-dir` neither downloads Pi nor touches the real HOME; with a previously verified candidate/stage injected, it can run isolated smoke/runner code inside the target. Direct Pi installation is separate and does not provide Stack's rollback guarantees. Do not use Pi's native `pi update --extensions` as a Stack repair path: it does not provide the managed receipt or Stack's activation/recovery guarantees. A Pi release is adopted only after its reader declaration, tarball and integrity pass the verified stage; no future version is pinned manually.
|
|
134
131
|
|
|
135
132
|
The artifact values in `src/lib/pi-runtime-pin.json` describe frozen historical/reference metadata, not the live install candidate; live artifact URL, version and integrity are resolved from the published registry.
|
|
136
133
|
|
|
@@ -146,37 +143,37 @@ The historical published artifact has two separate provenance anchors. The local
|
|
|
146
143
|
|
|
147
144
|
The historical `0.8.0` artifact records two distinct commit identities: the release checkout and tarball producer is `9f999747df3e335947a61d38e581555367973b09` (`main`, release `0.8.0`); and the Stack parity source is `11e7666ea4e40bde1de8bc434610747eb797ab9c`. Registry metadata has no `gitHead`; README does not invent a separate source identity, attestation or signature.
|
|
148
145
|
|
|
149
|
-
Install
|
|
146
|
+
Install and uninstall back up every managed file before changing it and are idempotent. `doctor` reports package and projection drift without repairing it. Uninstall removes only receipt-owned package/projection state, retains shared files also owned by another runtime, and preserves user content outside marked sections. Engram remains user-owned and is never removed; the receipts only carry the verified executable hand-off required by the package.
|
|
150
147
|
|
|
151
148
|
The package owns Pi's native primary-model projection: `openai-codex/gpt-5.6-sol`, with a local `contextWindow` request of 872K. It merges only missing compatible fields, records field ownership in `PI_CODING_AGENT_DIR/jorgex-pi/sol-lifecycle.v1.json`, and cleanup removes only still-owned canonical values. Stack does not duplicate that package-owned settings/models logic. The 872K value is local OAuth metadata until a real long-context smoke test confirms backend acceptance; it is not the API context limit.
|
|
152
149
|
|
|
153
|
-
Engram remains mandatory and user-owned. An existing binary is always preserved. When it is missing and the user authorizes installation, Stack resolves GitHub's current official latest stable release at runtime; GitHub's `releases/latest` endpoint excludes prereleases and drafts, and the installer never uses a branch. It matches the exact platform/architecture asset and validates its live metadata —published state, expected name, positive size and SHA-256— before publishing; missing network or metadata fails closed, with no static or offline fallback.
|
|
150
|
+
Engram remains mandatory and user-owned. An existing binary is always preserved. When it is missing and the user authorizes installation, Stack resolves GitHub's current official latest stable release at runtime; GitHub's `releases/latest` endpoint excludes prereleases and drafts, and the installer never uses a branch. It matches the exact platform/architecture asset and validates its live metadata —published state, expected name, positive size and SHA-256— before publishing; missing network or metadata fails closed, with no static or offline fallback. `install` may download Engram with `--engram` or with interactive confirmation; `update` only offers the explicit native channel confirmation and preserves the existing binary. The release installer writes only `~/.local/bin/engram` (or the platform equivalent) and does not use Brew or Go. El `sync` interno, `dry-run` y `--target-dir` no descargan Engram. Update permanece explícito y no sustituye un binario existente implícitamente. The database and memories are never updated or deleted, and uninstall preserves the official Engram artifacts and never removes the Engram binary. Under `--target-dir`, Stack accepts only `<target>/bin/engram`, isolates Pi/Home/XDG/AppData/temp/npm-cache paths inside the target, and never consults the host Engram or Pi configuration. This rolling channel does not mean that every upstream release was pre-reviewed by Stack.
|
|
154
151
|
|
|
155
152
|
Claude's official plugin still requires stable Engram 2.0.0 or newer: an existing binary below that minimum would make its setup write the obsolete `mcp/engram.json`, so the Claude preflight blocks it before setup. Stack never replaces an existing binary automatically; update it explicitly and rerun `install`. The official Claude plugin contributes hooks and its skill; `engram setup claude-code` registers a separate user-scoped MCP, not a bundled MCP. This integration does not claim an authenticated model-tool smoke.
|
|
156
153
|
|
|
157
154
|
### Integración oficial de Engram
|
|
158
155
|
|
|
159
|
-
En una instalación real, `install` delega Claude Code, Codex y OpenCode 1.x a `engram setup <runtime>` una vez por runtime durante esa instalación. Para Pi, si declara transporte nativo (`mcp-native-v1`), Stack ejecuta la fase nativa (`runNativePiMcpPhase`) y no invoca `engram setup pi`; en modo legacy Pi sigue ejecutando `engram setup pi` antes de activar el paquete. El comportamiento del provider oficial permanece sin cambios: Stack no proyecta el protocolo Engram ni filtra sus herramientas. No ejecuta ese setup durante `
|
|
156
|
+
En una instalación real, `install` delega Claude Code, Codex y OpenCode 1.x a `engram setup <runtime>` una vez por runtime durante esa instalación. Para Pi, si declara transporte nativo (`mcp-native-v1`), Stack ejecuta la fase nativa (`runNativePiMcpPhase`) y no invoca `engram setup pi`; en modo legacy Pi sigue ejecutando `engram setup pi` antes de activar el paquete. El comportamiento del provider oficial permanece sin cambios: Stack no proyecta el protocolo Engram ni filtra sus herramientas. No ejecuta ese setup durante `dry-run`, `--target-dir`, `doctor` ni `uninstall`; `install` lo invoca como parte de la reconciliación interna cuando es necesario. Stack respalda los archivos afectados, verifica los artefactos oficiales y revierte el cambio si falla; para Pi incluye `settings.json`, `mcp.json` y el árbol `npm`. No modifica `~/.engram`, sus memorias ni reemplaza un binario existente. Los artefactos oficiales se conservan al desinstalar. El `stack/plugins/opencode/engram.ts` legado ya no se despliega y queda retirado por esta integración.
|
|
160
157
|
|
|
161
|
-
Para Codex, Engram 2.0 ignora `CODEX_HOME` y escribe siempre en `$HOME/.codex`; por eso el setup oficial real requiere ese destino predeterminado. Si `CODEX_HOME` apunta a otro directorio, `install` falla cerrado en el preflight, antes de escribir la configuración de Codex, y recomienda usar `$HOME/.codex`. `
|
|
158
|
+
Para Codex, Engram 2.0 ignora `CODEX_HOME` y escribe siempre en `$HOME/.codex`; por eso el setup oficial real requiere ese destino predeterminado. Si `CODEX_HOME` apunta a otro directorio, `install` falla cerrado en el preflight, antes de escribir la configuración de Codex, y recomienda usar `$HOME/.codex`. `dry-run` y `--target-dir` no invocan el setup oficial.
|
|
162
159
|
|
|
163
|
-
La política de complementos distingue estrategias `exact` y `provider-managed`. DevTools MCP y Playwright CLI son `provider-managed`: un `install`/`update` deliberado resuelve y verifica el candidato exacto antes de activarlo, y guarda versión/integridad observadas para
|
|
160
|
+
La política de complementos distingue estrategias `exact` y `provider-managed`. DevTools MCP y Playwright CLI son `provider-managed`: un `install`/`update` deliberado resuelve y verifica el candidato exacto antes de activarlo, y guarda versión/integridad observadas para que `install`/`update` posteriores refresquen usando la preferencia persistida o el opt-in explícito. Las integraciones oficiales de Engram también son `provider-managed`/rolling, incluido Codex `main`, `pi-mcp-adapter` y el setup oficial de Pi sin pin en Stack. OpenCode 2 queda fuera de alcance y no bloquea esta integración.
|
|
164
161
|
|
|
165
162
|
Los receipts históricos, incluido `jorgex-pi@0.8.24`, son evidencia para recuperación/migración y no candidatos de instalación nuevos. La selección gestionada resuelve el `latest` publicado a una versión exacta y verifica el artefacto antes de activarlo. No edites receipts o hashes ni borres `HOME`, Engram o la proyección de otro runtime para forzar confianza. La migración y rollback están en [docs/references/pi-runtime.md](docs/references/pi-runtime.md).
|
|
166
163
|
|
|
167
164
|
Stack gestiona la selección dinámica y verificación de Pi en `install`/`update`; esto no significa que una instalación personal de Pi se haya migrado. La automatización Stack ↔ Pi es snapshot-only. La instalación directa de Pi no incluye la etapa aislada ni el rollback de Stack.
|
|
168
165
|
|
|
169
|
-
`update --agents pi` cambia versiones deliberadamente: resuelve y verifica el paquete Pi y los providers oficiales en stages aislados (con candidato nativo solo `gentle-engram`; con candidato legacy también `pi-mcp-adapter`), aplica la promoción acotada y verifica la configuración MCP. No entra en el updater global de Stack, no actualiza el host Pi ni toca los datos de Engram. `
|
|
166
|
+
`update --agents pi` cambia versiones deliberadamente: resuelve y verifica el paquete Pi y los providers oficiales en stages aislados (con candidato nativo solo `gentle-engram`; con candidato legacy también `pi-mcp-adapter`), aplica la promoción acotada y verifica la configuración MCP. No entra en el updater global de Stack, no actualiza el host Pi ni toca los datos de Engram. `install --agents pi` reaplica la proyección a partir del paquete autenticado y comprueba el estado MCP existente cuando ya hay receipt; en primera instalación verifica el tarball, normaliza el paquete, proyecta recursos y ejecuta el sync interno para inicializar Pi y escribir ambos receipts. `update --check --agents pi` consulta el runner sin mutar Pi; `doctor --agents pi` diagnostica paquete y proyección. Uninstall respalda los settings y retira solo el paquete exacto acreditado por el receipt, verificando su ausencia y conservando companions y estado ajeno. En modo nativo, `uninstall` corre la comprobación activa de ownership contra el módulo Pi realmente instalado antes de desactivar el paquete privado y respeta la autoridad granular `mcpNative` para decidir qué entradas retira. Consulta los límites de recuperación en la [referencia Pi](docs/references/pi-runtime.md).
|
|
170
167
|
|
|
171
|
-
###
|
|
168
|
+
### Compat del provider #1567 (publicada en 1.9.69) y recibo separado
|
|
172
169
|
|
|
173
|
-
> **
|
|
170
|
+
> **Compat del provider #1567 publicada en Stack 1.9.69.** `--engram-typebox-compat` aplica el diff de `#1567` sobre bytes oficiales verificados y registra su procedencia en un recibo separado, sin sustituir la autoridad de la fase nativa. Los gates CI Windows controlados del release están verdes; la instalación personal en Windows no está probada. Cuando el provider oficial ya viene corregido, se usa sin etapa derivada.
|
|
174
171
|
|
|
175
|
-
`--engram-typebox-compat` es un booleano explícito; cuando no se pasa, la propiedad queda **realmente ausente** (`undefined`) y no se conserva ninguna preferencia ni se añaden campos obligatorios a flags/fixtures. Sólo se acepta en `install` y `update` deliberados cuyo `--agents` incluya `pi` y **sin** combinar con `--dry-run` ni `--target-dir`; `update --check`, `--dry-run` y `--target-dir` (en `install` o `update`), `
|
|
172
|
+
`--engram-typebox-compat` es un booleano explícito; cuando no se pasa, la propiedad queda **realmente ausente** (`undefined`) y no se conserva ninguna preferencia ni se añaden campos obligatorios a flags/fixtures. Sólo se acepta en `install` y `update` deliberados cuyo `--agents` incluya `pi` y **sin** combinar con `--dry-run` ni `--target-dir`; `update --check`, `--dry-run` y `--target-dir` (en `install` o `update`), `models`, `doctor`, `uninstall` e `install` sin `pi` rechazan el flag antes de cualquier efecto. `--dry-run` y `--target-dir` siguen sin adquirir providers ni escribir estado personal. Stack registra la procedencia de `gentle-engram` y `pi-mcp-adapter` en `<home>/.jorgex-stack/pi-provider-receipt.json` (schemaVersion 1), un archivo distinto del `pi-receipt.json` del paquete JorgeX Pi y de la autoridad MCP. El campo `provenance` es **opcional** ligado a la adquisición `#1567`-compat: cuando el oficial ya viene corregido el builder devuelve `provenance.origin = "registry"`; mientras no, devuelve `provenance.origin = "derived"`; en ambos casos se descarta el `path` de stage y se conserva el payload original del manifiesto como `manifestBase64` (texto base64 que decodifica al manifiesto bounded —el límite aplica al payload decodificado, no al string literal) junto con su digest y la referencia del patch para verificación offline. Es procedencia local reproducible, no attestation independiente del publisher. `doctor` lee este recibo y diferencia `registry` vs `derived`; no consulta la red, no repara y nunca presenta un error como setup sano. Una `update` deliberada sobre derivado existente conserva la receta sin volver a requerir el flag, sólo si el recibo verificado lo permite; no se autosiembran preferencias y ningún otro comando propaga el opt-in. Las garantías de transacción (backup, idempotencia, rollback, detección de modificaciones ajenas con reporte de `recovery incomplete`), la retirada tras activación verificada del oficial corregido y la advertencia de que operaciones fuera de la transacción gestionada de Stack (comandos manuales, removedores externos, updater nativo de Pi en modo manual) pueden sustituir o degradar los bytes del provider —y que el verificador detecta ese drift sin ser una ACL— se describen en [la referencia Pi](docs/references/pi-runtime.md#variante-temporal-del-provider-y-recibo-separado-candidato-devtool). El updater de providers de **Stack** (función) opera sólo sobre el **transporte legacy**; el transporte nativo lo maneja la **fase nativa del padre** (PR203, `runNativePiMcpPhase`) con la misma política de opt-in y snapshot, sin duplicar la autoridad nativa.
|
|
176
173
|
|
|
177
174
|
### Estilo global de escritura
|
|
178
175
|
|
|
179
|
-
Stack incluye un prompt genérico de estilo de escritura como parte de su canon. `install`
|
|
176
|
+
Stack incluye un prompt genérico de estilo de escritura como parte de su canon. `install` lo gestiona en `~/.jorgex-stack/writing-style.md`; en modo humano proyecta el contenido efectivo directamente en una sección independiente de las instrucciones globales de los runtimes seleccionados. `install`/`update` reconcilian el canon internamente sin exponer un comando público de sync. El prompt se aplica a la prosa dirigida al usuario, sigue el idioma en el que escribe el usuario salvo que pida otro y conserva las instrucciones técnicas, los formatos de máquina, el código y la configuración nativa. El modo programático conserva la fuente local, pero omite la proyección de prosa.
|
|
180
177
|
|
|
181
178
|
La proyección contiene el canon directamente: Stack no añade un wrapper adicional ni una identidad personal. Si falta el archivo local o está vacío, Stack recrea el bloque gestionado. El corpus de mensajes y los informes privados de análisis no se distribuyen en el paquete. Consulta [configuración, prueba aislada, diagnóstico y límites](docs/references/writing-style.md).
|
|
182
179
|
|
|
@@ -203,7 +200,7 @@ jorgex-stack browser playwright -s=mi-tarea close
|
|
|
203
200
|
pnpm dlx jorgex-stack install --devtools
|
|
204
201
|
```
|
|
205
202
|
|
|
206
|
-
`
|
|
203
|
+
`install`/`update` pueden adquirir un nuevo release browser verificado con opt-in explícito o preferencia persistida; no son una alternativa offline al comando retirado `sync`. `doctor` revisa receipt, versión, caché Chromium y arranque headless local sin reparar. `update --check` observa solo estado local. `uninstall` conserva por defecto el árbol gestionado y los datos del navegador; `--remove-playwright` desactiva preferencia y guía con backup, sin retirar un CLI global ajeno. Una preferencia ilegible bloquea mutaciones y `doctor` señala su ruta. Con `--target-dir` Stack no toca el estado browser del HOME real. Consulta [automatización de navegador](docs/references/browser-automation.md) para receipts, reparación y handoffs Pi.
|
|
207
204
|
|
|
208
205
|
### Update: Interactive Flow
|
|
209
206
|
|
|
@@ -225,7 +222,7 @@ GitHub authentication: requests use `GH_TOKEN`/`GITHUB_TOKEN` from the environme
|
|
|
225
222
|
|
|
226
223
|
Goal Mode de OpenCode se ha retirado. Stack ya no instala su plugin ni el comando `/goal`; la continuidad de trabajo usa el lifecycle normal: `work/{name}/PRD.md` y `plan.md` permanecen durante los merges intermedios, `work/{name}/pr/{NN}` conserva cada checkpoint y `work/{name}/done` queda reservado para el cierre final.
|
|
227
224
|
|
|
228
|
-
La retirada no migra el historial. `
|
|
225
|
+
La retirada no migra el historial. `install`/`update` sólo retiran archivos gestionados cuando disponen de un manifest legible que registre esas rutas como gestionadas y un inventario completo, con backup previo; conservan los datos existentes en `~/.jorgex-stack/goals` y los plugins ajenos cuando el manifest del Stack está íntegro. El registro local no autentica la propiedad ni corrige una lista `owned` editada o inconsistente: si falta, no se puede parsear o el inventario es incompleto, no se borra el legacy. Ante sospecha sobre el manifest, no ejecutes `install`/`update`; revísalo o restáuralo con backup. `--target-dir` no implica limpiar ese estado.
|
|
229
226
|
|
|
230
227
|
La continuidad entre checkpoints sigue requiriendo trabajo aprobado, capacidades disponibles y merge humano explícito. PiGoal conserva su propio lifecycle. No se afirma disponibilidad de una alternativa GoalV2 de OpenCode.
|
|
231
228
|
|
package/dist/cli.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
type RuntimeId = "claude-code" | "codex" | "opencode";
|
|
8
8
|
type SelectableRuntimeId = RuntimeId | "pi";
|
|
9
9
|
|
|
10
|
-
declare const COMMANDS: readonly ["install", "
|
|
10
|
+
declare const COMMANDS: readonly ["install", "models", "update", "doctor", "restore", "uninstall", "quality", "browser"];
|
|
11
11
|
type Command = (typeof COMMANDS)[number];
|
|
12
12
|
interface Flags {
|
|
13
13
|
agents: SelectableRuntimeId[];
|
package/dist/cli.js
CHANGED
|
@@ -2480,7 +2480,7 @@ function assertCompatibleContext7(server, value) {
|
|
|
2480
2480
|
function ensureObject(parent, key, fieldPath) {
|
|
2481
2481
|
if (parent[key] === void 0) parent[key] = {};
|
|
2482
2482
|
const value = objectValue(parent[key]);
|
|
2483
|
-
if (value === null) throw new Error(`OpenCode: '${fieldPath}' debe ser un objeto; corr\xEDgelo antes de reintentar
|
|
2483
|
+
if (value === null) throw new Error(`OpenCode: '${fieldPath}' debe ser un objeto; corr\xEDgelo antes de reintentar install.`);
|
|
2484
2484
|
return value;
|
|
2485
2485
|
}
|
|
2486
2486
|
function ensureOwnedPrimaryObject(parent, key, field, owned, changes) {
|
|
@@ -2921,7 +2921,7 @@ ${gitReadCommands.map((command) => `- \`${command}\``).join("\n")}
|
|
|
2921
2921
|
const content = upsertJson(contentSource, (root) => {
|
|
2922
2922
|
const rawMcp = root["mcp"];
|
|
2923
2923
|
if (rawMcp !== void 0 && objectValue(rawMcp) === null) {
|
|
2924
|
-
throw new Error("OpenCode: la clave 'mcp' debe ser un objeto; corr\xEDgela antes de reintentar
|
|
2924
|
+
throw new Error("OpenCode: la clave 'mcp' debe ser un objeto; corr\xEDgela antes de reintentar install.");
|
|
2925
2925
|
}
|
|
2926
2926
|
const existingMcp = rawMcp;
|
|
2927
2927
|
const context7 = canonical.servers.context7;
|
|
@@ -2933,7 +2933,7 @@ ${gitReadCommands.map((command) => `- \`${command}\``).join("\n")}
|
|
|
2933
2933
|
primaryModelOwnership.push({ field: PRIMARY_MODEL_FIELD, owned: true });
|
|
2934
2934
|
}
|
|
2935
2935
|
} else if (typeof root[PRIMARY_MODEL_FIELD] !== "string" || root[PRIMARY_MODEL_FIELD].trim() === "") {
|
|
2936
|
-
throw new Error("OpenCode: 'model' debe ser un identificador provider/model no vac\xEDo; corr\xEDgelo antes de reintentar
|
|
2936
|
+
throw new Error("OpenCode: 'model' debe ser un identificador provider/model no vac\xEDo; corr\xEDgelo antes de reintentar install.");
|
|
2937
2937
|
}
|
|
2938
2938
|
const provider = ensureOwnedPrimaryObject(root, "provider", PRIMARY_PROVIDER_FIELD, ctx.ownedPrimaryModelFields, primaryModelOwnership);
|
|
2939
2939
|
const openai = ensureOwnedPrimaryObject(provider, "openai", PRIMARY_OPENAI_FIELD, ctx.ownedPrimaryModelFields, primaryModelOwnership);
|
|
@@ -3001,7 +3001,7 @@ ${gitReadCommands.map((command) => `- \`${command}\``).join("\n")}
|
|
|
3001
3001
|
if (server.transport === "stdio") {
|
|
3002
3002
|
if (server.command === "{{ENGRAM_BIN}}" && ctx.engramBin === null) {
|
|
3003
3003
|
ctx.warnings.push(
|
|
3004
|
-
"Engram no detectado: el MCP 'engram' no se registra. Inst\xE1lalo (github.com/Gentleman-Programming/engram) y re-ejecuta
|
|
3004
|
+
"Engram no detectado: el MCP 'engram' no se registra. Inst\xE1lalo (github.com/Gentleman-Programming/engram) y re-ejecuta install."
|
|
3005
3005
|
);
|
|
3006
3006
|
continue;
|
|
3007
3007
|
}
|
|
@@ -3600,7 +3600,7 @@ ${agent.body}`,
|
|
|
3600
3600
|
const content = upsertJson(readMcpConfig2(file), (root) => {
|
|
3601
3601
|
const rawServers = root["mcpServers"];
|
|
3602
3602
|
if (rawServers !== void 0 && !isRecord3(rawServers)) {
|
|
3603
|
-
throw new Error("Claude Code: la clave 'mcpServers' debe ser un objeto; corr\xEDgela antes de reintentar
|
|
3603
|
+
throw new Error("Claude Code: la clave 'mcpServers' debe ser un objeto; corr\xEDgela antes de reintentar install.");
|
|
3604
3604
|
}
|
|
3605
3605
|
const existingServers = rawServers;
|
|
3606
3606
|
const context7 = canonical.servers.context7;
|
|
@@ -3639,7 +3639,7 @@ ${agent.body}`,
|
|
|
3639
3639
|
if (server.transport === "stdio") {
|
|
3640
3640
|
if (server.command === "{{ENGRAM_BIN}}" && ctx.engramBin === null) {
|
|
3641
3641
|
ctx.warnings.push(
|
|
3642
|
-
"Engram no detectado: el MCP 'engram' no se registra. Inst\xE1lalo (github.com/Gentleman-Programming/engram) y re-ejecuta
|
|
3642
|
+
"Engram no detectado: el MCP 'engram' no se registra. Inst\xE1lalo (github.com/Gentleman-Programming/engram) y re-ejecuta install."
|
|
3643
3643
|
);
|
|
3644
3644
|
continue;
|
|
3645
3645
|
}
|
|
@@ -4308,7 +4308,7 @@ ${body}`
|
|
|
4308
4308
|
if (server.transport === "stdio") {
|
|
4309
4309
|
if (server.command === "{{ENGRAM_BIN}}" && ctx.engramBin === null) {
|
|
4310
4310
|
ctx.warnings.push(
|
|
4311
|
-
"Engram no detectado: el MCP 'engram' no se registra. Inst\xE1lalo (github.com/Gentleman-Programming/engram) y re-ejecuta
|
|
4311
|
+
"Engram no detectado: el MCP 'engram' no se registra. Inst\xE1lalo (github.com/Gentleman-Programming/engram) y re-ejecuta install."
|
|
4312
4312
|
);
|
|
4313
4313
|
continue;
|
|
4314
4314
|
}
|
|
@@ -10181,7 +10181,7 @@ async function runInstall(opts) {
|
|
|
10181
10181
|
}
|
|
10182
10182
|
if (promptReconciliationFailed) {
|
|
10183
10183
|
exitCode = 1;
|
|
10184
|
-
p.log.error("Playwright CLI y navegador se han instalado y la preferencia qued\xF3 activa, pero la gu\xEDa de navegador qued\xF3 en estado parcial. Ejecuta 'jorgex-stack
|
|
10184
|
+
p.log.error("Playwright CLI y navegador se han instalado y la preferencia qued\xF3 activa, pero la gu\xEDa de navegador qued\xF3 en estado parcial. Ejecuta 'jorgex-stack install' para repararla.");
|
|
10185
10185
|
} else {
|
|
10186
10186
|
const verified = verifiedCapability ?? (preparedEnv === void 0 ? inspectPlaywrightCapability({ browserVerified: true, expectedVersion: candidate.version }) : inspectPlaywrightCapability({ browserVerified: true, env: preparedEnv, expectedVersion: candidate.version }));
|
|
10187
10187
|
if (verified.effective && verified.cli.status === "current" && verified.cli.binPath !== null && verified.cli.detectedVersion !== null && verified.browserCache.status === "ready") {
|
|
@@ -15221,7 +15221,7 @@ function readDoctorTextIfExists(file) {
|
|
|
15221
15221
|
}
|
|
15222
15222
|
}
|
|
15223
15223
|
var STALE_PERMISSIONS_MARKER = "differs from the stack default and was left untouched";
|
|
15224
|
-
var UPGRADE_PERMISSIONS_REMEDY = "jorgex-stack
|
|
15224
|
+
var UPGRADE_PERMISSIONS_REMEDY = "jorgex-stack install --upgrade-permissions --dry-run";
|
|
15225
15225
|
function piAgentDir(targetDir) {
|
|
15226
15226
|
return targetDir === void 0 ? process.env.PI_CODING_AGENT_DIR ?? path41.join(HOME, ".pi", "agent") : path41.join(targetDir, "pi-agent");
|
|
15227
15227
|
}
|
|
@@ -15258,7 +15258,7 @@ function reportPiPermissions(targetDir) {
|
|
|
15258
15258
|
}
|
|
15259
15259
|
if (receipt !== null) return 0;
|
|
15260
15260
|
p3.log.warn(
|
|
15261
|
-
`Pi: permission policy present without package ownership (${configFile}) and left untouched; Stack never rewrites Pi state \u2014 align it by hand or remove it so a later 'jorgex-stack
|
|
15261
|
+
`Pi: permission policy present without package ownership (${configFile}) and left untouched; Stack never rewrites Pi state \u2014 align it by hand or remove it so a later 'jorgex-stack install --agents pi' can seed the package default.`
|
|
15262
15262
|
);
|
|
15263
15263
|
return 1;
|
|
15264
15264
|
}
|
|
@@ -15288,7 +15288,7 @@ function reportWritingStyle(options, style, mode) {
|
|
|
15288
15288
|
p3.log.info(`Estilo de escritura incluido: ${style.canonicalPath}; fuente local ${style.sourcePath}; tama\xF1o ${Buffer.byteLength(style.content, "utf8")} bytes de texto normalizado. La carga nativa no est\xE1 verificada.`);
|
|
15289
15289
|
if (style.originalContent === style.installedContent) p3.log.success("Archivo local de estilo actualizado con el canon incluido.");
|
|
15290
15290
|
else {
|
|
15291
|
-
p3.log.warn(`Archivo local de estilo ${style.originalContent === null ? "pendiente de instalar" : "desactualizado; pendiente de sincronizar"}; ejecuta install
|
|
15291
|
+
p3.log.warn(`Archivo local de estilo ${style.originalContent === null ? "pendiente de instalar" : "desactualizado; pendiente de sincronizar"}; ejecuta install (${style.sourcePath}).`);
|
|
15292
15292
|
problems++;
|
|
15293
15293
|
}
|
|
15294
15294
|
const expected = mode.mode !== "programmatic" ? upsertMarkdownSection(null, "writing-style", style.content).trim() : null;
|
|
@@ -15307,7 +15307,7 @@ function reportWritingStyle(options, style, mode) {
|
|
|
15307
15307
|
const matches = expected === null ? !content.includes(open) && !content.includes(close) : healthy && block === expected;
|
|
15308
15308
|
if (matches) p3.log.success(`${id}: proyecci\xF3n de estilo coincide (${file})${mode.mode === "programmatic" ? "; omitida en modo programmatic" : ""}.`);
|
|
15309
15309
|
else {
|
|
15310
|
-
p3.log.warn(`${id}: proyecci\xF3n de estilo desactualizada o ausente (${file}); ejecuta
|
|
15310
|
+
p3.log.warn(`${id}: proyecci\xF3n de estilo desactualizada o ausente (${file}); ejecuta install.`);
|
|
15311
15311
|
problems++;
|
|
15312
15312
|
}
|
|
15313
15313
|
if (id === "codex") {
|
|
@@ -15493,7 +15493,7 @@ async function runDoctor(options = {}) {
|
|
|
15493
15493
|
problems++;
|
|
15494
15494
|
}
|
|
15495
15495
|
if (pending > 0) {
|
|
15496
|
-
p3.log.warn(`${adapter.name}: ${pending} archivos gestionados desactualizados o ausentes \u2192 ejecuta '
|
|
15496
|
+
p3.log.warn(`${adapter.name}: ${pending} archivos gestionados desactualizados o ausentes \u2192 ejecuta 'install'.`);
|
|
15497
15497
|
problems++;
|
|
15498
15498
|
} else if (!stalePermissions) {
|
|
15499
15499
|
p3.log.success(`${adapter.name}: config del stack al d\xEDa (${detection.configDir}).`);
|
|
@@ -15501,7 +15501,7 @@ async function runDoctor(options = {}) {
|
|
|
15501
15501
|
const prev = manifest.runtimes[adapter.id];
|
|
15502
15502
|
const orphans = prev && current.complete ? findOrphans(prev.owned, current.targets) : [];
|
|
15503
15503
|
if (orphans.length > 0) {
|
|
15504
|
-
p3.log.warn(`${adapter.name}: ${orphans.length} archivos hu\xE9rfanos de versiones previas \u2192 ejecuta '
|
|
15504
|
+
p3.log.warn(`${adapter.name}: ${orphans.length} archivos hu\xE9rfanos de versiones previas \u2192 ejecuta 'install'.`);
|
|
15505
15505
|
problems++;
|
|
15506
15506
|
}
|
|
15507
15507
|
if (adapter.id === "codex" && fs34.existsSync(path41.join(detection.configDir, "hooks.json"))) {
|
|
@@ -21954,8 +21954,8 @@ async function completeProjection(operation, packageResult, deps) {
|
|
|
21954
21954
|
}
|
|
21955
21955
|
return projectionResult.kind === "blocked" ? projectionResult : packageResult;
|
|
21956
21956
|
}
|
|
21957
|
-
var INSTALL_INIT_REMEDY = "Corrige la causa y ejecuta
|
|
21958
|
-
var INSTALL_INIT_TARGET_REMEDY = "Corrige la causa y ejecuta
|
|
21957
|
+
var INSTALL_INIT_REMEDY = "Corrige la causa y ejecuta install --agents pi para completar la inicializaci\xF3n.";
|
|
21958
|
+
var INSTALL_INIT_TARGET_REMEDY = "Corrige la causa y ejecuta install --agents pi con el mismo --target-dir para completar la inicializaci\xF3n.";
|
|
21959
21959
|
function withInstallInitRemedy(result, fallbackRemedy) {
|
|
21960
21960
|
return result.remedy === void 0 ? { kind: "blocked", reason: result.reason, remedy: fallbackRemedy } : result;
|
|
21961
21961
|
}
|
|
@@ -22025,7 +22025,7 @@ function managedPackageResult(result) {
|
|
|
22025
22025
|
if (result.kind === "manual-existing") {
|
|
22026
22026
|
return {
|
|
22027
22027
|
kind: "manual-existing",
|
|
22028
|
-
remedy: result.remedy ?? "Pi ya est\xE1 configurado manualmente; conserva esa configuraci\xF3n o elim\xEDnala antes de ejecutar
|
|
22028
|
+
remedy: result.remedy ?? "Pi ya est\xE1 configurado manualmente; conserva esa configuraci\xF3n o elim\xEDnala antes de ejecutar install --agents pi."
|
|
22029
22029
|
};
|
|
22030
22030
|
}
|
|
22031
22031
|
if (result.kind === "models") return { kind: "models", models: result.models };
|
|
@@ -22602,7 +22602,7 @@ async function runManagedPiSystem(input) {
|
|
|
22602
22602
|
return Promise.resolve(result2.kind === "drift" ? {
|
|
22603
22603
|
kind: "drift",
|
|
22604
22604
|
paths: result2.paths,
|
|
22605
|
-
remedy: "Ejecuta
|
|
22605
|
+
remedy: "Ejecuta install --agents pi para reparar la proyecci\xF3n de Pi."
|
|
22606
22606
|
} : result2);
|
|
22607
22607
|
},
|
|
22608
22608
|
prepareProjectionUninstall() {
|
|
@@ -22673,7 +22673,7 @@ async function runManagedPiSystem(input) {
|
|
|
22673
22673
|
return {
|
|
22674
22674
|
kind: "blocked",
|
|
22675
22675
|
reason: "native-checker-conflict",
|
|
22676
|
-
remedy: "El paquete Pi qued\xF3 activado; la comprobaci\xF3n nativa detect\xF3 un conflicto de propiedad sobre mcp.json/autoridad. Resu\xE9lvelo y ejecuta
|
|
22676
|
+
remedy: "El paquete Pi qued\xF3 activado; la comprobaci\xF3n nativa detect\xF3 un conflicto de propiedad sobre mcp.json/autoridad. Resu\xE9lvelo y ejecuta install --agents pi para completar la inicializaci\xF3n."
|
|
22677
22677
|
};
|
|
22678
22678
|
}
|
|
22679
22679
|
const expectedClaims = nativeAuthority === void 0 ? previousNativeClaimNames(nativeHomeDir, authorityRaw) ?? [] : Object.keys(nativeAuthority.entries);
|
|
@@ -22689,7 +22689,7 @@ async function runManagedPiSystem(input) {
|
|
|
22689
22689
|
return {
|
|
22690
22690
|
kind: "blocked",
|
|
22691
22691
|
reason: "native-checker-failed",
|
|
22692
|
-
remedy: `El paquete Pi qued\xF3 activado; la comprobaci\xF3n nativa fall\xF3: ${error instanceof Error ? error.message : String(error)}. Inicializaci\xF3n nativa pendiente; ejecuta
|
|
22692
|
+
remedy: `El paquete Pi qued\xF3 activado; la comprobaci\xF3n nativa fall\xF3: ${error instanceof Error ? error.message : String(error)}. Inicializaci\xF3n nativa pendiente; ejecuta install --agents pi para reintentar.`
|
|
22693
22693
|
};
|
|
22694
22694
|
}
|
|
22695
22695
|
}
|
|
@@ -23750,7 +23750,7 @@ async function installMissingEngram(options = {}) {
|
|
|
23750
23750
|
|
|
23751
23751
|
// src/cli.ts
|
|
23752
23752
|
var VERSION = readPackageVersion();
|
|
23753
|
-
var COMMANDS = ["install", "
|
|
23753
|
+
var COMMANDS = ["install", "models", "update", "doctor", "restore", "uninstall", "quality", "browser"];
|
|
23754
23754
|
var QUALITY_REJECTED_VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
23755
23755
|
"--agents",
|
|
23756
23756
|
"--playwright-runtimes",
|
|
@@ -23759,15 +23759,15 @@ var QUALITY_REJECTED_VALUE_FLAGS = /* @__PURE__ */ new Set([
|
|
|
23759
23759
|
"--mode",
|
|
23760
23760
|
"--subagent-concurrency"
|
|
23761
23761
|
]);
|
|
23762
|
-
async function ensureOpenCodeModelsForInstall(
|
|
23762
|
+
async function ensureOpenCodeModelsForInstall(flags, runtimes) {
|
|
23763
23763
|
if (!runtimes.includes("opencode") || loadModelMap().opencode) return true;
|
|
23764
|
-
const canPrompt =
|
|
23764
|
+
const canPrompt = !flags.yes && !flags.dryRun && process.stdout.isTTY;
|
|
23765
23765
|
if (canPrompt) {
|
|
23766
23766
|
const code = await runModelsPicker({ yes: false, runtimes: ["opencode"] });
|
|
23767
23767
|
if (code === 0 && loadModelMap().opencode) return true;
|
|
23768
23768
|
}
|
|
23769
23769
|
console.error(
|
|
23770
|
-
"OpenCode no tiene modelos configurados. Ejecuta 'jorgex-stack models --agents opencode' de forma interactiva antes de install
|
|
23770
|
+
"OpenCode no tiene modelos configurados. Ejecuta 'jorgex-stack models --agents opencode' de forma interactiva antes de install."
|
|
23771
23771
|
);
|
|
23772
23772
|
return false;
|
|
23773
23773
|
}
|
|
@@ -23895,7 +23895,7 @@ Corrige o borra ${preferenceFile}, o vuelve a ejecutar con --mode human|programm
|
|
|
23895
23895
|
}
|
|
23896
23896
|
}
|
|
23897
23897
|
if (!promptIfMissing) {
|
|
23898
|
-
console.error("No hay modo guardado; usa --mode expl\xEDcito para
|
|
23898
|
+
console.error("No hay modo guardado; usa --mode expl\xEDcito para esta aplicaci\xF3n.");
|
|
23899
23899
|
process.exitCode = 1;
|
|
23900
23900
|
return null;
|
|
23901
23901
|
}
|
|
@@ -23929,7 +23929,7 @@ Corrige o borra ${preferenceFile}, o vuelve a ejecutar con --mode human|programm
|
|
|
23929
23929
|
subagentConcurrency: concurrency
|
|
23930
23930
|
};
|
|
23931
23931
|
}
|
|
23932
|
-
async function resolvePlaywrightToolConsent(
|
|
23932
|
+
async function resolvePlaywrightToolConsent(flags, runtimes) {
|
|
23933
23933
|
const interactive = Boolean(process.stdout.isTTY);
|
|
23934
23934
|
const supportsPiPlaywright = PI_RUNTIME_CANDIDATE.contract.capabilities.includes("playwright-handoff-v1");
|
|
23935
23935
|
const supported = runtimes.filter((runtime) => runtime !== "pi" || supportsPiPlaywright);
|
|
@@ -23949,13 +23949,13 @@ async function resolvePlaywrightToolConsent(command, flags, runtimes) {
|
|
|
23949
23949
|
return null;
|
|
23950
23950
|
}
|
|
23951
23951
|
}
|
|
23952
|
-
if (
|
|
23952
|
+
if (flags.playwright && supported.length === 0 && runtimes.includes("pi")) {
|
|
23953
23953
|
console.error("Pi no declara el handoff Playwright requerido.");
|
|
23954
23954
|
process.exitCode = 1;
|
|
23955
23955
|
return null;
|
|
23956
23956
|
}
|
|
23957
23957
|
let confirmed = false;
|
|
23958
|
-
if (
|
|
23958
|
+
if (interactive && !flags.yes && !flags.dryRun && flags.targetDir === void 0) {
|
|
23959
23959
|
const answer = await p6.confirm({
|
|
23960
23960
|
message: "Recomendado: \xBFinstalar Playwright CLI gestionado y descargar Chromium?",
|
|
23961
23961
|
initialValue: false
|
|
@@ -23965,7 +23965,7 @@ async function resolvePlaywrightToolConsent(command, flags, runtimes) {
|
|
|
23965
23965
|
}
|
|
23966
23966
|
let runtimeSelection;
|
|
23967
23967
|
const approved = interactive && !flags.yes ? confirmed : flags.yes && flags.playwright;
|
|
23968
|
-
if (
|
|
23968
|
+
if (approved && supported.length > 0) {
|
|
23969
23969
|
let selected = flags.playwrightRuntimes ?? supported;
|
|
23970
23970
|
if (interactive && !flags.yes && !flags.dryRun && flags.targetDir === void 0 && flags.playwrightRuntimes === void 0) {
|
|
23971
23971
|
const answer = await p6.multiselect({
|
|
@@ -23980,7 +23980,7 @@ async function resolvePlaywrightToolConsent(command, flags, runtimes) {
|
|
|
23980
23980
|
runtimeSelection = Object.fromEntries(supported.map((runtime) => [runtime, selected.includes(runtime)]));
|
|
23981
23981
|
}
|
|
23982
23982
|
return {
|
|
23983
|
-
command,
|
|
23983
|
+
command: "install",
|
|
23984
23984
|
interactive,
|
|
23985
23985
|
yes: flags.yes,
|
|
23986
23986
|
targetDir: flags.targetDir !== void 0,
|
|
@@ -23989,7 +23989,7 @@ async function resolvePlaywrightToolConsent(command, flags, runtimes) {
|
|
|
23989
23989
|
...runtimeSelection === void 0 ? {} : { runtimeSelection }
|
|
23990
23990
|
};
|
|
23991
23991
|
}
|
|
23992
|
-
async function resolveDevtoolsMcpSelection(
|
|
23992
|
+
async function resolveDevtoolsMcpSelection(flags, runtimes) {
|
|
23993
23993
|
if (flags.devtools && flags.noDevtools) {
|
|
23994
23994
|
console.error("Usa solo uno de --devtools o --no-devtools.");
|
|
23995
23995
|
process.exitCode = 1;
|
|
@@ -23998,7 +23998,7 @@ async function resolveDevtoolsMcpSelection(command, flags, runtimes) {
|
|
|
23998
23998
|
if (flags.devtools || flags.noDevtools) {
|
|
23999
23999
|
return Object.fromEntries(runtimes.map((runtime) => [runtime, flags.devtools]));
|
|
24000
24000
|
}
|
|
24001
|
-
if (
|
|
24001
|
+
if (flags.yes || flags.dryRun || flags.targetDir !== void 0 || !process.stdout.isTTY) {
|
|
24002
24002
|
return {};
|
|
24003
24003
|
}
|
|
24004
24004
|
const file = devtoolsMcpPreferenceFile();
|
|
@@ -24199,7 +24199,6 @@ Uso: pnpm dlx jorgex-stack [comando] [opciones]
|
|
|
24199
24199
|
|
|
24200
24200
|
Comandos:
|
|
24201
24201
|
install Instala el stack; OpenCode fresh exige elegir modelos conectados
|
|
24202
|
-
sync Re-aplica la config y el model-map existente (idempotente; sin picker)
|
|
24203
24202
|
models Picker por tier o subagente (OpenCode: 'opencode models' en vivo)
|
|
24204
24203
|
update --check: compara stack/Engram/skills con sus upstreams
|
|
24205
24204
|
doctor Estado: Engram, drift de config, hooks de Codex, key de context7
|
|
@@ -24219,9 +24218,9 @@ Opciones:
|
|
|
24219
24218
|
--yes, -y No interactivo
|
|
24220
24219
|
--playwright Autoriza Playwright CLI gestionado y Chromium (requerido con --yes/sin TTY)
|
|
24221
24220
|
--engram (install) autoriza instalar el binario Engram si falta
|
|
24222
|
-
--devtools (install
|
|
24223
|
-
--no-devtools (install
|
|
24224
|
-
--upgrade-permissions (install
|
|
24221
|
+
--devtools (install) activa Chrome DevTools MCP para los runtimes destino (opt-in)
|
|
24222
|
+
--no-devtools (install) desactiva Chrome DevTools MCP (incompatible con --devtools)
|
|
24223
|
+
--upgrade-permissions (install) re-aplica permisos gestionados sobre config existente (opt-in)
|
|
24225
24224
|
--engram-typebox-compat (install/update con Pi) opt-in expl\xEDcito a la variante temporal #1567;
|
|
24226
24225
|
sin el flag no se adquiere ni persiste ninguna preferencia
|
|
24227
24226
|
--remove-engram (uninstall) desregistra Engram de los runtimes;
|
|
@@ -24329,9 +24328,8 @@ Flags disponibles: jorgex-stack --help`
|
|
|
24329
24328
|
}
|
|
24330
24329
|
return;
|
|
24331
24330
|
}
|
|
24332
|
-
case "install":
|
|
24333
|
-
|
|
24334
|
-
const runtimes = await resolveRuntimes(flags, command === "install");
|
|
24331
|
+
case "install": {
|
|
24332
|
+
const runtimes = await resolveRuntimes(flags, true);
|
|
24335
24333
|
if (runtimes === null) return;
|
|
24336
24334
|
if (runtimes.length === 0) {
|
|
24337
24335
|
console.error("Ning\xFAn runtime detectado (opencode, claude-code, codex, pi).");
|
|
@@ -24363,12 +24361,12 @@ Flags disponibles: jorgex-stack --help`
|
|
|
24363
24361
|
}
|
|
24364
24362
|
const mode = fileRuntimes.length > 0 || flags.mode !== void 0 || flags.subagentConcurrency !== void 0 ? await resolveInstallMode(flags) : void 0;
|
|
24365
24363
|
if (mode === null) return;
|
|
24366
|
-
const devtoolsMcpSelection = await resolveDevtoolsMcpSelection(
|
|
24364
|
+
const devtoolsMcpSelection = await resolveDevtoolsMcpSelection(flags, runtimes);
|
|
24367
24365
|
if (devtoolsMcpSelection === null) {
|
|
24368
24366
|
exitCode = process.exitCode === 1 ? 1 : 0;
|
|
24369
24367
|
return;
|
|
24370
24368
|
}
|
|
24371
|
-
const playwrightToolConsent = await resolvePlaywrightToolConsent(
|
|
24369
|
+
const playwrightToolConsent = await resolvePlaywrightToolConsent(flags, runtimes);
|
|
24372
24370
|
if (playwrightToolConsent === null) {
|
|
24373
24371
|
exitCode = process.exitCode === 1 ? 1 : 0;
|
|
24374
24372
|
return;
|
|
@@ -24380,20 +24378,17 @@ Flags disponibles: jorgex-stack --help`
|
|
|
24380
24378
|
};
|
|
24381
24379
|
p6.log.info(`Estilo de escritura: ${writingStyle.sourcePath}${flags.dryRun ? " (instalaci\xF3n prevista; sin escrituras)" : ""}.`);
|
|
24382
24380
|
applyWritingStyle(writingStyle, flags.dryRun);
|
|
24383
|
-
if (!await ensureOpenCodeModelsForInstall(
|
|
24381
|
+
if (!await ensureOpenCodeModelsForInstall(flags, fileRuntimes)) {
|
|
24384
24382
|
exitCode = 1;
|
|
24385
24383
|
return;
|
|
24386
24384
|
}
|
|
24387
|
-
|
|
24388
|
-
if (
|
|
24389
|
-
|
|
24390
|
-
|
|
24391
|
-
|
|
24392
|
-
exitCode = 1;
|
|
24393
|
-
return;
|
|
24394
|
-
}
|
|
24395
|
-
engramBin = engram.bin;
|
|
24385
|
+
const engram = await resolveHostEngramForInstall(flags);
|
|
24386
|
+
if (!engram.ok) {
|
|
24387
|
+
p6.log.error(engram.message);
|
|
24388
|
+
exitCode = 1;
|
|
24389
|
+
return;
|
|
24396
24390
|
}
|
|
24391
|
+
const engramBin = engram.bin;
|
|
24397
24392
|
if (fileRuntimes.length > 0) {
|
|
24398
24393
|
exitCode = await runInstall({
|
|
24399
24394
|
runtimes: fileRuntimes,
|
|
@@ -24414,7 +24409,7 @@ Flags disponibles: jorgex-stack --help`
|
|
|
24414
24409
|
});
|
|
24415
24410
|
}
|
|
24416
24411
|
let piCanRun = true;
|
|
24417
|
-
if (
|
|
24412
|
+
if (fileRuntimes.length === 0 && runtimes.includes("pi") && playwrightToolPlan.actions.length > 0) {
|
|
24418
24413
|
if (flags.dryRun) {
|
|
24419
24414
|
p6.log.info("Playwright CLI: instalaci\xF3n global y navegador previstos (dry-run; no se ejecutan).");
|
|
24420
24415
|
} else {
|
|
@@ -24439,7 +24434,7 @@ Flags disponibles: jorgex-stack --help`
|
|
|
24439
24434
|
} else {
|
|
24440
24435
|
const piExitCode = await runSelectedPi({
|
|
24441
24436
|
operation: command,
|
|
24442
|
-
...
|
|
24437
|
+
...playwrightToolConsent.interactive && !flags.yes && flags.targetDir === void 0 && !playwrightToolConsent.confirmed ? { playwrightRefresh: false } : {},
|
|
24443
24438
|
targetDir: flags.targetDir,
|
|
24444
24439
|
yes: flags.yes,
|
|
24445
24440
|
resolvedEngramBin: flags.targetDir === void 0 ? engramBin : void 0,
|
|
@@ -24643,9 +24638,9 @@ Flags disponibles: jorgex-stack --help`
|
|
|
24643
24638
|
}));
|
|
24644
24639
|
}
|
|
24645
24640
|
if (result.syncRequired && fileRuntimes.length > 0 && (result.exitCode !== 0 || !canSync)) {
|
|
24646
|
-
p6.log.warn("Skills/stack actualizados, pero
|
|
24641
|
+
p6.log.warn("Skills/stack actualizados, pero su aplicaci\xF3n a los runtimes sigue pendiente. Ejecuta jorgex-stack install --mode human|programmatic.");
|
|
24647
24642
|
} else if (!playwrightReconciled && result.exitCode === 0 && result.syncRequired && fileRuntimes.length > 0 && canSync && !flags.yes && process.stdout.isTTY) {
|
|
24648
|
-
const apply = await p6.confirm({ message: "\xBFRe-aplicar a los runtimes ahora?
|
|
24643
|
+
const apply = await p6.confirm({ message: "\xBFRe-aplicar a los runtimes ahora?" });
|
|
24649
24644
|
if (!p6.isCancel(apply) && apply) {
|
|
24650
24645
|
process.exitCode = await runInstall({
|
|
24651
24646
|
runtimes: fileRuntimes,
|
|
@@ -24657,10 +24652,10 @@ Flags disponibles: jorgex-stack --help`
|
|
|
24657
24652
|
...updateCapability === void 0 ? {} : { playwrightCapability: updateCapability }
|
|
24658
24653
|
});
|
|
24659
24654
|
} else {
|
|
24660
|
-
console.log("Sin aplicar. Cuando quieras: jorgex-stack
|
|
24655
|
+
console.log("Sin aplicar. Cuando quieras: jorgex-stack install");
|
|
24661
24656
|
}
|
|
24662
24657
|
} else if (result.exitCode === 0 && result.syncRequired && fileRuntimes.length > 0 && canSync && (flags.yes || !process.stdout.isTTY)) {
|
|
24663
|
-
console.log("Skills/stack actualizados. Ejecuta jorgex-stack
|
|
24658
|
+
console.log("Skills/stack actualizados. Ejecuta jorgex-stack install para aplicarlos a los runtimes.");
|
|
24664
24659
|
}
|
|
24665
24660
|
if (runtimes.includes("pi")) {
|
|
24666
24661
|
persistSuccessfulGlobalMode(mode, flags.targetDir, flags.dryRun, process.exitCode ?? result.exitCode);
|
|
@@ -24680,14 +24675,14 @@ Flags disponibles: jorgex-stack --help`
|
|
|
24680
24675
|
if (runtimes.includes("pi")) code = Math.max(code, await runSelectedPi({ operation: "models", targetDir: flags.targetDir }));
|
|
24681
24676
|
process.exitCode = code;
|
|
24682
24677
|
if (code === 0 && fileRuntimes.length > 0 && !flags.yes && process.stdout.isTTY) {
|
|
24683
|
-
const apply = await p6.confirm({ message: "\xBFAplicar ahora los modelos a los agentes instalados?
|
|
24678
|
+
const apply = await p6.confirm({ message: "\xBFAplicar ahora los modelos a los agentes instalados?" });
|
|
24684
24679
|
if (!p6.isCancel(apply) && apply) {
|
|
24685
24680
|
const preferenceFile = installModePreferenceFile();
|
|
24686
24681
|
const explicitMode = flags.mode !== void 0 || flags.subagentConcurrency !== void 0;
|
|
24687
24682
|
const hasSavedMode = hasInstallModePreference(preferenceFile);
|
|
24688
24683
|
const canResolveMode = flags.targetDir !== void 0 || explicitMode || hasSavedMode;
|
|
24689
24684
|
if (!canResolveMode) {
|
|
24690
|
-
p6.log.warn("Model-map guardado:
|
|
24685
|
+
p6.log.warn("Model-map guardado: su aplicaci\xF3n a los runtimes requiere un modo. Ejecuta jorgex-stack install --mode human|programmatic.");
|
|
24691
24686
|
return;
|
|
24692
24687
|
}
|
|
24693
24688
|
const mode = await resolveInstallMode(flags, false);
|
|
@@ -24702,7 +24697,7 @@ Flags disponibles: jorgex-stack --help`
|
|
|
24702
24697
|
...playwrightCapability === void 0 ? {} : { playwrightCapability }
|
|
24703
24698
|
});
|
|
24704
24699
|
} else {
|
|
24705
|
-
console.log("Sin aplicar. Cuando quieras: jorgex-stack
|
|
24700
|
+
console.log("Sin aplicar. Cuando quieras: jorgex-stack install");
|
|
24706
24701
|
}
|
|
24707
24702
|
}
|
|
24708
24703
|
return;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jorgex-stack",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.72",
|
|
4
4
|
"description": "Harness multi-agente portable: instala la config JorgeX (agentes, skills, hooks, Engram, MCPs) en Claude Code, Codex CLI, OpenCode y Pi",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,10 +31,10 @@ You fix comments directly instead of reporting suggestions: trivial comment work
|
|
|
31
31
|
|
|
32
32
|
1. **Factual accuracy**: comments that no longer match what the code does → correct them.
|
|
33
33
|
2. **Worthless comments**: comments that restate obvious code → remove them.
|
|
34
|
-
3. **Missing critical context**:
|
|
34
|
+
3. **Missing critical context**: a verified, undocumented assumption or non-obvious "why" needed to use or change the code safely → add it.
|
|
35
35
|
4. **Misleading elements**: wording that could be misread → clarify.
|
|
36
36
|
|
|
37
|
-
|
|
37
|
+
Apply the shared system prompt's **Code comments** policy; follow local language and format, not density. Leave comments that already provide useful, accurate context untouched; cleanup is not a quota or a requirement to produce edits. Do not edit docstrings used as runtime metadata within this comments-only scope: report necessary contract changes to their owner.
|
|
38
38
|
|
|
39
39
|
## Output format
|
|
40
40
|
|
|
@@ -23,6 +23,8 @@ Spend disproportionate effort here. **Be aggressive. Be creative. Refuse to give
|
|
|
23
23
|
|
|
24
24
|
### Ways to construct one — try them in roughly this order
|
|
25
25
|
|
|
26
|
+
Inspect the project's existing runner, fixtures, helpers and diagnostic commands first. Reuse the closest suitable harness; the options below are not an instruction to build a second testing stack. Apply `lean-code`'s diagnostic tooling policy before adding or retaining tooling.
|
|
27
|
+
|
|
26
28
|
1. **Failing test** at whatever seam reaches the bug — unit, integration, e2e.
|
|
27
29
|
2. **Curl / HTTP script** against a running dev server.
|
|
28
30
|
3. **CLI invocation** with a fixture input, diffing stdout against a known-good snapshot.
|
|
@@ -38,7 +40,7 @@ Build the right feedback loop, and the bug is 90% fixed.
|
|
|
38
40
|
|
|
39
41
|
### Tighten the loop
|
|
40
42
|
|
|
41
|
-
|
|
43
|
+
Tighten the loop for this investigation, not into a permanent product:
|
|
42
44
|
|
|
43
45
|
- Can I make it faster? (Cache setup, skip unrelated init, narrow the test scope.)
|
|
44
46
|
- Can I make the signal sharper? (Assert on the specific symptom, not "didn't crash".)
|
|
@@ -134,7 +136,9 @@ Required before declaring done:
|
|
|
134
136
|
- [ ] Original repro no longer reproduces (re-run the Phase 1 loop)
|
|
135
137
|
- [ ] Regression test passes (or absence of seam is documented)
|
|
136
138
|
- [ ] All `[DEBUG-...]` instrumentation removed (`grep` the prefix)
|
|
137
|
-
- [ ] Throwaway
|
|
139
|
+
- [ ] Throwaway probes, scripts, harnesses and their owned resources cleaned up; moving them to a debug folder is not cleanup. Retain tooling only when the recurring need, consumer, harness gap and maintenance owner are justified under `lean-code`; preserve the regression test.
|
|
138
140
|
- [ ] The hypothesis that turned out correct is stated in the commit / PR message — so the next debugger learns
|
|
139
141
|
|
|
142
|
+
Keep compact, redacted, reproducible evidence in the existing task or PR: exact command, relevant environment/version and fixture or seed, observed failure and post-fix result. Distinguish verified observations from hypotheses. Preserve the first failure and any necessary diagnostic artifact when it carries unique evidence; do not retain full dumps or disposable environments by default. Report cleanup that could not safely finish.
|
|
143
|
+
|
|
140
144
|
**Then ask: what would have prevented this bug?** If the answer involves architectural change (no good test seam, tangled callers, hidden coupling) hand off to the `/improve-codebase-architecture` skill with the specifics. Make the recommendation **after** the fix is in, not before — you have more information now than when you started.
|
|
@@ -60,6 +60,10 @@ Do not add a new dependency unless the task explicitly requires it or the projec
|
|
|
60
60
|
Before adding a new helper, wrapper, abstraction, or dependency, run the ladder again.
|
|
61
61
|
Prefer the narrowest change that solves the real need.
|
|
62
62
|
|
|
63
|
+
### Diagnostic tooling
|
|
64
|
+
|
|
65
|
+
Reuse the project's runner, fixtures, helpers and existing diagnostic commands before building a harness. New probes, replay scripts and diagnostic harnesses are temporary by default, with explicit resource ownership and automatic teardown arranged before execution. Keep tooling only for a concrete recurring need: identify its consumer, why the existing harness cannot cover it, and who maintains it in the current task or PR. A successful one-off investigation alone does not justify a permanent command, framework or dependency. Preserve the authoritative regression test and compact reproduction evidence, not the disposable environment.
|
|
66
|
+
|
|
63
67
|
### Review / simplification
|
|
64
68
|
|
|
65
69
|
Use it as a bloat filter: delete, stdlib, native/platform, reuse, or shrink.
|
|
@@ -275,7 +275,9 @@ async def get_user(user_id: str) -> Dict[str, Any]:
|
|
|
275
275
|
|
|
276
276
|
## Tool Docstrings
|
|
277
277
|
|
|
278
|
-
Every tool
|
|
278
|
+
Every tool needs a concise docstring describing the contract clients need: purpose, non-obvious input constraints, output shape, side effects and relevant errors. Preserve information used to generate MCP descriptions or schemas; these docstrings are runtime metadata, not merely code comments. Do not repeat types or field descriptions already exposed by the generated schema unless needed to disambiguate behavior. Document dict/JSON return structure when it is not exposed by an output schema.
|
|
279
|
+
|
|
280
|
+
The example below illustrates possible contract details, not mandatory sections for every tool:
|
|
279
281
|
|
|
280
282
|
```python
|
|
281
283
|
async def search_users(params: UserSearchInput) -> str:
|
|
@@ -419,7 +421,7 @@ def _handle_api_error(e: Exception) -> str:
|
|
|
419
421
|
async def example_search_users(params: UserSearchInput) -> str:
|
|
420
422
|
'''Search for users in the Example system by name, email, or team.
|
|
421
423
|
|
|
422
|
-
[
|
|
424
|
+
[Concise tool contract docstring]
|
|
423
425
|
'''
|
|
424
426
|
try:
|
|
425
427
|
# Make API request using validated parameters
|
|
@@ -692,8 +694,8 @@ Before finalizing your Python MCP server implementation, ensure:
|
|
|
692
694
|
- [ ] Annotations correctly set (readOnlyHint, destructiveHint, idempotentHint, openWorldHint)
|
|
693
695
|
- [ ] All tools use Pydantic BaseModel for input validation with Field() definitions
|
|
694
696
|
- [ ] All Pydantic Fields have explicit types and descriptions with constraints
|
|
695
|
-
- [ ] All tools
|
|
696
|
-
- [ ]
|
|
697
|
+
- [ ] All tools expose concise, sufficient contract descriptions without duplicating generated schema information
|
|
698
|
+
- [ ] Dict/JSON return structure is exposed through an output schema or documented when no schema is exposed
|
|
697
699
|
- [ ] Pydantic models handle input validation (no manual validation needed)
|
|
698
700
|
|
|
699
701
|
### Advanced Features (where applicable)
|
|
@@ -716,4 +718,4 @@ Before finalizing your Python MCP server implementation, ensure:
|
|
|
716
718
|
- [ ] Server runs successfully: `python your_server.py --help`
|
|
717
719
|
- [ ] All imports resolve correctly
|
|
718
720
|
- [ ] Sample tool calls work as expected
|
|
719
|
-
- [ ] Error scenarios handled gracefully
|
|
721
|
+
- [ ] Error scenarios handled gracefully
|
|
@@ -54,13 +54,13 @@ For a manual xreview without an explicit work context, continue without PRD/plan
|
|
|
54
54
|
|
|
55
55
|
## 4. Comment pass FIRST (conditional)
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
Inspect relevant comment/docstring hunks first. Run `comment-fixer` ALONE before the analysts when source-code comments/docstrings need an accuracy, usefulness or critical-context pass under the shared system prompt's **Code comments** policy. It already owns comment cleanup; do not add a separate cleanup agent. Instruction prose, documentation pages and illustrative code fences alone do not trigger this pass. It edits comments in place (comments only, never code), so analysts review the resulting working state rather than mistaking its edits for contamination.
|
|
58
58
|
|
|
59
59
|
- Pass the frozen refs or working-state identity and the relevant comment/docstring scope.
|
|
60
60
|
- When the orchestrator supplied one, pass it the same exact work context path as every other review subagent.
|
|
61
61
|
- If it changed anything and the scope is a committed diff (branch/PR): comment-fixer itself never commits — YOU commit its fixes before launching reviewers, staging ONLY its files (never `-a`/`-A`). Then freeze the new candidate SHA and refresh scopes. If a commit cannot be made, report the uncommitted state; it cannot certify the committed candidate.
|
|
62
62
|
- For working-tree reviews: leave its edits uncommitted (they join the user's pending work) and say so in the report.
|
|
63
|
-
- If
|
|
63
|
+
- If no comment pass is needed, skip it and state why. A pass that leaves all comments unchanged is valid.
|
|
64
64
|
|
|
65
65
|
## 5. Launch the remaining subagents in PARALLEL
|
|
66
66
|
|
|
@@ -26,6 +26,10 @@ Ask questions when something isn't clear instead of assuming it's correct.
|
|
|
26
26
|
- Do not add dependencies without explicit user approval.
|
|
27
27
|
- Run lint and typecheck after significant changes when available.
|
|
28
28
|
|
|
29
|
+
### Code comments
|
|
30
|
+
|
|
31
|
+
Add comments only when they carry information the code does not make clear: a non-obvious reason, invariant, constraint or operational hazard. Do not narrate obvious code, mirror existing comment density, or add comments just because a function or test is new. Preserve contractual documentation, legal notices, directives, and critical security, concurrency or deletion context; docstrings used as runtime metadata are part of the contract, not disposable prose. Follow local language and format, without line-count or density quotas. Leaving already-clear code uncommented is valid.
|
|
32
|
+
|
|
29
33
|
---
|
|
30
34
|
|
|
31
35
|
## Default Architecture
|