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 CHANGED
@@ -198,19 +198,23 @@ Task intake and service routing for Docker service projects.
198
198
 
199
199
  ### Standalone Hooks
200
200
 
201
- **pip-venv-guard.py**
202
- - Trigger: PreToolUse (Bash)
203
- - Purpose: Prevent `pip install` outside virtual environments
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
- **statusline.js**
210
- - Trigger: StatusLine
211
- - Purpose: Display custom status line information
209
+ **agent_context.py**
210
+ - Trigger: Support module used by Python hooks
211
+ - Purpose: Shared hook input/output helper
212
212
 
213
- **NOTE** certain skills are third-party utilities, i believe they can be useful.
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 | Description |
305
- | -------- | --------------------------------- |
306
- | `sync` | Sync tools to target environments |
307
- | `status` | Show diff without making changes |
308
- | `reset` | Clear saved preferences |
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
- - **Interactive consent**: Multiselect for MCP servers (space to toggle, all pre-selected)
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/jaggers-agent-tools.git
399
- cd jaggers-agent-tools
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 (v1.7.0 Unified System)
465
+ ### MCP Servers (Unified CLI Sync)
461
466
 
462
- MCP servers are configured from canonical sources with automatic format adaptation for each agent.
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 (v1.7.0)**:
488
- - Uses official `mcp add`/`mcp remove`/`mcp list` commands for all agents
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
- **Supported Agents**:
498
- - Claude Code (`~/.claude.json` via `mcp add` CLI)
499
- - Antigravity (`~/.gemini/antigravity/mcp_config.json` via `mcp add` CLI)
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
- **Deprecated (v1.7.0)**:
502
- - JSON file sync for Claude/Gemini/Qwen MCP — superseded by official `mcp` CLI method
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) for both Claude and Gemini
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/jaggers-agent-tools/project-skills/service-skills-set/install-service-skills.py
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
- jaggers-agent-tools/
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/ # sync.ts, status.ts, reset.ts
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
- │ └── statusline.js # Status line display
718
+ │ └── main-guard.mjs # Protected-branch edit guard
712
719
 
713
720
  ├── config/ # Canonical configuration
714
721
  │ ├── mcp_servers.json # Core MCP servers
@@ -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
- if (toolName === "all" || toolName === "*") {
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());