repo-harness 0.2.0 → 0.2.2
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.es.md +35 -17
- package/README.fr.md +39 -16
- package/README.ja.md +30 -14
- package/README.md +59 -16
- package/README.zh-CN.md +51 -17
- package/assets/hooks/post-edit-guard.sh +3 -1
- package/assets/hooks/prompt-guard.sh +54 -1
- package/assets/templates/helpers/sync-brain-docs.sh +25 -2
- package/package.json +1 -1
- package/scripts/setup-plugins.sh +13 -5
- package/scripts/sync-brain-docs.sh +25 -2
- package/src/cli/commands/global-runtime.ts +83 -0
- package/src/cli/commands/init.ts +5 -4
- package/src/cli/commands/status.ts +1 -1
- package/src/cli/index.ts +43 -4
package/README.es.md
CHANGED
|
@@ -34,14 +34,23 @@ repo-local que él mismo genera para los proyectos downstream.
|
|
|
34
34
|
1KB o consulta el índice, en vez de gastar miles de tokens redescubriendo la
|
|
35
35
|
estructura.
|
|
36
36
|
|
|
37
|
-
## Novedades en 0.2.
|
|
37
|
+
## Novedades en 0.2.1
|
|
38
38
|
|
|
39
|
-
- **
|
|
40
|
-
|
|
39
|
+
- **Comando de inicialización global (`repo-harness init`).** Un solo comando
|
|
40
|
+
inicializa el entorno global de Claude: essential plugins, policy
|
|
41
41
|
hooks configurables (worktree guard, atomic commit/pending), LSP plugins
|
|
42
42
|
opcionales según el tipo de proyecto y cuatro hook profiles (`standard`,
|
|
43
43
|
`minimal`, `biome`, `biome-strict`). Ejecuta
|
|
44
|
-
`
|
|
44
|
+
`npx -y repo-harness init`; no necesitas clonar el repositorio fuente.
|
|
45
|
+
- **Comando de refresco del repo (`repo-harness update`).** La instalación y el
|
|
46
|
+
refresco de repos existentes tienen su propia superficie de comando, manteniendo
|
|
47
|
+
la ruta de migración repo-local anterior mientras `init` queda dedicado al
|
|
48
|
+
runtime global.
|
|
49
|
+
- **Auto-recuperación del índice CodeGraph.** Si el prompt hook detecta intención
|
|
50
|
+
de navegación estructural y el repo no tiene índice `.codegraph`, inicializa el
|
|
51
|
+
índice con el binario CodeGraph local o visible en PATH antes de emitir la pista.
|
|
52
|
+
Sigue siendo advisory: no instala dependencias, no ejecuta el readiness probe
|
|
53
|
+
pesado y no bloquea el prompt si CodeGraph no está disponible.
|
|
45
54
|
- **Centinela de seguridad (`repo-harness security scan` + `security-sentinel.sh`).**
|
|
46
55
|
Una verificación de solo lectura sobre las superficies de inyección de
|
|
47
56
|
configuración de alto valor (`~/.claude/settings.json`, `~/.codex/hooks.json`,
|
|
@@ -91,7 +100,7 @@ En conjunto hay tres capas:
|
|
|
91
100
|
1. **Capa del paquete fuente**: este repositorio mantiene la CLI, los command
|
|
92
101
|
skill facades, los templates, los hook assets, el workflow contract, los tests
|
|
93
102
|
y el release gate.
|
|
94
|
-
2. **Capa del contract del repositorio objetivo**: `repo-harness
|
|
103
|
+
2. **Capa del contract del repositorio objetivo**: `repo-harness update` o la
|
|
95
104
|
migración escribe `docs/spec.md`, `plans/`, `tasks/`, `.ai/context/`,
|
|
96
105
|
`.ai/harness/`, helper scripts y `.ai/hooks/`.
|
|
97
106
|
3. **Capa del host adapter**: el `~/.claude/settings.json` y el
|
|
@@ -178,14 +187,13 @@ npx -y repo-harness init
|
|
|
178
187
|
```
|
|
179
188
|
|
|
180
189
|
La npm package release line es ahora `0.2.x`; el workflow compatibility model line
|
|
181
|
-
generado se rastrea por separado como `5.x`. `repo-harness@0.2.
|
|
182
|
-
global
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
que usa el maintainer antes de publicar en npm.
|
|
190
|
+
generado se rastrea por separado como `5.x`. `repo-harness@0.2.1` separa el
|
|
191
|
+
bootstrap global inicial (`repo-harness init`) del refresco repo-local
|
|
192
|
+
(`repo-harness update`), conserva el instalador global de plugin/hook
|
|
193
|
+
(`scripts/setup-plugins.sh`), el centinela de seguridad de configuración de solo
|
|
194
|
+
lectura (`repo-harness security scan`), el ciclo de vida draft-plan explícito de
|
|
195
|
+
Claude/Codex y añade inicialización no bloqueante del índice CodeGraph para el
|
|
196
|
+
routing estructural de prompts.
|
|
189
197
|
|
|
190
198
|
Si trabajas desde un checkout del código fuente:
|
|
191
199
|
|
|
@@ -220,13 +228,13 @@ del runtime `project-initializer` ya retirado los limpia
|
|
|
220
228
|
En un repositorio existente, ejecuta desde el repo root:
|
|
221
229
|
|
|
222
230
|
```bash
|
|
223
|
-
npx -y repo-harness
|
|
231
|
+
npx -y repo-harness update --dry-run
|
|
224
232
|
```
|
|
225
233
|
|
|
226
234
|
Aplica solo después de que el reporte del dry-run sea correcto:
|
|
227
235
|
|
|
228
236
|
```bash
|
|
229
|
-
npx -y repo-harness
|
|
237
|
+
npx -y repo-harness update
|
|
230
238
|
```
|
|
231
239
|
|
|
232
240
|
Para un proyecto o módulo nuevo, usa el command skill `repo-harness-scaffold`. Para
|
|
@@ -263,6 +271,15 @@ Si la salida del dry-run no es correcta, detente aquí primero y lee
|
|
|
263
271
|
- Codex debe confiar en `~/.codex/hooks.json` en sus Settings para que los hooks se ejecuten.
|
|
264
272
|
- Orden de depuración: user-level adapter config -> `repo-harness-hook` o el fallback `repo-harness hook` -> route registry -> `.ai/hooks/*`.
|
|
265
273
|
|
|
274
|
+
`SessionStart` ejecuta dos scripts ordenados antes de empezar el trabajo:
|
|
275
|
+
|
|
276
|
+
```mermaid
|
|
277
|
+
flowchart LR
|
|
278
|
+
SessionStart["Claude/Codex SessionStart"] --> Ctx["session-start-context.sh<br/>contexto de resume + handoff"]
|
|
279
|
+
Ctx --> Sec["security-sentinel.sh<br/>escaneo de configuración de solo lectura, fingerprint-gated"]
|
|
280
|
+
Sec --> SSOut["SessionStart additionalContext<br/>estado de la sesión anterior + hallazgos de SecurityConfig"]
|
|
281
|
+
```
|
|
282
|
+
|
|
266
283
|
El prompt guard tiene un paso interno adicional:
|
|
267
284
|
|
|
268
285
|
```mermaid
|
|
@@ -274,6 +291,7 @@ flowchart LR
|
|
|
274
291
|
Shell --> Decision["repo-harness-hook prompt-guard-decide<br/>TypeScript decision table"]
|
|
275
292
|
Decision --> Action["single action enum"]
|
|
276
293
|
Action --> Shell
|
|
294
|
+
Shell --> RouteHint["Waza route hint<br/>think/planning explícito coincide primero → /think"]
|
|
277
295
|
Shell --> HostOutput["host-safe allow, advice, block, or done gate output"]
|
|
278
296
|
```
|
|
279
297
|
|
|
@@ -310,7 +328,7 @@ Guards habituales:
|
|
|
310
328
|
|
|
311
329
|
## Release actual
|
|
312
330
|
|
|
313
|
-
- npm package: `repo-harness@0.2.
|
|
331
|
+
- npm package: `repo-harness@0.2.1`
|
|
314
332
|
- Generated workflow compatibility: `5.2.3`
|
|
315
333
|
- GitHub repository: `Ancienttwo/repo-harness`
|
|
316
334
|
- Release history: [`docs/CHANGELOG.md`](docs/CHANGELOG.md)
|
|
@@ -325,7 +343,7 @@ Guards habituales:
|
|
|
325
343
|
- `assets/workflow-contract.v1.json`
|
|
326
344
|
- Los generated repos usan por defecto el repo-local harness flow:
|
|
327
345
|
- `docs/spec.md -> plans/ -> tasks/contracts/ -> tasks/reviews/ -> .ai/context/context-map.json -> .ai/harness/*`
|
|
328
|
-
- `repo-harness
|
|
346
|
+
- `repo-harness update` refresca las runtime pieces:
|
|
329
347
|
- los `repo-harness` skill aliases
|
|
330
348
|
- los global Codex/Claude hook adapters
|
|
331
349
|
- las Waza skills: `check`, `design`, `health`, `hunt`, `learn`, `read`, `think`, `write`
|
package/README.fr.md
CHANGED
|
@@ -34,14 +34,24 @@ workflow repo-local qu'il génère lui-même pour les projets en aval.
|
|
|
34
34
|
1 Ko ou interroge l'index, au lieu de dépenser des milliers de tokens à
|
|
35
35
|
redécouvrir la structure.
|
|
36
36
|
|
|
37
|
-
## Nouveautés de la 0.2.
|
|
37
|
+
## Nouveautés de la 0.2.1
|
|
38
38
|
|
|
39
|
-
- **
|
|
40
|
-
|
|
39
|
+
- **Commande d'initialisation globale (`repo-harness init`).** Une seule commande
|
|
40
|
+
amorce l'environnement Claude global : essential plugins,
|
|
41
41
|
policy hooks configurables (worktree guard, atomic commit/pending), LSP plugins
|
|
42
42
|
optionnels selon le type de projet, et quatre hook profiles (`standard`,
|
|
43
43
|
`minimal`, `biome`, `biome-strict`). Exécutez
|
|
44
|
-
`
|
|
44
|
+
`npx -y repo-harness init` ; aucun clone du dépôt source n'est nécessaire.
|
|
45
|
+
- **Commande de rafraîchissement du dépôt (`repo-harness update`).** L'installation
|
|
46
|
+
et le rafraîchissement des dépôts existants ont leur propre surface de commande,
|
|
47
|
+
tout en conservant l'ancien chemin de migration repo-local et en gardant `init`
|
|
48
|
+
dédié au runtime global.
|
|
49
|
+
- **Auto-réparation de l'index CodeGraph.** Quand le prompt hook détecte une
|
|
50
|
+
intention de navigation structurelle et que le dépôt n'a pas d'index
|
|
51
|
+
`.codegraph`, il initialise l'index avec le binaire CodeGraph local ou visible
|
|
52
|
+
dans PATH avant d'émettre l'indication de route. Cela reste advisory : pas
|
|
53
|
+
d'installation de dépendances, pas de readiness probe lourd, et pas de blocage
|
|
54
|
+
du prompt si CodeGraph est indisponible.
|
|
45
55
|
- **Sentinelle de sécurité (`repo-harness security scan` +
|
|
46
56
|
`security-sentinel.sh`).** Une vérification en lecture seule sur les surfaces
|
|
47
57
|
d'injection de configuration à forte valeur (`~/.claude/settings.json`,
|
|
@@ -92,7 +102,7 @@ L'ensemble se découpe en trois couches :
|
|
|
92
102
|
1. **Couche package source** : ce dépôt maintient le CLI, les command skill
|
|
93
103
|
facades, les templates, les hook assets, le workflow contract, les tests et le
|
|
94
104
|
release gate.
|
|
95
|
-
2. **Couche contrat du dépôt cible** : `repo-harness
|
|
105
|
+
2. **Couche contrat du dépôt cible** : `repo-harness update` ou une migration écrit
|
|
96
106
|
`docs/spec.md`, `plans/`, `tasks/`, `.ai/context/`, `.ai/harness/`, les helper
|
|
97
107
|
scripts et `.ai/hooks/`.
|
|
98
108
|
3. **Couche host adapter** : les `~/.claude/settings.json` et `~/.codex/hooks.json`
|
|
@@ -181,13 +191,16 @@ npx -y repo-harness init
|
|
|
181
191
|
```
|
|
182
192
|
|
|
183
193
|
La release line du package npm est désormais `0.2.x` ; la generated workflow
|
|
184
|
-
compatibility model line est suivie séparément en `5.x`. `repo-harness@0.2.
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
(`
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
194
|
+
compatibility model line est suivie séparément en `5.x`. `repo-harness@0.2.1`
|
|
195
|
+
sépare le bootstrap global initial (`repo-harness init`) du rafraîchissement
|
|
196
|
+
repo-local (`repo-harness update`), conserve l'installateur global de plugin/hook
|
|
197
|
+
(`scripts/setup-plugins.sh`), la sentinelle de sécurité en lecture seule
|
|
198
|
+
(`repo-harness security scan`), le cycle de vie draft-plan explicite de
|
|
199
|
+
Claude/Codex, et ajoute l'initialisation non bloquante de l'index CodeGraph pour
|
|
200
|
+
le routing structurel des prompts. Ces capacités reposent sur le CLI renommé, le
|
|
201
|
+
bootstrap de l'adapter de hook de niveau utilisateur, les AI-native scaffold
|
|
202
|
+
overlays, le typed prompt-guard decision engine, le nommage des task artifacts par
|
|
203
|
+
plan-stem, les runtime aliases
|
|
191
204
|
`REPO_HARNESS_*`, la Waza runtime skill sync, et le release gate que le maintainer
|
|
192
205
|
utilise avant de publier sur npm.
|
|
193
206
|
|
|
@@ -224,13 +237,13 @@ répertoires du runtime `project-initializer` retiré sont nettoyés par
|
|
|
224
237
|
Pour un dépôt existant, exécutez depuis le repo root :
|
|
225
238
|
|
|
226
239
|
```bash
|
|
227
|
-
npx -y repo-harness
|
|
240
|
+
npx -y repo-harness update --dry-run
|
|
228
241
|
```
|
|
229
242
|
|
|
230
243
|
Appliquez seulement une fois que le rapport du dry-run est correct :
|
|
231
244
|
|
|
232
245
|
```bash
|
|
233
|
-
npx -y repo-harness
|
|
246
|
+
npx -y repo-harness update
|
|
234
247
|
```
|
|
235
248
|
|
|
236
249
|
Pour un nouveau projet ou un nouveau module, utilisez la command skill
|
|
@@ -267,6 +280,15 @@ Si la sortie du dry-run est incorrecte, arrêtez-vous ici et lisez
|
|
|
267
280
|
- Codex doit faire confiance à `~/.codex/hooks.json` dans Settings pour que les hooks s'exécutent.
|
|
268
281
|
- Ordre de débogage : user-level adapter config -> `repo-harness-hook` ou fallback `repo-harness hook` -> route registry -> `.ai/hooks/*`.
|
|
269
282
|
|
|
283
|
+
`SessionStart` exécute deux scripts ordonnés avant le début du travail :
|
|
284
|
+
|
|
285
|
+
```mermaid
|
|
286
|
+
flowchart LR
|
|
287
|
+
SessionStart["Claude/Codex SessionStart"] --> Ctx["session-start-context.sh<br/>resume + handoff context"]
|
|
288
|
+
Ctx --> Sec["security-sentinel.sh<br/>read-only config scan, fingerprint-gated"]
|
|
289
|
+
Sec --> SSOut["SessionStart additionalContext<br/>prior-session state + SecurityConfig findings"]
|
|
290
|
+
```
|
|
291
|
+
|
|
270
292
|
Le prompt guard ajoute une étape interne supplémentaire :
|
|
271
293
|
|
|
272
294
|
```mermaid
|
|
@@ -278,6 +300,7 @@ flowchart LR
|
|
|
278
300
|
Shell --> Decision["repo-harness-hook prompt-guard-decide<br/>TypeScript decision table"]
|
|
279
301
|
Decision --> Action["single action enum"]
|
|
280
302
|
Action --> Shell
|
|
303
|
+
Shell --> RouteHint["Waza route hint<br/>explicit think/planning matched first → /think"]
|
|
281
304
|
Shell --> HostOutput["host-safe allow, advice, block, or done gate output"]
|
|
282
305
|
```
|
|
283
306
|
|
|
@@ -314,7 +337,7 @@ Guards courants :
|
|
|
314
337
|
|
|
315
338
|
## Release actuelle
|
|
316
339
|
|
|
317
|
-
- npm package : `repo-harness@0.2.
|
|
340
|
+
- npm package : `repo-harness@0.2.1`
|
|
318
341
|
- Generated workflow compatibility : `5.2.3`
|
|
319
342
|
- GitHub repository : `Ancienttwo/repo-harness`
|
|
320
343
|
- Release history : [`docs/CHANGELOG.md`](docs/CHANGELOG.md)
|
|
@@ -329,7 +352,7 @@ Guards courants :
|
|
|
329
352
|
- `assets/workflow-contract.v1.json`
|
|
330
353
|
- Les generated repos utilisent par défaut le repo-local harness flow :
|
|
331
354
|
- `docs/spec.md -> plans/ -> tasks/contracts/ -> tasks/reviews/ -> .ai/context/context-map.json -> .ai/harness/*`
|
|
332
|
-
- `repo-harness
|
|
355
|
+
- `repo-harness update` rafraîchit les runtime pieces :
|
|
333
356
|
- les `repo-harness` skill aliases
|
|
334
357
|
- les global Codex/Claude hook adapters
|
|
335
358
|
- les Waza skills : `check`, `design`, `health`, `hunt`, `learn`, `read`, `think`, `write`
|
package/README.ja.md
CHANGED
|
@@ -27,13 +27,20 @@ skill runtime を提供します。
|
|
|
27
27
|
触ったときだけ読み込まれる capability ブロックが加わる構成です。agent は構造を把握し直すために数千
|
|
28
28
|
token を費やすのではなく、1KB の capability contract を読むか index に問い合わせます。
|
|
29
29
|
|
|
30
|
-
## 0.2.
|
|
30
|
+
## 0.2.1 の新機能
|
|
31
31
|
|
|
32
|
-
-
|
|
32
|
+
- **Global init コマンド(`repo-harness init`)。** グローバルな Claude 環境を
|
|
33
33
|
1 コマンドで完了します。essential plugins、設定可能な policy hooks(worktree guard、atomic
|
|
34
34
|
commit/pending)、プロジェクト種別ごとのオプション LSP plugins、そして 4 段階の hook profile
|
|
35
35
|
(`standard`、`minimal`、`biome`、`biome-strict`)を扱います。
|
|
36
|
-
実行は `
|
|
36
|
+
実行は `npx -y repo-harness init`。source checkout は不要です。
|
|
37
|
+
- **Repo refresh コマンド(`repo-harness update`)。** 既存 repo の install / refresh は
|
|
38
|
+
独立した command surface になり、従来の repo-local migration path を保ちながら
|
|
39
|
+
`init` は global runtime setup に集中します。
|
|
40
|
+
- **CodeGraph index の自己修復。** prompt hook が構造的な code-navigation intent を検出し、
|
|
41
|
+
repo に `.codegraph` index がない場合、route hint を出す前に repo-local または PATH 上の
|
|
42
|
+
CodeGraph binary で index を初期化します。これは advisory のままで、依存関係の install や
|
|
43
|
+
重い readiness probe は実行せず、CodeGraph が使えない場合も prompt を block しません。
|
|
37
44
|
- **セキュリティ哨兵(`repo-harness security scan` + `security-sentinel.sh`)。** 高価値の設定インジェクション面
|
|
38
45
|
(`~/.claude/settings.json`、`~/.codex/hooks.json`、repo-local の `.vscode/tasks.json`、そして legacy な
|
|
39
46
|
プロジェクトレベルの `.claude`/`.codex` adapter)に対する読み取り専用のチェックです。危険なコマンド
|
|
@@ -72,7 +79,7 @@ product boundary は意図的に地味です。対象リポジトリを検査し
|
|
|
72
79
|
|
|
73
80
|
1. **ソースパッケージ層**:本リポジトリが CLI、command skill facades、templates、hook assets、
|
|
74
81
|
workflow contract、tests、release gate を所有します。
|
|
75
|
-
2. **対象リポジトリ contract 層**:`repo-harness
|
|
82
|
+
2. **対象リポジトリ contract 層**:`repo-harness update` または migration が、`docs/spec.md`、
|
|
76
83
|
`plans/`、`tasks/`、`.ai/context/`、`.ai/harness/`、helper scripts、`.ai/hooks/` といった
|
|
77
84
|
repo-local ファイルを書き込みます。
|
|
78
85
|
3. **Host adapter 層**:user-level の `~/.claude/settings.json` と `~/.codex/hooks.json` が
|
|
@@ -153,12 +160,11 @@ npx -y repo-harness init
|
|
|
153
160
|
```
|
|
154
161
|
|
|
155
162
|
npm package の release line は現在 `0.2.x` です。生成される workflow compatibility model line は
|
|
156
|
-
別途 `5.x` として追跡されます。`repo-harness@0.2.
|
|
157
|
-
(`
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
使う release gate の上に追加します。
|
|
163
|
+
別途 `5.x` として追跡されます。`repo-harness@0.2.1` は、初回 global bootstrap
|
|
164
|
+
(`repo-harness init`)と repo-local refresh(`repo-harness update`)を分離し、グローバルな
|
|
165
|
+
plugin/hook インストールスクリプト(`scripts/setup-plugins.sh`)、読み取り専用の設定セキュリティ哨兵
|
|
166
|
+
(`repo-harness security scan`)、明示的な Claude/Codex draft-plan ライフサイクルを保ち、
|
|
167
|
+
構造的 prompt routing 用の非ブロッキング CodeGraph index 初期化を追加します。
|
|
162
168
|
|
|
163
169
|
ソースの checkout から作業する場合:
|
|
164
170
|
|
|
@@ -191,13 +197,13 @@ symlink に裏打ちされた runtime entrypoint です。退役した `project-
|
|
|
191
197
|
既存リポジトリでは repo root から実行します。
|
|
192
198
|
|
|
193
199
|
```bash
|
|
194
|
-
npx -y repo-harness
|
|
200
|
+
npx -y repo-harness update --dry-run
|
|
195
201
|
```
|
|
196
202
|
|
|
197
203
|
dry-run のレポートが正しいことを確認してから適用します。
|
|
198
204
|
|
|
199
205
|
```bash
|
|
200
|
-
npx -y repo-harness
|
|
206
|
+
npx -y repo-harness update
|
|
201
207
|
```
|
|
202
208
|
|
|
203
209
|
新しいプロジェクトやモジュールには `repo-harness-scaffold` command skill を使います。既存リポジトリには
|
|
@@ -234,6 +240,15 @@ dry-run の出力がおかしい場合は、ここで一旦止め、
|
|
|
234
240
|
- Codex は Settings で `~/.codex/hooks.json` を信頼済みにしないと、hooks は実行されません。
|
|
235
241
|
- デバッグの順序:user-level adapter config -> `repo-harness-hook` または fallback の `repo-harness hook` -> route registry -> `.ai/hooks/*`。
|
|
236
242
|
|
|
243
|
+
`SessionStart` は作業開始前に 2 つの script を順番に実行します。
|
|
244
|
+
|
|
245
|
+
```mermaid
|
|
246
|
+
flowchart LR
|
|
247
|
+
SessionStart["Claude/Codex SessionStart"] --> Ctx["session-start-context.sh<br/>resume + handoff context"]
|
|
248
|
+
Ctx --> Sec["security-sentinel.sh<br/>read-only config scan, fingerprint-gated"]
|
|
249
|
+
Sec --> SSOut["SessionStart additionalContext<br/>prior-session state + SecurityConfig findings"]
|
|
250
|
+
```
|
|
251
|
+
|
|
237
252
|
Prompt guard には内部ステップが 1 つ増えます。
|
|
238
253
|
|
|
239
254
|
```mermaid
|
|
@@ -245,6 +260,7 @@ flowchart LR
|
|
|
245
260
|
Shell --> Decision["repo-harness-hook prompt-guard-decide<br/>TypeScript decision table"]
|
|
246
261
|
Decision --> Action["single action enum"]
|
|
247
262
|
Action --> Shell
|
|
263
|
+
Shell --> RouteHint["Waza route hint<br/>explicit think/planning matched first → /think"]
|
|
248
264
|
Shell --> HostOutput["host-safe allow, advice, block, or done gate output"]
|
|
249
265
|
```
|
|
250
266
|
|
|
@@ -279,7 +295,7 @@ hook がブロックしたときは、まず terminal の構造化された出
|
|
|
279
295
|
|
|
280
296
|
## 現在の Release
|
|
281
297
|
|
|
282
|
-
- npm package:`repo-harness@0.2.
|
|
298
|
+
- npm package:`repo-harness@0.2.1`
|
|
283
299
|
- Generated workflow compatibility:`5.2.3`
|
|
284
300
|
- GitHub repository:`Ancienttwo/repo-harness`
|
|
285
301
|
- Release history:[`docs/CHANGELOG.md`](docs/CHANGELOG.md)
|
|
@@ -294,7 +310,7 @@ hook がブロックしたときは、まず terminal の構造化された出
|
|
|
294
310
|
- `assets/workflow-contract.v1.json`
|
|
295
311
|
- Generated repos はデフォルトで repo-local harness flow を使います:
|
|
296
312
|
- `docs/spec.md -> plans/ -> tasks/contracts/ -> tasks/reviews/ -> .ai/context/context-map.json -> .ai/harness/*`
|
|
297
|
-
- `repo-harness
|
|
313
|
+
- `repo-harness update` は runtime pieces をリフレッシュします:
|
|
298
314
|
- `repo-harness` skill aliases
|
|
299
315
|
- global Codex/Claude hook adapters
|
|
300
316
|
- Waza skills:`check`、`design`、`health`、`hunt`、`learn`、`read`、`think`、`write`
|
package/README.md
CHANGED
|
@@ -34,13 +34,25 @@ This repository now dogfoods its own tasks-first contract. It is both:
|
|
|
34
34
|
read a 1KB capability contract or query the index instead of spending thousands of
|
|
35
35
|
tokens rediscovering structure.
|
|
36
36
|
|
|
37
|
-
## What's New in 0.2.
|
|
37
|
+
## What's New in 0.2.2
|
|
38
38
|
|
|
39
|
-
- **
|
|
39
|
+
- **Safer global init defaults.** `repo-harness init` now streams setup progress
|
|
40
|
+
directly to the terminal and no longer installs the Superpowers Claude
|
|
41
|
+
marketplace plugin by default. Use `repo-harness init --with-superpowers` only
|
|
42
|
+
when you explicitly want that marketplace plugin.
|
|
43
|
+
- **Global init command (`repo-harness init`).** One command bootstraps the global
|
|
40
44
|
Claude environment: essential plugins, configurable policy hooks (worktree guard,
|
|
41
45
|
atomic commit/pending), optional LSP plugins by project type, and four hook profiles
|
|
42
46
|
(`standard`, `minimal`, `biome`, `biome-strict`).
|
|
43
|
-
Run `
|
|
47
|
+
Run `npx -y repo-harness init`; no source checkout is required.
|
|
48
|
+
- **Repo refresh command (`repo-harness update`).** Existing-repo install and
|
|
49
|
+
refresh now has its own command surface, preserving the previous repo-local
|
|
50
|
+
harness migration path while keeping `init` focused on global runtime setup.
|
|
51
|
+
- **CodeGraph index self-heal.** When the prompt hook detects structural
|
|
52
|
+
code-navigation intent and the repo has no `.codegraph` index, it initializes
|
|
53
|
+
the index with the local or PATH-visible CodeGraph binary before emitting the
|
|
54
|
+
route hint. This remains advisory: no dependency install, no heavy readiness
|
|
55
|
+
probe, and no prompt block if CodeGraph is unavailable.
|
|
44
56
|
- **Security sentinel (`repo-harness security scan` + `security-sentinel.sh`).** A
|
|
45
57
|
read-only check over high-value config injection surfaces (`~/.claude/settings.json`,
|
|
46
58
|
`~/.codex/hooks.json`, repo-local `.vscode/tasks.json`, and legacy project-level
|
|
@@ -81,7 +93,7 @@ The design has three layers:
|
|
|
81
93
|
|
|
82
94
|
1. **Source package**: this repository owns the CLI, command skill facades,
|
|
83
95
|
templates, hook assets, workflow contract, tests, and release gate.
|
|
84
|
-
2. **Target repo contract**: `repo-harness
|
|
96
|
+
2. **Target repo contract**: `repo-harness update` or migration writes repo-local
|
|
85
97
|
files such as `docs/spec.md`, `plans/`, `tasks/`, `.ai/context/`,
|
|
86
98
|
`.ai/harness/`, helper scripts, and `.ai/hooks/`.
|
|
87
99
|
3. **Host adapters**: user-level `~/.claude/settings.json` and
|
|
@@ -159,26 +171,47 @@ flowchart TD
|
|
|
159
171
|
This is the fastest path for an AI tooling owner evaluating whether the workflow is
|
|
160
172
|
safe to adopt in a real repo.
|
|
161
173
|
|
|
162
|
-
###
|
|
174
|
+
### Initial bootstrap
|
|
163
175
|
|
|
164
176
|
```bash
|
|
165
177
|
npx -y repo-harness init
|
|
166
178
|
```
|
|
167
179
|
|
|
180
|
+
`init` is the first-run global bootstrap path. It runs the packaged
|
|
181
|
+
`scripts/setup-plugins.sh`, installs global Claude plugins and hook profiles, and
|
|
182
|
+
defaults to `--hooks standard`. Use `--hooks <profile>` or `--no-hooks` when you
|
|
183
|
+
need a different hook profile.
|
|
184
|
+
|
|
185
|
+
### Install or refresh a repo-local harness
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
npx -y repo-harness update --dry-run
|
|
189
|
+
npx -y repo-harness update
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
`update` is the existing-repo install and refresh path. Run it from a target
|
|
193
|
+
repository to install or refresh workflow files, hook assets, host adapters,
|
|
194
|
+
skill aliases, and repo-local verification surfaces from the current npm package.
|
|
195
|
+
|
|
168
196
|
The npm package release line is now `0.2.x`; generated workflow compatibility is
|
|
169
|
-
tracked separately as the `5.x` model line. The `0.2.
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
197
|
+
tracked separately as the `5.x` model line. The `0.2.2` package splits first-run
|
|
198
|
+
global bootstrap (`repo-harness init`) from repo-local refresh
|
|
199
|
+
(`repo-harness update`), keeps the global plugin/hook installer
|
|
200
|
+
(`scripts/setup-plugins.sh`), the read-only config security sentinel
|
|
201
|
+
(`repo-harness security scan`), the explicit Claude/Codex draft-plan lifecycle,
|
|
202
|
+
adds non-blocking CodeGraph index initialization for structural prompt routing,
|
|
203
|
+
and keeps Superpowers behind the explicit `--with-superpowers` opt-in flag.
|
|
204
|
+
These sit on top of the renamed `repo-harness` CLI, user-level hook
|
|
173
205
|
adapter bootstrap, AI-native scaffold overlays, the typed prompt-guard decision
|
|
174
206
|
engine, plan-stem task artifact naming, `REPO_HARNESS_*` runtime aliases, Waza
|
|
175
|
-
runtime skill sync, and the maintainer release gate.
|
|
176
|
-
|
|
207
|
+
runtime skill sync, and the maintainer release gate.
|
|
208
|
+
|
|
209
|
+
Only maintainers editing the package need a source checkout:
|
|
177
210
|
|
|
178
211
|
```bash
|
|
179
212
|
git clone https://github.com/Ancienttwo/repo-harness.git ~/Projects/repo-harness
|
|
180
213
|
cd ~/Projects/repo-harness
|
|
181
|
-
bun src/cli/index.ts
|
|
214
|
+
bun src/cli/index.ts update
|
|
182
215
|
```
|
|
183
216
|
|
|
184
217
|
Local path model:
|
|
@@ -208,13 +241,13 @@ The retired `project-initializer` directories under `~/.codex/skills` and
|
|
|
208
241
|
For an existing repo, run from the repo root:
|
|
209
242
|
|
|
210
243
|
```bash
|
|
211
|
-
npx -y repo-harness
|
|
244
|
+
npx -y repo-harness update --dry-run
|
|
212
245
|
```
|
|
213
246
|
|
|
214
247
|
Apply only after the dry-run report looks correct:
|
|
215
248
|
|
|
216
249
|
```bash
|
|
217
|
-
npx -y repo-harness
|
|
250
|
+
npx -y repo-harness update
|
|
218
251
|
```
|
|
219
252
|
|
|
220
253
|
For a new project or module, use the `repo-harness-scaffold` command skill. For
|
|
@@ -252,6 +285,15 @@ before applying anything.
|
|
|
252
285
|
- Codex must mark `~/.codex/hooks.json` as trusted in Codex Settings before those hooks run.
|
|
253
286
|
- Debug in this order: user-level adapter config -> `repo-harness-hook` (or fallback `repo-harness hook`) -> route registry -> `.ai/hooks/*`.
|
|
254
287
|
|
|
288
|
+
`SessionStart` runs two ordered scripts before work begins:
|
|
289
|
+
|
|
290
|
+
```mermaid
|
|
291
|
+
flowchart LR
|
|
292
|
+
SessionStart["Claude/Codex SessionStart"] --> Ctx["session-start-context.sh<br/>resume + handoff context"]
|
|
293
|
+
Ctx --> Sec["security-sentinel.sh<br/>read-only config scan, fingerprint-gated"]
|
|
294
|
+
Sec --> SSOut["SessionStart additionalContext<br/>prior-session state + SecurityConfig findings"]
|
|
295
|
+
```
|
|
296
|
+
|
|
255
297
|
Prompt guard has one extra internal step:
|
|
256
298
|
|
|
257
299
|
```mermaid
|
|
@@ -263,6 +305,7 @@ flowchart LR
|
|
|
263
305
|
Shell --> Decision["repo-harness-hook prompt-guard-decide<br/>TypeScript decision table"]
|
|
264
306
|
Decision --> Action["single action enum"]
|
|
265
307
|
Action --> Shell
|
|
308
|
+
Shell --> RouteHint["Waza route hint<br/>explicit think/planning matched first → /think"]
|
|
266
309
|
Shell --> HostOutput["host-safe allow, advice, block, or done gate output"]
|
|
267
310
|
```
|
|
268
311
|
|
|
@@ -297,7 +340,7 @@ Most common guards:
|
|
|
297
340
|
|
|
298
341
|
## Current Release
|
|
299
342
|
|
|
300
|
-
- npm package: `repo-harness@0.2.
|
|
343
|
+
- npm package: `repo-harness@0.2.2`
|
|
301
344
|
- Generated workflow compatibility: `5.2.3`
|
|
302
345
|
- GitHub repository: `Ancienttwo/repo-harness`
|
|
303
346
|
- Release history: [`docs/CHANGELOG.md`](docs/CHANGELOG.md)
|
|
@@ -328,7 +371,7 @@ Most common guards:
|
|
|
328
371
|
- `complex -> gstack`
|
|
329
372
|
- `simple -> Waza` with Codex-first runtime copies in `~/.codex/skills`
|
|
330
373
|
- `knowledge -> gbrain`
|
|
331
|
-
- `repo-harness
|
|
374
|
+
- `repo-harness update` bootstraps the Codex/Claude runtime pieces needed for the
|
|
332
375
|
default workflow:
|
|
333
376
|
- refreshes `repo-harness` skill aliases
|
|
334
377
|
- installs global Codex/Claude hook adapters
|
package/README.zh-CN.md
CHANGED
|
@@ -23,12 +23,20 @@ repo-local workflow 的自托管样例。
|
|
|
23
23
|
做渐进式上下文加载:一份小而稳定的 root context(约 12KB),加上只在改到对应文件时才加载的
|
|
24
24
|
capability 块。agent 读一份 1KB 的 capability 合约或查索引,而不是花上千 token 重新摸清结构。
|
|
25
25
|
|
|
26
|
-
## 0.2.
|
|
26
|
+
## 0.2.2 新特性
|
|
27
27
|
|
|
28
|
-
-
|
|
28
|
+
- **更安全的全局初始化默认值。** `repo-harness init` 现在会把 setup 进度直接输出到终端,
|
|
29
|
+
不再默认安装 Superpowers Claude marketplace plugin。只有你明确需要它时,才使用
|
|
30
|
+
`repo-harness init --with-superpowers`。
|
|
31
|
+
- **全局初始化命令(`repo-harness init`)。** 一条命令引导全局 Claude 环境:essential plugins、
|
|
29
32
|
可配置 policy hooks(worktree guard、atomic commit/pending)、按项目类型可选的 LSP plugins,以及
|
|
30
33
|
四档 hook profile(`standard`、`minimal`、`biome`、`biome-strict`)。运行
|
|
31
|
-
`
|
|
34
|
+
`npx -y repo-harness init`,不需要 clone 源码仓库。
|
|
35
|
+
- **仓库刷新命令(`repo-harness update`)。** 已有仓库的安装/刷新入口独立成命令,继续复用
|
|
36
|
+
原 repo-local harness migration 路径,同时让 `init` 专注于全局 runtime setup。
|
|
37
|
+
- **CodeGraph index 自愈。** prompt hook 检测到结构化代码导航意图、且仓库还没有 `.codegraph`
|
|
38
|
+
index 时,会先用 repo-local 或 PATH 上的 CodeGraph binary 初始化 index,再发路由提示。这个动作仍是
|
|
39
|
+
advisory:不安装依赖、不跑重 readiness probe,CodeGraph 不可用时也不阻塞 prompt。
|
|
32
40
|
- **安全哨兵(`repo-harness security scan` + `security-sentinel.sh`)。** 对高价值配置注入面做只读检查
|
|
33
41
|
(`~/.claude/settings.json`、`~/.codex/hooks.json`、仓库本地 `.vscode/tasks.json`,以及 legacy 项目级
|
|
34
42
|
`.claude`/`.codex` adapter)。它标记危险命令模式——远程 shell 管道、base64 解码执行、`osascript`、
|
|
@@ -62,7 +70,7 @@ repo-local hooks,然后验证这些 workflow surfaces 仍然一致。
|
|
|
62
70
|
|
|
63
71
|
1. **源码包层**:本仓库维护 CLI、command skill facades、templates、hook assets、
|
|
64
72
|
workflow contract、tests 和 release gate。
|
|
65
|
-
2. **目标仓库合约层**:`repo-harness
|
|
73
|
+
2. **目标仓库合约层**:`repo-harness update` 或 migration 会写入 `docs/spec.md`、
|
|
66
74
|
`plans/`、`tasks/`、`.ai/context/`、`.ai/harness/`、helper scripts 和
|
|
67
75
|
`.ai/hooks/`。
|
|
68
76
|
3. **Host adapter 层**:user-level `~/.claude/settings.json` 和 `~/.codex/hooks.json`
|
|
@@ -135,26 +143,42 @@ flowchart TD
|
|
|
135
143
|
|
|
136
144
|
这是评估一个真实仓库是否适合接入该 workflow 的最快路径。
|
|
137
145
|
|
|
138
|
-
###
|
|
146
|
+
### 初次引导
|
|
139
147
|
|
|
140
148
|
```bash
|
|
141
149
|
npx -y repo-harness init
|
|
142
150
|
```
|
|
143
151
|
|
|
152
|
+
`init` 是首次全局引导入口。它运行 npm 包里自带的 `scripts/setup-plugins.sh`,
|
|
153
|
+
安装全局 Claude plugins 和 hook profiles,默认等价于 `--hooks standard`。
|
|
154
|
+
需要不同 hook profile 时再传 `--hooks <profile>` 或 `--no-hooks`。
|
|
155
|
+
|
|
156
|
+
### 安装或刷新 repo-local harness
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
npx -y repo-harness update --dry-run
|
|
160
|
+
npx -y repo-harness update
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
`update` 是已有目标仓库的安装和刷新入口。从目标仓库根目录运行它,用当前 npm 包
|
|
164
|
+
安装或刷新 workflow files、hook assets、host adapters、skill aliases 和
|
|
165
|
+
repo-local verification surfaces。
|
|
166
|
+
|
|
144
167
|
npm package release line 现在是 `0.2.x`;生成的 workflow compatibility model line
|
|
145
|
-
单独以 `5.x` 追踪。`repo-harness@0.2.
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
168
|
+
单独以 `5.x` 追踪。`repo-harness@0.2.2` 把首次全局引导(`repo-harness init`)
|
|
169
|
+
和 repo-local 刷新(`repo-harness update`)拆开,同时保留全局 plugin/hook 安装脚本
|
|
170
|
+
(`scripts/setup-plugins.sh`)、只读配置安全哨兵(`repo-harness security scan`)、
|
|
171
|
+
显式 Claude/Codex draft-plan 生命周期,新增 prompt hook 的非阻塞 CodeGraph index 初始化,
|
|
172
|
+
并把 Superpowers 放到显式 `--with-superpowers` opt-in 后面。这些能力叠加在改名后的 CLI、user-level hook adapter bootstrap、AI-native scaffold overlays、
|
|
173
|
+
typed prompt-guard decision engine、plan-stem task artifact 命名、`REPO_HARNESS_*`
|
|
174
|
+
runtime aliases、Waza runtime skill sync,以及 maintainer 发布 npm 前使用的 release gate 之上。
|
|
151
175
|
|
|
152
|
-
|
|
176
|
+
只有维护者需要在编辑 package 源码时使用 source checkout:
|
|
153
177
|
|
|
154
178
|
```bash
|
|
155
179
|
git clone https://github.com/Ancienttwo/repo-harness.git ~/Projects/repo-harness
|
|
156
180
|
cd ~/Projects/repo-harness
|
|
157
|
-
bun src/cli/index.ts
|
|
181
|
+
bun src/cli/index.ts update
|
|
158
182
|
```
|
|
159
183
|
|
|
160
184
|
本地路径模型:
|
|
@@ -180,13 +204,13 @@ symlink-backed runtime entrypoints。退休的 `project-initializer` runtime 目
|
|
|
180
204
|
已有仓库从 repo root 执行:
|
|
181
205
|
|
|
182
206
|
```bash
|
|
183
|
-
npx -y repo-harness
|
|
207
|
+
npx -y repo-harness update --dry-run
|
|
184
208
|
```
|
|
185
209
|
|
|
186
210
|
dry-run 报告正确后再应用:
|
|
187
211
|
|
|
188
212
|
```bash
|
|
189
|
-
npx -y repo-harness
|
|
213
|
+
npx -y repo-harness update
|
|
190
214
|
```
|
|
191
215
|
|
|
192
216
|
新项目或新模块使用 `repo-harness-scaffold` command skill。已有仓库使用
|
|
@@ -222,6 +246,15 @@ bun test
|
|
|
222
246
|
- Codex 必须在 Settings 里信任 `~/.codex/hooks.json`,hooks 才会执行。
|
|
223
247
|
- 调试顺序:user-level adapter config -> `repo-harness-hook` 或 fallback `repo-harness hook` -> route registry -> `.ai/hooks/*`。
|
|
224
248
|
|
|
249
|
+
`SessionStart` 在开工前按顺序跑两个脚本:
|
|
250
|
+
|
|
251
|
+
```mermaid
|
|
252
|
+
flowchart LR
|
|
253
|
+
SessionStart["Claude/Codex SessionStart"] --> Ctx["session-start-context.sh<br/>恢复 + handoff 上下文"]
|
|
254
|
+
Ctx --> Sec["security-sentinel.sh<br/>只读配置扫描,按指纹门控"]
|
|
255
|
+
Sec --> SSOut["SessionStart additionalContext<br/>上次会话状态 + SecurityConfig 发现项"]
|
|
256
|
+
```
|
|
257
|
+
|
|
225
258
|
Prompt guard 多一个内部步骤:
|
|
226
259
|
|
|
227
260
|
```mermaid
|
|
@@ -233,6 +266,7 @@ flowchart LR
|
|
|
233
266
|
Shell --> Decision["repo-harness-hook prompt-guard-decide<br/>TypeScript decision table"]
|
|
234
267
|
Decision --> Action["single action enum"]
|
|
235
268
|
Action --> Shell
|
|
269
|
+
Shell --> RouteHint["Waza 路由提示<br/>显式 think/规划优先匹配 → /think"]
|
|
236
270
|
Shell --> HostOutput["host-safe allow, advice, block, or done gate output"]
|
|
237
271
|
```
|
|
238
272
|
|
|
@@ -267,7 +301,7 @@ hook block 工作时,先看 terminal 里的结构化输出。核心字段是
|
|
|
267
301
|
|
|
268
302
|
## 当前 Release
|
|
269
303
|
|
|
270
|
-
- npm package:`repo-harness@0.2.
|
|
304
|
+
- npm package:`repo-harness@0.2.2`
|
|
271
305
|
- Generated workflow compatibility:`5.2.3`
|
|
272
306
|
- GitHub repository:`Ancienttwo/repo-harness`
|
|
273
307
|
- Release history:[`docs/CHANGELOG.md`](docs/CHANGELOG.md)
|
|
@@ -282,7 +316,7 @@ hook block 工作时,先看 terminal 里的结构化输出。核心字段是
|
|
|
282
316
|
- `assets/workflow-contract.v1.json`
|
|
283
317
|
- Generated repos 默认使用 repo-local harness flow:
|
|
284
318
|
- `docs/spec.md -> plans/ -> tasks/contracts/ -> tasks/reviews/ -> .ai/context/context-map.json -> .ai/harness/*`
|
|
285
|
-
- `repo-harness
|
|
319
|
+
- `repo-harness update` 会刷新 runtime pieces:
|
|
286
320
|
- `repo-harness` skill aliases
|
|
287
321
|
- global Codex/Claude hook adapters
|
|
288
322
|
- Waza skills:`check`、`design`、`health`、`hunt`、`learn`、`read`、`think`、`write`
|
|
@@ -41,7 +41,9 @@ run_architecture_drift_sync() {
|
|
|
41
41
|
if [[ -x "scripts/context-contract-sync.sh" ]]; then
|
|
42
42
|
bash "scripts/context-contract-sync.sh" sync-latest || true
|
|
43
43
|
fi
|
|
44
|
-
if command -v
|
|
44
|
+
if [[ -n "${REPO_HARNESS_CLI:-}" && -f "$REPO_HARNESS_CLI" ]] && command -v bun >/dev/null 2>&1; then
|
|
45
|
+
bun "$REPO_HARNESS_CLI" capability-context request --from-latest-architecture-event || true
|
|
46
|
+
elif command -v repo-harness >/dev/null 2>&1; then
|
|
45
47
|
repo-harness capability-context request --from-latest-architecture-event || true
|
|
46
48
|
elif command -v bun >/dev/null 2>&1 && [[ -f "src/cli/index.ts" ]]; then
|
|
47
49
|
bun src/cli/index.ts capability-context request --from-latest-architecture-event || true
|
|
@@ -642,6 +642,55 @@ is_nontrivial_code_task_intent() {
|
|
|
642
642
|
echo "$PROMPT_INTENT_TEXT" | grep -qEi "(architecture|architectural|runtime|hook|hooks|shared contract|workflow contract|module boundary|route registry|multi[- ]?file|refactor|dependency path|架构|运行时|钩子|共享合约|工作流合约|模块边界|路由表|多文件|重构|依赖路径)"
|
|
643
643
|
}
|
|
644
644
|
|
|
645
|
+
resolve_codegraph_bin() {
|
|
646
|
+
if [[ -x "node_modules/.bin/codegraph" ]]; then
|
|
647
|
+
printf '%s\n' "node_modules/.bin/codegraph"
|
|
648
|
+
return 0
|
|
649
|
+
fi
|
|
650
|
+
|
|
651
|
+
command -v codegraph 2>/dev/null || return 1
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
run_codegraph_init_command() {
|
|
655
|
+
local codegraph_bin status cursor_dir_existed cursor_rules_dir_existed cursor_rule_existed
|
|
656
|
+
codegraph_bin="$(resolve_codegraph_bin)" || return 127
|
|
657
|
+
|
|
658
|
+
cursor_dir_existed=false
|
|
659
|
+
cursor_rules_dir_existed=false
|
|
660
|
+
cursor_rule_existed=false
|
|
661
|
+
[[ -d ".cursor" ]] && cursor_dir_existed=true
|
|
662
|
+
[[ -d ".cursor/rules" ]] && cursor_rules_dir_existed=true
|
|
663
|
+
[[ -e ".cursor/rules/codegraph.mdc" ]] && cursor_rule_existed=true
|
|
664
|
+
|
|
665
|
+
set +e
|
|
666
|
+
CODEGRAPH_NO_DAEMON=1 "$codegraph_bin" init -i .
|
|
667
|
+
status=$?
|
|
668
|
+
set -e
|
|
669
|
+
|
|
670
|
+
if [[ "$cursor_rule_existed" == "false" && -f ".cursor/rules/codegraph.mdc" ]]; then
|
|
671
|
+
rm -f ".cursor/rules/codegraph.mdc"
|
|
672
|
+
[[ "$cursor_rules_dir_existed" == "false" ]] && rmdir ".cursor/rules" 2>/dev/null || true
|
|
673
|
+
[[ "$cursor_dir_existed" == "false" ]] && rmdir ".cursor" 2>/dev/null || true
|
|
674
|
+
fi
|
|
675
|
+
|
|
676
|
+
return "$status"
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
ensure_codegraph_index_for_route() {
|
|
680
|
+
local output status
|
|
681
|
+
|
|
682
|
+
[[ -f ".codegraph/codegraph.db" ]] && return 0
|
|
683
|
+
|
|
684
|
+
output="$(run_codegraph_init_command 2>&1)"
|
|
685
|
+
status=$?
|
|
686
|
+
|
|
687
|
+
if [[ "$status" -eq 0 && -f ".codegraph/codegraph.db" ]]; then
|
|
688
|
+
echo "[CodegraphRoute] Initialized missing CodeGraph index before routing hint."
|
|
689
|
+
elif [[ "$status" -ne 127 ]]; then
|
|
690
|
+
echo "[CodegraphRoute] CodeGraph index init skipped or failed; run codegraph init -i . if structural tools are unavailable."
|
|
691
|
+
fi
|
|
692
|
+
}
|
|
693
|
+
|
|
645
694
|
emit_codegraph_route_hint() {
|
|
646
695
|
local session_key session_file=".claude/.session-id"
|
|
647
696
|
|
|
@@ -652,7 +701,11 @@ emit_codegraph_route_hint() {
|
|
|
652
701
|
return 0
|
|
653
702
|
fi
|
|
654
703
|
|
|
655
|
-
if is_codegraph_route_intent
|
|
704
|
+
if is_codegraph_route_intent; then
|
|
705
|
+
ensure_codegraph_index_for_route || true
|
|
706
|
+
echo "[CodegraphRoute] Structural code-navigation intent detected. Prefer CodeGraph context/search/callers/impact before grep/read when available."
|
|
707
|
+
session_state_mark_codegraph_nudged "$session_key" || true
|
|
708
|
+
elif is_nontrivial_code_task_intent; then
|
|
656
709
|
echo "[CodegraphRoute] Structural code-navigation intent detected. Prefer CodeGraph context/search/callers/impact before grep/read when available."
|
|
657
710
|
session_state_mark_codegraph_nudged "$session_key" || true
|
|
658
711
|
fi
|
|
@@ -246,9 +246,32 @@ for (const entry of selected) {
|
|
|
246
246
|
continue;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
|
|
249
|
+
let sourceContent;
|
|
250
|
+
try {
|
|
251
|
+
sourceContent = fs.readFileSync(entry.sourceFile, "utf8");
|
|
252
|
+
} catch (error) {
|
|
253
|
+
const code = error && error.code ? ` (${error.code})` : "";
|
|
254
|
+
issue(`Entry ${entry.id} source file is unreadable: ${entry.sourcePath}${code}`);
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
|
|
250
258
|
const targetExists = fs.existsSync(entry.targetPath);
|
|
251
|
-
|
|
259
|
+
let targetContent = null;
|
|
260
|
+
if (targetExists) {
|
|
261
|
+
try {
|
|
262
|
+
targetContent = fs.readFileSync(entry.targetPath, "utf8");
|
|
263
|
+
} catch (error) {
|
|
264
|
+
const code = error && error.code ? ` (${error.code})` : "";
|
|
265
|
+
const message = `Entry ${entry.id} brain file is unreadable: ${entry.brainPath}${code}`;
|
|
266
|
+
if (modeCheck && !requireVault) {
|
|
267
|
+
warn(`${message}; skipped sync drift check`);
|
|
268
|
+
skipped += 1;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
issue(message);
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
252
275
|
|
|
253
276
|
if (modeCheck) {
|
|
254
277
|
if (!targetExists) {
|
package/package.json
CHANGED
package/scripts/setup-plugins.sh
CHANGED
|
@@ -392,7 +392,7 @@ install_superpowers_plugin() {
|
|
|
392
392
|
local settings_file="$CLAUDE_DIR/settings.json"
|
|
393
393
|
local configured=false
|
|
394
394
|
|
|
395
|
-
echo -e "${BLUE}Configuring Superpowers plugin
|
|
395
|
+
echo -e "${BLUE}Configuring Superpowers plugin...${NC}"
|
|
396
396
|
|
|
397
397
|
if command_exists claude; then
|
|
398
398
|
if claude plugin marketplace add "$SUPERPOWERS_MARKETPLACE" >/dev/null 2>&1; then
|
|
@@ -722,6 +722,7 @@ print_summary() {
|
|
|
722
722
|
main() {
|
|
723
723
|
local install_optional=false
|
|
724
724
|
local install_obsidian=false
|
|
725
|
+
local install_superpowers=false
|
|
725
726
|
local hook_type="standard"
|
|
726
727
|
|
|
727
728
|
# Parse arguments
|
|
@@ -735,6 +736,10 @@ main() {
|
|
|
735
736
|
install_obsidian=true
|
|
736
737
|
shift
|
|
737
738
|
;;
|
|
739
|
+
--with-superpowers)
|
|
740
|
+
install_superpowers=true
|
|
741
|
+
shift
|
|
742
|
+
;;
|
|
738
743
|
--hooks)
|
|
739
744
|
hook_type="$2"
|
|
740
745
|
shift 2
|
|
@@ -754,7 +759,7 @@ main() {
|
|
|
754
759
|
--help)
|
|
755
760
|
echo "Usage: setup-plugins.sh [options]"
|
|
756
761
|
echo ""
|
|
757
|
-
echo "Default behavior: installs essential plugins
|
|
762
|
+
echo "Default behavior: installs essential plugins and hook-profile support"
|
|
758
763
|
echo "Runtime defaults: Plan-only, Codex platform default sandbox with approval on failure,"
|
|
759
764
|
echo " Claude default permissions, worktree-warning mutations (opt-in enforcement),"
|
|
760
765
|
echo " atomic checkpoint commits after green checks."
|
|
@@ -762,6 +767,7 @@ main() {
|
|
|
762
767
|
echo "Options:"
|
|
763
768
|
echo " --with-optional Install optional plugins (commit-commands, pr-review-toolkit, ralph-loop, etc.)"
|
|
764
769
|
echo " --with-obsidian Install Obsidian skills"
|
|
770
|
+
echo " --with-superpowers Install the Superpowers Claude marketplace plugin"
|
|
765
771
|
echo " --hooks TYPE Hook type: standard (default), minimal, biome, biome-strict, none"
|
|
766
772
|
echo " --no-hooks Skip hook configuration"
|
|
767
773
|
echo " --lsp PLUGIN Install specific LSP plugin (e.g., typescript-lsp, pyright-lsp, gopls-lsp)"
|
|
@@ -930,9 +936,11 @@ main() {
|
|
|
930
936
|
echo ""
|
|
931
937
|
add_permissions
|
|
932
938
|
|
|
933
|
-
# Configure Superpowers marketplace plugin
|
|
934
|
-
|
|
935
|
-
|
|
939
|
+
# Configure Superpowers marketplace plugin only when explicitly requested.
|
|
940
|
+
if [ "$install_superpowers" = true ]; then
|
|
941
|
+
echo ""
|
|
942
|
+
install_superpowers_plugin
|
|
943
|
+
fi
|
|
936
944
|
|
|
937
945
|
# Print summary
|
|
938
946
|
print_summary
|
|
@@ -246,9 +246,32 @@ for (const entry of selected) {
|
|
|
246
246
|
continue;
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
|
|
249
|
+
let sourceContent;
|
|
250
|
+
try {
|
|
251
|
+
sourceContent = fs.readFileSync(entry.sourceFile, "utf8");
|
|
252
|
+
} catch (error) {
|
|
253
|
+
const code = error && error.code ? ` (${error.code})` : "";
|
|
254
|
+
issue(`Entry ${entry.id} source file is unreadable: ${entry.sourcePath}${code}`);
|
|
255
|
+
continue;
|
|
256
|
+
}
|
|
257
|
+
|
|
250
258
|
const targetExists = fs.existsSync(entry.targetPath);
|
|
251
|
-
|
|
259
|
+
let targetContent = null;
|
|
260
|
+
if (targetExists) {
|
|
261
|
+
try {
|
|
262
|
+
targetContent = fs.readFileSync(entry.targetPath, "utf8");
|
|
263
|
+
} catch (error) {
|
|
264
|
+
const code = error && error.code ? ` (${error.code})` : "";
|
|
265
|
+
const message = `Entry ${entry.id} brain file is unreadable: ${entry.brainPath}${code}`;
|
|
266
|
+
if (modeCheck && !requireVault) {
|
|
267
|
+
warn(`${message}; skipped sync drift check`);
|
|
268
|
+
skipped += 1;
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
issue(message);
|
|
272
|
+
continue;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
252
275
|
|
|
253
276
|
if (modeCheck) {
|
|
254
277
|
if (!targetExists) {
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { spawnSync, type StdioOptions } from 'child_process';
|
|
2
|
+
import { existsSync } from 'fs';
|
|
3
|
+
import { dirname, join } from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
|
|
6
|
+
export const HOOK_PROFILES = ['standard', 'minimal', 'biome', 'biome-strict', 'none'] as const;
|
|
7
|
+
export type HookProfile = (typeof HOOK_PROFILES)[number];
|
|
8
|
+
|
|
9
|
+
export interface GlobalRuntimeOptions {
|
|
10
|
+
sourceRoot?: string;
|
|
11
|
+
cwd?: string;
|
|
12
|
+
env?: NodeJS.ProcessEnv;
|
|
13
|
+
stdio?: 'pipe' | 'inherit';
|
|
14
|
+
withOptional?: boolean;
|
|
15
|
+
withObsidian?: boolean;
|
|
16
|
+
withSuperpowers?: boolean;
|
|
17
|
+
hooks?: string | false;
|
|
18
|
+
lsp?: string;
|
|
19
|
+
projectType?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface GlobalRuntimeResult {
|
|
23
|
+
exitCode: number;
|
|
24
|
+
command: string[];
|
|
25
|
+
stdout: string;
|
|
26
|
+
stderr: string;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function defaultSourceRoot(): string {
|
|
30
|
+
return join(dirname(fileURLToPath(import.meta.url)), '..', '..', '..');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function buildGlobalRuntimeArgs(opts: GlobalRuntimeOptions): string[] {
|
|
34
|
+
const args: string[] = [];
|
|
35
|
+
if (opts.withOptional === true) args.push('--with-optional');
|
|
36
|
+
if (opts.withObsidian === true) args.push('--with-obsidian');
|
|
37
|
+
if (opts.withSuperpowers === true) args.push('--with-superpowers');
|
|
38
|
+
if (opts.hooks === false) args.push('--no-hooks');
|
|
39
|
+
else if (typeof opts.hooks === 'string') args.push('--hooks', opts.hooks);
|
|
40
|
+
if (opts.lsp) args.push('--lsp', opts.lsp);
|
|
41
|
+
if (opts.projectType) args.push('--project-type', opts.projectType);
|
|
42
|
+
return args;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export function validateHookProfile(
|
|
46
|
+
value: string | false | undefined,
|
|
47
|
+
commandName = 'init',
|
|
48
|
+
): string | null {
|
|
49
|
+
if (value === undefined || value === false) return null;
|
|
50
|
+
return HOOK_PROFILES.includes(value as HookProfile)
|
|
51
|
+
? null
|
|
52
|
+
: `repo-harness ${commandName}: invalid --hooks "${value}" (expected: ${HOOK_PROFILES.join(', ')})`;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function runGlobalRuntimeSetup(opts: GlobalRuntimeOptions): GlobalRuntimeResult {
|
|
56
|
+
const sourceRoot = opts.sourceRoot ?? defaultSourceRoot();
|
|
57
|
+
const scriptPath = join(sourceRoot, 'scripts', 'setup-plugins.sh');
|
|
58
|
+
const args = buildGlobalRuntimeArgs(opts);
|
|
59
|
+
const command = ['bash', scriptPath, ...args];
|
|
60
|
+
|
|
61
|
+
if (!existsSync(scriptPath)) {
|
|
62
|
+
return {
|
|
63
|
+
exitCode: 1,
|
|
64
|
+
command,
|
|
65
|
+
stdout: '',
|
|
66
|
+
stderr: `repo-harness init: script not found at ${scriptPath}`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const result = spawnSync('bash', [scriptPath, ...args], {
|
|
71
|
+
cwd: opts.cwd ?? process.cwd(),
|
|
72
|
+
encoding: 'utf-8',
|
|
73
|
+
env: { ...process.env, ...(opts.env ?? {}) },
|
|
74
|
+
stdio: (opts.stdio ?? 'pipe') as StdioOptions,
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
return {
|
|
78
|
+
exitCode: result.status ?? 1,
|
|
79
|
+
command,
|
|
80
|
+
stdout: result.stdout ?? '',
|
|
81
|
+
stderr: result.stderr || (result.error ? String(result.error.message || result.error) : ''),
|
|
82
|
+
};
|
|
83
|
+
}
|
package/src/cli/commands/init.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Existing-repo harness bootstrap/update implementation.
|
|
3
3
|
*
|
|
4
|
-
* This
|
|
5
|
-
* the target repo to cwd,
|
|
6
|
-
*
|
|
4
|
+
* This backs the public `repo-harness update` command and the legacy
|
|
5
|
+
* `repo-harness-init` skill facade: default the target repo to cwd,
|
|
6
|
+
* install/refresh the machine runtime pieces, apply the repo-local workflow
|
|
7
|
+
* migration, then verify the installed harness.
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
10
|
import { spawnSync } from "child_process";
|
|
@@ -15,7 +15,7 @@ import { isManagedEntry, type HooksByEvent } from '../installer/managed-entries'
|
|
|
15
15
|
import { readJsonOrEmpty } from '../installer/shared';
|
|
16
16
|
import type { Location } from '../installer/types';
|
|
17
17
|
|
|
18
|
-
export const CLI_VERSION = '0.2.
|
|
18
|
+
export const CLI_VERSION = '0.2.2';
|
|
19
19
|
|
|
20
20
|
const OPT_IN_MARKER = '.ai/harness/workflow-contract.json';
|
|
21
21
|
|
package/src/cli/index.ts
CHANGED
|
@@ -18,6 +18,7 @@ import { buildToolsCommand } from './commands/tools';
|
|
|
18
18
|
import { buildBrainCommand } from './commands/brain';
|
|
19
19
|
import { buildCapabilityContextCommand } from './commands/capability-context';
|
|
20
20
|
import { formatSecurityScan, runSecurityScan } from './commands/security';
|
|
21
|
+
import { HOOK_PROFILES, runGlobalRuntimeSetup, validateHookProfile } from './commands/global-runtime';
|
|
21
22
|
import { runPromptGuardDecisionFromEnv } from './commands/prompt-guard-decision';
|
|
22
23
|
import type { Location } from './installer/types';
|
|
23
24
|
import type { HookEvent, RouteId } from './hook/route-registry';
|
|
@@ -30,6 +31,7 @@ export const SUBCOMMANDS = [
|
|
|
30
31
|
'doctor',
|
|
31
32
|
'migrate',
|
|
32
33
|
'security',
|
|
34
|
+
'update',
|
|
33
35
|
'tools',
|
|
34
36
|
'brain',
|
|
35
37
|
'capability-context',
|
|
@@ -44,12 +46,49 @@ export function buildProgram(): Command {
|
|
|
44
46
|
program
|
|
45
47
|
.name('repo-harness')
|
|
46
48
|
.description('Repo-local agentic development harness CLI')
|
|
47
|
-
.version('0.2.
|
|
49
|
+
.version('0.2.2')
|
|
48
50
|
.exitOverride();
|
|
49
51
|
|
|
50
52
|
program
|
|
51
53
|
.command('init')
|
|
52
|
-
.description('
|
|
54
|
+
.description('Bootstrap global Claude plugins and hook profiles from the npm package')
|
|
55
|
+
.option('--with-optional', 'Install optional plugins')
|
|
56
|
+
.option('--with-obsidian', 'Install Obsidian skills')
|
|
57
|
+
.option('--with-superpowers', 'Install the Superpowers Claude marketplace plugin')
|
|
58
|
+
.option('--hooks <profile>', `Hook profile: ${HOOK_PROFILES.join('|')}`, 'standard')
|
|
59
|
+
.option('--no-hooks', 'Skip hook configuration')
|
|
60
|
+
.option('--lsp <plugin>', 'Install a specific LSP plugin')
|
|
61
|
+
.option('--project-type <type>', 'Auto-select LSP by repo-harness project type')
|
|
62
|
+
.action((rawOpts: {
|
|
63
|
+
withOptional?: boolean;
|
|
64
|
+
withObsidian?: boolean;
|
|
65
|
+
withSuperpowers?: boolean;
|
|
66
|
+
hooks?: string | false;
|
|
67
|
+
lsp?: string;
|
|
68
|
+
projectType?: string;
|
|
69
|
+
}) => {
|
|
70
|
+
const validationError = validateHookProfile(rawOpts.hooks, 'init');
|
|
71
|
+
if (validationError) {
|
|
72
|
+
console.error(validationError);
|
|
73
|
+
process.exit(2);
|
|
74
|
+
}
|
|
75
|
+
const result = runGlobalRuntimeSetup({
|
|
76
|
+
withOptional: rawOpts.withOptional === true,
|
|
77
|
+
withObsidian: rawOpts.withObsidian === true,
|
|
78
|
+
withSuperpowers: rawOpts.withSuperpowers === true,
|
|
79
|
+
hooks: rawOpts.hooks,
|
|
80
|
+
lsp: rawOpts.lsp,
|
|
81
|
+
projectType: rawOpts.projectType,
|
|
82
|
+
stdio: 'inherit',
|
|
83
|
+
});
|
|
84
|
+
if (result.stdout) process.stdout.write(result.stdout);
|
|
85
|
+
if (result.stderr) process.stderr.write(result.stderr);
|
|
86
|
+
process.exit(result.exitCode);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
program
|
|
90
|
+
.command('update')
|
|
91
|
+
.description('Install or refresh the repo-local harness workflow in an existing repo')
|
|
53
92
|
.option('--repo <path>', 'Target repository path (defaults to cwd)')
|
|
54
93
|
.option('--dry-run', 'Plan repo harness changes without applying them')
|
|
55
94
|
.option('--target <target>', `Host target for adapters and external skills: ${VALID_TARGETS.join('|')}`, 'both')
|
|
@@ -82,12 +121,12 @@ export function buildProgram(): Command {
|
|
|
82
121
|
}) => {
|
|
83
122
|
if (!VALID_TARGETS.includes(rawOpts.target as InstallTargetSpec)) {
|
|
84
123
|
console.error(
|
|
85
|
-
`repo-harness
|
|
124
|
+
`repo-harness update: invalid --target "${rawOpts.target}" (expected: ${VALID_TARGETS.join(', ')})`,
|
|
86
125
|
);
|
|
87
126
|
process.exit(2);
|
|
88
127
|
}
|
|
89
128
|
if (!['skip', 'manifest-only', 'install-gbrain-cli'].includes(rawOpts.brainMode ?? 'skip')) {
|
|
90
|
-
console.error('repo-harness
|
|
129
|
+
console.error('repo-harness update: invalid --brain-mode (expected: skip, manifest-only, install-gbrain-cli)');
|
|
91
130
|
process.exit(2);
|
|
92
131
|
}
|
|
93
132
|
const common = {
|