terminal-pilot 0.0.19 → 0.0.21
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 +1076 -496
- package/dist/cli.js.map +4 -4
- package/dist/commands/close-session.js.map +1 -1
- package/dist/commands/create-session.js.map +1 -1
- package/dist/commands/fill.js.map +1 -1
- package/dist/commands/get-session.js.map +1 -1
- package/dist/commands/index.js +481 -163
- package/dist/commands/index.js.map +4 -4
- package/dist/commands/install.js +448 -130
- package/dist/commands/install.js.map +4 -4
- package/dist/commands/installer.js +154 -60
- package/dist/commands/installer.js.map +4 -4
- package/dist/commands/list-sessions.js.map +1 -1
- package/dist/commands/press-key.js.map +1 -1
- package/dist/commands/read-history.js.map +1 -1
- package/dist/commands/read-screen.js.map +1 -1
- package/dist/commands/resize.js.map +1 -1
- package/dist/commands/runtime.js.map +1 -1
- package/dist/commands/screenshot.js.map +1 -1
- package/dist/commands/send-signal.js.map +1 -1
- package/dist/commands/type.js.map +1 -1
- package/dist/commands/uninstall.js +187 -93
- package/dist/commands/uninstall.js.map +4 -4
- package/dist/commands/wait-for-exit.js.map +1 -1
- package/dist/commands/wait-for.js.map +1 -1
- package/dist/testing/cli-repl.js +1072 -492
- package/dist/testing/cli-repl.js.map +4 -4
- package/dist/testing/qa-cli.js +1082 -502
- 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 +4 -2
package/dist/commands/index.js
CHANGED
|
@@ -16,19 +16,19 @@ var ToolcraftBugError = class extends Error {
|
|
|
16
16
|
};
|
|
17
17
|
|
|
18
18
|
// ../toolcraft/src/human-in-loop/config.ts
|
|
19
|
-
function validateHumanInLoopOnDefine(
|
|
20
|
-
const label = Array.isArray(
|
|
21
|
-
if (
|
|
22
|
-
throw new Error(`${label} '${
|
|
19
|
+
function validateHumanInLoopOnDefine(config2) {
|
|
20
|
+
const label = Array.isArray(config2.children) ? "group" : "command";
|
|
21
|
+
if (config2.confirm === true && config2.humanInLoop !== void 0 && config2.humanInLoop !== null) {
|
|
22
|
+
throw new Error(`${label} '${config2.name}': use either confirm or humanInLoop, not both`);
|
|
23
23
|
}
|
|
24
|
-
if (
|
|
24
|
+
if (config2.humanInLoop === void 0 || config2.humanInLoop === null) {
|
|
25
25
|
return;
|
|
26
26
|
}
|
|
27
|
-
if (
|
|
28
|
-
throw new Error(`${label} '${
|
|
27
|
+
if (config2.humanInLoop.mode !== "sync" && config2.humanInLoop.mode !== "async") {
|
|
28
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.mode must be "sync" or "async"`);
|
|
29
29
|
}
|
|
30
|
-
if (typeof
|
|
31
|
-
throw new Error(`${label} '${
|
|
30
|
+
if (typeof config2.humanInLoop.message !== "function") {
|
|
31
|
+
throw new Error(`${label} '${config2.name}': humanInLoop.message must be a function`);
|
|
32
32
|
}
|
|
33
33
|
}
|
|
34
34
|
function mergeHumanInLoopFromGroup(groupHumanInLoop, childHumanInLoop) {
|
|
@@ -58,12 +58,12 @@ function assertValidBranches(branches, discriminator) {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
function OneOf(
|
|
62
|
-
assertValidBranches(
|
|
61
|
+
function OneOf(config2) {
|
|
62
|
+
assertValidBranches(config2.branches, config2.discriminator);
|
|
63
63
|
return {
|
|
64
64
|
kind: "oneOf",
|
|
65
|
-
discriminator:
|
|
66
|
-
branches:
|
|
65
|
+
discriminator: config2.discriminator,
|
|
66
|
+
branches: config2.branches
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -262,22 +262,22 @@ function cloneStringArray(values) {
|
|
|
262
262
|
function cloneStringRecord(values) {
|
|
263
263
|
return values === void 0 ? void 0 : { ...values };
|
|
264
264
|
}
|
|
265
|
-
function cloneMcpServerConfig(
|
|
266
|
-
if (
|
|
265
|
+
function cloneMcpServerConfig(config2) {
|
|
266
|
+
if (config2 === void 0) {
|
|
267
267
|
return void 0;
|
|
268
268
|
}
|
|
269
|
-
if (
|
|
269
|
+
if (config2.transport === "stdio") {
|
|
270
270
|
return {
|
|
271
271
|
transport: "stdio",
|
|
272
|
-
command:
|
|
273
|
-
args: cloneStringArray(
|
|
274
|
-
env: cloneStringRecord(
|
|
272
|
+
command: config2.command,
|
|
273
|
+
args: cloneStringArray(config2.args),
|
|
274
|
+
env: cloneStringRecord(config2.env)
|
|
275
275
|
};
|
|
276
276
|
}
|
|
277
277
|
return {
|
|
278
278
|
transport: "http",
|
|
279
|
-
url:
|
|
280
|
-
headers: cloneStringRecord(
|
|
279
|
+
url: config2.url,
|
|
280
|
+
headers: cloneStringRecord(config2.headers)
|
|
281
281
|
};
|
|
282
282
|
}
|
|
283
283
|
function cloneRenameMap(rename2) {
|
|
@@ -399,57 +399,57 @@ function resolveCommandScope(ownScope, inheritedScope) {
|
|
|
399
399
|
function resolveGroupScope(ownScope, inheritedScope) {
|
|
400
400
|
return cloneScope(ownScope ?? inheritedScope);
|
|
401
401
|
}
|
|
402
|
-
function createBaseCommand(
|
|
402
|
+
function createBaseCommand(config2) {
|
|
403
403
|
const command = {
|
|
404
404
|
kind: "command",
|
|
405
|
-
name:
|
|
406
|
-
description:
|
|
407
|
-
aliases: [...
|
|
408
|
-
positional: [...
|
|
409
|
-
params:
|
|
410
|
-
secrets: cloneSecrets(
|
|
411
|
-
scope: resolveCommandScope(
|
|
412
|
-
confirm:
|
|
413
|
-
humanInLoop:
|
|
414
|
-
requires: cloneRequires(
|
|
415
|
-
handler:
|
|
416
|
-
render:
|
|
405
|
+
name: config2.name,
|
|
406
|
+
description: config2.description,
|
|
407
|
+
aliases: [...config2.aliases ?? []],
|
|
408
|
+
positional: [...config2.positional ?? []],
|
|
409
|
+
params: config2.params,
|
|
410
|
+
secrets: cloneSecrets(config2.secrets),
|
|
411
|
+
scope: resolveCommandScope(config2.scope, void 0),
|
|
412
|
+
confirm: config2.confirm ?? false,
|
|
413
|
+
humanInLoop: config2.humanInLoop,
|
|
414
|
+
requires: cloneRequires(config2.requires),
|
|
415
|
+
handler: config2.handler,
|
|
416
|
+
render: config2.render
|
|
417
417
|
};
|
|
418
418
|
Object.defineProperty(command, commandConfigSymbol, {
|
|
419
419
|
value: {
|
|
420
|
-
scope: cloneScope(
|
|
421
|
-
humanInLoop:
|
|
422
|
-
secrets: cloneSecrets(
|
|
423
|
-
requires: cloneRequires(
|
|
420
|
+
scope: cloneScope(config2.scope),
|
|
421
|
+
humanInLoop: config2.humanInLoop,
|
|
422
|
+
secrets: cloneSecrets(config2.secrets),
|
|
423
|
+
requires: cloneRequires(config2.requires),
|
|
424
424
|
sourcePath: inferCommandSourcePath()
|
|
425
425
|
}
|
|
426
426
|
});
|
|
427
427
|
return command;
|
|
428
428
|
}
|
|
429
|
-
function createBaseGroup(
|
|
429
|
+
function createBaseGroup(config2) {
|
|
430
430
|
const group = {
|
|
431
431
|
kind: "group",
|
|
432
|
-
name:
|
|
433
|
-
description:
|
|
434
|
-
aliases: [...
|
|
435
|
-
scope: resolveGroupScope(
|
|
436
|
-
humanInLoop:
|
|
437
|
-
secrets: cloneSecrets(
|
|
438
|
-
requires: cloneRequires(
|
|
432
|
+
name: config2.name,
|
|
433
|
+
description: config2.description,
|
|
434
|
+
aliases: [...config2.aliases ?? []],
|
|
435
|
+
scope: resolveGroupScope(config2.scope, void 0),
|
|
436
|
+
humanInLoop: config2.humanInLoop,
|
|
437
|
+
secrets: cloneSecrets(config2.secrets),
|
|
438
|
+
requires: cloneRequires(config2.requires),
|
|
439
439
|
children: [],
|
|
440
440
|
default: void 0
|
|
441
441
|
};
|
|
442
442
|
Object.defineProperty(group, groupConfigSymbol, {
|
|
443
443
|
value: {
|
|
444
|
-
mcp: cloneMcpServerConfig(
|
|
445
|
-
scope: cloneScope(
|
|
446
|
-
humanInLoop:
|
|
447
|
-
secrets: cloneSecrets(
|
|
448
|
-
tools: cloneStringArray(
|
|
449
|
-
rename: cloneRenameMap(
|
|
450
|
-
requires: cloneRequires(
|
|
451
|
-
children: [...
|
|
452
|
-
default:
|
|
444
|
+
mcp: cloneMcpServerConfig(config2.mcp),
|
|
445
|
+
scope: cloneScope(config2.scope),
|
|
446
|
+
humanInLoop: config2.humanInLoop,
|
|
447
|
+
secrets: cloneSecrets(config2.secrets),
|
|
448
|
+
tools: cloneStringArray(config2.tools),
|
|
449
|
+
rename: cloneRenameMap(config2.rename),
|
|
450
|
+
requires: cloneRequires(config2.requires),
|
|
451
|
+
children: [...config2.children],
|
|
452
|
+
default: config2.default
|
|
453
453
|
}
|
|
454
454
|
});
|
|
455
455
|
return group;
|
|
@@ -552,10 +552,10 @@ function materializeNode(node, inherited) {
|
|
|
552
552
|
}
|
|
553
553
|
return materializeGroup(node, inherited);
|
|
554
554
|
}
|
|
555
|
-
function defineCommand(
|
|
556
|
-
validateHumanInLoopOnDefine(
|
|
555
|
+
function defineCommand(config2) {
|
|
556
|
+
validateHumanInLoopOnDefine(config2);
|
|
557
557
|
return materializeCommand(
|
|
558
|
-
createBaseCommand(
|
|
558
|
+
createBaseCommand(config2),
|
|
559
559
|
{
|
|
560
560
|
scope: void 0,
|
|
561
561
|
humanInLoop: void 0,
|
|
@@ -564,10 +564,10 @@ function defineCommand(config) {
|
|
|
564
564
|
}
|
|
565
565
|
);
|
|
566
566
|
}
|
|
567
|
-
function defineGroup(
|
|
568
|
-
validateRenameMap(
|
|
569
|
-
validateHumanInLoopOnDefine(
|
|
570
|
-
return materializeGroup(createBaseGroup(
|
|
567
|
+
function defineGroup(config2) {
|
|
568
|
+
validateRenameMap(config2.rename);
|
|
569
|
+
validateHumanInLoopOnDefine(config2);
|
|
570
|
+
return materializeGroup(createBaseGroup(config2), {
|
|
571
571
|
scope: void 0,
|
|
572
572
|
humanInLoop: void 0,
|
|
573
573
|
secrets: {},
|
|
@@ -2325,11 +2325,11 @@ function resolveAgentSupport(input, registry = agentSkillConfigs) {
|
|
|
2325
2325
|
if (!resolvedId) {
|
|
2326
2326
|
return { status: "unknown", input };
|
|
2327
2327
|
}
|
|
2328
|
-
const
|
|
2329
|
-
if (!
|
|
2328
|
+
const config2 = registry[resolvedId];
|
|
2329
|
+
if (!config2) {
|
|
2330
2330
|
return { status: "unsupported", input, id: resolvedId };
|
|
2331
2331
|
}
|
|
2332
|
-
return { status: "supported", input, id: resolvedId, config: { ...
|
|
2332
|
+
return { status: "supported", input, id: resolvedId, config: { ...config2 } };
|
|
2333
2333
|
}
|
|
2334
2334
|
function getAgentConfig(agentId) {
|
|
2335
2335
|
const support = resolveAgentSupport(agentId);
|
|
@@ -2430,7 +2430,7 @@ var templateMutation = {
|
|
|
2430
2430
|
// ../config-mutations/src/execution/apply-mutation.ts
|
|
2431
2431
|
import path4 from "node:path";
|
|
2432
2432
|
|
|
2433
|
-
// ../design
|
|
2433
|
+
// ../toolcraft-design/src/internal/color-support.ts
|
|
2434
2434
|
function supportsColor(env = process.env, stream = process.stdout) {
|
|
2435
2435
|
if (env.FORCE_COLOR !== void 0 && env.FORCE_COLOR !== "0") {
|
|
2436
2436
|
return true;
|
|
@@ -2444,7 +2444,7 @@ function supportsColor(env = process.env, stream = process.stdout) {
|
|
|
2444
2444
|
return typeof env.TERM === "string" && env.TERM.length > 0 && env.TERM !== "dumb";
|
|
2445
2445
|
}
|
|
2446
2446
|
|
|
2447
|
-
// ../design
|
|
2447
|
+
// ../toolcraft-design/src/components/color.ts
|
|
2448
2448
|
var reset = "\x1B[0m";
|
|
2449
2449
|
var ansiStyles = {
|
|
2450
2450
|
reset: { open: reset },
|
|
@@ -2546,41 +2546,122 @@ function createColor(styles = []) {
|
|
|
2546
2546
|
}
|
|
2547
2547
|
var color = createColor();
|
|
2548
2548
|
|
|
2549
|
-
// ../design
|
|
2550
|
-
var
|
|
2551
|
-
|
|
2552
|
-
|
|
2553
|
-
|
|
2554
|
-
number: (text4) => color.cyanBright(text4),
|
|
2555
|
-
intro: (text4) => color.bgMagenta.white(` Poe - ${text4} `),
|
|
2556
|
-
resolvedSymbol: color.magenta("\u25C7"),
|
|
2557
|
-
errorSymbol: color.red("\u25A0"),
|
|
2558
|
-
accent: (text4) => color.cyan(text4),
|
|
2559
|
-
muted: (text4) => color.dim(text4),
|
|
2560
|
-
success: (text4) => color.green(text4),
|
|
2561
|
-
warning: (text4) => color.yellow(text4),
|
|
2562
|
-
error: (text4) => color.red(text4),
|
|
2563
|
-
info: (text4) => color.magenta(text4),
|
|
2564
|
-
badge: (text4) => color.bgYellow.black(` ${text4} `)
|
|
2549
|
+
// ../toolcraft-design/src/tokens/brand.ts
|
|
2550
|
+
var brands = {
|
|
2551
|
+
purple: { name: "purple", primary: "#a200ff" },
|
|
2552
|
+
blue: { name: "blue", primary: "#2f6fed" },
|
|
2553
|
+
green: { name: "green", primary: "#1f9d57" }
|
|
2565
2554
|
};
|
|
2566
|
-
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2570
|
-
|
|
2571
|
-
intro: (text4) => color.bgHex("#a200ff").white(` Poe - ${text4} `),
|
|
2572
|
-
resolvedSymbol: color.hex("#a200ff")("\u25C7"),
|
|
2573
|
-
errorSymbol: color.hex("#cc0000")("\u25A0"),
|
|
2574
|
-
accent: (text4) => color.hex("#006699").bold(text4),
|
|
2575
|
-
muted: (text4) => color.hex("#666666")(text4),
|
|
2576
|
-
success: (text4) => color.hex("#008800")(text4),
|
|
2577
|
-
warning: (text4) => color.hex("#cc6600")(text4),
|
|
2578
|
-
error: (text4) => color.hex("#cc0000")(text4),
|
|
2579
|
-
info: (text4) => color.hex("#a200ff")(text4),
|
|
2580
|
-
badge: (text4) => color.bgHex("#cc6600").white(` ${text4} `)
|
|
2555
|
+
|
|
2556
|
+
// ../toolcraft-design/src/internal/theme-state.ts
|
|
2557
|
+
var defaults = {
|
|
2558
|
+
brand: "purple",
|
|
2559
|
+
label: "Poe"
|
|
2581
2560
|
};
|
|
2561
|
+
var config = { ...defaults };
|
|
2562
|
+
var revision = 0;
|
|
2563
|
+
var brandConfigured = false;
|
|
2564
|
+
function getThemeConfig() {
|
|
2565
|
+
return { ...config };
|
|
2566
|
+
}
|
|
2567
|
+
function getThemeRevision() {
|
|
2568
|
+
return revision;
|
|
2569
|
+
}
|
|
2570
|
+
function isThemeBrandConfigured() {
|
|
2571
|
+
return brandConfigured;
|
|
2572
|
+
}
|
|
2582
2573
|
|
|
2583
|
-
// ../design
|
|
2574
|
+
// ../toolcraft-design/src/tokens/colors.ts
|
|
2575
|
+
var brand = brands.purple.primary;
|
|
2576
|
+
function withStyles(palette, styles) {
|
|
2577
|
+
return Object.defineProperty(palette, "styles", {
|
|
2578
|
+
value: styles,
|
|
2579
|
+
enumerable: false
|
|
2580
|
+
});
|
|
2581
|
+
}
|
|
2582
|
+
function brandColor(activeBrand, purple) {
|
|
2583
|
+
return activeBrand.name === "purple" ? purple : color.hex(activeBrand.primary);
|
|
2584
|
+
}
|
|
2585
|
+
function brandBackground(activeBrand, purple) {
|
|
2586
|
+
return activeBrand.name === "purple" ? purple : color.bgHex(activeBrand.primary);
|
|
2587
|
+
}
|
|
2588
|
+
function createPalette(activeBrand, mode) {
|
|
2589
|
+
const isPurple = activeBrand.name === "purple";
|
|
2590
|
+
if (mode === "light") {
|
|
2591
|
+
const active2 = color.hex(activeBrand.primary);
|
|
2592
|
+
const prompt2 = isPurple ? color.hex("#006699") : active2;
|
|
2593
|
+
const number2 = isPurple ? color.hex("#0077cc") : active2;
|
|
2594
|
+
return withStyles(
|
|
2595
|
+
{
|
|
2596
|
+
header: (text4) => active2.bold(text4),
|
|
2597
|
+
divider: (text4) => color.hex("#666666")(text4),
|
|
2598
|
+
prompt: (text4) => prompt2.bold(text4),
|
|
2599
|
+
number: (text4) => number2.bold(text4),
|
|
2600
|
+
intro: (text4) => color.bgHex(activeBrand.primary).white(` ${getThemeConfig().label} - ${text4} `),
|
|
2601
|
+
get resolvedSymbol() {
|
|
2602
|
+
return active2("\u25C7");
|
|
2603
|
+
},
|
|
2604
|
+
get errorSymbol() {
|
|
2605
|
+
return color.hex("#cc0000")("\u25A0");
|
|
2606
|
+
},
|
|
2607
|
+
accent: (text4) => prompt2.bold(text4),
|
|
2608
|
+
muted: (text4) => color.hex("#666666")(text4),
|
|
2609
|
+
success: (text4) => color.hex("#008800")(text4),
|
|
2610
|
+
warning: (text4) => color.hex("#cc6600")(text4),
|
|
2611
|
+
error: (text4) => color.hex("#cc0000")(text4),
|
|
2612
|
+
info: (text4) => active2(text4),
|
|
2613
|
+
badge: (text4) => color.bgHex("#cc6600").white(` ${text4} `)
|
|
2614
|
+
},
|
|
2615
|
+
{
|
|
2616
|
+
accent: { fg: isPurple ? "#006699" : activeBrand.primary, bold: true },
|
|
2617
|
+
muted: { fg: "#666666" },
|
|
2618
|
+
success: { fg: "#008800" },
|
|
2619
|
+
warning: { fg: "#cc6600" },
|
|
2620
|
+
error: { fg: "#cc0000" },
|
|
2621
|
+
info: { fg: activeBrand.primary }
|
|
2622
|
+
}
|
|
2623
|
+
);
|
|
2624
|
+
}
|
|
2625
|
+
const active = brandColor(activeBrand, color.magenta);
|
|
2626
|
+
const activeBright = brandColor(activeBrand, color.magentaBright);
|
|
2627
|
+
const activeBackground = brandBackground(activeBrand, color.bgMagenta);
|
|
2628
|
+
const prompt = isPurple ? color.cyan : active;
|
|
2629
|
+
const number = isPurple ? color.cyanBright : active;
|
|
2630
|
+
return withStyles(
|
|
2631
|
+
{
|
|
2632
|
+
header: (text4) => activeBright.bold(text4),
|
|
2633
|
+
divider: (text4) => color.dim(text4),
|
|
2634
|
+
prompt: (text4) => prompt(text4),
|
|
2635
|
+
number: (text4) => number(text4),
|
|
2636
|
+
intro: (text4) => activeBackground.white(` ${getThemeConfig().label} - ${text4} `),
|
|
2637
|
+
get resolvedSymbol() {
|
|
2638
|
+
return active("\u25C7");
|
|
2639
|
+
},
|
|
2640
|
+
get errorSymbol() {
|
|
2641
|
+
return color.red("\u25A0");
|
|
2642
|
+
},
|
|
2643
|
+
accent: (text4) => prompt(text4),
|
|
2644
|
+
muted: (text4) => color.dim(text4),
|
|
2645
|
+
success: (text4) => color.green(text4),
|
|
2646
|
+
warning: (text4) => color.yellow(text4),
|
|
2647
|
+
error: (text4) => color.red(text4),
|
|
2648
|
+
info: (text4) => active(text4),
|
|
2649
|
+
badge: (text4) => color.bgYellow.black(` ${text4} `)
|
|
2650
|
+
},
|
|
2651
|
+
{
|
|
2652
|
+
accent: { fg: isPurple ? "cyan" : activeBrand.primary, bold: true },
|
|
2653
|
+
muted: { dim: true },
|
|
2654
|
+
success: { fg: "green" },
|
|
2655
|
+
warning: { fg: "yellow" },
|
|
2656
|
+
error: { fg: "red" },
|
|
2657
|
+
info: { fg: isPurple ? "magenta" : activeBrand.primary }
|
|
2658
|
+
}
|
|
2659
|
+
);
|
|
2660
|
+
}
|
|
2661
|
+
var dark = createPalette(brands.purple, "dark");
|
|
2662
|
+
var light = createPalette(brands.purple, "light");
|
|
2663
|
+
|
|
2664
|
+
// ../toolcraft-design/src/internal/output-format.ts
|
|
2584
2665
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2585
2666
|
var VALID_FORMATS = /* @__PURE__ */ new Set(["terminal", "markdown", "json"]);
|
|
2586
2667
|
var formatStorage = new AsyncLocalStorage();
|
|
@@ -2598,7 +2679,7 @@ function resolveOutputFormat(env = process.env) {
|
|
|
2598
2679
|
return cached;
|
|
2599
2680
|
}
|
|
2600
2681
|
|
|
2601
|
-
// ../design
|
|
2682
|
+
// ../toolcraft-design/src/internal/theme-detect.ts
|
|
2602
2683
|
function detectThemeFromEnv(env) {
|
|
2603
2684
|
const apple = env.APPLE_INTERFACE_STYLE;
|
|
2604
2685
|
if (typeof apple === "string") {
|
|
@@ -2635,17 +2716,30 @@ function resolveThemeName(env = process.env) {
|
|
|
2635
2716
|
}
|
|
2636
2717
|
return "dark";
|
|
2637
2718
|
}
|
|
2638
|
-
var
|
|
2719
|
+
var themeCache = /* @__PURE__ */ new Map();
|
|
2720
|
+
var cachedRevision = -1;
|
|
2639
2721
|
function getTheme(env) {
|
|
2722
|
+
const themeName = resolveThemeName(env);
|
|
2723
|
+
const config2 = getThemeConfig();
|
|
2724
|
+
const requestedBrand = env?.POE_BRAND?.toLowerCase();
|
|
2725
|
+
const activeBrandName = !isThemeBrandConfigured() && requestedBrand && Object.hasOwn(brands, requestedBrand) ? requestedBrand : config2.brand;
|
|
2726
|
+
const revision2 = getThemeRevision();
|
|
2727
|
+
if (revision2 !== cachedRevision) {
|
|
2728
|
+
themeCache.clear();
|
|
2729
|
+
cachedRevision = revision2;
|
|
2730
|
+
}
|
|
2731
|
+
const cacheKey = `${activeBrandName}:${themeName}`;
|
|
2732
|
+
const cachedTheme = themeCache.get(cacheKey);
|
|
2640
2733
|
if (cachedTheme) {
|
|
2641
2734
|
return cachedTheme;
|
|
2642
2735
|
}
|
|
2643
|
-
const
|
|
2644
|
-
|
|
2645
|
-
|
|
2736
|
+
const activeBrand = brands[activeBrandName];
|
|
2737
|
+
const theme = activeBrandName === "purple" ? themeName === "light" ? light : dark : createPalette(activeBrand, themeName);
|
|
2738
|
+
themeCache.set(cacheKey, theme);
|
|
2739
|
+
return theme;
|
|
2646
2740
|
}
|
|
2647
2741
|
|
|
2648
|
-
// ../design
|
|
2742
|
+
// ../toolcraft-design/src/components/symbols.ts
|
|
2649
2743
|
var symbols = {
|
|
2650
2744
|
get info() {
|
|
2651
2745
|
const format = resolveOutputFormat();
|
|
@@ -2699,12 +2793,12 @@ var symbols = {
|
|
|
2699
2793
|
}
|
|
2700
2794
|
};
|
|
2701
2795
|
|
|
2702
|
-
// ../design
|
|
2796
|
+
// ../toolcraft-design/src/internal/strip-ansi.ts
|
|
2703
2797
|
function stripAnsi2(value) {
|
|
2704
2798
|
return value.replace(/\u001b\[[0-9;]*m/g, "");
|
|
2705
2799
|
}
|
|
2706
2800
|
|
|
2707
|
-
// ../design
|
|
2801
|
+
// ../toolcraft-design/src/prompts/primitives/log.ts
|
|
2708
2802
|
function renderMarkdownInline(value) {
|
|
2709
2803
|
return stripAnsi2(value).replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll("\r", " ");
|
|
2710
2804
|
}
|
|
@@ -2831,7 +2925,7 @@ var log = {
|
|
|
2831
2925
|
error
|
|
2832
2926
|
};
|
|
2833
2927
|
|
|
2834
|
-
// ../design
|
|
2928
|
+
// ../toolcraft-design/src/components/logger.ts
|
|
2835
2929
|
function createLogger(emitter) {
|
|
2836
2930
|
const emit = (level, message2) => {
|
|
2837
2931
|
if (emitter) {
|
|
@@ -2892,13 +2986,14 @@ function createLogger(emitter) {
|
|
|
2892
2986
|
}
|
|
2893
2987
|
var logger = createLogger();
|
|
2894
2988
|
|
|
2895
|
-
// ../design
|
|
2989
|
+
// ../toolcraft-design/src/components/help-formatter.ts
|
|
2896
2990
|
var graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
2897
2991
|
|
|
2898
|
-
// ../design
|
|
2992
|
+
// ../toolcraft-design/src/components/table.ts
|
|
2899
2993
|
var graphemeSegmenter2 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
2900
2994
|
|
|
2901
|
-
// ../design
|
|
2995
|
+
// ../toolcraft-design/src/components/template.ts
|
|
2996
|
+
var MAX_PARTIAL_DEPTH = 100;
|
|
2902
2997
|
var HTML_ESCAPE = {
|
|
2903
2998
|
"&": "&",
|
|
2904
2999
|
"<": "<",
|
|
@@ -2910,14 +3005,27 @@ var HTML_ESCAPE = {
|
|
|
2910
3005
|
"=": "="
|
|
2911
3006
|
};
|
|
2912
3007
|
function renderTemplate(template, view, options = {}) {
|
|
2913
|
-
const prepared = options.yield === void 0 ? template : template.split("{{yield}}").join(options.yield);
|
|
3008
|
+
const prepared = options.yield === void 0 ? template : resolveTemplatePartials(template, options.partials ?? {}).split("{{yield}}").join(options.yield);
|
|
2914
3009
|
const tokens = parseTemplate(prepared);
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
3010
|
+
validatePartialReferences(tokens, options.partials ?? {}, []);
|
|
3011
|
+
if (options.validate === true) {
|
|
3012
|
+
const expanded = resolveTemplatePartials(prepared, options.partials ?? {});
|
|
3013
|
+
validateVariables(parseTemplate(expanded), { view });
|
|
3014
|
+
}
|
|
3015
|
+
const state = {
|
|
3016
|
+
escape: options.escape === "none" ? String : escapeHtml,
|
|
3017
|
+
partials: options.partials ?? {},
|
|
3018
|
+
partialStack: [],
|
|
3019
|
+
preserveMissing: options.yield !== void 0 && options.escape === "none",
|
|
3020
|
+
validate: options.validate === true
|
|
3021
|
+
};
|
|
3022
|
+
return renderTokens(tokens, { view }, prepared, state);
|
|
3023
|
+
}
|
|
3024
|
+
function resolveTemplatePartials(template, partials) {
|
|
3025
|
+
return expandTemplatePartials(template, partials, []);
|
|
2918
3026
|
}
|
|
2919
|
-
function renderTemplateInContext(template, context,
|
|
2920
|
-
return renderTokens(parseTemplate(template), context, template,
|
|
3027
|
+
function renderTemplateInContext(template, context, state) {
|
|
3028
|
+
return renderTokens(parseTemplate(template), context, template, state);
|
|
2921
3029
|
}
|
|
2922
3030
|
function parseTemplate(template) {
|
|
2923
3031
|
const root = [];
|
|
@@ -2940,9 +3048,6 @@ function parseTemplate(template) {
|
|
|
2940
3048
|
index = standalone?.nextIndex ?? parsed.end;
|
|
2941
3049
|
continue;
|
|
2942
3050
|
}
|
|
2943
|
-
if (parsed.kind === "partial") {
|
|
2944
|
-
throw new Error(`Partials are not supported: "${parsed.name}"`);
|
|
2945
|
-
}
|
|
2946
3051
|
if (parsed.kind === "delimiter") {
|
|
2947
3052
|
throw new Error("Custom delimiters are not supported");
|
|
2948
3053
|
}
|
|
@@ -2960,6 +3065,15 @@ function parseTemplate(template) {
|
|
|
2960
3065
|
index = standalone?.nextIndex ?? parsed.end;
|
|
2961
3066
|
continue;
|
|
2962
3067
|
}
|
|
3068
|
+
if (parsed.kind === "partial") {
|
|
3069
|
+
tokens.push({
|
|
3070
|
+
type: "partial",
|
|
3071
|
+
name: parsed.name,
|
|
3072
|
+
indent: standalone === void 0 ? "" : template.slice(standalone.lineStart, open)
|
|
3073
|
+
});
|
|
3074
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
3075
|
+
continue;
|
|
3076
|
+
}
|
|
2963
3077
|
if (parsed.kind === "close") {
|
|
2964
3078
|
const frame2 = stack.pop();
|
|
2965
3079
|
if (frame2 === void 0) {
|
|
@@ -3030,7 +3144,7 @@ function getStandalone(template, tagStart, tagEnd, kind) {
|
|
|
3030
3144
|
}
|
|
3031
3145
|
return void 0;
|
|
3032
3146
|
}
|
|
3033
|
-
function renderTokens(tokens, context, template,
|
|
3147
|
+
function renderTokens(tokens, context, template, state) {
|
|
3034
3148
|
let output = "";
|
|
3035
3149
|
for (const token of tokens) {
|
|
3036
3150
|
switch (token.type) {
|
|
@@ -3039,32 +3153,62 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
3039
3153
|
continue;
|
|
3040
3154
|
case "name":
|
|
3041
3155
|
case "unescaped": {
|
|
3042
|
-
const
|
|
3043
|
-
if (value == null) {
|
|
3044
|
-
if (
|
|
3156
|
+
const result = lookup2(context, token.name);
|
|
3157
|
+
if (!result.hit || result.value == null) {
|
|
3158
|
+
if (state.validate) {
|
|
3159
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
3160
|
+
}
|
|
3161
|
+
if (state.preserveMissing) {
|
|
3045
3162
|
output += token.raw;
|
|
3046
3163
|
}
|
|
3047
3164
|
continue;
|
|
3048
3165
|
}
|
|
3049
|
-
const rendered = String(value);
|
|
3050
|
-
output += token.type === "name" ? escape(rendered) : rendered;
|
|
3166
|
+
const rendered = String(result.value);
|
|
3167
|
+
output += token.type === "name" ? state.escape(rendered) : rendered;
|
|
3168
|
+
continue;
|
|
3169
|
+
}
|
|
3170
|
+
case "partial": {
|
|
3171
|
+
if (!Object.hasOwn(state.partials, token.name)) {
|
|
3172
|
+
throw new Error(`Partial "${token.name}" not found.`);
|
|
3173
|
+
}
|
|
3174
|
+
if (state.partialStack.includes(token.name)) {
|
|
3175
|
+
throw new Error(
|
|
3176
|
+
`Circular partial reference detected: ${[...state.partialStack, token.name].join(" -> ")}.`
|
|
3177
|
+
);
|
|
3178
|
+
}
|
|
3179
|
+
if (state.partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
3180
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
3181
|
+
}
|
|
3182
|
+
const partial = indentPartial(state.partials[token.name], token.indent);
|
|
3183
|
+
output += renderTokens(parseTemplate(partial), context, partial, {
|
|
3184
|
+
...state,
|
|
3185
|
+
partialStack: [...state.partialStack, token.name]
|
|
3186
|
+
});
|
|
3051
3187
|
continue;
|
|
3052
3188
|
}
|
|
3053
3189
|
case "inverted": {
|
|
3054
|
-
const
|
|
3190
|
+
const result = lookup2(context, token.name);
|
|
3191
|
+
if (!result.hit && state.validate) {
|
|
3192
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
3193
|
+
}
|
|
3194
|
+
const value = result.value;
|
|
3055
3195
|
if (!value || Array.isArray(value) && value.length === 0) {
|
|
3056
|
-
output += renderTokens(token.children, context, template,
|
|
3196
|
+
output += renderTokens(token.children, context, template, state);
|
|
3057
3197
|
}
|
|
3058
3198
|
continue;
|
|
3059
3199
|
}
|
|
3060
3200
|
case "section": {
|
|
3061
|
-
const
|
|
3201
|
+
const result = lookup2(context, token.name);
|
|
3202
|
+
if (!result.hit && state.validate) {
|
|
3203
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
3204
|
+
}
|
|
3205
|
+
const value = result.value;
|
|
3062
3206
|
if (!value) {
|
|
3063
3207
|
continue;
|
|
3064
3208
|
}
|
|
3065
3209
|
if (Array.isArray(value)) {
|
|
3066
3210
|
for (const item of value) {
|
|
3067
|
-
output += renderTokens(token.children, pushContext(context, item), template,
|
|
3211
|
+
output += renderTokens(token.children, pushContext(context, item), template, state);
|
|
3068
3212
|
}
|
|
3069
3213
|
continue;
|
|
3070
3214
|
}
|
|
@@ -3073,7 +3217,7 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
3073
3217
|
const rendered = value.call(
|
|
3074
3218
|
context.view,
|
|
3075
3219
|
raw,
|
|
3076
|
-
(nextTemplate) => renderTemplateInContext(nextTemplate, context,
|
|
3220
|
+
(nextTemplate) => renderTemplateInContext(nextTemplate, context, state)
|
|
3077
3221
|
);
|
|
3078
3222
|
if (rendered != null) {
|
|
3079
3223
|
output += String(rendered);
|
|
@@ -3081,10 +3225,10 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
3081
3225
|
continue;
|
|
3082
3226
|
}
|
|
3083
3227
|
if (typeof value === "object" || typeof value === "string" || typeof value === "number") {
|
|
3084
|
-
output += renderTokens(token.children, pushContext(context, value), template,
|
|
3228
|
+
output += renderTokens(token.children, pushContext(context, value), template, state);
|
|
3085
3229
|
continue;
|
|
3086
3230
|
}
|
|
3087
|
-
output += renderTokens(token.children, context, template,
|
|
3231
|
+
output += renderTokens(token.children, context, template, state);
|
|
3088
3232
|
}
|
|
3089
3233
|
}
|
|
3090
3234
|
}
|
|
@@ -3092,17 +3236,115 @@ function renderTokens(tokens, context, template, escape, preserveMissing) {
|
|
|
3092
3236
|
}
|
|
3093
3237
|
function lookup2(context, name) {
|
|
3094
3238
|
if (name === ".") {
|
|
3095
|
-
return callLambda(context.view, context.view);
|
|
3239
|
+
return { hit: true, value: callLambda(context.view, context.view) };
|
|
3096
3240
|
}
|
|
3097
3241
|
let cursor = context;
|
|
3098
3242
|
while (cursor !== void 0) {
|
|
3099
3243
|
const result = name.includes(".") ? lookupDotted(cursor.view, name) : lookupName(cursor.view, name);
|
|
3100
3244
|
if (result.hit) {
|
|
3101
|
-
return callLambda(result.value, cursor.view);
|
|
3245
|
+
return { hit: true, value: callLambda(result.value, cursor.view) };
|
|
3102
3246
|
}
|
|
3103
3247
|
cursor = cursor.parent;
|
|
3104
3248
|
}
|
|
3105
|
-
return void 0;
|
|
3249
|
+
return { hit: false, value: void 0 };
|
|
3250
|
+
}
|
|
3251
|
+
function validateVariables(tokens, context) {
|
|
3252
|
+
for (const token of tokens) {
|
|
3253
|
+
if (token.type === "text" || token.type === "partial") {
|
|
3254
|
+
continue;
|
|
3255
|
+
}
|
|
3256
|
+
if (token.type === "name" || token.type === "unescaped") {
|
|
3257
|
+
if (!lookup2(context, token.name).hit) {
|
|
3258
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
3259
|
+
}
|
|
3260
|
+
continue;
|
|
3261
|
+
}
|
|
3262
|
+
if (token.type !== "section" && token.type !== "inverted") {
|
|
3263
|
+
continue;
|
|
3264
|
+
}
|
|
3265
|
+
const result = lookup2(context, token.name);
|
|
3266
|
+
if (!result.hit) {
|
|
3267
|
+
throw new Error(`Template variable "${token.name}" not found.`);
|
|
3268
|
+
}
|
|
3269
|
+
if (Array.isArray(result.value) && result.value.length > 0) {
|
|
3270
|
+
for (const item of result.value) {
|
|
3271
|
+
validateVariables(token.children, pushContext(context, item));
|
|
3272
|
+
}
|
|
3273
|
+
continue;
|
|
3274
|
+
}
|
|
3275
|
+
if (typeof result.value === "object" && result.value !== null || typeof result.value === "string" || typeof result.value === "number") {
|
|
3276
|
+
validateVariables(token.children, pushContext(context, result.value));
|
|
3277
|
+
continue;
|
|
3278
|
+
}
|
|
3279
|
+
validateVariables(token.children, context);
|
|
3280
|
+
}
|
|
3281
|
+
}
|
|
3282
|
+
function validatePartialReferences(tokens, partials, partialStack) {
|
|
3283
|
+
for (const token of tokens) {
|
|
3284
|
+
if (token.type === "section" || token.type === "inverted") {
|
|
3285
|
+
validatePartialReferences(token.children, partials, partialStack);
|
|
3286
|
+
continue;
|
|
3287
|
+
}
|
|
3288
|
+
if (token.type !== "partial") {
|
|
3289
|
+
continue;
|
|
3290
|
+
}
|
|
3291
|
+
if (!Object.hasOwn(partials, token.name)) {
|
|
3292
|
+
throw new Error(`Partial "${token.name}" not found.`);
|
|
3293
|
+
}
|
|
3294
|
+
if (partialStack.includes(token.name)) {
|
|
3295
|
+
throw new Error(
|
|
3296
|
+
`Circular partial reference detected: ${[...partialStack, token.name].join(" -> ")}.`
|
|
3297
|
+
);
|
|
3298
|
+
}
|
|
3299
|
+
if (partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
3300
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
3301
|
+
}
|
|
3302
|
+
validatePartialReferences(parseTemplate(partials[token.name]), partials, [
|
|
3303
|
+
...partialStack,
|
|
3304
|
+
token.name
|
|
3305
|
+
]);
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
function indentPartial(partial, indent) {
|
|
3309
|
+
if (indent === "") {
|
|
3310
|
+
return partial;
|
|
3311
|
+
}
|
|
3312
|
+
return partial.split("\n").map((line) => line === "" ? "" : `${indent}${line}`).join("\n");
|
|
3313
|
+
}
|
|
3314
|
+
function expandTemplatePartials(template, partials, partialStack) {
|
|
3315
|
+
let output = "";
|
|
3316
|
+
let index = 0;
|
|
3317
|
+
while (index < template.length) {
|
|
3318
|
+
const open = template.indexOf("{{", index);
|
|
3319
|
+
if (open === -1) {
|
|
3320
|
+
output += template.slice(index);
|
|
3321
|
+
break;
|
|
3322
|
+
}
|
|
3323
|
+
const parsed = parseTag(template, open);
|
|
3324
|
+
if (parsed.kind !== "partial") {
|
|
3325
|
+
output += template.slice(index, parsed.end);
|
|
3326
|
+
index = parsed.end;
|
|
3327
|
+
continue;
|
|
3328
|
+
}
|
|
3329
|
+
if (!Object.hasOwn(partials, parsed.name)) {
|
|
3330
|
+
throw new Error(`Partial "${parsed.name}" not found.`);
|
|
3331
|
+
}
|
|
3332
|
+
if (partialStack.includes(parsed.name)) {
|
|
3333
|
+
throw new Error(
|
|
3334
|
+
`Circular partial reference detected: ${[...partialStack, parsed.name].join(" -> ")}.`
|
|
3335
|
+
);
|
|
3336
|
+
}
|
|
3337
|
+
if (partialStack.length >= MAX_PARTIAL_DEPTH) {
|
|
3338
|
+
throw new Error(`Maximum partial depth exceeded (${MAX_PARTIAL_DEPTH}).`);
|
|
3339
|
+
}
|
|
3340
|
+
const standalone = getStandalone(template, open, parsed.end, parsed.kind);
|
|
3341
|
+
const beforePartial = standalone === void 0 ? template.slice(index, open) : template.slice(index, standalone.lineStart);
|
|
3342
|
+
const indent = standalone === void 0 ? "" : template.slice(standalone.lineStart, open);
|
|
3343
|
+
const partial = indentPartial(partials[parsed.name], indent);
|
|
3344
|
+
output += beforePartial + expandTemplatePartials(partial, partials, [...partialStack, parsed.name]);
|
|
3345
|
+
index = standalone?.nextIndex ?? parsed.end;
|
|
3346
|
+
}
|
|
3347
|
+
return output;
|
|
3106
3348
|
}
|
|
3107
3349
|
function lookupName(view, name) {
|
|
3108
3350
|
if (!isPropertyContainer(view) || !hasProperty(view, name)) {
|
|
@@ -3162,22 +3404,22 @@ function hasProperty(value, key) {
|
|
|
3162
3404
|
return Object.prototype.hasOwnProperty.call(value, key);
|
|
3163
3405
|
}
|
|
3164
3406
|
|
|
3165
|
-
// ../design
|
|
3407
|
+
// ../toolcraft-design/src/components/browser.ts
|
|
3166
3408
|
import { spawn as spawn2 } from "node:child_process";
|
|
3167
3409
|
import process2 from "node:process";
|
|
3168
3410
|
|
|
3169
|
-
// ../design
|
|
3411
|
+
// ../toolcraft-design/src/acp/writer.ts
|
|
3170
3412
|
import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
|
|
3171
3413
|
var storage = new AsyncLocalStorage2();
|
|
3172
3414
|
|
|
3173
|
-
// ../design
|
|
3415
|
+
// ../toolcraft-design/src/dashboard/terminal-width.ts
|
|
3174
3416
|
var graphemeSegmenter3 = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
3175
3417
|
|
|
3176
|
-
// ../design
|
|
3418
|
+
// ../toolcraft-design/src/dashboard/terminal.ts
|
|
3177
3419
|
import readline from "node:readline";
|
|
3178
3420
|
import { PassThrough } from "node:stream";
|
|
3179
3421
|
|
|
3180
|
-
// ../design
|
|
3422
|
+
// ../toolcraft-design/src/explorer/state.ts
|
|
3181
3423
|
var REGION_HEADER = 1 << 0;
|
|
3182
3424
|
var REGION_LIST = 1 << 1;
|
|
3183
3425
|
var REGION_DETAIL = 1 << 2;
|
|
@@ -3186,13 +3428,13 @@ var REGION_MODAL = 1 << 4;
|
|
|
3186
3428
|
var REGION_TOAST = 1 << 5;
|
|
3187
3429
|
var REGION_ALL = REGION_HEADER | REGION_LIST | REGION_DETAIL | REGION_FOOTER | REGION_MODAL | REGION_TOAST;
|
|
3188
3430
|
|
|
3189
|
-
// ../design
|
|
3431
|
+
// ../toolcraft-design/src/prompts/index.ts
|
|
3190
3432
|
import * as clack from "@clack/prompts";
|
|
3191
3433
|
|
|
3192
|
-
// ../design
|
|
3434
|
+
// ../toolcraft-design/src/prompts/primitives/cancel.ts
|
|
3193
3435
|
import { isCancel } from "@clack/prompts";
|
|
3194
3436
|
|
|
3195
|
-
// ../design
|
|
3437
|
+
// ../toolcraft-design/src/static/spinner.ts
|
|
3196
3438
|
var SPINNER_FRAMES = Object.freeze(["\u25D2", "\u25D0", "\u25D3", "\u25D1"]);
|
|
3197
3439
|
|
|
3198
3440
|
// ../config-mutations/src/formats/json.ts
|
|
@@ -3231,6 +3473,13 @@ function cloneConfigValue(value) {
|
|
|
3231
3473
|
function isConfigObject(value) {
|
|
3232
3474
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3233
3475
|
}
|
|
3476
|
+
function detectIndent(content) {
|
|
3477
|
+
const match = content.match(/^[\t ]+/m);
|
|
3478
|
+
if (match) {
|
|
3479
|
+
return match[0];
|
|
3480
|
+
}
|
|
3481
|
+
return " ";
|
|
3482
|
+
}
|
|
3234
3483
|
function parse3(content) {
|
|
3235
3484
|
if (!content || content.trim() === "") {
|
|
3236
3485
|
return {};
|
|
@@ -3270,6 +3519,9 @@ function merge(base, patch) {
|
|
|
3270
3519
|
}
|
|
3271
3520
|
return result;
|
|
3272
3521
|
}
|
|
3522
|
+
function configValuesEqual(left, right) {
|
|
3523
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
3524
|
+
}
|
|
3273
3525
|
function prune(obj, shape) {
|
|
3274
3526
|
let changed = false;
|
|
3275
3527
|
const result = cloneConfigObject(obj);
|
|
@@ -3306,9 +3558,56 @@ function prune(obj, shape) {
|
|
|
3306
3558
|
}
|
|
3307
3559
|
return { changed, result };
|
|
3308
3560
|
}
|
|
3561
|
+
function modifyAtPath(content, path10, value) {
|
|
3562
|
+
const indent = detectIndent(content);
|
|
3563
|
+
const formattingOptions = {
|
|
3564
|
+
tabSize: indent === " " ? 1 : indent.length,
|
|
3565
|
+
insertSpaces: indent !== " ",
|
|
3566
|
+
eol: "\n"
|
|
3567
|
+
};
|
|
3568
|
+
const edits = jsonc.modify(content, path10, value, { formattingOptions });
|
|
3569
|
+
let result = jsonc.applyEdits(content, edits);
|
|
3570
|
+
if (!result.endsWith("\n")) {
|
|
3571
|
+
result += "\n";
|
|
3572
|
+
}
|
|
3573
|
+
return result;
|
|
3574
|
+
}
|
|
3575
|
+
function removeAtPath(content, path10) {
|
|
3576
|
+
return modifyAtPath(content, path10, void 0);
|
|
3577
|
+
}
|
|
3578
|
+
function serializeUpdate(content, current, next) {
|
|
3579
|
+
let result = content || "{}";
|
|
3580
|
+
result = applyObjectUpdate(result, [], current, next);
|
|
3581
|
+
if (!result.endsWith("\n")) {
|
|
3582
|
+
result += "\n";
|
|
3583
|
+
}
|
|
3584
|
+
return result;
|
|
3585
|
+
}
|
|
3586
|
+
function applyObjectUpdate(content, path10, current, next) {
|
|
3587
|
+
let result = content;
|
|
3588
|
+
for (const key of Object.keys(current)) {
|
|
3589
|
+
if (!hasConfigEntry(next, key)) {
|
|
3590
|
+
result = removeAtPath(result, [...path10, key]);
|
|
3591
|
+
}
|
|
3592
|
+
}
|
|
3593
|
+
for (const [key, nextValue] of Object.entries(next)) {
|
|
3594
|
+
const nextPath = [...path10, key];
|
|
3595
|
+
const hasCurrent = hasConfigEntry(current, key);
|
|
3596
|
+
const currentValue = hasCurrent ? current[key] : void 0;
|
|
3597
|
+
if (hasCurrent && isConfigObject(currentValue) && isConfigObject(nextValue)) {
|
|
3598
|
+
result = applyObjectUpdate(result, nextPath, currentValue, nextValue);
|
|
3599
|
+
continue;
|
|
3600
|
+
}
|
|
3601
|
+
if (!hasCurrent || !configValuesEqual(currentValue, nextValue)) {
|
|
3602
|
+
result = modifyAtPath(result, nextPath, nextValue);
|
|
3603
|
+
}
|
|
3604
|
+
}
|
|
3605
|
+
return result;
|
|
3606
|
+
}
|
|
3309
3607
|
var jsonFormat = {
|
|
3310
3608
|
parse: parse3,
|
|
3311
3609
|
serialize,
|
|
3610
|
+
serializeUpdate,
|
|
3312
3611
|
merge,
|
|
3313
3612
|
prune
|
|
3314
3613
|
};
|
|
@@ -3690,7 +3989,7 @@ function pruneKeysByPrefix(table, prefix) {
|
|
|
3690
3989
|
const result = {};
|
|
3691
3990
|
for (const [key, value] of Object.entries(table)) {
|
|
3692
3991
|
if (!key.startsWith(prefix)) {
|
|
3693
|
-
result
|
|
3992
|
+
setConfigEntry(result, key, value);
|
|
3694
3993
|
}
|
|
3695
3994
|
}
|
|
3696
3995
|
return result;
|
|
@@ -3699,28 +3998,43 @@ function isConfigObject4(value) {
|
|
|
3699
3998
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3700
3999
|
}
|
|
3701
4000
|
function mergeWithPruneByPrefix(base, patch, pruneByPrefix) {
|
|
3702
|
-
const result =
|
|
4001
|
+
const result = cloneConfigObject(base);
|
|
3703
4002
|
const prefixMap = pruneByPrefix ?? {};
|
|
3704
4003
|
for (const [key, value] of Object.entries(patch)) {
|
|
4004
|
+
if (value === void 0) {
|
|
4005
|
+
continue;
|
|
4006
|
+
}
|
|
3705
4007
|
const current = result[key];
|
|
3706
4008
|
const prefix = prefixMap[key];
|
|
3707
4009
|
if (isConfigObject4(current) && isConfigObject4(value)) {
|
|
3708
4010
|
if (prefix) {
|
|
3709
4011
|
const pruned = pruneKeysByPrefix(current, prefix);
|
|
3710
|
-
result
|
|
4012
|
+
setConfigEntry(result, key, mergePrunedConfigObject(pruned, value));
|
|
3711
4013
|
} else {
|
|
3712
|
-
result
|
|
3713
|
-
current,
|
|
3714
|
-
value,
|
|
3715
|
-
prefixMap
|
|
3716
|
-
);
|
|
4014
|
+
setConfigEntry(result, key, mergeWithPruneByPrefix(current, value, prefixMap));
|
|
3717
4015
|
}
|
|
3718
4016
|
continue;
|
|
3719
4017
|
}
|
|
3720
|
-
result
|
|
4018
|
+
setConfigEntry(result, key, value);
|
|
4019
|
+
}
|
|
4020
|
+
return result;
|
|
4021
|
+
}
|
|
4022
|
+
function mergePrunedConfigObject(base, patch) {
|
|
4023
|
+
const result = cloneConfigObject(base);
|
|
4024
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
4025
|
+
if (value === void 0) {
|
|
4026
|
+
continue;
|
|
4027
|
+
}
|
|
4028
|
+
setConfigEntry(result, key, value);
|
|
3721
4029
|
}
|
|
3722
4030
|
return result;
|
|
3723
4031
|
}
|
|
4032
|
+
function serializeConfigUpdate(format, rawContent, current, next) {
|
|
4033
|
+
if (rawContent !== null && format.serializeUpdate) {
|
|
4034
|
+
return format.serializeUpdate(rawContent, current, next);
|
|
4035
|
+
}
|
|
4036
|
+
return format.serialize(next);
|
|
4037
|
+
}
|
|
3724
4038
|
async function applyMutation(mutation, context, options) {
|
|
3725
4039
|
switch (mutation.kind) {
|
|
3726
4040
|
case "ensureDirectory":
|
|
@@ -4033,6 +4347,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
4033
4347
|
}
|
|
4034
4348
|
const format = getConfigFormat(formatName);
|
|
4035
4349
|
const rawContent = await readFileIfExists(context.fs, targetPath);
|
|
4350
|
+
let preserveContent = rawContent;
|
|
4036
4351
|
let current;
|
|
4037
4352
|
try {
|
|
4038
4353
|
current = rawContent === null ? {} : format.parse(rawContent);
|
|
@@ -4041,6 +4356,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
4041
4356
|
await backupInvalidDocument(context, targetPath, rawContent);
|
|
4042
4357
|
}
|
|
4043
4358
|
current = {};
|
|
4359
|
+
preserveContent = null;
|
|
4044
4360
|
}
|
|
4045
4361
|
const value = resolveValue(mutation.value, options);
|
|
4046
4362
|
let merged;
|
|
@@ -4049,7 +4365,7 @@ async function applyConfigMerge(mutation, context, options) {
|
|
|
4049
4365
|
} else {
|
|
4050
4366
|
merged = format.merge(current, value);
|
|
4051
4367
|
}
|
|
4052
|
-
const serialized = format
|
|
4368
|
+
const serialized = serializeConfigUpdate(format, preserveContent, current, merged);
|
|
4053
4369
|
const changed = serialized !== rawContent;
|
|
4054
4370
|
if (changed && !context.dryRun) {
|
|
4055
4371
|
await writeAtomically(context, targetPath, serialized);
|
|
@@ -4117,7 +4433,7 @@ async function applyConfigPrune(mutation, context, options) {
|
|
|
4117
4433
|
details
|
|
4118
4434
|
};
|
|
4119
4435
|
}
|
|
4120
|
-
const serialized = format
|
|
4436
|
+
const serialized = serializeConfigUpdate(format, rawContent, current, result);
|
|
4121
4437
|
if (!context.dryRun) {
|
|
4122
4438
|
await writeAtomically(context, targetPath, serialized);
|
|
4123
4439
|
}
|
|
@@ -4142,6 +4458,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
4142
4458
|
}
|
|
4143
4459
|
const format = getConfigFormat(formatName);
|
|
4144
4460
|
const rawContent = await readFileIfExists(context.fs, targetPath);
|
|
4461
|
+
let preserveContent = rawContent;
|
|
4145
4462
|
let current;
|
|
4146
4463
|
try {
|
|
4147
4464
|
current = rawContent === null ? {} : format.parse(rawContent);
|
|
@@ -4150,6 +4467,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
4150
4467
|
await backupInvalidDocument(context, targetPath, rawContent);
|
|
4151
4468
|
}
|
|
4152
4469
|
current = {};
|
|
4470
|
+
preserveContent = null;
|
|
4153
4471
|
}
|
|
4154
4472
|
const { content: transformed, changed } = mutation.transform(current, options);
|
|
4155
4473
|
if (!changed) {
|
|
@@ -4173,7 +4491,7 @@ async function applyConfigTransform(mutation, context, options) {
|
|
|
4173
4491
|
details
|
|
4174
4492
|
};
|
|
4175
4493
|
}
|
|
4176
|
-
const serialized = format
|
|
4494
|
+
const serialized = serializeConfigUpdate(format, preserveContent, current, transformed);
|
|
4177
4495
|
if (!context.dryRun) {
|
|
4178
4496
|
await writeAtomically(context, targetPath, serialized);
|
|
4179
4497
|
}
|
|
@@ -4350,14 +4668,14 @@ async function installSkill(agentId, skill, options) {
|
|
|
4350
4668
|
throw new UnsupportedAgentError(agentId);
|
|
4351
4669
|
}
|
|
4352
4670
|
const scope = options.scope ?? "local";
|
|
4353
|
-
const
|
|
4671
|
+
const config2 = support.config;
|
|
4354
4672
|
if (skill.name.length === 0 || skill.name === "." || skill.name === ".." || skill.name.includes("/") || skill.name.includes("\\") || skill.name.includes("\n") || skill.name.includes("\r")) {
|
|
4355
4673
|
throw new Error(`Invalid skill name: ${skill.name}`);
|
|
4356
4674
|
}
|
|
4357
|
-
const skillDir = scope === "global" ?
|
|
4675
|
+
const skillDir = scope === "global" ? config2.globalSkillDir : toHomeRelative(config2.localSkillDir);
|
|
4358
4676
|
const skillFolderPath = `${skillDir}/${skill.name}`;
|
|
4359
4677
|
const skillFilePath = `${skillFolderPath}/SKILL.md`;
|
|
4360
|
-
const displayPath = `${scope === "global" ?
|
|
4678
|
+
const displayPath = `${scope === "global" ? config2.globalSkillDir : config2.localSkillDir}/${skill.name}/SKILL.md`;
|
|
4361
4679
|
const absoluteSkillPath = `${scope === "global" ? options.homeDir : options.cwd}/${skillFilePath.slice(2)}`;
|
|
4362
4680
|
if (await pathExists2(options.fs, absoluteSkillPath)) {
|
|
4363
4681
|
throw new Error(`Skill already exists: ${displayPath}`);
|
|
@@ -4478,17 +4796,17 @@ function resolveHomeRelativePath(targetPath, homeDir) {
|
|
|
4478
4796
|
return targetPath;
|
|
4479
4797
|
}
|
|
4480
4798
|
function getSkillFolderWithHome(agent, scope, cwd, homeDir) {
|
|
4481
|
-
const
|
|
4482
|
-
if (!
|
|
4799
|
+
const config2 = getAgentConfig(agent);
|
|
4800
|
+
if (!config2) {
|
|
4483
4801
|
throwUnsupportedAgent(agent);
|
|
4484
4802
|
}
|
|
4485
4803
|
return {
|
|
4486
4804
|
displayPath: path9.join(
|
|
4487
|
-
scope === "global" ?
|
|
4805
|
+
scope === "global" ? config2.globalSkillDir : config2.localSkillDir,
|
|
4488
4806
|
TERMINAL_PILOT_SKILL_NAME
|
|
4489
4807
|
),
|
|
4490
4808
|
fullPath: path9.join(
|
|
4491
|
-
scope === "global" ? resolveHomeRelativePath(
|
|
4809
|
+
scope === "global" ? resolveHomeRelativePath(config2.globalSkillDir, homeDir) : path9.resolve(cwd, config2.localSkillDir),
|
|
4492
4810
|
TERMINAL_PILOT_SKILL_NAME
|
|
4493
4811
|
)
|
|
4494
4812
|
};
|