terminal-pilot 0.0.19 → 0.0.20
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/dist/cli.js +537 -242
- package/dist/cli.js.map +4 -4
- package/dist/commands/index.js +261 -37
- package/dist/commands/index.js.map +3 -3
- package/dist/commands/install.js +261 -37
- package/dist/commands/install.js.map +3 -3
- package/dist/commands/installer.js.map +1 -1
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/testing/cli-repl.js +533 -238
- package/dist/testing/cli-repl.js.map +4 -4
- package/dist/testing/qa-cli.js +543 -248
- package/dist/testing/qa-cli.js.map +4 -4
- package/node_modules/@poe-code/agent-skill-config/README.md +103 -0
- package/node_modules/@poe-code/agent-skill-config/dist/apply.d.ts +25 -0
- package/node_modules/@poe-code/agent-skill-config/dist/apply.js +159 -0
- package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.d.ts +23 -0
- package/node_modules/@poe-code/agent-skill-config/dist/bridge-active-skills.js +341 -0
- package/node_modules/@poe-code/agent-skill-config/dist/configs.d.ts +16 -0
- package/node_modules/@poe-code/agent-skill-config/dist/configs.js +70 -0
- package/node_modules/@poe-code/agent-skill-config/dist/exports.compile-check.d.ts +1 -0
- package/node_modules/@poe-code/agent-skill-config/dist/exports.compile-check.js +1 -0
- package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.d.ts +8 -0
- package/node_modules/@poe-code/agent-skill-config/dist/git-exclude.js +159 -0
- package/node_modules/@poe-code/agent-skill-config/dist/index.d.ts +11 -0
- package/node_modules/@poe-code/agent-skill-config/dist/index.js +6 -0
- package/node_modules/@poe-code/agent-skill-config/dist/resolve-skill-reference.d.ts +22 -0
- package/node_modules/@poe-code/agent-skill-config/dist/resolve-skill-reference.js +87 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates/poe-generate.md +47 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates/terminal-pilot.md +45 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates.d.ts +3 -0
- package/node_modules/@poe-code/agent-skill-config/dist/templates.js +63 -0
- package/node_modules/@poe-code/agent-skill-config/dist/types.d.ts +16 -0
- package/node_modules/@poe-code/agent-skill-config/dist/types.js +1 -0
- package/node_modules/@poe-code/agent-skill-config/package.json +24 -0
- package/package.json +3 -2
package/dist/cli.js
CHANGED
|
@@ -7,12 +7,12 @@ var __export = (target, all) => {
|
|
|
7
7
|
|
|
8
8
|
// src/cli.ts
|
|
9
9
|
import { realpath as realpath2 } from "node:fs/promises";
|
|
10
|
-
import
|
|
10
|
+
import path23 from "node:path";
|
|
11
11
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
12
12
|
|
|
13
13
|
// ../toolcraft/src/cli.ts
|
|
14
14
|
import { access as access2, lstat as lstat3, readFile as readFile4, rename as rename3, unlink as unlink2, writeFile as writeFile5 } from "node:fs/promises";
|
|
15
|
-
import
|
|
15
|
+
import path14 from "node:path";
|
|
16
16
|
import {
|
|
17
17
|
Command as CommanderCommand,
|
|
18
18
|
CommanderError as CommanderError2,
|
|
@@ -1278,6 +1278,7 @@ ${options.theme.muted(options.badges.map((badge) => badge[0] + badge.slice(1).to
|
|
|
1278
1278
|
}
|
|
1279
1279
|
|
|
1280
1280
|
// ../design-system/src/components/template.ts
|
|
1281
|
+
var MAX_PARTIAL_DEPTH = 100;
|
|
1281
1282
|
var HTML_ESCAPE = {
|
|
1282
1283
|
"&": "&",
|
|
1283
1284
|
"<": "<",
|
|
@@ -1289,14 +1290,27 @@ var HTML_ESCAPE = {
|
|
|
1289
1290
|
"=": "="
|
|
1290
1291
|
};
|
|
1291
1292
|
function renderTemplate(template, view, options = {}) {
|
|
1292
|
-
const prepared = options.yield === void 0 ? template : template.split("{{yield}}").join(options.yield);
|
|
1293
|
+
const prepared = options.yield === void 0 ? template : resolveTemplatePartials(template, options.partials ?? {}).split("{{yield}}").join(options.yield);
|
|
1293
1294
|
const tokens = parseTemplate(prepared);
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1295
|
+
validatePartialReferences(tokens, options.partials ?? {}, []);
|
|
1296
|
+
if (options.validate === true) {
|
|
1297
|
+
const expanded = resolveTemplatePartials(prepared, options.partials ?? {});
|
|
1298
|
+
validateVariables(parseTemplate(expanded), { view });
|
|
1299
|
+
}
|
|
1300
|
+
const state = {
|
|
1301
|
+
escape: options.escape === "none" ? String : escapeHtml,
|
|
1302
|
+
partials: options.partials ?? {},
|
|
1303
|
+
partialStack: [],
|
|
1304
|
+
preserveMissing: options.yield !== void 0 && options.escape === "none",
|
|
1305
|
+
validate: options.validate === true
|
|
1306
|
+
};
|
|
1307
|
+
return renderTokens(tokens, { view }, prepared, state);
|
|
1308
|
+
}
|
|
1309
|
+
function resolveTemplatePartials(template, partials) {
|
|
1310
|
+
return expandTemplatePartials(template, partials, []);
|
|
1297
1311
|
}
|
|
1298
|
-
function renderTemplateInContext(template, context,
|
|
1299
|
-
return renderTokens(parseTemplate(template), context, template,
|
|
1312
|
+
function renderTemplateInContext(template, context, state) {
|
|
1313
|
+
return renderTokens(parseTemplate(template), context, template, state);
|
|
1300
1314
|
}
|
|
1301
1315
|
function parseTemplate(template) {
|
|
1302
1316
|
const root = [];
|
|
@@ -1319,9 +1333,6 @@ function parseTemplate(template) {
|
|
|
1319
1333
|
index = standalone?.nextIndex ?? parsed.end;
|
|
1320
1334
|
continue;
|
|
1321
1335
|
}
|
|
1322
|
-
if (parsed.kind === "partial") {
|
|
1323
|
-
throw new Error(`Partials are not supported: "${parsed.name}"`);
|
|
1324
|
-
}
|
|
1325
1336
|
if (parsed.kind === "delimiter") {
|
|
1326
1337
|
throw new Error("Custom delimiters are not supported");
|
|
1327
1338
|
}
|
|
@@ -1339,6 +1350,15 @@ function parseTemplate(template) {
|
|
|
1339
1350
|
index = standalone?.nextIndex ?? parsed.end;
|
|
1340
1351
|
continue;
|
|
1341
1352
|
}
|
|
1353
|
+
if (parsed.kind === "partial") {
|
|
1354
|
+
tokens.push({
|
|
1355
|
+
type: "partial",
|
|
1356
|
+
name: parsed.name,
|
|
1357
|
+
indent: standalone === void 0 ? "" : template.slice(standalone.lineStart, open)
|
|
1358
|
+
});
|
|
1359
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
1360
|
+
continue;
|
|
1361
|
+
}
|
|
1342
1362
|
if (parsed.kind === "close") {
|
|
1343
1363
|
const frame2 = stack.pop();
|
|
1344
1364
|
if (frame2 === void 0) {
|
|
@@ -1409,7 +1429,7 @@ function getStandalone(template, tagStart, tagEnd, kind) {
|
|
|
1409
1429
|
}
|
|
1410
1430
|
return void 0;
|
|
1411
1431
|
}
|
|
1412
|
-
function renderTokens(tokens, context, template,
|
|
1432
|
+
function renderTokens(tokens, context, template, state) {
|
|
1413
1433
|
let output = "";
|
|
1414
1434
|
for (const token of tokens) {
|
|
1415
1435
|
switch (token.type) {
|
|
@@ -1418,32 +1438,62 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1418
1438
|
continue;
|
|
1419
1439
|
case "name":
|
|
1420
1440
|
case "unescaped": {
|
|
1421
|
-
const
|
|
1422
|
-
if (value == null) {
|
|
1423
|
-
if (
|
|
1441
|
+
const result = lookup(context, token.name);
|
|
1442
|
+
if (!result.hit || result.value == null) {
|
|
1443
|
+
if (state.validate) {
|
|
1444
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1445
|
+
}
|
|
1446
|
+
if (state.preserveMissing) {
|
|
1424
1447
|
output += token.raw;
|
|
1425
1448
|
}
|
|
1426
1449
|
continue;
|
|
1427
1450
|
}
|
|
1428
|
-
const rendered = String(value);
|
|
1429
|
-
output += token.type === "name" ? escape(rendered) : rendered;
|
|
1451
|
+
const rendered = String(result.value);
|
|
1452
|
+
output += token.type === "name" ? state.escape(rendered) : rendered;
|
|
1453
|
+
continue;
|
|
1454
|
+
}
|
|
1455
|
+
case "partial": {
|
|
1456
|
+
if (!Object.hasOwn(state.partials, token.name)) {
|
|
1457
|
+
throw new Error(`Partial "${token.name}" not found.`);
|
|
1458
|
+
}
|
|
1459
|
+
if (state.partialStack.includes(token.name)) {
|
|
1460
|
+
throw new Error(
|
|
1461
|
+
`Circular partial reference detected: ${[...state.partialStack, token.name].join(" -> ")}.`
|
|
1462
|
+
);
|
|
1463
|
+
}
|
|
1464
|
+
if (state.partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1465
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1466
|
+
}
|
|
1467
|
+
const partial = indentPartial(state.partials[token.name], token.indent);
|
|
1468
|
+
output += renderTokens(parseTemplate(partial), context, partial, {
|
|
1469
|
+
...state,
|
|
1470
|
+
partialStack: [...state.partialStack, token.name]
|
|
1471
|
+
});
|
|
1430
1472
|
continue;
|
|
1431
1473
|
}
|
|
1432
1474
|
case "inverted": {
|
|
1433
|
-
const
|
|
1475
|
+
const result = lookup(context, token.name);
|
|
1476
|
+
if (!result.hit && state.validate) {
|
|
1477
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1478
|
+
}
|
|
1479
|
+
const value = result.value;
|
|
1434
1480
|
if (!value || Array.isArray(value) && value.length === 0) {
|
|
1435
|
-
output += renderTokens(token.children, context, template,
|
|
1481
|
+
output += renderTokens(token.children, context, template, state);
|
|
1436
1482
|
}
|
|
1437
1483
|
continue;
|
|
1438
1484
|
}
|
|
1439
1485
|
case "section": {
|
|
1440
|
-
const
|
|
1486
|
+
const result = lookup(context, token.name);
|
|
1487
|
+
if (!result.hit && state.validate) {
|
|
1488
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1489
|
+
}
|
|
1490
|
+
const value = result.value;
|
|
1441
1491
|
if (!value) {
|
|
1442
1492
|
continue;
|
|
1443
1493
|
}
|
|
1444
1494
|
if (Array.isArray(value)) {
|
|
1445
1495
|
for (const item of value) {
|
|
1446
|
-
output += renderTokens(token.children, pushContext(context, item), template,
|
|
1496
|
+
output += renderTokens(token.children, pushContext(context, item), template, state);
|
|
1447
1497
|
}
|
|
1448
1498
|
continue;
|
|
1449
1499
|
}
|
|
@@ -1452,7 +1502,7 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1452
1502
|
const rendered = value.call(
|
|
1453
1503
|
context.view,
|
|
1454
1504
|
raw,
|
|
1455
|
-
(nextTemplate) => renderTemplateInContext(nextTemplate, context,
|
|
1505
|
+
(nextTemplate) => renderTemplateInContext(nextTemplate, context, state)
|
|
1456
1506
|
);
|
|
1457
1507
|
if (rendered != null) {
|
|
1458
1508
|
output += String(rendered);
|
|
@@ -1460,10 +1510,10 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1460
1510
|
continue;
|
|
1461
1511
|
}
|
|
1462
1512
|
if (typeof value === "object" || typeof value === "string" || typeof value === "number") {
|
|
1463
|
-
output += renderTokens(token.children, pushContext(context, value), template,
|
|
1513
|
+
output += renderTokens(token.children, pushContext(context, value), template, state);
|
|
1464
1514
|
continue;
|
|
1465
1515
|
}
|
|
1466
|
-
output += renderTokens(token.children, context, template,
|
|
1516
|
+
output += renderTokens(token.children, context, template, state);
|
|
1467
1517
|
}
|
|
1468
1518
|
}
|
|
1469
1519
|
}
|
|
@@ -1471,17 +1521,115 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
1471
1521
|
}
|
|
1472
1522
|
function lookup(context, name) {
|
|
1473
1523
|
if (name === ".") {
|
|
1474
|
-
return callLambda(context.view, context.view);
|
|
1524
|
+
return { hit: true, value: callLambda(context.view, context.view) };
|
|
1475
1525
|
}
|
|
1476
1526
|
let cursor = context;
|
|
1477
1527
|
while (cursor !== void 0) {
|
|
1478
1528
|
const result = name.includes(".") ? lookupDotted(cursor.view, name) : lookupName(cursor.view, name);
|
|
1479
1529
|
if (result.hit) {
|
|
1480
|
-
return callLambda(result.value, cursor.view);
|
|
1530
|
+
return { hit: true, value: callLambda(result.value, cursor.view) };
|
|
1481
1531
|
}
|
|
1482
1532
|
cursor = cursor.parent;
|
|
1483
1533
|
}
|
|
1484
|
-
return void 0;
|
|
1534
|
+
return { hit: false, value: void 0 };
|
|
1535
|
+
}
|
|
1536
|
+
function validateVariables(tokens, context) {
|
|
1537
|
+
for (const token of tokens) {
|
|
1538
|
+
if (token.type === "text" || token.type === "partial") {
|
|
1539
|
+
continue;
|
|
1540
|
+
}
|
|
1541
|
+
if (token.type === "name" || token.type === "unescaped") {
|
|
1542
|
+
if (!lookup(context, token.name).hit) {
|
|
1543
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1544
|
+
}
|
|
1545
|
+
continue;
|
|
1546
|
+
}
|
|
1547
|
+
if (token.type !== "section" && token.type !== "inverted") {
|
|
1548
|
+
continue;
|
|
1549
|
+
}
|
|
1550
|
+
const result = lookup(context, token.name);
|
|
1551
|
+
if (!result.hit) {
|
|
1552
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
1553
|
+
}
|
|
1554
|
+
if (Array.isArray(result.value) && result.value.length > 0) {
|
|
1555
|
+
for (const item of result.value) {
|
|
1556
|
+
validateVariables(token.children, pushContext(context, item));
|
|
1557
|
+
}
|
|
1558
|
+
continue;
|
|
1559
|
+
}
|
|
1560
|
+
if (typeof result.value === "object" && result.value !== null || typeof result.value === "string" || typeof result.value === "number") {
|
|
1561
|
+
validateVariables(token.children, pushContext(context, result.value));
|
|
1562
|
+
continue;
|
|
1563
|
+
}
|
|
1564
|
+
validateVariables(token.children, context);
|
|
1565
|
+
}
|
|
1566
|
+
}
|
|
1567
|
+
function validatePartialReferences(tokens, partials, partialStack) {
|
|
1568
|
+
for (const token of tokens) {
|
|
1569
|
+
if (token.type === "section" || token.type === "inverted") {
|
|
1570
|
+
validatePartialReferences(token.children, partials, partialStack);
|
|
1571
|
+
continue;
|
|
1572
|
+
}
|
|
1573
|
+
if (token.type !== "partial") {
|
|
1574
|
+
continue;
|
|
1575
|
+
}
|
|
1576
|
+
if (!Object.hasOwn(partials, token.name)) {
|
|
1577
|
+
throw new Error(`Partial "${token.name}" not found.`);
|
|
1578
|
+
}
|
|
1579
|
+
if (partialStack.includes(token.name)) {
|
|
1580
|
+
throw new Error(
|
|
1581
|
+
`Circular partial reference detected: ${[...partialStack, token.name].join(" -> ")}.`
|
|
1582
|
+
);
|
|
1583
|
+
}
|
|
1584
|
+
if (partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1585
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1586
|
+
}
|
|
1587
|
+
validatePartialReferences(parseTemplate(partials[token.name]), partials, [
|
|
1588
|
+
...partialStack,
|
|
1589
|
+
token.name
|
|
1590
|
+
]);
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
function indentPartial(partial, indent) {
|
|
1594
|
+
if (indent === "") {
|
|
1595
|
+
return partial;
|
|
1596
|
+
}
|
|
1597
|
+
return partial.split("\n").map((line) => line === "" ? "" : `${indent}${line}`).join("\n");
|
|
1598
|
+
}
|
|
1599
|
+
function expandTemplatePartials(template, partials, partialStack) {
|
|
1600
|
+
let output = "";
|
|
1601
|
+
let index = 0;
|
|
1602
|
+
while (index < template.length) {
|
|
1603
|
+
const open = template.indexOf("{{", index);
|
|
1604
|
+
if (open === -1) {
|
|
1605
|
+
output += template.slice(index);
|
|
1606
|
+
break;
|
|
1607
|
+
}
|
|
1608
|
+
const parsed = parseTag(template, open);
|
|
1609
|
+
if (parsed.kind !== "partial") {
|
|
1610
|
+
output += template.slice(index, parsed.end);
|
|
1611
|
+
index = parsed.end;
|
|
1612
|
+
continue;
|
|
1613
|
+
}
|
|
1614
|
+
if (!Object.hasOwn(partials, parsed.name)) {
|
|
1615
|
+
throw new Error(`Partial "${parsed.name}" not found.`);
|
|
1616
|
+
}
|
|
1617
|
+
if (partialStack.includes(parsed.name)) {
|
|
1618
|
+
throw new Error(
|
|
1619
|
+
`Circular partial reference detected: ${[...partialStack, parsed.name].join(" -> ")}.`
|
|
1620
|
+
);
|
|
1621
|
+
}
|
|
1622
|
+
if (partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
1623
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
1624
|
+
}
|
|
1625
|
+
const standalone = getStandalone(template, open, parsed.end, parsed.kind);
|
|
1626
|
+
const beforePartial = standalone === void 0 ? template.slice(index, open) : template.slice(index, standalone.lineStart);
|
|
1627
|
+
const indent = standalone === void 0 ? "" : template.slice(standalone.lineStart, open);
|
|
1628
|
+
const partial = indentPartial(partials[parsed.name], indent);
|
|
1629
|
+
output += beforePartial + expandTemplatePartials(partial, partials, [...partialStack, parsed.name]);
|
|
1630
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
1631
|
+
}
|
|
1632
|
+
return output;
|
|
1485
1633
|
}
|
|
1486
1634
|
function lookupName(view, name) {
|
|
1487
1635
|
if (!isPropertyContainer(view) || !hasProperty(view, name)) {
|
|
@@ -2602,17 +2750,22 @@ import { randomBytes } from "node:crypto";
|
|
|
2602
2750
|
// ../process-runner/src/docker/args.ts
|
|
2603
2751
|
import path2 from "node:path";
|
|
2604
2752
|
|
|
2753
|
+
// ../process-runner/src/docker/env-file.ts
|
|
2754
|
+
import { mkdtempSync, rmSync, writeFileSync } from "node:fs";
|
|
2755
|
+
import { tmpdir } from "node:os";
|
|
2756
|
+
import path3 from "node:path";
|
|
2757
|
+
|
|
2605
2758
|
// ../process-runner/src/docker/docker-execution-env.ts
|
|
2606
2759
|
import { createHash as createHash2, randomBytes as randomBytes2 } from "node:crypto";
|
|
2607
|
-
import { mkdtempSync, rmSync } from "node:fs";
|
|
2760
|
+
import { mkdtempSync as mkdtempSync2, rmSync as rmSync2 } from "node:fs";
|
|
2608
2761
|
import { readdir, readFile, writeFile } from "node:fs/promises";
|
|
2609
|
-
import { tmpdir } from "node:os";
|
|
2610
|
-
import
|
|
2762
|
+
import { tmpdir as tmpdir2 } from "node:os";
|
|
2763
|
+
import path5 from "node:path";
|
|
2611
2764
|
|
|
2612
2765
|
// ../process-runner/src/host/host-runner.ts
|
|
2613
2766
|
import { spawn as spawnChildProcess } from "node:child_process";
|
|
2614
2767
|
function createHostRunner(options = {}) {
|
|
2615
|
-
const
|
|
2768
|
+
const detachedByDefault = options.detached === true;
|
|
2616
2769
|
return {
|
|
2617
2770
|
name: "host",
|
|
2618
2771
|
exec(spec) {
|
|
@@ -2630,18 +2783,19 @@ function createHostRunner(options = {}) {
|
|
|
2630
2783
|
const stdinMode = spec.stdin ?? "ignore";
|
|
2631
2784
|
const stdoutMode = spec.stdout ?? "pipe";
|
|
2632
2785
|
const stderrMode = spec.stderr ?? "pipe";
|
|
2786
|
+
const killProcessGroup = detachedByDefault || spec.killProcessGroup === true;
|
|
2633
2787
|
const stdio = stdinMode === "inherit" && stdoutMode === "inherit" && stderrMode === "inherit" ? "inherit" : [stdinMode, stdoutMode, stderrMode];
|
|
2634
2788
|
const child = spawnChildProcess(spec.command, spec.args ?? [], {
|
|
2635
2789
|
cwd: spec.cwd,
|
|
2636
2790
|
env: spec.env,
|
|
2637
2791
|
stdio,
|
|
2638
|
-
...
|
|
2792
|
+
...killProcessGroup ? { detached: true } : {}
|
|
2639
2793
|
});
|
|
2640
|
-
if (
|
|
2794
|
+
if (killProcessGroup) {
|
|
2641
2795
|
child.unref();
|
|
2642
2796
|
}
|
|
2643
2797
|
const kill = (signal) => {
|
|
2644
|
-
if (
|
|
2798
|
+
if (killProcessGroup && process.platform !== "win32" && child.pid !== void 0) {
|
|
2645
2799
|
process.kill(-child.pid, signal);
|
|
2646
2800
|
return;
|
|
2647
2801
|
}
|
|
@@ -2699,9 +2853,9 @@ function bindAbortSignal(signal, onAbort) {
|
|
|
2699
2853
|
}
|
|
2700
2854
|
|
|
2701
2855
|
// ../process-runner/src/workspace-transfer.ts
|
|
2702
|
-
import { createHash } from "node:crypto";
|
|
2856
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2703
2857
|
import { promises as nodeFs } from "node:fs";
|
|
2704
|
-
import
|
|
2858
|
+
import path4 from "node:path";
|
|
2705
2859
|
|
|
2706
2860
|
// ../process-runner/src/testing/mock-runner.ts
|
|
2707
2861
|
import { Readable, Writable } from "node:stream";
|
|
@@ -2772,7 +2926,7 @@ function resolveEndpoint(options = {}) {
|
|
|
2772
2926
|
}
|
|
2773
2927
|
|
|
2774
2928
|
// ../task-list/src/backends/utils.ts
|
|
2775
|
-
import
|
|
2929
|
+
import path6 from "node:path";
|
|
2776
2930
|
function compareCreated(left, right) {
|
|
2777
2931
|
const leftCreated = typeof left.raw.created === "string" ? left.raw.created : "";
|
|
2778
2932
|
const rightCreated = typeof right.raw.created === "string" ? right.raw.created : "";
|
|
@@ -2822,12 +2976,12 @@ async function statIfExists(fs4, filePath) {
|
|
|
2822
2976
|
}
|
|
2823
2977
|
}
|
|
2824
2978
|
async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
2825
|
-
const resolvedPath =
|
|
2826
|
-
const rootPath =
|
|
2827
|
-
const components = resolvedPath.slice(rootPath.length).split(
|
|
2979
|
+
const resolvedPath = path6.resolve(filePath);
|
|
2980
|
+
const rootPath = path6.parse(resolvedPath).root;
|
|
2981
|
+
const components = resolvedPath.slice(rootPath.length).split(path6.sep).filter(Boolean);
|
|
2828
2982
|
let currentPath = rootPath;
|
|
2829
2983
|
for (const component of components) {
|
|
2830
|
-
currentPath =
|
|
2984
|
+
currentPath = path6.join(currentPath, component);
|
|
2831
2985
|
try {
|
|
2832
2986
|
if ((await fs4.lstat(currentPath)).isSymbolicLink()) {
|
|
2833
2987
|
throw new Error(`Path "${filePath}" contains a symbolic link.`);
|
|
@@ -2843,7 +2997,7 @@ async function rejectSymbolicLinkComponents(fs4, filePath) {
|
|
|
2843
2997
|
async function writeAtomically(fs4, filePath, content) {
|
|
2844
2998
|
const tempPath = `${filePath}.tmp-${process.pid}-${tmpFileCounter}`;
|
|
2845
2999
|
tmpFileCounter += 1;
|
|
2846
|
-
await fs4.mkdir(
|
|
3000
|
+
await fs4.mkdir(path6.dirname(filePath), { recursive: true });
|
|
2847
3001
|
try {
|
|
2848
3002
|
await fs4.writeFile(tempPath, content, { encoding: "utf8", flag: "wx" });
|
|
2849
3003
|
await fs4.rename(tempPath, filePath);
|
|
@@ -2859,7 +3013,7 @@ async function writeAtomically(fs4, filePath, content) {
|
|
|
2859
3013
|
}
|
|
2860
3014
|
}
|
|
2861
3015
|
async function withFileLock(fs4, lockPath, operation) {
|
|
2862
|
-
await fs4.mkdir(
|
|
3016
|
+
await fs4.mkdir(path6.dirname(lockPath), { recursive: true });
|
|
2863
3017
|
for (; ; ) {
|
|
2864
3018
|
try {
|
|
2865
3019
|
await fs4.writeFile(lockPath, String(process.pid), { encoding: "utf8", flag: "wx" });
|
|
@@ -3946,7 +4100,7 @@ function parseQualifiedId(qualifiedId, listName) {
|
|
|
3946
4100
|
}
|
|
3947
4101
|
|
|
3948
4102
|
// ../task-list/src/backends/markdown-dir.ts
|
|
3949
|
-
import
|
|
4103
|
+
import path7 from "node:path";
|
|
3950
4104
|
import { parseDocument, stringify } from "yaml";
|
|
3951
4105
|
|
|
3952
4106
|
// ../task-list/src/schema/task.schema.json
|
|
@@ -4065,16 +4219,16 @@ function parseQualifiedId2(qualifiedId) {
|
|
|
4065
4219
|
};
|
|
4066
4220
|
}
|
|
4067
4221
|
function listPath(rootPath, layout, list) {
|
|
4068
|
-
return layout.kind === "single" ? rootPath :
|
|
4222
|
+
return layout.kind === "single" ? rootPath : path7.join(rootPath, list);
|
|
4069
4223
|
}
|
|
4070
4224
|
function archiveDirectoryPath(rootPath, layout, list) {
|
|
4071
|
-
return layout.kind === "single" ?
|
|
4225
|
+
return layout.kind === "single" ? path7.join(rootPath, ARCHIVE_DIRECTORY_NAME) : path7.join(rootPath, list, ARCHIVE_DIRECTORY_NAME);
|
|
4072
4226
|
}
|
|
4073
4227
|
function activeTaskFilename(id, order, width) {
|
|
4074
4228
|
return `${String(order).padStart(width, "0")}-${id}${MARKDOWN_EXTENSION}`;
|
|
4075
4229
|
}
|
|
4076
4230
|
function archivedTaskPath(rootPath, layout, list, id) {
|
|
4077
|
-
return
|
|
4231
|
+
return path7.join(archiveDirectoryPath(rootPath, layout, list), `${id}${MARKDOWN_EXTENSION}`);
|
|
4078
4232
|
}
|
|
4079
4233
|
function isMarkdownFile(entryName) {
|
|
4080
4234
|
return entryName.endsWith(MARKDOWN_EXTENSION);
|
|
@@ -4200,7 +4354,7 @@ function createTask(list, id, frontmatter, body, mode, sourcePath) {
|
|
|
4200
4354
|
state: frontmatter.state,
|
|
4201
4355
|
description: body,
|
|
4202
4356
|
metadata: metadataFromFrontmatter(frontmatter, mode),
|
|
4203
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
4357
|
+
...sourcePath !== void 0 && { sourcePath: path7.resolve(sourcePath) }
|
|
4204
4358
|
};
|
|
4205
4359
|
}
|
|
4206
4360
|
function serializeTaskDocument(frontmatter, description) {
|
|
@@ -4240,7 +4394,7 @@ async function readTaskFile(fs4, list, id, filePath, validStates, initialState,
|
|
|
4240
4394
|
task: createTask(list, id, frontmatter, document.body, mode, filePath)
|
|
4241
4395
|
};
|
|
4242
4396
|
}
|
|
4243
|
-
const parsedFilename = parseActiveFilename(
|
|
4397
|
+
const parsedFilename = parseActiveFilename(path7.basename(filePath));
|
|
4244
4398
|
const defaultName = parsedFilename?.id ?? id;
|
|
4245
4399
|
const effectiveFrontmatter = {
|
|
4246
4400
|
...frontmatter,
|
|
@@ -4269,7 +4423,7 @@ async function findTaskLocation(fs4, rootPath, layout, list, id) {
|
|
|
4269
4423
|
await rejectSymbolicLinkComponents(fs4, listDirectoryPath);
|
|
4270
4424
|
const activeName = await findActiveTaskFilename(fs4, listDirectoryPath, id);
|
|
4271
4425
|
if (activeName) {
|
|
4272
|
-
const activePath =
|
|
4426
|
+
const activePath = path7.join(listDirectoryPath, activeName);
|
|
4273
4427
|
await rejectSymbolicLinkComponents(fs4, activePath);
|
|
4274
4428
|
const activeStat = await statIfExists(fs4, activePath);
|
|
4275
4429
|
if (activeStat?.isFile()) {
|
|
@@ -4391,7 +4545,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4391
4545
|
if (isHiddenEntry(entryName)) continue;
|
|
4392
4546
|
const parsed = parseActiveFilename(entryName);
|
|
4393
4547
|
if (!parsed) continue;
|
|
4394
|
-
const entryPath =
|
|
4548
|
+
const entryPath = path7.join(listDirectoryPath, entryName);
|
|
4395
4549
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4396
4550
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4397
4551
|
if (!entryStat?.isFile()) continue;
|
|
@@ -4409,7 +4563,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4409
4563
|
const entries = await readActiveEntries();
|
|
4410
4564
|
const tasks = /* @__PURE__ */ new Map();
|
|
4411
4565
|
for (const entry of entries) {
|
|
4412
|
-
const filePath =
|
|
4566
|
+
const filePath = path7.join(listDirectoryPath, entry.filename);
|
|
4413
4567
|
const file = await readTaskFile(
|
|
4414
4568
|
deps.fs,
|
|
4415
4569
|
list,
|
|
@@ -4430,7 +4584,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4430
4584
|
const result = [];
|
|
4431
4585
|
for (const entryName of entries) {
|
|
4432
4586
|
if (isHiddenEntry(entryName) || !isMarkdownFile(entryName)) continue;
|
|
4433
|
-
const entryPath =
|
|
4587
|
+
const entryPath = path7.join(archivePath, entryName);
|
|
4434
4588
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4435
4589
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4436
4590
|
if (!entryStat?.isFile()) continue;
|
|
@@ -4460,12 +4614,12 @@ function createTasksView2(deps, layout, list) {
|
|
|
4460
4614
|
if (desiredOrder === void 0) continue;
|
|
4461
4615
|
const desiredFilename = activeTaskFilename(entry.id, desiredOrder, width);
|
|
4462
4616
|
if (entry.filename !== desiredFilename) {
|
|
4463
|
-
const fromPath =
|
|
4464
|
-
const stagingPath =
|
|
4617
|
+
const fromPath = path7.join(listDirectoryPath, entry.filename);
|
|
4618
|
+
const stagingPath = path7.join(
|
|
4465
4619
|
listDirectoryPath,
|
|
4466
4620
|
`${desiredFilename}.staging-${process.pid}-${index}`
|
|
4467
4621
|
);
|
|
4468
|
-
const targetPath =
|
|
4622
|
+
const targetPath = path7.join(listDirectoryPath, desiredFilename);
|
|
4469
4623
|
try {
|
|
4470
4624
|
await deps.fs.rename(fromPath, stagingPath);
|
|
4471
4625
|
staged.push({ original: fromPath, staging: stagingPath, target: targetPath, finalized: false });
|
|
@@ -4614,7 +4768,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4614
4768
|
assertCreateHasId(input);
|
|
4615
4769
|
validateTaskId(input.id);
|
|
4616
4770
|
await rejectSymbolicLinkComponents(deps.fs, listDirectoryPath);
|
|
4617
|
-
return withFileLock(deps.fs,
|
|
4771
|
+
return withFileLock(deps.fs, path7.join(listDirectoryPath, ".transition.lock"), async () => {
|
|
4618
4772
|
const existing = await findTaskLocation(deps.fs, deps.path, layout, list, input.id);
|
|
4619
4773
|
if (existing) {
|
|
4620
4774
|
throw new TaskAlreadyExistsError(`Task "${list}/${input.id}" already exists.`);
|
|
@@ -4627,7 +4781,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4627
4781
|
const nextOrder = maxOrder + 1;
|
|
4628
4782
|
const width = padWidthForCount(activeEntries.length + 1);
|
|
4629
4783
|
const filename = activeTaskFilename(input.id, nextOrder, width);
|
|
4630
|
-
const targetPath =
|
|
4784
|
+
const targetPath = path7.join(listDirectoryPath, filename);
|
|
4631
4785
|
const frontmatter = createdFrontmatter(
|
|
4632
4786
|
deps.defaults,
|
|
4633
4787
|
input,
|
|
@@ -4735,7 +4889,7 @@ function createTasksView2(deps, layout, list) {
|
|
|
4735
4889
|
validateTaskId(id);
|
|
4736
4890
|
const { event, nextTask } = await withFileLock(
|
|
4737
4891
|
deps.fs,
|
|
4738
|
-
|
|
4892
|
+
path7.join(listDirectoryPath, ".transition.lock"),
|
|
4739
4893
|
fireTask
|
|
4740
4894
|
);
|
|
4741
4895
|
await event.onEnter?.(nextTask);
|
|
@@ -4828,7 +4982,7 @@ async function markdownDirBackend(deps) {
|
|
|
4828
4982
|
if (entryName === ARCHIVE_DIRECTORY_NAME || isHiddenEntry(entryName)) {
|
|
4829
4983
|
continue;
|
|
4830
4984
|
}
|
|
4831
|
-
const entryPath =
|
|
4985
|
+
const entryPath = path7.join(deps.path, entryName);
|
|
4832
4986
|
await rejectSymbolicLinkComponents(deps.fs, entryPath);
|
|
4833
4987
|
const entryStat = await statIfExists(deps.fs, entryPath);
|
|
4834
4988
|
if (entryStat?.isDirectory()) {
|
|
@@ -4870,7 +5024,7 @@ async function markdownDirBackend(deps) {
|
|
|
4870
5024
|
}
|
|
4871
5025
|
const targetListDir = listPath(deps.path, layout, targetListName);
|
|
4872
5026
|
await rejectSymbolicLinkComponents(deps.fs, targetListDir);
|
|
4873
|
-
return withFileLock(deps.fs,
|
|
5027
|
+
return withFileLock(deps.fs, path7.join(targetListDir, ".transition.lock"), async () => {
|
|
4874
5028
|
const targetExisting = await findTaskLocation(deps.fs, deps.path, layout, targetListName, id);
|
|
4875
5029
|
if (targetExisting) {
|
|
4876
5030
|
throw new TaskAlreadyExistsError(`Task "${targetListName}/${id}" already exists.`);
|
|
@@ -4920,7 +5074,7 @@ async function markdownDirBackend(deps) {
|
|
|
4920
5074
|
);
|
|
4921
5075
|
const width = padWidthForCount(targetEntries.length + 1);
|
|
4922
5076
|
const targetFilename = activeTaskFilename(id, maxOrder + 1, width);
|
|
4923
|
-
const targetPath =
|
|
5077
|
+
const targetPath = path7.join(targetListDir, targetFilename);
|
|
4924
5078
|
await deps.fs.rename(sourceLocation.path, targetPath);
|
|
4925
5079
|
return createTask(
|
|
4926
5080
|
targetListName,
|
|
@@ -4942,7 +5096,7 @@ async function markdownDirBackend(deps) {
|
|
|
4942
5096
|
}
|
|
4943
5097
|
|
|
4944
5098
|
// ../task-list/src/backends/yaml-file.ts
|
|
4945
|
-
import
|
|
5099
|
+
import path8 from "node:path";
|
|
4946
5100
|
import { isMap, parseDocument as parseDocument2 } from "yaml";
|
|
4947
5101
|
|
|
4948
5102
|
// ../task-list/src/schema/store.schema.json
|
|
@@ -5038,7 +5192,7 @@ function createTask2(list, id, taskRecord, sourcePath) {
|
|
|
5038
5192
|
state: taskRecord.state,
|
|
5039
5193
|
description: descriptionFromTaskRecord(taskRecord),
|
|
5040
5194
|
metadata: metadataFromTaskRecord(taskRecord),
|
|
5041
|
-
...sourcePath !== void 0 && { sourcePath:
|
|
5195
|
+
...sourcePath !== void 0 && { sourcePath: path8.resolve(sourcePath) }
|
|
5042
5196
|
};
|
|
5043
5197
|
}
|
|
5044
5198
|
function matchesFilter(task, filter) {
|
|
@@ -5603,7 +5757,7 @@ async function openGhIssuesBackend(options) {
|
|
|
5603
5757
|
|
|
5604
5758
|
// ../task-list/src/move.ts
|
|
5605
5759
|
import * as fsPromises2 from "node:fs/promises";
|
|
5606
|
-
import
|
|
5760
|
+
import path9 from "node:path";
|
|
5607
5761
|
|
|
5608
5762
|
// ../toolcraft/src/human-in-loop/approval-tasks.ts
|
|
5609
5763
|
import { randomBytes as randomBytes3 } from "node:crypto";
|
|
@@ -6099,13 +6253,13 @@ function formatAvailableApprovalCommandPaths(root) {
|
|
|
6099
6253
|
}
|
|
6100
6254
|
function enumerateApprovalCommandPaths(root) {
|
|
6101
6255
|
const paths = [];
|
|
6102
|
-
const visit = (node,
|
|
6256
|
+
const visit = (node, path24) => {
|
|
6103
6257
|
if (node.kind === "command") {
|
|
6104
|
-
paths.push(
|
|
6258
|
+
paths.push(path24.join("."));
|
|
6105
6259
|
return;
|
|
6106
6260
|
}
|
|
6107
6261
|
for (const child of getVisibleCliChildren(node)) {
|
|
6108
|
-
visit(child, [...
|
|
6262
|
+
visit(child, [...path24, child.name]);
|
|
6109
6263
|
}
|
|
6110
6264
|
};
|
|
6111
6265
|
if (root.kind === "command") {
|
|
@@ -6140,21 +6294,21 @@ function createHandlerContext(command, params17) {
|
|
|
6140
6294
|
}
|
|
6141
6295
|
function createFs() {
|
|
6142
6296
|
return {
|
|
6143
|
-
readFile: async (
|
|
6144
|
-
writeFile: async (
|
|
6145
|
-
await writeFile2(
|
|
6297
|
+
readFile: async (path24, encoding = "utf8") => readFile2(path24, { encoding }),
|
|
6298
|
+
writeFile: async (path24, contents) => {
|
|
6299
|
+
await writeFile2(path24, contents);
|
|
6146
6300
|
},
|
|
6147
|
-
exists: async (
|
|
6301
|
+
exists: async (path24) => {
|
|
6148
6302
|
try {
|
|
6149
|
-
await access(
|
|
6303
|
+
await access(path24);
|
|
6150
6304
|
return true;
|
|
6151
6305
|
} catch {
|
|
6152
6306
|
return false;
|
|
6153
6307
|
}
|
|
6154
6308
|
},
|
|
6155
|
-
lstat: async (
|
|
6309
|
+
lstat: async (path24) => lstat(path24),
|
|
6156
6310
|
rename: async (fromPath, toPath) => rename(fromPath, toPath),
|
|
6157
|
-
unlink: async (
|
|
6311
|
+
unlink: async (path24) => unlink(path24)
|
|
6158
6312
|
};
|
|
6159
6313
|
}
|
|
6160
6314
|
function createEnv(values = process.env) {
|
|
@@ -6431,16 +6585,16 @@ function isMissingStateError(error3) {
|
|
|
6431
6585
|
|
|
6432
6586
|
// ../toolcraft/src/error-report.ts
|
|
6433
6587
|
import { mkdir as mkdir2, realpath, writeFile as writeFile4 } from "node:fs/promises";
|
|
6434
|
-
import { randomUUID as
|
|
6588
|
+
import { randomUUID as randomUUID3 } from "node:crypto";
|
|
6435
6589
|
import os from "node:os";
|
|
6436
|
-
import
|
|
6590
|
+
import path13 from "node:path";
|
|
6437
6591
|
import { CommanderError } from "commander";
|
|
6438
6592
|
|
|
6439
6593
|
// ../toolcraft/src/mcp-proxy.ts
|
|
6440
6594
|
import { existsSync as existsSync2 } from "node:fs";
|
|
6441
6595
|
import { lstat as lstat2, mkdir, readFile as readFile3, rename as rename2, writeFile as writeFile3 } from "node:fs/promises";
|
|
6442
|
-
import
|
|
6443
|
-
import { createHash as createHash3, randomUUID } from "node:crypto";
|
|
6596
|
+
import path12 from "node:path";
|
|
6597
|
+
import { createHash as createHash3, randomUUID as randomUUID2 } from "node:crypto";
|
|
6444
6598
|
|
|
6445
6599
|
// ../tiny-mcp-client/src/internal.ts
|
|
6446
6600
|
import { spawn as spawn5 } from "node:child_process";
|
|
@@ -6448,13 +6602,13 @@ import { PassThrough as PassThrough2 } from "node:stream";
|
|
|
6448
6602
|
|
|
6449
6603
|
// ../mcp-oauth/src/client/auth-store-session-store.ts
|
|
6450
6604
|
import crypto from "node:crypto";
|
|
6451
|
-
import
|
|
6605
|
+
import path11 from "node:path";
|
|
6452
6606
|
|
|
6453
6607
|
// ../auth-store/src/encrypted-file-store.ts
|
|
6454
6608
|
import { createCipheriv, createDecipheriv, randomBytes as randomBytes4, scrypt } from "node:crypto";
|
|
6455
6609
|
import { promises as fs } from "node:fs";
|
|
6456
6610
|
import { homedir, hostname, userInfo } from "node:os";
|
|
6457
|
-
import
|
|
6611
|
+
import path10 from "node:path";
|
|
6458
6612
|
var derivedKeyCache = /* @__PURE__ */ new Map();
|
|
6459
6613
|
var ENCRYPTION_ALGORITHM = "aes-256-gcm";
|
|
6460
6614
|
var ENCRYPTION_VERSION = 1;
|
|
@@ -6466,6 +6620,7 @@ var temporaryFileSequence = 0;
|
|
|
6466
6620
|
var EncryptedFileStore = class {
|
|
6467
6621
|
fs;
|
|
6468
6622
|
filePath;
|
|
6623
|
+
symbolicLinkCheckStartPath;
|
|
6469
6624
|
salt;
|
|
6470
6625
|
getMachineIdentity;
|
|
6471
6626
|
getRandomBytes;
|
|
@@ -6473,11 +6628,22 @@ var EncryptedFileStore = class {
|
|
|
6473
6628
|
constructor(input) {
|
|
6474
6629
|
this.fs = input.fs ?? fs;
|
|
6475
6630
|
this.salt = input.salt;
|
|
6476
|
-
|
|
6477
|
-
(input.getHomeDirectory ?? homedir)()
|
|
6478
|
-
input.defaultDirectory ?? ".auth-store"
|
|
6479
|
-
|
|
6480
|
-
|
|
6631
|
+
if (input.filePath === void 0) {
|
|
6632
|
+
const homeDirectory = (input.getHomeDirectory ?? homedir)();
|
|
6633
|
+
const defaultDirectory = input.defaultDirectory ?? ".auth-store";
|
|
6634
|
+
this.filePath = path10.join(
|
|
6635
|
+
homeDirectory,
|
|
6636
|
+
defaultDirectory,
|
|
6637
|
+
input.defaultFileName ?? "credentials.enc"
|
|
6638
|
+
);
|
|
6639
|
+
this.symbolicLinkCheckStartPath = resolveDefaultDirectoryCheckStart(
|
|
6640
|
+
homeDirectory,
|
|
6641
|
+
defaultDirectory
|
|
6642
|
+
);
|
|
6643
|
+
} else {
|
|
6644
|
+
this.filePath = input.filePath;
|
|
6645
|
+
this.symbolicLinkCheckStartPath = null;
|
|
6646
|
+
}
|
|
6481
6647
|
this.getMachineIdentity = input.getMachineIdentity ?? defaultMachineIdentity;
|
|
6482
6648
|
this.getRandomBytes = input.getRandomBytes ?? randomBytes4;
|
|
6483
6649
|
}
|
|
@@ -6528,7 +6694,7 @@ var EncryptedFileStore = class {
|
|
|
6528
6694
|
authTag: authTag.toString("base64"),
|
|
6529
6695
|
ciphertext: ciphertext.toString("base64")
|
|
6530
6696
|
};
|
|
6531
|
-
await this.fs.mkdir(
|
|
6697
|
+
await this.fs.mkdir(path10.dirname(this.filePath), { recursive: true });
|
|
6532
6698
|
await this.assertRegularCredentialPath();
|
|
6533
6699
|
const temporaryPath = `${this.filePath}.${process.pid}.${temporaryFileSequence++}.tmp`;
|
|
6534
6700
|
try {
|
|
@@ -6557,8 +6723,11 @@ var EncryptedFileStore = class {
|
|
|
6557
6723
|
}
|
|
6558
6724
|
}
|
|
6559
6725
|
async assertRegularCredentialPath() {
|
|
6560
|
-
const resolvedPath =
|
|
6561
|
-
const protectedPaths =
|
|
6726
|
+
const resolvedPath = path10.resolve(this.filePath);
|
|
6727
|
+
const protectedPaths = getProtectedCredentialPaths(
|
|
6728
|
+
resolvedPath,
|
|
6729
|
+
this.symbolicLinkCheckStartPath
|
|
6730
|
+
);
|
|
6562
6731
|
for (const currentPath of protectedPaths) {
|
|
6563
6732
|
try {
|
|
6564
6733
|
const stats = await this.fs.lstat(currentPath);
|
|
@@ -6586,6 +6755,30 @@ var EncryptedFileStore = class {
|
|
|
6586
6755
|
return this.keyPromise;
|
|
6587
6756
|
}
|
|
6588
6757
|
};
|
|
6758
|
+
function resolveDefaultDirectoryCheckStart(homeDirectory, defaultDirectory) {
|
|
6759
|
+
const [firstSegment] = defaultDirectory.split(/[\\/]+/).filter(Boolean);
|
|
6760
|
+
return path10.resolve(homeDirectory, firstSegment ?? ".");
|
|
6761
|
+
}
|
|
6762
|
+
function getProtectedCredentialPaths(resolvedPath, symbolicLinkCheckStartPath) {
|
|
6763
|
+
if (symbolicLinkCheckStartPath === null) {
|
|
6764
|
+
return [path10.dirname(resolvedPath), resolvedPath];
|
|
6765
|
+
}
|
|
6766
|
+
const resolvedStartPath = path10.resolve(symbolicLinkCheckStartPath);
|
|
6767
|
+
if (!isPathInsideOrEqual(resolvedPath, resolvedStartPath)) {
|
|
6768
|
+
return [path10.dirname(resolvedPath), resolvedPath];
|
|
6769
|
+
}
|
|
6770
|
+
const protectedPaths = [resolvedStartPath];
|
|
6771
|
+
let currentPath = resolvedStartPath;
|
|
6772
|
+
for (const segment of path10.relative(resolvedStartPath, resolvedPath).split(path10.sep).filter(Boolean)) {
|
|
6773
|
+
currentPath = path10.join(currentPath, segment);
|
|
6774
|
+
protectedPaths.push(currentPath);
|
|
6775
|
+
}
|
|
6776
|
+
return protectedPaths;
|
|
6777
|
+
}
|
|
6778
|
+
function isPathInsideOrEqual(childPath, parentPath) {
|
|
6779
|
+
const relativePath = path10.relative(parentPath, childPath);
|
|
6780
|
+
return relativePath === "" || !relativePath.startsWith("..") && !path10.isAbsolute(relativePath);
|
|
6781
|
+
}
|
|
6589
6782
|
async function removeIfPresent(fileSystem, filePath) {
|
|
6590
6783
|
try {
|
|
6591
6784
|
await fileSystem.unlink(filePath);
|
|
@@ -6736,6 +6929,17 @@ function runSecurityCommand(command, args, options) {
|
|
|
6736
6929
|
});
|
|
6737
6930
|
let stdout = "";
|
|
6738
6931
|
let stderr = "";
|
|
6932
|
+
let stdinErrorMessage;
|
|
6933
|
+
const appendStderr = (message2) => {
|
|
6934
|
+
stderr = stderr.length === 0 ? message2 : `${stderr}${stderr.endsWith("\n") ? "" : "\n"}${message2}`;
|
|
6935
|
+
};
|
|
6936
|
+
const appendStdinError = () => {
|
|
6937
|
+
if (stdinErrorMessage === void 0) {
|
|
6938
|
+
return;
|
|
6939
|
+
}
|
|
6940
|
+
appendStderr(stdinErrorMessage);
|
|
6941
|
+
stdinErrorMessage = void 0;
|
|
6942
|
+
};
|
|
6739
6943
|
child.stdout?.setEncoding("utf8");
|
|
6740
6944
|
child.stdout?.on("data", (chunk) => {
|
|
6741
6945
|
stdout += chunk.toString();
|
|
@@ -6745,17 +6949,23 @@ function runSecurityCommand(command, args, options) {
|
|
|
6745
6949
|
stderr += chunk.toString();
|
|
6746
6950
|
});
|
|
6747
6951
|
if (options?.stdin !== void 0) {
|
|
6952
|
+
child.stdin?.once("error", (error3) => {
|
|
6953
|
+
stdinErrorMessage = error3 instanceof Error ? error3.message : String(error3);
|
|
6954
|
+
});
|
|
6748
6955
|
child.stdin?.end(options.stdin);
|
|
6749
6956
|
}
|
|
6750
6957
|
child.on("error", (error3) => {
|
|
6751
6958
|
const message2 = error3 instanceof Error ? error3.message : String(error3 ?? "Unknown error");
|
|
6959
|
+
appendStdinError();
|
|
6960
|
+
appendStderr(message2);
|
|
6752
6961
|
resolve({
|
|
6753
6962
|
stdout,
|
|
6754
|
-
stderr
|
|
6963
|
+
stderr,
|
|
6755
6964
|
exitCode: 127
|
|
6756
6965
|
});
|
|
6757
6966
|
});
|
|
6758
6967
|
child.on("close", (code) => {
|
|
6968
|
+
appendStdinError();
|
|
6759
6969
|
resolve({
|
|
6760
6970
|
stdout,
|
|
6761
6971
|
stderr,
|
|
@@ -6895,7 +7105,7 @@ function createAuthStoreClientStore(options) {
|
|
|
6895
7105
|
}
|
|
6896
7106
|
function createNamedSecretStore(key2, options, defaults) {
|
|
6897
7107
|
const hash = crypto.createHash("sha256").update(key2).digest("hex");
|
|
6898
|
-
const parsedFilePath = options.fileStore?.filePath === void 0 ? null :
|
|
7108
|
+
const parsedFilePath = options.fileStore?.filePath === void 0 ? null : path11.parse(options.fileStore.filePath);
|
|
6899
7109
|
const fileStore = {
|
|
6900
7110
|
...options.fileStore,
|
|
6901
7111
|
salt: options.fileStore?.salt ?? defaults.salt,
|
|
@@ -8478,10 +8688,19 @@ var McpClient = class {
|
|
|
8478
8688
|
}
|
|
8479
8689
|
try {
|
|
8480
8690
|
let requestId;
|
|
8691
|
+
let cancellationSent = false;
|
|
8692
|
+
const sendCancellationNotification = () => {
|
|
8693
|
+
if (requestId === void 0 || cancellationSent) {
|
|
8694
|
+
return;
|
|
8695
|
+
}
|
|
8696
|
+
cancellationSent = true;
|
|
8697
|
+
messageLayer.sendNotification("notifications/cancelled", { requestId });
|
|
8698
|
+
};
|
|
8481
8699
|
const requestPromise = messageLayer.sendRequest("tools/call", requestParams, {
|
|
8482
8700
|
onRequestId: (nextRequestId) => {
|
|
8483
8701
|
requestId = nextRequestId;
|
|
8484
|
-
}
|
|
8702
|
+
},
|
|
8703
|
+
onTimeout: sendCancellationNotification
|
|
8485
8704
|
}).then((result) => {
|
|
8486
8705
|
if (!isCallToolResult(result)) {
|
|
8487
8706
|
throw new McpError(ERROR_INVALID_REQUEST, "Invalid tool result");
|
|
@@ -8495,9 +8714,7 @@ var McpClient = class {
|
|
|
8495
8714
|
let abortListener;
|
|
8496
8715
|
const abortPromise = new Promise((_, reject) => {
|
|
8497
8716
|
const rejectWithAbortReason = () => {
|
|
8498
|
-
|
|
8499
|
-
messageLayer.sendNotification("notifications/cancelled", { requestId });
|
|
8500
|
-
}
|
|
8717
|
+
sendCancellationNotification();
|
|
8501
8718
|
reject(signal.reason);
|
|
8502
8719
|
};
|
|
8503
8720
|
abortListener = rejectWithAbortReason;
|
|
@@ -9308,6 +9525,7 @@ var JsonRpcMessageLayer = class {
|
|
|
9308
9525
|
return new Promise((resolve, reject) => {
|
|
9309
9526
|
const timeout = setTimeout(() => {
|
|
9310
9527
|
this.pendingRequests.delete(id);
|
|
9528
|
+
options.onTimeout?.(id);
|
|
9311
9529
|
reject(new Error(`JSON-RPC request "${method}" timed out after ${timeoutMs}ms`));
|
|
9312
9530
|
}, timeoutMs);
|
|
9313
9531
|
this.pendingRequests.set(id, { resolve, reject, timeout });
|
|
@@ -9720,13 +9938,13 @@ function convertJsonSchema(schema) {
|
|
|
9720
9938
|
}
|
|
9721
9939
|
return convertSchema(schema, schema, []);
|
|
9722
9940
|
}
|
|
9723
|
-
function convertSchema(schema, root,
|
|
9724
|
-
const resolvedSchema = resolveReferencedSchema(schema, root,
|
|
9941
|
+
function convertSchema(schema, root, path24) {
|
|
9942
|
+
const resolvedSchema = resolveReferencedSchema(schema, root, path24);
|
|
9725
9943
|
const normalizedSchema = normalizeNullability(resolvedSchema);
|
|
9726
9944
|
const composition = getComposition(normalizedSchema.schema);
|
|
9727
9945
|
if (Array.isArray(normalizedSchema.schema.type)) {
|
|
9728
9946
|
throw new Error(
|
|
9729
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
9947
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" has an unsupported type "${formatJsonSchemaType(
|
|
9730
9948
|
normalizedSchema.schema.type
|
|
9731
9949
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
9732
9950
|
);
|
|
@@ -9738,13 +9956,13 @@ function convertSchema(schema, root, path23) {
|
|
|
9738
9956
|
return convertEnumSchema(resolvedSchema, normalizedSchema.nullable);
|
|
9739
9957
|
}
|
|
9740
9958
|
if (composition !== void 0) {
|
|
9741
|
-
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable,
|
|
9959
|
+
return convertCompositionSchema(normalizedSchema.schema, root, normalizedSchema.nullable, path24);
|
|
9742
9960
|
}
|
|
9743
9961
|
if (isRecordSchema(normalizedSchema.schema)) {
|
|
9744
9962
|
return applyMetadata(
|
|
9745
9963
|
S.Record(
|
|
9746
9964
|
convertSchema(normalizedSchema.schema.additionalProperties, root, [
|
|
9747
|
-
...
|
|
9965
|
+
...path24,
|
|
9748
9966
|
"additionalProperties"
|
|
9749
9967
|
])
|
|
9750
9968
|
),
|
|
@@ -9793,12 +10011,12 @@ function convertSchema(schema, root, path23) {
|
|
|
9793
10011
|
if (normalizedSchema.schema.items === void 0) {
|
|
9794
10012
|
throw new Error(
|
|
9795
10013
|
`JSON Schema "${formatJsonSchemaPath(
|
|
9796
|
-
|
|
10014
|
+
path24
|
|
9797
10015
|
)}" is an array but is missing the "items" field. Add "items": { ... } to declare the element type.`
|
|
9798
10016
|
);
|
|
9799
10017
|
}
|
|
9800
10018
|
return S.Array(
|
|
9801
|
-
convertSchema(normalizedSchema.schema.items, root, [...
|
|
10019
|
+
convertSchema(normalizedSchema.schema.items, root, [...path24, "items"]),
|
|
9802
10020
|
createCommonOptions(
|
|
9803
10021
|
normalizedSchema.schema,
|
|
9804
10022
|
normalizedSchema.nullable,
|
|
@@ -9808,7 +10026,7 @@ function convertSchema(schema, root, path23) {
|
|
|
9808
10026
|
case "object":
|
|
9809
10027
|
return convertObjectSchema(normalizedSchema.schema, root, {
|
|
9810
10028
|
nullable: normalizedSchema.nullable,
|
|
9811
|
-
path:
|
|
10029
|
+
path: path24
|
|
9812
10030
|
});
|
|
9813
10031
|
case "null":
|
|
9814
10032
|
return applyMetadata(S.Json(), normalizedSchema.schema, {
|
|
@@ -9823,12 +10041,12 @@ function convertSchema(schema, root, path23) {
|
|
|
9823
10041
|
}
|
|
9824
10042
|
throw new Error(
|
|
9825
10043
|
`JSON Schema "${formatJsonSchemaPath(
|
|
9826
|
-
|
|
10044
|
+
path24
|
|
9827
10045
|
)}" must declare one of: "type", "enum", "const", "oneOf", "anyOf", or "allOf".`
|
|
9828
10046
|
);
|
|
9829
10047
|
}
|
|
9830
10048
|
throw new Error(
|
|
9831
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10049
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" has an unsupported type "${formatJsonSchemaType(
|
|
9832
10050
|
normalizedSchema.schema.type
|
|
9833
10051
|
)}". Supported: string, number, integer, boolean, array, object.`
|
|
9834
10052
|
);
|
|
@@ -9872,21 +10090,21 @@ function convertEnumSchema(schema, nullable) {
|
|
|
9872
10090
|
)
|
|
9873
10091
|
});
|
|
9874
10092
|
}
|
|
9875
|
-
function convertCompositionSchema(schema, root, nullable,
|
|
10093
|
+
function convertCompositionSchema(schema, root, nullable, path24) {
|
|
9876
10094
|
const composition = getComposition(schema);
|
|
9877
10095
|
const branchSchemas = composition?.branches ?? [];
|
|
9878
10096
|
const keyword = composition?.keyword ?? "oneOf";
|
|
9879
10097
|
const branches = branchSchemas.map(
|
|
9880
|
-
(branch, index) => resolveReferencedSchema(branch, root, [...
|
|
10098
|
+
(branch, index) => resolveReferencedSchema(branch, root, [...path24, keyword, String(index)])
|
|
9881
10099
|
);
|
|
9882
|
-
const discriminator = findDiscriminator(branches, root,
|
|
10100
|
+
const discriminator = findDiscriminator(branches, root, path24);
|
|
9883
10101
|
if (discriminator !== void 0) {
|
|
9884
10102
|
const convertedBranches = Object.fromEntries(
|
|
9885
10103
|
branches.map((branch, index) => [
|
|
9886
10104
|
getDiscriminatorLiteral(branch, discriminator, root),
|
|
9887
10105
|
convertObjectSchema(branch, root, {
|
|
9888
10106
|
omitProperty: discriminator,
|
|
9889
|
-
path: [...
|
|
10107
|
+
path: [...path24, keyword, String(index)]
|
|
9890
10108
|
})
|
|
9891
10109
|
])
|
|
9892
10110
|
);
|
|
@@ -9905,7 +10123,7 @@ function convertCompositionSchema(schema, root, nullable, path23) {
|
|
|
9905
10123
|
S.Union(
|
|
9906
10124
|
branches.map(
|
|
9907
10125
|
(branch, index) => convertObjectSchema(branch, root, {
|
|
9908
|
-
path: [...
|
|
10126
|
+
path: [...path24, keyword, String(index)]
|
|
9909
10127
|
})
|
|
9910
10128
|
)
|
|
9911
10129
|
),
|
|
@@ -10007,11 +10225,11 @@ function getComposition(schema) {
|
|
|
10007
10225
|
}
|
|
10008
10226
|
return void 0;
|
|
10009
10227
|
}
|
|
10010
|
-
function formatJsonSchemaPath(
|
|
10011
|
-
if (
|
|
10228
|
+
function formatJsonSchemaPath(path24) {
|
|
10229
|
+
if (path24.length === 0) {
|
|
10012
10230
|
return "#";
|
|
10013
10231
|
}
|
|
10014
|
-
return `#/${
|
|
10232
|
+
return `#/${path24.map(escapeJsonPointerSegment).join("/")}`;
|
|
10015
10233
|
}
|
|
10016
10234
|
function formatJsonSchemaType(type2) {
|
|
10017
10235
|
return Array.isArray(type2) ? JSON.stringify(type2) : String(type2);
|
|
@@ -10027,11 +10245,11 @@ function isRecordSchema(schema) {
|
|
|
10027
10245
|
const propertyKeys = Object.keys(schema.properties ?? {});
|
|
10028
10246
|
return schema.type === "object" && propertyKeys.length === 0 && typeof schema.additionalProperties === "object" && schema.additionalProperties !== null;
|
|
10029
10247
|
}
|
|
10030
|
-
function findDiscriminator(branches, root,
|
|
10248
|
+
function findDiscriminator(branches, root, path24) {
|
|
10031
10249
|
const [firstBranch] = branches;
|
|
10032
10250
|
if (firstBranch === void 0) {
|
|
10033
10251
|
throw new Error(
|
|
10034
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10252
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" uses oneOf/anyOf/allOf but has no branches.`
|
|
10035
10253
|
);
|
|
10036
10254
|
}
|
|
10037
10255
|
const candidateKeys = Object.keys(firstBranch.properties ?? {});
|
|
@@ -10071,19 +10289,19 @@ function getDiscriminatorLiteral(branch, key2, root) {
|
|
|
10071
10289
|
}
|
|
10072
10290
|
return void 0;
|
|
10073
10291
|
}
|
|
10074
|
-
function resolveReferencedSchema(schema, root,
|
|
10292
|
+
function resolveReferencedSchema(schema, root, path24) {
|
|
10075
10293
|
if (schema.$ref === void 0) {
|
|
10076
10294
|
return schema;
|
|
10077
10295
|
}
|
|
10078
10296
|
const resolvedTarget = resolveLocalRef(root, schema.$ref);
|
|
10079
10297
|
if (resolvedTarget === void 0) {
|
|
10080
10298
|
throw new Error(
|
|
10081
|
-
`JSON Schema "${formatJsonSchemaPath(
|
|
10299
|
+
`JSON Schema "${formatJsonSchemaPath(path24)}" uses "$ref": ${schema.$ref}. toolcraft only supports internal refs like "#/components/schemas/Foo".`
|
|
10082
10300
|
);
|
|
10083
10301
|
}
|
|
10084
10302
|
const { $ref: ignoredRef, ...siblingKeywords } = schema;
|
|
10085
10303
|
void ignoredRef;
|
|
10086
|
-
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root,
|
|
10304
|
+
const resolvedSchema = resolveReferencedSchema(resolvedTarget, root, path24);
|
|
10087
10305
|
if (Object.keys(siblingKeywords).length === 0) {
|
|
10088
10306
|
return resolvedSchema;
|
|
10089
10307
|
}
|
|
@@ -10107,9 +10325,9 @@ function mergeJsonSchemas(base, overlay) {
|
|
|
10107
10325
|
...mergedRequired === void 0 ? {} : { required: mergedRequired }
|
|
10108
10326
|
};
|
|
10109
10327
|
}
|
|
10110
|
-
function hasSelfReferencingRef(schema, root,
|
|
10328
|
+
function hasSelfReferencingRef(schema, root, path24 = "#", activePaths = /* @__PURE__ */ new Set()) {
|
|
10111
10329
|
const nextActivePaths = new Set(activePaths);
|
|
10112
|
-
nextActivePaths.add(
|
|
10330
|
+
nextActivePaths.add(path24);
|
|
10113
10331
|
const localRefPath = getLocalRefPath(schema.$ref);
|
|
10114
10332
|
if (localRefPath !== void 0) {
|
|
10115
10333
|
if (nextActivePaths.has(localRefPath)) {
|
|
@@ -10120,13 +10338,13 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
|
|
|
10120
10338
|
return true;
|
|
10121
10339
|
}
|
|
10122
10340
|
}
|
|
10123
|
-
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${
|
|
10341
|
+
if (schema.items !== void 0 && hasSelfReferencingRef(schema.items, root, `${path24}/items`, nextActivePaths)) {
|
|
10124
10342
|
return true;
|
|
10125
10343
|
}
|
|
10126
10344
|
if (typeof schema.additionalProperties === "object" && schema.additionalProperties !== null && hasSelfReferencingRef(
|
|
10127
10345
|
schema.additionalProperties,
|
|
10128
10346
|
root,
|
|
10129
|
-
`${
|
|
10347
|
+
`${path24}/additionalProperties`,
|
|
10130
10348
|
nextActivePaths
|
|
10131
10349
|
)) {
|
|
10132
10350
|
return true;
|
|
@@ -10135,7 +10353,7 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
|
|
|
10135
10353
|
if (hasSelfReferencingRef(
|
|
10136
10354
|
childSchema,
|
|
10137
10355
|
root,
|
|
10138
|
-
`${
|
|
10356
|
+
`${path24}/properties/${escapeJsonPointerSegment(key2)}`,
|
|
10139
10357
|
nextActivePaths
|
|
10140
10358
|
)) {
|
|
10141
10359
|
return true;
|
|
@@ -10145,24 +10363,24 @@ function hasSelfReferencingRef(schema, root, path23 = "#", activePaths = /* @__P
|
|
|
10145
10363
|
if (hasSelfReferencingRef(
|
|
10146
10364
|
childSchema,
|
|
10147
10365
|
root,
|
|
10148
|
-
`${
|
|
10366
|
+
`${path24}/$defs/${escapeJsonPointerSegment(key2)}`,
|
|
10149
10367
|
nextActivePaths
|
|
10150
10368
|
)) {
|
|
10151
10369
|
return true;
|
|
10152
10370
|
}
|
|
10153
10371
|
}
|
|
10154
10372
|
for (const [index, childSchema] of (schema.oneOf ?? []).entries()) {
|
|
10155
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10373
|
+
if (hasSelfReferencingRef(childSchema, root, `${path24}/oneOf/${index}`, nextActivePaths)) {
|
|
10156
10374
|
return true;
|
|
10157
10375
|
}
|
|
10158
10376
|
}
|
|
10159
10377
|
for (const [index, childSchema] of (schema.anyOf ?? []).entries()) {
|
|
10160
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10378
|
+
if (hasSelfReferencingRef(childSchema, root, `${path24}/anyOf/${index}`, nextActivePaths)) {
|
|
10161
10379
|
return true;
|
|
10162
10380
|
}
|
|
10163
10381
|
}
|
|
10164
10382
|
for (const [index, childSchema] of (schema.allOf ?? []).entries()) {
|
|
10165
|
-
if (hasSelfReferencingRef(childSchema, root, `${
|
|
10383
|
+
if (hasSelfReferencingRef(childSchema, root, `${path24}/allOf/${index}`, nextActivePaths)) {
|
|
10166
10384
|
return true;
|
|
10167
10385
|
}
|
|
10168
10386
|
}
|
|
@@ -10178,14 +10396,14 @@ function getLocalRefPath(ref) {
|
|
|
10178
10396
|
return ref.startsWith("#/") ? ref : void 0;
|
|
10179
10397
|
}
|
|
10180
10398
|
function resolveLocalRef(root, ref) {
|
|
10181
|
-
const
|
|
10182
|
-
if (
|
|
10399
|
+
const path24 = getLocalRefPath(ref);
|
|
10400
|
+
if (path24 === void 0) {
|
|
10183
10401
|
return void 0;
|
|
10184
10402
|
}
|
|
10185
|
-
if (
|
|
10403
|
+
if (path24 === "#") {
|
|
10186
10404
|
return root;
|
|
10187
10405
|
}
|
|
10188
|
-
const segments =
|
|
10406
|
+
const segments = path24.slice(2).split("/").map(unescapeJsonPointerSegment);
|
|
10189
10407
|
let current = root;
|
|
10190
10408
|
for (const segment of segments) {
|
|
10191
10409
|
if (Array.isArray(current)) {
|
|
@@ -10446,8 +10664,8 @@ async function readCache(cachePath) {
|
|
|
10446
10664
|
}
|
|
10447
10665
|
}
|
|
10448
10666
|
async function writeCache(cachePath, cache) {
|
|
10449
|
-
const directory =
|
|
10450
|
-
const tempPath = `${cachePath}.tmp-${
|
|
10667
|
+
const directory = path12.dirname(cachePath);
|
|
10668
|
+
const tempPath = `${cachePath}.tmp-${randomUUID2()}`;
|
|
10451
10669
|
await assertCachePathHasNoSymlinks(cachePath);
|
|
10452
10670
|
await assertCachePathHasNoSymlinks(tempPath);
|
|
10453
10671
|
await mkdir(directory, { recursive: true });
|
|
@@ -10627,13 +10845,13 @@ function collectProxyGroups(root) {
|
|
|
10627
10845
|
function findProjectRoot(from = process.cwd()) {
|
|
10628
10846
|
let current = process.cwd();
|
|
10629
10847
|
if (from !== current) {
|
|
10630
|
-
current =
|
|
10848
|
+
current = path12.resolve(from);
|
|
10631
10849
|
}
|
|
10632
10850
|
while (true) {
|
|
10633
|
-
if (existsSync2(
|
|
10851
|
+
if (existsSync2(path12.join(current, "package.json"))) {
|
|
10634
10852
|
return current;
|
|
10635
10853
|
}
|
|
10636
|
-
const parent =
|
|
10854
|
+
const parent = path12.dirname(current);
|
|
10637
10855
|
if (parent === current) {
|
|
10638
10856
|
return void 0;
|
|
10639
10857
|
}
|
|
@@ -10650,7 +10868,7 @@ function resolveCachePath(name, projectRoot) {
|
|
|
10650
10868
|
if (name.length === 0 || name === "." || name === ".." || name.includes("/") || name.includes("\\")) {
|
|
10651
10869
|
throw new Error(`MCP proxy group name must be a file-safe name: "${name}".`);
|
|
10652
10870
|
}
|
|
10653
|
-
return
|
|
10871
|
+
return path12.join(resolvedProjectRoot, ".toolcraft", "mcp", `${name}.json`);
|
|
10654
10872
|
}
|
|
10655
10873
|
async function assertCachePathHasNoSymlinks(filePath) {
|
|
10656
10874
|
let currentPath = filePath;
|
|
@@ -10664,10 +10882,10 @@ async function assertCachePathHasNoSymlinks(filePath) {
|
|
|
10664
10882
|
throw error3;
|
|
10665
10883
|
}
|
|
10666
10884
|
}
|
|
10667
|
-
if (
|
|
10885
|
+
if (path12.basename(currentPath) === ".toolcraft") {
|
|
10668
10886
|
return;
|
|
10669
10887
|
}
|
|
10670
|
-
const parentPath =
|
|
10888
|
+
const parentPath = path12.dirname(currentPath);
|
|
10671
10889
|
if (parentPath === currentPath) {
|
|
10672
10890
|
return;
|
|
10673
10891
|
}
|
|
@@ -10741,20 +10959,20 @@ function reportsEnabled(option, env) {
|
|
|
10741
10959
|
function resolveReportDir(option, projectRoot) {
|
|
10742
10960
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
10743
10961
|
if (configuredDir === void 0 || configuredDir.length === 0) {
|
|
10744
|
-
return
|
|
10962
|
+
return path13.join(projectRoot, ".toolcraft", "errors");
|
|
10745
10963
|
}
|
|
10746
|
-
return
|
|
10964
|
+
return path13.isAbsolute(configuredDir) ? configuredDir : path13.join(projectRoot, configuredDir);
|
|
10747
10965
|
}
|
|
10748
10966
|
function reportDirMustStayWithinProject(option) {
|
|
10749
10967
|
const configuredDir = typeof option === "object" ? option.dir : void 0;
|
|
10750
|
-
return configuredDir === void 0 || configuredDir.length === 0 || !
|
|
10968
|
+
return configuredDir === void 0 || configuredDir.length === 0 || !path13.isAbsolute(configuredDir);
|
|
10751
10969
|
}
|
|
10752
10970
|
function isWithinDirectory(parent, child) {
|
|
10753
|
-
const relative =
|
|
10754
|
-
return relative === "" || !
|
|
10971
|
+
const relative = path13.relative(parent, child);
|
|
10972
|
+
return relative === "" || !path13.isAbsolute(relative) && relative !== ".." && !relative.startsWith(`..${path13.sep}`);
|
|
10755
10973
|
}
|
|
10756
10974
|
async function assertReportDirWithinProject(projectRoot, reportDir) {
|
|
10757
|
-
if (!isWithinDirectory(
|
|
10975
|
+
if (!isWithinDirectory(path13.resolve(projectRoot), path13.resolve(reportDir))) {
|
|
10758
10976
|
throw new Error("Error report directory resolves outside project root.");
|
|
10759
10977
|
}
|
|
10760
10978
|
const [canonicalProjectRoot, canonicalReportDir] = await Promise.all([
|
|
@@ -10805,7 +11023,7 @@ function slugifyCommandPath(commandPath) {
|
|
|
10805
11023
|
return output.length === 0 ? "root" : output;
|
|
10806
11024
|
}
|
|
10807
11025
|
function relativeDisplayPath(projectRoot, absolutePath) {
|
|
10808
|
-
const relative =
|
|
11026
|
+
const relative = path13.relative(projectRoot, absolutePath);
|
|
10809
11027
|
return relative.length === 0 || relative.startsWith("..") ? absolutePath : relative;
|
|
10810
11028
|
}
|
|
10811
11029
|
function redactValue(value) {
|
|
@@ -11045,8 +11263,8 @@ async function writeErrorReport(context) {
|
|
|
11045
11263
|
}
|
|
11046
11264
|
const projectRoot = resolveProjectRoot(context.projectRoot);
|
|
11047
11265
|
const reportDir = resolveReportDir(context.errorReports, projectRoot);
|
|
11048
|
-
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${
|
|
11049
|
-
const absolutePath =
|
|
11266
|
+
const fileName = `${formatTimestamp(/* @__PURE__ */ new Date())}-${slugifyCommandPath(context.commandPath)}-${randomUUID3()}.log`;
|
|
11267
|
+
const absolutePath = path13.join(reportDir, fileName);
|
|
11050
11268
|
await mkdir2(reportDir, { recursive: true });
|
|
11051
11269
|
if (reportDirMustStayWithinProject(context.errorReports)) {
|
|
11052
11270
|
await assertReportDirWithinProject(projectRoot, reportDir);
|
|
@@ -11510,7 +11728,7 @@ function inferProgramName(argv) {
|
|
|
11510
11728
|
if (typeof entrypoint !== "string" || entrypoint.length === 0) {
|
|
11511
11729
|
return "toolcraft";
|
|
11512
11730
|
}
|
|
11513
|
-
const parsed =
|
|
11731
|
+
const parsed = path14.parse(entrypoint);
|
|
11514
11732
|
return parsed.name.length > 0 ? parsed.name : "toolcraft";
|
|
11515
11733
|
}
|
|
11516
11734
|
function normalizeRoots(roots, argv) {
|
|
@@ -11568,11 +11786,11 @@ function formatSegment(segment, casing) {
|
|
|
11568
11786
|
const separator = casing === "snake" ? "_" : "-";
|
|
11569
11787
|
return splitWords3(segment).join(separator);
|
|
11570
11788
|
}
|
|
11571
|
-
function toOptionFlag(
|
|
11572
|
-
return `--${
|
|
11789
|
+
function toOptionFlag(path24, casing) {
|
|
11790
|
+
return `--${path24.map((segment) => formatSegment(segment, casing)).join(".")}`;
|
|
11573
11791
|
}
|
|
11574
|
-
function toOptionAttribute(
|
|
11575
|
-
return
|
|
11792
|
+
function toOptionAttribute(path24, casing) {
|
|
11793
|
+
return path24.map((segment) => {
|
|
11576
11794
|
const formatted = formatSegment(segment, casing);
|
|
11577
11795
|
if (casing === "snake") {
|
|
11578
11796
|
return formatted;
|
|
@@ -11583,23 +11801,23 @@ function toOptionAttribute(path23, casing) {
|
|
|
11583
11801
|
).join("");
|
|
11584
11802
|
}).join(".");
|
|
11585
11803
|
}
|
|
11586
|
-
function toDisplayPath(
|
|
11587
|
-
return
|
|
11804
|
+
function toDisplayPath(path24) {
|
|
11805
|
+
return path24.join(".");
|
|
11588
11806
|
}
|
|
11589
|
-
function toUnionKindControlPath(
|
|
11590
|
-
if (
|
|
11807
|
+
function toUnionKindControlPath(path24) {
|
|
11808
|
+
if (path24.length === 0) {
|
|
11591
11809
|
return ["kind"];
|
|
11592
11810
|
}
|
|
11593
|
-
const head =
|
|
11594
|
-
const tail =
|
|
11811
|
+
const head = path24.slice(0, -1);
|
|
11812
|
+
const tail = path24[path24.length - 1] ?? "";
|
|
11595
11813
|
return [...head, `${tail}Kind`];
|
|
11596
11814
|
}
|
|
11597
|
-
function toUnionKindDisplayPath(
|
|
11598
|
-
if (
|
|
11815
|
+
function toUnionKindDisplayPath(path24) {
|
|
11816
|
+
if (path24.length === 0) {
|
|
11599
11817
|
return "kind";
|
|
11600
11818
|
}
|
|
11601
|
-
const head =
|
|
11602
|
-
const tail =
|
|
11819
|
+
const head = path24.slice(0, -1);
|
|
11820
|
+
const tail = path24[path24.length - 1] ?? "";
|
|
11603
11821
|
return [...head, `${tail}-kind`].join(".");
|
|
11604
11822
|
}
|
|
11605
11823
|
function createSyntheticEnumSchema(values) {
|
|
@@ -11615,14 +11833,14 @@ function getRequiredBranchFingerprint(branch, casing) {
|
|
|
11615
11833
|
const requiredKeys = Object.entries(branch.shape).filter(([, schema]) => schema.kind !== "optional").map(([key2]) => formatSegment(key2, casing)).sort();
|
|
11616
11834
|
return requiredKeys.join("+");
|
|
11617
11835
|
}
|
|
11618
|
-
function collectFields(schema, casing, globalLongOptionFlags,
|
|
11836
|
+
function collectFields(schema, casing, globalLongOptionFlags, path24 = [], inheritedOptional = false, variantContext) {
|
|
11619
11837
|
const collected = {
|
|
11620
11838
|
dynamicFields: [],
|
|
11621
11839
|
fields: [],
|
|
11622
11840
|
variants: []
|
|
11623
11841
|
};
|
|
11624
11842
|
for (const [key2, rawChildSchema] of Object.entries(schema.shape)) {
|
|
11625
|
-
const nextPath = [...
|
|
11843
|
+
const nextPath = [...path24, key2];
|
|
11626
11844
|
const runtimeOptional = inheritedOptional || rawChildSchema.kind === "optional";
|
|
11627
11845
|
const childSchema = unwrapOptional2(rawChildSchema);
|
|
11628
11846
|
const requiredWhenActive = rawChildSchema.kind !== "optional" && childSchema.default === void 0;
|
|
@@ -11803,9 +12021,9 @@ function collectFields(schema, casing, globalLongOptionFlags, path23 = [], inher
|
|
|
11803
12021
|
}
|
|
11804
12022
|
return collected;
|
|
11805
12023
|
}
|
|
11806
|
-
function toCommanderOptionAttribute(
|
|
11807
|
-
const optionAttribute = toOptionAttribute(
|
|
11808
|
-
const optionFlag = toOptionFlag(
|
|
12024
|
+
function toCommanderOptionAttribute(path24, casing, globalLongOptionFlags) {
|
|
12025
|
+
const optionAttribute = toOptionAttribute(path24, casing);
|
|
12026
|
+
const optionFlag = toOptionFlag(path24, casing);
|
|
11809
12027
|
if (!globalLongOptionFlags.has(optionFlag)) {
|
|
11810
12028
|
return optionAttribute;
|
|
11811
12029
|
}
|
|
@@ -12774,10 +12992,10 @@ function parseDebugStackMode(value) {
|
|
|
12774
12992
|
formatInvalidEnumMessage("--debug", String(value), ["raw"], { candidates: ["raw"] })
|
|
12775
12993
|
);
|
|
12776
12994
|
}
|
|
12777
|
-
function setNestedValue(target,
|
|
12995
|
+
function setNestedValue(target, path24, value) {
|
|
12778
12996
|
let cursor = target;
|
|
12779
|
-
for (let index = 0; index <
|
|
12780
|
-
const segment =
|
|
12997
|
+
for (let index = 0; index < path24.length - 1; index += 1) {
|
|
12998
|
+
const segment = path24[index] ?? "";
|
|
12781
12999
|
const existing = Object.prototype.hasOwnProperty.call(cursor, segment) ? cursor[segment] : void 0;
|
|
12782
13000
|
if (typeof existing === "object" && existing !== null) {
|
|
12783
13001
|
cursor = existing;
|
|
@@ -12792,7 +13010,7 @@ function setNestedValue(target, path23, value) {
|
|
|
12792
13010
|
});
|
|
12793
13011
|
cursor = next;
|
|
12794
13012
|
}
|
|
12795
|
-
const leaf =
|
|
13013
|
+
const leaf = path24[path24.length - 1];
|
|
12796
13014
|
if (leaf !== void 0) {
|
|
12797
13015
|
Object.defineProperty(cursor, leaf, {
|
|
12798
13016
|
value,
|
|
@@ -12902,21 +13120,21 @@ async function withOutputFormat2(output, fn) {
|
|
|
12902
13120
|
}
|
|
12903
13121
|
function createFs2() {
|
|
12904
13122
|
return {
|
|
12905
|
-
readFile: async (
|
|
12906
|
-
writeFile: async (
|
|
12907
|
-
await writeFile5(
|
|
13123
|
+
readFile: async (path24, encoding = "utf8") => readFile4(path24, { encoding }),
|
|
13124
|
+
writeFile: async (path24, contents) => {
|
|
13125
|
+
await writeFile5(path24, contents);
|
|
12908
13126
|
},
|
|
12909
|
-
exists: async (
|
|
13127
|
+
exists: async (path24) => {
|
|
12910
13128
|
try {
|
|
12911
|
-
await access2(
|
|
13129
|
+
await access2(path24);
|
|
12912
13130
|
return true;
|
|
12913
13131
|
} catch {
|
|
12914
13132
|
return false;
|
|
12915
13133
|
}
|
|
12916
13134
|
},
|
|
12917
|
-
lstat: async (
|
|
13135
|
+
lstat: async (path24) => lstat3(path24),
|
|
12918
13136
|
rename: async (fromPath, toPath) => rename3(fromPath, toPath),
|
|
12919
|
-
unlink: async (
|
|
13137
|
+
unlink: async (path24) => unlink2(path24)
|
|
12920
13138
|
};
|
|
12921
13139
|
}
|
|
12922
13140
|
function createEnv2(values = process.env) {
|
|
@@ -12932,9 +13150,9 @@ function isPlainObject3(value) {
|
|
|
12932
13150
|
function hasFieldValue(value) {
|
|
12933
13151
|
return value !== void 0;
|
|
12934
13152
|
}
|
|
12935
|
-
function hasNestedField(fields,
|
|
13153
|
+
function hasNestedField(fields, path24) {
|
|
12936
13154
|
return fields.some(
|
|
12937
|
-
(field) =>
|
|
13155
|
+
(field) => path24.length < field.path.length && path24.every((segment, index) => field.path[index] === segment)
|
|
12938
13156
|
);
|
|
12939
13157
|
}
|
|
12940
13158
|
function describeExpectedPresetValue(schema) {
|
|
@@ -13040,9 +13258,9 @@ async function loadPresetValues(fields, presetPath) {
|
|
|
13040
13258
|
}
|
|
13041
13259
|
const fieldByPath = new Map(fields.map((field) => [field.displayPath, field]));
|
|
13042
13260
|
const presetValues = {};
|
|
13043
|
-
function visitObject(current,
|
|
13261
|
+
function visitObject(current, path24) {
|
|
13044
13262
|
for (const [key2, value] of Object.entries(current)) {
|
|
13045
|
-
const nextPath = [...
|
|
13263
|
+
const nextPath = [...path24, key2];
|
|
13046
13264
|
const displayPath = toDisplayPath(nextPath);
|
|
13047
13265
|
const field = fieldByPath.get(displayPath);
|
|
13048
13266
|
if (field !== void 0) {
|
|
@@ -13249,8 +13467,8 @@ function createFixtureService(definition) {
|
|
|
13249
13467
|
);
|
|
13250
13468
|
}
|
|
13251
13469
|
function resolveFixturePath(commandPath) {
|
|
13252
|
-
const parsed =
|
|
13253
|
-
return
|
|
13470
|
+
const parsed = path14.parse(commandPath);
|
|
13471
|
+
return path14.join(parsed.dir, `${parsed.name}.fixture.json`);
|
|
13254
13472
|
}
|
|
13255
13473
|
function selectFixtureScenario(scenarios, selector, fixturePath) {
|
|
13256
13474
|
if (isNumericFixtureSelector(selector)) {
|
|
@@ -13384,8 +13602,8 @@ function validateServices(services) {
|
|
|
13384
13602
|
}
|
|
13385
13603
|
}
|
|
13386
13604
|
}
|
|
13387
|
-
function getNestedValue(target,
|
|
13388
|
-
return
|
|
13605
|
+
function getNestedValue(target, path24) {
|
|
13606
|
+
return path24.reduce(
|
|
13389
13607
|
(current, segment) => current !== null && typeof current === "object" ? current[segment] : void 0,
|
|
13390
13608
|
target
|
|
13391
13609
|
);
|
|
@@ -14536,7 +14754,8 @@ function configureCommanderSuggestionOutput(command) {
|
|
|
14536
14754
|
}
|
|
14537
14755
|
async function runCLI(roots, options = {}) {
|
|
14538
14756
|
enableSourceMaps();
|
|
14539
|
-
const
|
|
14757
|
+
const normalizedRoot = normalizeRoots(roots, process.argv);
|
|
14758
|
+
const root = options.approvals === false ? normalizedRoot : mergeApprovalsGroup(normalizedRoot);
|
|
14540
14759
|
await resolveMcpProxies(root, { projectRoot: options.projectRoot });
|
|
14541
14760
|
const casing = options.casing ?? "kebab";
|
|
14542
14761
|
const services = options.services ?? {};
|
|
@@ -14648,7 +14867,7 @@ async function runCLI(roots, options = {}) {
|
|
|
14648
14867
|
}
|
|
14649
14868
|
|
|
14650
14869
|
// src/terminal-pilot.ts
|
|
14651
|
-
import { randomUUID as
|
|
14870
|
+
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
14652
14871
|
|
|
14653
14872
|
// src/terminal-session.ts
|
|
14654
14873
|
import { EventEmitter } from "node:events";
|
|
@@ -14667,7 +14886,7 @@ var DCS = 144;
|
|
|
14667
14886
|
var SOS = 152;
|
|
14668
14887
|
var PM = 158;
|
|
14669
14888
|
var APC = 159;
|
|
14670
|
-
function
|
|
14889
|
+
function stripAnsi4(input) {
|
|
14671
14890
|
let output = "";
|
|
14672
14891
|
for (let index = 0; index < input.length; index += 1) {
|
|
14673
14892
|
const code = input.charCodeAt(index);
|
|
@@ -15547,7 +15766,7 @@ var TerminalScreen = class {
|
|
|
15547
15766
|
cursor,
|
|
15548
15767
|
size
|
|
15549
15768
|
}) {
|
|
15550
|
-
this.lines = Object.freeze(lines.map((line) =>
|
|
15769
|
+
this.lines = Object.freeze(lines.map((line) => stripAnsi4(line)));
|
|
15551
15770
|
this.rawLines = Object.freeze([...rawLines]);
|
|
15552
15771
|
this.cursor = Object.freeze({ ...cursor });
|
|
15553
15772
|
this.size = Object.freeze({ ...size });
|
|
@@ -15702,7 +15921,7 @@ var TerminalSession = class {
|
|
|
15702
15921
|
});
|
|
15703
15922
|
}
|
|
15704
15923
|
async history(opts) {
|
|
15705
|
-
const normalized = normalizeHistoryBuffer(
|
|
15924
|
+
const normalized = normalizeHistoryBuffer(stripAnsi4(this.rawBuffer));
|
|
15706
15925
|
const lines = splitHistoryLines(normalized);
|
|
15707
15926
|
if (opts?.last === void 0) {
|
|
15708
15927
|
return lines;
|
|
@@ -15835,7 +16054,7 @@ function isMissingFileError(error3) {
|
|
|
15835
16054
|
return "code" in error3 && error3.code === "ENOENT";
|
|
15836
16055
|
}
|
|
15837
16056
|
function matchPattern(buffer, pattern) {
|
|
15838
|
-
const clean = normalizeHistoryBuffer(
|
|
16057
|
+
const clean = normalizeHistoryBuffer(stripAnsi4(buffer));
|
|
15839
16058
|
for (const line of clean.split("\n")) {
|
|
15840
16059
|
if (typeof pattern === "string") {
|
|
15841
16060
|
if (line.includes(pattern)) return line;
|
|
@@ -15923,7 +16142,7 @@ var TerminalPilot = class _TerminalPilot {
|
|
|
15923
16142
|
}
|
|
15924
16143
|
async newSession(opts) {
|
|
15925
16144
|
const session = new TerminalSession({
|
|
15926
|
-
id:
|
|
16145
|
+
id: randomUUID4(),
|
|
15927
16146
|
command: opts.command,
|
|
15928
16147
|
args: opts.args,
|
|
15929
16148
|
cwd: opts.cwd,
|
|
@@ -16191,7 +16410,7 @@ var getSession = defineCommand({
|
|
|
16191
16410
|
|
|
16192
16411
|
// ../agent-skill-config/src/configs.ts
|
|
16193
16412
|
import os2 from "node:os";
|
|
16194
|
-
import
|
|
16413
|
+
import path15 from "node:path";
|
|
16195
16414
|
|
|
16196
16415
|
// ../agent-defs/src/agents/claude-code.ts
|
|
16197
16416
|
var claudeCodeAgent = {
|
|
@@ -16500,7 +16719,7 @@ var templateMutation = {
|
|
|
16500
16719
|
};
|
|
16501
16720
|
|
|
16502
16721
|
// ../config-mutations/src/execution/apply-mutation.ts
|
|
16503
|
-
import
|
|
16722
|
+
import path17 from "node:path";
|
|
16504
16723
|
|
|
16505
16724
|
// ../config-mutations/src/formats/json.ts
|
|
16506
16725
|
import * as jsonc from "jsonc-parser";
|
|
@@ -16538,6 +16757,13 @@ function cloneConfigValue(value) {
|
|
|
16538
16757
|
function isConfigObject(value) {
|
|
16539
16758
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16540
16759
|
}
|
|
16760
|
+
function detectIndent(content) {
|
|
16761
|
+
const match = content.match(/^[\t ]+/m);
|
|
16762
|
+
if (match) {
|
|
16763
|
+
return match[0];
|
|
16764
|
+
}
|
|
16765
|
+
return " ";
|
|
16766
|
+
}
|
|
16541
16767
|
function parse3(content) {
|
|
16542
16768
|
if (!content || content.trim() === "") {
|
|
16543
16769
|
return {};
|
|
@@ -16577,6 +16803,9 @@ function merge(base, patch) {
|
|
|
16577
16803
|
}
|
|
16578
16804
|
return result;
|
|
16579
16805
|
}
|
|
16806
|
+
function configValuesEqual(left, right) {
|
|
16807
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
16808
|
+
}
|
|
16580
16809
|
function prune(obj, shape) {
|
|
16581
16810
|
let changed = false;
|
|
16582
16811
|
const result = cloneConfigObject(obj);
|
|
@@ -16613,9 +16842,56 @@ function prune(obj, shape) {
|
|
|
16613
16842
|
}
|
|
16614
16843
|
return { changed, result };
|
|
16615
16844
|
}
|
|
16845
|
+
function modifyAtPath(content, path24, value) {
|
|
16846
|
+
const indent = detectIndent(content);
|
|
16847
|
+
const formattingOptions = {
|
|
16848
|
+
tabSize: indent === " " ? 1 : indent.length,
|
|
16849
|
+
insertSpaces: indent !== " ",
|
|
16850
|
+
eol: "\n"
|
|
16851
|
+
};
|
|
16852
|
+
const edits = jsonc.modify(content, path24, value, { formattingOptions });
|
|
16853
|
+
let result = jsonc.applyEdits(content, edits);
|
|
16854
|
+
if (!result.endsWith("\n")) {
|
|
16855
|
+
result += "\n";
|
|
16856
|
+
}
|
|
16857
|
+
return result;
|
|
16858
|
+
}
|
|
16859
|
+
function removeAtPath(content, path24) {
|
|
16860
|
+
return modifyAtPath(content, path24, void 0);
|
|
16861
|
+
}
|
|
16862
|
+
function serializeUpdate(content, current, next) {
|
|
16863
|
+
let result = content || "{}";
|
|
16864
|
+
result = applyObjectUpdate(result, [], current, next);
|
|
16865
|
+
if (!result.endsWith("\n")) {
|
|
16866
|
+
result += "\n";
|
|
16867
|
+
}
|
|
16868
|
+
return result;
|
|
16869
|
+
}
|
|
16870
|
+
function applyObjectUpdate(content, path24, current, next) {
|
|
16871
|
+
let result = content;
|
|
16872
|
+
for (const key2 of Object.keys(current)) {
|
|
16873
|
+
if (!hasConfigEntry(next, key2)) {
|
|
16874
|
+
result = removeAtPath(result, [...path24, key2]);
|
|
16875
|
+
}
|
|
16876
|
+
}
|
|
16877
|
+
for (const [key2, nextValue] of Object.entries(next)) {
|
|
16878
|
+
const nextPath = [...path24, key2];
|
|
16879
|
+
const hasCurrent = hasConfigEntry(current, key2);
|
|
16880
|
+
const currentValue = hasCurrent ? current[key2] : void 0;
|
|
16881
|
+
if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
|
|
16882
|
+
result = applyObjectUpdate(result, nextPath, currentValue, nextValue);
|
|
16883
|
+
continue;
|
|
16884
|
+
}
|
|
16885
|
+
if (!hasCurrent || !configValuesEqual(currentValue, nextValue)) {
|
|
16886
|
+
result = modifyAtPath(result, nextPath, nextValue);
|
|
16887
|
+
}
|
|
16888
|
+
}
|
|
16889
|
+
return result;
|
|
16890
|
+
}
|
|
16616
16891
|
var jsonFormat = {
|
|
16617
16892
|
parse: parse3,
|
|
16618
16893
|
serialize,
|
|
16894
|
+
serializeUpdate,
|
|
16619
16895
|
merge,
|
|
16620
16896
|
prune
|
|
16621
16897
|
};
|
|
@@ -16799,20 +17075,20 @@ function getConfigFormat(pathOrFormat) {
|
|
|
16799
17075
|
}
|
|
16800
17076
|
return formatRegistry[formatName];
|
|
16801
17077
|
}
|
|
16802
|
-
function detectFormat(
|
|
16803
|
-
const ext = getExtension(
|
|
17078
|
+
function detectFormat(path24) {
|
|
17079
|
+
const ext = getExtension(path24);
|
|
16804
17080
|
return extensionMap[ext];
|
|
16805
17081
|
}
|
|
16806
|
-
function getExtension(
|
|
16807
|
-
const lastDot =
|
|
17082
|
+
function getExtension(path24) {
|
|
17083
|
+
const lastDot = path24.lastIndexOf(".");
|
|
16808
17084
|
if (lastDot === -1) {
|
|
16809
17085
|
return "";
|
|
16810
17086
|
}
|
|
16811
|
-
return
|
|
17087
|
+
return path24.slice(lastDot).toLowerCase();
|
|
16812
17088
|
}
|
|
16813
17089
|
|
|
16814
17090
|
// ../config-mutations/src/execution/path-utils.ts
|
|
16815
|
-
import
|
|
17091
|
+
import path16 from "node:path";
|
|
16816
17092
|
function expandHome(targetPath, homeDir) {
|
|
16817
17093
|
if (!targetPath?.startsWith("~")) {
|
|
16818
17094
|
return targetPath;
|
|
@@ -16829,7 +17105,7 @@ function expandHome(targetPath, homeDir) {
|
|
|
16829
17105
|
remainder = remainder.slice(1);
|
|
16830
17106
|
}
|
|
16831
17107
|
}
|
|
16832
|
-
return remainder.length === 0 ? homeDir :
|
|
17108
|
+
return remainder.length === 0 ? homeDir : path16.join(homeDir, remainder);
|
|
16833
17109
|
}
|
|
16834
17110
|
function validateHomePath(targetPath) {
|
|
16835
17111
|
if (typeof targetPath !== "string" || targetPath.length === 0) {
|
|
@@ -16844,21 +17120,21 @@ function validateHomePath(targetPath) {
|
|
|
16844
17120
|
function resolvePath(rawPath, homeDir, pathMapper) {
|
|
16845
17121
|
validateHomePath(rawPath);
|
|
16846
17122
|
const expanded = expandHome(rawPath, homeDir);
|
|
16847
|
-
const canonicalHome =
|
|
16848
|
-
const canonicalExpanded =
|
|
16849
|
-
const relative =
|
|
16850
|
-
if (relative === ".." || relative.startsWith(`..${
|
|
17123
|
+
const canonicalHome = path16.resolve(homeDir);
|
|
17124
|
+
const canonicalExpanded = path16.resolve(expanded);
|
|
17125
|
+
const relative = path16.relative(canonicalHome, canonicalExpanded);
|
|
17126
|
+
if (relative === ".." || relative.startsWith(`..${path16.sep}`) || path16.isAbsolute(relative)) {
|
|
16851
17127
|
throw new Error(`Target path resolves outside home directory: "${rawPath}"`);
|
|
16852
17128
|
}
|
|
16853
17129
|
if (!pathMapper) {
|
|
16854
17130
|
return canonicalExpanded;
|
|
16855
17131
|
}
|
|
16856
|
-
const rawDirectory =
|
|
17132
|
+
const rawDirectory = path16.dirname(expanded);
|
|
16857
17133
|
const mappedDirectory = pathMapper.mapTargetDirectory({
|
|
16858
17134
|
targetDirectory: rawDirectory
|
|
16859
17135
|
});
|
|
16860
|
-
const filename =
|
|
16861
|
-
return filename.length === 0 ? mappedDirectory :
|
|
17136
|
+
const filename = path16.basename(expanded);
|
|
17137
|
+
return filename.length === 0 ? mappedDirectory : path16.join(mappedDirectory, filename);
|
|
16862
17138
|
}
|
|
16863
17139
|
|
|
16864
17140
|
// ../config-mutations/src/fs-utils.ts
|
|
@@ -16922,8 +17198,8 @@ function isAlreadyExists(error3) {
|
|
|
16922
17198
|
return Boolean(error3 && typeof error3 === "object" && "code" in error3 && error3.code === "EEXIST");
|
|
16923
17199
|
}
|
|
16924
17200
|
async function assertRegularWriteTarget(context, targetPath) {
|
|
16925
|
-
const boundary =
|
|
16926
|
-
let currentPath =
|
|
17201
|
+
const boundary = path17.dirname(path17.resolve(context.homeDir));
|
|
17202
|
+
let currentPath = path17.resolve(targetPath);
|
|
16927
17203
|
while (currentPath !== boundary) {
|
|
16928
17204
|
try {
|
|
16929
17205
|
if ((await context.fs.lstat(currentPath)).isSymbolicLink()) {
|
|
@@ -16934,7 +17210,7 @@ async function assertRegularWriteTarget(context, targetPath) {
|
|
|
16934
17210
|
throw error3;
|
|
16935
17211
|
}
|
|
16936
17212
|
}
|
|
16937
|
-
const parentPath =
|
|
17213
|
+
const parentPath = path17.dirname(currentPath);
|
|
16938
17214
|
if (parentPath === currentPath) {
|
|
16939
17215
|
return;
|
|
16940
17216
|
}
|
|
@@ -16997,7 +17273,7 @@ function pruneKeysByPrefix(table, prefix) {
|
|
|
16997
17273
|
const result = {};
|
|
16998
17274
|
for (const [key2, value] of Object.entries(table)) {
|
|
16999
17275
|
if (!key2.startsWith(prefix)) {
|
|
17000
|
-
result
|
|
17276
|
+
setConfigEntry(result, key2, value);
|
|
17001
17277
|
}
|
|
17002
17278
|
}
|
|
17003
17279
|
return result;
|
|
@@ -17006,28 +17282,43 @@ function isConfigObject4(value) {
|
|
|
17006
17282
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
17007
17283
|
}
|
|
17008
17284
|
function mergeWithPruneByPrefix(base, patch, pruneByPrefix) {
|
|
17009
|
-
const result =
|
|
17285
|
+
const result = cloneConfigObject(base);
|
|
17010
17286
|
const prefixMap = pruneByPrefix ?? {};
|
|
17011
17287
|
for (const [key2, value] of Object.entries(patch)) {
|
|
17288
|
+
if (value === void 0) {
|
|
17289
|
+
continue;
|
|
17290
|
+
}
|
|
17012
17291
|
const current = result[key2];
|
|
17013
17292
|
const prefix = prefixMap[key2];
|
|
17014
17293
|
if (isConfigObject4(current) && isConfigObject4(value)) {
|
|
17015
17294
|
if (prefix) {
|
|
17016
17295
|
const pruned = pruneKeysByPrefix(current, prefix);
|
|
17017
|
-
result
|
|
17296
|
+
setConfigEntry(result, key2, mergePrunedConfigObject(pruned, value));
|
|
17018
17297
|
} else {
|
|
17019
|
-
result
|
|
17020
|
-
current,
|
|
17021
|
-
value,
|
|
17022
|
-
prefixMap
|
|
17023
|
-
);
|
|
17298
|
+
setConfigEntry(result, key2, mergeWithPruneByPrefix(current, value, prefixMap));
|
|
17024
17299
|
}
|
|
17025
17300
|
continue;
|
|
17026
17301
|
}
|
|
17027
|
-
result
|
|
17302
|
+
setConfigEntry(result, key2, value);
|
|
17028
17303
|
}
|
|
17029
17304
|
return result;
|
|
17030
17305
|
}
|
|
17306
|
+
function mergePrunedConfigObject(base, patch) {
|
|
17307
|
+
const result = cloneConfigObject(base);
|
|
17308
|
+
for (const [key2, value] of Object.entries(patch)) {
|
|
17309
|
+
if (value === void 0) {
|
|
17310
|
+
continue;
|
|
17311
|
+
}
|
|
17312
|
+
setConfigEntry(result, key2, value);
|
|
17313
|
+
}
|
|
17314
|
+
return result;
|
|
17315
|
+
}
|
|
17316
|
+
function serializeConfigUpdate(format, rawContent, current, next) {
|
|
17317
|
+
if (rawContent !== null && format.serializeUpdate) {
|
|
17318
|
+
return format.serializeUpdate(rawContent, current, next);
|
|
17319
|
+
}
|
|
17320
|
+
return format.serialize(next);
|
|
17321
|
+
}
|
|
17031
17322
|
async function applyMutation(mutation, context, options) {
|
|
17032
17323
|
switch (mutation.kind) {
|
|
17033
17324
|
case "ensureDirectory":
|
|
@@ -17340,6 +17631,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17340
17631
|
}
|
|
17341
17632
|
const format = getConfigFormat(formatName);
|
|
17342
17633
|
const rawContent = await readFileIfExists(context.fs, targetPath);
|
|
17634
|
+
let preserveContent = rawContent;
|
|
17343
17635
|
let current;
|
|
17344
17636
|
try {
|
|
17345
17637
|
current = rawContent === null ? {} : format.parse(rawContent);
|
|
@@ -17348,6 +17640,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17348
17640
|
await backupInvalidDocument(context, targetPath, rawContent);
|
|
17349
17641
|
}
|
|
17350
17642
|
current = {};
|
|
17643
|
+
preserveContent = null;
|
|
17351
17644
|
}
|
|
17352
17645
|
const value = resolveValue(mutation.value, options);
|
|
17353
17646
|
let merged;
|
|
@@ -17356,7 +17649,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
17356
17649
|
} else {
|
|
17357
17650
|
merged = format.merge(current, value);
|
|
17358
17651
|
}
|
|
17359
|
-
const serialized = format
|
|
17652
|
+
const serialized = serializeConfigUpdate(format, preserveContent, current, merged);
|
|
17360
17653
|
const changed = serialized !== rawContent;
|
|
17361
17654
|
if (changed && !context.dryRun) {
|
|
17362
17655
|
await writeAtomically2(context, targetPath, serialized);
|
|
@@ -17424,7 +17717,7 @@ async function applyConfigPrune(mutation, context, options) {
|
|
|
17424
17717
|
details
|
|
17425
17718
|
};
|
|
17426
17719
|
}
|
|
17427
|
-
const serialized = format
|
|
17720
|
+
const serialized = serializeConfigUpdate(format, rawContent, current, result);
|
|
17428
17721
|
if (!context.dryRun) {
|
|
17429
17722
|
await writeAtomically2(context, targetPath, serialized);
|
|
17430
17723
|
}
|
|
@@ -17449,6 +17742,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17449
17742
|
}
|
|
17450
17743
|
const format = getConfigFormat(formatName);
|
|
17451
17744
|
const rawContent = await readFileIfExists(context.fs, targetPath);
|
|
17745
|
+
let preserveContent = rawContent;
|
|
17452
17746
|
let current;
|
|
17453
17747
|
try {
|
|
17454
17748
|
current = rawContent === null ? {} : format.parse(rawContent);
|
|
@@ -17457,6 +17751,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17457
17751
|
await backupInvalidDocument(context, targetPath, rawContent);
|
|
17458
17752
|
}
|
|
17459
17753
|
current = {};
|
|
17754
|
+
preserveContent = null;
|
|
17460
17755
|
}
|
|
17461
17756
|
const { content: transformed, changed } = mutation.transform(current, options);
|
|
17462
17757
|
if (!changed) {
|
|
@@ -17480,7 +17775,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
17480
17775
|
details
|
|
17481
17776
|
};
|
|
17482
17777
|
}
|
|
17483
|
-
const serialized = format
|
|
17778
|
+
const serialized = serializeConfigUpdate(format, preserveContent, current, transformed);
|
|
17484
17779
|
if (!context.dryRun) {
|
|
17485
17780
|
await writeAtomically2(context, targetPath, serialized);
|
|
17486
17781
|
}
|
|
@@ -17622,7 +17917,7 @@ async function executeMutation(mutation, context, options) {
|
|
|
17622
17917
|
|
|
17623
17918
|
// ../agent-skill-config/src/templates.ts
|
|
17624
17919
|
import { readFile as readFile5, stat } from "node:fs/promises";
|
|
17625
|
-
import
|
|
17920
|
+
import path18 from "node:path";
|
|
17626
17921
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
17627
17922
|
|
|
17628
17923
|
// ../agent-skill-config/src/apply.ts
|
|
@@ -17699,21 +17994,21 @@ async function installSkill(agentId, skill, options) {
|
|
|
17699
17994
|
|
|
17700
17995
|
// ../agent-skill-config/src/resolve-skill-reference.ts
|
|
17701
17996
|
import { statSync as statSync2 } from "node:fs";
|
|
17702
|
-
import
|
|
17997
|
+
import path19 from "node:path";
|
|
17703
17998
|
|
|
17704
17999
|
// ../agent-skill-config/src/git-exclude.ts
|
|
17705
18000
|
import { execFileSync } from "node:child_process";
|
|
17706
18001
|
import * as fs2 from "node:fs";
|
|
17707
|
-
import
|
|
18002
|
+
import path20 from "node:path";
|
|
17708
18003
|
|
|
17709
18004
|
// ../agent-skill-config/src/bridge-active-skills.ts
|
|
17710
18005
|
import * as fs3 from "node:fs";
|
|
17711
|
-
import { createHash as createHash4, randomUUID as
|
|
17712
|
-
import
|
|
18006
|
+
import { createHash as createHash4, randomUUID as randomUUID5 } from "node:crypto";
|
|
18007
|
+
import path21 from "node:path";
|
|
17713
18008
|
|
|
17714
18009
|
// src/commands/installer.ts
|
|
17715
18010
|
import os3 from "node:os";
|
|
17716
|
-
import
|
|
18011
|
+
import path22 from "node:path";
|
|
17717
18012
|
import * as nodeFs2 from "node:fs/promises";
|
|
17718
18013
|
import { readFile as readFile6 } from "node:fs/promises";
|
|
17719
18014
|
var DEFAULT_INSTALL_AGENT = "claude-code";
|
|
@@ -17780,7 +18075,7 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
17780
18075
|
return homeDir;
|
|
17781
18076
|
}
|
|
17782
18077
|
if (targetPath.startsWith("~/")) {
|
|
17783
|
-
return
|
|
18078
|
+
return path22.join(homeDir, targetPath.slice(2));
|
|
17784
18079
|
}
|
|
17785
18080
|
return targetPath;
|
|
17786
18081
|
}
|
|
@@ -17790,18 +18085,18 @@ function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
|
17790
18085
|
throwUnsupportedAgent(agent);
|
|
17791
18086
|
}
|
|
17792
18087
|
return {
|
|
17793
|
-
displayPath:
|
|
18088
|
+
displayPath: path22.join(
|
|
17794
18089
|
scope === "global" ? config.globalSkillDir : config.localSkillDir,
|
|
17795
18090
|
TERMINAL_PILOT_SKILL_NAME
|
|
17796
18091
|
),
|
|
17797
|
-
fullPath:
|
|
17798
|
-
scope === "global" ? resolveHomeRelativePath(config.globalSkillDir, homeDir) :
|
|
18092
|
+
fullPath: path22.join(
|
|
18093
|
+
scope === "global" ? resolveHomeRelativePath(config.globalSkillDir, homeDir) : path22.resolve(cwd, config.localSkillDir),
|
|
17799
18094
|
TERMINAL_PILOT_SKILL_NAME
|
|
17800
18095
|
)
|
|
17801
18096
|
};
|
|
17802
18097
|
}
|
|
17803
18098
|
async function assertNoSymbolicLinkPath(fs4, targetPath) {
|
|
17804
|
-
const rootPath =
|
|
18099
|
+
const rootPath = path22.parse(targetPath).root;
|
|
17805
18100
|
let currentPath = targetPath;
|
|
17806
18101
|
while (currentPath !== rootPath) {
|
|
17807
18102
|
try {
|
|
@@ -17813,7 +18108,7 @@ async function assertNoSymbolicLinkPath(fs4, targetPath) {
|
|
|
17813
18108
|
throw error3;
|
|
17814
18109
|
}
|
|
17815
18110
|
}
|
|
17816
|
-
currentPath =
|
|
18111
|
+
currentPath = path22.dirname(currentPath);
|
|
17817
18112
|
}
|
|
17818
18113
|
}
|
|
17819
18114
|
|
|
@@ -17952,7 +18247,7 @@ var resize = defineCommand({
|
|
|
17952
18247
|
});
|
|
17953
18248
|
|
|
17954
18249
|
// ../terminal-png/src/index.ts
|
|
17955
|
-
import { randomUUID as
|
|
18250
|
+
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
17956
18251
|
import { rename as rename4, rm, writeFile as writeFile6 } from "node:fs/promises";
|
|
17957
18252
|
|
|
17958
18253
|
// ../terminal-png/src/ansi-parser.ts
|
|
@@ -18892,7 +19187,7 @@ async function renderTerminalPng(ansiText, options = {}) {
|
|
|
18892
19187
|
});
|
|
18893
19188
|
const png = renderPng(svg);
|
|
18894
19189
|
if (options.output) {
|
|
18895
|
-
const temporaryPath = `${options.output}.${
|
|
19190
|
+
const temporaryPath = `${options.output}.${randomUUID6()}.tmp`;
|
|
18896
19191
|
try {
|
|
18897
19192
|
await writeFile6(temporaryPath, png, { flag: "wx" });
|
|
18898
19193
|
await rename4(temporaryPath, options.output);
|
|
@@ -18969,7 +19264,7 @@ var type = defineCommand({
|
|
|
18969
19264
|
});
|
|
18970
19265
|
|
|
18971
19266
|
// src/commands/uninstall.ts
|
|
18972
|
-
import { randomUUID as
|
|
19267
|
+
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
18973
19268
|
var params14 = S.Object({
|
|
18974
19269
|
agent: S.Enum(installableAgents, {
|
|
18975
19270
|
description: "Agent to uninstall terminal-pilot from",
|
|
@@ -19005,7 +19300,7 @@ var uninstall = defineCommand({
|
|
|
19005
19300
|
if (!await folderExists(services.fs, skill.fullPath)) {
|
|
19006
19301
|
continue;
|
|
19007
19302
|
}
|
|
19008
|
-
const stagingPath = `${skill.fullPath}.removing-${
|
|
19303
|
+
const stagingPath = `${skill.fullPath}.removing-${randomUUID7()}`;
|
|
19009
19304
|
await services.fs.rename(skill.fullPath, stagingPath);
|
|
19010
19305
|
staged.push({ ...skill, stagingPath });
|
|
19011
19306
|
}
|
|
@@ -19135,7 +19430,7 @@ async function isDirectExecution(argv) {
|
|
|
19135
19430
|
try {
|
|
19136
19431
|
const modulePath = fileURLToPath5(import.meta.url);
|
|
19137
19432
|
const [resolvedEntryPoint, resolvedModulePath] = await Promise.all([
|
|
19138
|
-
realpath2(
|
|
19433
|
+
realpath2(path23.resolve(entryPoint)),
|
|
19139
19434
|
realpath2(modulePath)
|
|
19140
19435
|
]);
|
|
19141
19436
|
return resolvedEntryPoint === resolvedModulePath;
|