worktree-for-agents 0.0.0-stage → 1.0.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/GUIDE.md ADDED
@@ -0,0 +1,45 @@
1
+ Vas a implementar un cambio, ejecutar una spec o iniciar un flujo. ¿Quieres crear un worktree para hacerlo aislado?
2
+
3
+ Esta guía explica cómo usar el gestor `worktree-for-agents` para trabajar
4
+ aislado en un worktree antes de tocar la rama principal.
5
+
6
+ ## Las siete herramientas
7
+
8
+ El servicio MCP expone exactamente siete herramientas:
9
+
10
+ - `worktree_create`: crea un worktree y su rama para un identificador de trabajo.
11
+ - `worktree_complete`: integra el worktree en la rama base y retira el worktree.
12
+ - `worktree_cleanup`: retira el worktree y su rama sin integrar.
13
+ - `worktree_recover`: recupera una transacción pendiente por su identificador.
14
+ - `worktree_list`: lista los worktrees del repositorio.
15
+ - `worktree_prune`: poda la información de worktrees que ya no existen.
16
+ - `worktree_status`: muestra el estado de un trabajo.
17
+
18
+ Todas exigen una ruta absoluta de repositorio Git en `repo`.
19
+
20
+ ## Cuándo ofrecer el worktree
21
+
22
+ Antes de trabajar en la rama principal, ofrece crear un worktree con
23
+ `worktree_create`. Trabaja dentro del worktree y luego integra con
24
+ `worktree_complete`. Si el trabajo se descarta, usa `worktree_cleanup`.
25
+
26
+ ## Lanzamiento sin bin
27
+
28
+ El paquete no expone bin ni `npx`. El servicio MCP se lanza con Node y la
29
+ ruta absoluta del paquete:
30
+
31
+ ```sh
32
+ node <paquete>/mcp-server.mjs
33
+ ```
34
+
35
+ La CLI se lanza del mismo modo:
36
+
37
+ ```sh
38
+ node <paquete>/worktree.mjs --version
39
+ ```
40
+
41
+ El diagnóstico de la instalación se obtiene con:
42
+
43
+ ```sh
44
+ node <paquete>/setup.mjs
45
+ ```
package/README.md CHANGED
@@ -1,3 +1,181 @@
1
- # Temporary Holding Version
1
+ # Gestor de worktrees
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Gestor standalone para crear, completar, limpiar y recuperar worktrees de un
4
+ repositorio Git. El proyecto no conoce FlowTask ni depende de sus rutas, refs
5
+ heredadas o mecanismos de coordinación.
6
+
7
+ ## Requisitos
8
+
9
+ - **Python 3.9 o posterior.** El entrypoint sólo comprueba que `python3` esté
10
+ disponible en el `PATH`; el piso de 3.9 lo valida el postinstall del paquete
11
+ y `node <paquete>/setup.mjs`. El paquete usa sólo la biblioteca estándar.
12
+ - **Git 2.17.0 o posterior**, por `git worktree remove`, que es el comando más
13
+ reciente que usa el gestor. La línea base de las pruebas es Git 2.54.0. El
14
+ gestor no comprueba la versión de Git en tiempo de ejecución.
15
+ - **Node 18 o posterior** para los lanzadores `mcp-server.mjs`, `worktree.mjs`
16
+ y `setup.mjs`.
17
+ - **`bash`** para ejecutar las suites de pruebas.
18
+
19
+ ## Instalación
20
+
21
+ El gestor se distribuye como paquete npm `worktree-for-agents`, versión
22
+ `1.0.0`, sin bin ni `npx`:
23
+
24
+ ```sh
25
+ npm install -g worktree-for-agents@latest
26
+ pnpm add -g worktree-for-agents@latest
27
+ ```
28
+
29
+ Comprueba el diagnóstico de la instalación:
30
+
31
+ ```sh
32
+ node <paquete>/setup.mjs
33
+ ```
34
+
35
+ El clon del repositorio queda solo para desarrollo. No hay `pip install` ni
36
+ dependencias que resolver: el gestor usa sólo la biblioteca estándar de
37
+ Python. Una vez instalado, el gestor funciona sin red.
38
+
39
+ ## Uso rápido
40
+
41
+ Las opciones globales van antes del subcomando y `--repo` exige una ruta
42
+ absoluta.
43
+
44
+ ```text
45
+ worktree.sh [--repo ABS] [--config ABS] [--json] create <id> [--base BRANCH] [--init-submodules] [--prepare] [--verify]
46
+ worktree.sh [globales] complete <id> [--preserve-dirty] [--title TEXTO] [--body TEXTO]
47
+ worktree.sh [globales] cleanup <id> [--discard]
48
+ worktree.sh [globales] recover [<transaction-id>]
49
+ worktree.sh [globales] prune
50
+ worktree.sh [globales] list
51
+ ```
52
+
53
+ Target-direct opera sobre el repositorio indicado en `--repo` y no crea un
54
+ worktree del parent ni modifica su `HEAD`. Su sintaxis coloca `--parent-repo`
55
+ después de la acción y exige `--submodule-path` en `create`:
56
+
57
+ ```text
58
+ worktree.sh [--repo ABS] target-direct <acción> <id> --parent-repo <parent> [--target submodule] [--submodule-path <REL>] [--base BRANCH] [--link-parent staged-only] [--descriptor PATH]
59
+ ```
60
+
61
+ Las acciones son `create`, `link-parent`, `abort`, `complete` y `recover`, y el
62
+ único modo de enlace admitido es `--link-parent staged-only`.
63
+
64
+ `--json` publica un único documento JSON. `--request-json <archivo|->` publica
65
+ el mismo sobre de nueve claves que usa el transporte MCP, y acepta `--json` de
66
+ forma opcional. Un dry run de `create` publica `planned: true` y no crea
67
+ worktree ni rama.
68
+
69
+ El servicio MCP se publica por stdio. Desde el paquete instalado se lanza sin
70
+ bin:
71
+
72
+ ```sh
73
+ node <paquete>/mcp-server.mjs
74
+ ```
75
+
76
+ La CLI se usa del mismo modo:
77
+
78
+ ```sh
79
+ node <paquete>/worktree.mjs --version
80
+ ```
81
+
82
+ El `initialize` del MCP publica la guía en `instructions`:
83
+
84
+ ```text
85
+ Vas a implementar un cambio, ejecutar una spec o iniciar un flujo. ¿Quieres crear un worktree para hacerlo aislado?
86
+ ```
87
+
88
+ Para desarrollo, el transporte también arranca desde el checkout:
89
+
90
+ ```sh
91
+ PYTHONPATH=. python3 -m worktree_manager.mcp_transport
92
+ ```
93
+
94
+ ## Configuración
95
+
96
+ La configuración es un archivo opcional de `clave=valor`, seleccionado con
97
+ `--config` o tomado de `.worktree-manager.conf` en la raíz del repositorio.
98
+ Las once claves y sus valores por defecto son:
99
+
100
+ | Clave | Por defecto | Restricción |
101
+ |---|---|---|
102
+ | `worktrees_dir` | `.worktrees` | No puede empezar por `-` |
103
+ | `branch_prefix` | `worktree/` | — |
104
+ | `state_dir` | `worktree-manager` | Ruta relativa segura |
105
+ | `backup_dir` | `backups` | No es una ruta absoluta y no contiene `..` |
106
+ | `backup_ref_prefix` | `worktree-manager/backups` | Sin `..` |
107
+ | `lock_dir` | `locks` | Ruta relativa segura |
108
+ | `prepare_command` | `''` (vacío) | Requerida cuando `prepare_enabled=true` |
109
+ | `verify_command` | `''` (vacío) | Requerida cuando `verify_enabled=true` |
110
+ | `prepare_enabled` | `false` | `true` o `false` |
111
+ | `verify_enabled` | `false` | `true` o `false` |
112
+ | `preserve_dirty` | `false` | `true` o `false` |
113
+
114
+ Cada clave puede aparecer una sola vez. Las claves desconocidas, las líneas mal
115
+ formadas, los booleanos inválidos y las rutas inseguras se rechazan como
116
+ `invalid_configuration` con código de salida `3`. La variable de entorno
117
+ `WORKTREE_MANAGER_<CLAVE>`, con la clave en mayúsculas, reemplaza el valor
118
+ leído del archivo.
119
+
120
+ ## Arquitectura
121
+
122
+ `worktree.sh` es el entrypoint y delega el lifecycle en el paquete Python
123
+ `worktree_manager`, que se ejecuta con `python3 -m worktree_manager`. El paquete
124
+ es la única implementación del lifecycle: no existe un motor shell alternativo.
125
+
126
+ El paquete se organiza en módulos con una responsabilidad cada uno:
127
+
128
+ | Módulo | Responsabilidad |
129
+ | --- | --- |
130
+ | `worktree_manager.cli` | Despachador de comandos, despacho target-direct y contrato de salida. |
131
+ | `worktree_manager.configuration` | Lectura y validación de la configuración `clave=valor`. |
132
+ | `worktree_manager.models` | Valores de dominio compartidos: resultados, errores e identidades. |
133
+ | `worktree_manager.output` | Publicación del resultado como texto legible o como JSON. |
134
+ | `worktree_manager.git_repository` | Acceso compartido a Git para los módulos del lifecycle. |
135
+ | `worktree_manager.worktree_lifecycle` | Operaciones `create`, `complete`, `cleanup` y `prune`. |
136
+ | `worktree_manager.commit_message` | Composición determinista del mensaje de cierre y fallback neutro. |
137
+ | `worktree_manager.target_direct_adapter` | Operaciones target-direct sobre un submódulo. |
138
+ | `worktree_manager.recovery_manager` | Recuperación de transacciones pendientes. |
139
+ | `worktree_manager.transaction_journal` | Journal durable de transacciones y enlaces. |
140
+ | `worktree_manager.backup_store` | Referencias de respaldo retenidas. |
141
+ | `worktree_manager.lock_manager` | Exclusión mutua entre procesos. |
142
+ | `worktree_manager.state_digest` | Digest canónico del estado del repositorio y de un plan. |
143
+ | `worktree_manager.mcp_server` | Servicio MCP publicado por stdio. |
144
+ | `worktree_manager.mcp_contract` | Contratos estrictos y versionados de petición y de sobre. |
145
+ | `worktree_manager.mcp_operations` | Fachada sobre los servicios de lifecycle y de recuperación. |
146
+ | `worktree_manager.mcp_transport` | Punto de entrada del transporte por stdio. |
147
+
148
+ El paquete contiene además el marcador de paquete `__init__.py` y el punto de
149
+ entrada `__main__.py`, que es lo que ejecuta `python3 -m worktree_manager`.
150
+
151
+ ## Pruebas
152
+
153
+ ```sh
154
+ bash tests/cli-usage.sh
155
+ bash tests/cli-json.sh
156
+ bash tests/compatibility.sh
157
+ bash tests/smoke.sh
158
+ bash tests/parity.sh
159
+ PYTHONPATH=. python3 -m unittest discover -s tests -p 'test_*.py'
160
+ PYTHONPATH=. python3 -m unittest discover -s tests -p 'test_mcp*.py' -v
161
+ ```
162
+
163
+ ## Documentación
164
+
165
+ - [Contrato de salida de la CLI](docs/cli-contract-v1.md) — contrato.
166
+ - [Contrato del servicio MCP](docs/mcp-contract.md) — contrato.
167
+ - [Guía de instalación y uso](docs/installation.md) — guía.
168
+ - [Histórico bash → Python](docs/history-bash-to-python.md) — memoria, no contrato.
169
+
170
+ Los contratos fijan el comportamiento verificable. La guía explica cómo usarlo.
171
+ El histórico registra la transición y no sustituye a los contratos.
172
+
173
+ ## Fuente y distribución
174
+
175
+ Este repositorio es la fuente de verdad de la implementación, de los contratos,
176
+ de la instalación y del histórico del gestor.
177
+
178
+ El consumidor que integra este repositorio documenta el adaptador, el bridge y
179
+ la frontera del submódulo: **la documentación de esa integración vive en el
180
+ repositorio consumidor**. El gestor no mantiene una copia vendorizada de sí
181
+ mismo y no conoce al consumidor.
@@ -0,0 +1,214 @@
1
+ # Instalación y uso del gestor de worktrees
2
+
3
+ Esta guía explica cómo instalar el gestor como paquete npm y cómo usarlo
4
+ sobre un repositorio de prueba. La integración con un consumidor concreto
5
+ se documenta en el repositorio que integra el gestor.
6
+
7
+ Los ejemplos usan `$HOME` porque `--repo` exige una ruta absoluta. `<paquete>`
8
+ es la ruta del paquete instalado.
9
+
10
+ ## 1. Requisitos
11
+
12
+ Comprueba las versiones disponibles:
13
+
14
+ ```sh
15
+ python3 --version
16
+ git --version
17
+ node --version
18
+ ```
19
+
20
+ - **Python 3.9 o posterior.** El postinstall del paquete verifica el piso de
21
+ 3.9 y falla de forma visible si falta o es anterior. `node
22
+ <paquete>/setup.mjs` informa el intérprete detectado.
23
+ - **Git 2.17.0 o posterior**, por `git worktree remove`. La línea base de las
24
+ pruebas es Git 2.54.0. El gestor no comprueba la versión de Git en tiempo de
25
+ ejecución.
26
+ - **Node 18 o posterior** para los lanzadores `mcp-server.mjs`, `worktree.mjs`
27
+ y `setup.mjs`.
28
+ - **`bash`** para ejecutar las suites de pruebas.
29
+
30
+ ## 2. Instalar el paquete
31
+
32
+ ```sh
33
+ npm install -g worktree-for-agents@latest
34
+ pnpm add -g worktree-for-agents@latest
35
+ ```
36
+
37
+ Comprueba el diagnóstico:
38
+
39
+ ```sh
40
+ node <paquete>/setup.mjs
41
+ ```
42
+
43
+ El paquete no expone bin ni `npx`: el MCP se lanza con `node
44
+ <paquete>/mcp-server.mjs` y la CLI con `node <paquete>/worktree.mjs`. El clon
45
+ del repositorio queda solo para desarrollo. No hay `pip install` ni
46
+ dependencias que resolver: el gestor usa sólo la biblioteca estándar de
47
+ Python. Una vez instalado, el gestor funciona sin red.
48
+
49
+ ## 3. Un repositorio de prueba
50
+
51
+ El gestor exige que la ruta del worktree esté ignorada por Git, y
52
+ `.worktrees/` en el `.gitignore` cumple esa condición.
53
+
54
+ ```sh
55
+ mkdir "$HOME/demo" && cd "$HOME/demo"
56
+ git init -b main
57
+ git config user.name "Demo"
58
+ git config user.email "demo@example.invalid"
59
+ printf 'base\n' > file
60
+ printf '.worktrees/\n' > .gitignore
61
+ git add file .gitignore
62
+ git commit -m "base"
63
+ ```
64
+
65
+ Crea el worktree:
66
+
67
+ ```sh
68
+ "$HOME/worktree-manager/worktree.sh" --repo "$HOME/demo" create demo --base main
69
+ ```
70
+
71
+ Qué deja cada paso:
72
+
73
+ - `git init` crea el repositorio y su rama `main`.
74
+ - El commit inicial fija la base sobre la que se construye el worktree.
75
+ - `create` crea la rama `worktree/demo`, el worktree en `$HOME/demo/.worktrees/demo`
76
+ y el journal de la transacción en el directorio de estado del repositorio.
77
+
78
+ Comprueba el estado:
79
+
80
+ ```sh
81
+ "$HOME/worktree-manager/worktree.sh" --repo "$HOME/demo" list
82
+ ```
83
+
84
+ Trabaja dentro del worktree y luego intégralo:
85
+
86
+ ```sh
87
+ cd "$HOME/demo/.worktrees/demo"
88
+ printf 'cambio\n' >> file
89
+ git add file
90
+ git commit -m "cambio"
91
+ cd "$HOME/demo"
92
+ "$HOME/worktree-manager/worktree.sh" --repo "$HOME/demo" complete demo --base main
93
+ ```
94
+
95
+ `complete` exige que el repositorio esté en la rama base, que el worktree no
96
+ tenga cambios sin commitear y que el destino tampoco los tenga, salvo que se
97
+ use `--preserve-dirty`. Al terminar, el cambio queda integrado como un commit
98
+ de squash en `main`, y el worktree y su rama se retiran.
99
+
100
+ Para dejar un commit de cierre diciente, pasa `--title` y, opcionalmente,
101
+ `--body`:
102
+
103
+ ```sh
104
+ "$HOME/worktree-manager/worktree.sh" --repo "$HOME/demo" complete demo --base main \
105
+ --title "Cierre de demo" --body "Entrega: cambio integrado. Motivo: verificacion."
106
+ ```
107
+
108
+ Si no se pasa `--title`, el gestor usa el fallback generico:
109
+ `Complete <work_id> (generic closure)` con el cuerpo
110
+ `No delivery description was available at closure time.`.
111
+
112
+ ## 4. Configuración
113
+
114
+ La configuración es un archivo de `clave=valor`. El gestor lo toma de
115
+ `.worktree-manager.conf` en la raíz del repositorio, o del archivo que se le
116
+ pase con `--config`, que debe existir y ser una ruta absoluta. Si se pasan
117
+ ambos, `--config` prevalece. Después, la variable de entorno
118
+ `WORKTREE_MANAGER_<CLAVE>`, con la clave en mayúsculas, reemplaza el valor
119
+ leído del archivo.
120
+
121
+ Las once claves y sus valores por defecto son:
122
+
123
+ | Clave | Por defecto | Restricción |
124
+ |---|---|---|
125
+ | `worktrees_dir` | `.worktrees` | No puede empezar por `-` |
126
+ | `branch_prefix` | `worktree/` | — |
127
+ | `state_dir` | `worktree-manager` | Ruta relativa segura |
128
+ | `backup_dir` | `backups` | No es una ruta absoluta y no contiene `..` |
129
+ | `backup_ref_prefix` | `worktree-manager/backups` | Sin `..` |
130
+ | `lock_dir` | `locks` | Ruta relativa segura |
131
+ | `prepare_command` | `''` (vacío) | Requerida cuando `prepare_enabled=true` |
132
+ | `verify_command` | `''` (vacío) | Requerida cuando `verify_enabled=true` |
133
+ | `prepare_enabled` | `false` | `true` o `false` |
134
+ | `verify_enabled` | `false` | `true` o `false` |
135
+ | `preserve_dirty` | `false` | `true` o `false` |
136
+
137
+ Cada clave puede aparecer una sola vez. Una clave desconocida, una línea sin
138
+ `=`, un booleano inválido o una ruta insegura se rechazan como
139
+ `invalid_configuration` con código de salida `3`, antes de cualquier efecto.
140
+
141
+ ## 5. Contratos de salida
142
+
143
+ - `--json` publica un único documento JSON con siete claves: `contract_version`,
144
+ `tool_version`, `operation`, `result`, `data`, `warnings` y `error`.
145
+ - `--request-json <archivo|->` publica el mismo documento de nueve claves que
146
+ usa el transporte MCP: las siete anteriores más `repository` y
147
+ `transaction_id`. Acepta `--json` de forma opcional y el documento publicado
148
+ no cambia.
149
+ - Un dry run de `create` publica `planned: true` y no crea worktree ni rama.
150
+ `init_submodules_result` es `planned` o `not_requested`, y `prepare` y
151
+ `verify` son `planned` o `skipped`.
152
+ - El servicio MCP se publica por stdio y expone siete herramientas. Desde el
153
+ paquete instalado se lanza sin bin:
154
+
155
+ ```sh
156
+ node <paquete>/mcp-server.mjs
157
+ ```
158
+
159
+ El `initialize` publica la guía en `instructions`:
160
+
161
+ ```text
162
+ Vas a implementar un cambio, ejecutar una spec o iniciar un flujo. ¿Quieres crear un worktree para hacerlo aislado?
163
+ ```
164
+
165
+ Para desarrollo, el transporte también arranca desde el checkout:
166
+
167
+ ```sh
168
+ PYTHONPATH=. python3 -m worktree_manager.mcp_transport
169
+ ```
170
+
171
+ ## 6. Pruebas
172
+
173
+ ```sh
174
+ bash tests/cli-usage.sh
175
+ bash tests/cli-json.sh
176
+ bash tests/compatibility.sh
177
+ bash tests/smoke.sh
178
+ bash tests/parity.sh
179
+ PYTHONPATH=. python3 -m unittest discover -s tests -p 'test_*.py'
180
+ PYTHONPATH=. python3 -m unittest discover -s tests -p 'test_mcp*.py' -v
181
+ ```
182
+
183
+ ## 7. Consumo como submódulo y coexistencia
184
+
185
+ Un repositorio consumidor puede materializar el gestor como submódulo. La
186
+ regla es única: el checkout materializado y el gitlink registrado deben ser el
187
+ mismo commit.
188
+
189
+ El paquete npm `worktree-for-agents` es independiente del submódulo: embarca
190
+ el runtime Python y funciona sin red una vez instalado. `node
191
+ <paquete>/setup.mjs` diagnostica qué instalación está activa cuando coexisten
192
+ el paquete npm, la copia global de FlowTask y el submódulo local. El clon del
193
+ repositorio queda solo para desarrollo y no se promete otra distribución.
194
+
195
+ ## 8. Solución de problemas
196
+
197
+ - **`python3` no está en el `PATH`.** El entrypoint termina con el código `127`
198
+ y el mensaje
199
+ `worktree manager requires Python 3 (python3) on PATH; install Python 3 and retry.`
200
+ - **Falta el punto de entrada del paquete.** El entrypoint termina con el
201
+ código `126` y el mensaje
202
+ `worktree manager Python entry point is missing: <ruta>/worktree_manager/__main__.py`.
203
+ - **La ruta del repositorio es relativa.** La operación se rechaza con el
204
+ código `invalid_repository`, el código de salida `3` y el mensaje
205
+ `Repository path must be absolute`.
206
+ - **La versión de Python es anterior a 3.9.** El instalador del consumidor lo
207
+ informa como `python <version> is older than the required 3.9`. El entrypoint
208
+ de este repositorio no comprueba la versión.
209
+
210
+ ## 9. Qué no cubre
211
+
212
+ Esta guía no cubre la integración con un consumidor: ni el adaptador, ni el
213
+ bridge, ni la validación del gitlink, ni el procedimiento de instalación del
214
+ consumidor. Eso se documenta en el repositorio consumidor.
@@ -0,0 +1,78 @@
1
+ # Worktree manager MCP service
2
+
3
+ The optional stdio service starts independently from the existing CLI:
4
+
5
+ ```sh
6
+ python3 -m worktree_manager.mcp_transport
7
+ ```
8
+
9
+ It implements JSON-RPC `initialize`, `ping`, `tools/list` and `tools/call` and
10
+ publishes exactly `worktree_create`, `worktree_complete`, `worktree_cleanup`,
11
+ `worktree_recover`, `worktree_list`, `worktree_prune` and `worktree_status`.
12
+ Each call requires an absolute existing Git repository path; the process
13
+ working directory is never used as a repository default. Unknown arguments
14
+ are rejected. Responses carry contract version 1, operation, repository,
15
+ result, data, warnings, structured error and a nullable transaction ID.
16
+
17
+ The `initialize` result carries `serverInfo.name "worktree-for-agents"` and
18
+ an `instructions` field with the literal guide text:
19
+
20
+ ```text
21
+ Vas a implementar un cambio, ejecutar una spec o iniciar un flujo. ¿Quieres crear un worktree para hacerlo aislado?
22
+ ```
23
+
24
+ When installed from npm, the service is launched without a bin entry via:
25
+
26
+ ```sh
27
+ node <package>/mcp-server.mjs
28
+ ```
29
+
30
+ A rejected call publishes the same nine-key envelope as an accepted one, with
31
+ `result` set to `failure` or `pending_intervention` and `error` carrying
32
+ `code`, `message` and `exit_code`. The command line publishes that identical
33
+ envelope for `--request-json`, so both transports can be read by one client.
34
+
35
+ `worktree_create` accepts the optional booleans `init_submodules`, `prepare`
36
+ and `verify`. They are off by default and report the observed state of each
37
+ step; `prepare` and `verify` require the matching configured command and are
38
+ rejected as `invalid_configuration` before any worktree or branch is created.
39
+
40
+ Mutating dry runs do not invoke lifecycle operations. A per-call authorization is
41
+ required only in an execution, that is, when `dry_run` is absent or `false`; a
42
+ dry run of a destructive operation succeeds without it. A destructive execute
43
+ accepts `authorization: "I_AUTHORIZE_THIS_CALL"` directly, or `confirm: true`,
44
+ from which that authorization is derived. A `confirm: false` sent together with
45
+ the literal is rejected as `authorization_mismatch`. A `cleanup` with a discard
46
+ additionally requires the separate boolean `discard_consent: true`. A
47
+ target-direct `create`, `complete` or `recover` has no safe simulation and is
48
+ rejected as `unsupported_dry_run` with exit code `3` when a dry run is
49
+ requested. Authorization is not retained across requests. Do not expose this
50
+ local service to untrusted clients. CLI JSON v1 and its entrypoint remain
51
+ unchanged.
52
+
53
+ ## End-to-end verification
54
+
55
+ Run the real stdio client tests from the repository root:
56
+
57
+ ```sh
58
+ PYTHONPATH=. python3 -m unittest discover -s tests -p 'test_mcp*.py' -v
59
+ MCP_E2E_EVIDENCE_DIR=<evidence-dir> \
60
+ PYTHONPATH=. python3 -m unittest discover -s tests -p 'test_mcp_e2e.py' -v
61
+ ```
62
+
63
+ `test_mcp_e2e.py` uses isolated temporary Git repositories and launches the
64
+ stdio server as a subprocess. It exercises discovery and every public tool,
65
+ dry-run immutability, authorization and separate discard consent, transaction
66
+ recovery, worktree/ref/index/status effects, plus MCP-vs-Python-CLI completion
67
+ on independent equivalent repositories. When `MCP_E2E_EVIDENCE_DIR` is set,
68
+ each test writes its request/response trace there as JSON. No evidence or Git
69
+ fixture is written into the checked-out repository by default.
70
+
71
+ ## Mensaje de cierre
72
+
73
+ `worktree_complete` acepta `commit_title` y `commit_body` (strings opcionales).
74
+ Se validan como strings y se incluyen en el plan hash solo para esta operacion.
75
+ El dry-run publica `commit_subject` y `commit_body` compuestos; execute los
76
+ pasa al lifecycle. Si faltan, el gestor usa el fallback neutro
77
+ `Complete <work_id> (generic closure)` / `No delivery description was available
78
+ at closure time.`.
package/mcp-server.mjs ADDED
@@ -0,0 +1,54 @@
1
+ import { spawn } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ import { dirname, join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ import { probePython } from "./scripts/python.mjs";
6
+
7
+ const packageDir = dirname(fileURLToPath(import.meta.url));
8
+ const transport = join(packageDir, "worktree_manager", "mcp_transport.py");
9
+ const entry = join(packageDir, "worktree_manager", "__main__.py");
10
+
11
+ if (!existsSync(transport)) {
12
+ process.stderr.write(
13
+ "worktree-for-agents is incomplete: missing worktree_manager/mcp_transport.py. Reinstall the package.\n"
14
+ );
15
+ process.exit(126);
16
+ }
17
+ if (!existsSync(entry)) {
18
+ process.stderr.write(
19
+ "worktree-for-agents is incomplete: missing worktree_manager/__main__.py. Reinstall the package.\n"
20
+ );
21
+ process.exit(126);
22
+ }
23
+
24
+ const probed = probePython();
25
+ if (!probed.version) {
26
+ process.stderr.write(
27
+ "worktree-for-agents requires Python 3.9 or later. Install Python 3.9+ and rerun the installation.\n"
28
+ );
29
+ process.exit(127);
30
+ }
31
+
32
+ const env = {
33
+ ...process.env,
34
+ PYTHONPATH: packageDir + (process.env.PYTHONPATH ? `:${process.env.PYTHONPATH}` : ""),
35
+ };
36
+ const child = spawn(probed.bin, ["-m", "worktree_manager.mcp_transport"], {
37
+ cwd: packageDir,
38
+ env,
39
+ stdio: "inherit",
40
+ });
41
+ const forward = (signal) => {
42
+ if (child.exitCode === null && child.signalCode === null) {
43
+ child.kill(signal);
44
+ }
45
+ };
46
+ process.on("SIGINT", () => forward("SIGINT"));
47
+ process.on("SIGTERM", () => forward("SIGTERM"));
48
+ child.on("exit", (code, signal) => {
49
+ if (signal) {
50
+ process.kill(process.pid, signal);
51
+ return;
52
+ }
53
+ process.exit(code === null ? 1 : code);
54
+ });
package/package.json CHANGED
@@ -1,6 +1,39 @@
1
1
  {
2
2
  "name": "worktree-for-agents",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "Standalone Git worktree manager with a stdio MCP service usable by any coding agent",
5
+ "type": "module",
6
+ "engines": {
7
+ "node": ">=18"
8
+ },
9
+ "files": [
10
+ "worktree.sh",
11
+ "worktree_manager/**/*.py",
12
+ "mcp-server.mjs",
13
+ "worktree.mjs",
14
+ "setup.mjs",
15
+ "GUIDE.md",
16
+ "README.md",
17
+ "docs/installation.md",
18
+ "docs/mcp-contract.md",
19
+ "scripts/python.mjs",
20
+ "scripts/postinstall.mjs"
21
+ ],
22
+ "scripts": {
23
+ "postinstall": "node scripts/postinstall.mjs",
24
+ "prepublishOnly": "node scripts/verify-package.mjs"
25
+ },
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/Saez520/worktree-manager.git"
32
+ },
33
+ "keywords": [
34
+ "git",
35
+ "worktree",
36
+ "mcp",
37
+ "coding-agent"
38
+ ]
39
+ }
@@ -0,0 +1,11 @@
1
+ import { probePython } from "./python.mjs";
2
+
3
+ const probed = probePython();
4
+ if (!probed.version) {
5
+ process.stderr.write(
6
+ "worktree-for-agents requires Python 3.9 or later. Install Python 3.9+ and rerun the installation.\n"
7
+ );
8
+ process.exit(1);
9
+ }
10
+ process.stdout.write(`worktree-for-agents: Python ${probed.version} (${probed.bin})\n`);
11
+ process.stdout.write("Next: node <package>/setup.mjs\n");