xtrm-tools 2.1.2 → 2.1.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -30
- package/cli/dist/index.cjs +98 -5
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/hooks/main-guard.mjs +1 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -198,19 +198,23 @@ Task intake and service routing for Docker service projects.
|
|
|
198
198
|
|
|
199
199
|
### Standalone Hooks
|
|
200
200
|
|
|
201
|
-
**
|
|
202
|
-
- Trigger: PreToolUse (
|
|
203
|
-
- Purpose:
|
|
201
|
+
**main-guard.mjs**
|
|
202
|
+
- Trigger: PreToolUse (Write|Edit|MultiEdit)
|
|
203
|
+
- Purpose: Blocks direct edits on protected branches with structured deny output
|
|
204
204
|
|
|
205
205
|
**type-safety-enforcement.py**
|
|
206
206
|
- Trigger: PreToolUse (Bash|Edit|Write)
|
|
207
207
|
- Purpose: Enforce type safety in Python code
|
|
208
208
|
|
|
209
|
-
**
|
|
210
|
-
- Trigger:
|
|
211
|
-
- Purpose:
|
|
209
|
+
**agent_context.py**
|
|
210
|
+
- Trigger: Support module used by Python hooks
|
|
211
|
+
- Purpose: Shared hook input/output helper
|
|
212
212
|
|
|
213
|
-
**
|
|
213
|
+
**beads gate hooks** (installed with `xtrm install all`, or included when beads+dolt is available):
|
|
214
|
+
- `beads-edit-gate.mjs` (PreToolUse)
|
|
215
|
+
- `beads-commit-gate.mjs` (PreToolUse)
|
|
216
|
+
- `beads-stop-gate.mjs` (Stop)
|
|
217
|
+
- `beads-close-memory-prompt.mjs` (PostToolUse)
|
|
214
218
|
|
|
215
219
|
## Project Skills
|
|
216
220
|
|
|
@@ -301,11 +305,12 @@ npm link # registers `xtrm` globally
|
|
|
301
305
|
xtrm <command> [options]
|
|
302
306
|
```
|
|
303
307
|
|
|
304
|
-
| Command
|
|
305
|
-
|
|
|
306
|
-
| `
|
|
307
|
-
| `status`
|
|
308
|
-
| `reset`
|
|
308
|
+
| Command | Description |
|
|
309
|
+
| --------- | -------------------------------- |
|
|
310
|
+
| `install` | Install/update tools |
|
|
311
|
+
| `status` | Show diff without making changes |
|
|
312
|
+
| `reset` | Clear saved preferences |
|
|
313
|
+
| `help` | Show command/component overview |
|
|
309
314
|
|
|
310
315
|
---
|
|
311
316
|
|
|
@@ -329,7 +334,7 @@ xtrm install --backport # reverse direction: copy drifted local edits → re
|
|
|
329
334
|
- **cli-table3 plan table**: Formatted table showing Target / + New / ↑ Update / ! Drift / Total
|
|
330
335
|
- **boxen summary card**: Completion summary with green/yellow border based on drift
|
|
331
336
|
- **Themed output**: Semantic colors (success, error, warning, muted, accent) via `theme.ts`
|
|
332
|
-
- **
|
|
337
|
+
- **beads+dolt prerequisite flow**: `xtrm install` / `xtrm install all` check workflow backend and can install missing deps
|
|
333
338
|
- **Auto-detection**: Scans Claude Code targets automatically (`~/.claude`, `%APPDATA%/Claude` on Windows) plus the `.agents/skills` cache for skills-only sync
|
|
334
339
|
- **Inline sync**: `status` command offers to apply sync immediately after showing changes
|
|
335
340
|
- **Single confirmation**: See full plan across all targets, confirm once
|
|
@@ -395,8 +400,8 @@ xtrm reset
|
|
|
395
400
|
|
|
396
401
|
1. Clone this repository:
|
|
397
402
|
```bash
|
|
398
|
-
git clone https://github.com/Jaggerxtrm/
|
|
399
|
-
cd
|
|
403
|
+
git clone https://github.com/Jaggerxtrm/xtrm-tools.git
|
|
404
|
+
cd xtrm-tools
|
|
400
405
|
```
|
|
401
406
|
|
|
402
407
|
2. Copy skills to Claude Code:
|
|
@@ -457,9 +462,9 @@ If you use Gemini CLI or Qwen CLI, you can still use xtrm-tools skills and hooks
|
|
|
457
462
|
|
|
458
463
|
## Configuration
|
|
459
464
|
|
|
460
|
-
### MCP Servers (
|
|
465
|
+
### MCP Servers (Unified CLI Sync)
|
|
461
466
|
|
|
462
|
-
MCP servers are configured from canonical sources
|
|
467
|
+
MCP servers are configured from canonical sources and synced via official CLI commands.
|
|
463
468
|
|
|
464
469
|
**Core Servers** (installed by default):
|
|
465
470
|
- **serena**: Code analysis (requires `uvx`, auto project detection)
|
|
@@ -484,22 +489,24 @@ MCP servers are configured from canonical sources with automatic format adaptati
|
|
|
484
489
|
- **Persistence:** Values preserved across syncs; never overwritten
|
|
485
490
|
- Edit `~/.config/xtrm-tools/.env` to add your API keys manually
|
|
486
491
|
|
|
487
|
-
**Unified MCP CLI Sync
|
|
488
|
-
- Uses official `mcp add
|
|
492
|
+
**Unified MCP CLI Sync**:
|
|
493
|
+
- Uses official `claude mcp add` / `claude mcp list` commands
|
|
489
494
|
- **Idempotent:** Re-running is always safe — skips already-installed servers
|
|
490
495
|
- **Deduplication:** Prevents same server from syncing N times when multiple dirs selected
|
|
491
|
-
- **Interactive consent:** Multiselect prompt (space to toggle, all pre-selected)
|
|
492
496
|
- **Prerequisite auto-install:** Runs `npm install -g gitnexus` automatically when selected
|
|
493
497
|
- **Post-install guidance:** Shows required next steps (e.g., `npx gitnexus analyze`)
|
|
494
498
|
- **Timeout protection:** 10s timeout on CLI calls to prevent hangs
|
|
495
499
|
- **Clean errors:** User-friendly messages (no stack traces)
|
|
496
500
|
|
|
497
|
-
**
|
|
498
|
-
-
|
|
499
|
-
-
|
|
501
|
+
**Scopes**:
|
|
502
|
+
- Global installs (`xtrm install`, `xtrm install all`, `xtrm install basic`) sync MCP into Claude global config
|
|
503
|
+
- Project installs (`xtrm install project <name|all>`) sync core MCP at project scope (`-s project`)
|
|
500
504
|
|
|
501
|
-
**
|
|
502
|
-
-
|
|
505
|
+
**Supported Agent**:
|
|
506
|
+
- Claude Code
|
|
507
|
+
|
|
508
|
+
**Deprecated**:
|
|
509
|
+
- JSON file MCP sync (superseded by official CLI method)
|
|
503
510
|
- Repo `.env` files — use centralized `~/.config/xtrm-tools/.env`
|
|
504
511
|
|
|
505
512
|
**Documentation**: See [docs/mcp-servers-config.md](docs/mcp-servers-config.md) for complete setup guide.
|
|
@@ -526,7 +533,7 @@ Adjust hook execution timeouts in `settings.json`:
|
|
|
526
533
|
"hooks": {
|
|
527
534
|
"UserPromptSubmit": [{
|
|
528
535
|
"hooks": [{
|
|
529
|
-
"timeout": 5000 // Timeout in milliseconds (5000ms = 5 seconds)
|
|
536
|
+
"timeout": 5000 // Timeout in milliseconds (5000ms = 5 seconds)
|
|
530
537
|
}]
|
|
531
538
|
}]
|
|
532
539
|
}
|
|
@@ -574,7 +581,7 @@ Project-specific operational knowledge system for Docker service projects. Gives
|
|
|
574
581
|
|
|
575
582
|
```bash
|
|
576
583
|
cd ~/projects/my-project
|
|
577
|
-
python3 /path/to/
|
|
584
|
+
python3 /path/to/xtrm-tools/project-skills/service-skills-set/install-service-skills.py
|
|
578
585
|
```
|
|
579
586
|
|
|
580
587
|
- Idempotent — safe to re-run after updates
|
|
@@ -657,7 +664,7 @@ See [CHANGELOG.md](CHANGELOG.md) for complete version history.
|
|
|
657
664
|
## Repository Structure
|
|
658
665
|
|
|
659
666
|
```
|
|
660
|
-
|
|
667
|
+
xtrm-tools/
|
|
661
668
|
├── README.md # This file
|
|
662
669
|
├── CHANGELOG.md # Version history
|
|
663
670
|
├── ROADMAP.md # Future plans
|
|
@@ -667,7 +674,7 @@ jaggers-agent-tools/
|
|
|
667
674
|
├── cli/ # Config Manager CLI (TypeScript)
|
|
668
675
|
│ ├── src/
|
|
669
676
|
│ │ ├── index.ts # Entry point (Commander program)
|
|
670
|
-
│ │ ├── commands/ #
|
|
677
|
+
│ │ ├── commands/ # install.ts, install-project.ts, status.ts, reset.ts, help.ts
|
|
671
678
|
│ │ ├── adapters/ # base, claude, gemini, qwen, registry
|
|
672
679
|
│ │ ├── core/ # context, diff, sync-executor, manifest, rollback
|
|
673
680
|
│ │ ├── utils/ # hash, atomic-config, config-adapter, env-manager, theme…
|
|
@@ -708,7 +715,7 @@ jaggers-agent-tools/
|
|
|
708
715
|
│ ├── type-safety-enforcement.py # Type safety
|
|
709
716
|
│ ├── gitnexus/
|
|
710
717
|
│ │ └── gitnexus-hook.cjs # PreToolUse knowledge graph enrichment
|
|
711
|
-
│ └──
|
|
718
|
+
│ └── main-guard.mjs # Protected-branch edit guard
|
|
712
719
|
│
|
|
713
720
|
├── config/ # Canonical configuration
|
|
714
721
|
│ ├── mcp_servers.json # Core MCP servers
|
package/cli/dist/index.cjs
CHANGED
|
@@ -40942,6 +40942,78 @@ Installing ${skills.length} project skills:
|
|
|
40942
40942
|
await installProjectSkill(skill, projectRoot);
|
|
40943
40943
|
}
|
|
40944
40944
|
}
|
|
40945
|
+
function buildProjectInitGuide() {
|
|
40946
|
+
const lines = [
|
|
40947
|
+
kleur_default.bold("\nProject Init \u2014 Recommended baseline\n"),
|
|
40948
|
+
`${kleur_default.cyan("1) Install a quality gate skill (or equivalent checks):")}`,
|
|
40949
|
+
kleur_default.dim(" - TypeScript projects: xtrm install project ts-quality-gate"),
|
|
40950
|
+
kleur_default.dim(" - Python projects: xtrm install project py-quality-gate"),
|
|
40951
|
+
kleur_default.dim(" - TDD workflow: xtrm install project tdd-guard"),
|
|
40952
|
+
"",
|
|
40953
|
+
`${kleur_default.cyan("2) Ensure your checks are actually configured in this repo:")}`,
|
|
40954
|
+
kleur_default.dim(" - Testing: commands should run and fail when behavior regresses"),
|
|
40955
|
+
kleur_default.dim(" - Linting/formatting: ESLint+Prettier (TS) or ruff (Python)"),
|
|
40956
|
+
kleur_default.dim(" - Type checks: tsc (TS) or mypy/pyright (Python)"),
|
|
40957
|
+
kleur_default.dim(" - Hooks only enforce what your project config defines"),
|
|
40958
|
+
"",
|
|
40959
|
+
`${kleur_default.cyan("3) Optional: Service Skills Set (service-skills-set)")}`,
|
|
40960
|
+
kleur_default.dim(" - For multi-service/Docker repos with repeated operational workflows"),
|
|
40961
|
+
kleur_default.dim(" - Adds project hooks + skills that route Claude to service-specific context"),
|
|
40962
|
+
kleur_default.dim(" - Helps keep architecture knowledge persistent across sessions"),
|
|
40963
|
+
"",
|
|
40964
|
+
kleur_default.bold("Quick start commands:"),
|
|
40965
|
+
kleur_default.dim(" xtrm install project list"),
|
|
40966
|
+
kleur_default.dim(" xtrm install project ts-quality-gate # or py-quality-gate / tdd-guard"),
|
|
40967
|
+
""
|
|
40968
|
+
];
|
|
40969
|
+
return lines.join("\n");
|
|
40970
|
+
}
|
|
40971
|
+
async function printProjectInitGuide() {
|
|
40972
|
+
console.log(buildProjectInitGuide());
|
|
40973
|
+
await runBdInitForProject();
|
|
40974
|
+
}
|
|
40975
|
+
async function installProjectByName(toolName) {
|
|
40976
|
+
if (toolName === "all" || toolName === "*") {
|
|
40977
|
+
await installAllProjectSkills();
|
|
40978
|
+
return;
|
|
40979
|
+
}
|
|
40980
|
+
await installProjectSkill(toolName);
|
|
40981
|
+
}
|
|
40982
|
+
async function runBdInitForProject() {
|
|
40983
|
+
let projectRoot;
|
|
40984
|
+
try {
|
|
40985
|
+
projectRoot = getProjectRoot();
|
|
40986
|
+
} catch (err) {
|
|
40987
|
+
console.log(kleur_default.yellow(`
|
|
40988
|
+
\u26A0 Skipping bd init: ${err.message}
|
|
40989
|
+
`));
|
|
40990
|
+
return;
|
|
40991
|
+
}
|
|
40992
|
+
console.log(kleur_default.bold("Running beads initialization (bd init)..."));
|
|
40993
|
+
const result = (0, import_child_process2.spawnSync)("bd", ["init"], {
|
|
40994
|
+
cwd: projectRoot,
|
|
40995
|
+
encoding: "utf8",
|
|
40996
|
+
timeout: 15e3
|
|
40997
|
+
});
|
|
40998
|
+
if (result.error) {
|
|
40999
|
+
console.log(kleur_default.yellow(` \u26A0 Could not run bd init (${result.error.message})`));
|
|
41000
|
+
return;
|
|
41001
|
+
}
|
|
41002
|
+
if (result.status !== 0) {
|
|
41003
|
+
const text = `${result.stdout || ""}
|
|
41004
|
+
${result.stderr || ""}`.toLowerCase();
|
|
41005
|
+
if (text.includes("already initialized")) {
|
|
41006
|
+
console.log(kleur_default.dim(" \u2713 beads workspace already initialized"));
|
|
41007
|
+
return;
|
|
41008
|
+
}
|
|
41009
|
+
if (result.stdout) process.stdout.write(result.stdout);
|
|
41010
|
+
if (result.stderr) process.stderr.write(result.stderr);
|
|
41011
|
+
console.log(kleur_default.yellow(` \u26A0 bd init exited with code ${result.status}`));
|
|
41012
|
+
return;
|
|
41013
|
+
}
|
|
41014
|
+
if (result.stdout) process.stdout.write(result.stdout);
|
|
41015
|
+
if (result.stderr) process.stderr.write(result.stderr);
|
|
41016
|
+
}
|
|
40945
41017
|
async function listProjectSkills() {
|
|
40946
41018
|
const entries = await getAvailableProjectSkills();
|
|
40947
41019
|
if (entries.length === 0) {
|
|
@@ -40994,11 +41066,7 @@ function createInstallProjectCommand() {
|
|
|
40994
41066
|
const installProjectCmd = new Command("project").description("Install a project-specific skill package");
|
|
40995
41067
|
installProjectCmd.argument("<tool-name>", "Name of the project skill to install").action(async (toolName) => {
|
|
40996
41068
|
try {
|
|
40997
|
-
|
|
40998
|
-
await installAllProjectSkills();
|
|
40999
|
-
return;
|
|
41000
|
-
}
|
|
41001
|
-
await installProjectSkill(toolName);
|
|
41069
|
+
await installProjectByName(toolName);
|
|
41002
41070
|
} catch (err) {
|
|
41003
41071
|
console.error(kleur_default.red(`
|
|
41004
41072
|
\u2717 ${err.message}
|
|
@@ -41009,9 +41077,33 @@ function createInstallProjectCommand() {
|
|
|
41009
41077
|
const listCmd = new Command("list").description("List available project skills").action(async () => {
|
|
41010
41078
|
await listProjectSkills();
|
|
41011
41079
|
});
|
|
41080
|
+
const initCmd = new Command("init").description("Show project onboarding guidance (quality gates + service skills)").action(async () => {
|
|
41081
|
+
await printProjectInitGuide();
|
|
41082
|
+
});
|
|
41012
41083
|
installProjectCmd.addCommand(listCmd);
|
|
41084
|
+
installProjectCmd.addCommand(initCmd);
|
|
41013
41085
|
return installProjectCmd;
|
|
41014
41086
|
}
|
|
41087
|
+
function createProjectCommand() {
|
|
41088
|
+
const projectCmd = new Command("project").description("Project skill onboarding and installation helpers");
|
|
41089
|
+
projectCmd.command("init").description("Show project onboarding guidance (quality gates + service skills)").action(async () => {
|
|
41090
|
+
await printProjectInitGuide();
|
|
41091
|
+
});
|
|
41092
|
+
projectCmd.command("list").description("List available project skills").action(async () => {
|
|
41093
|
+
await listProjectSkills();
|
|
41094
|
+
});
|
|
41095
|
+
projectCmd.command("install").argument("<tool-name>", "Name of the project skill to install").description("Alias for xtrm install project <tool-name>").action(async (toolName) => {
|
|
41096
|
+
try {
|
|
41097
|
+
await installProjectByName(toolName);
|
|
41098
|
+
} catch (err) {
|
|
41099
|
+
console.error(kleur_default.red(`
|
|
41100
|
+
\u2717 ${err.message}
|
|
41101
|
+
`));
|
|
41102
|
+
process.exit(1);
|
|
41103
|
+
}
|
|
41104
|
+
});
|
|
41105
|
+
return projectCmd;
|
|
41106
|
+
}
|
|
41015
41107
|
|
|
41016
41108
|
// src/commands/install.ts
|
|
41017
41109
|
var import_child_process3 = require("child_process");
|
|
@@ -55703,6 +55795,7 @@ program2.exitOverride((err) => {
|
|
|
55703
55795
|
process.exit(1);
|
|
55704
55796
|
});
|
|
55705
55797
|
program2.addCommand(createInstallCommand());
|
|
55798
|
+
program2.addCommand(createProjectCommand());
|
|
55706
55799
|
program2.addCommand(createStatusCommand());
|
|
55707
55800
|
program2.addCommand(createResetCommand());
|
|
55708
55801
|
program2.addCommand(createHelpCommand());
|