xtrm-tools 0.7.13 → 0.7.15
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/.xtrm/config/hooks.json +10 -0
- package/.xtrm/hooks/specialists-agent-guard.mjs +76 -0
- package/.xtrm/registry.json +433 -413
- package/.xtrm/skills/default/releasing/SKILL.md +49 -45
- package/.xtrm/skills/default/releasing/scripts/xt-reports.ts +18 -0
- package/.xtrm/skills/default/session-close-report/SKILL.md +85 -17
- package/.xtrm/skills/default/specialists-creator/SKILL.md +133 -42
- package/.xtrm/skills/default/specialists-creator/scripts/audit-spec-uniformity.mjs +86 -0
- package/.xtrm/skills/default/specialists-creator/scripts/scaffold-specialist.ts +223 -0
- package/.xtrm/skills/default/specialists-creator/scripts/validate-specialist.ts +1 -1
- package/.xtrm/skills/default/update-specialists/SKILL.md +98 -392
- package/.xtrm/skills/default/using-nodes/SKILL.md +18 -102
- package/.xtrm/skills/default/using-script-specialists/SKILL.md +208 -0
- package/.xtrm/skills/default/using-specialists/SKILL.md +13 -0
- package/.xtrm/skills/default/using-specialists-v2/SKILL.md +105 -15
- package/.xtrm/skills/default/using-xtrm/SKILL.md +14 -0
- package/CHANGELOG.md +22 -0
- package/README.md +5 -1
- package/cli/dist/index.cjs +2991 -627
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/package.json +3 -2
- package/packages/pi-extensions/.serena/project.yml +11 -0
- package/packages/pi-extensions/package.json +1 -1
- package/scripts/patch-external-pi-tools.mjs +154 -0
|
@@ -1,448 +1,154 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: update-specialists
|
|
3
3
|
description: >
|
|
4
|
-
Reconcile
|
|
5
|
-
Use this skill when
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
version: 1.4
|
|
10
|
-
synced_at: 2026-04-29
|
|
4
|
+
Reconcile all xtrm-managed asset drift across repos.
|
|
5
|
+
Use this skill when user says "update specialists", "xtrm drift", "assets out of date",
|
|
6
|
+
or when operator needs guided refresh across one repo or many.
|
|
7
|
+
version: 2.0
|
|
8
|
+
synced_at: 2026-05-05
|
|
11
9
|
---
|
|
12
10
|
|
|
13
11
|
# update-specialists
|
|
14
12
|
|
|
15
|
-
|
|
16
|
-
fixes, then verify with `sp doctor`. Treat canonical state as both:
|
|
17
|
-
1. healthy repo wiring and runtime behavior, and
|
|
18
|
-
2. parity with currently installed `@jaggerxtrm/specialists` package version
|
|
19
|
-
when package-level comparison is available.
|
|
20
|
-
|
|
21
|
-
Ownership contract during repair:
|
|
22
|
-
- upstream source: package `config/*` (read-only for repo operators)
|
|
23
|
-
- managed mirror: `.specialists/default/*` (refresh via `sp init --sync-defaults`; sync scope = specialists + mandatory-rules + nodes; no hand edits)
|
|
24
|
-
- repo custom layer: `.specialists/user/*` + `config/nodes/*` + `.specialists/mandatory-rules/*` (rule overlay, wins on set-id conflict; NOT drift — do not overwrite or flag)
|
|
25
|
-
- runtime/generated: `.specialists/{jobs,ready,db}`
|
|
26
|
-
|
|
27
|
-
Isolation rule: backlog-clean surfaces out of scope for this skill.
|
|
28
|
-
|
|
29
|
-
## Canonical State
|
|
30
|
-
|
|
31
|
-
Check each item explicitly. This is what a healthy specialists-initialized project
|
|
32
|
-
looks like.
|
|
33
|
-
|
|
34
|
-
### Package + runtime parity
|
|
35
|
-
|
|
36
|
-
| Check | Expected value |
|
|
37
|
-
|-------|----------------|
|
|
38
|
-
| Installed `@jaggerxtrm/specialists` package version | Matches intended runtime version for repo install |
|
|
39
|
-
| `sp --version` / `specialists --version` | Matches installed package version or same release line |
|
|
40
|
-
| Installed package root | Resolvable from Node / npm environment |
|
|
41
|
-
| Canonical package defaults | Available from installed package for direct diffing |
|
|
42
|
-
| Repo install vs package install | No unexpected drift in canonical files unless intentionally customized |
|
|
43
|
-
|
|
44
|
-
### Specialists configs
|
|
45
|
-
|
|
46
|
-
| Check | Expected value |
|
|
47
|
-
|-------|----------------|
|
|
48
|
-
| `.specialists/default/*.specialist.json` | JSON-first specialist configs present |
|
|
49
|
-
| `metadata.name` | Matches filename stem |
|
|
50
|
-
| `metadata.version` | Valid semver string and consistent with canonical shipped copy when comparing like-for-like |
|
|
51
|
-
| `metadata.description` | Present |
|
|
52
|
-
| `metadata.category` | Present |
|
|
53
|
-
| `execution.model` | Present and pingable |
|
|
54
|
-
| `execution.fallback_model` | Present, different provider from primary |
|
|
55
|
-
| `execution.permission_required` | Valid enum |
|
|
56
|
-
| `skills.paths` | Referenced skill paths resolve correctly |
|
|
57
|
-
| `execution.interactive` | Matches intended keep-alive behavior |
|
|
58
|
-
| Installed default specialist copy | Matches canonical package copy unless intentionally customized |
|
|
59
|
-
|
|
60
|
-
### Hooks wiring
|
|
61
|
-
|
|
62
|
-
| Check | Expected value |
|
|
63
|
-
|-------|----------------|
|
|
64
|
-
| `.claude/settings.json` | Has hook entries for active events |
|
|
65
|
-
| Hook events | At minimum: `SessionStart`, `PreToolUse`, `PostToolUse`, `Stop` |
|
|
66
|
-
| Hook paths | Point at specialists runtime hook scripts, not stale xtrm-only paths |
|
|
67
|
-
| Hook format | Matches project's installed settings format and loads cleanly |
|
|
68
|
-
| Installed hook scripts | Match canonical package hook files unless intentionally customized |
|
|
69
|
-
|
|
70
|
-
### CLI reachability
|
|
71
|
-
|
|
72
|
-
| Check | Expected value |
|
|
73
|
-
|-------|----------------|
|
|
74
|
-
| `sp` command | On PATH and runs |
|
|
75
|
-
| `specialists` command | On PATH and runs |
|
|
76
|
-
| Version compatibility | `sp doctor` reports matching runtime / install state |
|
|
77
|
-
| Command surface | `sp doctor`, `sp init`, `sp clean`, `sp status` available |
|
|
78
|
-
|
|
79
|
-
### Jobs and runtime dirs
|
|
80
|
-
|
|
81
|
-
| Check | Expected value |
|
|
82
|
-
|-------|----------------|
|
|
83
|
-
| `.specialists/jobs/` | Exists |
|
|
84
|
-
| `.specialists/ready/` | Exists if used by runtime |
|
|
85
|
-
| `.specialists/default/` | Canonical install copy present |
|
|
86
|
-
| Orphaned worktrees | None under `.worktrees/` |
|
|
87
|
-
| Worktree ownership | No stale entries for deleted jobs |
|
|
88
|
-
|
|
89
|
-
### SQLite / observability
|
|
90
|
-
|
|
91
|
-
| Check | Expected value |
|
|
92
|
-
|-------|----------------|
|
|
93
|
-
| specialists DB | Opens cleanly (`.specialists/db/observability.db`) |
|
|
94
|
-
| Schema version | Matches runtime expectation (current: v11; auto-migrates on next runtime startup) |
|
|
95
|
-
| `specialist_job_metrics` table | Present at v11+ — holds aggregated per-job metrics |
|
|
96
|
-
| `specialist_job_metrics` columns | Includes `active_runtime_ms` + `waiting_ms` (drs41.1 — auto-added by idempotent `migrateToV11` ALTER TABLE on first start of upgraded runtime; pre-existing rows get NULL until next aggregate) |
|
|
97
|
-
| Auto-aggregation hook | Supervisor + `sp stop` invoke `aggregateJobMetricsBestEffort` after terminal-status persistence (drs41.1) — table populates without manual `sp db extract` under normal operation |
|
|
98
|
-
| Merge target lookup | DB-first (post-ofjvj): `readAllJobStatuses()` reads `specialist_jobs` via `listStatuses()`. `sp merge` no longer reads `.specialists/jobs/<id>/status.json`. Older versions silently failed after `sp stop` cleaned status.json. |
|
|
99
|
-
| WAL / busy timeout settings | Present when runtime uses SQLite |
|
|
100
|
-
| Corruption / lock errors | None in `sp doctor` |
|
|
101
|
-
| Pre-prune extract | `sp db prune --apply` extracts metrics to `specialist_job_metrics` before deleting events |
|
|
102
|
-
| Extract backfill | `sp db extract --all-missing` populates metrics for jobs whose events still exist (still useful for backfilling historical jobs that ran before the auto-aggregate hook landed) |
|
|
103
|
-
| Historical stats query | `sp db stats [--spec <name>] [--model <glob>] [--since <dur>]` reads the aggregated table; output includes `active_s`, `waiting_s`, `total_s` (drs41.1) |
|
|
104
|
-
|
|
105
|
-
**Safety: `sp init` and `sp init --sync-defaults` do NOT touch `.specialists/db/observability.db`.** Init checks file existence and skips with "observability database already exists (not touched)" when present. Schema migrations run on next runtime startup (any `sp` invocation that opens the DB), additively via `ALTER TABLE ADD COLUMN`. No data loss path during a normal package upgrade.
|
|
106
|
-
|
|
107
|
-
### Skills + extensions parity
|
|
108
|
-
|
|
109
|
-
| Check | Expected value |
|
|
110
|
-
|-------|----------------|
|
|
111
|
-
| `.xtrm/skills/default/` | Matches canonical package skill set for installed version |
|
|
112
|
-
| Active skill links / copies | Resolve to expected default or active targets |
|
|
113
|
-
| Skill frontmatter `version` / `synced_at` | Present and reasonable for shipped skills |
|
|
114
|
-
| `quality-gates` | Registered if project uses quality gates |
|
|
115
|
-
| `pi-gitnexus` | Registered when GitNexus integration is expected |
|
|
116
|
-
| `pi-serena-tools` | Registered when Serena integration is expected |
|
|
117
|
-
| Extension paths | Resolve from installed project, not stale workspace copies |
|
|
118
|
-
|
|
119
|
-
### Mandatory-rules template parity (three-tier)
|
|
120
|
-
|
|
121
|
-
Loader unions indexes from three paths and probes set files in reverse precedence
|
|
122
|
-
(overlay wins on set-id conflict). Full authoring guide:
|
|
123
|
-
`config/mandatory-rules/README.md`.
|
|
124
|
-
|
|
125
|
-
| Check | Expected value |
|
|
126
|
-
|-------|----------------|
|
|
127
|
-
| `.specialists/default/mandatory-rules/*` | Mirrors canonical package templates after `sp init --sync-defaults` (managed mirror, no hand edits) |
|
|
128
|
-
| `.specialists/mandatory-rules/*` | Repo-specific overlay (user-maintained). Present when repo ships its own rules. NOT drift. |
|
|
129
|
-
| Template frontmatter | YAML frontmatter present and parseable |
|
|
130
|
-
| `specialist.mandatory_rules.template_sets` references | Resolve in order: `.specialists/mandatory-rules/` → `.specialists/default/mandatory-rules/` → `config/mandatory-rules/` |
|
|
131
|
-
| Index files (`index.json`) | Any of the three tiers may define `required_template_sets` / `default_template_sets`; loader unions + dedups |
|
|
132
|
-
| Prompt injection behavior | Runner appends resolved `MANDATORY_RULES` block at end of prompt; supervisor emits `mandatory_rules_injection` meta event |
|
|
133
|
-
|
|
134
|
-
## Discover Latest Release
|
|
135
|
-
|
|
136
|
-
Before reconciling, determine whether a newer release is published. Compare local `package.json` version to the most recent `vX.Y.Z` tag on `origin`:
|
|
13
|
+
Interactive wrapper over `xt update` for xtrm-managed asset drift.
|
|
137
14
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
echo "local: $LOCAL latest: $LATEST"
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
If `LATEST > LOCAL`, read the corresponding `CHANGELOG.md` section to summarize what shipped:
|
|
145
|
-
|
|
146
|
-
```bash
|
|
147
|
-
awk -v ver="$LATEST" '/^## \[v?'"$LATEST"'\]/,/^## \[/{print}' CHANGELOG.md | head -60
|
|
148
|
-
```
|
|
15
|
+
Canonical-live model:
|
|
16
|
+
- **Category A**: specialist runtime / loader-live surfaces. No refresh needed; verify only.
|
|
17
|
+
- **Category B**: xtrm-managed snapshots under repos (`.xtrm/skills/default/`, `.xtrm/hooks/default/`, and related managed assets). These can drift and need operator-confirmed refresh.
|
|
149
18
|
|
|
150
|
-
|
|
19
|
+
Skill goal:
|
|
20
|
+
1. find projects root,
|
|
21
|
+
2. inspect drift,
|
|
22
|
+
3. summarize per-repo state,
|
|
23
|
+
4. ask operator which repos to refresh,
|
|
24
|
+
5. run `xt update --apply`,
|
|
25
|
+
6. re-check,
|
|
26
|
+
7. report final state.
|
|
151
27
|
|
|
152
|
-
|
|
28
|
+
No automatic execution. Always operator-confirmed.
|
|
153
29
|
|
|
154
|
-
|
|
30
|
+
## Operator Flow
|
|
155
31
|
|
|
156
|
-
|
|
32
|
+
### 1) Discover projects root
|
|
157
33
|
|
|
158
|
-
|
|
34
|
+
Ask for root if user did not name one.
|
|
159
35
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
sp status
|
|
166
|
-
|
|
167
|
-
# 3. Installed package + CLI version parity
|
|
168
|
-
npm ls @jaggerxtrm/specialists --depth=0 2>/dev/null || true
|
|
169
|
-
node -e "try { const pkg=require(require.resolve('@jaggerxtrm/specialists/package.json')); console.log(JSON.stringify({installed_package_version: pkg.version}, null, 2)); } catch (err) { console.log('PACKAGE_NOT_RESOLVABLE'); }"
|
|
170
|
-
sp --version 2>/dev/null || true
|
|
171
|
-
specialists --version 2>/dev/null || true
|
|
172
|
-
|
|
173
|
-
# 4. Resolve canonical package root for direct drift diff
|
|
174
|
-
node -e "try { const path=require('path'); const pkgPath=require.resolve('@jaggerxtrm/specialists/package.json'); console.log(path.dirname(pkgPath)); } catch (err) { console.log('PACKAGE_ROOT_UNAVAILABLE'); }"
|
|
175
|
-
|
|
176
|
-
# 5. Config shape
|
|
177
|
-
find .specialists/default -maxdepth 1 -name '*.specialist.json' -print
|
|
178
|
-
|
|
179
|
-
# 6. Validate specialist JSON files
|
|
180
|
-
node -e "const fs=require('fs'); const path=require('path'); const dir='.specialists/default'; for (const file of fs.readdirSync(dir)) { if (!file.endsWith('.specialist.json')) continue; const s=JSON.parse(fs.readFileSync(path.join(dir,file),'utf8')); const m=s.metadata||{}; const e=s.execution||{}; const missing=[]; for (const key of ['name','version','description','category']) if (!m[key]) missing.push('metadata.'+key); for (const key of ['model','fallback_model','permission_required']) if (!e[key]) missing.push('execution.'+key); if (missing.length) console.log(file+': MISSING '+missing.join(', ')); if (m.name && m.name !== file.replace(/\.specialist\.json$/, '')) console.log(file+': NAME MISMATCH '+m.name); }"
|
|
181
|
-
|
|
182
|
-
# 7. Validate referenced skill paths
|
|
183
|
-
node -e "const fs=require('fs'); const path=require('path'); const dir='.specialists/default'; for (const file of fs.readdirSync(dir)) { if (!file.endsWith('.specialist.json')) continue; const s=JSON.parse(fs.readFileSync(path.join(dir,file),'utf8')); for (const p of (s.skills?.paths ?? [])) { if (!fs.existsSync(p)) console.log(file+': MISSING SKILL PATH '+p); } }"
|
|
184
|
-
|
|
185
|
-
# 8. Compare repo defaults against installed package defaults (if package root resolvable)
|
|
186
|
-
PKG_ROOT="$(node -e "try { const path=require('path'); process.stdout.write(path.dirname(require.resolve('@jaggerxtrm/specialists/package.json'))); } catch (err) {}")"
|
|
187
|
-
if [ -n "$PKG_ROOT" ]; then
|
|
188
|
-
diff -rq .specialists/default "$PKG_ROOT/config/specialists" || true
|
|
189
|
-
diff -rq .xtrm/skills/default "$PKG_ROOT/config/skills" || true
|
|
190
|
-
diff -rq .claude/hooks "$PKG_ROOT/config/hooks" || true
|
|
191
|
-
else
|
|
192
|
-
echo PACKAGE_COMPARE_UNAVAILABLE
|
|
193
|
-
fi
|
|
194
|
-
|
|
195
|
-
# 9. Hooks wiring
|
|
196
|
-
node -e "const fs=require('fs'); const p='.claude/settings.json'; if (fs.existsSync(p)) { const s=JSON.parse(fs.readFileSync(p,'utf8')); console.log(JSON.stringify(s.hooks ?? s, null, 2)); } else { console.log('MISSING .claude/settings.json'); }"
|
|
197
|
-
|
|
198
|
-
# 10. Command availability
|
|
199
|
-
command -v sp
|
|
200
|
-
command -v specialists
|
|
201
|
-
specialists init --help | sed -n '1,120p'
|
|
202
|
-
specialists edit --help | sed -n '1,120p' | grep -E -- '--fork-from|fork-from' || true
|
|
203
|
-
sp doctor --json 2>/dev/null || true
|
|
204
|
-
|
|
205
|
-
# 11. Jobs and worktrees
|
|
206
|
-
ls -1 .specialists/jobs 2>/dev/null || true
|
|
207
|
-
find .worktrees -maxdepth 2 -mindepth 1 -type d 2>/dev/null || true
|
|
208
|
-
|
|
209
|
-
# 12. Extension registration
|
|
210
|
-
node -e "const fs=require('fs'); const p='.pi/settings.json'; if (fs.existsSync(p)) console.log(JSON.stringify(JSON.parse(fs.readFileSync(p,'utf8')).skills ?? JSON.parse(fs.readFileSync(p,'utf8')).extensions ?? {}, null, 2)); else console.log('MISSING .pi/settings.json')"
|
|
211
|
-
|
|
212
|
-
# 13a. Observability schema + metrics coverage + drs41.1 column presence
|
|
213
|
-
node -e "const {Database} = require('bun:sqlite'); const p='.specialists/db/observability.db'; const fs=require('fs'); if (!fs.existsSync(p)) { console.log('NO_DB'); process.exit(0); } const db=new Database(p,{readonly:true}); const v=db.query(\"SELECT value FROM schema_meta WHERE key='version'\").get(); const has=db.query(\"SELECT name FROM sqlite_master WHERE type='table' AND name='specialist_job_metrics'\").get(); const jobs=db.query('SELECT COUNT(*) c FROM specialist_jobs').get(); const metrics=has ? db.query('SELECT COUNT(*) c FROM specialist_job_metrics').get() : null; const cols=has ? new Set(db.query('PRAGMA table_info(specialist_job_metrics)').all().map(r=>r.name)) : new Set(); const drs41Cols={active_runtime_ms: cols.has('active_runtime_ms'), waiting_ms: cols.has('waiting_ms')}; console.log(JSON.stringify({schema_version: v?.value, has_metrics_table: !!has, drs41_columns_present: drs41Cols, jobs: jobs.c, metrics_rows: metrics?.c ?? 0, metrics_coverage: metrics ? (metrics.c/jobs.c).toFixed(2) : null}, null, 2));" 2>/dev/null || echo "REQUIRES_BUN_RUNTIME"
|
|
214
|
-
|
|
215
|
-
# 13. Mandatory-rules template tiers + reference checks (three-tier resolution)
|
|
216
|
-
find .specialists/default/mandatory-rules -maxdepth 1 -type f 2>/dev/null || true
|
|
217
|
-
find .specialists/mandatory-rules -maxdepth 1 -type f 2>/dev/null || true
|
|
218
|
-
node -e "const fs=require('fs'); const path=require('path'); const roots=['.specialists/default/specialists','.specialists/user/specialists']; const missing=[]; for (const root of roots) { if (!fs.existsSync(root)) continue; for (const file of fs.readdirSync(root)) { if (!file.endsWith('.specialist.json')) continue; const spec=JSON.parse(fs.readFileSync(path.join(root,file),'utf8')); const sets=spec.specialist?.mandatory_rules?.template_sets ?? []; for (const set of sets) { const candidates=[path.join('.specialists/mandatory-rules',set+'.md'), path.join('.specialists/default/mandatory-rules',set+'.md'), path.join('config/mandatory-rules',set+'.md')]; if (!candidates.some((p)=>fs.existsSync(p))) missing.push(file+': missing template set '+set); } } } if (missing.length) console.log(missing.join('\n'));"
|
|
219
|
-
|
|
220
|
-
# 14. Shipped skill frontmatter parity
|
|
221
|
-
node -e "const fs=require('fs'); const path=require('path'); const dir='.xtrm/skills/default'; if (!fs.existsSync(dir)) process.exit(0); for (const name of fs.readdirSync(dir)) { const p=path.join(dir,name,'SKILL.md'); if (!fs.existsSync(p)) continue; const head=fs.readFileSync(p,'utf8').split('---')[1] || ''; const version=(head.match(/version:\s*([^\n]+)/)||[])[1]; const synced=(head.match(/synced_at:\s*([^\n]+)/)||[])[1]; console.log(name+': version='+(version||'missing')+' synced_at='+(synced||'missing')); }"
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
## Drift -> Fix Mapping
|
|
225
|
-
|
|
226
|
-
Use targeted fixes first. Escalate to full sync only if needed.
|
|
227
|
-
|
|
228
|
-
| Drift | Fix |
|
|
229
|
-
|-------|-----|
|
|
230
|
-
| Installed package version mismatch | reinstall / upgrade `@jaggerxtrm/specialists`, then re-run checks |
|
|
231
|
-
| CLI version mismatch vs package | reinstall runtime so `sp` / `specialists` align with installed package |
|
|
232
|
-
| Specialist JSON missing required fields | `sp edit <name> ...` or regenerate via `specialists init --sync-defaults` |
|
|
233
|
-
| Need user-layer override from default/package specialist | `sp edit <name> --fork-from <base>` to materialize editable copy in `.specialists/user/` |
|
|
234
|
-
| Specialist JSON schema mismatch | `specialists init --sync-defaults` (refreshes specialists + mandatory-rules + nodes) |
|
|
235
|
-
| Installed specialist default differs from canonical package copy | `specialists init --sync-defaults` unless local customization is intentional |
|
|
236
|
-
| Hooks missing or stale | `specialists init` |
|
|
237
|
-
| Installed hook file differs from canonical package copy | `specialists init` unless local customization is intentional |
|
|
238
|
-
| `sp` / `specialists` missing from PATH | Reinstall / re-bootstrap specialists runtime |
|
|
239
|
-
| Job dir missing | `specialists init` |
|
|
240
|
-
| Orphaned `.worktrees/` entries | `specialists clean` |
|
|
241
|
-
| SQLite schema/version mismatch | `sp doctor` first, then `specialists init --sync-defaults` or runtime migration command |
|
|
242
|
-
| Schema below v11 (no `specialist_job_metrics`) | Reinstall / upgrade runtime; table is created by initSchema / migrateToV11. No data loss — raw events untouched. |
|
|
243
|
-
| `specialist_job_metrics` missing `active_runtime_ms` / `waiting_ms` columns (post-drs41.1) | Open any `sp` command — `migrateToV11` is idempotent and ALTERs the table to add the columns. No reinstall needed. Pre-existing rows show NULL until next aggregate or `sp db extract --all-missing`. |
|
|
244
|
-
| Auto-aggregate hook absent (older runtime) — empty `specialist_job_metrics` despite job activity | Upgrade `@jaggerxtrm/specialists` package. Post-drs41.1, supervisor + `sp stop` invoke `aggregateJobMetricsBestEffort` on every terminal status, so the table fills under normal operation. Backfill historical with `sp db extract --all-missing`. |
|
|
245
|
-
| `sp merge` fails after `sp stop` (older runtime) — "No chain-root job with worktree metadata found" | Upgrade `@jaggerxtrm/specialists` past ofjvj fix. Merge lookup is now DB-first via `readAllJobStatuses()` / `listStatuses()`. Pre-fix workaround was manual `git merge --no-ff feature/<branch>` (skips tsc + conflict gates). |
|
|
246
|
-
| Events about to be pruned but never aggregated | `sp db extract --all-missing` BEFORE `sp db prune --apply`. Prune refuses when extract fails (safe by design). |
|
|
247
|
-
| Emergency: need to prune but extract is wedged | `sp db prune --apply --skip-extract` — raw events deleted without aggregation. Use only when data loss is acceptable. |
|
|
248
|
-
| Historical per-job stats needed | `sp db stats` reads `specialist_job_metrics`. Replaces ad-hoc `status.json` scans. Supports `--format json\|table`. |
|
|
249
|
-
| Pi extensions missing | `specialists init --sync-skills` or reinstall extension registration |
|
|
250
|
-
| Hook config format stale | `specialists init` |
|
|
251
|
-
| Skill symlink / active-skill drift | `specialists init --sync-skills` |
|
|
252
|
-
| Installed default skill differs from canonical package copy | `specialists init --sync-skills` unless local customization is intentional |
|
|
253
|
-
| Skill frontmatter version / synced_at drift | `specialists init --sync-skills` or refresh packaged skills |
|
|
254
|
-
| Mandatory-rules mirror drift (`.specialists/default/mandatory-rules`) | `specialists init --sync-defaults` |
|
|
255
|
-
| `.specialists/mandatory-rules/` overlay present | Leave alone — this is repo overlay, NOT drift |
|
|
256
|
-
| Missing/invalid `template_sets` references | Check all three tiers first; `sp edit <name> --fork-from <base>` then fix references, or sync defaults if mirror missing, or add set to overlay if intended |
|
|
257
|
-
| Unknown manual drift | Stop, inspect, then apply user-approved fix |
|
|
258
|
-
|
|
259
|
-
## Remediation
|
|
260
|
-
|
|
261
|
-
### Fix: Package/runtime version drift
|
|
262
|
-
|
|
263
|
-
If installed npm package version, CLI version, or package root parity checks disagree:
|
|
264
|
-
|
|
265
|
-
```bash
|
|
266
|
-
npm ls @jaggerxtrm/specialists --depth=0
|
|
267
|
-
specialists --version
|
|
268
|
-
sp --version
|
|
269
|
-
```
|
|
36
|
+
Default order:
|
|
37
|
+
1. explicit user root,
|
|
38
|
+
2. `~/dev`,
|
|
39
|
+
3. git-discovered repo root / workspace root,
|
|
40
|
+
4. current directory as last fallback.
|
|
270
41
|
|
|
271
|
-
If
|
|
272
|
-
version is correct, re-run `specialists init` / sync commands to repair repo drift.
|
|
42
|
+
If multiple candidate roots exist, ask which one to use.
|
|
273
43
|
|
|
274
|
-
###
|
|
44
|
+
### 2) Run doctor
|
|
275
45
|
|
|
276
|
-
|
|
277
|
-
shows missing fields, wrong names, or schema mismatch:
|
|
46
|
+
Use:
|
|
278
47
|
|
|
279
48
|
```bash
|
|
280
|
-
|
|
49
|
+
xt doctor --cwd <root> --json
|
|
281
50
|
```
|
|
282
51
|
|
|
283
|
-
|
|
52
|
+
If `xt` is unavailable, stop and switch to fallback guidance below.
|
|
284
53
|
|
|
285
|
-
|
|
286
|
-
full sync. If target specialist lives in default/package layer, fork first:
|
|
54
|
+
### 3) Summarize drift
|
|
287
55
|
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
56
|
+
Render clean table grouped by repo:
|
|
57
|
+
- repo path
|
|
58
|
+
- status
|
|
59
|
+
- drift count
|
|
60
|
+
- missing / extra / mismatched assets
|
|
61
|
+
- suggested action
|
|
291
62
|
|
|
292
|
-
|
|
63
|
+
Keep focus on operator action, not internal diagnostics.
|
|
293
64
|
|
|
294
|
-
|
|
295
|
-
installed package canonical copies:
|
|
65
|
+
### 4) Ask for confirm
|
|
296
66
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
67
|
+
Offer three paths:
|
|
68
|
+
- refresh all repos,
|
|
69
|
+
- refresh specific repos,
|
|
70
|
+
- dry-run only.
|
|
300
71
|
|
|
301
|
-
If
|
|
302
|
-
when hook-only sync is not enough.
|
|
72
|
+
If user names one repo, keep flow narrow and confirm only that repo.
|
|
303
73
|
|
|
304
|
-
###
|
|
74
|
+
### 5) Apply refresh
|
|
305
75
|
|
|
306
|
-
|
|
76
|
+
Use:
|
|
307
77
|
|
|
308
78
|
```bash
|
|
309
|
-
|
|
79
|
+
xt update --apply --root <root>
|
|
310
80
|
```
|
|
311
81
|
|
|
312
|
-
|
|
313
|
-
Do not guess at file edits when command surface itself is broken.
|
|
314
|
-
|
|
315
|
-
### Fix: Job dirs or worktree GC drift
|
|
316
|
-
|
|
317
|
-
If jobs exist without owners, worktrees are orphaned, or cleanup state is stale:
|
|
82
|
+
Or for one repo:
|
|
318
83
|
|
|
319
84
|
```bash
|
|
320
|
-
|
|
85
|
+
xt update --apply --repo <repo>
|
|
321
86
|
```
|
|
322
87
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
### Fix: SQLite schema drift
|
|
88
|
+
For dry-run, omit `--apply`.
|
|
326
89
|
|
|
327
|
-
|
|
90
|
+
### 6) Re-run doctor
|
|
328
91
|
|
|
329
|
-
|
|
330
|
-
2. Apply runtime migration command if available.
|
|
331
|
-
3. If no automated migration exists, flag manual intervention.
|
|
92
|
+
Run same doctor command again after update and confirm clean state.
|
|
332
93
|
|
|
333
|
-
|
|
94
|
+
### 7) Final report
|
|
334
95
|
|
|
335
|
-
|
|
96
|
+
State:
|
|
97
|
+
- what drift existed,
|
|
98
|
+
- what refreshed,
|
|
99
|
+
- what stayed untouched,
|
|
100
|
+
- any residual manual fixes.
|
|
336
101
|
|
|
337
|
-
|
|
102
|
+
## Fallback When xt Missing
|
|
338
103
|
|
|
339
|
-
|
|
104
|
+
If `xt` / `xtrm` not installed or doctor/update help unavailable:
|
|
105
|
+
- do not block user,
|
|
106
|
+
- switch to per-repo guidance,
|
|
107
|
+
- tell user to run repo-local checks manually,
|
|
108
|
+
- do not invent bulk repair commands.
|
|
340
109
|
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
sp
|
|
110
|
+
Fallback response shape:
|
|
111
|
+
- identify likely drifted repos,
|
|
112
|
+
- point user at repo-local `sp doctor` / package-specific checks already available in that repo,
|
|
113
|
+
- say bulk refresh needs `xt` installed.
|
|
344
114
|
|
|
345
|
-
|
|
346
|
-
sp db extract --job <job-id>
|
|
347
|
-
|
|
348
|
-
# Query aggregates.
|
|
349
|
-
sp db stats
|
|
350
|
-
sp db stats --spec executor --since 7d --format json
|
|
351
|
-
sp db stats --model 'openai-codex/*' --since 30d
|
|
352
|
-
```
|
|
115
|
+
## Drift Review Rules
|
|
353
116
|
|
|
354
|
-
|
|
117
|
+
- Treat repo-custom overlays as intentional unless doctor marks them mismatched against managed snapshot.
|
|
118
|
+
- Do not overwrite user-owned layers.
|
|
119
|
+
- Prefer dry-run first when drift touches multiple repos.
|
|
120
|
+
- If only one repo needs refresh, keep output narrow and use single-repo update path.
|
|
121
|
+
- If doctor shows mixed drift across 3 repos, summarize each repo separately and ask which to refresh.
|
|
355
122
|
|
|
356
|
-
|
|
357
|
-
1. `sp db extract --all-missing` — verify no extract errors.
|
|
358
|
-
2. `sp db prune --before 30d --dry-run` — confirm scope.
|
|
359
|
-
3. `sp db prune --before 30d --apply` — prune with pre-extract built in.
|
|
360
|
-
4. `sp db vacuum` — compact file size.
|
|
123
|
+
## Output Shape
|
|
361
124
|
|
|
362
|
-
|
|
125
|
+
Use this order:
|
|
126
|
+
1. root chosen
|
|
127
|
+
2. doctor summary
|
|
128
|
+
3. drift table
|
|
129
|
+
4. confirm prompt
|
|
130
|
+
5. update action
|
|
131
|
+
6. post-update doctor result
|
|
132
|
+
7. final status
|
|
363
133
|
|
|
364
|
-
|
|
365
|
-
`.xtrm/skills/default/`, or `.claude/hooks/` drift from shipped canonical files:
|
|
134
|
+
## Example Operator Loop
|
|
366
135
|
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
```bash
|
|
371
|
-
specialists init --sync-defaults
|
|
372
|
-
specialists init --sync-skills
|
|
373
|
-
specialists init
|
|
374
|
-
```
|
|
375
|
-
|
|
376
|
-
### Fix: Pi extensions not registered
|
|
136
|
+
```text
|
|
137
|
+
Root: ~/dev
|
|
138
|
+
Doctor: 3 repos checked
|
|
377
139
|
|
|
378
|
-
|
|
140
|
+
repo status drift
|
|
141
|
+
repo-a drifted 4 assets
|
|
142
|
+
repo-b in-sync 0 assets
|
|
143
|
+
repo-c drifted 1 asset
|
|
379
144
|
|
|
380
|
-
|
|
381
|
-
specialists init --sync-skills
|
|
145
|
+
Refresh all / specific repos / dry-run?
|
|
382
146
|
```
|
|
383
147
|
|
|
384
|
-
If project uses different extension packaging, re-run install step that writes
|
|
385
|
-
`.pi/settings.json`.
|
|
386
|
-
|
|
387
148
|
## Verification
|
|
388
149
|
|
|
389
|
-
After
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
npm ls @jaggerxtrm/specialists --depth=0 2>/dev/null || true
|
|
395
|
-
specialists --version 2>/dev/null || true
|
|
396
|
-
sp --version 2>/dev/null || true
|
|
397
|
-
|
|
398
|
-
node -e "const fs=require('fs'); const p='.claude/settings.json'; const s=JSON.parse(fs.readFileSync(p,'utf8')); console.log(Boolean(s.hooks || Object.keys(s).length))"
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
Expected outcome:
|
|
402
|
-
- `sp doctor` clean
|
|
403
|
-
- `sp status` no drift / no repair hints
|
|
404
|
-
- `sp` and `specialists` reachable (`sp` is shorthand; `specialists` is canonical)
|
|
405
|
-
- installed package / CLI versions aligned
|
|
406
|
-
- specialist JSON files valid
|
|
407
|
-
- repo defaults match installed package defaults (or intentional custom drift acknowledged)
|
|
408
|
-
- hooks present on required events and canonical hook files match installed package copy
|
|
409
|
-
- no orphaned worktrees
|
|
410
|
-
- SQLite state healthy
|
|
411
|
-
|
|
412
|
-
## Manual Intervention
|
|
413
|
-
|
|
414
|
-
Flag these when automatic fix is unsafe or impossible:
|
|
415
|
-
|
|
416
|
-
- `sp doctor` reports corrupt DB / unreadable SQLite file
|
|
417
|
-
- command surface missing because install itself is broken
|
|
418
|
-
- hook scripts absent from repo and cannot be regenerated
|
|
419
|
-
- schema mismatch with no available migration path
|
|
420
|
-
- worktree cleanup would remove user changes
|
|
421
|
-
- extensions required by project are not installed at package level
|
|
422
|
-
- package root is unavailable, so package-vs-installed diff cannot be computed
|
|
423
|
-
- repo intentionally diverges from canonical package copies and user must preserve customizations
|
|
424
|
-
|
|
425
|
-
When manual intervention needed, report:
|
|
426
|
-
1. exact drift
|
|
427
|
-
2. exact command tried
|
|
428
|
-
3. why auto-fix stopped
|
|
429
|
-
4. next safe operator action
|
|
430
|
-
|
|
431
|
-
## User Summary Format
|
|
432
|
-
|
|
433
|
-
After detection + remediation, answer with compact status:
|
|
434
|
-
|
|
435
|
-
```text
|
|
436
|
-
## specialists update complete
|
|
437
|
-
|
|
438
|
-
✓ sp doctor clean
|
|
439
|
-
✓ package / CLI versions aligned
|
|
440
|
-
✓ specialist configs valid
|
|
441
|
-
✓ hooks wired
|
|
442
|
-
✓ canonical package parity checked
|
|
443
|
-
✓ jobs/worktrees clean
|
|
444
|
-
✓ SQLite healthy
|
|
445
|
-
✓ extensions registered
|
|
446
|
-
|
|
447
|
-
[manual items, if any]
|
|
448
|
-
```
|
|
150
|
+
After refresh:
|
|
151
|
+
- `xt doctor --cwd <root> --json` clean or reduced to intentional custom drift,
|
|
152
|
+
- repo-specific follow-up actions called out only when needed,
|
|
153
|
+
- single-repo case stays single-repo,
|
|
154
|
+
- missing `xt` path falls back cleanly.
|