xtrm-cli 0.5.0 → 0.5.27
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/.pi/structured-returns/0e4a7405-1ac3-4ae1-8dbc-d31507b2e2e4.combined.log +17 -0
- package/.pi/structured-returns/0e4a7405-1ac3-4ae1-8dbc-d31507b2e2e4.stderr.log +0 -0
- package/.pi/structured-returns/0e4a7405-1ac3-4ae1-8dbc-d31507b2e2e4.stdout.log +17 -0
- package/dist/index.cjs +969 -1059
- package/dist/index.cjs.map +1 -1
- package/package.json +1 -1
- package/src/commands/clean.ts +7 -6
- package/src/commands/debug.ts +255 -0
- package/src/commands/docs.ts +180 -0
- package/src/commands/help.ts +92 -171
- package/src/commands/init.ts +9 -32
- package/src/commands/install-pi.ts +9 -16
- package/src/commands/install.ts +150 -2
- package/src/commands/pi-install.ts +10 -44
- package/src/core/context.ts +4 -52
- package/src/core/diff.ts +3 -16
- package/src/core/preflight.ts +0 -1
- package/src/index.ts +7 -4
- package/src/types/config.ts +0 -2
- package/src/utils/config-injector.ts +3 -3
- package/src/utils/pi-extensions.ts +41 -0
- package/src/utils/worktree-session.ts +86 -50
- package/test/extensions/beads-claim-lifecycle.test.ts +93 -0
- package/test/extensions/beads-parity.test.ts +94 -0
- package/test/extensions/extension-harness.ts +5 -5
- package/test/extensions/quality-gates-parity.test.ts +89 -0
- package/test/extensions/session-flow.test.ts +91 -0
- package/test/extensions/xtrm-loader.test.ts +38 -20
- package/test/install-pi.test.ts +22 -11
- package/test/pi-extensions.test.ts +50 -0
- package/test/session-launcher.test.ts +28 -38
- package/extensions/beads.ts +0 -109
- package/extensions/core/adapter.ts +0 -45
- package/extensions/core/lib.ts +0 -3
- package/extensions/core/logger.ts +0 -45
- package/extensions/core/runner.ts +0 -71
- package/extensions/custom-footer.ts +0 -160
- package/extensions/main-guard-post-push.ts +0 -44
- package/extensions/main-guard.ts +0 -126
- package/extensions/minimal-mode.ts +0 -201
- package/extensions/quality-gates.ts +0 -67
- package/extensions/service-skills.ts +0 -150
- package/extensions/xtrm-loader.ts +0 -89
- package/hooks/gitnexus-impact-reminder.py +0 -13
- package/src/commands/finish.ts +0 -25
- package/src/core/session-state.ts +0 -139
- package/src/core/xtrm-finish.ts +0 -267
- package/src/tests/session-flow-parity.test.ts +0 -118
- package/src/tests/session-state.test.ts +0 -124
- package/src/tests/xtrm-finish.test.ts +0 -148
package/dist/index.cjs
CHANGED
|
@@ -3503,7 +3503,7 @@ var require_kleur = __commonJS({
|
|
|
3503
3503
|
bgCyan: init2(46, 49),
|
|
3504
3504
|
bgWhite: init2(47, 49)
|
|
3505
3505
|
};
|
|
3506
|
-
function
|
|
3506
|
+
function run2(arr, str) {
|
|
3507
3507
|
let i = 0, tmp, beg = "", end = "";
|
|
3508
3508
|
for (; i < arr.length; i++) {
|
|
3509
3509
|
tmp = arr[i];
|
|
@@ -3554,9 +3554,9 @@ var require_kleur = __commonJS({
|
|
|
3554
3554
|
return function(txt) {
|
|
3555
3555
|
if (this !== void 0 && this.has !== void 0) {
|
|
3556
3556
|
this.has.includes(open) || (this.has.push(open), this.keys.push(blk));
|
|
3557
|
-
return txt === void 0 ? this : $2.enabled ?
|
|
3557
|
+
return txt === void 0 ? this : $2.enabled ? run2(this.keys, txt + "") : txt + "";
|
|
3558
3558
|
}
|
|
3559
|
-
return txt === void 0 ? chain2([open], [blk]) : $2.enabled ?
|
|
3559
|
+
return txt === void 0 ? chain2([open], [blk]) : $2.enabled ? run2([blk], txt + "") : txt + "";
|
|
3560
3560
|
};
|
|
3561
3561
|
}
|
|
3562
3562
|
module2.exports = $2;
|
|
@@ -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
|
|
|
@@ -15255,7 +15255,7 @@ var require_dataType = __commonJS({
|
|
|
15255
15255
|
exports2.coerceAndCheckDataType = coerceAndCheckDataType;
|
|
15256
15256
|
var COERCIBLE = /* @__PURE__ */ new Set(["string", "number", "integer", "boolean", "null"]);
|
|
15257
15257
|
function coerceToTypes(types, coerceTypes) {
|
|
15258
|
-
return coerceTypes ? types.filter((
|
|
15258
|
+
return coerceTypes ? types.filter((t3) => COERCIBLE.has(t3) || coerceTypes === "array" && t3 === "array") : [];
|
|
15259
15259
|
}
|
|
15260
15260
|
function coerceData(it, types, coerceTo) {
|
|
15261
15261
|
const { gen, data, opts } = it;
|
|
@@ -15265,9 +15265,9 @@ var require_dataType = __commonJS({
|
|
|
15265
15265
|
gen.if((0, codegen_1._)`${dataType} == 'object' && Array.isArray(${data}) && ${data}.length == 1`, () => gen.assign(data, (0, codegen_1._)`${data}[0]`).assign(dataType, (0, codegen_1._)`typeof ${data}`).if(checkDataTypes(types, data, opts.strictNumbers), () => gen.assign(coerced, data)));
|
|
15266
15266
|
}
|
|
15267
15267
|
gen.if((0, codegen_1._)`${coerced} !== undefined`);
|
|
15268
|
-
for (const
|
|
15269
|
-
if (COERCIBLE.has(
|
|
15270
|
-
coerceSpecificType(
|
|
15268
|
+
for (const t3 of coerceTo) {
|
|
15269
|
+
if (COERCIBLE.has(t3) || t3 === "array" && opts.coerceTypes === "array") {
|
|
15270
|
+
coerceSpecificType(t3);
|
|
15271
15271
|
}
|
|
15272
15272
|
}
|
|
15273
15273
|
gen.else();
|
|
@@ -15277,8 +15277,8 @@ var require_dataType = __commonJS({
|
|
|
15277
15277
|
gen.assign(data, coerced);
|
|
15278
15278
|
assignParentData(it, coerced);
|
|
15279
15279
|
});
|
|
15280
|
-
function coerceSpecificType(
|
|
15281
|
-
switch (
|
|
15280
|
+
function coerceSpecificType(t3) {
|
|
15281
|
+
switch (t3) {
|
|
15282
15282
|
case "string":
|
|
15283
15283
|
gen.elseIf((0, codegen_1._)`${dataType} == "number" || ${dataType} == "boolean"`).assign(coerced, (0, codegen_1._)`"" + ${data}`).elseIf((0, codegen_1._)`${data} === null`).assign(coerced, (0, codegen_1._)`""`);
|
|
15284
15284
|
return;
|
|
@@ -15350,8 +15350,8 @@ var require_dataType = __commonJS({
|
|
|
15350
15350
|
}
|
|
15351
15351
|
if (types.number)
|
|
15352
15352
|
delete types.integer;
|
|
15353
|
-
for (const
|
|
15354
|
-
cond = (0, codegen_1.and)(cond, checkDataType(
|
|
15353
|
+
for (const t3 in types)
|
|
15354
|
+
cond = (0, codegen_1.and)(cond, checkDataType(t3, data, strictNums, correct));
|
|
15355
15355
|
return cond;
|
|
15356
15356
|
}
|
|
15357
15357
|
exports2.checkDataTypes = checkDataTypes;
|
|
@@ -16266,9 +16266,9 @@ var require_validate = __commonJS({
|
|
|
16266
16266
|
it.dataTypes = types;
|
|
16267
16267
|
return;
|
|
16268
16268
|
}
|
|
16269
|
-
types.forEach((
|
|
16270
|
-
if (!includesType(it.dataTypes,
|
|
16271
|
-
strictTypesError(it, `type "${
|
|
16269
|
+
types.forEach((t3) => {
|
|
16270
|
+
if (!includesType(it.dataTypes, t3)) {
|
|
16271
|
+
strictTypesError(it, `type "${t3}" not allowed by context "${it.dataTypes.join(",")}"`);
|
|
16272
16272
|
}
|
|
16273
16273
|
});
|
|
16274
16274
|
narrowSchemaTypes(it, types);
|
|
@@ -16284,7 +16284,7 @@ var require_validate = __commonJS({
|
|
|
16284
16284
|
const rule = rules[keyword];
|
|
16285
16285
|
if (typeof rule == "object" && (0, applicability_1.shouldUseRule)(it.schema, rule)) {
|
|
16286
16286
|
const { type } = rule.definition;
|
|
16287
|
-
if (type.length && !type.some((
|
|
16287
|
+
if (type.length && !type.some((t3) => hasApplicableType(ts, t3))) {
|
|
16288
16288
|
strictTypesError(it, `missing type "${type.join(",")}" for keyword "${keyword}"`);
|
|
16289
16289
|
}
|
|
16290
16290
|
}
|
|
@@ -16293,15 +16293,15 @@ var require_validate = __commonJS({
|
|
|
16293
16293
|
function hasApplicableType(schTs, kwdT) {
|
|
16294
16294
|
return schTs.includes(kwdT) || kwdT === "number" && schTs.includes("integer");
|
|
16295
16295
|
}
|
|
16296
|
-
function includesType(ts,
|
|
16297
|
-
return ts.includes(
|
|
16296
|
+
function includesType(ts, t3) {
|
|
16297
|
+
return ts.includes(t3) || t3 === "integer" && ts.includes("number");
|
|
16298
16298
|
}
|
|
16299
16299
|
function narrowSchemaTypes(it, withTypes) {
|
|
16300
16300
|
const ts = [];
|
|
16301
|
-
for (const
|
|
16302
|
-
if (includesType(withTypes,
|
|
16303
|
-
ts.push(
|
|
16304
|
-
else if (withTypes.includes("integer") &&
|
|
16301
|
+
for (const t3 of it.dataTypes) {
|
|
16302
|
+
if (includesType(withTypes, t3))
|
|
16303
|
+
ts.push(t3);
|
|
16304
|
+
else if (withTypes.includes("integer") && t3 === "number")
|
|
16305
16305
|
ts.push("integer");
|
|
16306
16306
|
}
|
|
16307
16307
|
it.dataTypes = ts;
|
|
@@ -17912,7 +17912,7 @@ var require_core = __commonJS({
|
|
|
17912
17912
|
type: (0, dataType_1.getJSONTypes)(def.type),
|
|
17913
17913
|
schemaType: (0, dataType_1.getJSONTypes)(def.schemaType)
|
|
17914
17914
|
};
|
|
17915
|
-
(0, util_1.eachItem)(keyword, definition.type.length === 0 ? (k) => addRule.call(this, k, definition) : (k) => definition.type.forEach((
|
|
17915
|
+
(0, util_1.eachItem)(keyword, definition.type.length === 0 ? (k) => addRule.call(this, k, definition) : (k) => definition.type.forEach((t3) => addRule.call(this, k, definition, t3)));
|
|
17916
17916
|
return this;
|
|
17917
17917
|
}
|
|
17918
17918
|
getKeyword(keyword) {
|
|
@@ -18111,7 +18111,7 @@ var require_core = __commonJS({
|
|
|
18111
18111
|
if (dataType && post)
|
|
18112
18112
|
throw new Error('keyword with "post" flag cannot have "type"');
|
|
18113
18113
|
const { RULES } = this;
|
|
18114
|
-
let ruleGroup = post ? RULES.post : RULES.rules.find(({ type:
|
|
18114
|
+
let ruleGroup = post ? RULES.post : RULES.rules.find(({ type: t3 }) => t3 === dataType);
|
|
18115
18115
|
if (!ruleGroup) {
|
|
18116
18116
|
ruleGroup = { type: dataType, rules: [] };
|
|
18117
18117
|
RULES.rules.push(ruleGroup);
|
|
@@ -18659,7 +18659,7 @@ var require_uniqueItems = __commonJS({
|
|
|
18659
18659
|
gen.if((0, codegen_1._)`${i} > 1`, () => (canOptimize() ? loopN : loopN2)(i, j));
|
|
18660
18660
|
}
|
|
18661
18661
|
function canOptimize() {
|
|
18662
|
-
return itemTypes.length > 0 && !itemTypes.some((
|
|
18662
|
+
return itemTypes.length > 0 && !itemTypes.some((t3) => t3 === "object" || t3 === "array");
|
|
18663
18663
|
}
|
|
18664
18664
|
function loopN(i, j) {
|
|
18665
18665
|
const item = gen.name("item");
|
|
@@ -20300,18 +20300,18 @@ var require_formats = __commonJS({
|
|
|
20300
20300
|
const timeZone = matches[5];
|
|
20301
20301
|
return (hour <= 23 && minute <= 59 && second <= 59 || hour === 23 && minute === 59 && second === 60) && (!withTimeZone || timeZone !== "");
|
|
20302
20302
|
}
|
|
20303
|
-
function compareTime(t1,
|
|
20304
|
-
if (!(t1 &&
|
|
20303
|
+
function compareTime(t1, t22) {
|
|
20304
|
+
if (!(t1 && t22))
|
|
20305
20305
|
return void 0;
|
|
20306
20306
|
const a1 = TIME.exec(t1);
|
|
20307
|
-
const a2 = TIME.exec(
|
|
20307
|
+
const a2 = TIME.exec(t22);
|
|
20308
20308
|
if (!(a1 && a2))
|
|
20309
20309
|
return void 0;
|
|
20310
20310
|
t1 = a1[1] + a1[2] + a1[3] + (a1[4] || "");
|
|
20311
|
-
|
|
20312
|
-
if (t1 >
|
|
20311
|
+
t22 = a2[1] + a2[2] + a2[3] + (a2[4] || "");
|
|
20312
|
+
if (t1 > t22)
|
|
20313
20313
|
return 1;
|
|
20314
|
-
if (t1 <
|
|
20314
|
+
if (t1 < t22)
|
|
20315
20315
|
return -1;
|
|
20316
20316
|
return 0;
|
|
20317
20317
|
}
|
|
@@ -20324,11 +20324,11 @@ var require_formats = __commonJS({
|
|
|
20324
20324
|
if (!(dt1 && dt2))
|
|
20325
20325
|
return void 0;
|
|
20326
20326
|
const [d1, t1] = dt1.split(DATE_TIME_SEPARATOR);
|
|
20327
|
-
const [d2,
|
|
20327
|
+
const [d2, t22] = dt2.split(DATE_TIME_SEPARATOR);
|
|
20328
20328
|
const res = compareDate(d1, d2);
|
|
20329
20329
|
if (res === void 0)
|
|
20330
20330
|
return void 0;
|
|
20331
|
-
return res || compareTime(t1,
|
|
20331
|
+
return res || compareTime(t1, t22);
|
|
20332
20332
|
}
|
|
20333
20333
|
var NOT_URI_FRAGMENT = /\/|:/;
|
|
20334
20334
|
var URI = /^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;
|
|
@@ -20536,7 +20536,7 @@ var require_re = __commonJS({
|
|
|
20536
20536
|
var safeRe = exports2.safeRe = [];
|
|
20537
20537
|
var src = exports2.src = [];
|
|
20538
20538
|
var safeSrc = exports2.safeSrc = [];
|
|
20539
|
-
var
|
|
20539
|
+
var t3 = exports2.t = {};
|
|
20540
20540
|
var R = 0;
|
|
20541
20541
|
var LETTERDASHNUMBER = "[a-zA-Z0-9-]";
|
|
20542
20542
|
var safeRegexReplacements = [
|
|
@@ -20554,7 +20554,7 @@ var require_re = __commonJS({
|
|
|
20554
20554
|
const safe = makeSafeRegex(value);
|
|
20555
20555
|
const index = R++;
|
|
20556
20556
|
debug(name, index, value);
|
|
20557
|
-
|
|
20557
|
+
t3[name] = index;
|
|
20558
20558
|
src[index] = value;
|
|
20559
20559
|
safeSrc[index] = safe;
|
|
20560
20560
|
re[index] = new RegExp(value, isGlobal ? "g" : void 0);
|
|
@@ -20563,46 +20563,46 @@ var require_re = __commonJS({
|
|
|
20563
20563
|
createToken("NUMERICIDENTIFIER", "0|[1-9]\\d*");
|
|
20564
20564
|
createToken("NUMERICIDENTIFIERLOOSE", "\\d+");
|
|
20565
20565
|
createToken("NONNUMERICIDENTIFIER", `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`);
|
|
20566
|
-
createToken("MAINVERSION", `(${src[
|
|
20567
|
-
createToken("MAINVERSIONLOOSE", `(${src[
|
|
20568
|
-
createToken("PRERELEASEIDENTIFIER", `(?:${src[
|
|
20569
|
-
createToken("PRERELEASEIDENTIFIERLOOSE", `(?:${src[
|
|
20570
|
-
createToken("PRERELEASE", `(?:-(${src[
|
|
20571
|
-
createToken("PRERELEASELOOSE", `(?:-?(${src[
|
|
20566
|
+
createToken("MAINVERSION", `(${src[t3.NUMERICIDENTIFIER]})\\.(${src[t3.NUMERICIDENTIFIER]})\\.(${src[t3.NUMERICIDENTIFIER]})`);
|
|
20567
|
+
createToken("MAINVERSIONLOOSE", `(${src[t3.NUMERICIDENTIFIERLOOSE]})\\.(${src[t3.NUMERICIDENTIFIERLOOSE]})\\.(${src[t3.NUMERICIDENTIFIERLOOSE]})`);
|
|
20568
|
+
createToken("PRERELEASEIDENTIFIER", `(?:${src[t3.NONNUMERICIDENTIFIER]}|${src[t3.NUMERICIDENTIFIER]})`);
|
|
20569
|
+
createToken("PRERELEASEIDENTIFIERLOOSE", `(?:${src[t3.NONNUMERICIDENTIFIER]}|${src[t3.NUMERICIDENTIFIERLOOSE]})`);
|
|
20570
|
+
createToken("PRERELEASE", `(?:-(${src[t3.PRERELEASEIDENTIFIER]}(?:\\.${src[t3.PRERELEASEIDENTIFIER]})*))`);
|
|
20571
|
+
createToken("PRERELEASELOOSE", `(?:-?(${src[t3.PRERELEASEIDENTIFIERLOOSE]}(?:\\.${src[t3.PRERELEASEIDENTIFIERLOOSE]})*))`);
|
|
20572
20572
|
createToken("BUILDIDENTIFIER", `${LETTERDASHNUMBER}+`);
|
|
20573
|
-
createToken("BUILD", `(?:\\+(${src[
|
|
20574
|
-
createToken("FULLPLAIN", `v?${src[
|
|
20575
|
-
createToken("FULL", `^${src[
|
|
20576
|
-
createToken("LOOSEPLAIN", `[v=\\s]*${src[
|
|
20577
|
-
createToken("LOOSE", `^${src[
|
|
20573
|
+
createToken("BUILD", `(?:\\+(${src[t3.BUILDIDENTIFIER]}(?:\\.${src[t3.BUILDIDENTIFIER]})*))`);
|
|
20574
|
+
createToken("FULLPLAIN", `v?${src[t3.MAINVERSION]}${src[t3.PRERELEASE]}?${src[t3.BUILD]}?`);
|
|
20575
|
+
createToken("FULL", `^${src[t3.FULLPLAIN]}$`);
|
|
20576
|
+
createToken("LOOSEPLAIN", `[v=\\s]*${src[t3.MAINVERSIONLOOSE]}${src[t3.PRERELEASELOOSE]}?${src[t3.BUILD]}?`);
|
|
20577
|
+
createToken("LOOSE", `^${src[t3.LOOSEPLAIN]}$`);
|
|
20578
20578
|
createToken("GTLT", "((?:<|>)?=?)");
|
|
20579
|
-
createToken("XRANGEIDENTIFIERLOOSE", `${src[
|
|
20580
|
-
createToken("XRANGEIDENTIFIER", `${src[
|
|
20581
|
-
createToken("XRANGEPLAIN", `[v=\\s]*(${src[
|
|
20582
|
-
createToken("XRANGEPLAINLOOSE", `[v=\\s]*(${src[
|
|
20583
|
-
createToken("XRANGE", `^${src[
|
|
20584
|
-
createToken("XRANGELOOSE", `^${src[
|
|
20579
|
+
createToken("XRANGEIDENTIFIERLOOSE", `${src[t3.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`);
|
|
20580
|
+
createToken("XRANGEIDENTIFIER", `${src[t3.NUMERICIDENTIFIER]}|x|X|\\*`);
|
|
20581
|
+
createToken("XRANGEPLAIN", `[v=\\s]*(${src[t3.XRANGEIDENTIFIER]})(?:\\.(${src[t3.XRANGEIDENTIFIER]})(?:\\.(${src[t3.XRANGEIDENTIFIER]})(?:${src[t3.PRERELEASE]})?${src[t3.BUILD]}?)?)?`);
|
|
20582
|
+
createToken("XRANGEPLAINLOOSE", `[v=\\s]*(${src[t3.XRANGEIDENTIFIERLOOSE]})(?:\\.(${src[t3.XRANGEIDENTIFIERLOOSE]})(?:\\.(${src[t3.XRANGEIDENTIFIERLOOSE]})(?:${src[t3.PRERELEASELOOSE]})?${src[t3.BUILD]}?)?)?`);
|
|
20583
|
+
createToken("XRANGE", `^${src[t3.GTLT]}\\s*${src[t3.XRANGEPLAIN]}$`);
|
|
20584
|
+
createToken("XRANGELOOSE", `^${src[t3.GTLT]}\\s*${src[t3.XRANGEPLAINLOOSE]}$`);
|
|
20585
20585
|
createToken("COERCEPLAIN", `${"(^|[^\\d])(\\d{1,"}${MAX_SAFE_COMPONENT_LENGTH}})(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`);
|
|
20586
|
-
createToken("COERCE", `${src[
|
|
20587
|
-
createToken("COERCEFULL", src[
|
|
20588
|
-
createToken("COERCERTL", src[
|
|
20589
|
-
createToken("COERCERTLFULL", src[
|
|
20586
|
+
createToken("COERCE", `${src[t3.COERCEPLAIN]}(?:$|[^\\d])`);
|
|
20587
|
+
createToken("COERCEFULL", src[t3.COERCEPLAIN] + `(?:${src[t3.PRERELEASE]})?(?:${src[t3.BUILD]})?(?:$|[^\\d])`);
|
|
20588
|
+
createToken("COERCERTL", src[t3.COERCE], true);
|
|
20589
|
+
createToken("COERCERTLFULL", src[t3.COERCEFULL], true);
|
|
20590
20590
|
createToken("LONETILDE", "(?:~>?)");
|
|
20591
|
-
createToken("TILDETRIM", `(\\s*)${src[
|
|
20591
|
+
createToken("TILDETRIM", `(\\s*)${src[t3.LONETILDE]}\\s+`, true);
|
|
20592
20592
|
exports2.tildeTrimReplace = "$1~";
|
|
20593
|
-
createToken("TILDE", `^${src[
|
|
20594
|
-
createToken("TILDELOOSE", `^${src[
|
|
20593
|
+
createToken("TILDE", `^${src[t3.LONETILDE]}${src[t3.XRANGEPLAIN]}$`);
|
|
20594
|
+
createToken("TILDELOOSE", `^${src[t3.LONETILDE]}${src[t3.XRANGEPLAINLOOSE]}$`);
|
|
20595
20595
|
createToken("LONECARET", "(?:\\^)");
|
|
20596
|
-
createToken("CARETTRIM", `(\\s*)${src[
|
|
20596
|
+
createToken("CARETTRIM", `(\\s*)${src[t3.LONECARET]}\\s+`, true);
|
|
20597
20597
|
exports2.caretTrimReplace = "$1^";
|
|
20598
|
-
createToken("CARET", `^${src[
|
|
20599
|
-
createToken("CARETLOOSE", `^${src[
|
|
20600
|
-
createToken("COMPARATORLOOSE", `^${src[
|
|
20601
|
-
createToken("COMPARATOR", `^${src[
|
|
20602
|
-
createToken("COMPARATORTRIM", `(\\s*)${src[
|
|
20598
|
+
createToken("CARET", `^${src[t3.LONECARET]}${src[t3.XRANGEPLAIN]}$`);
|
|
20599
|
+
createToken("CARETLOOSE", `^${src[t3.LONECARET]}${src[t3.XRANGEPLAINLOOSE]}$`);
|
|
20600
|
+
createToken("COMPARATORLOOSE", `^${src[t3.GTLT]}\\s*(${src[t3.LOOSEPLAIN]})$|^$`);
|
|
20601
|
+
createToken("COMPARATOR", `^${src[t3.GTLT]}\\s*(${src[t3.FULLPLAIN]})$|^$`);
|
|
20602
|
+
createToken("COMPARATORTRIM", `(\\s*)${src[t3.GTLT]}\\s*(${src[t3.LOOSEPLAIN]}|${src[t3.XRANGEPLAIN]})`, true);
|
|
20603
20603
|
exports2.comparatorTrimReplace = "$1$2$3";
|
|
20604
|
-
createToken("HYPHENRANGE", `^\\s*(${src[
|
|
20605
|
-
createToken("HYPHENRANGELOOSE", `^\\s*(${src[
|
|
20604
|
+
createToken("HYPHENRANGE", `^\\s*(${src[t3.XRANGEPLAIN]})\\s+-\\s+(${src[t3.XRANGEPLAIN]})\\s*$`);
|
|
20605
|
+
createToken("HYPHENRANGELOOSE", `^\\s*(${src[t3.XRANGEPLAINLOOSE]})\\s+-\\s+(${src[t3.XRANGEPLAINLOOSE]})\\s*$`);
|
|
20606
20606
|
createToken("STAR", "(<|>)?=?\\s*\\*");
|
|
20607
20607
|
createToken("GTE0", "^\\s*>=\\s*0\\.0\\.0\\s*$");
|
|
20608
20608
|
createToken("GTE0PRE", "^\\s*>=\\s*0\\.0\\.0-0\\s*$");
|
|
@@ -20659,7 +20659,7 @@ var require_semver = __commonJS({
|
|
|
20659
20659
|
"use strict";
|
|
20660
20660
|
var debug = require_debug();
|
|
20661
20661
|
var { MAX_LENGTH, MAX_SAFE_INTEGER } = require_constants();
|
|
20662
|
-
var { safeRe: re, t:
|
|
20662
|
+
var { safeRe: re, t: t3 } = require_re();
|
|
20663
20663
|
var parseOptions = require_parse_options();
|
|
20664
20664
|
var { compareIdentifiers } = require_identifiers();
|
|
20665
20665
|
var SemVer = class _SemVer {
|
|
@@ -20683,7 +20683,7 @@ var require_semver = __commonJS({
|
|
|
20683
20683
|
this.options = options;
|
|
20684
20684
|
this.loose = !!options.loose;
|
|
20685
20685
|
this.includePrerelease = !!options.includePrerelease;
|
|
20686
|
-
const m = version3.trim().match(options.loose ? re[
|
|
20686
|
+
const m = version3.trim().match(options.loose ? re[t3.LOOSE] : re[t3.FULL]);
|
|
20687
20687
|
if (!m) {
|
|
20688
20688
|
throw new TypeError(`Invalid Version: ${version3}`);
|
|
20689
20689
|
}
|
|
@@ -20822,7 +20822,7 @@ var require_semver = __commonJS({
|
|
|
20822
20822
|
throw new Error("invalid increment argument: identifier is empty");
|
|
20823
20823
|
}
|
|
20824
20824
|
if (identifier) {
|
|
20825
|
-
const match = `-${identifier}`.match(this.options.loose ? re[
|
|
20825
|
+
const match = `-${identifier}`.match(this.options.loose ? re[t3.PRERELEASELOOSE] : re[t3.PRERELEASE]);
|
|
20826
20826
|
if (!match || match[1] !== identifier) {
|
|
20827
20827
|
throw new Error(`invalid identifier: ${identifier}`);
|
|
20828
20828
|
}
|
|
@@ -21271,7 +21271,7 @@ var require_coerce = __commonJS({
|
|
|
21271
21271
|
"use strict";
|
|
21272
21272
|
var SemVer = require_semver();
|
|
21273
21273
|
var parse4 = require_parse();
|
|
21274
|
-
var { safeRe: re, t:
|
|
21274
|
+
var { safeRe: re, t: t3 } = require_re();
|
|
21275
21275
|
var coerce = (version3, options) => {
|
|
21276
21276
|
if (version3 instanceof SemVer) {
|
|
21277
21277
|
return version3;
|
|
@@ -21285,9 +21285,9 @@ var require_coerce = __commonJS({
|
|
|
21285
21285
|
options = options || {};
|
|
21286
21286
|
let match = null;
|
|
21287
21287
|
if (!options.rtl) {
|
|
21288
|
-
match = version3.match(options.includePrerelease ? re[
|
|
21288
|
+
match = version3.match(options.includePrerelease ? re[t3.COERCEFULL] : re[t3.COERCE]);
|
|
21289
21289
|
} else {
|
|
21290
|
-
const coerceRtlRegex = options.includePrerelease ? re[
|
|
21290
|
+
const coerceRtlRegex = options.includePrerelease ? re[t3.COERCERTLFULL] : re[t3.COERCERTL];
|
|
21291
21291
|
let next;
|
|
21292
21292
|
while ((next = coerceRtlRegex.exec(version3)) && (!match || match.index + match[0].length !== version3.length)) {
|
|
21293
21293
|
if (!match || next.index + next[0].length !== match.index + match[0].length) {
|
|
@@ -21426,20 +21426,20 @@ var require_range = __commonJS({
|
|
|
21426
21426
|
return cached2;
|
|
21427
21427
|
}
|
|
21428
21428
|
const loose = this.options.loose;
|
|
21429
|
-
const hr = loose ? re[
|
|
21429
|
+
const hr = loose ? re[t3.HYPHENRANGELOOSE] : re[t3.HYPHENRANGE];
|
|
21430
21430
|
range = range.replace(hr, hyphenReplace(this.options.includePrerelease));
|
|
21431
21431
|
debug("hyphen replace", range);
|
|
21432
|
-
range = range.replace(re[
|
|
21432
|
+
range = range.replace(re[t3.COMPARATORTRIM], comparatorTrimReplace);
|
|
21433
21433
|
debug("comparator trim", range);
|
|
21434
|
-
range = range.replace(re[
|
|
21434
|
+
range = range.replace(re[t3.TILDETRIM], tildeTrimReplace);
|
|
21435
21435
|
debug("tilde trim", range);
|
|
21436
|
-
range = range.replace(re[
|
|
21436
|
+
range = range.replace(re[t3.CARETTRIM], caretTrimReplace);
|
|
21437
21437
|
debug("caret trim", range);
|
|
21438
21438
|
let rangeList = range.split(" ").map((comp) => parseComparator(comp, this.options)).join(" ").split(/\s+/).map((comp) => replaceGTE0(comp, this.options));
|
|
21439
21439
|
if (loose) {
|
|
21440
21440
|
rangeList = rangeList.filter((comp) => {
|
|
21441
21441
|
debug("loose invalid filter", comp, this.options);
|
|
21442
|
-
return !!comp.match(re[
|
|
21442
|
+
return !!comp.match(re[t3.COMPARATORLOOSE]);
|
|
21443
21443
|
});
|
|
21444
21444
|
}
|
|
21445
21445
|
debug("range list", rangeList);
|
|
@@ -21501,7 +21501,7 @@ var require_range = __commonJS({
|
|
|
21501
21501
|
var SemVer = require_semver();
|
|
21502
21502
|
var {
|
|
21503
21503
|
safeRe: re,
|
|
21504
|
-
t:
|
|
21504
|
+
t: t3,
|
|
21505
21505
|
comparatorTrimReplace,
|
|
21506
21506
|
tildeTrimReplace,
|
|
21507
21507
|
caretTrimReplace
|
|
@@ -21522,7 +21522,7 @@ var require_range = __commonJS({
|
|
|
21522
21522
|
return result;
|
|
21523
21523
|
};
|
|
21524
21524
|
var parseComparator = (comp, options) => {
|
|
21525
|
-
comp = comp.replace(re[
|
|
21525
|
+
comp = comp.replace(re[t3.BUILD], "");
|
|
21526
21526
|
debug("comp", comp, options);
|
|
21527
21527
|
comp = replaceCarets(comp, options);
|
|
21528
21528
|
debug("caret", comp);
|
|
@@ -21539,7 +21539,7 @@ var require_range = __commonJS({
|
|
|
21539
21539
|
return comp.trim().split(/\s+/).map((c) => replaceTilde(c, options)).join(" ");
|
|
21540
21540
|
};
|
|
21541
21541
|
var replaceTilde = (comp, options) => {
|
|
21542
|
-
const r = options.loose ? re[
|
|
21542
|
+
const r = options.loose ? re[t3.TILDELOOSE] : re[t3.TILDE];
|
|
21543
21543
|
return comp.replace(r, (_, M, m, p, pr) => {
|
|
21544
21544
|
debug("tilde", comp, _, M, m, p, pr);
|
|
21545
21545
|
let ret;
|
|
@@ -21564,7 +21564,7 @@ var require_range = __commonJS({
|
|
|
21564
21564
|
};
|
|
21565
21565
|
var replaceCaret = (comp, options) => {
|
|
21566
21566
|
debug("caret", comp, options);
|
|
21567
|
-
const r = options.loose ? re[
|
|
21567
|
+
const r = options.loose ? re[t3.CARETLOOSE] : re[t3.CARET];
|
|
21568
21568
|
const z2 = options.includePrerelease ? "-0" : "";
|
|
21569
21569
|
return comp.replace(r, (_, M, m, p, pr) => {
|
|
21570
21570
|
debug("caret", comp, _, M, m, p, pr);
|
|
@@ -21612,7 +21612,7 @@ var require_range = __commonJS({
|
|
|
21612
21612
|
};
|
|
21613
21613
|
var replaceXRange = (comp, options) => {
|
|
21614
21614
|
comp = comp.trim();
|
|
21615
|
-
const r = options.loose ? re[
|
|
21615
|
+
const r = options.loose ? re[t3.XRANGELOOSE] : re[t3.XRANGE];
|
|
21616
21616
|
return comp.replace(r, (ret, gtlt, M, m, p, pr) => {
|
|
21617
21617
|
debug("xRange", comp, ret, gtlt, M, m, p, pr);
|
|
21618
21618
|
const xM = isX(M);
|
|
@@ -21667,11 +21667,11 @@ var require_range = __commonJS({
|
|
|
21667
21667
|
};
|
|
21668
21668
|
var replaceStars = (comp, options) => {
|
|
21669
21669
|
debug("replaceStars", comp, options);
|
|
21670
|
-
return comp.trim().replace(re[
|
|
21670
|
+
return comp.trim().replace(re[t3.STAR], "");
|
|
21671
21671
|
};
|
|
21672
21672
|
var replaceGTE0 = (comp, options) => {
|
|
21673
21673
|
debug("replaceGTE0", comp, options);
|
|
21674
|
-
return comp.trim().replace(re[options.includePrerelease ?
|
|
21674
|
+
return comp.trim().replace(re[options.includePrerelease ? t3.GTE0PRE : t3.GTE0], "");
|
|
21675
21675
|
};
|
|
21676
21676
|
var hyphenReplace = (incPr) => ($0, from, fM, fm, fp, fpr, fb, to, tM, tm, tp, tpr) => {
|
|
21677
21677
|
if (isX(fM)) {
|
|
@@ -21757,7 +21757,7 @@ var require_comparator = __commonJS({
|
|
|
21757
21757
|
debug("comp", this);
|
|
21758
21758
|
}
|
|
21759
21759
|
parse(comp) {
|
|
21760
|
-
const r = this.options.loose ? re[
|
|
21760
|
+
const r = this.options.loose ? re[t3.COMPARATORLOOSE] : re[t3.COMPARATOR];
|
|
21761
21761
|
const m = comp.match(r);
|
|
21762
21762
|
if (!m) {
|
|
21763
21763
|
throw new TypeError(`Invalid comparator: ${comp}`);
|
|
@@ -21831,7 +21831,7 @@ var require_comparator = __commonJS({
|
|
|
21831
21831
|
};
|
|
21832
21832
|
module2.exports = Comparator;
|
|
21833
21833
|
var parseOptions = require_parse_options();
|
|
21834
|
-
var { safeRe: re, t:
|
|
21834
|
+
var { safeRe: re, t: t3 } = require_re();
|
|
21835
21835
|
var cmp = require_cmp();
|
|
21836
21836
|
var debug = require_debug();
|
|
21837
21837
|
var SemVer = require_semver();
|
|
@@ -24334,15 +24334,15 @@ var require_esprima = __commonJS({
|
|
|
24334
24334
|
return this.scanner.source.slice(token.start, token.end);
|
|
24335
24335
|
};
|
|
24336
24336
|
Parser2.prototype.convertToken = function(token) {
|
|
24337
|
-
var
|
|
24337
|
+
var t3 = {
|
|
24338
24338
|
type: token_1.TokenName[token.type],
|
|
24339
24339
|
value: this.getTokenRaw(token)
|
|
24340
24340
|
};
|
|
24341
24341
|
if (this.config.range) {
|
|
24342
|
-
|
|
24342
|
+
t3.range = [token.start, token.end];
|
|
24343
24343
|
}
|
|
24344
24344
|
if (this.config.loc) {
|
|
24345
|
-
|
|
24345
|
+
t3.loc = {
|
|
24346
24346
|
start: {
|
|
24347
24347
|
line: this.startMarker.line,
|
|
24348
24348
|
column: this.startMarker.column
|
|
@@ -24356,9 +24356,9 @@ var require_esprima = __commonJS({
|
|
|
24356
24356
|
if (token.type === 9) {
|
|
24357
24357
|
var pattern = token.pattern;
|
|
24358
24358
|
var flags = token.flags;
|
|
24359
|
-
|
|
24359
|
+
t3.regex = { pattern, flags };
|
|
24360
24360
|
}
|
|
24361
|
-
return
|
|
24361
|
+
return t3;
|
|
24362
24362
|
};
|
|
24363
24363
|
Parser2.prototype.nextToken = function() {
|
|
24364
24364
|
var token = this.lookahead;
|
|
@@ -27021,19 +27021,19 @@ var require_esprima = __commonJS({
|
|
|
27021
27021
|
}
|
|
27022
27022
|
return error49;
|
|
27023
27023
|
};
|
|
27024
|
-
ErrorHandler2.prototype.createError = function(index, line,
|
|
27024
|
+
ErrorHandler2.prototype.createError = function(index, line, col, description) {
|
|
27025
27025
|
var msg = "Line " + line + ": " + description;
|
|
27026
|
-
var error49 = this.constructError(msg,
|
|
27026
|
+
var error49 = this.constructError(msg, col);
|
|
27027
27027
|
error49.index = index;
|
|
27028
27028
|
error49.lineNumber = line;
|
|
27029
27029
|
error49.description = description;
|
|
27030
27030
|
return error49;
|
|
27031
27031
|
};
|
|
27032
|
-
ErrorHandler2.prototype.throwError = function(index, line,
|
|
27033
|
-
throw this.createError(index, line,
|
|
27032
|
+
ErrorHandler2.prototype.throwError = function(index, line, col, description) {
|
|
27033
|
+
throw this.createError(index, line, col, description);
|
|
27034
27034
|
};
|
|
27035
|
-
ErrorHandler2.prototype.tolerateError = function(index, line,
|
|
27036
|
-
var error49 = this.createError(index, line,
|
|
27035
|
+
ErrorHandler2.prototype.tolerateError = function(index, line, col, description) {
|
|
27036
|
+
var error49 = this.createError(index, line, col, description);
|
|
27037
27037
|
if (this.tolerant) {
|
|
27038
27038
|
this.recordError(error49);
|
|
27039
27039
|
} else {
|
|
@@ -28461,7 +28461,7 @@ var require_esprima = __commonJS({
|
|
|
28461
28461
|
this.values = [];
|
|
28462
28462
|
this.curly = this.paren = -1;
|
|
28463
28463
|
}
|
|
28464
|
-
Reader2.prototype.beforeFunctionExpression = function(
|
|
28464
|
+
Reader2.prototype.beforeFunctionExpression = function(t3) {
|
|
28465
28465
|
return [
|
|
28466
28466
|
"(",
|
|
28467
28467
|
"{",
|
|
@@ -28519,7 +28519,7 @@ var require_esprima = __commonJS({
|
|
|
28519
28519
|
">",
|
|
28520
28520
|
"!=",
|
|
28521
28521
|
"!=="
|
|
28522
|
-
].indexOf(
|
|
28522
|
+
].indexOf(t3) >= 0;
|
|
28523
28523
|
};
|
|
28524
28524
|
Reader2.prototype.isRegexStart = function() {
|
|
28525
28525
|
var previous = this.values[this.values.length - 1];
|
|
@@ -28746,18 +28746,18 @@ var require_src2 = __commonJS({
|
|
|
28746
28746
|
}
|
|
28747
28747
|
const al = log10(a);
|
|
28748
28748
|
const bl = log10(b);
|
|
28749
|
-
let
|
|
28749
|
+
let t3 = 0;
|
|
28750
28750
|
if (al < bl) {
|
|
28751
28751
|
a *= POWERS_OF_TEN[bl - al - 1];
|
|
28752
28752
|
b /= 10;
|
|
28753
|
-
|
|
28753
|
+
t3 = -1;
|
|
28754
28754
|
} else if (al > bl) {
|
|
28755
28755
|
b *= POWERS_OF_TEN[al - bl - 1];
|
|
28756
28756
|
a /= 10;
|
|
28757
|
-
|
|
28757
|
+
t3 = 1;
|
|
28758
28758
|
}
|
|
28759
28759
|
if (a === b) {
|
|
28760
|
-
return
|
|
28760
|
+
return t3;
|
|
28761
28761
|
}
|
|
28762
28762
|
return a < b ? -1 : 1;
|
|
28763
28763
|
}
|
|
@@ -28797,9 +28797,9 @@ var require_src2 = __commonJS({
|
|
|
28797
28797
|
function reverseRun(array2, lo, hi) {
|
|
28798
28798
|
hi--;
|
|
28799
28799
|
while (lo < hi) {
|
|
28800
|
-
const
|
|
28800
|
+
const t3 = array2[lo];
|
|
28801
28801
|
array2[lo++] = array2[hi];
|
|
28802
|
-
array2[hi--] =
|
|
28802
|
+
array2[hi--] = t3;
|
|
28803
28803
|
}
|
|
28804
28804
|
}
|
|
28805
28805
|
function binaryInsertionSort(array2, lo, hi, start, compare) {
|
|
@@ -30006,7 +30006,7 @@ var require_parse2 = __commonJS({
|
|
|
30006
30006
|
}
|
|
30007
30007
|
return current.type === "Punctuator" ? current.value : current.type;
|
|
30008
30008
|
};
|
|
30009
|
-
var is = (
|
|
30009
|
+
var is = (t3) => type() === t3;
|
|
30010
30010
|
var expect = (a) => {
|
|
30011
30011
|
if (!is(a)) {
|
|
30012
30012
|
unexpected();
|
|
@@ -30319,10 +30319,10 @@ var require_stringify = __commonJS({
|
|
|
30319
30319
|
replacer = null;
|
|
30320
30320
|
indent2 = EMPTY;
|
|
30321
30321
|
};
|
|
30322
|
-
var
|
|
30322
|
+
var join6 = (one, two, gap) => one ? two ? one + two.trim() + LF + gap : one.trimRight() + LF + gap : two ? two.trimRight() + LF + gap : EMPTY;
|
|
30323
30323
|
var join_content = (inside, value, gap) => {
|
|
30324
30324
|
const comment = process_comments(value, PREFIX_BEFORE, gap + indent2, true);
|
|
30325
|
-
return
|
|
30325
|
+
return join6(comment, inside, gap);
|
|
30326
30326
|
};
|
|
30327
30327
|
var array_stringify = (value, gap) => {
|
|
30328
30328
|
const deeper_gap = gap + indent2;
|
|
@@ -30333,7 +30333,7 @@ var require_stringify = __commonJS({
|
|
|
30333
30333
|
if (i !== 0) {
|
|
30334
30334
|
inside += COMMA;
|
|
30335
30335
|
}
|
|
30336
|
-
const before =
|
|
30336
|
+
const before = join6(
|
|
30337
30337
|
after_comma,
|
|
30338
30338
|
process_comments(value, BEFORE(i), deeper_gap),
|
|
30339
30339
|
deeper_gap
|
|
@@ -30343,7 +30343,7 @@ var require_stringify = __commonJS({
|
|
|
30343
30343
|
inside += process_comments(value, AFTER_VALUE(i), deeper_gap);
|
|
30344
30344
|
after_comma = process_comments(value, AFTER(i), deeper_gap);
|
|
30345
30345
|
}
|
|
30346
|
-
inside +=
|
|
30346
|
+
inside += join6(
|
|
30347
30347
|
after_comma,
|
|
30348
30348
|
process_comments(value, PREFIX_AFTER, deeper_gap),
|
|
30349
30349
|
deeper_gap
|
|
@@ -30368,7 +30368,7 @@ var require_stringify = __commonJS({
|
|
|
30368
30368
|
inside += COMMA;
|
|
30369
30369
|
}
|
|
30370
30370
|
first = false;
|
|
30371
|
-
const before =
|
|
30371
|
+
const before = join6(
|
|
30372
30372
|
after_comma,
|
|
30373
30373
|
process_comments(value, BEFORE(key), deeper_gap),
|
|
30374
30374
|
deeper_gap
|
|
@@ -30378,7 +30378,7 @@ var require_stringify = __commonJS({
|
|
|
30378
30378
|
after_comma = process_comments(value, AFTER(key), deeper_gap);
|
|
30379
30379
|
};
|
|
30380
30380
|
keys.forEach(iteratee);
|
|
30381
|
-
inside +=
|
|
30381
|
+
inside += join6(
|
|
30382
30382
|
after_comma,
|
|
30383
30383
|
process_comments(value, PREFIX_AFTER, deeper_gap),
|
|
30384
30384
|
deeper_gap
|
|
@@ -31075,7 +31075,7 @@ var require_main = __commonJS({
|
|
|
31075
31075
|
"use strict";
|
|
31076
31076
|
var fs22 = require("fs");
|
|
31077
31077
|
var path22 = require("path");
|
|
31078
|
-
var
|
|
31078
|
+
var os8 = require("os");
|
|
31079
31079
|
var crypto2 = require("crypto");
|
|
31080
31080
|
var packageJson = require_package();
|
|
31081
31081
|
var version3 = packageJson.version;
|
|
@@ -31198,7 +31198,7 @@ var require_main = __commonJS({
|
|
|
31198
31198
|
return null;
|
|
31199
31199
|
}
|
|
31200
31200
|
function _resolveHome(envPath) {
|
|
31201
|
-
return envPath[0] === "~" ? path22.join(
|
|
31201
|
+
return envPath[0] === "~" ? path22.join(os8.homedir(), envPath.slice(1)) : envPath;
|
|
31202
31202
|
}
|
|
31203
31203
|
function _configVault(options) {
|
|
31204
31204
|
const debug = Boolean(options && options.debug);
|
|
@@ -31880,7 +31880,7 @@ var require_has_flag = __commonJS({
|
|
|
31880
31880
|
var require_supports_colors = __commonJS({
|
|
31881
31881
|
"../node_modules/@colors/colors/lib/system/supports-colors.js"(exports2, module2) {
|
|
31882
31882
|
"use strict";
|
|
31883
|
-
var
|
|
31883
|
+
var os8 = require("os");
|
|
31884
31884
|
var hasFlag2 = require_has_flag();
|
|
31885
31885
|
var env3 = process.env;
|
|
31886
31886
|
var forceColor = void 0;
|
|
@@ -31918,7 +31918,7 @@ var require_supports_colors = __commonJS({
|
|
|
31918
31918
|
}
|
|
31919
31919
|
var min = forceColor ? 1 : 0;
|
|
31920
31920
|
if (process.platform === "win32") {
|
|
31921
|
-
var osRelease =
|
|
31921
|
+
var osRelease = os8.release().split(".");
|
|
31922
31922
|
if (Number(process.versions.node.split(".")[0]) >= 8 && Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) {
|
|
31923
31923
|
return Number(osRelease[2]) >= 14931 ? 3 : 2;
|
|
31924
31924
|
}
|
|
@@ -32847,19 +32847,19 @@ var require_layout_manager = __commonJS({
|
|
|
32847
32847
|
var Cell = require_cell();
|
|
32848
32848
|
var { ColSpanCell, RowSpanCell } = Cell;
|
|
32849
32849
|
(function() {
|
|
32850
|
-
function next(alloc,
|
|
32851
|
-
if (alloc[
|
|
32852
|
-
return next(alloc,
|
|
32850
|
+
function next(alloc, col) {
|
|
32851
|
+
if (alloc[col] > 0) {
|
|
32852
|
+
return next(alloc, col + 1);
|
|
32853
32853
|
}
|
|
32854
|
-
return
|
|
32854
|
+
return col;
|
|
32855
32855
|
}
|
|
32856
32856
|
function layoutTable(table) {
|
|
32857
32857
|
let alloc = {};
|
|
32858
32858
|
table.forEach(function(row, rowIndex) {
|
|
32859
|
-
let
|
|
32859
|
+
let col = 0;
|
|
32860
32860
|
row.forEach(function(cell) {
|
|
32861
32861
|
cell.y = rowIndex;
|
|
32862
|
-
cell.x = rowIndex ? next(alloc,
|
|
32862
|
+
cell.x = rowIndex ? next(alloc, col) : col;
|
|
32863
32863
|
const rowSpan = cell.rowSpan || 1;
|
|
32864
32864
|
const colSpan = cell.colSpan || 1;
|
|
32865
32865
|
if (rowSpan > 1) {
|
|
@@ -32867,7 +32867,7 @@ var require_layout_manager = __commonJS({
|
|
|
32867
32867
|
alloc[cell.x + cs] = rowSpan;
|
|
32868
32868
|
}
|
|
32869
32869
|
}
|
|
32870
|
-
|
|
32870
|
+
col = cell.x + colSpan;
|
|
32871
32871
|
});
|
|
32872
32872
|
Object.keys(alloc).forEach((idx) => {
|
|
32873
32873
|
alloc[idx]--;
|
|
@@ -33039,29 +33039,29 @@ var require_layout_manager = __commonJS({
|
|
|
33039
33039
|
for (let k = spanners.length - 1; k >= 0; k--) {
|
|
33040
33040
|
let cell = spanners[k];
|
|
33041
33041
|
let span = cell[colSpan];
|
|
33042
|
-
let
|
|
33043
|
-
let existingWidth = result[
|
|
33044
|
-
let editableCols = typeof vals[
|
|
33042
|
+
let col = cell[x];
|
|
33043
|
+
let existingWidth = result[col];
|
|
33044
|
+
let editableCols = typeof vals[col] === "number" ? 0 : 1;
|
|
33045
33045
|
if (typeof existingWidth === "number") {
|
|
33046
33046
|
for (let i = 1; i < span; i++) {
|
|
33047
|
-
existingWidth += 1 + result[
|
|
33048
|
-
if (typeof vals[
|
|
33047
|
+
existingWidth += 1 + result[col + i];
|
|
33048
|
+
if (typeof vals[col + i] !== "number") {
|
|
33049
33049
|
editableCols++;
|
|
33050
33050
|
}
|
|
33051
33051
|
}
|
|
33052
33052
|
} else {
|
|
33053
33053
|
existingWidth = desiredWidth === "desiredWidth" ? cell.desiredWidth - 1 : 1;
|
|
33054
|
-
if (!auto[
|
|
33055
|
-
auto[
|
|
33054
|
+
if (!auto[col] || auto[col] < existingWidth) {
|
|
33055
|
+
auto[col] = existingWidth;
|
|
33056
33056
|
}
|
|
33057
33057
|
}
|
|
33058
33058
|
if (cell[desiredWidth] > existingWidth) {
|
|
33059
33059
|
let i = 0;
|
|
33060
33060
|
while (editableCols > 0 && cell[desiredWidth] > existingWidth) {
|
|
33061
|
-
if (typeof vals[
|
|
33061
|
+
if (typeof vals[col + i] !== "number") {
|
|
33062
33062
|
let dif = Math.round((cell[desiredWidth] - existingWidth) / editableCols);
|
|
33063
33063
|
existingWidth += dif;
|
|
33064
|
-
result[
|
|
33064
|
+
result[col + i] += dif;
|
|
33065
33065
|
editableCols--;
|
|
33066
33066
|
}
|
|
33067
33067
|
i++;
|
|
@@ -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);
|
|
@@ -34911,12 +34911,12 @@ var TestRendererSerializer = class {
|
|
|
34911
34911
|
data
|
|
34912
34912
|
};
|
|
34913
34913
|
if (typeof this.options?.task !== "boolean") {
|
|
34914
|
-
const
|
|
34914
|
+
const t3 = Object.fromEntries(this.options.task.map((entity) => {
|
|
34915
34915
|
const property = task[entity];
|
|
34916
34916
|
if (typeof property === "function") return [entity, property.call(task)];
|
|
34917
34917
|
return [entity, property];
|
|
34918
34918
|
}));
|
|
34919
|
-
if (Object.keys(task).length > 0) output.task =
|
|
34919
|
+
if (Object.keys(task).length > 0) output.task = t3;
|
|
34920
34920
|
}
|
|
34921
34921
|
return output;
|
|
34922
34922
|
}
|
|
@@ -35746,14 +35746,15 @@ var Listr = class {
|
|
|
35746
35746
|
};
|
|
35747
35747
|
|
|
35748
35748
|
// src/commands/install.ts
|
|
35749
|
-
var
|
|
35749
|
+
var import_fs_extra12 = __toESM(require_lib2(), 1);
|
|
35750
|
+
var import_os5 = __toESM(require("os"), 1);
|
|
35750
35751
|
|
|
35751
35752
|
// src/core/context.ts
|
|
35752
35753
|
var import_os2 = __toESM(require("os"), 1);
|
|
35753
35754
|
var import_path = __toESM(require("path"), 1);
|
|
35754
35755
|
var import_fs_extra = __toESM(require_lib2(), 1);
|
|
35755
35756
|
|
|
35756
|
-
//
|
|
35757
|
+
// node_modules/conf/dist/source/index.js
|
|
35757
35758
|
var import_node_util3 = require("util");
|
|
35758
35759
|
var import_node_process10 = __toESM(require("process"), 1);
|
|
35759
35760
|
var import_node_fs3 = __toESM(require("fs"), 1);
|
|
@@ -36080,9 +36081,9 @@ var retryifyAsync = (fn, options) => {
|
|
|
36080
36081
|
throw error49;
|
|
36081
36082
|
if (Date.now() >= timestamp)
|
|
36082
36083
|
throw error49;
|
|
36083
|
-
const
|
|
36084
|
-
if (
|
|
36085
|
-
const delayPromise = new Promise((resolve2) => setTimeout(resolve2,
|
|
36084
|
+
const delay3 = Math.round(interval * Math.random());
|
|
36085
|
+
if (delay3 > 0) {
|
|
36086
|
+
const delayPromise = new Promise((resolve2) => setTimeout(resolve2, delay3));
|
|
36086
36087
|
return delayPromise.then(() => attempt.apply(void 0, args));
|
|
36087
36088
|
} else {
|
|
36088
36089
|
return attempt.apply(void 0, args);
|
|
@@ -36341,14 +36342,14 @@ var Temp = {
|
|
|
36341
36342
|
}
|
|
36342
36343
|
},
|
|
36343
36344
|
truncate: (filePath) => {
|
|
36344
|
-
const
|
|
36345
|
-
if (
|
|
36345
|
+
const basename2 = import_node_path2.default.basename(filePath);
|
|
36346
|
+
if (basename2.length <= LIMIT_BASENAME_LENGTH)
|
|
36346
36347
|
return filePath;
|
|
36347
|
-
const truncable = /^(\.?)(.*?)((?:\.[^.]+)?(?:\.tmp-\d{10}[a-f0-9]{6})?)$/.exec(
|
|
36348
|
+
const truncable = /^(\.?)(.*?)((?:\.[^.]+)?(?:\.tmp-\d{10}[a-f0-9]{6})?)$/.exec(basename2);
|
|
36348
36349
|
if (!truncable)
|
|
36349
36350
|
return filePath;
|
|
36350
|
-
const truncationLength =
|
|
36351
|
-
return `${filePath.slice(0, -
|
|
36351
|
+
const truncationLength = basename2.length - LIMIT_BASENAME_LENGTH;
|
|
36352
|
+
return `${filePath.slice(0, -basename2.length)}${truncable[1]}${truncable[2].slice(0, -truncationLength)}${truncable[3]}`;
|
|
36352
36353
|
}
|
|
36353
36354
|
};
|
|
36354
36355
|
node_default(Temp.purgeSyncAll);
|
|
@@ -36432,7 +36433,7 @@ function writeFileSync(filePath, data, options = DEFAULT_WRITE_OPTIONS) {
|
|
|
36432
36433
|
}
|
|
36433
36434
|
}
|
|
36434
36435
|
|
|
36435
|
-
//
|
|
36436
|
+
// node_modules/conf/dist/source/index.js
|
|
36436
36437
|
var import_ajv = __toESM(require_ajv(), 1);
|
|
36437
36438
|
var import_ajv_formats = __toESM(require_dist2(), 1);
|
|
36438
36439
|
|
|
@@ -36546,7 +36547,7 @@ var debounceFn = (inputFunction, options = {}) => {
|
|
|
36546
36547
|
};
|
|
36547
36548
|
var debounce_fn_default = debounceFn;
|
|
36548
36549
|
|
|
36549
|
-
//
|
|
36550
|
+
// node_modules/conf/dist/source/index.js
|
|
36550
36551
|
var import_semver = __toESM(require_semver2(), 1);
|
|
36551
36552
|
|
|
36552
36553
|
// ../node_modules/uint8array-extras/index.js
|
|
@@ -36588,7 +36589,7 @@ function stringToUint8Array(string4) {
|
|
|
36588
36589
|
}
|
|
36589
36590
|
var byteToHexLookupTable = Array.from({ length: 256 }, (_, index) => index.toString(16).padStart(2, "0"));
|
|
36590
36591
|
|
|
36591
|
-
//
|
|
36592
|
+
// node_modules/conf/dist/source/index.js
|
|
36592
36593
|
var Ajv = import_ajv.default.default;
|
|
36593
36594
|
var ajvFormats = import_ajv_formats.default.default;
|
|
36594
36595
|
var encryptionAlgorithm = "aes-256-cbc";
|
|
@@ -36985,7 +36986,6 @@ var Conf = class {
|
|
|
36985
36986
|
};
|
|
36986
36987
|
|
|
36987
36988
|
// src/core/context.ts
|
|
36988
|
-
var import_prompts = __toESM(require_prompts3(), 1);
|
|
36989
36989
|
var config = null;
|
|
36990
36990
|
function getConfig() {
|
|
36991
36991
|
if (!config) {
|
|
@@ -37021,58 +37021,17 @@ function resolveTargets(selector, candidates) {
|
|
|
37021
37021
|
}
|
|
37022
37022
|
async function getContext(options = {}) {
|
|
37023
37023
|
const { selector, createMissingDirs = true } = options;
|
|
37024
|
-
const choices = [];
|
|
37025
37024
|
const candidates = getCandidatePaths();
|
|
37026
37025
|
const directTargets = resolveTargets(selector, candidates);
|
|
37027
|
-
if (directTargets) {
|
|
37028
|
-
const activeConfig2 = getConfig();
|
|
37029
|
-
if (createMissingDirs) {
|
|
37030
|
-
for (const target of directTargets) {
|
|
37031
|
-
await import_fs_extra.default.ensureDir(target);
|
|
37032
|
-
}
|
|
37033
|
-
}
|
|
37034
|
-
return {
|
|
37035
|
-
targets: directTargets,
|
|
37036
|
-
syncMode: activeConfig2.get("syncMode"),
|
|
37037
|
-
config: activeConfig2
|
|
37038
|
-
};
|
|
37039
|
-
}
|
|
37040
37026
|
const activeConfig = getConfig();
|
|
37041
|
-
|
|
37042
|
-
const exists = await import_fs_extra.default.pathExists(c.path);
|
|
37043
|
-
const icon = exists ? kleur_default.green("\u25CF") : kleur_default.gray("\u25CB");
|
|
37044
|
-
const desc = exists ? "Found" : "Not found (will create)";
|
|
37045
|
-
choices.push({
|
|
37046
|
-
title: `${icon} ${c.label} (${c.path})`,
|
|
37047
|
-
description: desc,
|
|
37048
|
-
value: c.path,
|
|
37049
|
-
selected: exists
|
|
37050
|
-
// Pre-select existing environments
|
|
37051
|
-
});
|
|
37052
|
-
}
|
|
37053
|
-
const response = await (0, import_prompts.default)({
|
|
37054
|
-
type: "multiselect",
|
|
37055
|
-
name: "targets",
|
|
37056
|
-
message: "Select target environment(s):",
|
|
37057
|
-
choices,
|
|
37058
|
-
hint: "- Space to select. Return to submit",
|
|
37059
|
-
instructions: false
|
|
37060
|
-
});
|
|
37061
|
-
if (response.targets === void 0) {
|
|
37062
|
-
console.log(kleur_default.gray("\nCancelled."));
|
|
37063
|
-
process.exit(130);
|
|
37064
|
-
}
|
|
37065
|
-
if (response.targets.length === 0) {
|
|
37066
|
-
console.log(kleur_default.gray("No targets selected."));
|
|
37067
|
-
process.exit(0);
|
|
37068
|
-
}
|
|
37027
|
+
const selectedPaths = directTargets ?? candidates.map((c) => c.path);
|
|
37069
37028
|
if (createMissingDirs) {
|
|
37070
|
-
for (const target of
|
|
37029
|
+
for (const target of selectedPaths) {
|
|
37071
37030
|
await import_fs_extra.default.ensureDir(target);
|
|
37072
37031
|
}
|
|
37073
37032
|
}
|
|
37074
37033
|
return {
|
|
37075
|
-
targets:
|
|
37034
|
+
targets: selectedPaths,
|
|
37076
37035
|
syncMode: activeConfig.get("syncMode"),
|
|
37077
37036
|
config: activeConfig
|
|
37078
37037
|
};
|
|
@@ -37182,16 +37141,13 @@ var PruneModeReadError = class extends Error {
|
|
|
37182
37141
|
async function calculateDiff(repoRoot, systemRoot, pruneMode = false) {
|
|
37183
37142
|
const adapter = detectAdapter(systemRoot);
|
|
37184
37143
|
const isClaude = adapter?.toolName === "claude-code";
|
|
37185
|
-
const isQwen = adapter?.toolName === "qwen";
|
|
37186
37144
|
const normalizedRoot = (0, import_path4.normalize)(systemRoot).replace(/\\/g, "/");
|
|
37187
37145
|
const isAgentsSkills = normalizedRoot.includes(".agents/skills");
|
|
37188
37146
|
const changeSet = {
|
|
37189
37147
|
skills: { missing: [], outdated: [], drifted: [], total: 0 },
|
|
37190
37148
|
hooks: { missing: [], outdated: [], drifted: [], total: 0 },
|
|
37191
37149
|
config: { missing: [], outdated: [], drifted: [], total: 0 },
|
|
37192
|
-
commands: { missing: [], outdated: [], drifted: [], total: 0 }
|
|
37193
|
-
"qwen-commands": { missing: [], outdated: [], drifted: [], total: 0 },
|
|
37194
|
-
"antigravity-workflows": { missing: [], outdated: [], drifted: [], total: 0 }
|
|
37150
|
+
commands: { missing: [], outdated: [], drifted: [], total: 0 }
|
|
37195
37151
|
};
|
|
37196
37152
|
const manifestPath = (0, import_path4.join)(systemRoot, ".jaggers-sync-manifest.json");
|
|
37197
37153
|
let installedHashes = null;
|
|
@@ -37215,18 +37171,10 @@ async function calculateDiff(repoRoot, systemRoot, pruneMode = false) {
|
|
|
37215
37171
|
return changeSet;
|
|
37216
37172
|
}
|
|
37217
37173
|
const folders = ["skills", "hooks"];
|
|
37218
|
-
if (
|
|
37219
|
-
else if (!isClaude) folders.push("commands");
|
|
37174
|
+
if (!isClaude) folders.push("commands");
|
|
37220
37175
|
for (const category of folders) {
|
|
37221
|
-
|
|
37222
|
-
|
|
37223
|
-
if (category === "qwen-commands") {
|
|
37224
|
-
repoPath = (0, import_path4.join)(repoRoot, ".qwen", "commands");
|
|
37225
|
-
systemPath = (0, import_path4.join)(systemRoot, "commands");
|
|
37226
|
-
} else {
|
|
37227
|
-
repoPath = (0, import_path4.join)(repoRoot, category);
|
|
37228
|
-
systemPath = (0, import_path4.join)(systemRoot, category);
|
|
37229
|
-
}
|
|
37176
|
+
const repoPath = (0, import_path4.join)(repoRoot, category);
|
|
37177
|
+
const systemPath = (0, import_path4.join)(systemRoot, category);
|
|
37230
37178
|
if (!await import_fs_extra3.default.pathExists(repoPath)) continue;
|
|
37231
37179
|
const items = (await import_fs_extra3.default.readdir(repoPath)).filter((i) => !IGNORED_ITEMS.has(i));
|
|
37232
37180
|
changeSet[category].total = items.length;
|
|
@@ -37417,7 +37365,7 @@ function mergeHookWrappers(existing, incoming) {
|
|
|
37417
37365
|
if (!existingCommands.some((c) => incomingKeys.has(commandKey(c)))) return false;
|
|
37418
37366
|
if (typeof existingWrapper2.matcher === "string" && typeof incomingWrapper.matcher === "string" && incomingTokens.size > 0) {
|
|
37419
37367
|
const existingTokens = existingWrapper2.matcher.split("|").map((s) => s.trim()).filter(Boolean);
|
|
37420
|
-
const hasOverlap = existingTokens.some((
|
|
37368
|
+
const hasOverlap = existingTokens.some((t3) => incomingTokens.has(t3));
|
|
37421
37369
|
if (!hasOverlap) return false;
|
|
37422
37370
|
}
|
|
37423
37371
|
return true;
|
|
@@ -40170,7 +40118,7 @@ async function handleMissingEnvVars(missing) {
|
|
|
40170
40118
|
if (missing.length === 0) {
|
|
40171
40119
|
return true;
|
|
40172
40120
|
}
|
|
40173
|
-
const
|
|
40121
|
+
const prompts6 = (await Promise.resolve().then(() => __toESM(require_prompts3(), 1))).default;
|
|
40174
40122
|
const answers = {};
|
|
40175
40123
|
for (const key of missing) {
|
|
40176
40124
|
const config3 = REQUIRED_ENV_VARS[key];
|
|
@@ -40182,7 +40130,7 @@ async function handleMissingEnvVars(missing) {
|
|
|
40182
40130
|
console.log(kleur_default.yellow(`
|
|
40183
40131
|
\u26A0\uFE0F ${key} is required by a selected MCP server`));
|
|
40184
40132
|
}
|
|
40185
|
-
const { value } = await
|
|
40133
|
+
const { value } = await prompts6({
|
|
40186
40134
|
type: "text",
|
|
40187
40135
|
name: "value",
|
|
40188
40136
|
message: `Enter ${key}:`,
|
|
@@ -40395,8 +40343,8 @@ async function syncMcpServersWithCli(agent, mcpConfig, dryRun = false, prune = f
|
|
|
40395
40343
|
}
|
|
40396
40344
|
let selectedNames = toAdd.map(([name]) => name);
|
|
40397
40345
|
if (!dryRun) {
|
|
40398
|
-
const
|
|
40399
|
-
const { selected } = await
|
|
40346
|
+
const prompts6 = await Promise.resolve().then(() => __toESM(require_prompts3(), 1));
|
|
40347
|
+
const { selected } = await prompts6.default({
|
|
40400
40348
|
type: "multiselect",
|
|
40401
40349
|
name: "selected",
|
|
40402
40350
|
message: `Select MCP servers to install via ${agent} CLI:`,
|
|
@@ -40853,36 +40801,49 @@ var sym = {
|
|
|
40853
40801
|
};
|
|
40854
40802
|
|
|
40855
40803
|
// src/commands/install.ts
|
|
40856
|
-
var
|
|
40804
|
+
var import_path12 = __toESM(require("path"), 1);
|
|
40857
40805
|
|
|
40858
40806
|
// src/commands/pi-install.ts
|
|
40859
|
-
var
|
|
40860
|
-
var
|
|
40807
|
+
var import_fs_extra11 = __toESM(require_lib2(), 1);
|
|
40808
|
+
var import_path11 = __toESM(require("path"), 1);
|
|
40861
40809
|
var import_node_child_process = require("child_process");
|
|
40862
40810
|
var import_node_os4 = require("os");
|
|
40863
|
-
|
|
40811
|
+
|
|
40812
|
+
// src/utils/pi-extensions.ts
|
|
40813
|
+
var import_fs_extra10 = __toESM(require_lib2(), 1);
|
|
40814
|
+
var import_path10 = __toESM(require("path"), 1);
|
|
40815
|
+
async function syncManagedPiExtensions({
|
|
40816
|
+
sourceDir,
|
|
40817
|
+
targetDir,
|
|
40818
|
+
dryRun = false,
|
|
40819
|
+
log
|
|
40820
|
+
}) {
|
|
40821
|
+
if (!await import_fs_extra10.default.pathExists(sourceDir)) return 0;
|
|
40822
|
+
if (!dryRun) {
|
|
40823
|
+
await import_fs_extra10.default.ensureDir(import_path10.default.dirname(targetDir));
|
|
40824
|
+
await import_fs_extra10.default.copy(sourceDir, targetDir, { overwrite: true });
|
|
40825
|
+
}
|
|
40826
|
+
const entries = await import_fs_extra10.default.readdir(sourceDir, { withFileTypes: true });
|
|
40827
|
+
const managedPackages = entries.filter((entry) => entry.isDirectory()).length;
|
|
40828
|
+
if (log) {
|
|
40829
|
+
if (dryRun) {
|
|
40830
|
+
log(` [DRY RUN] sync extensions ${sourceDir} -> ${targetDir}`);
|
|
40831
|
+
}
|
|
40832
|
+
log(` Pi will auto-discover ${managedPackages} extension package(s) from ${targetDir}`);
|
|
40833
|
+
}
|
|
40834
|
+
return managedPackages;
|
|
40835
|
+
}
|
|
40836
|
+
|
|
40837
|
+
// src/commands/pi-install.ts
|
|
40838
|
+
var PI_AGENT_DIR = process.env.PI_AGENT_DIR || import_path11.default.join((0, import_node_os4.homedir)(), ".pi", "agent");
|
|
40864
40839
|
function isPiInstalled() {
|
|
40865
40840
|
const r = (0, import_node_child_process.spawnSync)("pi", ["--version"], { encoding: "utf8", stdio: "pipe" });
|
|
40866
40841
|
return r.status === 0;
|
|
40867
40842
|
}
|
|
40868
|
-
async function listExtensionDirs(baseDir) {
|
|
40869
|
-
if (!await import_fs_extra10.default.pathExists(baseDir)) return [];
|
|
40870
|
-
const entries = await import_fs_extra10.default.readdir(baseDir, { withFileTypes: true });
|
|
40871
|
-
const extDirs = [];
|
|
40872
|
-
for (const entry of entries) {
|
|
40873
|
-
if (!entry.isDirectory()) continue;
|
|
40874
|
-
const extPath = import_path10.default.join(baseDir, entry.name);
|
|
40875
|
-
const pkgPath = import_path10.default.join(extPath, "package.json");
|
|
40876
|
-
if (await import_fs_extra10.default.pathExists(pkgPath)) {
|
|
40877
|
-
extDirs.push(extPath);
|
|
40878
|
-
}
|
|
40879
|
-
}
|
|
40880
|
-
return extDirs;
|
|
40881
|
-
}
|
|
40882
40843
|
async function runPiInstall(dryRun = false) {
|
|
40883
40844
|
const repoRoot = await findRepoRoot();
|
|
40884
|
-
const piConfigDir =
|
|
40885
|
-
const schemaPath =
|
|
40845
|
+
const piConfigDir = import_path11.default.join(repoRoot, "config", "pi");
|
|
40846
|
+
const schemaPath = import_path11.default.join(piConfigDir, "install-schema.json");
|
|
40886
40847
|
console.log(t.bold("\n \u2699 Pi extensions + packages"));
|
|
40887
40848
|
if (!isPiInstalled()) {
|
|
40888
40849
|
console.log(kleur_default.yellow(" pi not found \u2014 installing oh-pi globally..."));
|
|
@@ -40900,37 +40861,22 @@ async function runPiInstall(dryRun = false) {
|
|
|
40900
40861
|
const v = (0, import_node_child_process.spawnSync)("pi", ["--version"], { encoding: "utf8" });
|
|
40901
40862
|
console.log(t.success(` \u2713 pi ${v.stdout.trim()} already installed`));
|
|
40902
40863
|
}
|
|
40903
|
-
const extensionsSrc =
|
|
40904
|
-
const extensionsDst =
|
|
40905
|
-
|
|
40906
|
-
|
|
40907
|
-
|
|
40908
|
-
|
|
40909
|
-
|
|
40910
|
-
|
|
40911
|
-
|
|
40912
|
-
|
|
40913
|
-
console.log(kleur_default.dim(` Registering ${extDirs.length} extensions...`));
|
|
40914
|
-
for (const extPath of extDirs) {
|
|
40915
|
-
const extName = import_path10.default.basename(extPath);
|
|
40916
|
-
if (dryRun) {
|
|
40917
|
-
console.log(kleur_default.cyan(` [DRY RUN] pi install -l ~/.pi/agent/extensions/${extName}`));
|
|
40918
|
-
continue;
|
|
40919
|
-
}
|
|
40920
|
-
const r = (0, import_node_child_process.spawnSync)("pi", ["install", "-l", extPath], { stdio: "pipe", encoding: "utf8" });
|
|
40921
|
-
if (r.status === 0) {
|
|
40922
|
-
console.log(t.success(` ${sym.ok} ${extName} registered`));
|
|
40923
|
-
} else {
|
|
40924
|
-
console.log(kleur_default.yellow(` \u26A0 ${extName} \u2014 registration failed`));
|
|
40925
|
-
}
|
|
40926
|
-
}
|
|
40927
|
-
}
|
|
40864
|
+
const extensionsSrc = import_path11.default.join(piConfigDir, "extensions");
|
|
40865
|
+
const extensionsDst = import_path11.default.join(PI_AGENT_DIR, "extensions");
|
|
40866
|
+
const managedPackages = await syncManagedPiExtensions({
|
|
40867
|
+
sourceDir: extensionsSrc,
|
|
40868
|
+
targetDir: extensionsDst,
|
|
40869
|
+
dryRun,
|
|
40870
|
+
log: (message) => console.log(kleur_default.dim(message))
|
|
40871
|
+
});
|
|
40872
|
+
if (managedPackages > 0) {
|
|
40873
|
+
console.log(t.success(` ${sym.ok} extensions synced (${managedPackages} packages)`));
|
|
40928
40874
|
}
|
|
40929
|
-
if (!await
|
|
40875
|
+
if (!await import_fs_extra11.default.pathExists(schemaPath)) {
|
|
40930
40876
|
console.log(kleur_default.dim(" No install-schema.json found, skipping packages"));
|
|
40931
40877
|
return;
|
|
40932
40878
|
}
|
|
40933
|
-
const schema = await
|
|
40879
|
+
const schema = await import_fs_extra11.default.readJson(schemaPath);
|
|
40934
40880
|
for (const pkg of schema.packages) {
|
|
40935
40881
|
if (dryRun) {
|
|
40936
40882
|
console.log(kleur_default.cyan(` [DRY RUN] pi install ${pkg}`));
|
|
@@ -40996,7 +40942,7 @@ function formatTargetLabel(target) {
|
|
|
40996
40942
|
const normalized = target.replace(/\\/g, "/").toLowerCase();
|
|
40997
40943
|
if (normalized.endsWith("/.agents/skills") || normalized.includes("/.agents/skills/")) return "~/.agents/skills";
|
|
40998
40944
|
if (normalized.endsWith("/.claude") || normalized.includes("/.claude/")) return "~/.claude";
|
|
40999
|
-
return
|
|
40945
|
+
return import_path12.default.basename(target);
|
|
41000
40946
|
}
|
|
41001
40947
|
function isBeadsInstalled() {
|
|
41002
40948
|
try {
|
|
@@ -41014,19 +40960,27 @@ function isDoltInstalled() {
|
|
|
41014
40960
|
return false;
|
|
41015
40961
|
}
|
|
41016
40962
|
}
|
|
40963
|
+
function isDeepwikiInstalled() {
|
|
40964
|
+
try {
|
|
40965
|
+
(0, import_child_process2.execSync)("deepwiki --version", { stdio: "ignore" });
|
|
40966
|
+
return true;
|
|
40967
|
+
} catch {
|
|
40968
|
+
return false;
|
|
40969
|
+
}
|
|
40970
|
+
}
|
|
41017
40971
|
async function needsSettingsSync(repoRoot, target) {
|
|
41018
40972
|
const normalizedTarget = target.replace(/\\/g, "/").toLowerCase();
|
|
41019
40973
|
if (normalizedTarget.includes(".agents/skills")) return false;
|
|
41020
40974
|
if (detectAgent(target) === "claude") return false;
|
|
41021
|
-
const hooksTemplatePath =
|
|
41022
|
-
if (!await
|
|
41023
|
-
const requiredEvents = Object.keys((await
|
|
40975
|
+
const hooksTemplatePath = import_path12.default.join(repoRoot, "config", "hooks.json");
|
|
40976
|
+
if (!await import_fs_extra12.default.pathExists(hooksTemplatePath)) return false;
|
|
40977
|
+
const requiredEvents = Object.keys((await import_fs_extra12.default.readJson(hooksTemplatePath)).hooks ?? {});
|
|
41024
40978
|
if (requiredEvents.length === 0) return false;
|
|
41025
|
-
const targetSettingsPath =
|
|
41026
|
-
if (!await
|
|
40979
|
+
const targetSettingsPath = import_path12.default.join(target, "settings.json");
|
|
40980
|
+
if (!await import_fs_extra12.default.pathExists(targetSettingsPath)) return true;
|
|
41027
40981
|
let settings = {};
|
|
41028
40982
|
try {
|
|
41029
|
-
settings = await
|
|
40983
|
+
settings = await import_fs_extra12.default.readJson(targetSettingsPath);
|
|
41030
40984
|
} catch {
|
|
41031
40985
|
return true;
|
|
41032
40986
|
}
|
|
@@ -41069,20 +41023,114 @@ async function installOfficialClaudePlugins(dryRun) {
|
|
|
41069
41023
|
console.log(t.success(` \u2713 Official plugins ready (${installedCount} installed, ${alreadyInstalledCount} already present)
|
|
41070
41024
|
`));
|
|
41071
41025
|
}
|
|
41026
|
+
async function cleanStalePrePluginFiles(repoRoot, dryRun) {
|
|
41027
|
+
const home = import_os5.default.homedir();
|
|
41028
|
+
const staleHooksDir = import_path12.default.join(home, ".claude", "hooks");
|
|
41029
|
+
const staleSkillsDir = import_path12.default.join(home, ".claude", "skills");
|
|
41030
|
+
const settingsPath = import_path12.default.join(home, ".claude", "settings.json");
|
|
41031
|
+
const removed = [];
|
|
41032
|
+
const repoHooksDir = import_path12.default.join(repoRoot, "hooks");
|
|
41033
|
+
if (await import_fs_extra12.default.pathExists(repoHooksDir) && await import_fs_extra12.default.pathExists(staleHooksDir)) {
|
|
41034
|
+
const repoHookNames = (await import_fs_extra12.default.readdir(repoHooksDir)).filter((n) => n !== "README.md" && n !== "hooks.json");
|
|
41035
|
+
for (const name of repoHookNames) {
|
|
41036
|
+
const staleFile = import_path12.default.join(staleHooksDir, name);
|
|
41037
|
+
if (await import_fs_extra12.default.pathExists(staleFile)) {
|
|
41038
|
+
if (dryRun) {
|
|
41039
|
+
console.log(t.accent(` [DRY RUN] Would remove stale hook: ~/.claude/hooks/${name}`));
|
|
41040
|
+
} else {
|
|
41041
|
+
await import_fs_extra12.default.remove(staleFile);
|
|
41042
|
+
console.log(t.muted(` \u2717 Removed stale hook: ~/.claude/hooks/${name}`));
|
|
41043
|
+
}
|
|
41044
|
+
removed.push(`hooks/${name}`);
|
|
41045
|
+
}
|
|
41046
|
+
}
|
|
41047
|
+
}
|
|
41048
|
+
const repoSkillsDir = import_path12.default.join(repoRoot, "skills");
|
|
41049
|
+
if (await import_fs_extra12.default.pathExists(repoSkillsDir) && await import_fs_extra12.default.pathExists(staleSkillsDir)) {
|
|
41050
|
+
const repoSkillNames = (await import_fs_extra12.default.readdir(repoSkillsDir)).filter((n) => !n.startsWith("."));
|
|
41051
|
+
for (const name of repoSkillNames) {
|
|
41052
|
+
const staleDir = import_path12.default.join(staleSkillsDir, name);
|
|
41053
|
+
if (await import_fs_extra12.default.pathExists(staleDir)) {
|
|
41054
|
+
if (dryRun) {
|
|
41055
|
+
console.log(t.accent(` [DRY RUN] Would remove stale skill: ~/.claude/skills/${name}`));
|
|
41056
|
+
} else {
|
|
41057
|
+
await import_fs_extra12.default.remove(staleDir);
|
|
41058
|
+
console.log(t.muted(` \u2717 Removed stale skill: ~/.claude/skills/${name}`));
|
|
41059
|
+
}
|
|
41060
|
+
removed.push(`skills/${name}`);
|
|
41061
|
+
}
|
|
41062
|
+
}
|
|
41063
|
+
}
|
|
41064
|
+
if (await import_fs_extra12.default.pathExists(settingsPath)) {
|
|
41065
|
+
let settings;
|
|
41066
|
+
try {
|
|
41067
|
+
settings = await import_fs_extra12.default.readJson(settingsPath);
|
|
41068
|
+
} catch {
|
|
41069
|
+
settings = null;
|
|
41070
|
+
}
|
|
41071
|
+
if (settings && settings.hooks && typeof settings.hooks === "object") {
|
|
41072
|
+
let settingsModified = false;
|
|
41073
|
+
for (const [event, matchers] of Object.entries(settings.hooks)) {
|
|
41074
|
+
if (!Array.isArray(matchers)) continue;
|
|
41075
|
+
const cleanedMatchers = matchers.filter((matcher) => {
|
|
41076
|
+
const hooks = Array.isArray(matcher?.hooks) ? matcher.hooks : [];
|
|
41077
|
+
const staleHooks = hooks.filter((h) => {
|
|
41078
|
+
const cmd = typeof h?.command === "string" ? h.command : "";
|
|
41079
|
+
return cmd.includes("/.claude/hooks/") && !cmd.includes("${CLAUDE_PLUGIN_ROOT}");
|
|
41080
|
+
});
|
|
41081
|
+
if (staleHooks.length > 0) {
|
|
41082
|
+
for (const h of staleHooks) {
|
|
41083
|
+
const msg = `settings.json [${event}] hook: ${h.command}`;
|
|
41084
|
+
if (dryRun) {
|
|
41085
|
+
console.log(t.accent(` [DRY RUN] Would remove stale ${msg}`));
|
|
41086
|
+
} else {
|
|
41087
|
+
console.log(t.muted(` \u2717 Removed stale ${msg}`));
|
|
41088
|
+
}
|
|
41089
|
+
removed.push(msg);
|
|
41090
|
+
}
|
|
41091
|
+
const remainingHooks = hooks.filter((h) => {
|
|
41092
|
+
const cmd = typeof h?.command === "string" ? h.command : "";
|
|
41093
|
+
return !(cmd.includes("/.claude/hooks/") && !cmd.includes("${CLAUDE_PLUGIN_ROOT}"));
|
|
41094
|
+
});
|
|
41095
|
+
if (remainingHooks.length === 0) return false;
|
|
41096
|
+
matcher.hooks = remainingHooks;
|
|
41097
|
+
settingsModified = true;
|
|
41098
|
+
return true;
|
|
41099
|
+
}
|
|
41100
|
+
return true;
|
|
41101
|
+
});
|
|
41102
|
+
if (cleanedMatchers.length !== matchers.length) {
|
|
41103
|
+
settings.hooks[event] = cleanedMatchers;
|
|
41104
|
+
settingsModified = true;
|
|
41105
|
+
}
|
|
41106
|
+
}
|
|
41107
|
+
if (settingsModified && !dryRun) {
|
|
41108
|
+
await import_fs_extra12.default.writeJson(settingsPath, settings, { spaces: 2 });
|
|
41109
|
+
}
|
|
41110
|
+
}
|
|
41111
|
+
}
|
|
41112
|
+
if (removed.length === 0) {
|
|
41113
|
+
console.log(t.success(" \u2713 No stale pre-plugin files found"));
|
|
41114
|
+
}
|
|
41115
|
+
}
|
|
41072
41116
|
async function installPlugin(repoRoot, dryRun) {
|
|
41073
41117
|
console.log(t.bold("\n \u2699 xtrm-tools (Claude Code plugin)"));
|
|
41074
41118
|
if (dryRun) {
|
|
41075
41119
|
console.log(t.accent(" [DRY RUN] Would register xtrm-tools marketplace and install plugin\n"));
|
|
41120
|
+
await cleanStalePrePluginFiles(repoRoot, true);
|
|
41076
41121
|
await installOfficialClaudePlugins(true);
|
|
41077
41122
|
return;
|
|
41078
41123
|
}
|
|
41079
|
-
|
|
41124
|
+
const xtrmPkgRoot = import_path12.default.resolve(__dirname, "..", "..");
|
|
41125
|
+
(0, import_child_process3.spawnSync)("claude", ["plugin", "marketplace", "add", xtrmPkgRoot, "--scope", "user"], { stdio: "pipe" });
|
|
41080
41126
|
const listResult = (0, import_child_process3.spawnSync)("claude", ["plugin", "list"], { encoding: "utf8", stdio: "pipe" });
|
|
41081
41127
|
if (listResult.stdout?.includes("xtrm-tools@xtrm-tools")) {
|
|
41082
41128
|
(0, import_child_process3.spawnSync)("claude", ["plugin", "uninstall", "xtrm-tools@xtrm-tools"], { stdio: "inherit" });
|
|
41083
41129
|
}
|
|
41084
41130
|
(0, import_child_process3.spawnSync)("claude", ["plugin", "install", "xtrm-tools@xtrm-tools", "--scope", "user"], { stdio: "inherit" });
|
|
41085
41131
|
console.log(t.success(" \u2713 xtrm-tools plugin installed"));
|
|
41132
|
+
console.log(t.warning(" \u21BB Restart Claude Code for the new plugin hooks to take effect"));
|
|
41133
|
+
await cleanStalePrePluginFiles(repoRoot, dryRun);
|
|
41086
41134
|
await installOfficialClaudePlugins(false);
|
|
41087
41135
|
}
|
|
41088
41136
|
function createInstallAllCommand() {
|
|
@@ -41107,8 +41155,8 @@ function createInstallCommand() {
|
|
|
41107
41155
|
createMissingDirs: !dryRun
|
|
41108
41156
|
});
|
|
41109
41157
|
const { targets, syncMode } = ctx;
|
|
41110
|
-
const claudeTargets = targets.filter((
|
|
41111
|
-
const otherTargets = targets.filter((
|
|
41158
|
+
const claudeTargets = targets.filter((t3) => detectAgent(t3) === "claude");
|
|
41159
|
+
const otherTargets = targets.filter((t3) => detectAgent(t3) !== "claude");
|
|
41112
41160
|
if (!backport) {
|
|
41113
41161
|
console.log(t.bold("\n \u2699 beads + dolt (workflow enforcement backend)"));
|
|
41114
41162
|
console.log(t.muted(" beads is a git-backed issue tracker; dolt is its SQL+git storage backend."));
|
|
@@ -41121,7 +41169,7 @@ function createInstallCommand() {
|
|
|
41121
41169
|
const missing = [!beadsOk && "bd", !doltOk && "dolt"].filter(Boolean).join(", ");
|
|
41122
41170
|
let doInstall = effectiveYes;
|
|
41123
41171
|
if (!effectiveYes) {
|
|
41124
|
-
const { install } = await (0,
|
|
41172
|
+
const { install } = await (0, import_prompts.default)({
|
|
41125
41173
|
type: "confirm",
|
|
41126
41174
|
name: "install",
|
|
41127
41175
|
message: `Install beads + dolt? (${missing} not found) \u2014 required for workflow enforcement hooks`,
|
|
@@ -41154,6 +41202,31 @@ function createInstallCommand() {
|
|
|
41154
41202
|
}
|
|
41155
41203
|
}
|
|
41156
41204
|
}
|
|
41205
|
+
if (!backport) {
|
|
41206
|
+
console.log(t.bold("\n \u2699 deepwiki (AI-powered repo documentation)"));
|
|
41207
|
+
const deepwikiOk = isDeepwikiInstalled();
|
|
41208
|
+
if (deepwikiOk) {
|
|
41209
|
+
console.log(t.success(" \u2713 deepwiki already installed\n"));
|
|
41210
|
+
} else {
|
|
41211
|
+
let doInstall = effectiveYes;
|
|
41212
|
+
if (!effectiveYes) {
|
|
41213
|
+
const { install } = await (0, import_prompts.default)({
|
|
41214
|
+
type: "confirm",
|
|
41215
|
+
name: "install",
|
|
41216
|
+
message: "Install @seflless/deepwiki?",
|
|
41217
|
+
initial: true
|
|
41218
|
+
});
|
|
41219
|
+
doInstall = install;
|
|
41220
|
+
}
|
|
41221
|
+
if (doInstall) {
|
|
41222
|
+
console.log(t.muted("\n Installing @seflless/deepwiki..."));
|
|
41223
|
+
(0, import_child_process3.spawnSync)("npm", ["install", "-g", "@seflless/deepwiki"], { stdio: "inherit" });
|
|
41224
|
+
console.log(t.success(" \u2713 deepwiki installed\n"));
|
|
41225
|
+
} else {
|
|
41226
|
+
console.log(t.muted(" \u2139 Skipped.\n"));
|
|
41227
|
+
}
|
|
41228
|
+
}
|
|
41229
|
+
}
|
|
41157
41230
|
if (!backport) {
|
|
41158
41231
|
for (const _claudeTarget of claudeTargets) {
|
|
41159
41232
|
await installPlugin(repoRoot, dryRun);
|
|
@@ -41207,7 +41280,7 @@ function createInstallCommand() {
|
|
|
41207
41280
|
}
|
|
41208
41281
|
if (!effectiveYes) {
|
|
41209
41282
|
const totalChangesCount = allChanges.reduce((s, c) => s + c.totalChanges, 0);
|
|
41210
|
-
const { confirm } = await (0,
|
|
41283
|
+
const { confirm } = await (0, import_prompts.default)({
|
|
41211
41284
|
type: "confirm",
|
|
41212
41285
|
name: "confirm",
|
|
41213
41286
|
message: `Proceed with ${actionLabel} (${totalChangesCount} total changes)?`,
|
|
@@ -41245,61 +41318,93 @@ var import_node_child_process3 = require("child_process");
|
|
|
41245
41318
|
|
|
41246
41319
|
// src/utils/worktree-session.ts
|
|
41247
41320
|
var import_node_path5 = __toESM(require("path"), 1);
|
|
41248
|
-
var import_fs_extra12 = __toESM(require_lib2(), 1);
|
|
41249
41321
|
var import_node_child_process2 = require("child_process");
|
|
41322
|
+
var import_node_fs4 = require("fs");
|
|
41323
|
+
var import_node_os5 = require("os");
|
|
41250
41324
|
function randomSlug(len = 4) {
|
|
41251
41325
|
return Math.random().toString(36).slice(2, 2 + len);
|
|
41252
41326
|
}
|
|
41253
|
-
function
|
|
41254
|
-
const
|
|
41255
|
-
|
|
41327
|
+
function gitRepoRoot(cwd) {
|
|
41328
|
+
const r = (0, import_node_child_process2.spawnSync)("git", ["rev-parse", "--show-toplevel"], {
|
|
41329
|
+
cwd,
|
|
41330
|
+
stdio: "pipe",
|
|
41331
|
+
encoding: "utf8"
|
|
41332
|
+
});
|
|
41333
|
+
return r.status === 0 ? (r.stdout ?? "").trim() : null;
|
|
41334
|
+
}
|
|
41335
|
+
function resolveStatuslineScript() {
|
|
41336
|
+
const pluginsFile = import_node_path5.default.join((0, import_node_os5.homedir)(), ".claude", "plugins", "installed_plugins.json");
|
|
41337
|
+
try {
|
|
41338
|
+
const plugins = JSON.parse((0, import_node_fs4.readFileSync)(pluginsFile, "utf8"));
|
|
41339
|
+
for (const [key, entries] of Object.entries(plugins?.plugins ?? {})) {
|
|
41340
|
+
if (!key.startsWith("xtrm-tools@") || !entries?.length) continue;
|
|
41341
|
+
const p = import_node_path5.default.join(entries[0].installPath, "hooks", "statusline.mjs");
|
|
41342
|
+
if ((0, import_node_fs4.existsSync)(p)) return p;
|
|
41343
|
+
}
|
|
41344
|
+
} catch {
|
|
41345
|
+
}
|
|
41346
|
+
const fallback = import_node_path5.default.join((0, import_node_os5.homedir)(), ".claude", "hooks", "statusline.mjs");
|
|
41347
|
+
return (0, import_node_fs4.existsSync)(fallback) ? fallback : null;
|
|
41256
41348
|
}
|
|
41257
41349
|
async function launchWorktreeSession(opts) {
|
|
41258
41350
|
const { runtime, name } = opts;
|
|
41259
41351
|
const cwd = process.cwd();
|
|
41260
|
-
const repoRoot =
|
|
41261
|
-
|
|
41262
|
-
|
|
41263
|
-
|
|
41264
|
-
|
|
41265
|
-
const
|
|
41352
|
+
const repoRoot = gitRepoRoot(cwd);
|
|
41353
|
+
if (!repoRoot) {
|
|
41354
|
+
console.error(kleur_default.red("\n \u2717 Not inside a git repository\n"));
|
|
41355
|
+
process.exit(1);
|
|
41356
|
+
}
|
|
41357
|
+
const cwdBasename = import_node_path5.default.basename(repoRoot);
|
|
41358
|
+
const slug = name ?? randomSlug(4);
|
|
41359
|
+
const worktreeName = `${cwdBasename}-xt-${runtime}-${slug}`;
|
|
41360
|
+
const worktreePath = import_node_path5.default.join(repoRoot, ".xtrm", "worktrees", worktreeName);
|
|
41361
|
+
const branchName = `xt/${slug}`;
|
|
41266
41362
|
console.log(kleur_default.bold(`
|
|
41267
41363
|
Launching ${runtime} session`));
|
|
41268
41364
|
console.log(kleur_default.dim(` worktree: ${worktreePath}`));
|
|
41269
41365
|
console.log(kleur_default.dim(` branch: ${branchName}
|
|
41270
41366
|
`));
|
|
41271
|
-
const
|
|
41367
|
+
const bdResult = (0, import_node_child_process2.spawnSync)("bd", ["worktree", "create", worktreePath, "--branch", branchName], {
|
|
41272
41368
|
cwd: repoRoot,
|
|
41273
|
-
stdio: "
|
|
41274
|
-
})
|
|
41275
|
-
|
|
41276
|
-
|
|
41277
|
-
|
|
41278
|
-
|
|
41369
|
+
stdio: "inherit"
|
|
41370
|
+
});
|
|
41371
|
+
if (bdResult.error || bdResult.status !== 0) {
|
|
41372
|
+
if (bdResult.status !== 0 && !bdResult.error) {
|
|
41373
|
+
console.log(kleur_default.dim(" beads: no database found, creating worktree without redirect"));
|
|
41374
|
+
}
|
|
41375
|
+
const branchExists = (0, import_node_child_process2.spawnSync)("git", ["rev-parse", "--verify", branchName], {
|
|
41376
|
+
cwd: repoRoot,
|
|
41377
|
+
stdio: "pipe"
|
|
41378
|
+
}).status === 0;
|
|
41379
|
+
const gitArgs = branchExists ? ["worktree", "add", worktreePath, branchName] : ["worktree", "add", "-b", branchName, worktreePath];
|
|
41380
|
+
const gitResult = (0, import_node_child_process2.spawnSync)("git", gitArgs, { cwd: repoRoot, stdio: "inherit" });
|
|
41381
|
+
if (gitResult.status !== 0) {
|
|
41382
|
+
console.error(kleur_default.red(`
|
|
41279
41383
|
\u2717 Failed to create worktree at ${worktreePath}
|
|
41280
41384
|
`));
|
|
41281
|
-
|
|
41282
|
-
}
|
|
41283
|
-
const mainBeadsDir = import_node_path5.default.join(repoRoot, ".beads");
|
|
41284
|
-
const worktreeBeadsDir = import_node_path5.default.join(worktreePath, ".beads");
|
|
41285
|
-
const mainPortFile = import_node_path5.default.join(mainBeadsDir, "dolt-server.port");
|
|
41286
|
-
if (await import_fs_extra12.default.pathExists(mainBeadsDir)) {
|
|
41287
|
-
const worktreePortFile = import_node_path5.default.join(worktreeBeadsDir, "dolt-server.port");
|
|
41288
|
-
(0, import_node_child_process2.spawnSync)("bd", ["dolt", "stop"], { cwd: worktreePath, stdio: "pipe" });
|
|
41289
|
-
if (await import_fs_extra12.default.pathExists(mainPortFile)) {
|
|
41290
|
-
const mainPort = (await import_fs_extra12.default.readFile(mainPortFile, "utf8")).trim();
|
|
41291
|
-
await import_fs_extra12.default.ensureDir(worktreeBeadsDir);
|
|
41292
|
-
await import_fs_extra12.default.writeFile(worktreePortFile, mainPort, "utf8");
|
|
41293
|
-
console.log(kleur_default.dim(` beads: redirected to main server (port ${mainPort})`));
|
|
41294
|
-
} else {
|
|
41295
|
-
console.log(kleur_default.dim(" beads: no port file found in main checkout, skipping redirect"));
|
|
41385
|
+
process.exit(1);
|
|
41296
41386
|
}
|
|
41297
41387
|
}
|
|
41298
41388
|
console.log(kleur_default.green(`
|
|
41299
41389
|
\u2713 Worktree ready \u2014 launching ${runtime}...
|
|
41300
41390
|
`));
|
|
41391
|
+
if (runtime === "claude") {
|
|
41392
|
+
const statuslinePath = resolveStatuslineScript();
|
|
41393
|
+
if (statuslinePath) {
|
|
41394
|
+
const claudeDir = import_node_path5.default.join(worktreePath, ".claude");
|
|
41395
|
+
const localSettingsPath = import_node_path5.default.join(claudeDir, "settings.local.json");
|
|
41396
|
+
try {
|
|
41397
|
+
(0, import_node_fs4.mkdirSync)(claudeDir, { recursive: true });
|
|
41398
|
+
(0, import_node_fs4.writeFileSync)(localSettingsPath, JSON.stringify({
|
|
41399
|
+
statusLine: { type: "command", command: `node ${statuslinePath}`, padding: 1 }
|
|
41400
|
+
}, null, 2));
|
|
41401
|
+
} catch {
|
|
41402
|
+
}
|
|
41403
|
+
}
|
|
41404
|
+
}
|
|
41301
41405
|
const runtimeCmd = runtime === "claude" ? "claude" : "pi";
|
|
41302
|
-
const
|
|
41406
|
+
const runtimeArgs = runtime === "claude" ? ["--dangerously-skip-permissions"] : [];
|
|
41407
|
+
const launchResult = (0, import_node_child_process2.spawnSync)(runtimeCmd, runtimeArgs, {
|
|
41303
41408
|
cwd: worktreePath,
|
|
41304
41409
|
stdio: "inherit"
|
|
41305
41410
|
});
|
|
@@ -41392,31 +41497,31 @@ function createClaudeCommand() {
|
|
|
41392
41497
|
}
|
|
41393
41498
|
|
|
41394
41499
|
// src/commands/pi.ts
|
|
41395
|
-
var
|
|
41500
|
+
var import_path14 = __toESM(require("path"), 1);
|
|
41396
41501
|
var import_node_child_process5 = require("child_process");
|
|
41397
|
-
var
|
|
41502
|
+
var import_node_os7 = require("os");
|
|
41398
41503
|
var import_fs_extra14 = __toESM(require_lib2(), 1);
|
|
41399
41504
|
|
|
41400
41505
|
// src/commands/install-pi.ts
|
|
41401
|
-
var
|
|
41506
|
+
var import_prompts2 = __toESM(require_prompts3(), 1);
|
|
41402
41507
|
var import_fs_extra13 = __toESM(require_lib2(), 1);
|
|
41403
|
-
var
|
|
41508
|
+
var import_path13 = __toESM(require("path"), 1);
|
|
41404
41509
|
var import_node_child_process4 = require("child_process");
|
|
41405
|
-
var
|
|
41406
|
-
var PI_AGENT_DIR2 = process.env.PI_AGENT_DIR ||
|
|
41510
|
+
var import_node_os6 = require("os");
|
|
41511
|
+
var PI_AGENT_DIR2 = process.env.PI_AGENT_DIR || import_path13.default.join((0, import_node_os6.homedir)(), ".pi", "agent");
|
|
41407
41512
|
function fillTemplate(template, values) {
|
|
41408
41513
|
return template.replace(/\{\{(\w+)\}\}/g, (_, key) => values[key] ?? "");
|
|
41409
41514
|
}
|
|
41410
41515
|
function readExistingPiValues(piAgentDir) {
|
|
41411
41516
|
const values = {};
|
|
41412
41517
|
try {
|
|
41413
|
-
const auth = JSON.parse(require("fs").readFileSync(
|
|
41518
|
+
const auth = JSON.parse(require("fs").readFileSync(import_path13.default.join(piAgentDir, "auth.json"), "utf8"));
|
|
41414
41519
|
if (auth?.dashscope?.key) values["DASHSCOPE_API_KEY"] = auth.dashscope.key;
|
|
41415
41520
|
if (auth?.zai?.key) values["ZAI_API_KEY"] = auth.zai.key;
|
|
41416
41521
|
} catch {
|
|
41417
41522
|
}
|
|
41418
41523
|
try {
|
|
41419
|
-
const models = JSON.parse(require("fs").readFileSync(
|
|
41524
|
+
const models = JSON.parse(require("fs").readFileSync(import_path13.default.join(piAgentDir, "models.json"), "utf8"));
|
|
41420
41525
|
if (!values["DASHSCOPE_API_KEY"] && models?.providers?.dashscope?.apiKey) {
|
|
41421
41526
|
values["DASHSCOPE_API_KEY"] = models.providers.dashscope.apiKey;
|
|
41422
41527
|
}
|
|
@@ -41427,14 +41532,14 @@ function readExistingPiValues(piAgentDir) {
|
|
|
41427
41532
|
function isPiInstalled2() {
|
|
41428
41533
|
return (0, import_node_child_process4.spawnSync)("pi", ["--version"], { encoding: "utf8" }).status === 0;
|
|
41429
41534
|
}
|
|
41430
|
-
async function
|
|
41535
|
+
async function listExtensionDirs(baseDir) {
|
|
41431
41536
|
if (!await import_fs_extra13.default.pathExists(baseDir)) return [];
|
|
41432
41537
|
const entries = await import_fs_extra13.default.readdir(baseDir, { withFileTypes: true });
|
|
41433
41538
|
const extDirs = [];
|
|
41434
41539
|
for (const entry of entries) {
|
|
41435
41540
|
if (!entry.isDirectory()) continue;
|
|
41436
|
-
const extPath =
|
|
41437
|
-
const pkgPath =
|
|
41541
|
+
const extPath = import_path13.default.join(baseDir, entry.name);
|
|
41542
|
+
const pkgPath = import_path13.default.join(extPath, "package.json");
|
|
41438
41543
|
if (await import_fs_extra13.default.pathExists(pkgPath)) {
|
|
41439
41544
|
extDirs.push(entry.name);
|
|
41440
41545
|
}
|
|
@@ -41447,8 +41552,8 @@ async function fileSha256(filePath) {
|
|
|
41447
41552
|
return crypto2.createHash("sha256").update(content).digest("hex");
|
|
41448
41553
|
}
|
|
41449
41554
|
async function extensionHash(extDir) {
|
|
41450
|
-
const pkgPath =
|
|
41451
|
-
const indexPath =
|
|
41555
|
+
const pkgPath = import_path13.default.join(extDir, "package.json");
|
|
41556
|
+
const indexPath = import_path13.default.join(extDir, "index.ts");
|
|
41452
41557
|
const hashes = [];
|
|
41453
41558
|
if (await import_fs_extra13.default.pathExists(pkgPath)) {
|
|
41454
41559
|
hashes.push(await fileSha256(pkgPath));
|
|
@@ -41459,20 +41564,20 @@ async function extensionHash(extDir) {
|
|
|
41459
41564
|
return hashes.join(":");
|
|
41460
41565
|
}
|
|
41461
41566
|
async function diffPiExtensions(sourceDir, targetDir) {
|
|
41462
|
-
const sourceAbs =
|
|
41463
|
-
const targetAbs =
|
|
41464
|
-
const sourceExts = await
|
|
41567
|
+
const sourceAbs = import_path13.default.resolve(sourceDir);
|
|
41568
|
+
const targetAbs = import_path13.default.resolve(targetDir);
|
|
41569
|
+
const sourceExts = await listExtensionDirs(sourceAbs);
|
|
41465
41570
|
const missing = [];
|
|
41466
41571
|
const stale = [];
|
|
41467
41572
|
const upToDate = [];
|
|
41468
41573
|
for (const extName of sourceExts) {
|
|
41469
|
-
const srcExtPath =
|
|
41470
|
-
const dstExtPath =
|
|
41574
|
+
const srcExtPath = import_path13.default.join(sourceAbs, extName);
|
|
41575
|
+
const dstExtPath = import_path13.default.join(targetAbs, extName);
|
|
41471
41576
|
if (!await import_fs_extra13.default.pathExists(dstExtPath)) {
|
|
41472
41577
|
missing.push(extName);
|
|
41473
41578
|
continue;
|
|
41474
41579
|
}
|
|
41475
|
-
const dstPkgPath =
|
|
41580
|
+
const dstPkgPath = import_path13.default.join(dstExtPath, "package.json");
|
|
41476
41581
|
if (!await import_fs_extra13.default.pathExists(dstPkgPath)) {
|
|
41477
41582
|
missing.push(extName);
|
|
41478
41583
|
continue;
|
|
@@ -41512,10 +41617,10 @@ function createInstallPiCommand() {
|
|
|
41512
41617
|
cmd.description("Install Pi coding agent with providers, extensions, and npm packages").option("-y, --yes", "Skip confirmation prompts", false).option("--check", "Check Pi extension deployment drift without writing changes", false).action(async (opts) => {
|
|
41513
41618
|
const { yes, check: check2 } = opts;
|
|
41514
41619
|
const repoRoot = await findRepoRoot();
|
|
41515
|
-
const piConfigDir =
|
|
41620
|
+
const piConfigDir = import_path13.default.join(repoRoot, "config", "pi");
|
|
41516
41621
|
if (check2) {
|
|
41517
|
-
const sourceDir =
|
|
41518
|
-
const targetDir =
|
|
41622
|
+
const sourceDir = import_path13.default.join(piConfigDir, "extensions");
|
|
41623
|
+
const targetDir = import_path13.default.join(PI_AGENT_DIR2, "extensions");
|
|
41519
41624
|
const diff = await diffPiExtensions(sourceDir, targetDir);
|
|
41520
41625
|
printPiCheckSummary(diff);
|
|
41521
41626
|
if (diff.missing.length > 0 || diff.stale.length > 0) {
|
|
@@ -41538,7 +41643,7 @@ function createInstallPiCommand() {
|
|
|
41538
41643
|
console.log(t.success(` pi ${v.stdout.trim()} already installed
|
|
41539
41644
|
`));
|
|
41540
41645
|
}
|
|
41541
|
-
const schema = await import_fs_extra13.default.readJson(
|
|
41646
|
+
const schema = await import_fs_extra13.default.readJson(import_path13.default.join(piConfigDir, "install-schema.json"));
|
|
41542
41647
|
const existing = readExistingPiValues(PI_AGENT_DIR2);
|
|
41543
41648
|
const values = { ...existing };
|
|
41544
41649
|
console.log(t.bold(" API Keys\n"));
|
|
@@ -41548,43 +41653,36 @@ function createInstallPiCommand() {
|
|
|
41548
41653
|
continue;
|
|
41549
41654
|
}
|
|
41550
41655
|
if (!field.required && !yes) {
|
|
41551
|
-
const { include } = await (0,
|
|
41656
|
+
const { include } = await (0, import_prompts2.default)({ type: "confirm", name: "include", message: ` Configure ${field.label}? (optional)`, initial: false });
|
|
41552
41657
|
if (!include) continue;
|
|
41553
41658
|
}
|
|
41554
|
-
const { value } = await (0,
|
|
41659
|
+
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 });
|
|
41555
41660
|
if (value) values[field.key] = value;
|
|
41556
41661
|
}
|
|
41557
41662
|
await import_fs_extra13.default.ensureDir(PI_AGENT_DIR2);
|
|
41558
41663
|
console.log(t.muted(`
|
|
41559
41664
|
Writing config to ${PI_AGENT_DIR2}`));
|
|
41560
41665
|
for (const name of ["models.json", "auth.json", "settings.json"]) {
|
|
41561
|
-
const destPath =
|
|
41666
|
+
const destPath = import_path13.default.join(PI_AGENT_DIR2, name);
|
|
41562
41667
|
if (name === "auth.json" && await import_fs_extra13.default.pathExists(destPath) && !yes) {
|
|
41563
|
-
const { overwrite } = await (0,
|
|
41668
|
+
const { overwrite } = await (0, import_prompts2.default)({ type: "confirm", name: "overwrite", message: ` ${name} already exists \u2014 overwrite? (OAuth tokens will be lost)`, initial: false });
|
|
41564
41669
|
if (!overwrite) {
|
|
41565
41670
|
console.log(t.muted(` skipped ${name}`));
|
|
41566
41671
|
continue;
|
|
41567
41672
|
}
|
|
41568
41673
|
}
|
|
41569
|
-
const raw = await import_fs_extra13.default.readFile(
|
|
41674
|
+
const raw = await import_fs_extra13.default.readFile(import_path13.default.join(piConfigDir, `${name}.template`), "utf8");
|
|
41570
41675
|
await import_fs_extra13.default.writeFile(destPath, fillTemplate(raw, values), "utf8");
|
|
41571
41676
|
console.log(t.success(` ${sym.ok} ${name}`));
|
|
41572
41677
|
}
|
|
41573
|
-
|
|
41574
|
-
|
|
41575
|
-
|
|
41576
|
-
|
|
41577
|
-
console.log(kleur_default.dim(`
|
|
41578
|
-
|
|
41579
|
-
|
|
41580
|
-
|
|
41581
|
-
const r = (0, import_node_child_process4.spawnSync)("pi", ["install", "-l", extPath], { stdio: "pipe", encoding: "utf8" });
|
|
41582
|
-
if (r.status === 0) {
|
|
41583
|
-
console.log(t.success(` ${sym.ok} ${extName} registered`));
|
|
41584
|
-
} else {
|
|
41585
|
-
console.log(kleur_default.yellow(` \u26A0 ${extName} \u2014 registration failed`));
|
|
41586
|
-
}
|
|
41587
|
-
}
|
|
41678
|
+
const managedPackages = await syncManagedPiExtensions({
|
|
41679
|
+
sourceDir: import_path13.default.join(piConfigDir, "extensions"),
|
|
41680
|
+
targetDir: import_path13.default.join(PI_AGENT_DIR2, "extensions"),
|
|
41681
|
+
dryRun: false,
|
|
41682
|
+
log: (message) => console.log(kleur_default.dim(` ${message}`))
|
|
41683
|
+
});
|
|
41684
|
+
if (managedPackages > 0) {
|
|
41685
|
+
console.log(t.success(` ${sym.ok} extensions/ (${managedPackages} packages)`));
|
|
41588
41686
|
}
|
|
41589
41687
|
console.log(t.bold("\n npm Packages\n"));
|
|
41590
41688
|
for (const pkg of schema.packages) {
|
|
@@ -41602,7 +41700,7 @@ function createInstallPiCommand() {
|
|
|
41602
41700
|
}
|
|
41603
41701
|
|
|
41604
41702
|
// src/commands/pi.ts
|
|
41605
|
-
var PI_AGENT_DIR3 = process.env.PI_AGENT_DIR ||
|
|
41703
|
+
var PI_AGENT_DIR3 = process.env.PI_AGENT_DIR || import_path14.default.join((0, import_node_os7.homedir)(), ".pi", "agent");
|
|
41606
41704
|
function createPiCommand() {
|
|
41607
41705
|
const cmd = new Command("pi").description("Launch a Pi session in a sandboxed worktree, or manage the Pi runtime").argument("[name]", "Optional session name \u2014 used as xt/<name> branch (random if omitted)").action(async (name) => {
|
|
41608
41706
|
await launchWorktreeSession({ runtime: "pi", name });
|
|
@@ -41625,8 +41723,8 @@ function createPiCommand() {
|
|
|
41625
41723
|
return;
|
|
41626
41724
|
}
|
|
41627
41725
|
const repoRoot = await findRepoRoot();
|
|
41628
|
-
const sourceDir =
|
|
41629
|
-
const targetDir =
|
|
41726
|
+
const sourceDir = import_path14.default.join(repoRoot, "config", "pi", "extensions");
|
|
41727
|
+
const targetDir = import_path14.default.join(PI_AGENT_DIR3, "extensions");
|
|
41630
41728
|
const diff = await diffPiExtensions(sourceDir, targetDir);
|
|
41631
41729
|
if (diff.missing.length === 0 && diff.stale.length === 0) {
|
|
41632
41730
|
console.log(t.success(` \u2713 extensions up-to-date (${diff.upToDate.length} deployed)`));
|
|
@@ -41648,9 +41746,9 @@ function createPiCommand() {
|
|
|
41648
41746
|
allOk = false;
|
|
41649
41747
|
}
|
|
41650
41748
|
const repoRoot = await findRepoRoot();
|
|
41651
|
-
const piConfigDir =
|
|
41652
|
-
const sourceDir =
|
|
41653
|
-
const targetDir =
|
|
41749
|
+
const piConfigDir = import_path14.default.join(repoRoot, "config", "pi");
|
|
41750
|
+
const sourceDir = import_path14.default.join(piConfigDir, "extensions");
|
|
41751
|
+
const targetDir = import_path14.default.join(PI_AGENT_DIR3, "extensions");
|
|
41654
41752
|
const diff = await diffPiExtensions(sourceDir, targetDir);
|
|
41655
41753
|
if (diff.missing.length === 0 && diff.stale.length === 0) {
|
|
41656
41754
|
console.log(t.success(` \u2713 extensions deployed (${diff.upToDate.length})`));
|
|
@@ -41658,7 +41756,7 @@ function createPiCommand() {
|
|
|
41658
41756
|
console.log(kleur_default.yellow(` \u26A0 extension drift (${diff.missing.length} missing, ${diff.stale.length} stale)`));
|
|
41659
41757
|
allOk = false;
|
|
41660
41758
|
}
|
|
41661
|
-
const schemaPath =
|
|
41759
|
+
const schemaPath = import_path14.default.join(piConfigDir, "install-schema.json");
|
|
41662
41760
|
if (await import_fs_extra14.default.pathExists(schemaPath)) {
|
|
41663
41761
|
try {
|
|
41664
41762
|
(0, import_node_child_process5.execSync)("pi --version", { stdio: "ignore" });
|
|
@@ -41690,49 +41788,45 @@ function createPiCommand() {
|
|
|
41690
41788
|
}
|
|
41691
41789
|
|
|
41692
41790
|
// src/commands/init.ts
|
|
41693
|
-
var
|
|
41791
|
+
var import_path16 = __toESM(require("path"), 1);
|
|
41694
41792
|
var import_fs_extra16 = __toESM(require_lib2(), 1);
|
|
41695
41793
|
var import_child_process4 = require("child_process");
|
|
41696
41794
|
|
|
41697
41795
|
// src/commands/install-service-skills.ts
|
|
41698
|
-
var
|
|
41796
|
+
var import_path15 = __toESM(require("path"), 1);
|
|
41699
41797
|
var import_fs_extra15 = __toESM(require_lib2(), 1);
|
|
41700
41798
|
function resolvePkgRoot() {
|
|
41701
41799
|
const candidates = [
|
|
41702
|
-
|
|
41703
|
-
|
|
41800
|
+
import_path15.default.resolve(__dirname, "../.."),
|
|
41801
|
+
import_path15.default.resolve(__dirname, "../../..")
|
|
41704
41802
|
];
|
|
41705
|
-
const match = candidates.find((candidate) => import_fs_extra15.default.existsSync(
|
|
41803
|
+
const match = candidates.find((candidate) => import_fs_extra15.default.existsSync(import_path15.default.join(candidate, "project-skills")));
|
|
41706
41804
|
if (!match) {
|
|
41707
41805
|
throw new Error("Unable to locate project-skills directory from CLI runtime.");
|
|
41708
41806
|
}
|
|
41709
41807
|
return match;
|
|
41710
41808
|
}
|
|
41711
41809
|
var PKG_ROOT = resolvePkgRoot();
|
|
41712
|
-
var SKILLS_SRC =
|
|
41810
|
+
var SKILLS_SRC = import_path15.default.join(PKG_ROOT, "project-skills", "service-skills-set", ".claude");
|
|
41713
41811
|
|
|
41714
41812
|
// src/commands/init.ts
|
|
41715
41813
|
function resolvePkgRoot2() {
|
|
41716
41814
|
const candidates = [
|
|
41717
|
-
|
|
41718
|
-
|
|
41815
|
+
import_path16.default.resolve(__dirname, "../.."),
|
|
41816
|
+
import_path16.default.resolve(__dirname, "../../..")
|
|
41719
41817
|
];
|
|
41720
|
-
const match = candidates.find((candidate) => import_fs_extra16.default.existsSync(
|
|
41818
|
+
const match = candidates.find((candidate) => import_fs_extra16.default.existsSync(import_path16.default.join(candidate, "project-skills")));
|
|
41721
41819
|
if (!match) {
|
|
41722
41820
|
throw new Error("Unable to locate project-skills directory from CLI runtime.");
|
|
41723
41821
|
}
|
|
41724
41822
|
return match;
|
|
41725
41823
|
}
|
|
41726
41824
|
var PKG_ROOT2 = resolvePkgRoot2();
|
|
41727
|
-
var PROJECT_SKILLS_DIR =
|
|
41728
|
-
var MCP_CORE_CONFIG_PATH =
|
|
41729
|
-
var INSTRUCTIONS_DIR =
|
|
41825
|
+
var PROJECT_SKILLS_DIR = import_path16.default.join(PKG_ROOT2, "project-skills");
|
|
41826
|
+
var MCP_CORE_CONFIG_PATH = import_path16.default.join(PKG_ROOT2, "config", "mcp_servers.json");
|
|
41827
|
+
var INSTRUCTIONS_DIR = import_path16.default.join(PKG_ROOT2, "config", "instructions");
|
|
41730
41828
|
var XTRM_BLOCK_START = "<!-- xtrm:start -->";
|
|
41731
41829
|
var XTRM_BLOCK_END = "<!-- xtrm:end -->";
|
|
41732
|
-
var syncedProjectMcpRoots = /* @__PURE__ */ new Set();
|
|
41733
|
-
function toServiceId(name) {
|
|
41734
|
-
return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "service";
|
|
41735
|
-
}
|
|
41736
41830
|
function parseComposeServices(content) {
|
|
41737
41831
|
const lines = content.split("\n");
|
|
41738
41832
|
const services = /* @__PURE__ */ new Set();
|
|
@@ -41756,8 +41850,8 @@ function parseComposeServices(content) {
|
|
|
41756
41850
|
return [...services];
|
|
41757
41851
|
}
|
|
41758
41852
|
async function detectProjectFeatures(projectRoot) {
|
|
41759
|
-
const hasTypeScript = await import_fs_extra16.default.pathExists(
|
|
41760
|
-
const hasPython = await import_fs_extra16.default.pathExists(
|
|
41853
|
+
const hasTypeScript = await import_fs_extra16.default.pathExists(import_path16.default.join(projectRoot, "tsconfig.json"));
|
|
41854
|
+
const hasPython = await import_fs_extra16.default.pathExists(import_path16.default.join(projectRoot, "pyproject.toml")) || await import_fs_extra16.default.pathExists(import_path16.default.join(projectRoot, "setup.py")) || await import_fs_extra16.default.pathExists(import_path16.default.join(projectRoot, "requirements.txt"));
|
|
41761
41855
|
const composeCandidates = [
|
|
41762
41856
|
"docker-compose.yml",
|
|
41763
41857
|
"docker-compose.yaml",
|
|
@@ -41766,7 +41860,7 @@ async function detectProjectFeatures(projectRoot) {
|
|
|
41766
41860
|
];
|
|
41767
41861
|
const dockerServices = /* @__PURE__ */ new Set();
|
|
41768
41862
|
for (const composeFile of composeCandidates) {
|
|
41769
|
-
const composePath =
|
|
41863
|
+
const composePath = import_path16.default.join(projectRoot, composeFile);
|
|
41770
41864
|
if (!await import_fs_extra16.default.pathExists(composePath)) continue;
|
|
41771
41865
|
try {
|
|
41772
41866
|
const content = await import_fs_extra16.default.readFile(composePath, "utf8");
|
|
@@ -41776,9 +41870,9 @@ async function detectProjectFeatures(projectRoot) {
|
|
|
41776
41870
|
} catch {
|
|
41777
41871
|
}
|
|
41778
41872
|
}
|
|
41779
|
-
const hasDockerfile = await import_fs_extra16.default.pathExists(
|
|
41873
|
+
const hasDockerfile = await import_fs_extra16.default.pathExists(import_path16.default.join(projectRoot, "Dockerfile"));
|
|
41780
41874
|
if (hasDockerfile && dockerServices.size === 0) {
|
|
41781
|
-
dockerServices.add(
|
|
41875
|
+
dockerServices.add(import_path16.default.basename(projectRoot));
|
|
41782
41876
|
}
|
|
41783
41877
|
return {
|
|
41784
41878
|
hasTypeScript,
|
|
@@ -41787,116 +41881,6 @@ async function detectProjectFeatures(projectRoot) {
|
|
|
41787
41881
|
generatedRegistry: false
|
|
41788
41882
|
};
|
|
41789
41883
|
}
|
|
41790
|
-
async function ensureServiceRegistry(projectRoot, services) {
|
|
41791
|
-
const registryPath = import_path15.default.join(projectRoot, "service-registry.json");
|
|
41792
|
-
if (services.length === 0) {
|
|
41793
|
-
return { generated: false, registryPath };
|
|
41794
|
-
}
|
|
41795
|
-
const existedBefore = await import_fs_extra16.default.pathExists(registryPath);
|
|
41796
|
-
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
41797
|
-
let registry2 = { version: "1.0.0", services: {} };
|
|
41798
|
-
if (existedBefore) {
|
|
41799
|
-
try {
|
|
41800
|
-
registry2 = await import_fs_extra16.default.readJson(registryPath);
|
|
41801
|
-
if (!registry2.services || typeof registry2.services !== "object") {
|
|
41802
|
-
registry2.services = {};
|
|
41803
|
-
}
|
|
41804
|
-
} catch {
|
|
41805
|
-
registry2 = { version: "1.0.0", services: {} };
|
|
41806
|
-
}
|
|
41807
|
-
}
|
|
41808
|
-
let changed = false;
|
|
41809
|
-
for (const serviceName of services) {
|
|
41810
|
-
const serviceId = toServiceId(serviceName);
|
|
41811
|
-
if (registry2.services[serviceId]) continue;
|
|
41812
|
-
registry2.services[serviceId] = {
|
|
41813
|
-
name: serviceName,
|
|
41814
|
-
description: `Detected from Docker configuration (${serviceName}).`,
|
|
41815
|
-
territory: [],
|
|
41816
|
-
skill_path: `.claude/skills/${serviceId}/SKILL.md`,
|
|
41817
|
-
last_sync: now
|
|
41818
|
-
};
|
|
41819
|
-
changed = true;
|
|
41820
|
-
}
|
|
41821
|
-
if (changed || !existedBefore) {
|
|
41822
|
-
await import_fs_extra16.default.writeJson(registryPath, registry2, { spaces: 2 });
|
|
41823
|
-
}
|
|
41824
|
-
return { generated: changed || !existedBefore, registryPath };
|
|
41825
|
-
}
|
|
41826
|
-
function resolveEnvVars(value) {
|
|
41827
|
-
if (typeof value !== "string") return value;
|
|
41828
|
-
return value.replace(/\$\{([A-Z0-9_]+)\}/g, (_m, name) => process.env[name] || "");
|
|
41829
|
-
}
|
|
41830
|
-
function hasClaudeCli() {
|
|
41831
|
-
const r = (0, import_child_process4.spawnSync)("claude", ["--version"], { stdio: "pipe" });
|
|
41832
|
-
return r.status === 0;
|
|
41833
|
-
}
|
|
41834
|
-
function buildProjectMcpArgs(name, server) {
|
|
41835
|
-
const transport = server.type || (server.url?.includes("/sse") ? "sse" : "http");
|
|
41836
|
-
if (server.command) {
|
|
41837
|
-
const args = ["mcp", "add", "-s", "project"];
|
|
41838
|
-
if (server.env && typeof server.env === "object") {
|
|
41839
|
-
for (const [k, v] of Object.entries(server.env)) {
|
|
41840
|
-
args.push("-e", `${k}=${resolveEnvVars(String(v))}`);
|
|
41841
|
-
}
|
|
41842
|
-
}
|
|
41843
|
-
args.push(name, "--", server.command, ...server.args || []);
|
|
41844
|
-
return args;
|
|
41845
|
-
}
|
|
41846
|
-
if (server.url || server.serverUrl) {
|
|
41847
|
-
const url2 = server.url || server.serverUrl;
|
|
41848
|
-
const args = ["mcp", "add", "-s", "project", "--transport", transport, name, url2];
|
|
41849
|
-
if (server.headers && typeof server.headers === "object") {
|
|
41850
|
-
for (const [k, v] of Object.entries(server.headers)) {
|
|
41851
|
-
args.push("--header", `${k}: ${resolveEnvVars(String(v))}`);
|
|
41852
|
-
}
|
|
41853
|
-
}
|
|
41854
|
-
return args;
|
|
41855
|
-
}
|
|
41856
|
-
return null;
|
|
41857
|
-
}
|
|
41858
|
-
async function syncProjectMcpServers(projectRoot) {
|
|
41859
|
-
if (syncedProjectMcpRoots.has(projectRoot)) return;
|
|
41860
|
-
syncedProjectMcpRoots.add(projectRoot);
|
|
41861
|
-
if (!await import_fs_extra16.default.pathExists(MCP_CORE_CONFIG_PATH)) return;
|
|
41862
|
-
console.log(kleur_default.bold("\n\u2500\u2500 Installing MCP (project scope) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
41863
|
-
if (!hasClaudeCli()) {
|
|
41864
|
-
console.log(kleur_default.yellow(" \u26A0 Claude CLI not found; skipping project-scope MCP registration."));
|
|
41865
|
-
return;
|
|
41866
|
-
}
|
|
41867
|
-
const mcpConfig = await import_fs_extra16.default.readJson(MCP_CORE_CONFIG_PATH);
|
|
41868
|
-
const servers = Object.entries(mcpConfig?.mcpServers ?? {});
|
|
41869
|
-
if (servers.length === 0) {
|
|
41870
|
-
console.log(kleur_default.dim(" \u2139 No core MCP servers configured."));
|
|
41871
|
-
return;
|
|
41872
|
-
}
|
|
41873
|
-
let added = 0;
|
|
41874
|
-
let existing = 0;
|
|
41875
|
-
let failed = 0;
|
|
41876
|
-
for (const [name, server] of servers) {
|
|
41877
|
-
const args = buildProjectMcpArgs(name, server);
|
|
41878
|
-
if (!args) continue;
|
|
41879
|
-
const r = (0, import_child_process4.spawnSync)("claude", args, {
|
|
41880
|
-
cwd: projectRoot,
|
|
41881
|
-
encoding: "utf8",
|
|
41882
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
41883
|
-
});
|
|
41884
|
-
if (r.status === 0) {
|
|
41885
|
-
added++;
|
|
41886
|
-
console.log(`${kleur_default.green(" \u2713")} ${name}`);
|
|
41887
|
-
continue;
|
|
41888
|
-
}
|
|
41889
|
-
const stderr = `${r.stderr || ""}`.toLowerCase();
|
|
41890
|
-
if (stderr.includes("already exists") || stderr.includes("already configured")) {
|
|
41891
|
-
existing++;
|
|
41892
|
-
console.log(kleur_default.dim(` \u2713 ${name} (already configured)`));
|
|
41893
|
-
continue;
|
|
41894
|
-
}
|
|
41895
|
-
failed++;
|
|
41896
|
-
console.log(kleur_default.red(` \u2717 ${name} (${(r.stderr || r.stdout || "failed").toString().trim()})`));
|
|
41897
|
-
}
|
|
41898
|
-
console.log(kleur_default.dim(` \u21B3 MCP project-scope result: ${added} added, ${existing} existing, ${failed} failed`));
|
|
41899
|
-
}
|
|
41900
41884
|
function upsertManagedBlock(fileContent, blockBody, startMarker = XTRM_BLOCK_START, endMarker = XTRM_BLOCK_END) {
|
|
41901
41885
|
const normalizedBody = blockBody.trim();
|
|
41902
41886
|
const managedBlock = `${startMarker}
|
|
@@ -41922,13 +41906,13 @@ async function injectProjectInstructionHeaders(projectRoot) {
|
|
|
41922
41906
|
];
|
|
41923
41907
|
console.log(kleur_default.bold("Injecting xtrm agent instruction headers..."));
|
|
41924
41908
|
for (const target of targets) {
|
|
41925
|
-
const templatePath =
|
|
41909
|
+
const templatePath = import_path16.default.join(INSTRUCTIONS_DIR, target.template);
|
|
41926
41910
|
if (!await import_fs_extra16.default.pathExists(templatePath)) {
|
|
41927
41911
|
console.log(kleur_default.yellow(` \u26A0 Missing template: ${target.template}`));
|
|
41928
41912
|
continue;
|
|
41929
41913
|
}
|
|
41930
41914
|
const template = await import_fs_extra16.default.readFile(templatePath, "utf8");
|
|
41931
|
-
const outputPath =
|
|
41915
|
+
const outputPath = import_path16.default.join(projectRoot, target.output);
|
|
41932
41916
|
const existing = await import_fs_extra16.default.pathExists(outputPath) ? await import_fs_extra16.default.readFile(outputPath, "utf8") : "";
|
|
41933
41917
|
const next = upsertManagedBlock(existing, template);
|
|
41934
41918
|
if (next === existing) {
|
|
@@ -41948,15 +41932,14 @@ function buildProjectInitGuide() {
|
|
|
41948
41932
|
kleur_default.dim(" xtrm init (alias: xtrm project init)"),
|
|
41949
41933
|
kleur_default.dim(" - Initializes beads workspace (bd init)"),
|
|
41950
41934
|
kleur_default.dim(" - Refreshes GitNexus index if missing/stale"),
|
|
41951
|
-
kleur_default.dim(" -
|
|
41952
|
-
kleur_default.dim(" - Detects
|
|
41953
|
-
kleur_default.dim(" - Scaffolds service-registry.json when Docker services are detected"),
|
|
41935
|
+
kleur_default.dim(" - Injects XTRM workflow headers into AGENTS.md + CLAUDE.md"),
|
|
41936
|
+
kleur_default.dim(" - Detects TypeScript/Python project signals"),
|
|
41954
41937
|
"",
|
|
41955
41938
|
`${kleur_default.cyan("2) What is already global (no per-project install needed):")}`,
|
|
41956
|
-
kleur_default.dim(" - quality gates hooks (
|
|
41957
|
-
kleur_default.dim(" -
|
|
41958
|
-
kleur_default.dim(" -
|
|
41959
|
-
kleur_default.dim(" -
|
|
41939
|
+
kleur_default.dim(" - quality gates hooks (ESLint/tsc/ruff/mypy on every edit)"),
|
|
41940
|
+
kleur_default.dim(" - beads workflow gates (edit/commit/stop/memory enforcement)"),
|
|
41941
|
+
kleur_default.dim(" - session-flow gates (claim sync, stop gate, xt end reminder)"),
|
|
41942
|
+
kleur_default.dim(" - service-skills routing and drift checks"),
|
|
41960
41943
|
"",
|
|
41961
41944
|
`${kleur_default.cyan("3) Configure repo quality tools (hooks enforce what exists):")}`,
|
|
41962
41945
|
kleur_default.dim(" - TS: eslint + prettier + tsc"),
|
|
@@ -41968,12 +41951,9 @@ function buildProjectInitGuide() {
|
|
|
41968
41951
|
kleur_default.dim(" - During work: keep issue status current; create discovered follow-ups"),
|
|
41969
41952
|
kleur_default.dim(' - Finish work: bd close <id> --reason "Done" --json'),
|
|
41970
41953
|
"",
|
|
41971
|
-
`${kleur_default.cyan("5) Git workflow
|
|
41972
|
-
kleur_default.dim(
|
|
41973
|
-
kleur_default.dim(" -
|
|
41974
|
-
kleur_default.dim(" - git push -u origin feature/<name>"),
|
|
41975
|
-
kleur_default.dim(" - gh pr create --fill && gh pr merge --squash"),
|
|
41976
|
-
kleur_default.dim(" - git checkout main && git pull --ff-only"),
|
|
41954
|
+
`${kleur_default.cyan("5) Git workflow:")}`,
|
|
41955
|
+
kleur_default.dim(' - bd close <id> --reason "..." \u2190 closes issue + auto-commits'),
|
|
41956
|
+
kleur_default.dim(" - xt end \u2190 push, PR, merge, worktree cleanup"),
|
|
41977
41957
|
""
|
|
41978
41958
|
];
|
|
41979
41959
|
return lines.join("\n");
|
|
@@ -41996,28 +41976,12 @@ async function bootstrapProjectInit() {
|
|
|
41996
41976
|
await runBdInitForProject(projectRoot);
|
|
41997
41977
|
await injectProjectInstructionHeaders(projectRoot);
|
|
41998
41978
|
await runGitNexusInitForProject(projectRoot);
|
|
41999
|
-
await syncProjectMcpServers(projectRoot);
|
|
42000
|
-
if (detected.dockerServices.length > 0) {
|
|
42001
|
-
const { generated, registryPath } = await ensureServiceRegistry(projectRoot, detected.dockerServices);
|
|
42002
|
-
detected.generatedRegistry = generated;
|
|
42003
|
-
detected.registryPath = registryPath;
|
|
42004
|
-
if (generated) {
|
|
42005
|
-
console.log(`${kleur_default.green(" \u2713")} service registry scaffolded at ${import_path15.default.relative(projectRoot, registryPath)}`);
|
|
42006
|
-
} else {
|
|
42007
|
-
console.log(kleur_default.dim(" \u2713 service-registry.json already includes detected services"));
|
|
42008
|
-
}
|
|
42009
|
-
}
|
|
42010
41979
|
const projectTypes = [];
|
|
42011
41980
|
if (detected.hasTypeScript) projectTypes.push("TypeScript");
|
|
42012
41981
|
if (detected.hasPython) projectTypes.push("Python");
|
|
42013
|
-
if (detected.dockerServices.length > 0) projectTypes.push("Docker");
|
|
42014
41982
|
console.log(kleur_default.bold("\nProject initialized."));
|
|
42015
41983
|
console.log(kleur_default.white(` Quality gates active globally.`));
|
|
42016
41984
|
console.log(kleur_default.white(` Project types: ${projectTypes.length > 0 ? projectTypes.join(", ") : "none detected"}.`));
|
|
42017
|
-
console.log(kleur_default.white(` Services detected: ${detected.dockerServices.length > 0 ? detected.dockerServices.join(", ") : "none"}.`));
|
|
42018
|
-
if (detected.registryPath) {
|
|
42019
|
-
console.log(kleur_default.dim(` Service registry: ${detected.registryPath}`));
|
|
42020
|
-
}
|
|
42021
41985
|
console.log("");
|
|
42022
41986
|
}
|
|
42023
41987
|
async function runBdInitForProject(projectRoot) {
|
|
@@ -42092,14 +42056,14 @@ function getProjectRoot() {
|
|
|
42092
42056
|
if (result.status !== 0) {
|
|
42093
42057
|
throw new Error("Not inside a git repository. Run this command from your target project directory.");
|
|
42094
42058
|
}
|
|
42095
|
-
return
|
|
42059
|
+
return import_path16.default.resolve(result.stdout.trim());
|
|
42096
42060
|
}
|
|
42097
42061
|
|
|
42098
42062
|
// src/commands/status.ts
|
|
42099
|
-
var
|
|
42063
|
+
var import_prompts3 = __toESM(require_prompts3(), 1);
|
|
42100
42064
|
|
|
42101
42065
|
// src/core/manifest.ts
|
|
42102
|
-
var
|
|
42066
|
+
var import_path17 = require("path");
|
|
42103
42067
|
|
|
42104
42068
|
// ../node_modules/zod/v4/classic/external.js
|
|
42105
42069
|
var external_exports = {};
|
|
@@ -42948,8 +42912,8 @@ function numKeys(data) {
|
|
|
42948
42912
|
return keyCount;
|
|
42949
42913
|
}
|
|
42950
42914
|
var getParsedType = (data) => {
|
|
42951
|
-
const
|
|
42952
|
-
switch (
|
|
42915
|
+
const t3 = typeof data;
|
|
42916
|
+
switch (t3) {
|
|
42953
42917
|
case "undefined":
|
|
42954
42918
|
return "undefined";
|
|
42955
42919
|
case "string":
|
|
@@ -42988,7 +42952,7 @@ var getParsedType = (data) => {
|
|
|
42988
42952
|
}
|
|
42989
42953
|
return "object";
|
|
42990
42954
|
default:
|
|
42991
|
-
throw new Error(`Unknown data type: ${
|
|
42955
|
+
throw new Error(`Unknown data type: ${t3}`);
|
|
42992
42956
|
}
|
|
42993
42957
|
};
|
|
42994
42958
|
var propertyKeyTypes = /* @__PURE__ */ new Set(["string", "number", "symbol"]);
|
|
@@ -43295,8 +43259,8 @@ function getLengthableOrigin(input) {
|
|
|
43295
43259
|
return "unknown";
|
|
43296
43260
|
}
|
|
43297
43261
|
function parsedType(data) {
|
|
43298
|
-
const
|
|
43299
|
-
switch (
|
|
43262
|
+
const t3 = typeof data;
|
|
43263
|
+
switch (t3) {
|
|
43300
43264
|
case "number": {
|
|
43301
43265
|
return Number.isNaN(data) ? "nan" : "number";
|
|
43302
43266
|
}
|
|
@@ -43313,7 +43277,7 @@ function parsedType(data) {
|
|
|
43313
43277
|
}
|
|
43314
43278
|
}
|
|
43315
43279
|
}
|
|
43316
|
-
return
|
|
43280
|
+
return t3;
|
|
43317
43281
|
}
|
|
43318
43282
|
function issue(...args) {
|
|
43319
43283
|
const [iss, input, inst] = args;
|
|
@@ -45023,12 +44987,12 @@ function handleCatchall(proms, input, payload, ctx, def, inst) {
|
|
|
45023
44987
|
const unrecognized = [];
|
|
45024
44988
|
const keySet = def.keySet;
|
|
45025
44989
|
const _catchall = def.catchall._zod;
|
|
45026
|
-
const
|
|
44990
|
+
const t3 = _catchall.def.type;
|
|
45027
44991
|
const isOptionalOut = _catchall.optout === "optional";
|
|
45028
44992
|
for (const key in input) {
|
|
45029
44993
|
if (keySet.has(key))
|
|
45030
44994
|
continue;
|
|
45031
|
-
if (
|
|
44995
|
+
if (t3 === "never") {
|
|
45032
44996
|
unrecognized.push(key);
|
|
45033
44997
|
continue;
|
|
45034
44998
|
}
|
|
@@ -48135,16 +48099,16 @@ var error17 = () => {
|
|
|
48135
48099
|
number: { unit: "", shortLabel: "\u05E7\u05D8\u05DF", longLabel: "\u05D2\u05D3\u05D5\u05DC" }
|
|
48136
48100
|
// no unit
|
|
48137
48101
|
};
|
|
48138
|
-
const typeEntry = (
|
|
48139
|
-
const typeLabel = (
|
|
48140
|
-
const e = typeEntry(
|
|
48102
|
+
const typeEntry = (t3) => t3 ? TypeNames[t3] : void 0;
|
|
48103
|
+
const typeLabel = (t3) => {
|
|
48104
|
+
const e = typeEntry(t3);
|
|
48141
48105
|
if (e)
|
|
48142
48106
|
return e.label;
|
|
48143
|
-
return
|
|
48107
|
+
return t3 ?? TypeNames.unknown.label;
|
|
48144
48108
|
};
|
|
48145
|
-
const withDefinite = (
|
|
48146
|
-
const verbFor = (
|
|
48147
|
-
const e = typeEntry(
|
|
48109
|
+
const withDefinite = (t3) => `\u05D4${typeLabel(t3)}`;
|
|
48110
|
+
const verbFor = (t3) => {
|
|
48111
|
+
const e = typeEntry(t3);
|
|
48148
48112
|
const gender = e?.gender ?? "m";
|
|
48149
48113
|
return gender === "f" ? "\u05E6\u05E8\u05D9\u05DB\u05D4 \u05DC\u05D4\u05D9\u05D5\u05EA" : "\u05E6\u05E8\u05D9\u05DA \u05DC\u05D4\u05D9\u05D5\u05EA";
|
|
48150
48114
|
};
|
|
@@ -55539,8 +55503,8 @@ function convertBaseSchema(schema, ctx) {
|
|
|
55539
55503
|
}
|
|
55540
55504
|
const type = schema.type;
|
|
55541
55505
|
if (Array.isArray(type)) {
|
|
55542
|
-
const typeSchemas = type.map((
|
|
55543
|
-
const typeSchema = { ...schema, type:
|
|
55506
|
+
const typeSchemas = type.map((t3) => {
|
|
55507
|
+
const typeSchema = { ...schema, type: t3 };
|
|
55544
55508
|
return convertBaseSchema(typeSchema, ctx);
|
|
55545
55509
|
});
|
|
55546
55510
|
if (typeSchemas.length === 0) {
|
|
@@ -55886,9 +55850,7 @@ var ChangeSetSchema = external_exports.object({
|
|
|
55886
55850
|
skills: ChangeSetCategorySchema,
|
|
55887
55851
|
hooks: ChangeSetCategorySchema,
|
|
55888
55852
|
config: ChangeSetCategorySchema,
|
|
55889
|
-
commands: ChangeSetCategorySchema
|
|
55890
|
-
"qwen-commands": ChangeSetCategorySchema,
|
|
55891
|
-
"antigravity-workflows": ChangeSetCategorySchema
|
|
55853
|
+
commands: ChangeSetCategorySchema
|
|
55892
55854
|
});
|
|
55893
55855
|
var SyncPlanSchema = external_exports.object({
|
|
55894
55856
|
mode: SyncModeSchema,
|
|
@@ -55910,17 +55872,17 @@ var ManifestSchema = external_exports.object({
|
|
|
55910
55872
|
// src/core/manifest.ts
|
|
55911
55873
|
var MANIFEST_FILE = ".jaggers-sync-manifest.json";
|
|
55912
55874
|
function getManifestPath(projectDir) {
|
|
55913
|
-
return (0,
|
|
55875
|
+
return (0, import_path17.join)(projectDir, MANIFEST_FILE);
|
|
55914
55876
|
}
|
|
55915
55877
|
|
|
55916
55878
|
// src/commands/status.ts
|
|
55917
55879
|
var import_fs_extra17 = __toESM(require_lib2(), 1);
|
|
55918
|
-
var
|
|
55880
|
+
var import_path18 = __toESM(require("path"), 1);
|
|
55919
55881
|
function formatTargetLabel2(target) {
|
|
55920
55882
|
const normalized = target.replace(/\\/g, "/").toLowerCase();
|
|
55921
55883
|
if (normalized.endsWith("/.agents/skills") || normalized.includes("/.agents/skills/")) return "~/.agents/skills";
|
|
55922
55884
|
if (normalized.endsWith("/.claude") || normalized.includes("/.claude/")) return "~/.claude";
|
|
55923
|
-
return
|
|
55885
|
+
return import_path18.default.basename(target);
|
|
55924
55886
|
}
|
|
55925
55887
|
function formatRelativeTime(timestamp) {
|
|
55926
55888
|
const now = Date.now();
|
|
@@ -56002,7 +55964,7 @@ function createStatusCommand() {
|
|
|
56002
55964
|
console.log(kleur_default.yellow(`
|
|
56003
55965
|
\u26A0 ${totalPending} pending change${totalPending !== 1 ? "s" : ""} across ${pending.length} environment${pending.length !== 1 ? "s" : ""}
|
|
56004
55966
|
`));
|
|
56005
|
-
const { selected } = await (0,
|
|
55967
|
+
const { selected } = await (0, import_prompts3.default)({
|
|
56006
55968
|
type: "multiselect",
|
|
56007
55969
|
name: "selected",
|
|
56008
55970
|
message: "Select environments to sync:",
|
|
@@ -56044,176 +56006,100 @@ function createResetCommand() {
|
|
|
56044
56006
|
}
|
|
56045
56007
|
|
|
56046
56008
|
// src/commands/help.ts
|
|
56047
|
-
|
|
56048
|
-
|
|
56049
|
-
var HOOK_CATALOG = [
|
|
56050
|
-
{ file: "main-guard.mjs", event: "PreToolUse", desc: "Blocks direct edits / unsafe Bash on protected branches" },
|
|
56051
|
-
{ file: "main-guard-post-push.mjs", event: "PostToolUse", desc: "After feature-branch push, reminds PR/merge/sync steps" },
|
|
56052
|
-
{ file: "serena-workflow-reminder.py", event: "SessionStart", desc: "Injects Serena semantic editing workflow reminder" },
|
|
56053
|
-
{ file: "gitnexus/gitnexus-hook.cjs", event: "PostToolUse", desc: "Adds GitNexus context for search and Serena tooling" },
|
|
56054
|
-
{ file: "agent_context.py", event: "Support module", desc: "Shared hook I/O helper used by Python hook scripts" },
|
|
56055
|
-
{ file: "beads-edit-gate.mjs", event: "PreToolUse", desc: "Blocks file edits if no beads issue is claimed", beads: true },
|
|
56056
|
-
{ file: "beads-commit-gate.mjs", event: "PreToolUse", desc: "Blocks commits when no beads issue is in progress", beads: true },
|
|
56057
|
-
{ file: "beads-memory-gate.mjs", event: "Stop", desc: "Prompts memory save when claim was closed", beads: true },
|
|
56058
|
-
{ file: "beads-compact-save.mjs", event: "PreCompact", desc: "Saves in_progress issue + session-state bundle", beads: true },
|
|
56059
|
-
{ file: "beads-compact-restore.mjs", event: "SessionStart", desc: "Restores compacted issue + session-state bundle", beads: true },
|
|
56060
|
-
{ file: "beads-claim-sync.mjs", event: "PostToolUse", desc: "Auto-claim sync + worktree/session-state bootstrap", sessionFlow: true },
|
|
56061
|
-
{ file: "beads-stop-gate.mjs", event: "Stop", desc: "Blocks stop for waiting-merge/conflicting/pending-cleanup", sessionFlow: true },
|
|
56062
|
-
{ file: "branch-state.mjs", event: "UserPromptSubmit", desc: "Injects current git branch into prompt context" },
|
|
56063
|
-
{ file: "quality-check.cjs", event: "PostToolUse", desc: "Runs JS/TS quality checks on mutating edits" },
|
|
56064
|
-
{ file: "quality-check.py", event: "PostToolUse", desc: "Runs Python quality checks on mutating edits" }
|
|
56065
|
-
];
|
|
56066
|
-
async function readSkillsFromDir(dir) {
|
|
56067
|
-
if (!await import_fs_extra18.default.pathExists(dir)) return [];
|
|
56068
|
-
const entries = await import_fs_extra18.default.readdir(dir);
|
|
56069
|
-
const skills = [];
|
|
56070
|
-
for (const name of entries.sort()) {
|
|
56071
|
-
const skillMd = import_path18.default.join(dir, name, "SKILL.md");
|
|
56072
|
-
if (!await import_fs_extra18.default.pathExists(skillMd)) continue;
|
|
56073
|
-
const content = await import_fs_extra18.default.readFile(skillMd, "utf8");
|
|
56074
|
-
const m = content.match(/^description:\s*(.+)$/m);
|
|
56075
|
-
skills.push({ name, desc: m ? m[1].replace(/^["']|["']$/g, "").trim() : "" });
|
|
56076
|
-
}
|
|
56077
|
-
return skills;
|
|
56078
|
-
}
|
|
56079
|
-
async function readProjectSkillsFromDir(dir) {
|
|
56080
|
-
if (!await import_fs_extra18.default.pathExists(dir)) return [];
|
|
56081
|
-
const entries = await import_fs_extra18.default.readdir(dir);
|
|
56082
|
-
const skills = [];
|
|
56083
|
-
for (const name of entries.sort()) {
|
|
56084
|
-
const readme = import_path18.default.join(dir, name, "README.md");
|
|
56085
|
-
if (!await import_fs_extra18.default.pathExists(readme)) continue;
|
|
56086
|
-
const content = await import_fs_extra18.default.readFile(readme, "utf8");
|
|
56087
|
-
const descLine = content.split("\n").find((line) => {
|
|
56088
|
-
const trimmed = line.trim();
|
|
56089
|
-
return Boolean(trimmed) && !trimmed.startsWith("#") && !trimmed.startsWith("[") && !trimmed.startsWith("<");
|
|
56090
|
-
}) || "";
|
|
56091
|
-
skills.push({ name, desc: descLine.replace(/[*_`]/g, "").trim() });
|
|
56092
|
-
}
|
|
56093
|
-
return skills;
|
|
56094
|
-
}
|
|
56095
|
-
function resolvePkgRootFallback() {
|
|
56096
|
-
const candidates = [
|
|
56097
|
-
import_path18.default.resolve(__dirname, "../.."),
|
|
56098
|
-
import_path18.default.resolve(__dirname, "../../..")
|
|
56099
|
-
];
|
|
56100
|
-
const match = candidates.find(
|
|
56101
|
-
(candidate) => import_fs_extra18.default.existsSync(import_path18.default.join(candidate, "skills")) || import_fs_extra18.default.existsSync(import_path18.default.join(candidate, "project-skills"))
|
|
56102
|
-
);
|
|
56103
|
-
return match || null;
|
|
56104
|
-
}
|
|
56105
|
-
function col(s, width) {
|
|
56106
|
-
return s.length >= width ? s.slice(0, width - 1) + "\u2026" : s.padEnd(width);
|
|
56009
|
+
function section(title, lines) {
|
|
56010
|
+
return [title, ...lines, ""].join("\n");
|
|
56107
56011
|
}
|
|
56108
56012
|
function createHelpCommand() {
|
|
56109
|
-
return new Command("help").description("Show help
|
|
56110
|
-
|
|
56111
|
-
|
|
56112
|
-
|
|
56113
|
-
|
|
56114
|
-
|
|
56115
|
-
|
|
56116
|
-
|
|
56117
|
-
|
|
56118
|
-
|
|
56119
|
-
|
|
56120
|
-
|
|
56121
|
-
|
|
56122
|
-
|
|
56123
|
-
|
|
56124
|
-
|
|
56125
|
-
|
|
56126
|
-
|
|
56127
|
-
|
|
56128
|
-
|
|
56129
|
-
|
|
56130
|
-
|
|
56131
|
-
|
|
56013
|
+
return new Command("help").description("Show rich CLI help in a plain text format").action(async () => {
|
|
56014
|
+
const blocks = [];
|
|
56015
|
+
blocks.push(section("XTRM CLI", [
|
|
56016
|
+
" xtrm and xt are equivalent commands.",
|
|
56017
|
+
" Use xt for short workflow commands (xt claude, xt pi, xt end)."
|
|
56018
|
+
]));
|
|
56019
|
+
blocks.push(section("USAGE", [
|
|
56020
|
+
" xtrm <command> [subcommand] [options]",
|
|
56021
|
+
" xt <command> [subcommand] [options]"
|
|
56022
|
+
]));
|
|
56023
|
+
blocks.push(section("CORE WORKFLOW", [
|
|
56024
|
+
" 1) Start a runtime session in a worktree:",
|
|
56025
|
+
" xt claude [name] or xt pi [name]",
|
|
56026
|
+
" 2) Do your work in that worktree/branch.",
|
|
56027
|
+
" 3) Finish with:",
|
|
56028
|
+
" xt end",
|
|
56029
|
+
" 4) Manage old worktrees when needed:",
|
|
56030
|
+
" xt worktree list | xt worktree clean"
|
|
56031
|
+
]));
|
|
56032
|
+
blocks.push(section("PRIMARY COMMANDS", [
|
|
56033
|
+
" xtrm install [target-selector] [options]",
|
|
56034
|
+
" Install/sync tools, hooks, skills, and MCP wiring.",
|
|
56035
|
+
" Options: --dry-run, --yes/-y, --prune, --backport",
|
|
56132
56036
|
"",
|
|
56133
|
-
|
|
56134
|
-
|
|
56135
|
-
` ${kleur_default.dim("No beads dependency -- safe to run with zero external deps.")}`,
|
|
56037
|
+
" xtrm status [--json]",
|
|
56038
|
+
" Show pending changes for detected environments.",
|
|
56136
56039
|
"",
|
|
56137
|
-
|
|
56138
|
-
|
|
56139
|
-
|
|
56040
|
+
" xtrm clean [options]",
|
|
56041
|
+
" Remove orphaned hooks/skills and stale hook wiring entries.",
|
|
56042
|
+
" Options: --dry-run, --hooks-only, --skills-only, --yes/-y",
|
|
56140
56043
|
"",
|
|
56141
|
-
|
|
56142
|
-
|
|
56143
|
-
` ${kleur_default.dim("~/.claude/skills (global Claude skills)")}`,
|
|
56144
|
-
` ${kleur_default.dim("~/.agents/skills (agents skills cache mirror)")}`,
|
|
56044
|
+
" xtrm init",
|
|
56045
|
+
" Initialize project-level workflow setup.",
|
|
56145
56046
|
"",
|
|
56146
|
-
|
|
56147
|
-
|
|
56148
|
-
const general = HOOK_CATALOG.filter((h) => !h.beads && !h.sessionFlow);
|
|
56149
|
-
const beads = HOOK_CATALOG.filter((h) => h.beads);
|
|
56150
|
-
const sessionFlow = HOOK_CATALOG.filter((h) => h.sessionFlow);
|
|
56151
|
-
const hookRows = (hooks) => hooks.map(
|
|
56152
|
-
(h) => ` ${kleur_default.white(col(h.file, 34))}${kleur_default.yellow(col(h.event, 20))}${kleur_default.dim(h.desc)}`
|
|
56153
|
-
).join("\n");
|
|
56154
|
-
const hooksSection = [
|
|
56155
|
-
section("GLOBAL HOOKS"),
|
|
56047
|
+
" xtrm docs show [filter] [--raw] [--json]",
|
|
56048
|
+
" Show frontmatter for README/CHANGELOG/docs/*.md.",
|
|
56156
56049
|
"",
|
|
56157
|
-
|
|
56050
|
+
" xtrm debug [options]",
|
|
56051
|
+
" Stream xtrm event log (tool calls, gates, session/bd lifecycle).",
|
|
56052
|
+
" Options: --follow, --all, --session <id>, --type <domain>, --json",
|
|
56158
56053
|
"",
|
|
56159
|
-
|
|
56054
|
+
" xtrm reset",
|
|
56055
|
+
" Clear saved CLI preferences.",
|
|
56160
56056
|
"",
|
|
56161
|
-
|
|
56162
|
-
|
|
56057
|
+
" xtrm help",
|
|
56058
|
+
" Show this help page."
|
|
56059
|
+
]));
|
|
56060
|
+
blocks.push(section("RUNTIME COMMANDS", [
|
|
56061
|
+
" xt claude [name]",
|
|
56062
|
+
" Launch Claude in a sandboxed xt/<name> worktree.",
|
|
56063
|
+
" xt claude install [--dry-run]",
|
|
56064
|
+
" Install/refresh xtrm Claude plugin + official plugins.",
|
|
56065
|
+
" xt claude status | xt claude doctor | xt claude reload",
|
|
56163
56066
|
"",
|
|
56164
|
-
|
|
56165
|
-
|
|
56166
|
-
|
|
56167
|
-
|
|
56168
|
-
|
|
56169
|
-
|
|
56170
|
-
|
|
56171
|
-
|
|
56172
|
-
|
|
56173
|
-
"",
|
|
56174
|
-
|
|
56175
|
-
|
|
56176
|
-
|
|
56177
|
-
|
|
56178
|
-
|
|
56179
|
-
|
|
56180
|
-
|
|
56181
|
-
"",
|
|
56182
|
-
|
|
56183
|
-
""
|
|
56184
|
-
|
|
56185
|
-
|
|
56186
|
-
|
|
56187
|
-
|
|
56188
|
-
|
|
56189
|
-
|
|
56190
|
-
|
|
56191
|
-
` ${kleur_default.bold("xtrm finish")} ${kleur_default.dim("Run blocking session closure lifecycle (PR + cleanup)")}`,
|
|
56192
|
-
` ${kleur_default.bold("xtrm reset")} ${kleur_default.dim("Clear saved preferences and start fresh")}`,
|
|
56193
|
-
` ${kleur_default.bold("xtrm help")} ${kleur_default.dim("Show this overview")}`
|
|
56194
|
-
].join("\n");
|
|
56195
|
-
const resourcesSection = [
|
|
56196
|
-
section("RESOURCES"),
|
|
56197
|
-
"",
|
|
56198
|
-
` Repository https://github.com/Jaggerxtrm/xtrm-tools`,
|
|
56199
|
-
` Issues https://github.com/Jaggerxtrm/xtrm-tools/issues`,
|
|
56200
|
-
"",
|
|
56201
|
-
` ${kleur_default.dim("Run 'xtrm <command> --help' for command-specific options.")}`,
|
|
56202
|
-
""
|
|
56203
|
-
].join("\n");
|
|
56204
|
-
console.log([installSection, hooksSection, skillsSection, psSection, otherSection, resourcesSection].join("\n"));
|
|
56067
|
+
" xt pi [name]",
|
|
56068
|
+
" Launch Pi in a sandboxed xt/<name> worktree.",
|
|
56069
|
+
" xt pi install [--dry-run]",
|
|
56070
|
+
" Non-interactive extension sync + package install.",
|
|
56071
|
+
" xt pi setup",
|
|
56072
|
+
" Interactive first-time setup.",
|
|
56073
|
+
" xt pi status | xt pi doctor | xt pi reload"
|
|
56074
|
+
]));
|
|
56075
|
+
blocks.push(section("WORKTREE COMMANDS", [
|
|
56076
|
+
" xt worktree list",
|
|
56077
|
+
" List active xt/* worktrees and merge status.",
|
|
56078
|
+
" xt worktree clean [--yes/-y]",
|
|
56079
|
+
" Remove worktrees already merged into main.",
|
|
56080
|
+
" xt worktree remove <name> [--yes/-y]",
|
|
56081
|
+
" Remove a specific xt worktree by name or path."
|
|
56082
|
+
]));
|
|
56083
|
+
blocks.push(section("SESSION CLOSE", [
|
|
56084
|
+
" xt end [options]",
|
|
56085
|
+
" Rebase to origin/main, push, open PR, link issues, and optionally clean worktree.",
|
|
56086
|
+
" Options: --draft, --keep, --yes/-y"
|
|
56087
|
+
]));
|
|
56088
|
+
blocks.push(section("NOTES", [
|
|
56089
|
+
" - Banner is shown only for xtrm install.",
|
|
56090
|
+
" - For command-level details, run: xtrm <command> --help",
|
|
56091
|
+
" - For subcommand details, run: xtrm <command> <subcommand> --help"
|
|
56092
|
+
]));
|
|
56093
|
+
process.stdout.write(blocks.join("\n"));
|
|
56205
56094
|
});
|
|
56206
56095
|
}
|
|
56207
56096
|
|
|
56208
56097
|
// src/commands/clean.ts
|
|
56209
|
-
var
|
|
56098
|
+
var import_fs_extra18 = __toESM(require_lib2(), 1);
|
|
56210
56099
|
var import_path19 = __toESM(require("path"), 1);
|
|
56211
|
-
var
|
|
56100
|
+
var import_os6 = require("os");
|
|
56212
56101
|
var CANONICAL_HOOKS = /* @__PURE__ */ new Set([
|
|
56213
|
-
"
|
|
56214
|
-
"serena-workflow-reminder.py",
|
|
56215
|
-
"main-guard.mjs",
|
|
56216
|
-
"main-guard-post-push.mjs",
|
|
56102
|
+
"using-xtrm-reminder.mjs",
|
|
56217
56103
|
"beads-gate-core.mjs",
|
|
56218
56104
|
"beads-gate-utils.mjs",
|
|
56219
56105
|
"beads-gate-messages.mjs",
|
|
@@ -56224,12 +56110,16 @@ var CANONICAL_HOOKS = /* @__PURE__ */ new Set([
|
|
|
56224
56110
|
"beads-claim-sync.mjs",
|
|
56225
56111
|
"beads-compact-save.mjs",
|
|
56226
56112
|
"beads-compact-restore.mjs",
|
|
56227
|
-
"
|
|
56113
|
+
"worktree-boundary.mjs",
|
|
56114
|
+
"statusline.mjs",
|
|
56228
56115
|
"quality-check.cjs",
|
|
56116
|
+
"quality-check-env.mjs",
|
|
56229
56117
|
"quality-check.py",
|
|
56118
|
+
"xtrm-logger.mjs",
|
|
56119
|
+
"xtrm-tool-logger.mjs",
|
|
56120
|
+
"xtrm-session-logger.mjs",
|
|
56230
56121
|
"gitnexus",
|
|
56231
56122
|
// directory
|
|
56232
|
-
"statusline-starship.sh",
|
|
56233
56123
|
"README.md"
|
|
56234
56124
|
]);
|
|
56235
56125
|
var CANONICAL_SKILLS = /* @__PURE__ */ new Set([
|
|
@@ -56269,18 +56159,18 @@ var IGNORED_ITEMS2 = /* @__PURE__ */ new Set([
|
|
|
56269
56159
|
"node_modules"
|
|
56270
56160
|
]);
|
|
56271
56161
|
async function cleanHooks(dryRun) {
|
|
56272
|
-
const hooksDir = import_path19.default.join((0,
|
|
56162
|
+
const hooksDir = import_path19.default.join((0, import_os6.homedir)(), ".claude", "hooks");
|
|
56273
56163
|
const removed = [];
|
|
56274
56164
|
const cache = [];
|
|
56275
|
-
if (!await
|
|
56165
|
+
if (!await import_fs_extra18.default.pathExists(hooksDir)) {
|
|
56276
56166
|
return { removed, cache };
|
|
56277
56167
|
}
|
|
56278
|
-
const entries = await
|
|
56168
|
+
const entries = await import_fs_extra18.default.readdir(hooksDir);
|
|
56279
56169
|
for (const entry of entries) {
|
|
56280
56170
|
if (IGNORED_ITEMS2.has(entry)) {
|
|
56281
56171
|
if (!dryRun) {
|
|
56282
56172
|
const fullPath2 = import_path19.default.join(hooksDir, entry);
|
|
56283
|
-
await
|
|
56173
|
+
await import_fs_extra18.default.remove(fullPath2);
|
|
56284
56174
|
}
|
|
56285
56175
|
cache.push(entry);
|
|
56286
56176
|
continue;
|
|
@@ -56289,10 +56179,10 @@ async function cleanHooks(dryRun) {
|
|
|
56289
56179
|
continue;
|
|
56290
56180
|
}
|
|
56291
56181
|
const fullPath = import_path19.default.join(hooksDir, entry);
|
|
56292
|
-
const stat = await
|
|
56182
|
+
const stat = await import_fs_extra18.default.stat(fullPath);
|
|
56293
56183
|
if (stat.isFile() || stat.isDirectory() && IGNORED_ITEMS2.has(entry)) {
|
|
56294
56184
|
if (!dryRun) {
|
|
56295
|
-
await
|
|
56185
|
+
await import_fs_extra18.default.remove(fullPath);
|
|
56296
56186
|
}
|
|
56297
56187
|
removed.push(entry);
|
|
56298
56188
|
}
|
|
@@ -56300,12 +56190,12 @@ async function cleanHooks(dryRun) {
|
|
|
56300
56190
|
return { removed, cache };
|
|
56301
56191
|
}
|
|
56302
56192
|
async function cleanSkills(dryRun) {
|
|
56303
|
-
const skillsDir = import_path19.default.join((0,
|
|
56193
|
+
const skillsDir = import_path19.default.join((0, import_os6.homedir)(), ".agents", "skills");
|
|
56304
56194
|
const removed = [];
|
|
56305
|
-
if (!await
|
|
56195
|
+
if (!await import_fs_extra18.default.pathExists(skillsDir)) {
|
|
56306
56196
|
return removed;
|
|
56307
56197
|
}
|
|
56308
|
-
const entries = await
|
|
56198
|
+
const entries = await import_fs_extra18.default.readdir(skillsDir);
|
|
56309
56199
|
for (const entry of entries) {
|
|
56310
56200
|
if (IGNORED_ITEMS2.has(entry)) {
|
|
56311
56201
|
continue;
|
|
@@ -56317,10 +56207,10 @@ async function cleanSkills(dryRun) {
|
|
|
56317
56207
|
continue;
|
|
56318
56208
|
}
|
|
56319
56209
|
const fullPath = import_path19.default.join(skillsDir, entry);
|
|
56320
|
-
const stat = await
|
|
56210
|
+
const stat = await import_fs_extra18.default.stat(fullPath);
|
|
56321
56211
|
if (stat.isDirectory()) {
|
|
56322
56212
|
if (!dryRun) {
|
|
56323
|
-
await
|
|
56213
|
+
await import_fs_extra18.default.remove(fullPath);
|
|
56324
56214
|
}
|
|
56325
56215
|
removed.push(entry);
|
|
56326
56216
|
}
|
|
@@ -56328,14 +56218,14 @@ async function cleanSkills(dryRun) {
|
|
|
56328
56218
|
return removed;
|
|
56329
56219
|
}
|
|
56330
56220
|
async function cleanOrphanedHookEntries(dryRun, repoRoot) {
|
|
56331
|
-
const settingsPath = import_path19.default.join((0,
|
|
56221
|
+
const settingsPath = import_path19.default.join((0, import_os6.homedir)(), ".claude", "settings.json");
|
|
56332
56222
|
const removed = [];
|
|
56333
|
-
if (!await
|
|
56223
|
+
if (!await import_fs_extra18.default.pathExists(settingsPath)) {
|
|
56334
56224
|
return removed;
|
|
56335
56225
|
}
|
|
56336
56226
|
let settings = {};
|
|
56337
56227
|
try {
|
|
56338
|
-
settings = await
|
|
56228
|
+
settings = await import_fs_extra18.default.readJson(settingsPath);
|
|
56339
56229
|
} catch {
|
|
56340
56230
|
return removed;
|
|
56341
56231
|
}
|
|
@@ -56353,8 +56243,8 @@ async function cleanOrphanedHookEntries(dryRun, repoRoot) {
|
|
|
56353
56243
|
if (repoRoot) {
|
|
56354
56244
|
const hooksJsonPath = import_path19.default.join(repoRoot, "config", "hooks.json");
|
|
56355
56245
|
try {
|
|
56356
|
-
if (await
|
|
56357
|
-
const hooksJson = await
|
|
56246
|
+
if (await import_fs_extra18.default.pathExists(hooksJsonPath)) {
|
|
56247
|
+
const hooksJson = await import_fs_extra18.default.readJson(hooksJsonPath);
|
|
56358
56248
|
for (const [event, entries] of Object.entries(hooksJson.hooks ?? {})) {
|
|
56359
56249
|
for (const entry of entries) {
|
|
56360
56250
|
const script = entry.script;
|
|
@@ -56416,7 +56306,7 @@ async function cleanOrphanedHookEntries(dryRun, repoRoot) {
|
|
|
56416
56306
|
}
|
|
56417
56307
|
}
|
|
56418
56308
|
if (modified && !dryRun) {
|
|
56419
|
-
await
|
|
56309
|
+
await import_fs_extra18.default.writeJson(settingsPath, settings, { spaces: 2 });
|
|
56420
56310
|
}
|
|
56421
56311
|
return removed;
|
|
56422
56312
|
}
|
|
@@ -56497,327 +56387,15 @@ function createCleanCommand() {
|
|
|
56497
56387
|
});
|
|
56498
56388
|
}
|
|
56499
56389
|
|
|
56500
|
-
// src/core/xtrm-finish.ts
|
|
56501
|
-
var import_node_child_process7 = require("child_process");
|
|
56502
|
-
var import_node_fs5 = require("fs");
|
|
56503
|
-
|
|
56504
|
-
// src/core/session-state.ts
|
|
56505
|
-
var import_node_child_process6 = require("child_process");
|
|
56506
|
-
var import_node_fs4 = require("fs");
|
|
56507
|
-
var import_node_path6 = __toESM(require("path"), 1);
|
|
56508
|
-
var SESSION_STATE_FILE = ".xtrm-session-state.json";
|
|
56509
|
-
var SESSION_PHASES = [
|
|
56510
|
-
"claimed",
|
|
56511
|
-
"phase1-done",
|
|
56512
|
-
"waiting-merge",
|
|
56513
|
-
"conflicting",
|
|
56514
|
-
"pending-cleanup",
|
|
56515
|
-
"merged",
|
|
56516
|
-
"cleanup-done"
|
|
56517
|
-
];
|
|
56518
|
-
var ALLOWED_TRANSITIONS = {
|
|
56519
|
-
claimed: ["phase1-done", "waiting-merge", "conflicting", "pending-cleanup", "cleanup-done"],
|
|
56520
|
-
"phase1-done": ["waiting-merge", "conflicting", "pending-cleanup", "cleanup-done"],
|
|
56521
|
-
"waiting-merge": ["conflicting", "pending-cleanup", "merged", "cleanup-done"],
|
|
56522
|
-
conflicting: ["waiting-merge", "pending-cleanup", "merged", "cleanup-done"],
|
|
56523
|
-
"pending-cleanup": ["waiting-merge", "conflicting", "merged", "cleanup-done"],
|
|
56524
|
-
merged: ["cleanup-done"],
|
|
56525
|
-
"cleanup-done": []
|
|
56526
|
-
};
|
|
56527
|
-
var nowIso = () => (/* @__PURE__ */ new Date()).toISOString();
|
|
56528
|
-
function isPhase(value) {
|
|
56529
|
-
return typeof value === "string" && SESSION_PHASES.includes(value);
|
|
56530
|
-
}
|
|
56531
|
-
function normalizeState(value) {
|
|
56532
|
-
if (!value || typeof value !== "object") {
|
|
56533
|
-
throw new Error("Invalid session state payload");
|
|
56534
|
-
}
|
|
56535
|
-
const state = value;
|
|
56536
|
-
if (!state.issueId || !state.branch || !state.worktreePath || !state.phase) {
|
|
56537
|
-
throw new Error("Session state requires issueId, branch, worktreePath, and phase");
|
|
56538
|
-
}
|
|
56539
|
-
if (!isPhase(state.phase)) throw new Error(`Invalid session phase: ${String(state.phase)}`);
|
|
56540
|
-
return {
|
|
56541
|
-
issueId: String(state.issueId),
|
|
56542
|
-
branch: String(state.branch),
|
|
56543
|
-
worktreePath: String(state.worktreePath),
|
|
56544
|
-
prNumber: state.prNumber ?? null,
|
|
56545
|
-
prUrl: state.prUrl ?? null,
|
|
56546
|
-
phase: state.phase,
|
|
56547
|
-
conflictFiles: Array.isArray(state.conflictFiles) ? state.conflictFiles.map(String) : [],
|
|
56548
|
-
startedAt: state.startedAt || nowIso(),
|
|
56549
|
-
lastChecked: nowIso()
|
|
56550
|
-
};
|
|
56551
|
-
}
|
|
56552
|
-
function findSessionStateFile(startCwd = process.cwd()) {
|
|
56553
|
-
let current = import_node_path6.default.resolve(startCwd);
|
|
56554
|
-
for (; ; ) {
|
|
56555
|
-
const candidate = import_node_path6.default.join(current, SESSION_STATE_FILE);
|
|
56556
|
-
if ((0, import_node_fs4.existsSync)(candidate)) return candidate;
|
|
56557
|
-
const parent = import_node_path6.default.dirname(current);
|
|
56558
|
-
if (parent === current) return null;
|
|
56559
|
-
current = parent;
|
|
56560
|
-
}
|
|
56561
|
-
}
|
|
56562
|
-
function readSessionState(startCwd = process.cwd()) {
|
|
56563
|
-
const filePath = findSessionStateFile(startCwd);
|
|
56564
|
-
if (!filePath) return null;
|
|
56565
|
-
try {
|
|
56566
|
-
const parsed = JSON.parse((0, import_node_fs4.readFileSync)(filePath, "utf8"));
|
|
56567
|
-
return normalizeState(parsed);
|
|
56568
|
-
} catch {
|
|
56569
|
-
return null;
|
|
56570
|
-
}
|
|
56571
|
-
}
|
|
56572
|
-
function updateSessionPhase(nextPhase, startCwd = process.cwd(), patch = {}) {
|
|
56573
|
-
const filePath = findSessionStateFile(startCwd);
|
|
56574
|
-
if (!filePath) throw new Error("Session state file not found");
|
|
56575
|
-
const current = readSessionState(startCwd);
|
|
56576
|
-
if (!current) throw new Error("Session state file invalid");
|
|
56577
|
-
if (!isPhase(nextPhase)) {
|
|
56578
|
-
throw new Error(`Invalid session phase: ${String(nextPhase)}`);
|
|
56579
|
-
}
|
|
56580
|
-
if (current.phase !== nextPhase && !ALLOWED_TRANSITIONS[current.phase].includes(nextPhase)) {
|
|
56581
|
-
throw new Error(`Invalid phase transition: ${current.phase} -> ${nextPhase}`);
|
|
56582
|
-
}
|
|
56583
|
-
const nextState = normalizeState({
|
|
56584
|
-
...current,
|
|
56585
|
-
...patch,
|
|
56586
|
-
phase: nextPhase
|
|
56587
|
-
});
|
|
56588
|
-
(0, import_node_fs4.writeFileSync)(filePath, JSON.stringify(nextState, null, 2) + "\n", "utf8");
|
|
56589
|
-
return nextState;
|
|
56590
|
-
}
|
|
56591
|
-
|
|
56592
|
-
// src/core/xtrm-finish.ts
|
|
56593
|
-
var DEFAULT_POLL_INTERVAL_MS = 5e3;
|
|
56594
|
-
var DEFAULT_TIMEOUT_MS = 10 * 60 * 1e3;
|
|
56595
|
-
function run2(cmd, args, cwd) {
|
|
56596
|
-
const r = (0, import_node_child_process7.spawnSync)(cmd, args, {
|
|
56597
|
-
cwd,
|
|
56598
|
-
encoding: "utf8",
|
|
56599
|
-
stdio: ["pipe", "pipe", "pipe"]
|
|
56600
|
-
});
|
|
56601
|
-
return {
|
|
56602
|
-
code: r.status ?? 1,
|
|
56603
|
-
stdout: (r.stdout ?? "").trim(),
|
|
56604
|
-
stderr: (r.stderr ?? "").trim()
|
|
56605
|
-
};
|
|
56606
|
-
}
|
|
56607
|
-
function getControlRepoRoot(cwd) {
|
|
56608
|
-
const commonDir = run2("git", ["rev-parse", "--path-format=absolute", "--git-common-dir"], cwd);
|
|
56609
|
-
if (commonDir.code === 0 && commonDir.stdout) {
|
|
56610
|
-
return commonDir.stdout.replace(/\/.git$/, "");
|
|
56611
|
-
}
|
|
56612
|
-
return cwd;
|
|
56613
|
-
}
|
|
56614
|
-
function resolveExecutionCwd(controlCwd, state) {
|
|
56615
|
-
if (state.worktreePath && (0, import_node_fs5.existsSync)(state.worktreePath)) {
|
|
56616
|
-
return state.worktreePath;
|
|
56617
|
-
}
|
|
56618
|
-
return controlCwd;
|
|
56619
|
-
}
|
|
56620
|
-
function parsePrCreate(stdout) {
|
|
56621
|
-
const urlMatch = stdout.match(/https?:\/\/\S+\/pull\/(\d+)/);
|
|
56622
|
-
if (urlMatch) {
|
|
56623
|
-
return { prNumber: Number(urlMatch[1]), prUrl: urlMatch[0] };
|
|
56624
|
-
}
|
|
56625
|
-
const numberMatch = stdout.match(/#(\d+)/);
|
|
56626
|
-
if (numberMatch) {
|
|
56627
|
-
return { prNumber: Number(numberMatch[1]), prUrl: null };
|
|
56628
|
-
}
|
|
56629
|
-
return { prNumber: null, prUrl: null };
|
|
56630
|
-
}
|
|
56631
|
-
function getConflictFiles(cwd) {
|
|
56632
|
-
const out = run2("git", ["diff", "--name-only", "--diff-filter=U"], cwd);
|
|
56633
|
-
if (out.code !== 0 || !out.stdout) return [];
|
|
56634
|
-
return out.stdout.split("\n").map((s) => s.trim()).filter(Boolean);
|
|
56635
|
-
}
|
|
56636
|
-
async function delay2(ms) {
|
|
56637
|
-
if (ms <= 0) return;
|
|
56638
|
-
await new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
56639
|
-
}
|
|
56640
|
-
function ensureCleanPhaseTransition(cwd, phase, patch = {}) {
|
|
56641
|
-
try {
|
|
56642
|
-
updateSessionPhase(phase, cwd, patch);
|
|
56643
|
-
} catch {
|
|
56644
|
-
}
|
|
56645
|
-
}
|
|
56646
|
-
function handleRebaseAndPush(cwd) {
|
|
56647
|
-
const fetch = run2("git", ["fetch", "origin"], cwd);
|
|
56648
|
-
if (fetch.code !== 0) return { ok: false, error: fetch.stderr || fetch.stdout };
|
|
56649
|
-
const rebase = run2("git", ["rebase", "origin/main"], cwd);
|
|
56650
|
-
if (rebase.code !== 0) {
|
|
56651
|
-
const conflicts = getConflictFiles(cwd);
|
|
56652
|
-
return { ok: false, conflicts, error: rebase.stderr || rebase.stdout };
|
|
56653
|
-
}
|
|
56654
|
-
const push = run2("git", ["push", "--force-with-lease"], cwd);
|
|
56655
|
-
if (push.code !== 0) {
|
|
56656
|
-
return { ok: false, error: push.stderr || push.stdout };
|
|
56657
|
-
}
|
|
56658
|
-
return { ok: true };
|
|
56659
|
-
}
|
|
56660
|
-
function cleanupPhase(controlCwd, state) {
|
|
56661
|
-
if ((0, import_node_fs5.existsSync)(state.worktreePath)) {
|
|
56662
|
-
const rm = run2("git", ["worktree", "remove", state.worktreePath, "--force"], controlCwd);
|
|
56663
|
-
if (rm.code !== 0) {
|
|
56664
|
-
return { ok: false, message: rm.stderr || rm.stdout || `Failed to remove worktree ${state.worktreePath}` };
|
|
56665
|
-
}
|
|
56666
|
-
}
|
|
56667
|
-
run2("git", ["fetch", "--prune"], controlCwd);
|
|
56668
|
-
ensureCleanPhaseTransition(controlCwd, "cleanup-done");
|
|
56669
|
-
const prLabel = state.prNumber != null ? `#${state.prNumber}` : "(unknown PR)";
|
|
56670
|
-
return { ok: true, message: `Done. PR ${prLabel} merged. Worktree removed.` };
|
|
56671
|
-
}
|
|
56672
|
-
async function pollUntilMerged(controlCwd, executionCwd, state, opts) {
|
|
56673
|
-
if (state.prNumber == null) {
|
|
56674
|
-
return { ok: false, message: "Session state missing prNumber. Re-run phase 1 before polling." };
|
|
56675
|
-
}
|
|
56676
|
-
const started = Date.now();
|
|
56677
|
-
while (Date.now() - started < opts.timeoutMs) {
|
|
56678
|
-
const view = run2("gh", ["pr", "view", String(state.prNumber), "--json", "state,mergeStateStatus,mergeable"], executionCwd);
|
|
56679
|
-
if (view.code !== 0) {
|
|
56680
|
-
return { ok: false, message: view.stderr || view.stdout || `Failed to inspect PR #${state.prNumber}` };
|
|
56681
|
-
}
|
|
56682
|
-
let payload = null;
|
|
56683
|
-
try {
|
|
56684
|
-
payload = JSON.parse(view.stdout);
|
|
56685
|
-
} catch {
|
|
56686
|
-
return { ok: false, message: `Unable to parse gh pr view output for #${state.prNumber}` };
|
|
56687
|
-
}
|
|
56688
|
-
ensureCleanPhaseTransition(controlCwd, "waiting-merge");
|
|
56689
|
-
if (payload.state === "MERGED") {
|
|
56690
|
-
ensureCleanPhaseTransition(controlCwd, "merged");
|
|
56691
|
-
const latest = readSessionState(controlCwd) ?? state;
|
|
56692
|
-
return cleanupPhase(controlCwd, latest);
|
|
56693
|
-
}
|
|
56694
|
-
if (payload.mergeStateStatus === "BEHIND") {
|
|
56695
|
-
run2("git", ["fetch", "origin"], executionCwd);
|
|
56696
|
-
run2("git", ["push"], executionCwd);
|
|
56697
|
-
await delay2(opts.pollIntervalMs);
|
|
56698
|
-
continue;
|
|
56699
|
-
}
|
|
56700
|
-
if (payload.mergeable === "CONFLICTING") {
|
|
56701
|
-
const rebased = handleRebaseAndPush(executionCwd);
|
|
56702
|
-
if (!rebased.ok) {
|
|
56703
|
-
const conflictFiles = rebased.conflicts ?? getConflictFiles(executionCwd);
|
|
56704
|
-
ensureCleanPhaseTransition(controlCwd, "conflicting", { conflictFiles });
|
|
56705
|
-
return {
|
|
56706
|
-
ok: false,
|
|
56707
|
-
message: `Conflicts in: ${conflictFiles.join(", ") || "unknown files"}. Resolve, push, then re-run xtrm finish.`
|
|
56708
|
-
};
|
|
56709
|
-
}
|
|
56710
|
-
ensureCleanPhaseTransition(controlCwd, "waiting-merge", { conflictFiles: [] });
|
|
56711
|
-
await delay2(opts.pollIntervalMs);
|
|
56712
|
-
continue;
|
|
56713
|
-
}
|
|
56714
|
-
await delay2(opts.pollIntervalMs);
|
|
56715
|
-
}
|
|
56716
|
-
ensureCleanPhaseTransition(controlCwd, "pending-cleanup");
|
|
56717
|
-
return {
|
|
56718
|
-
ok: false,
|
|
56719
|
-
message: `PR #${state.prNumber} not yet merged. Run xtrm finish when ready.`
|
|
56720
|
-
};
|
|
56721
|
-
}
|
|
56722
|
-
function isWorkingTreeDirty(cwd) {
|
|
56723
|
-
const st = run2("git", ["status", "--porcelain"], cwd);
|
|
56724
|
-
return st.code === 0 && st.stdout.length > 0;
|
|
56725
|
-
}
|
|
56726
|
-
function runPhase1(controlCwd, executionCwd, state) {
|
|
56727
|
-
if (isWorkingTreeDirty(executionCwd)) {
|
|
56728
|
-
const add = run2("git", ["add", "-A"], executionCwd);
|
|
56729
|
-
if (add.code !== 0) return { ok: false, message: add.stderr || add.stdout };
|
|
56730
|
-
const msg = `feat(${state.issueId}): ${state.branch}`;
|
|
56731
|
-
const commit = run2("git", ["commit", "-m", msg], executionCwd);
|
|
56732
|
-
if (commit.code !== 0) {
|
|
56733
|
-
return { ok: false, message: commit.stderr || commit.stdout || "git commit failed" };
|
|
56734
|
-
}
|
|
56735
|
-
}
|
|
56736
|
-
const push = run2("git", ["push", "-u", "origin", state.branch], executionCwd);
|
|
56737
|
-
if (push.code !== 0) return { ok: false, message: push.stderr || push.stdout || "git push failed" };
|
|
56738
|
-
const create = run2("gh", ["pr", "create", "--fill"], executionCwd);
|
|
56739
|
-
if (create.code !== 0) return { ok: false, message: create.stderr || create.stdout || "gh pr create failed" };
|
|
56740
|
-
const parsed = parsePrCreate(create.stdout);
|
|
56741
|
-
const merge2 = run2("gh", ["pr", "merge", "--squash", "--auto"], executionCwd);
|
|
56742
|
-
if (merge2.code !== 0) return { ok: false, message: merge2.stderr || merge2.stdout || "gh pr merge failed" };
|
|
56743
|
-
ensureCleanPhaseTransition(controlCwd, "phase1-done", {
|
|
56744
|
-
prNumber: parsed.prNumber,
|
|
56745
|
-
prUrl: parsed.prUrl
|
|
56746
|
-
});
|
|
56747
|
-
ensureCleanPhaseTransition(controlCwd, "waiting-merge", {
|
|
56748
|
-
prNumber: parsed.prNumber,
|
|
56749
|
-
prUrl: parsed.prUrl
|
|
56750
|
-
});
|
|
56751
|
-
return { ok: true, message: "phase1 complete" };
|
|
56752
|
-
}
|
|
56753
|
-
async function runXtrmFinish(options = {}) {
|
|
56754
|
-
const cwd = options.cwd ?? process.cwd();
|
|
56755
|
-
const controlCwd = getControlRepoRoot(cwd);
|
|
56756
|
-
const state = readSessionState(controlCwd);
|
|
56757
|
-
if (!state) {
|
|
56758
|
-
return { ok: false, message: "No .xtrm-session-state.json found. Claim an issue first (bd update <id> --claim)." };
|
|
56759
|
-
}
|
|
56760
|
-
const executionCwd = resolveExecutionCwd(controlCwd, state);
|
|
56761
|
-
const opts = {
|
|
56762
|
-
cwd: controlCwd,
|
|
56763
|
-
pollIntervalMs: options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS,
|
|
56764
|
-
timeoutMs: options.timeoutMs ?? DEFAULT_TIMEOUT_MS
|
|
56765
|
-
};
|
|
56766
|
-
if (state.phase === "cleanup-done") {
|
|
56767
|
-
return { ok: true, message: "Session is already cleanup-done." };
|
|
56768
|
-
}
|
|
56769
|
-
if (state.phase === "conflicting") {
|
|
56770
|
-
const resolved = handleRebaseAndPush(executionCwd);
|
|
56771
|
-
if (!resolved.ok) {
|
|
56772
|
-
const files = resolved.conflicts ?? getConflictFiles(executionCwd);
|
|
56773
|
-
ensureCleanPhaseTransition(controlCwd, "conflicting", { conflictFiles: files });
|
|
56774
|
-
return { ok: false, message: `Conflicts in: ${files.join(", ") || "unknown files"}. Resolve, push, then re-run xtrm finish.` };
|
|
56775
|
-
}
|
|
56776
|
-
ensureCleanPhaseTransition(controlCwd, "waiting-merge", { conflictFiles: [] });
|
|
56777
|
-
const refreshed2 = readSessionState(controlCwd) ?? state;
|
|
56778
|
-
return pollUntilMerged(controlCwd, executionCwd, refreshed2, opts);
|
|
56779
|
-
}
|
|
56780
|
-
if (state.phase === "waiting-merge" || state.phase === "pending-cleanup" || state.phase === "merged") {
|
|
56781
|
-
const refreshed2 = readSessionState(controlCwd) ?? state;
|
|
56782
|
-
if (refreshed2.phase === "merged") return cleanupPhase(controlCwd, refreshed2);
|
|
56783
|
-
return pollUntilMerged(controlCwd, executionCwd, refreshed2, opts);
|
|
56784
|
-
}
|
|
56785
|
-
const phase1 = runPhase1(controlCwd, executionCwd, state);
|
|
56786
|
-
if (!phase1.ok) return phase1;
|
|
56787
|
-
const refreshed = readSessionState(controlCwd) ?? state;
|
|
56788
|
-
return pollUntilMerged(controlCwd, executionCwd, refreshed, opts);
|
|
56789
|
-
}
|
|
56790
|
-
|
|
56791
|
-
// src/commands/finish.ts
|
|
56792
|
-
function createFinishCommand() {
|
|
56793
|
-
return new Command("finish").description("Complete session closure lifecycle (phase1 + merge polling + cleanup)").option("--poll-interval-ms <ms>", "Polling interval for PR state checks", (v) => Number(v), 5e3).option("--timeout-ms <ms>", "Maximum wait time before pending-cleanup", (v) => Number(v), 10 * 60 * 1e3).action(async (opts) => {
|
|
56794
|
-
const result = await runXtrmFinish({
|
|
56795
|
-
cwd: process.cwd(),
|
|
56796
|
-
pollIntervalMs: opts.pollIntervalMs,
|
|
56797
|
-
timeoutMs: opts.timeoutMs
|
|
56798
|
-
});
|
|
56799
|
-
if (result.ok) {
|
|
56800
|
-
console.log(kleur_default.green(`
|
|
56801
|
-
\u2713 ${result.message}
|
|
56802
|
-
`));
|
|
56803
|
-
return;
|
|
56804
|
-
}
|
|
56805
|
-
console.error(kleur_default.red(`
|
|
56806
|
-
\u2717 ${result.message}
|
|
56807
|
-
`));
|
|
56808
|
-
process.exitCode = 1;
|
|
56809
|
-
});
|
|
56810
|
-
}
|
|
56811
|
-
|
|
56812
56390
|
// src/commands/end.ts
|
|
56813
|
-
var
|
|
56814
|
-
var
|
|
56391
|
+
var import_prompts4 = __toESM(require_prompts3(), 1);
|
|
56392
|
+
var import_node_child_process6 = require("child_process");
|
|
56815
56393
|
function git(args, cwd) {
|
|
56816
|
-
const r = (0,
|
|
56394
|
+
const r = (0, import_node_child_process6.spawnSync)("git", args, { cwd, encoding: "utf8", stdio: "pipe" });
|
|
56817
56395
|
return { ok: r.status === 0, out: (r.stdout ?? "").trim(), err: (r.stderr ?? "").trim() };
|
|
56818
56396
|
}
|
|
56819
56397
|
function bd(args, cwd) {
|
|
56820
|
-
const r = (0,
|
|
56398
|
+
const r = (0, import_node_child_process6.spawnSync)("bd", args, { cwd, encoding: "utf8", stdio: "pipe" });
|
|
56821
56399
|
return { ok: r.status === 0, out: (r.stdout ?? "").trim() };
|
|
56822
56400
|
}
|
|
56823
56401
|
function extractIssueIds(commitLog) {
|
|
@@ -56945,7 +56523,7 @@ function createEndCommand() {
|
|
|
56945
56523
|
console.log(kleur_default.dim(" Creating PR..."));
|
|
56946
56524
|
const prArgs = ["pr", "create", "--title", prTitle, "--body", prBody];
|
|
56947
56525
|
if (opts.draft) prArgs.push("--draft");
|
|
56948
|
-
const prResult = (0,
|
|
56526
|
+
const prResult = (0, import_node_child_process6.spawnSync)("gh", prArgs, { cwd, encoding: "utf8", stdio: "pipe" });
|
|
56949
56527
|
if (prResult.status !== 0) {
|
|
56950
56528
|
console.error(kleur_default.red(`
|
|
56951
56529
|
\u2717 PR creation failed:
|
|
@@ -56964,7 +56542,7 @@ function createEndCommand() {
|
|
|
56964
56542
|
if (!opts.keep) {
|
|
56965
56543
|
let doRemove = opts.yes;
|
|
56966
56544
|
if (!opts.yes) {
|
|
56967
|
-
const { remove } = await (0,
|
|
56545
|
+
const { remove } = await (0, import_prompts4.default)({
|
|
56968
56546
|
type: "confirm",
|
|
56969
56547
|
name: "remove",
|
|
56970
56548
|
message: `Remove local worktree at ${cwd}?`,
|
|
@@ -56975,7 +56553,7 @@ function createEndCommand() {
|
|
|
56975
56553
|
if (doRemove) {
|
|
56976
56554
|
try {
|
|
56977
56555
|
const repoRoot = git(["rev-parse", "--show-toplevel"], cwd).out;
|
|
56978
|
-
const removeResult = (0,
|
|
56556
|
+
const removeResult = (0, import_node_child_process6.spawnSync)(
|
|
56979
56557
|
"git",
|
|
56980
56558
|
["worktree", "remove", cwd, "--force"],
|
|
56981
56559
|
{ cwd: repoRoot, encoding: "utf8", stdio: "pipe" }
|
|
@@ -56998,10 +56576,10 @@ function createEndCommand() {
|
|
|
56998
56576
|
}
|
|
56999
56577
|
|
|
57000
56578
|
// src/commands/worktree.ts
|
|
57001
|
-
var
|
|
57002
|
-
var
|
|
56579
|
+
var import_prompts5 = __toESM(require_prompts3(), 1);
|
|
56580
|
+
var import_node_child_process7 = require("child_process");
|
|
57003
56581
|
function listXtWorktrees(repoRoot) {
|
|
57004
|
-
const r = (0,
|
|
56582
|
+
const r = (0, import_node_child_process7.spawnSync)("git", ["worktree", "list", "--porcelain"], {
|
|
57005
56583
|
cwd: repoRoot,
|
|
57006
56584
|
encoding: "utf8",
|
|
57007
56585
|
stdio: "pipe"
|
|
@@ -57030,7 +56608,7 @@ function listXtWorktrees(repoRoot) {
|
|
|
57030
56608
|
}
|
|
57031
56609
|
function isMergedIntoMain(branch, repoRoot) {
|
|
57032
56610
|
const branchShort = branch.replace("refs/heads/", "");
|
|
57033
|
-
const r = (0,
|
|
56611
|
+
const r = (0, import_node_child_process7.spawnSync)("git", ["branch", "--merged", "origin/main", "--list", branchShort], {
|
|
57034
56612
|
cwd: repoRoot,
|
|
57035
56613
|
encoding: "utf8",
|
|
57036
56614
|
stdio: "pipe"
|
|
@@ -57038,7 +56616,7 @@ function isMergedIntoMain(branch, repoRoot) {
|
|
|
57038
56616
|
return (r.stdout ?? "").includes(branchShort);
|
|
57039
56617
|
}
|
|
57040
56618
|
function getRepoRoot(cwd) {
|
|
57041
|
-
const r = (0,
|
|
56619
|
+
const r = (0, import_node_child_process7.spawnSync)("git", ["rev-parse", "--show-toplevel"], { cwd, encoding: "utf8", stdio: "pipe" });
|
|
57042
56620
|
return r.ok ? r.stdout.trim() : cwd;
|
|
57043
56621
|
}
|
|
57044
56622
|
function createWorktreeCommand() {
|
|
@@ -57079,7 +56657,7 @@ function createWorktreeCommand() {
|
|
|
57079
56657
|
}
|
|
57080
56658
|
let doRemove = opts.yes;
|
|
57081
56659
|
if (!opts.yes) {
|
|
57082
|
-
const { confirm } = await (0,
|
|
56660
|
+
const { confirm } = await (0, import_prompts5.default)({
|
|
57083
56661
|
type: "confirm",
|
|
57084
56662
|
name: "confirm",
|
|
57085
56663
|
message: `Remove ${merged.length} worktree(s)?`,
|
|
@@ -57092,7 +56670,7 @@ function createWorktreeCommand() {
|
|
|
57092
56670
|
return;
|
|
57093
56671
|
}
|
|
57094
56672
|
for (const wt of merged) {
|
|
57095
|
-
const r = (0,
|
|
56673
|
+
const r = (0, import_node_child_process7.spawnSync)("git", ["worktree", "remove", wt.path, "--force"], {
|
|
57096
56674
|
cwd: repoRoot,
|
|
57097
56675
|
encoding: "utf8",
|
|
57098
56676
|
stdio: "pipe"
|
|
@@ -57120,7 +56698,7 @@ function createWorktreeCommand() {
|
|
|
57120
56698
|
}
|
|
57121
56699
|
let doRemove = opts.yes;
|
|
57122
56700
|
if (!opts.yes) {
|
|
57123
|
-
const { confirm } = await (0,
|
|
56701
|
+
const { confirm } = await (0, import_prompts5.default)({
|
|
57124
56702
|
type: "confirm",
|
|
57125
56703
|
name: "confirm",
|
|
57126
56704
|
message: `Remove ${target.path}?`,
|
|
@@ -57132,7 +56710,7 @@ function createWorktreeCommand() {
|
|
|
57132
56710
|
console.log(kleur_default.dim(" Cancelled\n"));
|
|
57133
56711
|
return;
|
|
57134
56712
|
}
|
|
57135
|
-
const r = (0,
|
|
56713
|
+
const r = (0, import_node_child_process7.spawnSync)("git", ["worktree", "remove", target.path, "--force"], {
|
|
57136
56714
|
cwd: repoRoot,
|
|
57137
56715
|
encoding: "utf8",
|
|
57138
56716
|
stdio: "pipe"
|
|
@@ -57151,6 +56729,336 @@ function createWorktreeCommand() {
|
|
|
57151
56729
|
return cmd;
|
|
57152
56730
|
}
|
|
57153
56731
|
|
|
56732
|
+
// src/commands/docs.ts
|
|
56733
|
+
var import_fs_extra19 = __toESM(require_lib2(), 1);
|
|
56734
|
+
var import_path20 = __toESM(require("path"), 1);
|
|
56735
|
+
var REQUIRED_FIELDS = /* @__PURE__ */ new Set(["title", "type", "status", "updated_at", "version"]);
|
|
56736
|
+
function parseFrontmatter(content) {
|
|
56737
|
+
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
56738
|
+
if (!match) return null;
|
|
56739
|
+
const fm = {};
|
|
56740
|
+
for (const line of match[1].split("\n")) {
|
|
56741
|
+
const colon = line.indexOf(":");
|
|
56742
|
+
if (colon === -1) continue;
|
|
56743
|
+
const key = line.slice(0, colon).trim();
|
|
56744
|
+
const value = line.slice(colon + 1).trim().replace(/^["']|["']$/g, "");
|
|
56745
|
+
if (key) fm[key] = value;
|
|
56746
|
+
}
|
|
56747
|
+
return fm;
|
|
56748
|
+
}
|
|
56749
|
+
async function collectDocFiles(repoRoot, filterPattern) {
|
|
56750
|
+
const candidates = [];
|
|
56751
|
+
for (const name of ["README.md", "CHANGELOG.md"]) {
|
|
56752
|
+
const p = import_path20.default.join(repoRoot, name);
|
|
56753
|
+
if (await import_fs_extra19.default.pathExists(p)) candidates.push(p);
|
|
56754
|
+
}
|
|
56755
|
+
const docsDir = import_path20.default.join(repoRoot, "docs");
|
|
56756
|
+
if (await import_fs_extra19.default.pathExists(docsDir)) {
|
|
56757
|
+
const entries = await import_fs_extra19.default.readdir(docsDir);
|
|
56758
|
+
for (const entry of entries) {
|
|
56759
|
+
if (entry.endsWith(".md")) candidates.push(import_path20.default.join(docsDir, entry));
|
|
56760
|
+
}
|
|
56761
|
+
}
|
|
56762
|
+
const results = [];
|
|
56763
|
+
for (const filePath of candidates) {
|
|
56764
|
+
const rel = import_path20.default.relative(repoRoot, filePath);
|
|
56765
|
+
if (filterPattern && !rel.includes(filterPattern) && !import_path20.default.basename(filePath).includes(filterPattern)) {
|
|
56766
|
+
continue;
|
|
56767
|
+
}
|
|
56768
|
+
let entry;
|
|
56769
|
+
try {
|
|
56770
|
+
const stat = await import_fs_extra19.default.stat(filePath);
|
|
56771
|
+
const content = await import_fs_extra19.default.readFile(filePath, "utf8");
|
|
56772
|
+
const frontmatter = parseFrontmatter(content);
|
|
56773
|
+
entry = {
|
|
56774
|
+
filePath,
|
|
56775
|
+
relativePath: rel,
|
|
56776
|
+
frontmatter,
|
|
56777
|
+
sizeBytes: stat.size,
|
|
56778
|
+
lastModified: stat.mtime
|
|
56779
|
+
};
|
|
56780
|
+
} catch (err) {
|
|
56781
|
+
entry = {
|
|
56782
|
+
filePath,
|
|
56783
|
+
relativePath: rel,
|
|
56784
|
+
frontmatter: null,
|
|
56785
|
+
sizeBytes: 0,
|
|
56786
|
+
lastModified: /* @__PURE__ */ new Date(0),
|
|
56787
|
+
parseError: err.message
|
|
56788
|
+
};
|
|
56789
|
+
}
|
|
56790
|
+
results.push(entry);
|
|
56791
|
+
}
|
|
56792
|
+
return results;
|
|
56793
|
+
}
|
|
56794
|
+
function formatSize(bytes) {
|
|
56795
|
+
if (bytes < 1024) return `${bytes}B`;
|
|
56796
|
+
return `${(bytes / 1024).toFixed(1)}KB`;
|
|
56797
|
+
}
|
|
56798
|
+
function formatDate(d) {
|
|
56799
|
+
return d.toISOString().slice(0, 10);
|
|
56800
|
+
}
|
|
56801
|
+
function printEntry(entry, raw) {
|
|
56802
|
+
const header = kleur_default.bold().white(entry.relativePath);
|
|
56803
|
+
const meta3 = kleur_default.gray(` ${formatSize(entry.sizeBytes)} modified ${formatDate(entry.lastModified)}`);
|
|
56804
|
+
console.log(`
|
|
56805
|
+
${header}${meta3}`);
|
|
56806
|
+
if (entry.parseError) {
|
|
56807
|
+
console.log(kleur_default.red(` \u2717 Error reading file: ${entry.parseError}`));
|
|
56808
|
+
return;
|
|
56809
|
+
}
|
|
56810
|
+
if (!entry.frontmatter || Object.keys(entry.frontmatter).length === 0) {
|
|
56811
|
+
console.log(kleur_default.gray(" (no frontmatter)"));
|
|
56812
|
+
return;
|
|
56813
|
+
}
|
|
56814
|
+
if (raw) {
|
|
56815
|
+
console.log(kleur_default.gray(" ---"));
|
|
56816
|
+
for (const [k, v] of Object.entries(entry.frontmatter)) {
|
|
56817
|
+
console.log(` ${k}: ${v}`);
|
|
56818
|
+
}
|
|
56819
|
+
console.log(kleur_default.gray(" ---"));
|
|
56820
|
+
return;
|
|
56821
|
+
}
|
|
56822
|
+
for (const [k, v] of Object.entries(entry.frontmatter)) {
|
|
56823
|
+
const keyStr = REQUIRED_FIELDS.has(k) ? kleur_default.cyan(k.padEnd(14)) : kleur_default.gray(k.padEnd(14));
|
|
56824
|
+
const valStr = v ?? "";
|
|
56825
|
+
console.log(` ${keyStr} ${valStr}`);
|
|
56826
|
+
}
|
|
56827
|
+
}
|
|
56828
|
+
function createDocsCommand() {
|
|
56829
|
+
const docs = new Command("docs").description("Documentation management commands");
|
|
56830
|
+
docs.command("show [filter]").description("Display frontmatters for README, CHANGELOG, and docs/ files").option("--raw", "Output raw YAML frontmatter", false).option("--json", "Output JSON", false).action(async (filter, opts) => {
|
|
56831
|
+
const repoRoot = await findRepoRoot();
|
|
56832
|
+
const entries = await collectDocFiles(repoRoot, filter);
|
|
56833
|
+
if (entries.length === 0) {
|
|
56834
|
+
console.log(kleur_default.yellow("\n No documentation files found.\n"));
|
|
56835
|
+
return;
|
|
56836
|
+
}
|
|
56837
|
+
if (opts.json) {
|
|
56838
|
+
const output = entries.map((e) => ({
|
|
56839
|
+
path: e.relativePath,
|
|
56840
|
+
sizeBytes: e.sizeBytes,
|
|
56841
|
+
lastModified: e.lastModified.toISOString(),
|
|
56842
|
+
frontmatter: e.frontmatter,
|
|
56843
|
+
parseError: e.parseError ?? null
|
|
56844
|
+
}));
|
|
56845
|
+
console.log(JSON.stringify(output, null, 2));
|
|
56846
|
+
return;
|
|
56847
|
+
}
|
|
56848
|
+
for (const entry of entries) {
|
|
56849
|
+
printEntry(entry, opts.raw);
|
|
56850
|
+
}
|
|
56851
|
+
const without = entries.filter((e) => !e.frontmatter || Object.keys(e.frontmatter).length === 0).length;
|
|
56852
|
+
console.log(
|
|
56853
|
+
`
|
|
56854
|
+
${sym.ok} ${entries.length} file${entries.length !== 1 ? "s" : ""}` + (without > 0 ? kleur_default.gray(` (${without} without frontmatter)`) : "") + "\n"
|
|
56855
|
+
);
|
|
56856
|
+
});
|
|
56857
|
+
return docs;
|
|
56858
|
+
}
|
|
56859
|
+
|
|
56860
|
+
// src/commands/debug.ts
|
|
56861
|
+
var import_node_child_process8 = require("child_process");
|
|
56862
|
+
var import_node_fs5 = require("fs");
|
|
56863
|
+
var import_node_path6 = require("path");
|
|
56864
|
+
var KIND_LABELS = {
|
|
56865
|
+
"session.start": { label: "SESS+", color: kleur_default.green },
|
|
56866
|
+
"session.end": { label: "SESS-", color: kleur_default.white },
|
|
56867
|
+
"gate.edit.allow": { label: "EDIT+", color: kleur_default.green },
|
|
56868
|
+
"gate.edit.block": { label: "EDIT-", color: kleur_default.red },
|
|
56869
|
+
"gate.commit.allow": { label: "CMIT+", color: kleur_default.green },
|
|
56870
|
+
"gate.commit.block": { label: "CMIT-", color: kleur_default.red },
|
|
56871
|
+
"gate.stop.block": { label: "STOP-", color: kleur_default.red },
|
|
56872
|
+
"gate.memory.triggered": { label: "MEMO-", color: kleur_default.yellow },
|
|
56873
|
+
"gate.memory.acked": { label: "MEMO+", color: kleur_default.green },
|
|
56874
|
+
"gate.worktree.block": { label: "WTRE-", color: kleur_default.red },
|
|
56875
|
+
"bd.claimed": { label: "CLMD ", color: kleur_default.cyan },
|
|
56876
|
+
"bd.closed": { label: "CLSD ", color: kleur_default.green },
|
|
56877
|
+
"bd.committed": {
|
|
56878
|
+
label: (outcome) => outcome === "error" ? "ACMT-" : "ACMT+",
|
|
56879
|
+
color: (outcome) => outcome === "error" ? kleur_default.red : kleur_default.cyan
|
|
56880
|
+
}
|
|
56881
|
+
};
|
|
56882
|
+
var TOOL_ABBREVS = {
|
|
56883
|
+
Bash: "BASH",
|
|
56884
|
+
bash: "BASH",
|
|
56885
|
+
execute_shell_command: "BASH",
|
|
56886
|
+
Read: "READ",
|
|
56887
|
+
Write: "WRIT",
|
|
56888
|
+
Edit: "EDIT",
|
|
56889
|
+
MultiEdit: "EDIT",
|
|
56890
|
+
NotebookEdit: "NTED",
|
|
56891
|
+
Glob: "GLOB",
|
|
56892
|
+
Grep: "GREP",
|
|
56893
|
+
WebFetch: "WBFT",
|
|
56894
|
+
WebSearch: "WSRC",
|
|
56895
|
+
Agent: "AGNT",
|
|
56896
|
+
Task: "TASK",
|
|
56897
|
+
LSP: "LSP "
|
|
56898
|
+
};
|
|
56899
|
+
function toolAbbrev(toolName) {
|
|
56900
|
+
if (TOOL_ABBREVS[toolName]) return TOOL_ABBREVS[toolName];
|
|
56901
|
+
if (toolName.startsWith("mcp__serena__")) return "SRNA";
|
|
56902
|
+
if (toolName.startsWith("mcp__gitnexus__")) return "GTNX";
|
|
56903
|
+
if (toolName.startsWith("mcp__deepwiki__")) return "WIKI";
|
|
56904
|
+
if (toolName.startsWith("mcp__")) return "MCP ";
|
|
56905
|
+
return toolName.slice(0, 4).toUpperCase();
|
|
56906
|
+
}
|
|
56907
|
+
function getLabel(event) {
|
|
56908
|
+
if (event.kind === "tool.call") {
|
|
56909
|
+
const abbrev = toolAbbrev(event.tool_name ?? "").padEnd(5);
|
|
56910
|
+
return event.outcome === "error" ? kleur_default.red(abbrev) : kleur_default.dim(abbrev);
|
|
56911
|
+
}
|
|
56912
|
+
const def = KIND_LABELS[event.kind];
|
|
56913
|
+
if (!def) {
|
|
56914
|
+
const seg = (event.kind.split(".").pop() ?? "UNKN").slice(0, 4).toUpperCase();
|
|
56915
|
+
const label = `${seg}${event.outcome === "block" ? "-" : "+"}`.padEnd(5);
|
|
56916
|
+
return event.outcome === "block" ? kleur_default.red(label) : kleur_default.dim(label);
|
|
56917
|
+
}
|
|
56918
|
+
if (event.kind === "bd.committed") {
|
|
56919
|
+
const label = event.outcome === "error" ? "ACMT-" : "ACMT+";
|
|
56920
|
+
return event.outcome === "error" ? kleur_default.red(label) : kleur_default.cyan(label);
|
|
56921
|
+
}
|
|
56922
|
+
return def.color(
|
|
56923
|
+
def.label
|
|
56924
|
+
);
|
|
56925
|
+
}
|
|
56926
|
+
var SESSION_COLORS = [
|
|
56927
|
+
kleur_default.blue,
|
|
56928
|
+
kleur_default.green,
|
|
56929
|
+
kleur_default.yellow,
|
|
56930
|
+
kleur_default.cyan,
|
|
56931
|
+
kleur_default.magenta
|
|
56932
|
+
];
|
|
56933
|
+
function buildColorMap(events) {
|
|
56934
|
+
const map2 = /* @__PURE__ */ new Map();
|
|
56935
|
+
for (const ev of events) {
|
|
56936
|
+
if (!map2.has(ev.session_id)) {
|
|
56937
|
+
map2.set(ev.session_id, SESSION_COLORS[map2.size % SESSION_COLORS.length]);
|
|
56938
|
+
}
|
|
56939
|
+
}
|
|
56940
|
+
return map2;
|
|
56941
|
+
}
|
|
56942
|
+
function extendColorMap(map2, events) {
|
|
56943
|
+
for (const ev of events) {
|
|
56944
|
+
if (!map2.has(ev.session_id)) {
|
|
56945
|
+
map2.set(ev.session_id, SESSION_COLORS[map2.size % SESSION_COLORS.length]);
|
|
56946
|
+
}
|
|
56947
|
+
}
|
|
56948
|
+
}
|
|
56949
|
+
function fmtTime(ts) {
|
|
56950
|
+
return new Date(ts).toLocaleTimeString("en-GB", { hour12: false });
|
|
56951
|
+
}
|
|
56952
|
+
function buildDetail(event) {
|
|
56953
|
+
const parts = [];
|
|
56954
|
+
let d = null;
|
|
56955
|
+
if (event.data) {
|
|
56956
|
+
try {
|
|
56957
|
+
d = JSON.parse(event.data);
|
|
56958
|
+
} catch {
|
|
56959
|
+
}
|
|
56960
|
+
}
|
|
56961
|
+
if (event.kind === "tool.call") {
|
|
56962
|
+
if (d?.cmd) parts.push(kleur_default.dim(d.cmd.slice(0, 72)));
|
|
56963
|
+
if (d?.file) parts.push(kleur_default.dim((0, import_node_path6.basename)(d.file)));
|
|
56964
|
+
if (d?.pattern) parts.push(kleur_default.dim(`/${d.pattern}/`));
|
|
56965
|
+
if (d?.url) parts.push(kleur_default.dim(d.url.slice(0, 72)));
|
|
56966
|
+
if (d?.query) parts.push(kleur_default.dim(d.query.slice(0, 72)));
|
|
56967
|
+
if (d?.prompt) parts.push(kleur_default.dim(d.prompt.slice(0, 72)));
|
|
56968
|
+
} else {
|
|
56969
|
+
if (event.issue_id) parts.push(kleur_default.yellow(event.issue_id));
|
|
56970
|
+
if (d?.file) parts.push(kleur_default.dim((0, import_node_path6.basename)(d.file)));
|
|
56971
|
+
if (d?.reason_code) parts.push(kleur_default.dim(`[${d.reason_code}]`));
|
|
56972
|
+
if (event.worktree) parts.push(kleur_default.dim(`wt:${event.worktree}`));
|
|
56973
|
+
}
|
|
56974
|
+
return parts.join(" ") || kleur_default.dim("\u2014");
|
|
56975
|
+
}
|
|
56976
|
+
function formatLine(event, colorMap) {
|
|
56977
|
+
const time3 = kleur_default.dim(fmtTime(event.ts));
|
|
56978
|
+
const colorFn = colorMap.get(event.session_id) ?? kleur_default.white;
|
|
56979
|
+
const session = colorFn(event.session_id.slice(0, 8));
|
|
56980
|
+
const label = getLabel(event);
|
|
56981
|
+
const detail = buildDetail(event);
|
|
56982
|
+
return `${time3} ${label} ${session} ${detail}`;
|
|
56983
|
+
}
|
|
56984
|
+
function findDbPath(cwd) {
|
|
56985
|
+
let dir = cwd;
|
|
56986
|
+
for (let i = 0; i < 10; i++) {
|
|
56987
|
+
if ((0, import_node_fs5.existsSync)((0, import_node_path6.join)(dir, ".beads"))) return (0, import_node_path6.join)(dir, ".xtrm", "debug.db");
|
|
56988
|
+
const parent = (0, import_node_path6.join)(dir, "..");
|
|
56989
|
+
if (parent === dir) break;
|
|
56990
|
+
dir = parent;
|
|
56991
|
+
}
|
|
56992
|
+
return null;
|
|
56993
|
+
}
|
|
56994
|
+
function buildWhere(opts, base) {
|
|
56995
|
+
const clauses = [];
|
|
56996
|
+
if (base) clauses.push(base);
|
|
56997
|
+
if (opts.session) {
|
|
56998
|
+
const s = opts.session.replace(/'/g, "''");
|
|
56999
|
+
clauses.push(`session_id LIKE '${s}%'`);
|
|
57000
|
+
}
|
|
57001
|
+
if (opts.type) {
|
|
57002
|
+
const t3 = opts.type.replace(/'/g, "''");
|
|
57003
|
+
clauses.push(`kind LIKE '${t3}.%' OR kind = '${t3}'`);
|
|
57004
|
+
}
|
|
57005
|
+
return clauses.length ? clauses.join(" AND ") : "";
|
|
57006
|
+
}
|
|
57007
|
+
function queryEvents(dbPath, where, limit) {
|
|
57008
|
+
const sql = `SELECT id,ts,session_id,runtime,worktree,kind,tool_name,outcome,issue_id,duration_ms,data FROM events${where ? ` WHERE ${where}` : ""} ORDER BY id ASC LIMIT ${limit}`;
|
|
57009
|
+
const result = (0, import_node_child_process8.spawnSync)("sqlite3", [dbPath, "-json", sql], {
|
|
57010
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
57011
|
+
encoding: "utf8",
|
|
57012
|
+
timeout: 5e3
|
|
57013
|
+
});
|
|
57014
|
+
if (result.status !== 0 || !result.stdout.trim()) return [];
|
|
57015
|
+
try {
|
|
57016
|
+
return JSON.parse(result.stdout);
|
|
57017
|
+
} catch {
|
|
57018
|
+
return [];
|
|
57019
|
+
}
|
|
57020
|
+
}
|
|
57021
|
+
function follow(dbPath, opts) {
|
|
57022
|
+
const sinceTs = Date.now() - 5 * 60 * 1e3;
|
|
57023
|
+
const initial = queryEvents(dbPath, buildWhere(opts, `ts >= ${sinceTs}`), 200);
|
|
57024
|
+
const colorMap = buildColorMap(initial);
|
|
57025
|
+
let lastId = 0;
|
|
57026
|
+
for (const ev of initial) {
|
|
57027
|
+
if (ev.id > lastId) lastId = ev.id;
|
|
57028
|
+
opts.json ? console.log(JSON.stringify(ev)) : console.log(formatLine(ev, colorMap));
|
|
57029
|
+
}
|
|
57030
|
+
const interval = setInterval(() => {
|
|
57031
|
+
const events = queryEvents(dbPath, buildWhere(opts, `id > ${lastId}`), 50);
|
|
57032
|
+
if (events.length > 0) {
|
|
57033
|
+
extendColorMap(colorMap, events);
|
|
57034
|
+
for (const ev of events) {
|
|
57035
|
+
if (ev.id > lastId) lastId = ev.id;
|
|
57036
|
+
opts.json ? console.log(JSON.stringify(ev)) : console.log(formatLine(ev, colorMap));
|
|
57037
|
+
}
|
|
57038
|
+
}
|
|
57039
|
+
}, 2e3);
|
|
57040
|
+
process.on("SIGINT", () => {
|
|
57041
|
+
clearInterval(interval);
|
|
57042
|
+
process.exit(0);
|
|
57043
|
+
});
|
|
57044
|
+
}
|
|
57045
|
+
function createDebugCommand() {
|
|
57046
|
+
return new Command("debug").description("Watch xtrm events: tool calls, gate decisions, bd lifecycle").option("-f, --follow", "Follow new events (default)", false).option("--all", "Show full history and exit", false).option("--session <id>", "Filter by session ID (prefix match)").option("--type <domain>", "Filter by domain: tool | gate | bd | session").option("--json", "Output raw JSON lines", false).action((opts) => {
|
|
57047
|
+
const cwd = process.cwd();
|
|
57048
|
+
const dbPath = findDbPath(cwd);
|
|
57049
|
+
if (!dbPath || !(0, import_node_fs5.existsSync)(dbPath)) return;
|
|
57050
|
+
if (opts.all) {
|
|
57051
|
+
const events = queryEvents(dbPath, buildWhere(opts, ""), 1e3);
|
|
57052
|
+
const colorMap = buildColorMap(events);
|
|
57053
|
+
for (const ev of events) {
|
|
57054
|
+
opts.json ? console.log(JSON.stringify(ev)) : console.log(formatLine(ev, colorMap));
|
|
57055
|
+
}
|
|
57056
|
+
return;
|
|
57057
|
+
}
|
|
57058
|
+
follow(dbPath, opts);
|
|
57059
|
+
});
|
|
57060
|
+
}
|
|
57061
|
+
|
|
57154
57062
|
// src/utils/banner.ts
|
|
57155
57063
|
var ART = [
|
|
57156
57064
|
" \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2557",
|
|
@@ -57218,7 +57126,7 @@ function pressAnyKey() {
|
|
|
57218
57126
|
setTimeout(finish, 4e3);
|
|
57219
57127
|
});
|
|
57220
57128
|
}
|
|
57221
|
-
function
|
|
57129
|
+
function delay2(ms) {
|
|
57222
57130
|
return new Promise((r) => setTimeout(r, ms));
|
|
57223
57131
|
}
|
|
57224
57132
|
async function typewriterTagline(text) {
|
|
@@ -57228,7 +57136,7 @@ async function typewriterTagline(text) {
|
|
|
57228
57136
|
process.stdout.write(prefix);
|
|
57229
57137
|
for (const ch of text) {
|
|
57230
57138
|
process.stdout.write(ch);
|
|
57231
|
-
await
|
|
57139
|
+
await delay2(CHAR_DELAY);
|
|
57232
57140
|
}
|
|
57233
57141
|
process.stdout.write(suffix + "\n");
|
|
57234
57142
|
}
|
|
@@ -57249,8 +57157,8 @@ function gradientLine(line) {
|
|
|
57249
57157
|
let out = "";
|
|
57250
57158
|
const len = line.length;
|
|
57251
57159
|
for (let i = 0; i < len; i++) {
|
|
57252
|
-
const
|
|
57253
|
-
const hue = HUE_START +
|
|
57160
|
+
const t3 = len > 1 ? i / (len - 1) : 0;
|
|
57161
|
+
const hue = HUE_START + t3 * (HUE_END - HUE_START);
|
|
57254
57162
|
const [r, g, b] = hslToRgb(hue, SAT, LIG);
|
|
57255
57163
|
out += `\x1B[38;2;${r};${g};${b}m` + line[i];
|
|
57256
57164
|
}
|
|
@@ -57346,9 +57254,10 @@ program2.command("init").description("Alias for xtrm project init").action(async
|
|
|
57346
57254
|
program2.addCommand(createStatusCommand());
|
|
57347
57255
|
program2.addCommand(createResetCommand());
|
|
57348
57256
|
program2.addCommand(createCleanCommand());
|
|
57349
|
-
program2.addCommand(createFinishCommand());
|
|
57350
57257
|
program2.addCommand(createEndCommand());
|
|
57351
57258
|
program2.addCommand(createWorktreeCommand());
|
|
57259
|
+
program2.addCommand(createDocsCommand());
|
|
57260
|
+
program2.addCommand(createDebugCommand());
|
|
57352
57261
|
program2.addCommand(createHelpCommand());
|
|
57353
57262
|
program2.action(async () => {
|
|
57354
57263
|
program2.help();
|
|
@@ -57369,8 +57278,9 @@ process.on("unhandledRejection", (reason) => {
|
|
|
57369
57278
|
process.exit(1);
|
|
57370
57279
|
});
|
|
57371
57280
|
var isHelpOrVersion = process.argv.some((a) => a === "--help" || a === "-h" || a === "--version" || a === "-V");
|
|
57281
|
+
var isInstallCommand = (process.argv[2] ?? "") === "install";
|
|
57372
57282
|
(async () => {
|
|
57373
|
-
if (!isHelpOrVersion) {
|
|
57283
|
+
if (!isHelpOrVersion && isInstallCommand) {
|
|
57374
57284
|
await printBanner(version2);
|
|
57375
57285
|
}
|
|
57376
57286
|
program2.parseAsync(process.argv);
|