xtrm-tools 0.5.11 → 0.5.14
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 +4 -1
- package/cli/dist/index.cjs +31 -72
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/hooks/beads-gate-messages.mjs +4 -4
- package/hooks/gitnexus/gitnexus-hook.cjs +1 -1
- package/hooks/hooks.json +5 -11
- package/hooks/quality-check-env.mjs +79 -0
- package/hooks/quality-check.cjs +6 -6
- package/hooks/statusline.mjs +115 -0
- package/package.json +1 -1
- package/hooks/branch-state.mjs +0 -39
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
9
9
|
|
|
10
10
|
## [Unreleased]
|
|
11
11
|
|
|
12
|
+
### Added
|
|
13
|
+
- gitnexus hook now fires on Grep/Read/Glob tools (parity with Pi); quality-check covers .cjs/.mjs files; quality gate env pre-check at SessionStart; policies.md rewritten from scaffold; using-xtrm SKILL.md rewritten; worktree-session migrated to bd worktree; branch state + xt end reminders in gate messages
|
|
14
|
+
|
|
12
15
|
---
|
|
13
16
|
|
|
14
17
|
## [0.5.0] - 2026-03-20
|
|
@@ -529,4 +532,4 @@ ln -s ~/.claude/skills/prompt-improving ~/.claude/skills/p
|
|
|
529
532
|
- **Skill `p`**: 118 lines, 52KB references (9 files)
|
|
530
533
|
- **Skill `ccs-delegation`**: 486 lines, 103KB references (6 files)
|
|
531
534
|
- **Total overhead**: 155KB token cost per skill activation
|
|
532
|
-
- **Load time**: 5-8 seconds per skill invocation
|
|
535
|
+
- **Load time**: 5-8 seconds per skill invocation
|
package/cli/dist/index.cjs
CHANGED
|
@@ -6053,7 +6053,7 @@ var require_dist = __commonJS({
|
|
|
6053
6053
|
});
|
|
6054
6054
|
};
|
|
6055
6055
|
}
|
|
6056
|
-
var
|
|
6056
|
+
var prompts6 = require_prompts();
|
|
6057
6057
|
var passOn = ["suggest", "format", "onState", "validate", "onRender", "type"];
|
|
6058
6058
|
var noop = () => {
|
|
6059
6059
|
};
|
|
@@ -6104,7 +6104,7 @@ var require_dist = __commonJS({
|
|
|
6104
6104
|
var _question2 = question;
|
|
6105
6105
|
name = _question2.name;
|
|
6106
6106
|
type = _question2.type;
|
|
6107
|
-
if (
|
|
6107
|
+
if (prompts6[type] === void 0) {
|
|
6108
6108
|
throw new Error(`prompt type (${type}) is not defined`);
|
|
6109
6109
|
}
|
|
6110
6110
|
if (override2[question.name] !== void 0) {
|
|
@@ -6115,7 +6115,7 @@ var require_dist = __commonJS({
|
|
|
6115
6115
|
}
|
|
6116
6116
|
}
|
|
6117
6117
|
try {
|
|
6118
|
-
answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : yield
|
|
6118
|
+
answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : yield prompts6[type](question);
|
|
6119
6119
|
answers[name] = answer = yield getFormattedAnswer(question, answer, true);
|
|
6120
6120
|
quit = yield onSubmit(question, answer, answers);
|
|
6121
6121
|
} catch (err) {
|
|
@@ -6147,7 +6147,7 @@ var require_dist = __commonJS({
|
|
|
6147
6147
|
}
|
|
6148
6148
|
module2.exports = Object.assign(prompt, {
|
|
6149
6149
|
prompt,
|
|
6150
|
-
prompts:
|
|
6150
|
+
prompts: prompts6,
|
|
6151
6151
|
inject,
|
|
6152
6152
|
override
|
|
6153
6153
|
});
|
|
@@ -8234,7 +8234,7 @@ var require_prompts2 = __commonJS({
|
|
|
8234
8234
|
var require_lib = __commonJS({
|
|
8235
8235
|
"../node_modules/prompts/lib/index.js"(exports2, module2) {
|
|
8236
8236
|
"use strict";
|
|
8237
|
-
var
|
|
8237
|
+
var prompts6 = require_prompts2();
|
|
8238
8238
|
var passOn = ["suggest", "format", "onState", "validate", "onRender", "type"];
|
|
8239
8239
|
var noop = () => {
|
|
8240
8240
|
};
|
|
@@ -8266,7 +8266,7 @@ var require_lib = __commonJS({
|
|
|
8266
8266
|
throw new Error("prompt message is required");
|
|
8267
8267
|
}
|
|
8268
8268
|
({ name, type } = question);
|
|
8269
|
-
if (
|
|
8269
|
+
if (prompts6[type] === void 0) {
|
|
8270
8270
|
throw new Error(`prompt type (${type}) is not defined`);
|
|
8271
8271
|
}
|
|
8272
8272
|
if (override2[question.name] !== void 0) {
|
|
@@ -8277,7 +8277,7 @@ var require_lib = __commonJS({
|
|
|
8277
8277
|
}
|
|
8278
8278
|
}
|
|
8279
8279
|
try {
|
|
8280
|
-
answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : await
|
|
8280
|
+
answer = prompt._injected ? getInjectedAnswer(prompt._injected, question.initial) : await prompts6[type](question);
|
|
8281
8281
|
answers[name] = answer = await getFormattedAnswer(question, answer, true);
|
|
8282
8282
|
quit = await onSubmit(question, answer, answers);
|
|
8283
8283
|
} catch (err) {
|
|
@@ -8300,7 +8300,7 @@ var require_lib = __commonJS({
|
|
|
8300
8300
|
function override(answers) {
|
|
8301
8301
|
prompt._override = Object.assign({}, answers);
|
|
8302
8302
|
}
|
|
8303
|
-
module2.exports = Object.assign(prompt, { prompt, prompts:
|
|
8303
|
+
module2.exports = Object.assign(prompt, { prompt, prompts: prompts6, inject, override });
|
|
8304
8304
|
}
|
|
8305
8305
|
});
|
|
8306
8306
|
|
|
@@ -33948,7 +33948,7 @@ function init(open, close) {
|
|
|
33948
33948
|
var kleur_default = $;
|
|
33949
33949
|
|
|
33950
33950
|
// src/commands/install.ts
|
|
33951
|
-
var
|
|
33951
|
+
var import_prompts = __toESM(require_prompts3(), 1);
|
|
33952
33952
|
|
|
33953
33953
|
// ../node_modules/eventemitter3/index.mjs
|
|
33954
33954
|
var import_index2 = __toESM(require_eventemitter3(), 1);
|
|
@@ -36986,7 +36986,6 @@ var Conf = class {
|
|
|
36986
36986
|
};
|
|
36987
36987
|
|
|
36988
36988
|
// src/core/context.ts
|
|
36989
|
-
var import_prompts = __toESM(require_prompts3(), 1);
|
|
36990
36989
|
var config = null;
|
|
36991
36990
|
function getConfig() {
|
|
36992
36991
|
if (!config) {
|
|
@@ -37022,58 +37021,17 @@ function resolveTargets(selector, candidates) {
|
|
|
37022
37021
|
}
|
|
37023
37022
|
async function getContext(options = {}) {
|
|
37024
37023
|
const { selector, createMissingDirs = true } = options;
|
|
37025
|
-
const choices = [];
|
|
37026
37024
|
const candidates = getCandidatePaths();
|
|
37027
37025
|
const directTargets = resolveTargets(selector, candidates);
|
|
37028
|
-
if (directTargets) {
|
|
37029
|
-
const activeConfig2 = getConfig();
|
|
37030
|
-
if (createMissingDirs) {
|
|
37031
|
-
for (const target of directTargets) {
|
|
37032
|
-
await import_fs_extra.default.ensureDir(target);
|
|
37033
|
-
}
|
|
37034
|
-
}
|
|
37035
|
-
return {
|
|
37036
|
-
targets: directTargets,
|
|
37037
|
-
syncMode: activeConfig2.get("syncMode"),
|
|
37038
|
-
config: activeConfig2
|
|
37039
|
-
};
|
|
37040
|
-
}
|
|
37041
37026
|
const activeConfig = getConfig();
|
|
37042
|
-
|
|
37043
|
-
const exists = await import_fs_extra.default.pathExists(c.path);
|
|
37044
|
-
const icon = exists ? kleur_default.green("\u25CF") : kleur_default.gray("\u25CB");
|
|
37045
|
-
const desc = exists ? "Found" : "Not found (will create)";
|
|
37046
|
-
choices.push({
|
|
37047
|
-
title: `${icon} ${c.label} (${c.path})`,
|
|
37048
|
-
description: desc,
|
|
37049
|
-
value: c.path,
|
|
37050
|
-
selected: exists
|
|
37051
|
-
// Pre-select existing environments
|
|
37052
|
-
});
|
|
37053
|
-
}
|
|
37054
|
-
const response = await (0, import_prompts.default)({
|
|
37055
|
-
type: "multiselect",
|
|
37056
|
-
name: "targets",
|
|
37057
|
-
message: "Select target environment(s):",
|
|
37058
|
-
choices,
|
|
37059
|
-
hint: "- Space to select. Return to submit",
|
|
37060
|
-
instructions: false
|
|
37061
|
-
});
|
|
37062
|
-
if (response.targets === void 0) {
|
|
37063
|
-
console.log(kleur_default.gray("\nCancelled."));
|
|
37064
|
-
process.exit(130);
|
|
37065
|
-
}
|
|
37066
|
-
if (response.targets.length === 0) {
|
|
37067
|
-
console.log(kleur_default.gray("No targets selected."));
|
|
37068
|
-
process.exit(0);
|
|
37069
|
-
}
|
|
37027
|
+
const selectedPaths = directTargets ?? candidates.map((c) => c.path);
|
|
37070
37028
|
if (createMissingDirs) {
|
|
37071
|
-
for (const target of
|
|
37029
|
+
for (const target of selectedPaths) {
|
|
37072
37030
|
await import_fs_extra.default.ensureDir(target);
|
|
37073
37031
|
}
|
|
37074
37032
|
}
|
|
37075
37033
|
return {
|
|
37076
|
-
targets:
|
|
37034
|
+
targets: selectedPaths,
|
|
37077
37035
|
syncMode: activeConfig.get("syncMode"),
|
|
37078
37036
|
config: activeConfig
|
|
37079
37037
|
};
|
|
@@ -40160,7 +40118,7 @@ async function handleMissingEnvVars(missing) {
|
|
|
40160
40118
|
if (missing.length === 0) {
|
|
40161
40119
|
return true;
|
|
40162
40120
|
}
|
|
40163
|
-
const
|
|
40121
|
+
const prompts6 = (await Promise.resolve().then(() => __toESM(require_prompts3(), 1))).default;
|
|
40164
40122
|
const answers = {};
|
|
40165
40123
|
for (const key of missing) {
|
|
40166
40124
|
const config3 = REQUIRED_ENV_VARS[key];
|
|
@@ -40172,7 +40130,7 @@ async function handleMissingEnvVars(missing) {
|
|
|
40172
40130
|
console.log(kleur_default.yellow(`
|
|
40173
40131
|
\u26A0\uFE0F ${key} is required by a selected MCP server`));
|
|
40174
40132
|
}
|
|
40175
|
-
const { value } = await
|
|
40133
|
+
const { value } = await prompts6({
|
|
40176
40134
|
type: "text",
|
|
40177
40135
|
name: "value",
|
|
40178
40136
|
message: `Enter ${key}:`,
|
|
@@ -40385,8 +40343,8 @@ async function syncMcpServersWithCli(agent, mcpConfig, dryRun = false, prune = f
|
|
|
40385
40343
|
}
|
|
40386
40344
|
let selectedNames = toAdd.map(([name]) => name);
|
|
40387
40345
|
if (!dryRun) {
|
|
40388
|
-
const
|
|
40389
|
-
const { selected } = await
|
|
40346
|
+
const prompts6 = await Promise.resolve().then(() => __toESM(require_prompts3(), 1));
|
|
40347
|
+
const { selected } = await prompts6.default({
|
|
40390
40348
|
type: "multiselect",
|
|
40391
40349
|
name: "selected",
|
|
40392
40350
|
message: `Select MCP servers to install via ${agent} CLI:`,
|
|
@@ -41203,7 +41161,7 @@ function createInstallCommand() {
|
|
|
41203
41161
|
const missing = [!beadsOk && "bd", !doltOk && "dolt"].filter(Boolean).join(", ");
|
|
41204
41162
|
let doInstall = effectiveYes;
|
|
41205
41163
|
if (!effectiveYes) {
|
|
41206
|
-
const { install } = await (0,
|
|
41164
|
+
const { install } = await (0, import_prompts.default)({
|
|
41207
41165
|
type: "confirm",
|
|
41208
41166
|
name: "install",
|
|
41209
41167
|
message: `Install beads + dolt? (${missing} not found) \u2014 required for workflow enforcement hooks`,
|
|
@@ -41289,7 +41247,7 @@ function createInstallCommand() {
|
|
|
41289
41247
|
}
|
|
41290
41248
|
if (!effectiveYes) {
|
|
41291
41249
|
const totalChangesCount = allChanges.reduce((s, c) => s + c.totalChanges, 0);
|
|
41292
|
-
const { confirm } = await (0,
|
|
41250
|
+
const { confirm } = await (0, import_prompts.default)({
|
|
41293
41251
|
type: "confirm",
|
|
41294
41252
|
name: "confirm",
|
|
41295
41253
|
message: `Proceed with ${actionLabel} (${totalChangesCount} total changes)?`,
|
|
@@ -41482,7 +41440,7 @@ var import_node_os6 = require("os");
|
|
|
41482
41440
|
var import_fs_extra13 = __toESM(require_lib2(), 1);
|
|
41483
41441
|
|
|
41484
41442
|
// src/commands/install-pi.ts
|
|
41485
|
-
var
|
|
41443
|
+
var import_prompts2 = __toESM(require_prompts3(), 1);
|
|
41486
41444
|
var import_fs_extra12 = __toESM(require_lib2(), 1);
|
|
41487
41445
|
var import_path12 = __toESM(require("path"), 1);
|
|
41488
41446
|
var import_node_child_process4 = require("child_process");
|
|
@@ -41632,10 +41590,10 @@ function createInstallPiCommand() {
|
|
|
41632
41590
|
continue;
|
|
41633
41591
|
}
|
|
41634
41592
|
if (!field.required && !yes) {
|
|
41635
|
-
const { include } = await (0,
|
|
41593
|
+
const { include } = await (0, import_prompts2.default)({ type: "confirm", name: "include", message: ` Configure ${field.label}? (optional)`, initial: false });
|
|
41636
41594
|
if (!include) continue;
|
|
41637
41595
|
}
|
|
41638
|
-
const { value } = await (0,
|
|
41596
|
+
const { value } = await (0, import_prompts2.default)({ type: field.secret ? "password" : "text", name: "value", message: ` ${field.label}`, hint: field.hint, validate: (v) => field.required && !v ? "Required" : true });
|
|
41639
41597
|
if (value) values[field.key] = value;
|
|
41640
41598
|
}
|
|
41641
41599
|
await import_fs_extra12.default.ensureDir(PI_AGENT_DIR2);
|
|
@@ -41644,7 +41602,7 @@ function createInstallPiCommand() {
|
|
|
41644
41602
|
for (const name of ["models.json", "auth.json", "settings.json"]) {
|
|
41645
41603
|
const destPath = import_path12.default.join(PI_AGENT_DIR2, name);
|
|
41646
41604
|
if (name === "auth.json" && await import_fs_extra12.default.pathExists(destPath) && !yes) {
|
|
41647
|
-
const { overwrite } = await (0,
|
|
41605
|
+
const { overwrite } = await (0, import_prompts2.default)({ type: "confirm", name: "overwrite", message: ` ${name} already exists \u2014 overwrite? (OAuth tokens will be lost)`, initial: false });
|
|
41648
41606
|
if (!overwrite) {
|
|
41649
41607
|
console.log(t.muted(` skipped ${name}`));
|
|
41650
41608
|
continue;
|
|
@@ -42049,7 +42007,7 @@ function getProjectRoot() {
|
|
|
42049
42007
|
}
|
|
42050
42008
|
|
|
42051
42009
|
// src/commands/status.ts
|
|
42052
|
-
var
|
|
42010
|
+
var import_prompts3 = __toESM(require_prompts3(), 1);
|
|
42053
42011
|
|
|
42054
42012
|
// src/core/manifest.ts
|
|
42055
42013
|
var import_path16 = require("path");
|
|
@@ -55953,7 +55911,7 @@ function createStatusCommand() {
|
|
|
55953
55911
|
console.log(kleur_default.yellow(`
|
|
55954
55912
|
\u26A0 ${totalPending} pending change${totalPending !== 1 ? "s" : ""} across ${pending.length} environment${pending.length !== 1 ? "s" : ""}
|
|
55955
55913
|
`));
|
|
55956
|
-
const { selected } = await (0,
|
|
55914
|
+
const { selected } = await (0, import_prompts3.default)({
|
|
55957
55915
|
type: "multiselect",
|
|
55958
55916
|
name: "selected",
|
|
55959
55917
|
message: "Select environments to sync:",
|
|
@@ -56175,8 +56133,9 @@ var CANONICAL_HOOKS = /* @__PURE__ */ new Set([
|
|
|
56175
56133
|
"beads-claim-sync.mjs",
|
|
56176
56134
|
"beads-compact-save.mjs",
|
|
56177
56135
|
"beads-compact-restore.mjs",
|
|
56178
|
-
"
|
|
56136
|
+
"statusline.mjs",
|
|
56179
56137
|
"quality-check.cjs",
|
|
56138
|
+
"quality-check-env.mjs",
|
|
56180
56139
|
"quality-check.py",
|
|
56181
56140
|
"gitnexus",
|
|
56182
56141
|
// directory
|
|
@@ -56449,7 +56408,7 @@ function createCleanCommand() {
|
|
|
56449
56408
|
}
|
|
56450
56409
|
|
|
56451
56410
|
// src/commands/end.ts
|
|
56452
|
-
var
|
|
56411
|
+
var import_prompts4 = __toESM(require_prompts3(), 1);
|
|
56453
56412
|
var import_node_child_process6 = require("child_process");
|
|
56454
56413
|
function git(args, cwd) {
|
|
56455
56414
|
const r = (0, import_node_child_process6.spawnSync)("git", args, { cwd, encoding: "utf8", stdio: "pipe" });
|
|
@@ -56603,7 +56562,7 @@ function createEndCommand() {
|
|
|
56603
56562
|
if (!opts.keep) {
|
|
56604
56563
|
let doRemove = opts.yes;
|
|
56605
56564
|
if (!opts.yes) {
|
|
56606
|
-
const { remove } = await (0,
|
|
56565
|
+
const { remove } = await (0, import_prompts4.default)({
|
|
56607
56566
|
type: "confirm",
|
|
56608
56567
|
name: "remove",
|
|
56609
56568
|
message: `Remove local worktree at ${cwd}?`,
|
|
@@ -56637,7 +56596,7 @@ function createEndCommand() {
|
|
|
56637
56596
|
}
|
|
56638
56597
|
|
|
56639
56598
|
// src/commands/worktree.ts
|
|
56640
|
-
var
|
|
56599
|
+
var import_prompts5 = __toESM(require_prompts3(), 1);
|
|
56641
56600
|
var import_node_child_process7 = require("child_process");
|
|
56642
56601
|
function listXtWorktrees(repoRoot) {
|
|
56643
56602
|
const r = (0, import_node_child_process7.spawnSync)("git", ["worktree", "list", "--porcelain"], {
|
|
@@ -56718,7 +56677,7 @@ function createWorktreeCommand() {
|
|
|
56718
56677
|
}
|
|
56719
56678
|
let doRemove = opts.yes;
|
|
56720
56679
|
if (!opts.yes) {
|
|
56721
|
-
const { confirm } = await (0,
|
|
56680
|
+
const { confirm } = await (0, import_prompts5.default)({
|
|
56722
56681
|
type: "confirm",
|
|
56723
56682
|
name: "confirm",
|
|
56724
56683
|
message: `Remove ${merged.length} worktree(s)?`,
|
|
@@ -56759,7 +56718,7 @@ function createWorktreeCommand() {
|
|
|
56759
56718
|
}
|
|
56760
56719
|
let doRemove = opts.yes;
|
|
56761
56720
|
if (!opts.yes) {
|
|
56762
|
-
const { confirm } = await (0,
|
|
56721
|
+
const { confirm } = await (0, import_prompts5.default)({
|
|
56763
56722
|
type: "confirm",
|
|
56764
56723
|
name: "confirm",
|
|
56765
56724
|
message: `Remove ${target.path}?`,
|