xtrm-tools 0.7.1 → 0.7.3
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/pi/extensions/xtrm-ui/index.ts +10 -1
- package/.xtrm/config/pi/extensions/xtrm-ui/themes/pidex-dark.json +7 -3
- package/.xtrm/config/pi/extensions/xtrm-ui/themes/pidex-light.json +4 -0
- package/.xtrm/extensions/xtrm-ui/index.ts +10 -1
- package/.xtrm/registry.json +593 -325
- package/CHANGELOG.md +5 -1
- package/README.md +18 -3
- package/cli/dist/index.cjs +216 -29
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +5 -3
- package/package.json +4 -2
- package/scripts/ghgrep.mjs +358 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,13 +7,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
---
|
|
9
9
|
|
|
10
|
-
## [0.7.1] - 2026-04-
|
|
10
|
+
## [0.7.1] - 2026-04-02
|
|
11
11
|
|
|
12
12
|
### Added
|
|
13
13
|
- **`docs/skills-tier-architecture.md`**: New reference document covering three-tier skills model (default/optional/user), state.json schema, PACK.json schema, runtime active views, and xt skills CLI commands.
|
|
14
14
|
- **`docs/xtrm-directory.md`**: New reference document for centralized `.xtrm/` directory layout — skills, hooks, extensions, worktrees, reports, registry.json.
|
|
15
|
+
- **`docs/bash-tools.md`**: New reference for specialist bash CLIs (`ghgrep`, `ctx7`, `deepwiki`) including install source, usage examples, and CLI-vs-MCP guidance; README now links and surfaces `ghgrep` under capabilities.
|
|
15
16
|
|
|
16
17
|
### Changed
|
|
18
|
+
- **Optional packs install behavior docs**: Updated README + skills docs to reflect that `xt install` now pre-populates `.xtrm/skills/optional/`; packs are activated with `xt skills enable <pack>`.
|
|
19
|
+
- **Pi core resolution path docs**: Updated Pi architecture docs to reflect the new symlink location at `.xtrm/extensions/node_modules/@xtrm/pi-core` (replacing legacy `.pi/node_modules/@xtrm/pi-core`).
|
|
20
|
+
- **Default skills catalog docs**: Added `deepwiki`, `specialists-creator`, and `using-specialists` to default-skill listings in README and skills documentation.
|
|
17
21
|
- **`docs/skills.md`**: Rewritten to cover tier architecture, xt skills CLI, and updated skill catalog (v2.0.0).
|
|
18
22
|
- **`docs/cli-architecture.md`**: Updated skills.ts section — enable/disable/create-pack now fully implemented, added runtime flags documentation (v1.5.0).
|
|
19
23
|
- **`docs/skills-registry-exploration.md`**: Updated implementation status — Phase v0.9 pack lifecycle delivered, enable/disable/create-pack implemented (v1.2.0).
|
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ Native integration with the [specialists](https://github.com/Jaggerxtrm/speciali
|
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
-
**Version 0.
|
|
31
|
+
**Version 0.7.1** | [Complete Guide](XTRM-GUIDE.md) | [Changelog](CHANGELOG.md)
|
|
32
32
|
|
|
33
33
|
---
|
|
34
34
|
|
|
@@ -43,6 +43,7 @@ Native integration with the [specialists](https://github.com/Jaggerxtrm/speciali
|
|
|
43
43
|
| [docs/pi-extensions.md](docs/pi-extensions.md) | Pi extensions — managed sync, authoring, parity notes |
|
|
44
44
|
| [docs/worktrees.md](docs/worktrees.md) | xt worktrees — `xt claude/pi`, `xt attach`, `xt end`, isolation model |
|
|
45
45
|
| [docs/mcp-servers.md](docs/mcp-servers.md) | MCP servers — gitnexus, github-grep, deepwiki, official plugins |
|
|
46
|
+
| [docs/bash-tools.md](docs/bash-tools.md) | Bash-native specialist CLIs — ghgrep, ctx7, deepwiki |
|
|
46
47
|
| [docs/cli-architecture.md](docs/cli-architecture.md) | CLI internals — install flow, diff/sync engine, config merge |
|
|
47
48
|
| [docs/docs-commands.md](docs/docs-commands.md) | Docs command suite — `show`, `list`, `cross-check`, output modes, drift checks |
|
|
48
49
|
| [docs/project-skills.md](docs/project-skills.md) | Legacy project-skill migration notes and current asset location |
|
|
@@ -62,7 +63,7 @@ xtrm init
|
|
|
62
63
|
|
|
63
64
|
# Verify
|
|
64
65
|
claude plugin list
|
|
65
|
-
# → xtrm-tools@xtrm-tools Version: 0.
|
|
66
|
+
# → xtrm-tools@xtrm-tools Version: 0.7.1 Status: enabled
|
|
66
67
|
```
|
|
67
68
|
|
|
68
69
|
**One-line run:**
|
|
@@ -103,7 +104,7 @@ xt merge
|
|
|
103
104
|
|
|
104
105
|
### Skills
|
|
105
106
|
|
|
106
|
-
Skills are resolved through a three-tier registry in `.xtrm/skills/` (`default` + `optional` + `user`). Optional packs are installed
|
|
107
|
+
Skills are resolved through a three-tier registry in `.xtrm/skills/` (`default` + `optional` + `user`). Optional packs are installed by default during `xt install`; activate any pack with `xt skills enable <pack>`. Current optional pack catalog: `research-methods`, `code-quality`, `security-ops`, `data-engineering`, and `architecture-design`.
|
|
107
108
|
|
|
108
109
|
Skills are organized into two categories: **xtrm workflow** skills built specifically for the xtrm stack, and **general-purpose** expert skills that work in any project.
|
|
109
110
|
|
|
@@ -123,10 +124,12 @@ These skills implement the xtrm-specific development workflow — session manage
|
|
|
123
124
|
| `planning` | Structured issue board from any spec, with phases and deps |
|
|
124
125
|
| `test-planning` | Test coverage planning alongside implementation work |
|
|
125
126
|
| `delegating` | Cost-optimized task delegation to background agents |
|
|
127
|
+
| `using-specialists` | Specialist routing and execution workflow (`specialists run/feed/result`) |
|
|
126
128
|
| `orchestrating-agents` | Multi-model orchestration (Gemini, Qwen handshake) |
|
|
127
129
|
| `documenting` | SSOT doc maintenance with drift detection |
|
|
128
130
|
| `sync-docs` | Doc audit and structural sync across a sprint |
|
|
129
131
|
| `skill-creator` | Create, improve, and evaluate skills |
|
|
132
|
+
| `specialists-creator` | Create and validate `.specialist.yaml` definitions |
|
|
130
133
|
| `find-skills` | Discover and install skills on demand |
|
|
131
134
|
| `creating-service-skills` | Generate operational service skill packages |
|
|
132
135
|
| `scoping-service-skills` | Task intake and service routing |
|
|
@@ -152,6 +155,7 @@ Domain expert skills that can be used in any project, independent of the xtrm wo
|
|
|
152
155
|
| `gitnexus-debugging` | Trace bugs through call chains |
|
|
153
156
|
| `gitnexus-refactoring` | Plan safe refactors via dependency mapping |
|
|
154
157
|
| `obsidian-cli` | Interact with Obsidian vaults via CLI |
|
|
158
|
+
| `deepwiki` | Query repository/library docs via DeepWiki |
|
|
155
159
|
|
|
156
160
|
---
|
|
157
161
|
|
|
@@ -225,6 +229,16 @@ Official Claude plugins installed by `xtrm init`: `serena`, `context7`, `github`
|
|
|
225
229
|
|
|
226
230
|
See [docs/mcp-servers.md](docs/mcp-servers.md) for configuration details.
|
|
227
231
|
|
|
232
|
+
## Specialist Bash Tools
|
|
233
|
+
|
|
234
|
+
| Tool | Purpose | Install source |
|
|
235
|
+
|------|---------|----------------|
|
|
236
|
+
| `ghgrep` | GitHub code search CLI wrapper over `mcp.grep.app` | Ships as `bin` in `xtrm-tools` |
|
|
237
|
+
| `ctx7` | Context7 docs + skills CLI | Installed by machine-bootstrap (`xt install` / `xt init`) |
|
|
238
|
+
| `deepwiki` | Repo documentation Q&A CLI | Installed by machine-bootstrap (`xt install` / `xt init`) |
|
|
239
|
+
|
|
240
|
+
See [docs/bash-tools.md](docs/bash-tools.md) for usage examples and when to use CLIs vs MCP equivalents.
|
|
241
|
+
|
|
228
242
|
---
|
|
229
243
|
|
|
230
244
|
## Issue Tracking (Beads)
|
|
@@ -243,6 +257,7 @@ See [XTRM-GUIDE.md](XTRM-GUIDE.md) for the full `bd` command reference.
|
|
|
243
257
|
|
|
244
258
|
| Version | Date | Highlights |
|
|
245
259
|
|---------|------|------------|
|
|
260
|
+
| 0.7.1 | 2026-04-02 | Optional packs pre-populated on install; Pi core symlink path fix; new default skills (`deepwiki`, `specialists-creator`, `using-specialists`) |
|
|
246
261
|
| 0.5.30 | 2026-03-22 | Fix statusline on fresh installs; `xt end --dry-run` |
|
|
247
262
|
| 0.5.29 | 2026-03-22 | Statusline truecolor gradient; `--no-verify` autocommit; xt-merge skill |
|
|
248
263
|
| 0.5.24 | 2026-03-21 | Hash-based docs drift detection; CLI docs cleanup |
|
package/cli/dist/index.cjs
CHANGED
|
@@ -43977,6 +43977,10 @@ function resolvePkgRoot() {
|
|
|
43977
43977
|
return candidates[0];
|
|
43978
43978
|
}
|
|
43979
43979
|
var PI_AGENT_DIR = process.env.PI_AGENT_DIR || import_path3.default.join((0, import_node_os.homedir)(), ".pi", "agent");
|
|
43980
|
+
var PI_MCP_ADAPTER_OVERRIDE_DIR = import_path3.default.join(PI_AGENT_DIR, "extensions", "pi-mcp-adapter");
|
|
43981
|
+
var PI_MCP_ADAPTER_REQUIRED_ENTRY = "commands.js";
|
|
43982
|
+
var PROJECT_EXTENSIONS_ENTRY = "../.xtrm/extensions";
|
|
43983
|
+
var PROJECT_SKILLS_ENTRY = "../.xtrm/skills/active/pi";
|
|
43980
43984
|
var MANAGED_EXTENSIONS = [
|
|
43981
43985
|
{ id: "core", displayName: "@xtrm/pi-core", isLibrary: true, required: true },
|
|
43982
43986
|
{ id: "auto-session-name", displayName: "auto-session-name", required: false },
|
|
@@ -44136,20 +44140,150 @@ function renderPiRuntimePlan(plan) {
|
|
|
44136
44140
|
console.log(kleur_default.yellow(" \u26A0 Missing required items.\n"));
|
|
44137
44141
|
}
|
|
44138
44142
|
}
|
|
44143
|
+
function mergePiSyncResults(base, incoming) {
|
|
44144
|
+
return {
|
|
44145
|
+
extensionsAdded: [...base.extensionsAdded, ...incoming.extensionsAdded],
|
|
44146
|
+
extensionsUpdated: [...base.extensionsUpdated, ...incoming.extensionsUpdated],
|
|
44147
|
+
extensionsRemoved: [...base.extensionsRemoved, ...incoming.extensionsRemoved],
|
|
44148
|
+
packagesInstalled: [...base.packagesInstalled, ...incoming.packagesInstalled],
|
|
44149
|
+
failed: [...base.failed, ...incoming.failed]
|
|
44150
|
+
};
|
|
44151
|
+
}
|
|
44139
44152
|
async function ensureCorePackageSymlink(coreSrcDir, projectRoot, dryRun, log) {
|
|
44140
|
-
if (!await import_fs_extra7.default.pathExists(coreSrcDir)) return;
|
|
44141
|
-
const
|
|
44153
|
+
if (!await import_fs_extra7.default.pathExists(coreSrcDir)) return "missing-source";
|
|
44154
|
+
const extensionsDir = import_path3.default.join(projectRoot, ".xtrm", "extensions");
|
|
44155
|
+
const nodeModulesDir = import_path3.default.join(extensionsDir, "node_modules", "@xtrm");
|
|
44142
44156
|
const symlinkPath = import_path3.default.join(nodeModulesDir, "pi-core");
|
|
44157
|
+
const expectedTarget = import_path3.default.resolve(coreSrcDir);
|
|
44143
44158
|
const existing = await import_fs_extra7.default.lstat(symlinkPath).catch(() => null);
|
|
44144
|
-
if (existing)
|
|
44159
|
+
if (existing) {
|
|
44160
|
+
if (existing.isSymbolicLink()) {
|
|
44161
|
+
const currentLinkTarget = await import_fs_extra7.default.readlink(symlinkPath);
|
|
44162
|
+
const resolvedTarget = import_path3.default.resolve(import_path3.default.dirname(symlinkPath), currentLinkTarget);
|
|
44163
|
+
if (resolvedTarget === expectedTarget) {
|
|
44164
|
+
return "ok";
|
|
44165
|
+
}
|
|
44166
|
+
}
|
|
44167
|
+
if (dryRun) {
|
|
44168
|
+
log?.(kleur_default.dim("[DRY RUN] would repair @xtrm/pi-core symlink target"));
|
|
44169
|
+
return "would-repair";
|
|
44170
|
+
}
|
|
44171
|
+
await import_fs_extra7.default.remove(symlinkPath);
|
|
44172
|
+
await import_fs_extra7.default.ensureDir(nodeModulesDir);
|
|
44173
|
+
const relTarget2 = import_path3.default.relative(nodeModulesDir, coreSrcDir);
|
|
44174
|
+
await import_fs_extra7.default.symlink(relTarget2, symlinkPath);
|
|
44175
|
+
log?.(kleur_default.dim("Repaired @xtrm/pi-core symlink \u2192 .xtrm/extensions/node_modules/@xtrm/pi-core"));
|
|
44176
|
+
return "repaired";
|
|
44177
|
+
}
|
|
44145
44178
|
if (dryRun) {
|
|
44146
|
-
log?.(kleur_default.dim(
|
|
44147
|
-
return;
|
|
44179
|
+
log?.(kleur_default.dim("[DRY RUN] would create @xtrm/pi-core symlink"));
|
|
44180
|
+
return "would-create";
|
|
44148
44181
|
}
|
|
44149
44182
|
await import_fs_extra7.default.ensureDir(nodeModulesDir);
|
|
44150
44183
|
const relTarget = import_path3.default.relative(nodeModulesDir, coreSrcDir);
|
|
44151
44184
|
await import_fs_extra7.default.symlink(relTarget, symlinkPath);
|
|
44152
|
-
log?.(kleur_default.dim(
|
|
44185
|
+
log?.(kleur_default.dim("Created @xtrm/pi-core symlink \u2192 .xtrm/extensions/node_modules/@xtrm/pi-core"));
|
|
44186
|
+
return "created";
|
|
44187
|
+
}
|
|
44188
|
+
async function remediateStalePiMcpAdapterOverride(dryRun, log) {
|
|
44189
|
+
const stat = await import_fs_extra7.default.lstat(PI_MCP_ADAPTER_OVERRIDE_DIR).catch(() => null);
|
|
44190
|
+
if (!stat) {
|
|
44191
|
+
return {
|
|
44192
|
+
path: PI_MCP_ADAPTER_OVERRIDE_DIR,
|
|
44193
|
+
found: false,
|
|
44194
|
+
stale: false,
|
|
44195
|
+
remediated: false
|
|
44196
|
+
};
|
|
44197
|
+
}
|
|
44198
|
+
if (stat.isSymbolicLink()) {
|
|
44199
|
+
return {
|
|
44200
|
+
path: PI_MCP_ADAPTER_OVERRIDE_DIR,
|
|
44201
|
+
found: true,
|
|
44202
|
+
stale: false,
|
|
44203
|
+
remediated: false
|
|
44204
|
+
};
|
|
44205
|
+
}
|
|
44206
|
+
const hasRequiredEntry = await import_fs_extra7.default.pathExists(import_path3.default.join(PI_MCP_ADAPTER_OVERRIDE_DIR, PI_MCP_ADAPTER_REQUIRED_ENTRY));
|
|
44207
|
+
if (stat.isDirectory() && hasRequiredEntry) {
|
|
44208
|
+
return {
|
|
44209
|
+
path: PI_MCP_ADAPTER_OVERRIDE_DIR,
|
|
44210
|
+
found: true,
|
|
44211
|
+
stale: false,
|
|
44212
|
+
remediated: false
|
|
44213
|
+
};
|
|
44214
|
+
}
|
|
44215
|
+
const reason = stat.isDirectory() ? `missing ${PI_MCP_ADAPTER_REQUIRED_ENTRY}` : "not a directory/symlink";
|
|
44216
|
+
if (dryRun) {
|
|
44217
|
+
log?.(kleur_default.dim(`[DRY RUN] would remove stale pi-mcp-adapter override (${reason})`));
|
|
44218
|
+
return {
|
|
44219
|
+
path: PI_MCP_ADAPTER_OVERRIDE_DIR,
|
|
44220
|
+
found: true,
|
|
44221
|
+
stale: true,
|
|
44222
|
+
remediated: false,
|
|
44223
|
+
reason
|
|
44224
|
+
};
|
|
44225
|
+
}
|
|
44226
|
+
await import_fs_extra7.default.remove(PI_MCP_ADAPTER_OVERRIDE_DIR);
|
|
44227
|
+
log?.(kleur_default.dim(`Removed stale pi-mcp-adapter override (${reason})`));
|
|
44228
|
+
return {
|
|
44229
|
+
path: PI_MCP_ADAPTER_OVERRIDE_DIR,
|
|
44230
|
+
found: true,
|
|
44231
|
+
stale: true,
|
|
44232
|
+
remediated: true,
|
|
44233
|
+
reason
|
|
44234
|
+
};
|
|
44235
|
+
}
|
|
44236
|
+
async function runPiLaunchPreflight(projectRoot, dryRun, log) {
|
|
44237
|
+
const staleOverride = await remediateStalePiMcpAdapterOverride(dryRun, log);
|
|
44238
|
+
const coreSymlinkStatus = await ensureCorePackageSymlink(
|
|
44239
|
+
import_path3.default.join(projectRoot, ".xtrm", "extensions", "core"),
|
|
44240
|
+
projectRoot,
|
|
44241
|
+
dryRun,
|
|
44242
|
+
log
|
|
44243
|
+
);
|
|
44244
|
+
return {
|
|
44245
|
+
coreSymlinkStatus,
|
|
44246
|
+
staleOverride
|
|
44247
|
+
};
|
|
44248
|
+
}
|
|
44249
|
+
function isXtrmExtensionsSetting(entry) {
|
|
44250
|
+
const normalizedEntry = entry.replaceAll("\\", "/").replace(/\/$/, "");
|
|
44251
|
+
return normalizedEntry === PROJECT_EXTENSIONS_ENTRY || normalizedEntry === ".xtrm/extensions";
|
|
44252
|
+
}
|
|
44253
|
+
async function cleanupLegacyProjectExtensionCopies(projectRoot, dryRun, log) {
|
|
44254
|
+
const piSettingsPath = import_path3.default.join(projectRoot, ".pi", "settings.json");
|
|
44255
|
+
let existingSettings = {};
|
|
44256
|
+
try {
|
|
44257
|
+
existingSettings = await import_fs_extra7.default.readJson(piSettingsPath);
|
|
44258
|
+
} catch {
|
|
44259
|
+
return { removed: [], failed: [] };
|
|
44260
|
+
}
|
|
44261
|
+
const pointsToXtrmExtensions = (existingSettings.extensions ?? []).some(isXtrmExtensionsSetting);
|
|
44262
|
+
if (!pointsToXtrmExtensions) return { removed: [], failed: [] };
|
|
44263
|
+
const legacyExtensionsDir = import_path3.default.join(projectRoot, ".pi", "extensions");
|
|
44264
|
+
if (!await import_fs_extra7.default.pathExists(legacyExtensionsDir)) return { removed: [], failed: [] };
|
|
44265
|
+
const removed = [];
|
|
44266
|
+
const failed = [];
|
|
44267
|
+
for (const ext of MANAGED_EXTENSIONS) {
|
|
44268
|
+
const legacyExtPath = import_path3.default.join(legacyExtensionsDir, ext.id);
|
|
44269
|
+
const legacyStat = await import_fs_extra7.default.lstat(legacyExtPath).catch(() => null);
|
|
44270
|
+
if (!legacyStat || legacyStat.isSymbolicLink() || !legacyStat.isDirectory()) {
|
|
44271
|
+
continue;
|
|
44272
|
+
}
|
|
44273
|
+
if (dryRun) {
|
|
44274
|
+
log?.(kleur_default.dim(`[DRY RUN] - .pi/extensions/${ext.id} (legacy copy)`));
|
|
44275
|
+
continue;
|
|
44276
|
+
}
|
|
44277
|
+
try {
|
|
44278
|
+
await import_fs_extra7.default.remove(legacyExtPath);
|
|
44279
|
+
removed.push(ext.id);
|
|
44280
|
+
log?.(kleur_default.dim(`Removed legacy .pi/extensions/${ext.id}`));
|
|
44281
|
+
} catch (err) {
|
|
44282
|
+
failed.push(ext.id);
|
|
44283
|
+
log?.(kleur_default.red(`\u2717 Failed to remove legacy .pi/extensions/${ext.id}: ${err}`));
|
|
44284
|
+
}
|
|
44285
|
+
}
|
|
44286
|
+
return { removed, failed };
|
|
44153
44287
|
}
|
|
44154
44288
|
async function updatePiSettings(projectRoot, dryRun, log) {
|
|
44155
44289
|
const piSettingsPath = import_path3.default.join(projectRoot, ".pi", "settings.json");
|
|
@@ -44162,16 +44296,14 @@ async function updatePiSettings(projectRoot, dryRun, log) {
|
|
|
44162
44296
|
existingSettings = await import_fs_extra7.default.readJson(piSettingsPath);
|
|
44163
44297
|
} catch {
|
|
44164
44298
|
}
|
|
44165
|
-
const extensionsEntry = "../.xtrm/extensions";
|
|
44166
|
-
const skillsEntry = "../.xtrm/skills/active/pi";
|
|
44167
44299
|
const existingPackages = (existingSettings.packages ?? []).filter(
|
|
44168
44300
|
(p) => !p.startsWith("./extensions/")
|
|
44169
44301
|
);
|
|
44170
44302
|
await import_fs_extra7.default.ensureDir(import_path3.default.join(projectRoot, ".pi"));
|
|
44171
44303
|
await import_fs_extra7.default.writeJson(piSettingsPath, {
|
|
44172
44304
|
...existingSettings,
|
|
44173
|
-
extensions: [
|
|
44174
|
-
skills: [
|
|
44305
|
+
extensions: [PROJECT_EXTENSIONS_ENTRY],
|
|
44306
|
+
skills: [PROJECT_SKILLS_ENTRY],
|
|
44175
44307
|
packages: existingPackages
|
|
44176
44308
|
}, { spaces: 2 });
|
|
44177
44309
|
log?.(kleur_default.dim(`Updated .pi/settings.json \u2192 .xtrm/extensions + .xtrm/skills/active/pi`));
|
|
@@ -44272,20 +44404,26 @@ async function runPiRuntimeSync(opts = {}) {
|
|
|
44272
44404
|
packagesInstalled: [],
|
|
44273
44405
|
failed: []
|
|
44274
44406
|
};
|
|
44407
|
+
const result = { ...emptyResult };
|
|
44275
44408
|
if (!await import_fs_extra7.default.pathExists(sourceDir)) {
|
|
44276
44409
|
console.log(kleur_default.dim("\n Managed extensions: skipped (not bundled in npm package)\n"));
|
|
44277
|
-
return
|
|
44410
|
+
return result;
|
|
44411
|
+
}
|
|
44412
|
+
const preflight = await runPiLaunchPreflight(resolvedProjectRoot, dryRun, log);
|
|
44413
|
+
if (preflight.staleOverride.remediated) {
|
|
44414
|
+
result.extensionsRemoved.push("pi-mcp-adapter");
|
|
44278
44415
|
}
|
|
44279
44416
|
if (isGlobal) {
|
|
44280
44417
|
const targetDir = import_path3.default.join(PI_AGENT_DIR, "extensions");
|
|
44281
44418
|
const plan = await inventoryPiRuntime(sourceDir, targetDir);
|
|
44282
44419
|
renderPiRuntimePlan(plan);
|
|
44283
|
-
if (plan.allPresent) return
|
|
44284
|
-
|
|
44420
|
+
if (plan.allPresent) return result;
|
|
44421
|
+
const synced = await executePiSync(plan, sourceDir, targetDir, {
|
|
44285
44422
|
dryRun,
|
|
44286
44423
|
isGlobal: true,
|
|
44287
44424
|
removeOrphaned: true
|
|
44288
44425
|
});
|
|
44426
|
+
return mergePiSyncResults(result, synced);
|
|
44289
44427
|
}
|
|
44290
44428
|
const installedPkgIds = getInstalledPiPackages();
|
|
44291
44429
|
const packageStatuses = [];
|
|
@@ -44306,7 +44444,9 @@ async function runPiRuntimeSync(opts = {}) {
|
|
|
44306
44444
|
console.log(kleur_default.yellow(` Missing: ${names}`));
|
|
44307
44445
|
}
|
|
44308
44446
|
console.log(kleur_default.dim(" " + "-".repeat(50)));
|
|
44309
|
-
const
|
|
44447
|
+
const legacyCleanup = await cleanupLegacyProjectExtensionCopies(resolvedProjectRoot, dryRun, log);
|
|
44448
|
+
result.extensionsRemoved.push(...legacyCleanup.removed);
|
|
44449
|
+
result.failed.push(...legacyCleanup.failed);
|
|
44310
44450
|
for (const status of missingPackages) {
|
|
44311
44451
|
const { pkg } = status;
|
|
44312
44452
|
if (dryRun) {
|
|
@@ -44339,7 +44479,6 @@ async function runPiRuntimeSync(opts = {}) {
|
|
|
44339
44479
|
}
|
|
44340
44480
|
}
|
|
44341
44481
|
await updatePiSettings(resolvedProjectRoot, dryRun, log);
|
|
44342
|
-
await ensureCorePackageSymlink(import_path3.default.join(sourceDir, "core"), resolvedProjectRoot, dryRun, log);
|
|
44343
44482
|
const requiredFailed = missingPackages.filter(
|
|
44344
44483
|
(s) => s.pkg.required && result.failed.includes(s.pkg.id)
|
|
44345
44484
|
);
|
|
@@ -44541,12 +44680,11 @@ async function launchWorktreeSession(opts) {
|
|
|
44541
44680
|
} catch {
|
|
44542
44681
|
}
|
|
44543
44682
|
}
|
|
44544
|
-
const worktreeExtensionsDir = import_node_path5.default.join(worktreePiDir, "extensions");
|
|
44545
44683
|
try {
|
|
44546
|
-
await
|
|
44684
|
+
await runPiLaunchPreflight(worktreePath, false);
|
|
44547
44685
|
} catch (error48) {
|
|
44548
44686
|
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
44549
|
-
console.log(kleur_default.dim(` warning:
|
|
44687
|
+
console.log(kleur_default.dim(` warning: pi launch preflight failed (${message})`));
|
|
44550
44688
|
}
|
|
44551
44689
|
}
|
|
44552
44690
|
if (runtime === "claude") {
|
|
@@ -44718,6 +44856,17 @@ var MANAGED_DEPS = [
|
|
|
44718
44856
|
install: {
|
|
44719
44857
|
default: [{ cmd: "npm", args: ["install", "-g", "@seflless/deepwiki"] }]
|
|
44720
44858
|
}
|
|
44859
|
+
},
|
|
44860
|
+
{
|
|
44861
|
+
id: "ctx7",
|
|
44862
|
+
cli: "ctx7",
|
|
44863
|
+
versionFlag: "--version",
|
|
44864
|
+
displayName: "ctx7",
|
|
44865
|
+
description: "Context7 CLI \u2014 library docs lookup for specialists",
|
|
44866
|
+
required: false,
|
|
44867
|
+
install: {
|
|
44868
|
+
default: [{ cmd: "npm", args: ["install", "-g", "ctx7"] }]
|
|
44869
|
+
}
|
|
44721
44870
|
}
|
|
44722
44871
|
];
|
|
44723
44872
|
function checkDep(dep) {
|
|
@@ -45424,6 +45573,33 @@ function createPiCommand() {
|
|
|
45424
45573
|
const bundleRoot = await findRepoRoot();
|
|
45425
45574
|
const sourceDir = import_path7.default.join(bundleRoot, ".xtrm", "extensions");
|
|
45426
45575
|
const globalTargetDir = import_path7.default.join(PI_AGENT_DIR4, "extensions");
|
|
45576
|
+
try {
|
|
45577
|
+
const staleOverride = await remediateStalePiMcpAdapterOverride(false);
|
|
45578
|
+
if (staleOverride.stale && staleOverride.remediated) {
|
|
45579
|
+
console.log(t.success(" \u2713 removed stale ~/.pi/agent/extensions/pi-mcp-adapter override"));
|
|
45580
|
+
} else if (staleOverride.stale) {
|
|
45581
|
+
console.log(kleur_default.yellow(" \u26A0 stale ~/.pi/agent/extensions/pi-mcp-adapter override detected"));
|
|
45582
|
+
allOk = false;
|
|
45583
|
+
} else {
|
|
45584
|
+
console.log(t.success(" \u2713 pi-mcp-adapter override check passed"));
|
|
45585
|
+
}
|
|
45586
|
+
} catch (error48) {
|
|
45587
|
+
console.log(kleur_default.yellow(` \u26A0 failed to remediate pi-mcp-adapter override: ${error48}`));
|
|
45588
|
+
allOk = false;
|
|
45589
|
+
}
|
|
45590
|
+
try {
|
|
45591
|
+
const coreStatus = await ensureCorePackageSymlink(import_path7.default.join(sourceDir, "core"), projectRoot, false);
|
|
45592
|
+
if (coreStatus === "repaired" || coreStatus === "created") {
|
|
45593
|
+
console.log(t.success(" \u2713 repaired .xtrm/extensions/node_modules/@xtrm/pi-core symlink"));
|
|
45594
|
+
} else if (coreStatus === "ok") {
|
|
45595
|
+
console.log(t.success(" \u2713 @xtrm/pi-core symlink is healthy"));
|
|
45596
|
+
} else if (coreStatus === "missing-source") {
|
|
45597
|
+
console.log(kleur_default.dim(" \u25CB @xtrm/pi-core source not bundled in this install"));
|
|
45598
|
+
}
|
|
45599
|
+
} catch (error48) {
|
|
45600
|
+
console.log(kleur_default.yellow(` \u26A0 failed to ensure @xtrm/pi-core symlink: ${error48}`));
|
|
45601
|
+
allOk = false;
|
|
45602
|
+
}
|
|
45427
45603
|
if (!await import_fs_extra11.default.pathExists(sourceDir)) {
|
|
45428
45604
|
console.log(kleur_default.dim(" \u25CB managed extensions not bundled in this install"));
|
|
45429
45605
|
} else {
|
|
@@ -50500,6 +50676,14 @@ function createAttachCommand() {
|
|
|
50500
50676
|
console.log(kleur_default.dim(` runtime: ${runtime} (resuming session)`));
|
|
50501
50677
|
console.log(kleur_default.dim(` path: ${target.path}
|
|
50502
50678
|
`));
|
|
50679
|
+
if (runtime === "pi") {
|
|
50680
|
+
try {
|
|
50681
|
+
await runPiLaunchPreflight(target.path, false);
|
|
50682
|
+
} catch (error48) {
|
|
50683
|
+
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
50684
|
+
console.log(kleur_default.dim(` warning: pi launch preflight failed (${message})`));
|
|
50685
|
+
}
|
|
50686
|
+
}
|
|
50503
50687
|
const result = (0, import_node_child_process8.spawnSync)(runtime, resumeArgs, {
|
|
50504
50688
|
cwd: target.path,
|
|
50505
50689
|
stdio: "inherit"
|
|
@@ -52462,6 +52646,7 @@ var ART = [
|
|
|
52462
52646
|
" \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u255D"
|
|
52463
52647
|
];
|
|
52464
52648
|
var ART_WIDTH = 84;
|
|
52649
|
+
var TAGLINE = "agent infrastructure layer \u2014 runtimes, skills,\n hooks, extensions, packages";
|
|
52465
52650
|
function isTTY2() {
|
|
52466
52651
|
return Boolean(process.stdout.isTTY);
|
|
52467
52652
|
}
|
|
@@ -52508,12 +52693,14 @@ async function typewriterTagline(text) {
|
|
|
52508
52693
|
const CHAR_DELAY = 42;
|
|
52509
52694
|
const prefix = ` \x1B[2m\u2014\x1B[0m \x1B[1m\x1B[37m`;
|
|
52510
52695
|
const suffix = `\x1B[0m \x1B[2m\u2014\x1B[0m`;
|
|
52511
|
-
|
|
52512
|
-
|
|
52513
|
-
|
|
52514
|
-
|
|
52696
|
+
for (const line of text.split("\n")) {
|
|
52697
|
+
process.stdout.write(prefix);
|
|
52698
|
+
for (const ch of line) {
|
|
52699
|
+
process.stdout.write(ch);
|
|
52700
|
+
await delay(CHAR_DELAY);
|
|
52701
|
+
}
|
|
52702
|
+
process.stdout.write(suffix + "\n");
|
|
52515
52703
|
}
|
|
52516
|
-
process.stdout.write(suffix + "\n");
|
|
52517
52704
|
}
|
|
52518
52705
|
var HUE_START = 170;
|
|
52519
52706
|
var HUE_END = 230;
|
|
@@ -52547,7 +52734,7 @@ async function renderTier0(version3) {
|
|
|
52547
52734
|
}
|
|
52548
52735
|
process.stdout.write(rule + "\n");
|
|
52549
52736
|
process.stdout.write(" \x1B[2mv" + version3 + "\x1B[0m\n");
|
|
52550
|
-
await typewriterTagline(
|
|
52737
|
+
await typewriterTagline(TAGLINE);
|
|
52551
52738
|
}
|
|
52552
52739
|
function renderTier1(version3) {
|
|
52553
52740
|
console.log("");
|
|
@@ -52557,7 +52744,7 @@ function renderTier1(version3) {
|
|
|
52557
52744
|
console.log(kleur_default.dim(" " + "\u2500".repeat(ART_WIDTH - 1)));
|
|
52558
52745
|
console.log(kleur_default.dim(" v" + version3));
|
|
52559
52746
|
console.log(
|
|
52560
|
-
" " + kleur_default.dim("\u2014") + " " + kleur_default.bold().white(
|
|
52747
|
+
" " + kleur_default.dim("\u2014") + " " + kleur_default.bold().white(TAGLINE) + " " + kleur_default.dim("\u2014")
|
|
52561
52748
|
);
|
|
52562
52749
|
console.log("");
|
|
52563
52750
|
}
|
|
@@ -52566,19 +52753,19 @@ function renderTier2(version3) {
|
|
|
52566
52753
|
console.log(
|
|
52567
52754
|
kleur_default.cyan(" \u25C8 ") + kleur_default.bold().white("xtrm-tools") + kleur_default.dim(" v" + version3)
|
|
52568
52755
|
);
|
|
52569
|
-
console.log(kleur_default.dim(
|
|
52756
|
+
console.log(kleur_default.dim(` ${TAGLINE}`));
|
|
52570
52757
|
console.log("");
|
|
52571
52758
|
}
|
|
52572
52759
|
function renderTier3(version3) {
|
|
52573
52760
|
console.log("");
|
|
52574
52761
|
console.log(kleur_default.bold(" xtrm-tools") + kleur_default.dim(" v" + version3));
|
|
52575
|
-
console.log(kleur_default.dim(
|
|
52762
|
+
console.log(kleur_default.dim(` ${TAGLINE}`));
|
|
52576
52763
|
console.log("");
|
|
52577
52764
|
}
|
|
52578
52765
|
function renderTier4(version3) {
|
|
52579
52766
|
console.log("");
|
|
52580
52767
|
console.log("xtrm-tools v" + version3);
|
|
52581
|
-
console.log(
|
|
52768
|
+
console.log(TAGLINE);
|
|
52582
52769
|
console.log("");
|
|
52583
52770
|
}
|
|
52584
52771
|
async function printBanner(version3) {
|
|
@@ -52609,7 +52796,7 @@ try {
|
|
|
52609
52796
|
} catch {
|
|
52610
52797
|
}
|
|
52611
52798
|
var program2 = new Command();
|
|
52612
|
-
program2.name("xtrm").description("
|
|
52799
|
+
program2.name("xtrm").description("Agent infrastructure layer for runtimes, skills, hooks, extensions, and packages").version(version2);
|
|
52613
52800
|
program2.exitOverride((err) => {
|
|
52614
52801
|
if (err.code === "commander.unknownCommand") {
|
|
52615
52802
|
console.error(kleur_default.red(`
|