xtrm-tools 0.7.1 → 0.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -1
- package/README.md +18 -3
- package/cli/dist/index.cjs +76 -19
- 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,8 @@ 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 PROJECT_EXTENSIONS_ENTRY = "../.xtrm/extensions";
|
|
43981
|
+
var PROJECT_SKILLS_ENTRY = "../.xtrm/skills/active/pi";
|
|
43980
43982
|
var MANAGED_EXTENSIONS = [
|
|
43981
43983
|
{ id: "core", displayName: "@xtrm/pi-core", isLibrary: true, required: true },
|
|
43982
43984
|
{ id: "auto-session-name", displayName: "auto-session-name", required: false },
|
|
@@ -44138,7 +44140,8 @@ function renderPiRuntimePlan(plan) {
|
|
|
44138
44140
|
}
|
|
44139
44141
|
async function ensureCorePackageSymlink(coreSrcDir, projectRoot, dryRun, log) {
|
|
44140
44142
|
if (!await import_fs_extra7.default.pathExists(coreSrcDir)) return;
|
|
44141
|
-
const
|
|
44143
|
+
const extensionsDir = import_path3.default.join(projectRoot, ".xtrm", "extensions");
|
|
44144
|
+
const nodeModulesDir = import_path3.default.join(extensionsDir, "node_modules", "@xtrm");
|
|
44142
44145
|
const symlinkPath = import_path3.default.join(nodeModulesDir, "pi-core");
|
|
44143
44146
|
const existing = await import_fs_extra7.default.lstat(symlinkPath).catch(() => null);
|
|
44144
44147
|
if (existing) return;
|
|
@@ -44149,7 +44152,46 @@ async function ensureCorePackageSymlink(coreSrcDir, projectRoot, dryRun, log) {
|
|
|
44149
44152
|
await import_fs_extra7.default.ensureDir(nodeModulesDir);
|
|
44150
44153
|
const relTarget = import_path3.default.relative(nodeModulesDir, coreSrcDir);
|
|
44151
44154
|
await import_fs_extra7.default.symlink(relTarget, symlinkPath);
|
|
44152
|
-
log?.(kleur_default.dim(`Created @xtrm/pi-core symlink
|
|
44155
|
+
log?.(kleur_default.dim(`Created @xtrm/pi-core symlink \u2192 .xtrm/extensions/node_modules/@xtrm/pi-core`));
|
|
44156
|
+
}
|
|
44157
|
+
function isXtrmExtensionsSetting(entry) {
|
|
44158
|
+
const normalizedEntry = entry.replaceAll("\\", "/").replace(/\/$/, "");
|
|
44159
|
+
return normalizedEntry === PROJECT_EXTENSIONS_ENTRY || normalizedEntry === ".xtrm/extensions";
|
|
44160
|
+
}
|
|
44161
|
+
async function cleanupLegacyProjectExtensionCopies(projectRoot, dryRun, log) {
|
|
44162
|
+
const piSettingsPath = import_path3.default.join(projectRoot, ".pi", "settings.json");
|
|
44163
|
+
let existingSettings = {};
|
|
44164
|
+
try {
|
|
44165
|
+
existingSettings = await import_fs_extra7.default.readJson(piSettingsPath);
|
|
44166
|
+
} catch {
|
|
44167
|
+
return { removed: [], failed: [] };
|
|
44168
|
+
}
|
|
44169
|
+
const pointsToXtrmExtensions = (existingSettings.extensions ?? []).some(isXtrmExtensionsSetting);
|
|
44170
|
+
if (!pointsToXtrmExtensions) return { removed: [], failed: [] };
|
|
44171
|
+
const legacyExtensionsDir = import_path3.default.join(projectRoot, ".pi", "extensions");
|
|
44172
|
+
if (!await import_fs_extra7.default.pathExists(legacyExtensionsDir)) return { removed: [], failed: [] };
|
|
44173
|
+
const removed = [];
|
|
44174
|
+
const failed = [];
|
|
44175
|
+
for (const ext of MANAGED_EXTENSIONS) {
|
|
44176
|
+
const legacyExtPath = import_path3.default.join(legacyExtensionsDir, ext.id);
|
|
44177
|
+
const legacyStat = await import_fs_extra7.default.lstat(legacyExtPath).catch(() => null);
|
|
44178
|
+
if (!legacyStat || legacyStat.isSymbolicLink() || !legacyStat.isDirectory()) {
|
|
44179
|
+
continue;
|
|
44180
|
+
}
|
|
44181
|
+
if (dryRun) {
|
|
44182
|
+
log?.(kleur_default.dim(`[DRY RUN] - .pi/extensions/${ext.id} (legacy copy)`));
|
|
44183
|
+
continue;
|
|
44184
|
+
}
|
|
44185
|
+
try {
|
|
44186
|
+
await import_fs_extra7.default.remove(legacyExtPath);
|
|
44187
|
+
removed.push(ext.id);
|
|
44188
|
+
log?.(kleur_default.dim(`Removed legacy .pi/extensions/${ext.id}`));
|
|
44189
|
+
} catch (err) {
|
|
44190
|
+
failed.push(ext.id);
|
|
44191
|
+
log?.(kleur_default.red(`\u2717 Failed to remove legacy .pi/extensions/${ext.id}: ${err}`));
|
|
44192
|
+
}
|
|
44193
|
+
}
|
|
44194
|
+
return { removed, failed };
|
|
44153
44195
|
}
|
|
44154
44196
|
async function updatePiSettings(projectRoot, dryRun, log) {
|
|
44155
44197
|
const piSettingsPath = import_path3.default.join(projectRoot, ".pi", "settings.json");
|
|
@@ -44162,16 +44204,14 @@ async function updatePiSettings(projectRoot, dryRun, log) {
|
|
|
44162
44204
|
existingSettings = await import_fs_extra7.default.readJson(piSettingsPath);
|
|
44163
44205
|
} catch {
|
|
44164
44206
|
}
|
|
44165
|
-
const extensionsEntry = "../.xtrm/extensions";
|
|
44166
|
-
const skillsEntry = "../.xtrm/skills/active/pi";
|
|
44167
44207
|
const existingPackages = (existingSettings.packages ?? []).filter(
|
|
44168
44208
|
(p) => !p.startsWith("./extensions/")
|
|
44169
44209
|
);
|
|
44170
44210
|
await import_fs_extra7.default.ensureDir(import_path3.default.join(projectRoot, ".pi"));
|
|
44171
44211
|
await import_fs_extra7.default.writeJson(piSettingsPath, {
|
|
44172
44212
|
...existingSettings,
|
|
44173
|
-
extensions: [
|
|
44174
|
-
skills: [
|
|
44213
|
+
extensions: [PROJECT_EXTENSIONS_ENTRY],
|
|
44214
|
+
skills: [PROJECT_SKILLS_ENTRY],
|
|
44175
44215
|
packages: existingPackages
|
|
44176
44216
|
}, { spaces: 2 });
|
|
44177
44217
|
log?.(kleur_default.dim(`Updated .pi/settings.json \u2192 .xtrm/extensions + .xtrm/skills/active/pi`));
|
|
@@ -44307,6 +44347,9 @@ async function runPiRuntimeSync(opts = {}) {
|
|
|
44307
44347
|
}
|
|
44308
44348
|
console.log(kleur_default.dim(" " + "-".repeat(50)));
|
|
44309
44349
|
const result = { ...emptyResult };
|
|
44350
|
+
const legacyCleanup = await cleanupLegacyProjectExtensionCopies(resolvedProjectRoot, dryRun, log);
|
|
44351
|
+
result.extensionsRemoved.push(...legacyCleanup.removed);
|
|
44352
|
+
result.failed.push(...legacyCleanup.failed);
|
|
44310
44353
|
for (const status of missingPackages) {
|
|
44311
44354
|
const { pkg } = status;
|
|
44312
44355
|
if (dryRun) {
|
|
@@ -44541,9 +44584,9 @@ async function launchWorktreeSession(opts) {
|
|
|
44541
44584
|
} catch {
|
|
44542
44585
|
}
|
|
44543
44586
|
}
|
|
44544
|
-
const
|
|
44587
|
+
const coreExtDir = import_node_path5.default.join(worktreePath, ".xtrm", "extensions", "core");
|
|
44545
44588
|
try {
|
|
44546
|
-
await ensureCorePackageSymlink(
|
|
44589
|
+
await ensureCorePackageSymlink(coreExtDir, worktreePath, false);
|
|
44547
44590
|
} catch (error48) {
|
|
44548
44591
|
const message = error48 instanceof Error ? error48.message : String(error48);
|
|
44549
44592
|
console.log(kleur_default.dim(` warning: could not ensure @xtrm/pi-core symlink (${message})`));
|
|
@@ -44718,6 +44761,17 @@ var MANAGED_DEPS = [
|
|
|
44718
44761
|
install: {
|
|
44719
44762
|
default: [{ cmd: "npm", args: ["install", "-g", "@seflless/deepwiki"] }]
|
|
44720
44763
|
}
|
|
44764
|
+
},
|
|
44765
|
+
{
|
|
44766
|
+
id: "ctx7",
|
|
44767
|
+
cli: "ctx7",
|
|
44768
|
+
versionFlag: "--version",
|
|
44769
|
+
displayName: "ctx7",
|
|
44770
|
+
description: "Context7 CLI \u2014 library docs lookup for specialists",
|
|
44771
|
+
required: false,
|
|
44772
|
+
install: {
|
|
44773
|
+
default: [{ cmd: "npm", args: ["install", "-g", "ctx7"] }]
|
|
44774
|
+
}
|
|
44721
44775
|
}
|
|
44722
44776
|
];
|
|
44723
44777
|
function checkDep(dep) {
|
|
@@ -52462,6 +52516,7 @@ var ART = [
|
|
|
52462
52516
|
" \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
52517
|
];
|
|
52464
52518
|
var ART_WIDTH = 84;
|
|
52519
|
+
var TAGLINE = "agent infrastructure layer \u2014 runtimes, skills,\n hooks, extensions, packages";
|
|
52465
52520
|
function isTTY2() {
|
|
52466
52521
|
return Boolean(process.stdout.isTTY);
|
|
52467
52522
|
}
|
|
@@ -52508,12 +52563,14 @@ async function typewriterTagline(text) {
|
|
|
52508
52563
|
const CHAR_DELAY = 42;
|
|
52509
52564
|
const prefix = ` \x1B[2m\u2014\x1B[0m \x1B[1m\x1B[37m`;
|
|
52510
52565
|
const suffix = `\x1B[0m \x1B[2m\u2014\x1B[0m`;
|
|
52511
|
-
|
|
52512
|
-
|
|
52513
|
-
|
|
52514
|
-
|
|
52566
|
+
for (const line of text.split("\n")) {
|
|
52567
|
+
process.stdout.write(prefix);
|
|
52568
|
+
for (const ch of line) {
|
|
52569
|
+
process.stdout.write(ch);
|
|
52570
|
+
await delay(CHAR_DELAY);
|
|
52571
|
+
}
|
|
52572
|
+
process.stdout.write(suffix + "\n");
|
|
52515
52573
|
}
|
|
52516
|
-
process.stdout.write(suffix + "\n");
|
|
52517
52574
|
}
|
|
52518
52575
|
var HUE_START = 170;
|
|
52519
52576
|
var HUE_END = 230;
|
|
@@ -52547,7 +52604,7 @@ async function renderTier0(version3) {
|
|
|
52547
52604
|
}
|
|
52548
52605
|
process.stdout.write(rule + "\n");
|
|
52549
52606
|
process.stdout.write(" \x1B[2mv" + version3 + "\x1B[0m\n");
|
|
52550
|
-
await typewriterTagline(
|
|
52607
|
+
await typewriterTagline(TAGLINE);
|
|
52551
52608
|
}
|
|
52552
52609
|
function renderTier1(version3) {
|
|
52553
52610
|
console.log("");
|
|
@@ -52557,7 +52614,7 @@ function renderTier1(version3) {
|
|
|
52557
52614
|
console.log(kleur_default.dim(" " + "\u2500".repeat(ART_WIDTH - 1)));
|
|
52558
52615
|
console.log(kleur_default.dim(" v" + version3));
|
|
52559
52616
|
console.log(
|
|
52560
|
-
" " + kleur_default.dim("\u2014") + " " + kleur_default.bold().white(
|
|
52617
|
+
" " + kleur_default.dim("\u2014") + " " + kleur_default.bold().white(TAGLINE) + " " + kleur_default.dim("\u2014")
|
|
52561
52618
|
);
|
|
52562
52619
|
console.log("");
|
|
52563
52620
|
}
|
|
@@ -52566,19 +52623,19 @@ function renderTier2(version3) {
|
|
|
52566
52623
|
console.log(
|
|
52567
52624
|
kleur_default.cyan(" \u25C8 ") + kleur_default.bold().white("xtrm-tools") + kleur_default.dim(" v" + version3)
|
|
52568
52625
|
);
|
|
52569
|
-
console.log(kleur_default.dim(
|
|
52626
|
+
console.log(kleur_default.dim(` ${TAGLINE}`));
|
|
52570
52627
|
console.log("");
|
|
52571
52628
|
}
|
|
52572
52629
|
function renderTier3(version3) {
|
|
52573
52630
|
console.log("");
|
|
52574
52631
|
console.log(kleur_default.bold(" xtrm-tools") + kleur_default.dim(" v" + version3));
|
|
52575
|
-
console.log(kleur_default.dim(
|
|
52632
|
+
console.log(kleur_default.dim(` ${TAGLINE}`));
|
|
52576
52633
|
console.log("");
|
|
52577
52634
|
}
|
|
52578
52635
|
function renderTier4(version3) {
|
|
52579
52636
|
console.log("");
|
|
52580
52637
|
console.log("xtrm-tools v" + version3);
|
|
52581
|
-
console.log(
|
|
52638
|
+
console.log(TAGLINE);
|
|
52582
52639
|
console.log("");
|
|
52583
52640
|
}
|
|
52584
52641
|
async function printBanner(version3) {
|
|
@@ -52609,7 +52666,7 @@ try {
|
|
|
52609
52666
|
} catch {
|
|
52610
52667
|
}
|
|
52611
52668
|
var program2 = new Command();
|
|
52612
|
-
program2.name("xtrm").description("
|
|
52669
|
+
program2.name("xtrm").description("Agent infrastructure layer for runtimes, skills, hooks, extensions, and packages").version(version2);
|
|
52613
52670
|
program2.exitOverride((err) => {
|
|
52614
52671
|
if (err.code === "commander.unknownCommand") {
|
|
52615
52672
|
console.error(kleur_default.red(`
|