@alcyone-labs/arg-parser 2.10.2 → 2.11.0
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/README.md +229 -91
- package/dist/config/ConfigurationManager.d.ts +8 -0
- package/dist/config/ConfigurationManager.d.ts.map +1 -1
- package/dist/core/ArgParser.d.ts +3 -2
- package/dist/core/ArgParser.d.ts.map +1 -1
- package/dist/core/ArgParserBase.d.ts +24 -3
- package/dist/core/ArgParserBase.d.ts.map +1 -1
- package/dist/core/types.d.ts +126 -5
- package/dist/core/types.d.ts.map +1 -1
- package/dist/index.cjs +632 -948
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.min.mjs +5504 -5676
- package/dist/index.min.mjs.map +1 -1
- package/dist/index.mjs +632 -948
- package/dist/index.mjs.map +1 -1
- package/dist/mcp/mcp-integration.d.ts.map +1 -1
- package/dist/mcp/mcp-notifications.d.ts +0 -6
- package/dist/mcp/mcp-notifications.d.ts.map +1 -1
- package/dist/mcp/mcp-prompts.d.ts.map +1 -1
- package/dist/mcp/mcp-resources.d.ts.map +1 -1
- package/dist/mcp/zod-compatibility.d.ts.map +1 -1
- package/dist/testing/fuzzy-tester.d.ts +2 -2
- package/dist/testing/fuzzy-tester.d.ts.map +1 -1
- package/dist/tui/types.d.ts +60 -0
- package/dist/tui/types.d.ts.map +1 -0
- package/dist/utils/debug-utils.d.ts.map +1 -1
- package/package.json +13 -9
- package/dist/ui/App.d.ts +0 -18
- package/dist/ui/App.d.ts.map +0 -1
- package/dist/ui/Component.d.ts +0 -21
- package/dist/ui/Component.d.ts.map +0 -1
- package/dist/ui/Layout.d.ts +0 -19
- package/dist/ui/Layout.d.ts.map +0 -1
- package/dist/ui/Terminal.d.ts +0 -19
- package/dist/ui/Terminal.d.ts.map +0 -1
- package/dist/ui/Theme.d.ts +0 -20
- package/dist/ui/Theme.d.ts.map +0 -1
- package/dist/ui/components/Input.d.ts +0 -21
- package/dist/ui/components/Input.d.ts.map +0 -1
- package/dist/ui/components/List.d.ts +0 -23
- package/dist/ui/components/List.d.ts.map +0 -1
- package/dist/ui/components/ScrollArea.d.ts +0 -19
- package/dist/ui/components/ScrollArea.d.ts.map +0 -1
- package/dist/ui/components/StackNavigator.d.ts +0 -16
- package/dist/ui/components/StackNavigator.d.ts.map +0 -1
- package/dist/ui/index.d.ts +0 -10
- package/dist/ui/index.d.ts.map +0 -1
- package/dist/ui/utils/ansi-utils.d.ts +0 -17
- package/dist/ui/utils/ansi-utils.d.ts.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -55,6 +55,7 @@ const RESET$1 = "\x1B[0m";
|
|
|
55
55
|
const BOLD$1 = "\x1B[1m";
|
|
56
56
|
const DIM$1 = "\x1B[2m";
|
|
57
57
|
const UNDERLINE$1 = "\x1B[4m";
|
|
58
|
+
const CLEAR$1 = "\x1B[2J\x1B[3J\x1B[H";
|
|
58
59
|
const BLACK$1 = "\x1B[30m";
|
|
59
60
|
const RED$1 = "\x1B[31m";
|
|
60
61
|
const GREEN$1 = "\x1B[32m";
|
|
@@ -96,7 +97,7 @@ function addChalkProperty(fn, name, code, codes) {
|
|
|
96
97
|
});
|
|
97
98
|
}
|
|
98
99
|
function createColorFunction(codes) {
|
|
99
|
-
const fn = (text) => colorize(text, ...codes);
|
|
100
|
+
const fn = ((text) => colorize(text, ...codes));
|
|
100
101
|
addChalkProperty(fn, "bold", BOLD$1, codes);
|
|
101
102
|
addChalkProperty(fn, "dim", DIM$1, codes);
|
|
102
103
|
addChalkProperty(fn, "underline", UNDERLINE$1, codes);
|
|
@@ -111,6 +112,10 @@ function createColorFunction(codes) {
|
|
|
111
112
|
addChalkProperty(fn, "gray", GRAY$1, codes);
|
|
112
113
|
addChalkProperty(fn, "grey", GRAY$1, codes);
|
|
113
114
|
addChalkProperty(fn, "blueBright", CYAN$1, codes);
|
|
115
|
+
Object.defineProperty(fn, "clear", {
|
|
116
|
+
get: () => colorEnabled$1 ? CLEAR$1 : "",
|
|
117
|
+
configurable: true
|
|
118
|
+
});
|
|
114
119
|
return fn;
|
|
115
120
|
}
|
|
116
121
|
const simpleChalk = createColorFunction([]);
|
|
@@ -118,6 +123,7 @@ const RESET = "\x1B[0m";
|
|
|
118
123
|
const BOLD = "\x1B[1m";
|
|
119
124
|
const DIM = "\x1B[2m";
|
|
120
125
|
const UNDERLINE = "\x1B[4m";
|
|
126
|
+
const CLEAR = "\x1B[2J\x1B[3J\x1B[H";
|
|
121
127
|
const BLACK = "\x1B[30m";
|
|
122
128
|
const RED = "\x1B[31m";
|
|
123
129
|
const GREEN = "\x1B[32m";
|
|
@@ -166,6 +172,16 @@ const simpleChalkFast = {
|
|
|
166
172
|
bold: format$2(BOLD),
|
|
167
173
|
dim: format$2(DIM),
|
|
168
174
|
underline: format$2(UNDERLINE),
|
|
175
|
+
/**
|
|
176
|
+
* [NON-CHALK EXTENSION] Returns an ANSI escape sequence that clears the screen
|
|
177
|
+
* and the scrollback buffer (equivalent to CMD+K).
|
|
178
|
+
*
|
|
179
|
+
* @example
|
|
180
|
+
* ```javascript
|
|
181
|
+
* process.stdout.write(fast.clear);
|
|
182
|
+
* ```
|
|
183
|
+
*/
|
|
184
|
+
clear: colorEnabled ? CLEAR : "",
|
|
169
185
|
// Pre-created common combinations for some chaining support
|
|
170
186
|
redBold: format$2(RED + BOLD),
|
|
171
187
|
greenBold: format$2(GREEN + BOLD),
|
|
@@ -269,6 +285,28 @@ const simpleChalkBrowser = {
|
|
|
269
285
|
bold: format$1("bold"),
|
|
270
286
|
dim: format$1("dim"),
|
|
271
287
|
underline: format$1("underline"),
|
|
288
|
+
/**
|
|
289
|
+
* [NON-CHALK EXTENSION] Clears the screen and scrollback buffer.
|
|
290
|
+
* In a browser environment, this calls console.clear().
|
|
291
|
+
* In a Node environment, it returns the ANSI clear/scrollback sequence.
|
|
292
|
+
*
|
|
293
|
+
* @example
|
|
294
|
+
* ```javascript
|
|
295
|
+
* // In browser: console.clear() will be called immediately
|
|
296
|
+
* // In node: will return ANSI string
|
|
297
|
+
* console.log(...browser.clear);
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
clear: (() => {
|
|
301
|
+
if (!supportsColor())
|
|
302
|
+
return "";
|
|
303
|
+
if (isBrowser) {
|
|
304
|
+
console.clear();
|
|
305
|
+
return "";
|
|
306
|
+
} else {
|
|
307
|
+
return "\x1B[2J\x1B[3J\x1B[H";
|
|
308
|
+
}
|
|
309
|
+
})(),
|
|
272
310
|
// Browser-specific combinations (CSS can combine styles)
|
|
273
311
|
redBold: (text) => {
|
|
274
312
|
if (isBrowser) {
|
|
@@ -779,6 +817,30 @@ class ConfigurationManager {
|
|
|
779
817
|
}
|
|
780
818
|
return config;
|
|
781
819
|
}
|
|
820
|
+
/**
|
|
821
|
+
* Discovers .env files in a specified directory
|
|
822
|
+
* Searches in priority order: .env.local, .env.dev/.env.test, .env
|
|
823
|
+
*
|
|
824
|
+
* @param searchDir - The directory to search for .env files
|
|
825
|
+
* @returns Path to found .env file, or null if none is found
|
|
826
|
+
*/
|
|
827
|
+
discoverEnvFile(searchDir) {
|
|
828
|
+
const envFilesToCheck = [".env.local"];
|
|
829
|
+
const nodeEnv = process.env["NODE_ENV"]?.toLowerCase();
|
|
830
|
+
if (nodeEnv === "development" || nodeEnv === "dev") {
|
|
831
|
+
envFilesToCheck.push(".env.dev");
|
|
832
|
+
} else if (nodeEnv === "test") {
|
|
833
|
+
envFilesToCheck.push(".env.test");
|
|
834
|
+
}
|
|
835
|
+
envFilesToCheck.push(".env");
|
|
836
|
+
for (const envFile of envFilesToCheck) {
|
|
837
|
+
const envPath = path__namespace.join(searchDir, envFile);
|
|
838
|
+
if (fs__namespace.existsSync(envPath)) {
|
|
839
|
+
return envPath;
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
return null;
|
|
843
|
+
}
|
|
782
844
|
/**
|
|
783
845
|
* Parses JSON file content
|
|
784
846
|
*/
|
|
@@ -1412,6 +1474,22 @@ const _DxtPathResolver = class _DxtPathResolver {
|
|
|
1412
1474
|
};
|
|
1413
1475
|
_DxtPathResolver._cachedContext = null;
|
|
1414
1476
|
let DxtPathResolver = _DxtPathResolver;
|
|
1477
|
+
const FlagInheritance = {
|
|
1478
|
+
/**
|
|
1479
|
+
* No flags are inherited from the parent.
|
|
1480
|
+
*/
|
|
1481
|
+
NONE: "none",
|
|
1482
|
+
/**
|
|
1483
|
+
* Inherits flags only from the direct parent at the time of attachment (Snapshot behavior).
|
|
1484
|
+
* Equivalent to `true` in legacy boolean config.
|
|
1485
|
+
*/
|
|
1486
|
+
DirectParentOnly: "direct-parent-only",
|
|
1487
|
+
/**
|
|
1488
|
+
* Inherits flags from the entire parent chain, ensuring grandchildren receive root flags
|
|
1489
|
+
* even in bottom-up construction scenarios.
|
|
1490
|
+
*/
|
|
1491
|
+
AllParents: "all-parents"
|
|
1492
|
+
};
|
|
1415
1493
|
const zodDxtOptionsSchema = zod.z.object({
|
|
1416
1494
|
sensitive: zod.z.boolean().optional().describe(
|
|
1417
1495
|
"Whether this field should be marked as sensitive in DXT user_config"
|
|
@@ -1517,6 +1595,9 @@ const zodFlagSchema = zod.z.object({
|
|
|
1517
1595
|
),
|
|
1518
1596
|
dynamicRegister: zod.z.custom((val) => typeof val === "function").optional().describe(
|
|
1519
1597
|
"Optional callback that can register additional flags dynamically when this flag is present."
|
|
1598
|
+
),
|
|
1599
|
+
setWorkingDirectory: zod.z.boolean().optional().describe(
|
|
1600
|
+
"If true, this flag's value becomes the effective working directory for file operations."
|
|
1520
1601
|
)
|
|
1521
1602
|
}).transform((obj) => {
|
|
1522
1603
|
const newObj = { ...obj };
|
|
@@ -3083,6 +3164,7 @@ export default ${JSON.stringify(buildConfig, null, 2)};
|
|
|
3083
3164
|
return null;
|
|
3084
3165
|
}
|
|
3085
3166
|
}
|
|
3167
|
+
const logger$5 = simpleMcpLogger.createMcpLogger("MCP Notifications");
|
|
3086
3168
|
class McpNotificationsManager {
|
|
3087
3169
|
constructor() {
|
|
3088
3170
|
this.clients = /* @__PURE__ */ new Map();
|
|
@@ -3172,7 +3254,7 @@ class McpNotificationsManager {
|
|
|
3172
3254
|
try {
|
|
3173
3255
|
listener(event);
|
|
3174
3256
|
} catch (error) {
|
|
3175
|
-
|
|
3257
|
+
logger$5.error("Error in global change listener:", error);
|
|
3176
3258
|
}
|
|
3177
3259
|
}
|
|
3178
3260
|
for (const client of this.clients.values()) {
|
|
@@ -3240,7 +3322,7 @@ class McpNotificationsManager {
|
|
|
3240
3322
|
);
|
|
3241
3323
|
}
|
|
3242
3324
|
} catch (error) {
|
|
3243
|
-
|
|
3325
|
+
logger$5.error(
|
|
3244
3326
|
`Error sending notification to client ${client.clientId}:`,
|
|
3245
3327
|
error
|
|
3246
3328
|
);
|
|
@@ -3274,6 +3356,7 @@ class McpNotificationsManager {
|
|
|
3274
3356
|
this.changeHistory = [];
|
|
3275
3357
|
}
|
|
3276
3358
|
}
|
|
3359
|
+
const logger$4 = simpleMcpLogger.createMcpLogger("MCP Prompts");
|
|
3277
3360
|
class McpPromptsManager {
|
|
3278
3361
|
constructor() {
|
|
3279
3362
|
this.prompts = /* @__PURE__ */ new Map();
|
|
@@ -3391,11 +3474,12 @@ class McpPromptsManager {
|
|
|
3391
3474
|
try {
|
|
3392
3475
|
listener();
|
|
3393
3476
|
} catch (error) {
|
|
3394
|
-
|
|
3477
|
+
logger$4.error("Error in prompt change listener:", error);
|
|
3395
3478
|
}
|
|
3396
3479
|
}
|
|
3397
3480
|
}
|
|
3398
3481
|
}
|
|
3482
|
+
const logger$3 = simpleMcpLogger.createMcpLogger("MCP Resources");
|
|
3399
3483
|
class ResourceTemplateParser {
|
|
3400
3484
|
constructor(template) {
|
|
3401
3485
|
const paramMatches = template.match(/\{([^}]+)\}/g) || [];
|
|
@@ -3545,7 +3629,7 @@ class McpResourcesManager {
|
|
|
3545
3629
|
try {
|
|
3546
3630
|
listener();
|
|
3547
3631
|
} catch (error) {
|
|
3548
|
-
|
|
3632
|
+
logger$3.error("Error in resource change listener:", error);
|
|
3549
3633
|
}
|
|
3550
3634
|
}
|
|
3551
3635
|
}
|
|
@@ -3557,13 +3641,15 @@ const isDebugEnabled = () => {
|
|
|
3557
3641
|
return false;
|
|
3558
3642
|
}
|
|
3559
3643
|
};
|
|
3644
|
+
const logger$2 = simpleMcpLogger.createMcpLogger("DEBUG");
|
|
3560
3645
|
const debug = {
|
|
3561
3646
|
/**
|
|
3562
3647
|
* Log a debug message to stderr (only when DEBUG=true)
|
|
3563
3648
|
*/
|
|
3564
3649
|
log: (...args) => {
|
|
3565
3650
|
if (isDebugEnabled()) {
|
|
3566
|
-
|
|
3651
|
+
const [msg, ...rest] = args;
|
|
3652
|
+
logger$2.error(typeof msg === "string" ? msg : String(msg), ...rest);
|
|
3567
3653
|
}
|
|
3568
3654
|
},
|
|
3569
3655
|
/**
|
|
@@ -3571,7 +3657,8 @@ const debug = {
|
|
|
3571
3657
|
*/
|
|
3572
3658
|
error: (...args) => {
|
|
3573
3659
|
if (isDebugEnabled()) {
|
|
3574
|
-
|
|
3660
|
+
const [msg, ...rest] = args;
|
|
3661
|
+
logger$2.error(typeof msg === "string" ? msg : String(msg), ...rest);
|
|
3575
3662
|
}
|
|
3576
3663
|
},
|
|
3577
3664
|
/**
|
|
@@ -3579,7 +3666,8 @@ const debug = {
|
|
|
3579
3666
|
*/
|
|
3580
3667
|
warn: (...args) => {
|
|
3581
3668
|
if (isDebugEnabled()) {
|
|
3582
|
-
|
|
3669
|
+
const [msg, ...rest] = args;
|
|
3670
|
+
logger$2.warn(typeof msg === "string" ? msg : String(msg), ...rest);
|
|
3583
3671
|
}
|
|
3584
3672
|
},
|
|
3585
3673
|
/**
|
|
@@ -3587,7 +3675,8 @@ const debug = {
|
|
|
3587
3675
|
*/
|
|
3588
3676
|
info: (...args) => {
|
|
3589
3677
|
if (isDebugEnabled()) {
|
|
3590
|
-
|
|
3678
|
+
const [msg, ...rest] = args;
|
|
3679
|
+
logger$2.info(typeof msg === "string" ? msg : String(msg), ...rest);
|
|
3591
3680
|
}
|
|
3592
3681
|
},
|
|
3593
3682
|
/**
|
|
@@ -3595,7 +3684,8 @@ const debug = {
|
|
|
3595
3684
|
*/
|
|
3596
3685
|
prefixed: (prefix, ...args) => {
|
|
3597
3686
|
if (isDebugEnabled()) {
|
|
3598
|
-
|
|
3687
|
+
const [msg, ...rest] = args;
|
|
3688
|
+
logger$2.info(`[${prefix}] ${typeof msg === "string" ? msg : String(msg)}`, ...rest);
|
|
3599
3689
|
}
|
|
3600
3690
|
},
|
|
3601
3691
|
/**
|
|
@@ -3727,12 +3817,21 @@ class ArgParserBase {
|
|
|
3727
3817
|
#dxtGenerator;
|
|
3728
3818
|
#configurationManager;
|
|
3729
3819
|
#fuzzyMode = false;
|
|
3820
|
+
#triggerAutoHelpIfNoHandler = false;
|
|
3821
|
+
#logger;
|
|
3730
3822
|
// Track dynamically added flags so we can clean them between parses
|
|
3731
3823
|
#dynamicFlagNames = /* @__PURE__ */ new Set();
|
|
3732
3824
|
// MCP-related managers
|
|
3733
3825
|
#mcpResourcesManager = new McpResourcesManager();
|
|
3734
3826
|
#mcpPromptsManager = new McpPromptsManager();
|
|
3735
3827
|
#mcpNotificationsManager = new McpNotificationsManager();
|
|
3828
|
+
// Working directory management
|
|
3829
|
+
/** The effective working directory for this parser instance */
|
|
3830
|
+
#effectiveWorkingDirectory = null;
|
|
3831
|
+
/** The original root path from user's CLI invocation */
|
|
3832
|
+
#rootPath = null;
|
|
3833
|
+
/** Tracks if effective working directory has been resolved */
|
|
3834
|
+
#workingDirectoryResolved = false;
|
|
3736
3835
|
constructor(options = {}, initialFlags) {
|
|
3737
3836
|
this.#appName = options.appName || "app";
|
|
3738
3837
|
if (options.blankSpaceWidth && !isNaN(Number(options.blankSpaceWidth)) && Number(options.blankSpaceWidth) > 20)
|
|
@@ -3754,9 +3853,14 @@ class ArgParserBase {
|
|
|
3754
3853
|
this.#handleErrors = options.handleErrors ?? true;
|
|
3755
3854
|
this.#autoExit = options.autoExit ?? true;
|
|
3756
3855
|
this.#inheritParentFlags = options.inheritParentFlags ?? false;
|
|
3856
|
+
this.#triggerAutoHelpIfNoHandler = options.triggerAutoHelpIfNoHandler ?? false;
|
|
3757
3857
|
this.#description = options.description;
|
|
3758
3858
|
this.#handler = options.handler;
|
|
3759
3859
|
this.#appCommandName = options.appCommandName;
|
|
3860
|
+
this.#logger = options.logger || simpleMcpLogger.createMcpLogger({
|
|
3861
|
+
prefix: this.#appName,
|
|
3862
|
+
mcpMode: false
|
|
3863
|
+
});
|
|
3760
3864
|
const helpFlag = {
|
|
3761
3865
|
name: "help",
|
|
3762
3866
|
description: "Display this help message and exits",
|
|
@@ -3792,6 +3896,12 @@ class ArgParserBase {
|
|
|
3792
3896
|
getAppCommandName() {
|
|
3793
3897
|
return this.#appCommandName;
|
|
3794
3898
|
}
|
|
3899
|
+
/**
|
|
3900
|
+
* Access to the logger
|
|
3901
|
+
*/
|
|
3902
|
+
get logger() {
|
|
3903
|
+
return this.#logger;
|
|
3904
|
+
}
|
|
3795
3905
|
getSubCommandName() {
|
|
3796
3906
|
return this.#subCommandName;
|
|
3797
3907
|
}
|
|
@@ -3958,7 +4068,9 @@ class ArgParserBase {
|
|
|
3958
4068
|
subParser.#appCommandName = this.#appCommandName;
|
|
3959
4069
|
}
|
|
3960
4070
|
subParser.#autoExit = this.#autoExit;
|
|
3961
|
-
|
|
4071
|
+
subParser.#triggerAutoHelpIfNoHandler = this.#triggerAutoHelpIfNoHandler;
|
|
4072
|
+
const shouldInherit = subParser.#inheritParentFlags === true || subParser.#inheritParentFlags === FlagInheritance.DirectParentOnly || subParser.#inheritParentFlags === FlagInheritance.AllParents;
|
|
4073
|
+
if (shouldInherit) {
|
|
3962
4074
|
const parentFlags = this.#flagManager.flags;
|
|
3963
4075
|
for (const parentFlag of parentFlags) {
|
|
3964
4076
|
if (!subParser.#flagManager.hasFlag(parentFlag["name"])) {
|
|
@@ -3967,11 +4079,38 @@ class ArgParserBase {
|
|
|
3967
4079
|
}
|
|
3968
4080
|
}
|
|
3969
4081
|
this.#subCommands.set(subCommandConfig.name, subCommandConfig);
|
|
4082
|
+
this.#propagateFlagsRecursive(subParser);
|
|
3970
4083
|
if (subCommandConfig.handler) {
|
|
3971
4084
|
subParser.setHandler(subCommandConfig.handler);
|
|
3972
4085
|
}
|
|
3973
4086
|
return this;
|
|
3974
4087
|
}
|
|
4088
|
+
/**
|
|
4089
|
+
* Propagates available flags from the current parser to its subcommands,
|
|
4090
|
+
* if those subcommands are configured to inherit recursively (AllParents).
|
|
4091
|
+
*/
|
|
4092
|
+
#propagateFlagsRecursive(parser) {
|
|
4093
|
+
for (const [_, subConfig] of parser.getSubCommands()) {
|
|
4094
|
+
const childParser = subConfig.parser;
|
|
4095
|
+
if (!(childParser instanceof ArgParserBase)) continue;
|
|
4096
|
+
const isAllParents = childParser.#inheritParentFlags === FlagInheritance.AllParents;
|
|
4097
|
+
if (isAllParents) {
|
|
4098
|
+
const parentFlags = parser.#flagManager.flags;
|
|
4099
|
+
let flagsAdded = false;
|
|
4100
|
+
for (const parentFlag of parentFlags) {
|
|
4101
|
+
if (!childParser.#flagManager.hasFlag(parentFlag["name"])) {
|
|
4102
|
+
childParser.#flagManager._setProcessedFlagForInheritance(
|
|
4103
|
+
parentFlag
|
|
4104
|
+
);
|
|
4105
|
+
flagsAdded = true;
|
|
4106
|
+
}
|
|
4107
|
+
}
|
|
4108
|
+
if (flagsAdded) {
|
|
4109
|
+
this.#propagateFlagsRecursive(childParser);
|
|
4110
|
+
}
|
|
4111
|
+
}
|
|
4112
|
+
}
|
|
4113
|
+
}
|
|
3975
4114
|
/**
|
|
3976
4115
|
* Sets the handler function for this specific parser instance.
|
|
3977
4116
|
* This handler will be executed if this parser is the final one
|
|
@@ -3995,7 +4134,7 @@ class ArgParserBase {
|
|
|
3995
4134
|
const outputObject = this.#_buildRecursiveJson(this);
|
|
3996
4135
|
const jsonString = JSON.stringify(outputObject, null, 2);
|
|
3997
4136
|
fs__namespace.writeFileSync(filePath, jsonString);
|
|
3998
|
-
|
|
4137
|
+
this.#logger.info(`ArgParser configuration JSON dumped to: ${filePath}`);
|
|
3999
4138
|
} else {
|
|
4000
4139
|
const outputString = this.#_buildRecursiveString(this, 0);
|
|
4001
4140
|
const plainText = outputString.replace(
|
|
@@ -4003,18 +4142,18 @@ class ArgParserBase {
|
|
|
4003
4142
|
""
|
|
4004
4143
|
);
|
|
4005
4144
|
fs__namespace.writeFileSync(filePath, plainText);
|
|
4006
|
-
|
|
4145
|
+
this.#logger.info(`ArgParser configuration text dumped to: ${filePath}`);
|
|
4007
4146
|
}
|
|
4008
4147
|
} catch (error) {
|
|
4009
|
-
|
|
4148
|
+
this.#logger.error(
|
|
4010
4149
|
`Error writing ArgParser configuration to file '${filePath}':`,
|
|
4011
4150
|
error
|
|
4012
4151
|
);
|
|
4013
4152
|
}
|
|
4014
4153
|
} else {
|
|
4015
|
-
|
|
4154
|
+
this.#logger.info("\n--- ArgParser Configuration Dump ---");
|
|
4016
4155
|
this.#_printRecursiveToConsole(this, 0);
|
|
4017
|
-
|
|
4156
|
+
this.#logger.info("--- End Configuration Dump ---\\n");
|
|
4018
4157
|
}
|
|
4019
4158
|
}
|
|
4020
4159
|
#_identifyCommandChainAndParsers(argsToParse, currentParser, commandChainSoFar, parserChainSoFar) {
|
|
@@ -4053,10 +4192,85 @@ class ArgParserBase {
|
|
|
4053
4192
|
nextParserChain
|
|
4054
4193
|
);
|
|
4055
4194
|
}
|
|
4195
|
+
#_resolveWorkingDirectory(processArgs, parserChain) {
|
|
4196
|
+
if (!this.#rootPath) {
|
|
4197
|
+
this.#rootPath = process.cwd();
|
|
4198
|
+
}
|
|
4199
|
+
let foundCwd = null;
|
|
4200
|
+
for (let i = parserChain.length - 1; i >= 0; i--) {
|
|
4201
|
+
const parser = parserChain[i];
|
|
4202
|
+
const chdirFlags = parser.#flagManager.flags.filter(
|
|
4203
|
+
(flag) => flag["setWorkingDirectory"]
|
|
4204
|
+
);
|
|
4205
|
+
for (const flag of chdirFlags) {
|
|
4206
|
+
for (const option of flag["options"]) {
|
|
4207
|
+
const flagIndex = processArgs.indexOf(option);
|
|
4208
|
+
if (flagIndex !== -1 && flagIndex + 1 < processArgs.length) {
|
|
4209
|
+
const value = processArgs[flagIndex + 1];
|
|
4210
|
+
if (!value || value.startsWith("-")) continue;
|
|
4211
|
+
const resolvedPath = path__namespace.resolve(
|
|
4212
|
+
this.#effectiveWorkingDirectory || this.#rootPath,
|
|
4213
|
+
value
|
|
4214
|
+
);
|
|
4215
|
+
if (!fs__namespace.existsSync(resolvedPath)) {
|
|
4216
|
+
console.warn(
|
|
4217
|
+
simpleChalk.yellow(
|
|
4218
|
+
`Warning: Working directory '${resolvedPath}' specified by ${option} does not exist. Using current directory instead.`
|
|
4219
|
+
)
|
|
4220
|
+
);
|
|
4221
|
+
continue;
|
|
4222
|
+
}
|
|
4223
|
+
if (!fs__namespace.statSync(resolvedPath).isDirectory()) {
|
|
4224
|
+
console.warn(
|
|
4225
|
+
simpleChalk.yellow(
|
|
4226
|
+
`Warning: Path '${resolvedPath}' specified by ${option} is not a directory. Using current directory instead.`
|
|
4227
|
+
)
|
|
4228
|
+
);
|
|
4229
|
+
continue;
|
|
4230
|
+
}
|
|
4231
|
+
foundCwd = resolvedPath;
|
|
4232
|
+
process.chdir(resolvedPath);
|
|
4233
|
+
const allChdirIndices = [];
|
|
4234
|
+
for (let j = 0; j < processArgs.length; j++) {
|
|
4235
|
+
for (const p of parserChain) {
|
|
4236
|
+
for (const f of p.#flagManager.flags) {
|
|
4237
|
+
if (f["setWorkingDirectory"] && f["options"].includes(processArgs[j])) {
|
|
4238
|
+
allChdirIndices.push({ index: j, flag: processArgs[j] });
|
|
4239
|
+
}
|
|
4240
|
+
}
|
|
4241
|
+
}
|
|
4242
|
+
}
|
|
4243
|
+
if (allChdirIndices.length > 1) {
|
|
4244
|
+
this.#logger.warn(
|
|
4245
|
+
simpleChalk.yellow(
|
|
4246
|
+
`Warning: Multiple working directory flags detected. Using '${option}' (last one in command chain).`
|
|
4247
|
+
)
|
|
4248
|
+
);
|
|
4249
|
+
}
|
|
4250
|
+
break;
|
|
4251
|
+
}
|
|
4252
|
+
}
|
|
4253
|
+
if (foundCwd) break;
|
|
4254
|
+
}
|
|
4255
|
+
if (foundCwd) break;
|
|
4256
|
+
}
|
|
4257
|
+
return {
|
|
4258
|
+
effectiveCwd: foundCwd || this.#rootPath,
|
|
4259
|
+
rootPath: this.#rootPath
|
|
4260
|
+
};
|
|
4261
|
+
}
|
|
4056
4262
|
async #_handleGlobalChecks(processArgs, options) {
|
|
4263
|
+
const { finalParser: parserChainParser } = this.#_identifyCommandChainAndParsers(processArgs, this, [], [this]);
|
|
4264
|
+
const { effectiveCwd, rootPath } = this.#_resolveWorkingDirectory(
|
|
4265
|
+
processArgs,
|
|
4266
|
+
parserChainParser ? [this, parserChainParser] : [this]
|
|
4267
|
+
);
|
|
4268
|
+
this.#effectiveWorkingDirectory = effectiveCwd;
|
|
4269
|
+
this.#rootPath = rootPath;
|
|
4270
|
+
this.#workingDirectoryResolved = true;
|
|
4057
4271
|
const isRootCliParser = !this.#parentParser && !!this.#appCommandName;
|
|
4058
4272
|
if (processArgs.length === 0 && isRootCliParser && !this.#handler && !options?.skipHelpHandling) {
|
|
4059
|
-
|
|
4273
|
+
this.#logger.info(this.helpText());
|
|
4060
4274
|
return this._handleExit(0, "Help displayed", "help");
|
|
4061
4275
|
}
|
|
4062
4276
|
if (processArgs.includes("--s-debug-print")) {
|
|
@@ -4070,66 +4284,101 @@ class ArgParserBase {
|
|
|
4070
4284
|
}
|
|
4071
4285
|
const withEnvIndex = processArgs.findIndex((arg) => arg === "--s-with-env");
|
|
4072
4286
|
if (withEnvIndex !== -1) {
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4287
|
+
let envFilePath = null;
|
|
4288
|
+
let shouldAutoDiscover;
|
|
4289
|
+
shouldAutoDiscover = this.#workingDirectoryResolved && this.#effectiveWorkingDirectory !== this.#rootPath && withEnvIndex + 1 >= processArgs.length;
|
|
4290
|
+
if (withEnvIndex + 1 < processArgs.length) {
|
|
4291
|
+
const providedPath = processArgs[withEnvIndex + 1];
|
|
4292
|
+
if (providedPath && !providedPath.startsWith("-")) {
|
|
4293
|
+
const basePath = this.#effectiveWorkingDirectory || process.cwd();
|
|
4294
|
+
envFilePath = path__namespace.resolve(basePath, providedPath);
|
|
4295
|
+
} else {
|
|
4296
|
+
const basePath = this.#effectiveWorkingDirectory || process.cwd();
|
|
4297
|
+
envFilePath = this.#configurationManager.discoverEnvFile(basePath);
|
|
4298
|
+
if (!envFilePath) {
|
|
4299
|
+
this.#logger.warn(
|
|
4300
|
+
simpleChalk.yellow(
|
|
4301
|
+
"Warning: No .env file found in working directory. Continuing without environment configuration."
|
|
4302
|
+
)
|
|
4303
|
+
);
|
|
4304
|
+
processArgs.splice(withEnvIndex, 1);
|
|
4305
|
+
}
|
|
4306
|
+
}
|
|
4082
4307
|
}
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
|
|
4086
|
-
|
|
4087
|
-
|
|
4088
|
-
|
|
4089
|
-
|
|
4090
|
-
|
|
4091
|
-
|
|
4092
|
-
|
|
4308
|
+
if (shouldAutoDiscover) {
|
|
4309
|
+
const basePath = this.#effectiveWorkingDirectory || process.cwd();
|
|
4310
|
+
envFilePath = this.#configurationManager.discoverEnvFile(basePath);
|
|
4311
|
+
if (envFilePath) {
|
|
4312
|
+
this.#logger.info(simpleChalk.dim(`Auto-discovered env file: ${envFilePath}`));
|
|
4313
|
+
} else {
|
|
4314
|
+
this.#logger.warn(
|
|
4315
|
+
simpleChalk.yellow(
|
|
4316
|
+
"Warning: No .env file found in working directory. Continuing without environment configuration."
|
|
4317
|
+
)
|
|
4318
|
+
);
|
|
4319
|
+
processArgs.splice(withEnvIndex, 1);
|
|
4320
|
+
}
|
|
4093
4321
|
}
|
|
4094
|
-
|
|
4095
|
-
|
|
4096
|
-
|
|
4097
|
-
|
|
4098
|
-
|
|
4099
|
-
|
|
4100
|
-
|
|
4101
|
-
|
|
4102
|
-
|
|
4103
|
-
|
|
4104
|
-
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4322
|
+
if (envFilePath) {
|
|
4323
|
+
try {
|
|
4324
|
+
const {
|
|
4325
|
+
finalParser: identifiedFinalParser2,
|
|
4326
|
+
parserChain: identifiedParserChain
|
|
4327
|
+
} = this.#_identifyCommandChainAndParsers(
|
|
4328
|
+
processArgs,
|
|
4329
|
+
this,
|
|
4330
|
+
[],
|
|
4331
|
+
[this]
|
|
4332
|
+
);
|
|
4333
|
+
const envConfigArgs = identifiedFinalParser2.#configurationManager.loadEnvFile(
|
|
4334
|
+
envFilePath,
|
|
4335
|
+
identifiedParserChain
|
|
4336
|
+
);
|
|
4337
|
+
if (envConfigArgs) {
|
|
4338
|
+
const mergedArgs = identifiedFinalParser2.#configurationManager.mergeEnvConfigWithArgs(
|
|
4339
|
+
envConfigArgs,
|
|
4340
|
+
processArgs
|
|
4341
|
+
);
|
|
4342
|
+
processArgs.length = 0;
|
|
4343
|
+
processArgs.push(...mergedArgs);
|
|
4344
|
+
}
|
|
4345
|
+
const finalWithEnvIndex = processArgs.findIndex(
|
|
4346
|
+
(arg) => arg === "--s-with-env"
|
|
4347
|
+
);
|
|
4348
|
+
if (finalWithEnvIndex !== -1) {
|
|
4349
|
+
if (finalWithEnvIndex + 1 < processArgs.length && !processArgs[finalWithEnvIndex + 1].startsWith("-")) {
|
|
4350
|
+
processArgs.splice(finalWithEnvIndex, 2);
|
|
4351
|
+
} else {
|
|
4352
|
+
processArgs.splice(finalWithEnvIndex, 1);
|
|
4353
|
+
}
|
|
4354
|
+
}
|
|
4355
|
+
} catch (error) {
|
|
4356
|
+
console.error(
|
|
4357
|
+
simpleChalk.red(
|
|
4358
|
+
`Error loading environment file: ${error instanceof Error ? error.message : String(error)}`
|
|
4359
|
+
)
|
|
4360
|
+
);
|
|
4361
|
+
return this._handleExit(
|
|
4362
|
+
1,
|
|
4363
|
+
`Error loading environment file: ${error instanceof Error ? error.message : String(error)}`,
|
|
4364
|
+
"error"
|
|
4112
4365
|
);
|
|
4113
|
-
processArgs.length = 0;
|
|
4114
|
-
processArgs.push(...mergedArgs);
|
|
4115
4366
|
}
|
|
4116
|
-
|
|
4117
|
-
|
|
4118
|
-
|
|
4119
|
-
|
|
4120
|
-
|
|
4367
|
+
}
|
|
4368
|
+
shouldAutoDiscover = this.#workingDirectoryResolved && this.#effectiveWorkingDirectory !== this.#rootPath && withEnvIndex + 1 >= processArgs.length;
|
|
4369
|
+
if (shouldAutoDiscover) {
|
|
4370
|
+
const basePath = this.#effectiveWorkingDirectory || process.cwd();
|
|
4371
|
+
envFilePath = this.#configurationManager.discoverEnvFile(basePath);
|
|
4372
|
+
if (envFilePath) {
|
|
4373
|
+
console.warn(`Auto-discovered env file: ${envFilePath}`);
|
|
4374
|
+
} else {
|
|
4375
|
+
console.warn(
|
|
4376
|
+
"Warning: No .env file found in working directory. Continuing without environment configuration."
|
|
4377
|
+
);
|
|
4378
|
+
}
|
|
4379
|
+
if (!envFilePath) {
|
|
4380
|
+
processArgs.splice(withEnvIndex, 1);
|
|
4121
4381
|
}
|
|
4122
|
-
} catch (error) {
|
|
4123
|
-
console.error(
|
|
4124
|
-
simpleChalk.red(
|
|
4125
|
-
`Error loading environment file: ${error instanceof Error ? error.message : String(error)}`
|
|
4126
|
-
)
|
|
4127
|
-
);
|
|
4128
|
-
return this._handleExit(
|
|
4129
|
-
1,
|
|
4130
|
-
`Error loading environment file: ${error instanceof Error ? error.message : String(error)}`,
|
|
4131
|
-
"error"
|
|
4132
|
-
);
|
|
4133
4382
|
}
|
|
4134
4383
|
}
|
|
4135
4384
|
const { finalParser: identifiedFinalParser } = this.#_identifyCommandChainAndParsers(processArgs, this, [], [this]);
|
|
@@ -4205,7 +4454,9 @@ class ArgParserBase {
|
|
|
4205
4454
|
});
|
|
4206
4455
|
break;
|
|
4207
4456
|
}
|
|
4208
|
-
currentParser = currentParser.#subCommands.get(
|
|
4457
|
+
currentParser = currentParser.#subCommands.get(
|
|
4458
|
+
subCommandName
|
|
4459
|
+
)?.parser;
|
|
4209
4460
|
remainingArgs = remainingArgs.slice(1);
|
|
4210
4461
|
const nextSubCommandIndex = remainingArgs.findIndex(
|
|
4211
4462
|
(arg) => currentParser.#subCommands.has(arg)
|
|
@@ -4227,43 +4478,43 @@ class ArgParserBase {
|
|
|
4227
4478
|
}
|
|
4228
4479
|
remainingArgs = nextSubCommandIndex === -1 ? [] : remainingArgs.slice(nextSubCommandIndex);
|
|
4229
4480
|
}
|
|
4230
|
-
|
|
4481
|
+
this.#logger.info(simpleChalk.yellow("\nParsing Simulation Steps:"));
|
|
4231
4482
|
parsingSteps.forEach((step) => {
|
|
4232
|
-
|
|
4233
|
-
|
|
4483
|
+
this.#logger.info(` Level: ${simpleChalk.cyan(step.level)}`);
|
|
4484
|
+
this.#logger.info(
|
|
4234
4485
|
` Args Slice Considered: ${JSON.stringify(step.argsSlice)}`
|
|
4235
4486
|
);
|
|
4236
4487
|
if (step.parsed) {
|
|
4237
|
-
|
|
4488
|
+
this.#logger.info(
|
|
4238
4489
|
` Parsed Args at this Level: ${JSON.stringify(step.parsed)}`
|
|
4239
4490
|
);
|
|
4240
4491
|
}
|
|
4241
4492
|
if (step.error) {
|
|
4242
|
-
|
|
4493
|
+
this.#logger.info(
|
|
4243
4494
|
` ${simpleChalk.red("Error during parse simulation:")} ${step.error}`
|
|
4244
4495
|
);
|
|
4245
4496
|
}
|
|
4246
4497
|
});
|
|
4247
|
-
|
|
4498
|
+
this.#logger.info(
|
|
4248
4499
|
simpleChalk.yellow(
|
|
4249
4500
|
"\nFinal Accumulated Args State (before final validation):"
|
|
4250
4501
|
)
|
|
4251
4502
|
);
|
|
4252
|
-
|
|
4253
|
-
|
|
4254
|
-
|
|
4255
|
-
|
|
4503
|
+
this.#logger.info(JSON.stringify(accumulatedArgs, null, 2));
|
|
4504
|
+
this.#logger.info(simpleChalk.yellow("\nArguments Remaining After Simulation:"));
|
|
4505
|
+
this.#logger.info(JSON.stringify(remainingArgs, null, 2));
|
|
4506
|
+
this.#logger.info(
|
|
4256
4507
|
simpleChalk.yellow.bold(
|
|
4257
4508
|
"\n--- ArgParser Static Configuration (Final Parser) ---"
|
|
4258
4509
|
)
|
|
4259
4510
|
);
|
|
4260
4511
|
identifiedFinalParser.printAll();
|
|
4261
|
-
|
|
4512
|
+
this.#logger.info(simpleChalk.yellow.bold("--- End ArgParser --s-debug ---"));
|
|
4262
4513
|
return this._handleExit(0, "Debug information displayed", "debug");
|
|
4263
4514
|
}
|
|
4264
4515
|
let parserNameForLog = "undefined_parser";
|
|
4265
4516
|
if (identifiedFinalParser instanceof ArgParserBase) {
|
|
4266
|
-
parserNameForLog = identifiedFinalParser
|
|
4517
|
+
parserNameForLog = identifiedFinalParser.getSubCommandName() || identifiedFinalParser.getAppName() || "unknown";
|
|
4267
4518
|
} else if (identifiedFinalParser) {
|
|
4268
4519
|
parserNameForLog = identifiedFinalParser.name || identifiedFinalParser.appName || "unknown_type";
|
|
4269
4520
|
}
|
|
@@ -4372,14 +4623,21 @@ class ArgParserBase {
|
|
|
4372
4623
|
}
|
|
4373
4624
|
if (foundVal !== void 0) {
|
|
4374
4625
|
try {
|
|
4375
|
-
const typedVal = this.#configurationManager.convertValueToFlagType(
|
|
4626
|
+
const typedVal = this.#configurationManager.convertValueToFlagType(
|
|
4627
|
+
foundVal,
|
|
4628
|
+
flag
|
|
4629
|
+
);
|
|
4376
4630
|
if (flag["allowMultiple"]) {
|
|
4377
4631
|
finalArgs[flagName] = Array.isArray(typedVal) ? typedVal : [typedVal];
|
|
4378
4632
|
} else {
|
|
4379
4633
|
finalArgs[flagName] = typedVal;
|
|
4380
4634
|
}
|
|
4381
4635
|
} catch (e) {
|
|
4382
|
-
console.warn(
|
|
4636
|
+
console.warn(
|
|
4637
|
+
simpleChalk.yellow(
|
|
4638
|
+
`Warning: Failed to parse env var for flag '${flagName}': ${e}`
|
|
4639
|
+
)
|
|
4640
|
+
);
|
|
4383
4641
|
}
|
|
4384
4642
|
}
|
|
4385
4643
|
}
|
|
@@ -4420,7 +4678,7 @@ class ArgParserBase {
|
|
|
4420
4678
|
return;
|
|
4421
4679
|
}
|
|
4422
4680
|
const finalParserWhoseHandlerWillRun = handlerToExecute.context.parser;
|
|
4423
|
-
const finalParserFlags = finalParserWhoseHandlerWillRun
|
|
4681
|
+
const finalParserFlags = finalParserWhoseHandlerWillRun.flags;
|
|
4424
4682
|
const handlerArgs = handlerToExecute.context.args;
|
|
4425
4683
|
for (const flag of finalParserFlags) {
|
|
4426
4684
|
const flagName = flag["name"];
|
|
@@ -4634,16 +4892,33 @@ class ArgParserBase {
|
|
|
4634
4892
|
finalParseResultArgs["$commandChain"] = commandChainSoFar;
|
|
4635
4893
|
}
|
|
4636
4894
|
let handlerToExecute = void 0;
|
|
4895
|
+
const handlerContext = {
|
|
4896
|
+
args: currentLevelArgs,
|
|
4897
|
+
parentArgs: accumulatedParentArgs,
|
|
4898
|
+
commandChain: commandChainSoFar,
|
|
4899
|
+
parser: currentParser,
|
|
4900
|
+
parentParser,
|
|
4901
|
+
// displayHelp implementation that respects autoExit setting
|
|
4902
|
+
displayHelp: () => {
|
|
4903
|
+
console.log(currentParser.helpText());
|
|
4904
|
+
if (currentParser.getAutoExit() && typeof process === "object" && typeof process.exit === "function") {
|
|
4905
|
+
process.exit(0);
|
|
4906
|
+
}
|
|
4907
|
+
},
|
|
4908
|
+
// Add rootPath if working directory was resolved
|
|
4909
|
+
rootPath: this.#rootPath || void 0,
|
|
4910
|
+
logger: this.#logger,
|
|
4911
|
+
isMcp: options?.isMcp || false
|
|
4912
|
+
};
|
|
4637
4913
|
if (currentParser.#handler) {
|
|
4638
4914
|
handlerToExecute = {
|
|
4639
4915
|
handler: currentParser.#handler,
|
|
4640
|
-
context:
|
|
4641
|
-
|
|
4642
|
-
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
}
|
|
4916
|
+
context: handlerContext
|
|
4917
|
+
};
|
|
4918
|
+
} else if (currentParser.#triggerAutoHelpIfNoHandler) {
|
|
4919
|
+
handlerToExecute = {
|
|
4920
|
+
handler: (ctx) => ctx.displayHelp(),
|
|
4921
|
+
context: handlerContext
|
|
4647
4922
|
};
|
|
4648
4923
|
}
|
|
4649
4924
|
return { finalArgs: finalParseResultArgs, handlerToExecute };
|
|
@@ -4948,8 +5223,8 @@ ${cyan("Flags:")}
|
|
|
4948
5223
|
if (typeof flag["type"] === "function" && flag["type"].name === "Array") {
|
|
4949
5224
|
isRepeatable = true;
|
|
4950
5225
|
}
|
|
4951
|
-
const
|
|
4952
|
-
if (
|
|
5226
|
+
const maybeZodSchema = flag["type"];
|
|
5227
|
+
if (maybeZodSchema && typeof maybeZodSchema === "object" && maybeZodSchema._def && maybeZodSchema._def.typeName === "ZodArray") {
|
|
4953
5228
|
isRepeatable = true;
|
|
4954
5229
|
}
|
|
4955
5230
|
if (flag["allowMultiple"]) isRepeatable = true;
|
|
@@ -5055,9 +5330,9 @@ ${indent(2)}${white(line)}`).join("")}
|
|
|
5055
5330
|
} catch {
|
|
5056
5331
|
}
|
|
5057
5332
|
}
|
|
5058
|
-
|
|
5333
|
+
this.#logger.error(`
|
|
5059
5334
|
${simpleChalk.red.bold("Error:")} ${error.message}`);
|
|
5060
|
-
|
|
5335
|
+
this.#logger.error(
|
|
5061
5336
|
`
|
|
5062
5337
|
${simpleChalk.dim(`Try '${commandNameToSuggest} --help' for usage details.`)}`
|
|
5063
5338
|
);
|
|
@@ -5081,65 +5356,65 @@ ${simpleChalk.dim(`Try '${commandNameToSuggest} --help' for usage details.`)}`
|
|
|
5081
5356
|
const indent = " ".repeat(level);
|
|
5082
5357
|
const subIndent = " ".repeat(level + 1);
|
|
5083
5358
|
const flagIndent = " ".repeat(level + 2);
|
|
5084
|
-
|
|
5359
|
+
this.#logger.info(
|
|
5085
5360
|
`${indent}Parser: ${simpleChalk.blueBright(parser.#subCommandName || parser.#appName)}`
|
|
5086
5361
|
);
|
|
5087
5362
|
if (parser.#description) {
|
|
5088
|
-
|
|
5363
|
+
this.#logger.info(`${subIndent}Description: ${parser.#description}`);
|
|
5089
5364
|
}
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5365
|
+
this.#logger.info(`${subIndent}Options:`);
|
|
5366
|
+
this.#logger.info(`${flagIndent}appName: ${parser.#appName}`);
|
|
5367
|
+
this.#logger.info(
|
|
5093
5368
|
`${flagIndent}appCommandName: ${parser.#appCommandName ?? simpleChalk.dim("undefined")}`
|
|
5094
5369
|
);
|
|
5095
|
-
|
|
5096
|
-
|
|
5370
|
+
this.#logger.info(`${flagIndent}handleErrors: ${parser.#handleErrors}`);
|
|
5371
|
+
this.#logger.info(
|
|
5097
5372
|
`${flagIndent}throwForDuplicateFlags: ${parser.#throwForDuplicateFlags}`
|
|
5098
5373
|
);
|
|
5099
|
-
|
|
5374
|
+
this.#logger.info(
|
|
5100
5375
|
`${flagIndent}inheritParentFlags: ${parser.#inheritParentFlags}`
|
|
5101
5376
|
);
|
|
5102
|
-
|
|
5103
|
-
|
|
5377
|
+
this.#logger.info(`${flagIndent}Handler Defined: ${!!parser.#handler}`);
|
|
5378
|
+
this.#logger.info(
|
|
5104
5379
|
`${subIndent}Internal Params: ${JSON.stringify(parser.#parameters)}`
|
|
5105
5380
|
);
|
|
5106
5381
|
const flags = parser.#flagManager.flags;
|
|
5107
5382
|
if (flags.length > 0) {
|
|
5108
|
-
|
|
5383
|
+
this.#logger.info(`${subIndent}Flags (${flags.length}):`);
|
|
5109
5384
|
flags.forEach((flag) => {
|
|
5110
|
-
|
|
5111
|
-
|
|
5112
|
-
|
|
5385
|
+
this.#logger.info(`${flagIndent}* ${simpleChalk.green(flag["name"])}:`);
|
|
5386
|
+
this.#logger.info(`${flagIndent} Options: ${flag["options"].join(", ")}`);
|
|
5387
|
+
this.#logger.info(
|
|
5113
5388
|
`${flagIndent} Description: ${Array.isArray(flag["description"]) ? flag["description"].join(" | ") : flag["description"]}`
|
|
5114
5389
|
);
|
|
5115
|
-
|
|
5390
|
+
this.#logger.info(
|
|
5116
5391
|
`${flagIndent} Type: ${typeof flag["type"] === "function" ? flag["type"].name || "custom function" : flag["type"]}`
|
|
5117
5392
|
);
|
|
5118
|
-
|
|
5393
|
+
this.#logger.info(
|
|
5119
5394
|
`${flagIndent} Mandatory: ${typeof flag["mandatory"] === "function" ? "dynamic" : flag["mandatory"] ?? false}`
|
|
5120
5395
|
);
|
|
5121
|
-
|
|
5396
|
+
this.#logger.info(
|
|
5122
5397
|
`${flagIndent} Default: ${JSON.stringify(flag["defaultValue"])}`
|
|
5123
5398
|
);
|
|
5124
|
-
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5399
|
+
this.#logger.info(`${flagIndent} Flag Only: ${flag["flagOnly"]}`);
|
|
5400
|
+
this.#logger.info(`${flagIndent} Allow Multiple: ${flag["allowMultiple"]}`);
|
|
5401
|
+
this.#logger.info(`${flagIndent} Allow Ligature: ${flag["allowLigature"]}`);
|
|
5402
|
+
this.#logger.info(
|
|
5128
5403
|
`${flagIndent} Enum: ${flag["enum"] && flag["enum"].length > 0 ? flag["enum"].join(", ") : "none"}`
|
|
5129
5404
|
);
|
|
5130
|
-
|
|
5405
|
+
this.#logger.info(`${flagIndent} Validator Defined: ${!!flag["validate"]}`);
|
|
5131
5406
|
});
|
|
5132
5407
|
} else {
|
|
5133
|
-
|
|
5408
|
+
this.#logger.info(`${subIndent}Flags: ${simpleChalk.dim("none")}`);
|
|
5134
5409
|
}
|
|
5135
5410
|
const subCommandParsers = Array.from(parser.#subCommands.values());
|
|
5136
5411
|
if (subCommandParsers.length > 0) {
|
|
5137
|
-
|
|
5412
|
+
this.#logger.info(`${subIndent}Sub-Commands (${subCommandParsers.length}):`);
|
|
5138
5413
|
subCommandParsers.forEach((subCommand) => {
|
|
5139
5414
|
this.#_printRecursiveToConsole(subCommand.parser, level + 1, visited);
|
|
5140
5415
|
});
|
|
5141
5416
|
} else {
|
|
5142
|
-
|
|
5417
|
+
this.#logger.info(`${subIndent}Sub-Commands: ${simpleChalk.dim("none")}`);
|
|
5143
5418
|
}
|
|
5144
5419
|
}
|
|
5145
5420
|
#_buildRecursiveString(parser, level, visited = /* @__PURE__ */ new Set()) {
|
|
@@ -5446,6 +5721,7 @@ ${simpleChalk.dim(`Try '${commandNameToSuggest} --help' for usage details.`)}`
|
|
|
5446
5721
|
}
|
|
5447
5722
|
debug.log("Created MCP logger, about to hijack console");
|
|
5448
5723
|
globalThis.console = mcpLogger;
|
|
5724
|
+
this.#logger = mcpLogger;
|
|
5449
5725
|
debug.log("Console hijacked successfully");
|
|
5450
5726
|
} catch {
|
|
5451
5727
|
debug.log("Failed to import simple-mcp-logger, using fallback");
|
|
@@ -5758,6 +6034,9 @@ ${simpleChalk.dim(`Try '${commandNameToSuggest} --help' for usage details.`)}`
|
|
|
5758
6034
|
return options;
|
|
5759
6035
|
}
|
|
5760
6036
|
}
|
|
6037
|
+
const autoHelpHandler = async (ctx) => {
|
|
6038
|
+
ctx.displayHelp();
|
|
6039
|
+
};
|
|
5761
6040
|
function sanitizeMcpToolName(name) {
|
|
5762
6041
|
if (!name || typeof name !== "string") {
|
|
5763
6042
|
throw new Error("Tool name must be a non-empty string");
|
|
@@ -5778,6 +6057,7 @@ function isValidMcpToolName(name) {
|
|
|
5778
6057
|
const mcpNamePattern = /^[a-zA-Z0-9_-]{1,64}$/;
|
|
5779
6058
|
return mcpNamePattern.test(name);
|
|
5780
6059
|
}
|
|
6060
|
+
const logger$1 = simpleMcpLogger.createMcpLogger("MCP Integration");
|
|
5781
6061
|
function createMcpSuccessResponse(data2) {
|
|
5782
6062
|
return {
|
|
5783
6063
|
content: [
|
|
@@ -5813,7 +6093,7 @@ function convertFlagToJsonSchemaProperty(flag) {
|
|
|
5813
6093
|
const isRequired2 = !!(flag.mandatory || flag.required);
|
|
5814
6094
|
return { property: property2, isRequired: isRequired2 };
|
|
5815
6095
|
} catch (error) {
|
|
5816
|
-
|
|
6096
|
+
logger$1.error(`Failed to convert Zod schema to JSON Schema for flag '${flag.name}':`, error);
|
|
5817
6097
|
const property2 = {
|
|
5818
6098
|
type: "object",
|
|
5819
6099
|
description: flag.description || `${flag.name} parameter (Zod schema)`
|
|
@@ -6003,8 +6283,7 @@ function mapArgParserFlagToZodSchema(flag) {
|
|
|
6003
6283
|
zodSchema = zod.z.record(zod.z.string(), zod.z.any());
|
|
6004
6284
|
break;
|
|
6005
6285
|
default:
|
|
6006
|
-
|
|
6007
|
-
logger.mcpError(
|
|
6286
|
+
logger$1.error(
|
|
6008
6287
|
`Flag '${flag["name"]}' has an unknown type '${typeName}'. Defaulting to z.string().`
|
|
6009
6288
|
);
|
|
6010
6289
|
zodSchema = zod.z.string();
|
|
@@ -6100,10 +6379,10 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6100
6379
|
outputSchema,
|
|
6101
6380
|
async execute(mcpInputArgs) {
|
|
6102
6381
|
if (process.env["MCP_DEBUG"]) {
|
|
6103
|
-
|
|
6382
|
+
logger$1.error(
|
|
6104
6383
|
`[MCP Execute] Starting execution for tool '${toolName}'`
|
|
6105
6384
|
);
|
|
6106
|
-
|
|
6385
|
+
logger$1.error(
|
|
6107
6386
|
`[MCP Execute] Input args:`,
|
|
6108
6387
|
JSON.stringify(mcpInputArgs, null, 2)
|
|
6109
6388
|
);
|
|
@@ -6178,7 +6457,7 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6178
6457
|
}
|
|
6179
6458
|
try {
|
|
6180
6459
|
if (process.env["MCP_DEBUG"]) {
|
|
6181
|
-
|
|
6460
|
+
logger$1.error(
|
|
6182
6461
|
`[MCP Execute] Starting try block for tool '${toolName}'`
|
|
6183
6462
|
);
|
|
6184
6463
|
}
|
|
@@ -6186,25 +6465,25 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6186
6465
|
const unifiedTools = rootParserTyped._tools;
|
|
6187
6466
|
const isUnifiedTool = unifiedTools && unifiedTools.has(toolName);
|
|
6188
6467
|
if (process.env["MCP_DEBUG"]) {
|
|
6189
|
-
|
|
6468
|
+
logger$1.error(
|
|
6190
6469
|
`[MCP Tool Debug] Checking tool '${toolName}' for unified execution`
|
|
6191
6470
|
);
|
|
6192
|
-
|
|
6193
|
-
|
|
6471
|
+
logger$1.error(`[MCP Tool Debug] Has _tools:`, !!unifiedTools);
|
|
6472
|
+
logger$1.error(
|
|
6194
6473
|
`[MCP Tool Debug] Available tools:`,
|
|
6195
6474
|
unifiedTools ? Array.from(unifiedTools.keys()) : []
|
|
6196
6475
|
);
|
|
6197
|
-
|
|
6476
|
+
logger$1.error(`[MCP Tool Debug] Is unified tool:`, isUnifiedTool);
|
|
6198
6477
|
}
|
|
6199
6478
|
let parseResult;
|
|
6200
6479
|
if (isUnifiedTool) {
|
|
6201
6480
|
const toolConfig = unifiedTools.get(toolName);
|
|
6202
6481
|
if (process.env["MCP_DEBUG"]) {
|
|
6203
|
-
|
|
6482
|
+
logger$1.error(
|
|
6204
6483
|
`[MCP Tool Debug] Found unified tool config:`,
|
|
6205
6484
|
!!toolConfig
|
|
6206
6485
|
);
|
|
6207
|
-
|
|
6486
|
+
logger$1.error(
|
|
6208
6487
|
`[MCP Tool Debug] Has handler:`,
|
|
6209
6488
|
!!(toolConfig && toolConfig.handler)
|
|
6210
6489
|
);
|
|
@@ -6212,10 +6491,10 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6212
6491
|
if (toolConfig && toolConfig.handler) {
|
|
6213
6492
|
try {
|
|
6214
6493
|
if (process.env["MCP_DEBUG"]) {
|
|
6215
|
-
|
|
6494
|
+
logger$1.error(
|
|
6216
6495
|
`[MCP Tool Debug] Executing unified tool handler for '${toolName}'`
|
|
6217
6496
|
);
|
|
6218
|
-
|
|
6497
|
+
logger$1.error(
|
|
6219
6498
|
`[MCP Tool Debug] Handler args:`,
|
|
6220
6499
|
JSON.stringify(mcpInputArgs, null, 2)
|
|
6221
6500
|
);
|
|
@@ -6245,11 +6524,18 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6245
6524
|
parser: rootParser,
|
|
6246
6525
|
parentArgs: void 0,
|
|
6247
6526
|
isMcp: true,
|
|
6248
|
-
getFlag
|
|
6527
|
+
getFlag,
|
|
6528
|
+
logger: logger$1,
|
|
6529
|
+
// Add logger to context
|
|
6530
|
+
displayHelp: () => {
|
|
6531
|
+
logger$1.error(
|
|
6532
|
+
"Help display is not supported in MCP mode."
|
|
6533
|
+
);
|
|
6534
|
+
}
|
|
6249
6535
|
};
|
|
6250
6536
|
const handlerResult = await toolConfig.handler(handlerContext);
|
|
6251
6537
|
if (process.env["MCP_DEBUG"]) {
|
|
6252
|
-
|
|
6538
|
+
logger$1.error(
|
|
6253
6539
|
`[MCP Tool Debug] Handler result:`,
|
|
6254
6540
|
JSON.stringify(handlerResult, null, 2)
|
|
6255
6541
|
);
|
|
@@ -6261,7 +6547,7 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6261
6547
|
};
|
|
6262
6548
|
} catch (handlerError) {
|
|
6263
6549
|
if (process.env["MCP_DEBUG"]) {
|
|
6264
|
-
|
|
6550
|
+
logger$1.error(
|
|
6265
6551
|
`[MCP Tool Debug] Handler error:`,
|
|
6266
6552
|
handlerError
|
|
6267
6553
|
);
|
|
@@ -6287,10 +6573,10 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6287
6573
|
}
|
|
6288
6574
|
} else {
|
|
6289
6575
|
if (process.env["MCP_DEBUG"]) {
|
|
6290
|
-
|
|
6576
|
+
logger$1.error(
|
|
6291
6577
|
`[MCP Tool Debug] Using CLI-generated tool parsing for '${toolName}'`
|
|
6292
6578
|
);
|
|
6293
|
-
|
|
6579
|
+
logger$1.error(
|
|
6294
6580
|
`[MCP Tool Debug] Parse argv:`,
|
|
6295
6581
|
JSON.stringify(argv, null, 2)
|
|
6296
6582
|
);
|
|
@@ -6315,7 +6601,7 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6315
6601
|
if (outputSchema && typeof outputSchema === "object" && outputSchema !== null && outputSchema._def) {
|
|
6316
6602
|
const zodSchema = outputSchema;
|
|
6317
6603
|
if (process.env["MCP_DEBUG"]) {
|
|
6318
|
-
|
|
6604
|
+
logger$1.error(
|
|
6319
6605
|
`[MCP Debug] Output schema type:`,
|
|
6320
6606
|
zodSchema._def?.typeName || zodSchema._def?.type
|
|
6321
6607
|
);
|
|
@@ -6326,7 +6612,7 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6326
6612
|
const shape = typeof shapeGetter === "function" ? shapeGetter() : shapeGetter;
|
|
6327
6613
|
if (shape && typeof shape === "object") {
|
|
6328
6614
|
if (process.env["MCP_DEBUG"]) {
|
|
6329
|
-
|
|
6615
|
+
logger$1.error(
|
|
6330
6616
|
`[MCP Debug] Schema shape keys:`,
|
|
6331
6617
|
Object.keys(shape)
|
|
6332
6618
|
);
|
|
@@ -6368,14 +6654,14 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6368
6654
|
}
|
|
6369
6655
|
} catch (schemaError) {
|
|
6370
6656
|
if (process.env["MCP_DEBUG"]) {
|
|
6371
|
-
|
|
6657
|
+
logger$1.error(
|
|
6372
6658
|
`[MCP Debug] Error processing output schema for structured error:`,
|
|
6373
6659
|
schemaError
|
|
6374
6660
|
);
|
|
6375
6661
|
}
|
|
6376
6662
|
}
|
|
6377
6663
|
if (process.env["MCP_DEBUG"]) {
|
|
6378
|
-
|
|
6664
|
+
logger$1.error(
|
|
6379
6665
|
`[MCP Debug] Final structured error:`,
|
|
6380
6666
|
JSON.stringify(structuredError, null, 2)
|
|
6381
6667
|
);
|
|
@@ -6486,7 +6772,13 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6486
6772
|
parser: finalParser,
|
|
6487
6773
|
parentArgs: resolvedParentArgs,
|
|
6488
6774
|
isMcp: true,
|
|
6489
|
-
getFlag
|
|
6775
|
+
getFlag,
|
|
6776
|
+
displayHelp: () => {
|
|
6777
|
+
logger$1.error(
|
|
6778
|
+
"Help display is not supported in MCP mode."
|
|
6779
|
+
);
|
|
6780
|
+
},
|
|
6781
|
+
logger: logger$1
|
|
6490
6782
|
};
|
|
6491
6783
|
try {
|
|
6492
6784
|
handlerResponse = await handlerToCall(handlerContext);
|
|
@@ -6496,10 +6788,10 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6496
6788
|
}
|
|
6497
6789
|
}
|
|
6498
6790
|
if (process.env["MCP_DEBUG"]) {
|
|
6499
|
-
|
|
6791
|
+
logger$1.error(
|
|
6500
6792
|
`[MCP Execute] Formatting response for tool '${toolName}'`
|
|
6501
6793
|
);
|
|
6502
|
-
|
|
6794
|
+
logger$1.error(
|
|
6503
6795
|
`[MCP Execute] Handler response:`,
|
|
6504
6796
|
JSON.stringify(handlerResponse, null, 2)
|
|
6505
6797
|
);
|
|
@@ -6515,7 +6807,7 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6515
6807
|
handlerResponse.structuredContent = handlerResponse;
|
|
6516
6808
|
}
|
|
6517
6809
|
if (process.env["MCP_DEBUG"]) {
|
|
6518
|
-
|
|
6810
|
+
logger$1.error(
|
|
6519
6811
|
`[MCP Execute] Returning MCP format response for '${toolName}'`
|
|
6520
6812
|
);
|
|
6521
6813
|
}
|
|
@@ -6531,10 +6823,10 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6531
6823
|
structuredContent: handlerResponse
|
|
6532
6824
|
};
|
|
6533
6825
|
if (process.env["MCP_DEBUG"]) {
|
|
6534
|
-
|
|
6826
|
+
logger$1.error(
|
|
6535
6827
|
`[MCP Execute] Wrapping plain response in MCP format for '${toolName}'`
|
|
6536
6828
|
);
|
|
6537
|
-
|
|
6829
|
+
logger$1.error(
|
|
6538
6830
|
`[MCP Execute] Final MCP response:`,
|
|
6539
6831
|
JSON.stringify(mcpResponse, null, 2)
|
|
6540
6832
|
);
|
|
@@ -6544,10 +6836,10 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6544
6836
|
}
|
|
6545
6837
|
const defaultResponse = handlerResponse || { success: true };
|
|
6546
6838
|
if (process.env["MCP_DEBUG"]) {
|
|
6547
|
-
|
|
6839
|
+
logger$1.error(
|
|
6548
6840
|
`[MCP Execute] Using default response for tool '${toolName}'`
|
|
6549
6841
|
);
|
|
6550
|
-
|
|
6842
|
+
logger$1.error(
|
|
6551
6843
|
`[MCP Execute] Default response:`,
|
|
6552
6844
|
JSON.stringify(defaultResponse, null, 2)
|
|
6553
6845
|
);
|
|
@@ -6563,10 +6855,10 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6563
6855
|
structuredContent: defaultResponse
|
|
6564
6856
|
};
|
|
6565
6857
|
if (process.env["MCP_DEBUG"]) {
|
|
6566
|
-
|
|
6858
|
+
logger$1.error(
|
|
6567
6859
|
`[MCP Execute] Returning structured default response for '${toolName}'`
|
|
6568
6860
|
);
|
|
6569
|
-
|
|
6861
|
+
logger$1.error(
|
|
6570
6862
|
`[MCP Execute] Final response:`,
|
|
6571
6863
|
JSON.stringify(finalResponse, null, 2)
|
|
6572
6864
|
);
|
|
@@ -6574,14 +6866,14 @@ function generateMcpToolsFromArgParser(rootParser, options) {
|
|
|
6574
6866
|
return finalResponse;
|
|
6575
6867
|
}
|
|
6576
6868
|
if (process.env["MCP_DEBUG"]) {
|
|
6577
|
-
|
|
6869
|
+
logger$1.error(
|
|
6578
6870
|
`[MCP Execute] Returning success response for '${toolName}'`
|
|
6579
6871
|
);
|
|
6580
6872
|
}
|
|
6581
6873
|
return createMcpSuccessResponse(defaultResponse);
|
|
6582
6874
|
} catch (e) {
|
|
6583
6875
|
if (process.env["MCP_DEBUG"]) {
|
|
6584
|
-
|
|
6876
|
+
logger$1.error(
|
|
6585
6877
|
`[MCP Execute] Exception caught in tool '${toolName}':`,
|
|
6586
6878
|
e
|
|
6587
6879
|
);
|
|
@@ -6695,41 +6987,42 @@ function compareVersions(v1, v2) {
|
|
|
6695
6987
|
if (v1 === v2) return 0;
|
|
6696
6988
|
return v1 < v2 ? -1 : 1;
|
|
6697
6989
|
}
|
|
6990
|
+
const logger = simpleMcpLogger.createMcpLogger("Zod Compatibility");
|
|
6698
6991
|
function debugSchemaStructure(schema, label = "Schema") {
|
|
6699
6992
|
if (process.env["MCP_DEBUG"]) {
|
|
6700
|
-
|
|
6701
|
-
|
|
6702
|
-
|
|
6703
|
-
|
|
6704
|
-
|
|
6705
|
-
|
|
6706
|
-
|
|
6707
|
-
|
|
6708
|
-
|
|
6993
|
+
logger.error(`[Zod Compatibility Debug] ${label} structure:`);
|
|
6994
|
+
logger.error(` - Type: ${typeof schema}`);
|
|
6995
|
+
logger.error(` - Constructor: ${schema?.constructor?.name}`);
|
|
6996
|
+
logger.error(` - Has shape: ${!!schema?.shape}`);
|
|
6997
|
+
logger.error(` - Has _def: ${!!schema?._def}`);
|
|
6998
|
+
logger.error(` - _def.typeName: ${schema?._def?.typeName}`);
|
|
6999
|
+
logger.error(` - _def.type: ${schema?._def?.type}`);
|
|
7000
|
+
logger.error(` - Has parse: ${typeof schema?.parse}`);
|
|
7001
|
+
logger.error(` - Has safeParse: ${typeof schema?.safeParse}`);
|
|
6709
7002
|
if (schema?.shape) {
|
|
6710
|
-
|
|
7003
|
+
logger.error(` - Shape keys: ${Object.keys(schema.shape)}`);
|
|
6711
7004
|
}
|
|
6712
7005
|
}
|
|
6713
7006
|
}
|
|
6714
7007
|
function validateMcpSchemaCompatibility(schema) {
|
|
6715
7008
|
try {
|
|
6716
7009
|
if (typeof schema?.parse !== "function") {
|
|
6717
|
-
|
|
7010
|
+
logger.warn("[Zod Compatibility] Schema missing parse method");
|
|
6718
7011
|
return false;
|
|
6719
7012
|
}
|
|
6720
7013
|
if (typeof schema?.safeParse !== "function") {
|
|
6721
|
-
|
|
7014
|
+
logger.warn("[Zod Compatibility] Schema missing safeParse method");
|
|
6722
7015
|
return false;
|
|
6723
7016
|
}
|
|
6724
7017
|
if ((schema?._def?.typeName === "ZodObject" || schema?._def?.type === "object") && !schema?.shape) {
|
|
6725
|
-
|
|
7018
|
+
logger.warn(
|
|
6726
7019
|
"[Zod Compatibility] ZodObject schema missing shape property"
|
|
6727
7020
|
);
|
|
6728
7021
|
return false;
|
|
6729
7022
|
}
|
|
6730
7023
|
return true;
|
|
6731
7024
|
} catch (error) {
|
|
6732
|
-
|
|
7025
|
+
logger.error(
|
|
6733
7026
|
"[Zod Compatibility] Error validating schema compatibility:",
|
|
6734
7027
|
error
|
|
6735
7028
|
);
|
|
@@ -6870,12 +7163,9 @@ class ArgParser extends ArgParserBase {
|
|
|
6870
7163
|
}
|
|
6871
7164
|
const sanitizedName = sanitizeMcpToolName(toolConfig.name);
|
|
6872
7165
|
if (sanitizedName !== toolConfig.name) {
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
`[ArgParser] Tool name '${toolConfig.name}' was sanitized to '${sanitizedName}' for MCP compatibility`
|
|
6877
|
-
);
|
|
6878
|
-
}
|
|
7166
|
+
console.warn(
|
|
7167
|
+
`[ArgParser] Tool name '${toolConfig.name}' was sanitized to '${sanitizedName}' for MCP compatibility`
|
|
7168
|
+
);
|
|
6879
7169
|
}
|
|
6880
7170
|
if (this._tools.has(sanitizedName)) {
|
|
6881
7171
|
throw new Error(`Tool with name '${sanitizedName}' already exists`);
|
|
@@ -6918,30 +7208,14 @@ class ArgParser extends ArgParserBase {
|
|
|
6918
7208
|
* @returns This ArgParser instance for chaining
|
|
6919
7209
|
*/
|
|
6920
7210
|
addMcpTool(toolConfig) {
|
|
6921
|
-
|
|
6922
|
-
if (typeof process !== "undefined" && process.stderr) {
|
|
6923
|
-
process.stderr.write(`[DEPRECATED] addMcpTool() is deprecated and will be removed in v2.0.
|
|
6924
|
-
Please use addTool() instead for a unified CLI/MCP experience.
|
|
6925
|
-
Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-MIGRATION.md
|
|
6926
|
-
`);
|
|
6927
|
-
} else {
|
|
6928
|
-
console.warn(`[DEPRECATED] addMcpTool() is deprecated and will be removed in v2.0.
|
|
7211
|
+
console.warn(`[DEPRECATED] addMcpTool() is deprecated and will be removed in v2.0.
|
|
6929
7212
|
Please use addTool() instead for a unified CLI/MCP experience.
|
|
6930
7213
|
Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-MIGRATION.md`);
|
|
6931
|
-
}
|
|
6932
|
-
} catch {
|
|
6933
|
-
console.warn(`[DEPRECATED] addMcpTool() is deprecated and will be removed in v2.0.
|
|
6934
|
-
Please use addTool() instead for a unified CLI/MCP experience.
|
|
6935
|
-
Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-MIGRATION.md`);
|
|
6936
|
-
}
|
|
6937
7214
|
const sanitizedName = sanitizeMcpToolName(toolConfig.name);
|
|
6938
7215
|
if (sanitizedName !== toolConfig.name) {
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
|
|
6942
|
-
`[ArgParser] Tool name '${toolConfig.name}' was sanitized to '${sanitizedName}' for MCP compatibility`
|
|
6943
|
-
);
|
|
6944
|
-
}
|
|
7216
|
+
console.warn(
|
|
7217
|
+
`[ArgParser] Tool name '${toolConfig.name}' was sanitized to '${sanitizedName}' for MCP compatibility`
|
|
7218
|
+
);
|
|
6945
7219
|
}
|
|
6946
7220
|
if (this._mcpTools.has(sanitizedName)) {
|
|
6947
7221
|
throw new Error(`MCP tool with name '${sanitizedName}' already exists`);
|
|
@@ -7104,18 +7378,18 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7104
7378
|
outputSchema = mergedOptions.outputSchemaMap[toolConfig.name];
|
|
7105
7379
|
} else if (toolConfig.outputSchema) {
|
|
7106
7380
|
if (process.env["MCP_DEBUG"]) {
|
|
7107
|
-
|
|
7381
|
+
this.logger.error(
|
|
7108
7382
|
`[MCP Debug] Tool '${toolConfig.name}' has outputSchema:`,
|
|
7109
7383
|
typeof toolConfig.outputSchema
|
|
7110
7384
|
);
|
|
7111
|
-
|
|
7385
|
+
this.logger.error(
|
|
7112
7386
|
`[MCP Debug] outputSchema has _def:`,
|
|
7113
7387
|
!!(toolConfig.outputSchema && typeof toolConfig.outputSchema === "object" && "_def" in toolConfig.outputSchema)
|
|
7114
7388
|
);
|
|
7115
7389
|
}
|
|
7116
7390
|
outputSchema = createOutputSchema(toolConfig.outputSchema);
|
|
7117
7391
|
if (process.env["MCP_DEBUG"]) {
|
|
7118
|
-
|
|
7392
|
+
this.logger.error(
|
|
7119
7393
|
`[MCP Debug] Created output schema for '${toolConfig.name}':`,
|
|
7120
7394
|
!!outputSchema
|
|
7121
7395
|
);
|
|
@@ -7133,7 +7407,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7133
7407
|
}
|
|
7134
7408
|
if (outputSchema && !this.supportsOutputSchemas()) {
|
|
7135
7409
|
if (process.env["MCP_DEBUG"]) {
|
|
7136
|
-
|
|
7410
|
+
this.logger.error(
|
|
7137
7411
|
`[MCP Debug] Output schema for '${toolConfig.name}' removed due to MCP version ${this._mcpProtocolVersion} not supporting output schemas`
|
|
7138
7412
|
);
|
|
7139
7413
|
}
|
|
@@ -7171,13 +7445,17 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7171
7445
|
parentArgs: {},
|
|
7172
7446
|
commandChain: [toolConfig.name],
|
|
7173
7447
|
parser: this,
|
|
7174
|
-
isMcp: true
|
|
7448
|
+
isMcp: true,
|
|
7449
|
+
logger: this.logger,
|
|
7450
|
+
displayHelp: () => {
|
|
7451
|
+
this.logger.error("Help display is not supported in MCP mode.");
|
|
7452
|
+
}
|
|
7175
7453
|
};
|
|
7176
7454
|
const startTime = Date.now();
|
|
7177
7455
|
const result = await toolConfig.handler(context);
|
|
7178
7456
|
const executionTime = Date.now() - startTime;
|
|
7179
7457
|
if (process.env["MCP_DEBUG"]) {
|
|
7180
|
-
|
|
7458
|
+
this.logger.error(
|
|
7181
7459
|
`[MCP Tool] '${toolConfig.name}' executed successfully in ${executionTime}ms`
|
|
7182
7460
|
);
|
|
7183
7461
|
}
|
|
@@ -7204,9 +7482,9 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7204
7482
|
} catch (error) {
|
|
7205
7483
|
const errorMessage = `Tool '${toolConfig.name}' execution failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
7206
7484
|
if (process.env["MCP_DEBUG"]) {
|
|
7207
|
-
|
|
7485
|
+
this.logger.error(`[MCP Tool Error] ${errorMessage}`);
|
|
7208
7486
|
if (error instanceof Error && error.stack) {
|
|
7209
|
-
|
|
7487
|
+
this.logger.error(`[MCP Tool Stack] ${error.stack}`);
|
|
7210
7488
|
}
|
|
7211
7489
|
}
|
|
7212
7490
|
return createMcpErrorResponse(errorMessage);
|
|
@@ -7229,7 +7507,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7229
7507
|
const result = await toolConfig.handler(args);
|
|
7230
7508
|
const executionTime = Date.now() - startTime;
|
|
7231
7509
|
if (process.env["MCP_DEBUG"]) {
|
|
7232
|
-
|
|
7510
|
+
this.logger.error(
|
|
7233
7511
|
`[MCP Tool] '${toolConfig.name}' (legacy) executed successfully in ${executionTime}ms`
|
|
7234
7512
|
);
|
|
7235
7513
|
}
|
|
@@ -7256,7 +7534,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7256
7534
|
} catch (error) {
|
|
7257
7535
|
const errorMessage = `Tool '${toolConfig.name}' execution failed: ${error instanceof Error ? error.message : String(error)}`;
|
|
7258
7536
|
if (process.env["MCP_DEBUG"]) {
|
|
7259
|
-
|
|
7537
|
+
this.logger.error(`[MCP Tool Error] ${errorMessage}`);
|
|
7260
7538
|
}
|
|
7261
7539
|
return createMcpErrorResponse(errorMessage);
|
|
7262
7540
|
}
|
|
@@ -7286,7 +7564,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7286
7564
|
*/
|
|
7287
7565
|
async createMcpServer(serverInfo, toolOptions, logPath) {
|
|
7288
7566
|
const loggerConfig = this.#_resolveLoggerConfig(logPath);
|
|
7289
|
-
const
|
|
7567
|
+
const logger2 = typeof loggerConfig === "string" ? simpleMcpLogger.createMcpLogger("MCP Server Creation", loggerConfig) : simpleMcpLogger.createMcpLogger(
|
|
7290
7568
|
loggerConfig.prefix || "MCP Server Creation",
|
|
7291
7569
|
loggerConfig.logToFile
|
|
7292
7570
|
);
|
|
@@ -7297,11 +7575,11 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7297
7575
|
"No MCP server configuration found. Use withMcp() to configure server info or provide serverInfo parameter."
|
|
7298
7576
|
);
|
|
7299
7577
|
}
|
|
7300
|
-
|
|
7578
|
+
logger2.mcpError(
|
|
7301
7579
|
`Creating MCP server: ${effectiveServerInfo.name} v${effectiveServerInfo.version}`
|
|
7302
7580
|
);
|
|
7303
7581
|
const { McpServer: McpServer2, ResourceTemplate: ResourceTemplate2 } = await Promise.resolve().then(() => mcp);
|
|
7304
|
-
|
|
7582
|
+
logger2.mcpError(
|
|
7305
7583
|
"Successfully imported McpServer and ResourceTemplate from SDK"
|
|
7306
7584
|
);
|
|
7307
7585
|
const server = new McpServer2({
|
|
@@ -7310,13 +7588,13 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7310
7588
|
name: effectiveServerInfo.name,
|
|
7311
7589
|
description: effectiveServerInfo.description
|
|
7312
7590
|
});
|
|
7313
|
-
|
|
7591
|
+
logger2.mcpError("Successfully created McpServer instance");
|
|
7314
7592
|
const isInMcpServeMode = process.argv.includes("--s-mcp-serve");
|
|
7315
7593
|
if (this._mcpServerConfig?.lifecycle && !isInMcpServeMode) {
|
|
7316
7594
|
const { McpLifecycleManager: McpLifecycleManager2 } = await Promise.resolve().then(() => mcpLifecycle);
|
|
7317
7595
|
const lifecycleManager = new McpLifecycleManager2(
|
|
7318
7596
|
this._mcpServerConfig.lifecycle,
|
|
7319
|
-
|
|
7597
|
+
logger2,
|
|
7320
7598
|
effectiveServerInfo,
|
|
7321
7599
|
this
|
|
7322
7600
|
);
|
|
@@ -7330,17 +7608,17 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7330
7608
|
});
|
|
7331
7609
|
const parsedArgs = parsedResult?.args || parsedResult || {};
|
|
7332
7610
|
lifecycleManager.setParsedArgs(parsedArgs);
|
|
7333
|
-
|
|
7611
|
+
logger2.mcpError(
|
|
7334
7612
|
`Lifecycle manager initialized with parsed args: ${Object.keys(parsedArgs).join(", ")}`
|
|
7335
7613
|
);
|
|
7336
7614
|
} catch (parseError) {
|
|
7337
|
-
|
|
7615
|
+
logger2.mcpError(
|
|
7338
7616
|
`Warning: Could not parse arguments for lifecycle manager: ${parseError instanceof Error ? parseError.message : String(parseError)}`
|
|
7339
7617
|
);
|
|
7340
7618
|
}
|
|
7341
7619
|
const originalConnect = server.connect.bind(server);
|
|
7342
7620
|
server.connect = async (transport) => {
|
|
7343
|
-
|
|
7621
|
+
logger2.mcpError("MCP server connecting with lifecycle events...");
|
|
7344
7622
|
const result = await originalConnect(transport);
|
|
7345
7623
|
try {
|
|
7346
7624
|
await lifecycleManager.handleInitialize(
|
|
@@ -7355,38 +7633,38 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7355
7633
|
try {
|
|
7356
7634
|
await lifecycleManager.handleInitialized();
|
|
7357
7635
|
} catch (error) {
|
|
7358
|
-
|
|
7636
|
+
logger2.mcpError(
|
|
7359
7637
|
`Lifecycle onInitialized error: ${error instanceof Error ? error.message : String(error)}`
|
|
7360
7638
|
);
|
|
7361
7639
|
}
|
|
7362
7640
|
}, 100);
|
|
7363
7641
|
} catch (error) {
|
|
7364
|
-
|
|
7642
|
+
logger2.mcpError(
|
|
7365
7643
|
`Lifecycle onInitialize error: ${error instanceof Error ? error.message : String(error)}`
|
|
7366
7644
|
);
|
|
7367
7645
|
}
|
|
7368
7646
|
return result;
|
|
7369
7647
|
};
|
|
7370
7648
|
server._lifecycleManager = lifecycleManager;
|
|
7371
|
-
|
|
7649
|
+
logger2.mcpError("Successfully set up MCP lifecycle manager");
|
|
7372
7650
|
}
|
|
7373
|
-
|
|
7651
|
+
logger2.mcpError(
|
|
7374
7652
|
"MCP server will register actual resources and prompts for full capability support"
|
|
7375
7653
|
);
|
|
7376
|
-
|
|
7654
|
+
logger2.mcpError("Generating MCP tools from ArgParser");
|
|
7377
7655
|
const tools = this.toMcpTools(toolOptions);
|
|
7378
|
-
|
|
7656
|
+
logger2.mcpError(`Generated ${tools.length} MCP tools`);
|
|
7379
7657
|
const uniqueTools = tools.reduce((acc, tool) => {
|
|
7380
7658
|
if (!acc.find((t) => t.name === tool.name)) {
|
|
7381
7659
|
acc.push(tool);
|
|
7382
7660
|
}
|
|
7383
7661
|
return acc;
|
|
7384
7662
|
}, []);
|
|
7385
|
-
|
|
7663
|
+
logger2.mcpError(
|
|
7386
7664
|
`After deduplication: ${uniqueTools.length} unique tools`
|
|
7387
7665
|
);
|
|
7388
7666
|
uniqueTools.forEach((tool) => {
|
|
7389
|
-
|
|
7667
|
+
logger2.mcpError(`Registering tool: ${tool.name}`);
|
|
7390
7668
|
let zodSchema;
|
|
7391
7669
|
const toolFromUnified = Array.from(this._tools.values()).find(
|
|
7392
7670
|
(t) => t.name === tool.name
|
|
@@ -7404,58 +7682,58 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7404
7682
|
let mcpCompatibleSchema;
|
|
7405
7683
|
try {
|
|
7406
7684
|
if (process.env["MCP_DEBUG"]) {
|
|
7407
|
-
|
|
7408
|
-
|
|
7685
|
+
this.logger.error(`[MCP Debug] Preparing schema for tool ${tool.name}`);
|
|
7686
|
+
this.logger.error(`[MCP Debug] Input zodSchema:`, zodSchema);
|
|
7409
7687
|
}
|
|
7410
7688
|
mcpCompatibleSchema = zodSchema;
|
|
7411
7689
|
if (process.env["MCP_DEBUG"]) {
|
|
7412
|
-
|
|
7690
|
+
this.logger.error(
|
|
7413
7691
|
`[MCP Debug] Successfully prepared schema for tool ${tool.name}`
|
|
7414
7692
|
);
|
|
7415
7693
|
}
|
|
7416
7694
|
} catch (schemaError) {
|
|
7417
|
-
|
|
7695
|
+
this.logger.error(
|
|
7418
7696
|
`[MCP Debug] Error preparing schema for tool ${tool.name}:`,
|
|
7419
7697
|
schemaError
|
|
7420
7698
|
);
|
|
7421
7699
|
throw schemaError;
|
|
7422
7700
|
}
|
|
7423
7701
|
if (process.env["MCP_DEBUG"]) {
|
|
7424
|
-
|
|
7702
|
+
this.logger.error(
|
|
7425
7703
|
`[MCP Debug] Prepared mcpCompatibleSchema for tool ${tool.name}:`,
|
|
7426
7704
|
JSON.stringify(mcpCompatibleSchema, null, 2)
|
|
7427
7705
|
);
|
|
7428
|
-
|
|
7706
|
+
this.logger.error(
|
|
7429
7707
|
`[MCP Debug] Schema properties:`,
|
|
7430
7708
|
Object.keys(mcpCompatibleSchema || {})
|
|
7431
7709
|
);
|
|
7432
|
-
|
|
7710
|
+
this.logger.error(
|
|
7433
7711
|
`[MCP Debug] Schema def:`,
|
|
7434
7712
|
mcpCompatibleSchema?.def
|
|
7435
7713
|
);
|
|
7436
|
-
|
|
7714
|
+
this.logger.error(
|
|
7437
7715
|
`[MCP Debug] Schema shape:`,
|
|
7438
7716
|
mcpCompatibleSchema?.shape
|
|
7439
7717
|
);
|
|
7440
|
-
|
|
7718
|
+
this.logger.error(
|
|
7441
7719
|
`[MCP Debug] Schema parse function:`,
|
|
7442
7720
|
typeof mcpCompatibleSchema?.parse
|
|
7443
7721
|
);
|
|
7444
7722
|
}
|
|
7445
7723
|
if (process.env["MCP_DEBUG"]) {
|
|
7446
|
-
|
|
7724
|
+
this.logger.error(
|
|
7447
7725
|
`[MCP Debug] About to prepare schema for tool ${tool.name}`
|
|
7448
7726
|
);
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7727
|
+
this.logger.error(`[MCP Debug] zodSchema type:`, typeof zodSchema);
|
|
7728
|
+
this.logger.error(`[MCP Debug] zodSchema:`, zodSchema);
|
|
7729
|
+
this.logger.error(
|
|
7452
7730
|
`[MCP Debug] zodSchema constructor:`,
|
|
7453
7731
|
zodSchema?.constructor?.name
|
|
7454
7732
|
);
|
|
7455
7733
|
}
|
|
7456
7734
|
debugSchemaStructure(mcpCompatibleSchema, `Tool ${tool.name} schema`);
|
|
7457
7735
|
if (!validateMcpSchemaCompatibility(mcpCompatibleSchema)) {
|
|
7458
|
-
|
|
7736
|
+
logger2.mcpError(
|
|
7459
7737
|
`Warning: Schema for tool ${tool.name} may not be fully compatible with MCP SDK`
|
|
7460
7738
|
);
|
|
7461
7739
|
}
|
|
@@ -7467,35 +7745,35 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7467
7745
|
// Use Zod v3 compatible schema for MCP SDK
|
|
7468
7746
|
};
|
|
7469
7747
|
if (process.env["MCP_DEBUG"]) {
|
|
7470
|
-
|
|
7748
|
+
this.logger.error(
|
|
7471
7749
|
`[MCP Debug] Final toolConfig for ${tool.name}:`,
|
|
7472
7750
|
JSON.stringify(toolConfig, null, 2)
|
|
7473
7751
|
);
|
|
7474
|
-
|
|
7752
|
+
this.logger.error(
|
|
7475
7753
|
`[MCP Debug] toolConfig.inputSchema type:`,
|
|
7476
7754
|
typeof toolConfig.inputSchema
|
|
7477
7755
|
);
|
|
7478
|
-
|
|
7756
|
+
this.logger.error(
|
|
7479
7757
|
`[MCP Debug] toolConfig.inputSchema constructor:`,
|
|
7480
7758
|
toolConfig.inputSchema?.constructor?.name
|
|
7481
7759
|
);
|
|
7482
|
-
|
|
7760
|
+
this.logger.error(
|
|
7483
7761
|
`[MCP Debug] toolConfig.inputSchema._def:`,
|
|
7484
7762
|
toolConfig.inputSchema?._def
|
|
7485
7763
|
);
|
|
7486
|
-
|
|
7764
|
+
this.logger.error(
|
|
7487
7765
|
`[MCP Debug] toolConfig.inputSchema.shape:`,
|
|
7488
7766
|
toolConfig.inputSchema?.shape
|
|
7489
7767
|
);
|
|
7490
|
-
|
|
7768
|
+
this.logger.error(
|
|
7491
7769
|
`[MCP Debug] toolConfig.inputSchema._zod:`,
|
|
7492
7770
|
toolConfig.inputSchema?._zod
|
|
7493
7771
|
);
|
|
7494
|
-
|
|
7772
|
+
this.logger.error(
|
|
7495
7773
|
`[MCP Debug] Schema keys:`,
|
|
7496
7774
|
Object.keys(mcpCompatibleSchema || {})
|
|
7497
7775
|
);
|
|
7498
|
-
|
|
7776
|
+
this.logger.error(`[MCP Debug] About to call server.registerTool with:`, {
|
|
7499
7777
|
name: tool.name,
|
|
7500
7778
|
description: tool.description,
|
|
7501
7779
|
inputSchema: mcpCompatibleSchema
|
|
@@ -7505,28 +7783,28 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7505
7783
|
const convertedOutputSchema = createOutputSchema(tool.outputSchema);
|
|
7506
7784
|
toolConfig.outputSchema = convertedOutputSchema;
|
|
7507
7785
|
if (process.env["MCP_DEBUG"]) {
|
|
7508
|
-
|
|
7786
|
+
this.logger.error(
|
|
7509
7787
|
`[MCP Debug] Including outputSchema for tool '${tool.name}':`,
|
|
7510
7788
|
typeof tool.outputSchema
|
|
7511
7789
|
);
|
|
7512
|
-
|
|
7790
|
+
this.logger.error(
|
|
7513
7791
|
`[MCP Debug] Converted outputSchema constructor:`,
|
|
7514
7792
|
convertedOutputSchema?.constructor?.name
|
|
7515
7793
|
);
|
|
7516
|
-
|
|
7794
|
+
this.logger.error(
|
|
7517
7795
|
`[MCP Debug] supportsOutputSchemas():`,
|
|
7518
7796
|
this.supportsOutputSchemas()
|
|
7519
7797
|
);
|
|
7520
7798
|
}
|
|
7521
7799
|
} else if (process.env["MCP_DEBUG"]) {
|
|
7522
|
-
|
|
7800
|
+
this.logger.error(
|
|
7523
7801
|
`[MCP Debug] NOT including outputSchema for tool '${tool.name}':`,
|
|
7524
7802
|
`hasOutputSchema=${!!tool.outputSchema}, supportsOutputSchemas=${this.supportsOutputSchemas()}`
|
|
7525
7803
|
);
|
|
7526
7804
|
}
|
|
7527
7805
|
const simpleExecute = async (args) => {
|
|
7528
7806
|
if (process.env["MCP_DEBUG"]) {
|
|
7529
|
-
|
|
7807
|
+
this.logger.error(
|
|
7530
7808
|
`[MCP Simple Execute] 🎯 TOOL CALLED: '${tool.name}' with args:`,
|
|
7531
7809
|
JSON.stringify(args, null, 2)
|
|
7532
7810
|
);
|
|
@@ -7534,7 +7812,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7534
7812
|
try {
|
|
7535
7813
|
const result = await tool.execute(args);
|
|
7536
7814
|
if (process.env["MCP_DEBUG"]) {
|
|
7537
|
-
|
|
7815
|
+
this.logger.error(
|
|
7538
7816
|
`[MCP Simple Execute] Tool '${tool.name}' returned:`,
|
|
7539
7817
|
JSON.stringify(result, null, 2)
|
|
7540
7818
|
);
|
|
@@ -7553,7 +7831,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7553
7831
|
} catch (error) {
|
|
7554
7832
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
7555
7833
|
if (process.env["MCP_DEBUG"]) {
|
|
7556
|
-
|
|
7834
|
+
this.logger.error(
|
|
7557
7835
|
`[MCP Simple Execute] Tool '${tool.name}' error:`,
|
|
7558
7836
|
errorMessage
|
|
7559
7837
|
);
|
|
@@ -7571,9 +7849,9 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7571
7849
|
};
|
|
7572
7850
|
server.registerTool(tool.name, toolConfig, simpleExecute);
|
|
7573
7851
|
});
|
|
7574
|
-
|
|
7852
|
+
logger2.mcpError("Successfully registered all tools with MCP server");
|
|
7575
7853
|
const resources = this.getMcpResources();
|
|
7576
|
-
|
|
7854
|
+
logger2.mcpError(`Registering ${resources.length} MCP resources`);
|
|
7577
7855
|
resources.forEach((resource) => {
|
|
7578
7856
|
try {
|
|
7579
7857
|
const resourceConfig = {
|
|
@@ -7610,7 +7888,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7610
7888
|
})
|
|
7611
7889
|
};
|
|
7612
7890
|
} catch (error) {
|
|
7613
|
-
|
|
7891
|
+
logger2.mcpError(
|
|
7614
7892
|
`Resource template handler error for ${resource.name}: ${error instanceof Error ? error.message : String(error)}`
|
|
7615
7893
|
);
|
|
7616
7894
|
throw error;
|
|
@@ -7647,7 +7925,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7647
7925
|
})
|
|
7648
7926
|
};
|
|
7649
7927
|
} catch (error) {
|
|
7650
|
-
|
|
7928
|
+
logger2.mcpError(
|
|
7651
7929
|
`Resource handler error for ${resource.name}: ${error instanceof Error ? error.message : String(error)}`
|
|
7652
7930
|
);
|
|
7653
7931
|
throw error;
|
|
@@ -7660,34 +7938,34 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7660
7938
|
resourceHandler
|
|
7661
7939
|
);
|
|
7662
7940
|
}
|
|
7663
|
-
|
|
7941
|
+
logger2.mcpError(`Successfully registered resource: ${resource.name}`);
|
|
7664
7942
|
} catch (error) {
|
|
7665
|
-
|
|
7943
|
+
logger2.mcpError(
|
|
7666
7944
|
`Failed to register resource ${resource.name}: ${error instanceof Error ? error.message : String(error)}`
|
|
7667
7945
|
);
|
|
7668
7946
|
}
|
|
7669
7947
|
});
|
|
7670
|
-
|
|
7948
|
+
logger2.mcpError("Successfully registered all resources with MCP server");
|
|
7671
7949
|
const prompts = this.getMcpPrompts();
|
|
7672
|
-
|
|
7950
|
+
logger2.mcpError(`Registering ${prompts.length} MCP prompts`);
|
|
7673
7951
|
prompts.forEach((prompt) => {
|
|
7674
7952
|
try {
|
|
7675
7953
|
let mcpCompatibleSchema;
|
|
7676
7954
|
try {
|
|
7677
7955
|
if (process.env["MCP_DEBUG"]) {
|
|
7678
|
-
|
|
7956
|
+
this.logger.error(
|
|
7679
7957
|
`[MCP Debug] Preparing schema for prompt ${prompt.name}`
|
|
7680
7958
|
);
|
|
7681
|
-
|
|
7959
|
+
this.logger.error(`[MCP Debug] Input argsSchema:`, prompt.argsSchema);
|
|
7682
7960
|
}
|
|
7683
7961
|
mcpCompatibleSchema = prompt.argsSchema;
|
|
7684
7962
|
if (process.env["MCP_DEBUG"]) {
|
|
7685
|
-
|
|
7963
|
+
this.logger.error(
|
|
7686
7964
|
`[MCP Debug] Successfully prepared schema for prompt ${prompt.name}`
|
|
7687
7965
|
);
|
|
7688
7966
|
}
|
|
7689
7967
|
} catch (schemaError) {
|
|
7690
|
-
|
|
7968
|
+
this.logger.error(
|
|
7691
7969
|
`[MCP Debug] Error preparing schema for prompt ${prompt.name}:`,
|
|
7692
7970
|
schemaError
|
|
7693
7971
|
);
|
|
@@ -7713,14 +7991,14 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7713
7991
|
const validatedArgs = prompt.argsSchema.parse(args);
|
|
7714
7992
|
const result = await prompt.handler(validatedArgs);
|
|
7715
7993
|
if (process.env["MCP_DEBUG"]) {
|
|
7716
|
-
|
|
7994
|
+
this.logger.error(
|
|
7717
7995
|
`[MCP Debug] Prompt '${prompt.name}' executed successfully`
|
|
7718
7996
|
);
|
|
7719
7997
|
}
|
|
7720
7998
|
return result;
|
|
7721
7999
|
} catch (error) {
|
|
7722
8000
|
if (process.env["MCP_DEBUG"]) {
|
|
7723
|
-
|
|
8001
|
+
this.logger.error(
|
|
7724
8002
|
`[MCP Debug] Prompt '${prompt.name}' execution error:`,
|
|
7725
8003
|
error
|
|
7726
8004
|
);
|
|
@@ -7733,26 +8011,26 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7733
8011
|
promptConfig,
|
|
7734
8012
|
promptHandler
|
|
7735
8013
|
);
|
|
7736
|
-
|
|
8014
|
+
logger2.mcpError(`Successfully registered prompt: ${prompt.name}`);
|
|
7737
8015
|
} catch (error) {
|
|
7738
|
-
|
|
8016
|
+
logger2.mcpError(
|
|
7739
8017
|
`Failed to register prompt ${prompt.name}: ${error instanceof Error ? error.message : String(error)}`
|
|
7740
8018
|
);
|
|
7741
8019
|
}
|
|
7742
8020
|
});
|
|
7743
|
-
|
|
8021
|
+
logger2.mcpError("Successfully registered all prompts with MCP server");
|
|
7744
8022
|
this.setupMcpChangeNotifications(server);
|
|
7745
|
-
|
|
8023
|
+
logger2.mcpError("Successfully set up MCP change notifications");
|
|
7746
8024
|
if (server._lifecycleManager) {
|
|
7747
8025
|
const originalClose = server.close?.bind(server);
|
|
7748
8026
|
server.close = async () => {
|
|
7749
|
-
|
|
8027
|
+
logger2.mcpError("MCP server shutdown initiated");
|
|
7750
8028
|
try {
|
|
7751
8029
|
await server._lifecycleManager.handleShutdown(
|
|
7752
8030
|
"server_shutdown"
|
|
7753
8031
|
);
|
|
7754
8032
|
} catch (error) {
|
|
7755
|
-
|
|
8033
|
+
logger2.mcpError(
|
|
7756
8034
|
`Error during lifecycle shutdown: ${error instanceof Error ? error.message : String(error)}`
|
|
7757
8035
|
);
|
|
7758
8036
|
}
|
|
@@ -7763,11 +8041,11 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7763
8041
|
}
|
|
7764
8042
|
return server;
|
|
7765
8043
|
} catch (error) {
|
|
7766
|
-
|
|
8044
|
+
logger2.mcpError(
|
|
7767
8045
|
`Error creating MCP server: ${error instanceof Error ? error.message : String(error)}`
|
|
7768
8046
|
);
|
|
7769
8047
|
if (error instanceof Error && error.stack) {
|
|
7770
|
-
|
|
8048
|
+
logger2.mcpError(`Stack trace: ${error.stack}`);
|
|
7771
8049
|
}
|
|
7772
8050
|
throw error;
|
|
7773
8051
|
}
|
|
@@ -7778,8 +8056,8 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7778
8056
|
*/
|
|
7779
8057
|
setupMcpChangeNotifications(_server) {
|
|
7780
8058
|
this.onMcpChange((event) => {
|
|
7781
|
-
const
|
|
7782
|
-
|
|
8059
|
+
const logger2 = simpleMcpLogger.createMcpLogger("MCP Change Notifications");
|
|
8060
|
+
logger2.mcpError(
|
|
7783
8061
|
`MCP ${event.type} ${event.action}: ${event.entityName || "unknown"}`
|
|
7784
8062
|
);
|
|
7785
8063
|
});
|
|
@@ -7844,20 +8122,20 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7844
8122
|
*/
|
|
7845
8123
|
async #_startSingleTransport(server, serverInfo, transportConfig, logPath) {
|
|
7846
8124
|
const resolvedLogPath = resolveLogPath(logPath || "./logs/mcp.log");
|
|
7847
|
-
const
|
|
8125
|
+
const logger2 = simpleMcpLogger.createMcpLogger("MCP Transport", resolvedLogPath);
|
|
7848
8126
|
try {
|
|
7849
|
-
|
|
8127
|
+
logger2.mcpError(
|
|
7850
8128
|
`Starting ${transportConfig.type} transport for server: ${serverInfo.name}`
|
|
7851
8129
|
);
|
|
7852
8130
|
switch (transportConfig.type) {
|
|
7853
8131
|
case "stdio": {
|
|
7854
|
-
|
|
8132
|
+
logger2.mcpError("Importing StdioServerTransport from SDK");
|
|
7855
8133
|
const { StdioServerTransport: StdioServerTransport2 } = await Promise.resolve().then(() => stdio);
|
|
7856
|
-
|
|
8134
|
+
logger2.mcpError("Creating StdioServerTransport instance");
|
|
7857
8135
|
const transport = new StdioServerTransport2();
|
|
7858
|
-
|
|
8136
|
+
logger2.mcpError("Connecting server to stdio transport");
|
|
7859
8137
|
await server.connect(transport);
|
|
7860
|
-
|
|
8138
|
+
logger2.mcpError("Successfully connected to stdio transport");
|
|
7861
8139
|
break;
|
|
7862
8140
|
}
|
|
7863
8141
|
case "sse": {
|
|
@@ -7873,7 +8151,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
7873
8151
|
});
|
|
7874
8152
|
await new Promise((resolve) => {
|
|
7875
8153
|
app.listen(port, transportConfig.host || "localhost", () => {
|
|
7876
|
-
|
|
8154
|
+
this.logger.error(
|
|
7877
8155
|
`[${serverInfo.name}] MCP Server listening on http://${transportConfig.host || "localhost"}:${port}${path2} (SSE)`
|
|
7878
8156
|
);
|
|
7879
8157
|
resolve();
|
|
@@ -8055,20 +8333,20 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
8055
8333
|
break;
|
|
8056
8334
|
}
|
|
8057
8335
|
default:
|
|
8058
|
-
|
|
8336
|
+
logger2.mcpError(
|
|
8059
8337
|
`Unsupported transport type: ${transportConfig.type}`
|
|
8060
8338
|
);
|
|
8061
8339
|
throw new Error(
|
|
8062
8340
|
`Unsupported transport type: ${transportConfig.type}`
|
|
8063
8341
|
);
|
|
8064
8342
|
}
|
|
8065
|
-
|
|
8343
|
+
logger2.mcpError(`Successfully started ${transportConfig.type} transport`);
|
|
8066
8344
|
} catch (error) {
|
|
8067
|
-
|
|
8345
|
+
logger2.mcpError(
|
|
8068
8346
|
`Error starting ${transportConfig.type} transport: ${error instanceof Error ? error.message : String(error)}`
|
|
8069
8347
|
);
|
|
8070
8348
|
if (error instanceof Error && error.stack) {
|
|
8071
|
-
|
|
8349
|
+
logger2.mcpError(`Stack trace: ${error.stack}`);
|
|
8072
8350
|
}
|
|
8073
8351
|
throw error;
|
|
8074
8352
|
}
|
|
@@ -8132,7 +8410,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
8132
8410
|
*
|
|
8133
8411
|
* // With error handling:
|
|
8134
8412
|
* await cli.parseIfExecutedDirectly(import.meta.url).catch((error) => {
|
|
8135
|
-
*
|
|
8413
|
+
* this.logger.error("Fatal error:", error instanceof Error ? error.message : String(error));
|
|
8136
8414
|
* process.exit(1);
|
|
8137
8415
|
* });
|
|
8138
8416
|
* ```
|
|
@@ -8191,30 +8469,30 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
8191
8469
|
};
|
|
8192
8470
|
}
|
|
8193
8471
|
const mcpHandler = async (ctx) => {
|
|
8194
|
-
const
|
|
8195
|
-
globalThis.console =
|
|
8472
|
+
const logger2 = simpleMcpLogger.createMcpLogger("MCP Handler");
|
|
8473
|
+
globalThis.console = logger2;
|
|
8196
8474
|
try {
|
|
8197
|
-
|
|
8475
|
+
logger2.mcpError(
|
|
8198
8476
|
"MCP handler started - console hijacked for MCP safety"
|
|
8199
8477
|
);
|
|
8200
|
-
|
|
8478
|
+
logger2.mcpError(`Handler context args: ${JSON.stringify(ctx.args)}`);
|
|
8201
8479
|
if (!ctx.parentParser) {
|
|
8202
|
-
|
|
8480
|
+
logger2.mcpError(
|
|
8203
8481
|
"Critical: MCP server handler called without a parent parser context."
|
|
8204
8482
|
);
|
|
8205
8483
|
process.exit(1);
|
|
8206
8484
|
}
|
|
8207
|
-
|
|
8485
|
+
logger2.mcpError("Parent parser found, casting to ArgParser");
|
|
8208
8486
|
const mcpParser = ctx.parentParser;
|
|
8209
|
-
|
|
8487
|
+
logger2.mcpError("Checking transport configuration");
|
|
8210
8488
|
const transports = ctx.args["transports"];
|
|
8211
8489
|
if (transports) {
|
|
8212
|
-
|
|
8490
|
+
logger2.mcpError(
|
|
8213
8491
|
`Multiple transports specified via CLI: ${transports}`
|
|
8214
8492
|
);
|
|
8215
8493
|
try {
|
|
8216
8494
|
const transportConfigs = JSON.parse(transports);
|
|
8217
|
-
|
|
8495
|
+
logger2.mcpError(
|
|
8218
8496
|
`Parsed transport configs: ${JSON.stringify(transportConfigs)}`
|
|
8219
8497
|
);
|
|
8220
8498
|
await mcpParser.startMcpServerWithMultipleTransports(
|
|
@@ -8223,16 +8501,16 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
8223
8501
|
toolOptions
|
|
8224
8502
|
);
|
|
8225
8503
|
} catch (error) {
|
|
8226
|
-
|
|
8504
|
+
logger2.mcpError(
|
|
8227
8505
|
`Error parsing transports configuration: ${error.message}`
|
|
8228
8506
|
);
|
|
8229
|
-
|
|
8507
|
+
logger2.mcpError(
|
|
8230
8508
|
`Expected JSON format: '[{"type":"stdio"},{"type":"sse","port":3001}]'`
|
|
8231
8509
|
);
|
|
8232
8510
|
process.exit(1);
|
|
8233
8511
|
}
|
|
8234
8512
|
} else if (defaultTransports && defaultTransports.length > 0) {
|
|
8235
|
-
|
|
8513
|
+
logger2.mcpError(
|
|
8236
8514
|
`Using preset multiple transports: ${JSON.stringify(defaultTransports)}`
|
|
8237
8515
|
);
|
|
8238
8516
|
await mcpParser.startMcpServerWithMultipleTransports(
|
|
@@ -8241,7 +8519,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
8241
8519
|
toolOptions
|
|
8242
8520
|
);
|
|
8243
8521
|
} else if (defaultTransport) {
|
|
8244
|
-
|
|
8522
|
+
logger2.mcpError(
|
|
8245
8523
|
`Using preset single transport: ${JSON.stringify(defaultTransport)}`
|
|
8246
8524
|
);
|
|
8247
8525
|
await mcpParser.startMcpServerWithTransport(
|
|
@@ -8262,7 +8540,7 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
8262
8540
|
host: ctx.args["host"],
|
|
8263
8541
|
path: ctx.args["path"]
|
|
8264
8542
|
};
|
|
8265
|
-
|
|
8543
|
+
logger2.mcpError(
|
|
8266
8544
|
`Using single transport mode: ${transportType} with options: ${JSON.stringify(transportOptions)}`
|
|
8267
8545
|
);
|
|
8268
8546
|
await mcpParser.startMcpServerWithTransport(
|
|
@@ -8272,15 +8550,15 @@ Migration guide: https://github.com/alcyone-labs/arg-parser/blob/main/docs/MCP-M
|
|
|
8272
8550
|
toolOptions
|
|
8273
8551
|
);
|
|
8274
8552
|
}
|
|
8275
|
-
|
|
8553
|
+
logger2.mcpError("MCP server setup completed, keeping process alive");
|
|
8276
8554
|
return new Promise(() => {
|
|
8277
8555
|
});
|
|
8278
8556
|
} catch (error) {
|
|
8279
|
-
|
|
8557
|
+
logger2.mcpError(
|
|
8280
8558
|
`Error in MCP handler: ${error instanceof Error ? error.message : String(error)}`
|
|
8281
8559
|
);
|
|
8282
8560
|
if (error instanceof Error && error.stack) {
|
|
8283
|
-
|
|
8561
|
+
logger2.mcpError(`Stack trace: ${error.stack}`);
|
|
8284
8562
|
}
|
|
8285
8563
|
process.exit(1);
|
|
8286
8564
|
}
|
|
@@ -8692,9 +8970,9 @@ class ArgParserFuzzyTester {
|
|
|
8692
8970
|
const commandPaths = this.discoverCommandPaths();
|
|
8693
8971
|
const results = [];
|
|
8694
8972
|
if (this.options.verbose) {
|
|
8695
|
-
|
|
8973
|
+
this.parser.logger.info(`Discovered ${commandPaths.length} command paths:`);
|
|
8696
8974
|
commandPaths.forEach(
|
|
8697
|
-
(path2) =>
|
|
8975
|
+
(path2) => this.parser.logger.info(` ${path2.join(" ") || "(root)"}`)
|
|
8698
8976
|
);
|
|
8699
8977
|
}
|
|
8700
8978
|
for (const commandPath of commandPaths) {
|
|
@@ -8749,7 +9027,7 @@ class ArgParserFuzzyTester {
|
|
|
8749
9027
|
const targetParser = this.getParserForPath(commandPath);
|
|
8750
9028
|
const flags = this.getFlags(targetParser);
|
|
8751
9029
|
if (this.options.verbose) {
|
|
8752
|
-
|
|
9030
|
+
this.parser.logger.info(`Testing command path: ${commandPath.join(" ") || "(root)"}`);
|
|
8753
9031
|
}
|
|
8754
9032
|
const validCombinations = this.generateValidFlagCombinations(flags);
|
|
8755
9033
|
for (const flagArgs of validCombinations) {
|
|
@@ -8990,585 +9268,6 @@ class ArgParserFuzzyTester {
|
|
|
8990
9268
|
};
|
|
8991
9269
|
}
|
|
8992
9270
|
}
|
|
8993
|
-
class Terminal {
|
|
8994
|
-
constructor() {
|
|
8995
|
-
}
|
|
8996
|
-
static getInstance() {
|
|
8997
|
-
if (!Terminal.instance) {
|
|
8998
|
-
Terminal.instance = new Terminal();
|
|
8999
|
-
}
|
|
9000
|
-
return Terminal.instance;
|
|
9001
|
-
}
|
|
9002
|
-
get width() {
|
|
9003
|
-
return process.stdout.columns || 80;
|
|
9004
|
-
}
|
|
9005
|
-
get height() {
|
|
9006
|
-
return process.stdout.rows || 24;
|
|
9007
|
-
}
|
|
9008
|
-
write(text) {
|
|
9009
|
-
process.stdout.write(text);
|
|
9010
|
-
}
|
|
9011
|
-
clear() {
|
|
9012
|
-
process.stdout.write("\x1B[2J\x1B[3J\x1B[H");
|
|
9013
|
-
}
|
|
9014
|
-
hideCursor() {
|
|
9015
|
-
process.stdout.write("\x1B[?25l");
|
|
9016
|
-
}
|
|
9017
|
-
showCursor() {
|
|
9018
|
-
process.stdout.write("\x1B[?25h");
|
|
9019
|
-
}
|
|
9020
|
-
moveCursor(x, y) {
|
|
9021
|
-
process.stdout.write(`\x1B[${y + 1};${x + 1}H`);
|
|
9022
|
-
}
|
|
9023
|
-
enableRawMode() {
|
|
9024
|
-
if (process.stdin.isTTY) {
|
|
9025
|
-
process.stdin.setRawMode(true);
|
|
9026
|
-
process.stdin.resume();
|
|
9027
|
-
process.stdin.setEncoding("utf8");
|
|
9028
|
-
}
|
|
9029
|
-
}
|
|
9030
|
-
enableMouse() {
|
|
9031
|
-
process.stdout.write("\x1B[?1000h\x1B[?1002h\x1B[?1006h");
|
|
9032
|
-
}
|
|
9033
|
-
disableMouse() {
|
|
9034
|
-
process.stdout.write("\x1B[?1000l\x1B[?1002l\x1B[?1006l");
|
|
9035
|
-
}
|
|
9036
|
-
disableRawMode() {
|
|
9037
|
-
if (process.stdin.isTTY) {
|
|
9038
|
-
process.stdin.setRawMode(false);
|
|
9039
|
-
process.stdin.pause();
|
|
9040
|
-
}
|
|
9041
|
-
}
|
|
9042
|
-
onKey(callback) {
|
|
9043
|
-
process.stdin.on("data", (data2) => {
|
|
9044
|
-
const char = data2.toString();
|
|
9045
|
-
if (char === "") {
|
|
9046
|
-
this.cleanup();
|
|
9047
|
-
process.exit(0);
|
|
9048
|
-
}
|
|
9049
|
-
callback(char, false);
|
|
9050
|
-
});
|
|
9051
|
-
}
|
|
9052
|
-
cleanup() {
|
|
9053
|
-
this.showCursor();
|
|
9054
|
-
this.disableMouse();
|
|
9055
|
-
this.disableRawMode();
|
|
9056
|
-
}
|
|
9057
|
-
}
|
|
9058
|
-
class Component {
|
|
9059
|
-
constructor(config = {}) {
|
|
9060
|
-
this.x = 0;
|
|
9061
|
-
this.y = 0;
|
|
9062
|
-
this.width = 0;
|
|
9063
|
-
this.height = 0;
|
|
9064
|
-
this.config = config;
|
|
9065
|
-
this.id = config.id || `component_${Math.random().toString(36).substr(2, 9)}`;
|
|
9066
|
-
}
|
|
9067
|
-
resize(x, y, width, height) {
|
|
9068
|
-
this.x = x;
|
|
9069
|
-
this.y = y;
|
|
9070
|
-
this.width = width;
|
|
9071
|
-
this.height = height;
|
|
9072
|
-
}
|
|
9073
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
9074
|
-
handleInput(_key) {
|
|
9075
|
-
}
|
|
9076
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
9077
|
-
handleMouse(_event) {
|
|
9078
|
-
}
|
|
9079
|
-
}
|
|
9080
|
-
class SplitLayout extends Component {
|
|
9081
|
-
constructor(config) {
|
|
9082
|
-
super(config);
|
|
9083
|
-
this.direction = config.direction;
|
|
9084
|
-
this.first = config.first;
|
|
9085
|
-
this.second = config.second;
|
|
9086
|
-
this.splitRatio = config.splitRatio ?? 0.5;
|
|
9087
|
-
}
|
|
9088
|
-
resize(x, y, width, height) {
|
|
9089
|
-
super.resize(x, y, width, height);
|
|
9090
|
-
if (this.direction === "horizontal") {
|
|
9091
|
-
const splitX = Math.floor(width * this.splitRatio);
|
|
9092
|
-
this.first.resize(x, y, splitX, height);
|
|
9093
|
-
this.second.resize(x + splitX, y, width - splitX, height);
|
|
9094
|
-
} else {
|
|
9095
|
-
const splitY = Math.floor(height * this.splitRatio);
|
|
9096
|
-
this.first.resize(x, y, width, splitY);
|
|
9097
|
-
this.second.resize(x, y + splitY, width, height - splitY);
|
|
9098
|
-
}
|
|
9099
|
-
}
|
|
9100
|
-
render() {
|
|
9101
|
-
const lines = [];
|
|
9102
|
-
const firstLines = this.first.render();
|
|
9103
|
-
const secondLines = this.second.render();
|
|
9104
|
-
if (this.direction === "horizontal") {
|
|
9105
|
-
const maxHeight = Math.max(firstLines.length, secondLines.length);
|
|
9106
|
-
for (let i = 0; i < maxHeight; i++) {
|
|
9107
|
-
const line1 = firstLines[i] || " ".repeat(this.first["width"]);
|
|
9108
|
-
const line2 = secondLines[i] || " ".repeat(this.second["width"]);
|
|
9109
|
-
lines.push(line1 + line2);
|
|
9110
|
-
}
|
|
9111
|
-
} else {
|
|
9112
|
-
lines.push(...firstLines);
|
|
9113
|
-
lines.push(...secondLines);
|
|
9114
|
-
}
|
|
9115
|
-
return lines;
|
|
9116
|
-
}
|
|
9117
|
-
handleInput(key) {
|
|
9118
|
-
this.first.handleInput(key);
|
|
9119
|
-
this.second.handleInput(key);
|
|
9120
|
-
}
|
|
9121
|
-
handleMouse(event) {
|
|
9122
|
-
this.first.handleMouse(event);
|
|
9123
|
-
this.second.handleMouse(event);
|
|
9124
|
-
}
|
|
9125
|
-
}
|
|
9126
|
-
class App {
|
|
9127
|
-
constructor() {
|
|
9128
|
-
this.isRunning = false;
|
|
9129
|
-
this.lastRenderedLines = [];
|
|
9130
|
-
this.terminal = Terminal.getInstance();
|
|
9131
|
-
}
|
|
9132
|
-
run(root) {
|
|
9133
|
-
this.root = root;
|
|
9134
|
-
this.isRunning = true;
|
|
9135
|
-
this.terminal.enableRawMode();
|
|
9136
|
-
this.terminal.enableMouse();
|
|
9137
|
-
this.terminal.hideCursor();
|
|
9138
|
-
this.terminal.clear();
|
|
9139
|
-
this.render();
|
|
9140
|
-
const cleanup = () => this.terminal.cleanup();
|
|
9141
|
-
process.on("exit", cleanup);
|
|
9142
|
-
process.on("SIGINT", () => {
|
|
9143
|
-
cleanup();
|
|
9144
|
-
process.exit(0);
|
|
9145
|
-
});
|
|
9146
|
-
process.on("uncaughtException", (err) => {
|
|
9147
|
-
cleanup();
|
|
9148
|
-
console.error(err);
|
|
9149
|
-
process.exit(1);
|
|
9150
|
-
});
|
|
9151
|
-
this.terminal.onKey((key) => {
|
|
9152
|
-
if (key.startsWith("\x1B[<")) {
|
|
9153
|
-
const parts = key.substring(3).split(";");
|
|
9154
|
-
if (parts.length === 3) {
|
|
9155
|
-
let buttonCode = parseInt(parts[0]);
|
|
9156
|
-
const x = parseInt(parts[1]) - 1;
|
|
9157
|
-
const lastPart = parts[2];
|
|
9158
|
-
const y = parseInt(lastPart.substring(0, lastPart.length - 1)) - 1;
|
|
9159
|
-
const type2 = lastPart.charAt(lastPart.length - 1);
|
|
9160
|
-
let action = "press";
|
|
9161
|
-
let button = 0;
|
|
9162
|
-
if (type2 === "m") {
|
|
9163
|
-
action = "release";
|
|
9164
|
-
} else {
|
|
9165
|
-
if (buttonCode >= 64) {
|
|
9166
|
-
action = buttonCode === 64 ? "scroll_up" : "scroll_down";
|
|
9167
|
-
buttonCode -= 64;
|
|
9168
|
-
} else {
|
|
9169
|
-
if (buttonCode === 0) button = 0;
|
|
9170
|
-
else if (buttonCode === 1) button = 1;
|
|
9171
|
-
else if (buttonCode === 2) button = 2;
|
|
9172
|
-
if ((buttonCode & 32) === 32) {
|
|
9173
|
-
action = "drag";
|
|
9174
|
-
buttonCode -= 32;
|
|
9175
|
-
if (buttonCode === 0) button = 0;
|
|
9176
|
-
}
|
|
9177
|
-
}
|
|
9178
|
-
}
|
|
9179
|
-
const event = { x, y, button, action };
|
|
9180
|
-
if (this.root) {
|
|
9181
|
-
this.root.handleMouse(event);
|
|
9182
|
-
this.render();
|
|
9183
|
-
}
|
|
9184
|
-
return;
|
|
9185
|
-
}
|
|
9186
|
-
}
|
|
9187
|
-
if (key === "\x1B" || key === "") {
|
|
9188
|
-
this.stop();
|
|
9189
|
-
return;
|
|
9190
|
-
}
|
|
9191
|
-
if (this.root) {
|
|
9192
|
-
this.root.handleInput(key);
|
|
9193
|
-
this.render();
|
|
9194
|
-
}
|
|
9195
|
-
});
|
|
9196
|
-
process.stdout.on("resize", () => {
|
|
9197
|
-
this.render();
|
|
9198
|
-
});
|
|
9199
|
-
}
|
|
9200
|
-
stop() {
|
|
9201
|
-
this.isRunning = false;
|
|
9202
|
-
this.terminal.cleanup();
|
|
9203
|
-
process.exit(0);
|
|
9204
|
-
}
|
|
9205
|
-
render() {
|
|
9206
|
-
if (!this.root || !this.isRunning) return;
|
|
9207
|
-
const width = this.terminal.width;
|
|
9208
|
-
const height = this.terminal.height;
|
|
9209
|
-
this.root.resize(0, 0, width, height);
|
|
9210
|
-
const lines = this.root.render();
|
|
9211
|
-
const maxLines = Math.min(lines.length, height - 1);
|
|
9212
|
-
this.terminal.write("\x1B[H");
|
|
9213
|
-
for (let i = 0; i < maxLines; i++) {
|
|
9214
|
-
const line = lines[i];
|
|
9215
|
-
const lastLine = this.lastRenderedLines[i];
|
|
9216
|
-
if (line !== lastLine) {
|
|
9217
|
-
this.terminal.moveCursor(0, i);
|
|
9218
|
-
this.terminal.write(line);
|
|
9219
|
-
this.terminal.write("\x1B[K");
|
|
9220
|
-
}
|
|
9221
|
-
}
|
|
9222
|
-
this.lastRenderedLines = [...lines];
|
|
9223
|
-
}
|
|
9224
|
-
}
|
|
9225
|
-
const Themes = {
|
|
9226
|
-
Default: {
|
|
9227
|
-
// Dark Mode
|
|
9228
|
-
base: simpleChalk.white,
|
|
9229
|
-
muted: simpleChalk.gray,
|
|
9230
|
-
accent: simpleChalk.cyan,
|
|
9231
|
-
highlight: simpleChalk.cyan,
|
|
9232
|
-
// Was bgBlue.white
|
|
9233
|
-
success: simpleChalk.green,
|
|
9234
|
-
warning: simpleChalk.yellow,
|
|
9235
|
-
error: simpleChalk.red,
|
|
9236
|
-
border: simpleChalk.gray,
|
|
9237
|
-
scrollbarThumb: simpleChalk.white,
|
|
9238
|
-
scrollbarTrack: simpleChalk.gray
|
|
9239
|
-
},
|
|
9240
|
-
Light: {
|
|
9241
|
-
// "Ocean" theme (High contrast on dark)
|
|
9242
|
-
base: simpleChalk.white,
|
|
9243
|
-
muted: simpleChalk.gray,
|
|
9244
|
-
accent: simpleChalk.cyan,
|
|
9245
|
-
highlight: simpleChalk.cyan,
|
|
9246
|
-
// Fallback since bgCyan not supported
|
|
9247
|
-
success: simpleChalk.green,
|
|
9248
|
-
warning: simpleChalk.yellow,
|
|
9249
|
-
error: simpleChalk.red,
|
|
9250
|
-
border: simpleChalk.cyan,
|
|
9251
|
-
scrollbarThumb: simpleChalk.cyan,
|
|
9252
|
-
scrollbarTrack: simpleChalk.gray
|
|
9253
|
-
},
|
|
9254
|
-
Monokai: {
|
|
9255
|
-
base: simpleChalk.white,
|
|
9256
|
-
muted: simpleChalk.gray,
|
|
9257
|
-
accent: simpleChalk.magenta,
|
|
9258
|
-
highlight: simpleChalk.magenta,
|
|
9259
|
-
// Was bgMagenta.white
|
|
9260
|
-
success: simpleChalk.green,
|
|
9261
|
-
warning: simpleChalk.yellow,
|
|
9262
|
-
error: simpleChalk.red,
|
|
9263
|
-
border: simpleChalk.gray,
|
|
9264
|
-
scrollbarThumb: simpleChalk.magenta,
|
|
9265
|
-
scrollbarTrack: simpleChalk.gray
|
|
9266
|
-
}
|
|
9267
|
-
};
|
|
9268
|
-
const _ThemeManager = class _ThemeManager {
|
|
9269
|
-
static get current() {
|
|
9270
|
-
return this._current;
|
|
9271
|
-
}
|
|
9272
|
-
static setTheme(name) {
|
|
9273
|
-
if (Themes[name]) {
|
|
9274
|
-
this._current = Themes[name];
|
|
9275
|
-
}
|
|
9276
|
-
}
|
|
9277
|
-
static setCustomTheme(theme) {
|
|
9278
|
-
this._current = theme;
|
|
9279
|
-
}
|
|
9280
|
-
};
|
|
9281
|
-
_ThemeManager._current = Themes["Default"];
|
|
9282
|
-
let ThemeManager = _ThemeManager;
|
|
9283
|
-
class List extends Component {
|
|
9284
|
-
constructor(config) {
|
|
9285
|
-
super(config);
|
|
9286
|
-
this.selectedIndex = 0;
|
|
9287
|
-
this.scrollOffset = 0;
|
|
9288
|
-
this.items = config.items;
|
|
9289
|
-
this.onSelect = config.onSelect;
|
|
9290
|
-
this.onSubmit = config.onSubmit;
|
|
9291
|
-
}
|
|
9292
|
-
setItems(items2) {
|
|
9293
|
-
this.items = items2;
|
|
9294
|
-
if (this.selectedIndex >= this.items.length) {
|
|
9295
|
-
this.selectedIndex = Math.max(0, this.items.length - 1);
|
|
9296
|
-
}
|
|
9297
|
-
}
|
|
9298
|
-
render() {
|
|
9299
|
-
const lines = [];
|
|
9300
|
-
const visibleCount = this.height;
|
|
9301
|
-
if (this.selectedIndex < this.scrollOffset) {
|
|
9302
|
-
this.scrollOffset = this.selectedIndex;
|
|
9303
|
-
} else if (this.selectedIndex >= this.scrollOffset + visibleCount) {
|
|
9304
|
-
this.scrollOffset = this.selectedIndex - visibleCount + 1;
|
|
9305
|
-
}
|
|
9306
|
-
const visibleItems = this.items.slice(this.scrollOffset, this.scrollOffset + visibleCount);
|
|
9307
|
-
for (let i = 0; i < this.height; i++) {
|
|
9308
|
-
const itemIndex = this.scrollOffset + i;
|
|
9309
|
-
const item = visibleItems[i];
|
|
9310
|
-
if (!item) {
|
|
9311
|
-
lines.push(" ".repeat(this.width));
|
|
9312
|
-
continue;
|
|
9313
|
-
}
|
|
9314
|
-
const isSelected = itemIndex === this.selectedIndex;
|
|
9315
|
-
const theme = ThemeManager.current;
|
|
9316
|
-
let line = "";
|
|
9317
|
-
if (isSelected) {
|
|
9318
|
-
line = theme.highlight("> " + item.label);
|
|
9319
|
-
} else {
|
|
9320
|
-
line = theme.base(" " + item.label);
|
|
9321
|
-
}
|
|
9322
|
-
const rawLabelLength = item.label.length + 2;
|
|
9323
|
-
const padding = Math.max(0, this.width - rawLabelLength);
|
|
9324
|
-
if (isSelected) {
|
|
9325
|
-
line = theme.highlight("> " + item.label + " ".repeat(padding));
|
|
9326
|
-
} else {
|
|
9327
|
-
line = theme.base(" " + item.label + " ".repeat(padding));
|
|
9328
|
-
}
|
|
9329
|
-
lines.push(line);
|
|
9330
|
-
}
|
|
9331
|
-
return lines;
|
|
9332
|
-
}
|
|
9333
|
-
handleInput(key) {
|
|
9334
|
-
if (this.items.length === 0) return;
|
|
9335
|
-
if (key === "\x1B[A") {
|
|
9336
|
-
this.selectedIndex = Math.max(0, this.selectedIndex - 1);
|
|
9337
|
-
if (this.onSelect) this.onSelect(this.items[this.selectedIndex]);
|
|
9338
|
-
} else if (key === "\x1B[B") {
|
|
9339
|
-
this.selectedIndex = Math.min(this.items.length - 1, this.selectedIndex + 1);
|
|
9340
|
-
if (this.onSelect) this.onSelect(this.items[this.selectedIndex]);
|
|
9341
|
-
} else if (key === "\r" || key === "\x1B[C") {
|
|
9342
|
-
if (this.onSubmit) this.onSubmit(this.items[this.selectedIndex]);
|
|
9343
|
-
}
|
|
9344
|
-
}
|
|
9345
|
-
}
|
|
9346
|
-
function stripAnsi(str) {
|
|
9347
|
-
return str.replace(/[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g, "");
|
|
9348
|
-
}
|
|
9349
|
-
function visualLength(str) {
|
|
9350
|
-
return stripAnsi(str).length;
|
|
9351
|
-
}
|
|
9352
|
-
function wrapText(text, width) {
|
|
9353
|
-
if (width <= 0) return [text];
|
|
9354
|
-
const result = [];
|
|
9355
|
-
const lines = text.split("\n");
|
|
9356
|
-
for (const line of lines) {
|
|
9357
|
-
if (visualLength(line) <= width) {
|
|
9358
|
-
result.push(line);
|
|
9359
|
-
continue;
|
|
9360
|
-
}
|
|
9361
|
-
let currentLine = "";
|
|
9362
|
-
let currentVisibleLength = 0;
|
|
9363
|
-
let activeAnsiCodes = [];
|
|
9364
|
-
const tokenRegex = /(\u001b\[(?:\d{1,3}(?:;\d{1,3})*)?[mK])|([\s\S])/g;
|
|
9365
|
-
let match;
|
|
9366
|
-
while ((match = tokenRegex.exec(line)) !== null) {
|
|
9367
|
-
const ansiCode = match[1];
|
|
9368
|
-
const char = match[2];
|
|
9369
|
-
if (ansiCode) {
|
|
9370
|
-
currentLine += ansiCode;
|
|
9371
|
-
if (ansiCode === "\x1B[0m") {
|
|
9372
|
-
activeAnsiCodes = [];
|
|
9373
|
-
} else if (ansiCode.endsWith("m")) {
|
|
9374
|
-
activeAnsiCodes.push(ansiCode);
|
|
9375
|
-
}
|
|
9376
|
-
} else if (char) {
|
|
9377
|
-
if (currentVisibleLength >= width) {
|
|
9378
|
-
result.push(currentLine + "\x1B[0m");
|
|
9379
|
-
currentLine = activeAnsiCodes.join("") + char;
|
|
9380
|
-
currentVisibleLength = 1;
|
|
9381
|
-
} else {
|
|
9382
|
-
currentLine += char;
|
|
9383
|
-
currentVisibleLength++;
|
|
9384
|
-
}
|
|
9385
|
-
}
|
|
9386
|
-
}
|
|
9387
|
-
if (currentLine.length > 0) {
|
|
9388
|
-
result.push(currentLine + "\x1B[0m");
|
|
9389
|
-
}
|
|
9390
|
-
}
|
|
9391
|
-
return result;
|
|
9392
|
-
}
|
|
9393
|
-
class ScrollArea extends Component {
|
|
9394
|
-
constructor(config) {
|
|
9395
|
-
super(config);
|
|
9396
|
-
this.contentLines = [];
|
|
9397
|
-
this.scrollOffset = 0;
|
|
9398
|
-
this.wrapText = false;
|
|
9399
|
-
this.content = config.content;
|
|
9400
|
-
this.wrapText = !!config.wrapText;
|
|
9401
|
-
this.updateContentLines();
|
|
9402
|
-
}
|
|
9403
|
-
setContent(content) {
|
|
9404
|
-
this.content = typeof content === "string" ? content : String(content || "");
|
|
9405
|
-
this.scrollOffset = 0;
|
|
9406
|
-
this.updateContentLines();
|
|
9407
|
-
}
|
|
9408
|
-
resize(x, y, width, height) {
|
|
9409
|
-
super.resize(x, y, width, height);
|
|
9410
|
-
if (this.wrapText) {
|
|
9411
|
-
this.updateContentLines();
|
|
9412
|
-
}
|
|
9413
|
-
}
|
|
9414
|
-
updateContentLines() {
|
|
9415
|
-
if (this.wrapText && this.width > 0) {
|
|
9416
|
-
this.contentLines = wrapText(this.content, Math.max(1, this.width - 2));
|
|
9417
|
-
} else {
|
|
9418
|
-
this.contentLines = this.content.split("\n");
|
|
9419
|
-
}
|
|
9420
|
-
}
|
|
9421
|
-
render() {
|
|
9422
|
-
const lines = [];
|
|
9423
|
-
const visibleLines = this.contentLines.slice(this.scrollOffset, this.scrollOffset + this.height);
|
|
9424
|
-
const showScrollbar = this.contentLines.length > this.height;
|
|
9425
|
-
let scrollbarHeight = 0;
|
|
9426
|
-
let scrollbarTop = 0;
|
|
9427
|
-
if (showScrollbar) {
|
|
9428
|
-
const ratio = this.height / this.contentLines.length;
|
|
9429
|
-
scrollbarHeight = Math.max(1, Math.floor(this.height * ratio));
|
|
9430
|
-
const scrollPercent = this.scrollOffset / (this.contentLines.length - this.height);
|
|
9431
|
-
const maxTop = this.height - scrollbarHeight;
|
|
9432
|
-
scrollbarTop = Math.floor(scrollPercent * maxTop);
|
|
9433
|
-
}
|
|
9434
|
-
for (let i = 0; i < this.height; i++) {
|
|
9435
|
-
const lineContent = visibleLines[i] || "";
|
|
9436
|
-
let prefix = "";
|
|
9437
|
-
if (showScrollbar) {
|
|
9438
|
-
const isThumb = i >= scrollbarTop && i < scrollbarTop + scrollbarHeight;
|
|
9439
|
-
const theme = ThemeManager.current;
|
|
9440
|
-
prefix = isThumb ? theme.scrollbarThumb("█") : theme.scrollbarTrack("│");
|
|
9441
|
-
prefix += " ";
|
|
9442
|
-
}
|
|
9443
|
-
const visibleWidth = showScrollbar ? this.width - 2 : this.width;
|
|
9444
|
-
const visibleLength = stripAnsi(lineContent).length;
|
|
9445
|
-
const rawLength = lineContent.length;
|
|
9446
|
-
const invisibleLength = rawLength - visibleLength;
|
|
9447
|
-
let renderedContent = "";
|
|
9448
|
-
if (visibleLength > visibleWidth) {
|
|
9449
|
-
renderedContent = lineContent.substring(0, visibleWidth + invisibleLength);
|
|
9450
|
-
} else {
|
|
9451
|
-
const padding = Math.max(0, visibleWidth - visibleLength);
|
|
9452
|
-
renderedContent = lineContent + " ".repeat(padding);
|
|
9453
|
-
}
|
|
9454
|
-
lines.push(prefix + renderedContent);
|
|
9455
|
-
}
|
|
9456
|
-
return lines;
|
|
9457
|
-
}
|
|
9458
|
-
handleMouse(event) {
|
|
9459
|
-
if (event.x >= this.x && event.x < this.x + this.width && event.y >= this.y && event.y < this.y + this.height) {
|
|
9460
|
-
if (event.action === "scroll_up") {
|
|
9461
|
-
this.scrollOffset = Math.max(0, this.scrollOffset - 3);
|
|
9462
|
-
} else if (event.action === "scroll_down") {
|
|
9463
|
-
const maxScroll = Math.max(0, this.contentLines.length - this.height);
|
|
9464
|
-
this.scrollOffset = Math.min(maxScroll, this.scrollOffset + 3);
|
|
9465
|
-
}
|
|
9466
|
-
}
|
|
9467
|
-
}
|
|
9468
|
-
handleInput(key) {
|
|
9469
|
-
if (key === "\x1B[A") {
|
|
9470
|
-
this.scrollOffset = Math.max(0, this.scrollOffset - 1);
|
|
9471
|
-
} else if (key === "\x1B[B") {
|
|
9472
|
-
const maxScroll = Math.max(0, this.contentLines.length - this.height);
|
|
9473
|
-
this.scrollOffset = Math.min(maxScroll, this.scrollOffset + 1);
|
|
9474
|
-
} else if (key === "\x1B[5~") {
|
|
9475
|
-
this.scrollOffset = Math.max(0, this.scrollOffset - this.height);
|
|
9476
|
-
} else if (key === "\x1B[6~") {
|
|
9477
|
-
const maxScroll = Math.max(0, this.contentLines.length - this.height);
|
|
9478
|
-
this.scrollOffset = Math.min(maxScroll, this.scrollOffset + this.height);
|
|
9479
|
-
}
|
|
9480
|
-
}
|
|
9481
|
-
}
|
|
9482
|
-
class Input extends Component {
|
|
9483
|
-
constructor(config) {
|
|
9484
|
-
super(config);
|
|
9485
|
-
this.prefix = config.prefix || "";
|
|
9486
|
-
this.placeholder = config.placeholder || "";
|
|
9487
|
-
this.value = config.value || "";
|
|
9488
|
-
this.onChange = config.onChange;
|
|
9489
|
-
this.onSubmit = config.onSubmit;
|
|
9490
|
-
}
|
|
9491
|
-
setValue(value) {
|
|
9492
|
-
this.value = value;
|
|
9493
|
-
if (this.onChange) this.onChange(this.value);
|
|
9494
|
-
}
|
|
9495
|
-
getValue() {
|
|
9496
|
-
return this.value;
|
|
9497
|
-
}
|
|
9498
|
-
render() {
|
|
9499
|
-
const lines = [];
|
|
9500
|
-
const theme = ThemeManager.current;
|
|
9501
|
-
let text = this.prefix + (this.value || theme.muted(this.placeholder));
|
|
9502
|
-
if (text.length > this.width) {
|
|
9503
|
-
text = text.substring(0, this.width - 1) + "…";
|
|
9504
|
-
}
|
|
9505
|
-
lines.push((text + " ".repeat(Math.max(0, this.width - text.length))).substring(0, this.width));
|
|
9506
|
-
return lines;
|
|
9507
|
-
}
|
|
9508
|
-
handleInput(key) {
|
|
9509
|
-
if (key === "\r") {
|
|
9510
|
-
if (this.onSubmit) this.onSubmit(this.value);
|
|
9511
|
-
} else if (key === "" || key === "\b") {
|
|
9512
|
-
if (this.value.length > 0) {
|
|
9513
|
-
this.value = this.value.substring(0, this.value.length - 1);
|
|
9514
|
-
if (this.onChange) this.onChange(this.value);
|
|
9515
|
-
}
|
|
9516
|
-
} else if (key.length === 1 && key >= " " && key <= "~") {
|
|
9517
|
-
this.value += key;
|
|
9518
|
-
if (this.onChange) this.onChange(this.value);
|
|
9519
|
-
}
|
|
9520
|
-
}
|
|
9521
|
-
}
|
|
9522
|
-
class StackNavigator extends Component {
|
|
9523
|
-
constructor(config) {
|
|
9524
|
-
super(config);
|
|
9525
|
-
this.stack = [];
|
|
9526
|
-
this.stack.push(config.initialComponent);
|
|
9527
|
-
}
|
|
9528
|
-
push(component) {
|
|
9529
|
-
this.stack.push(component);
|
|
9530
|
-
component.resize(this.x, this.y, this.width, this.height);
|
|
9531
|
-
}
|
|
9532
|
-
pop() {
|
|
9533
|
-
if (this.stack.length > 1) {
|
|
9534
|
-
this.stack.pop();
|
|
9535
|
-
}
|
|
9536
|
-
}
|
|
9537
|
-
get currentComponent() {
|
|
9538
|
-
return this.stack[this.stack.length - 1];
|
|
9539
|
-
}
|
|
9540
|
-
resize(x, y, width, height) {
|
|
9541
|
-
super.resize(x, y, width, height);
|
|
9542
|
-
this.currentComponent.resize(x, y, width, height);
|
|
9543
|
-
}
|
|
9544
|
-
render() {
|
|
9545
|
-
return this.currentComponent.render();
|
|
9546
|
-
}
|
|
9547
|
-
handleInput(key) {
|
|
9548
|
-
if ((key === "\x1B" || key === "\x1B[D") && this.stack.length > 1) {
|
|
9549
|
-
this.pop();
|
|
9550
|
-
this.currentComponent.resize(this.x, this.y, this.width, this.height);
|
|
9551
|
-
return;
|
|
9552
|
-
}
|
|
9553
|
-
this.currentComponent.handleInput(key);
|
|
9554
|
-
}
|
|
9555
|
-
handleMouse(event) {
|
|
9556
|
-
this.currentComponent.handleMouse(event);
|
|
9557
|
-
}
|
|
9558
|
-
}
|
|
9559
|
-
const index$2 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
9560
|
-
__proto__: null,
|
|
9561
|
-
App,
|
|
9562
|
-
Component,
|
|
9563
|
-
Input,
|
|
9564
|
-
List,
|
|
9565
|
-
ScrollArea,
|
|
9566
|
-
SplitLayout,
|
|
9567
|
-
StackNavigator,
|
|
9568
|
-
Terminal,
|
|
9569
|
-
ThemeManager,
|
|
9570
|
-
Themes
|
|
9571
|
-
}, Symbol.toStringTag, { value: "Module" }));
|
|
9572
9271
|
const LATEST_PROTOCOL_VERSION = "2025-06-18";
|
|
9573
9272
|
const DEFAULT_NEGOTIATED_PROTOCOL_VERSION = "2025-03-26";
|
|
9574
9273
|
const SUPPORTED_PROTOCOL_VERSIONS = [
|
|
@@ -10942,7 +10641,7 @@ function requireUri_all() {
|
|
|
10942
10641
|
(function(module2, exports2) {
|
|
10943
10642
|
(function(global2, factory) {
|
|
10944
10643
|
factory(exports2);
|
|
10945
|
-
})(uri_all, function(exports3) {
|
|
10644
|
+
})(uri_all, (function(exports3) {
|
|
10946
10645
|
function merge() {
|
|
10947
10646
|
for (var _len = arguments.length, sets = Array(_len), _key = 0; _key < _len; _key++) {
|
|
10948
10647
|
sets[_key] = arguments[_key];
|
|
@@ -11009,7 +10708,7 @@ function requireUri_all() {
|
|
|
11009
10708
|
}
|
|
11010
10709
|
var URI_PROTOCOL = buildExps(false);
|
|
11011
10710
|
var IRI_PROTOCOL = buildExps(true);
|
|
11012
|
-
var slicedToArray = /* @__PURE__ */ function() {
|
|
10711
|
+
var slicedToArray = /* @__PURE__ */ (function() {
|
|
11013
10712
|
function sliceIterator(arr, i) {
|
|
11014
10713
|
var _arr = [];
|
|
11015
10714
|
var _n = true;
|
|
@@ -11041,7 +10740,7 @@ function requireUri_all() {
|
|
|
11041
10740
|
throw new TypeError("Invalid attempt to destructure non-iterable instance");
|
|
11042
10741
|
}
|
|
11043
10742
|
};
|
|
11044
|
-
}();
|
|
10743
|
+
})();
|
|
11045
10744
|
var toConsumableArray = function(arr) {
|
|
11046
10745
|
if (Array.isArray(arr)) {
|
|
11047
10746
|
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
|
|
@@ -11956,7 +11655,7 @@ function requireUri_all() {
|
|
|
11956
11655
|
exports3.escapeComponent = escapeComponent;
|
|
11957
11656
|
exports3.unescapeComponent = unescapeComponent;
|
|
11958
11657
|
Object.defineProperty(exports3, "__esModule", { value: true });
|
|
11959
|
-
});
|
|
11658
|
+
}));
|
|
11960
11659
|
})(uri_all$1, uri_all$1.exports);
|
|
11961
11660
|
return uri_all$1.exports;
|
|
11962
11661
|
}
|
|
@@ -12550,7 +12249,7 @@ function requireFastJsonStableStringify() {
|
|
|
12550
12249
|
if (!opts) opts = {};
|
|
12551
12250
|
if (typeof opts === "function") opts = { cmp: opts };
|
|
12552
12251
|
var cycles = typeof opts.cycles === "boolean" ? opts.cycles : false;
|
|
12553
|
-
var cmp = opts.cmp && /* @__PURE__ */ function(f) {
|
|
12252
|
+
var cmp = opts.cmp && /* @__PURE__ */ (function(f) {
|
|
12554
12253
|
return function(node) {
|
|
12555
12254
|
return function(a, b) {
|
|
12556
12255
|
var aobj = { key: a, value: node[a] };
|
|
@@ -12558,9 +12257,9 @@ function requireFastJsonStableStringify() {
|
|
|
12558
12257
|
return f(aobj, bobj);
|
|
12559
12258
|
};
|
|
12560
12259
|
};
|
|
12561
|
-
}(opts.cmp);
|
|
12260
|
+
})(opts.cmp);
|
|
12562
12261
|
var seen = [];
|
|
12563
|
-
return function stringify2(node) {
|
|
12262
|
+
return (function stringify2(node) {
|
|
12564
12263
|
if (node && node.toJSON && typeof node.toJSON === "function") {
|
|
12565
12264
|
node = node.toJSON();
|
|
12566
12265
|
}
|
|
@@ -12593,7 +12292,7 @@ function requireFastJsonStableStringify() {
|
|
|
12593
12292
|
}
|
|
12594
12293
|
seen.splice(seenIndex, 1);
|
|
12595
12294
|
return "{" + out + "}";
|
|
12596
|
-
}(data2);
|
|
12295
|
+
})(data2);
|
|
12597
12296
|
};
|
|
12598
12297
|
return fastJsonStableStringify;
|
|
12599
12298
|
}
|
|
@@ -16954,14 +16653,14 @@ function requireAjv() {
|
|
|
16954
16653
|
return metaOpts;
|
|
16955
16654
|
}
|
|
16956
16655
|
function setLogger(self2) {
|
|
16957
|
-
var
|
|
16958
|
-
if (
|
|
16656
|
+
var logger2 = self2._opts.logger;
|
|
16657
|
+
if (logger2 === false) {
|
|
16959
16658
|
self2.logger = { log: noop, warn: noop, error: noop };
|
|
16960
16659
|
} else {
|
|
16961
|
-
if (
|
|
16962
|
-
if (!(typeof
|
|
16660
|
+
if (logger2 === void 0) logger2 = console;
|
|
16661
|
+
if (!(typeof logger2 == "object" && logger2.log && logger2.warn && logger2.error))
|
|
16963
16662
|
throw new Error("logger must implement log, warn and error methods");
|
|
16964
|
-
self2.logger =
|
|
16663
|
+
self2.logger = logger2;
|
|
16965
16664
|
}
|
|
16966
16665
|
}
|
|
16967
16666
|
function noop() {
|
|
@@ -18152,9 +17851,9 @@ const mcp = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty(
|
|
|
18152
17851
|
ResourceTemplate
|
|
18153
17852
|
}, Symbol.toStringTag, { value: "Module" }));
|
|
18154
17853
|
class McpLifecycleManager {
|
|
18155
|
-
constructor(events,
|
|
17854
|
+
constructor(events, logger2, serverInfo, argParser) {
|
|
18156
17855
|
this.events = events;
|
|
18157
|
-
this.logger =
|
|
17856
|
+
this.logger = logger2;
|
|
18158
17857
|
this.serverInfo = serverInfo;
|
|
18159
17858
|
this.argParser = argParser;
|
|
18160
17859
|
this.state = {
|
|
@@ -20428,7 +20127,7 @@ function requireBuffer() {
|
|
|
20428
20127
|
function numberIsNaN(obj) {
|
|
20429
20128
|
return obj !== obj;
|
|
20430
20129
|
}
|
|
20431
|
-
var hexSliceLookupTable = function() {
|
|
20130
|
+
var hexSliceLookupTable = (function() {
|
|
20432
20131
|
var alphabet = "0123456789abcdef";
|
|
20433
20132
|
var table = new Array(256);
|
|
20434
20133
|
for (var i = 0; i < 16; ++i) {
|
|
@@ -20438,7 +20137,7 @@ function requireBuffer() {
|
|
|
20438
20137
|
}
|
|
20439
20138
|
}
|
|
20440
20139
|
return table;
|
|
20441
|
-
}();
|
|
20140
|
+
})();
|
|
20442
20141
|
})(buffer);
|
|
20443
20142
|
return buffer;
|
|
20444
20143
|
}
|
|
@@ -25524,7 +25223,7 @@ function getStringEnd(str, seek) {
|
|
|
25524
25223
|
}
|
|
25525
25224
|
return seek;
|
|
25526
25225
|
}
|
|
25527
|
-
let DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}
|
|
25226
|
+
let DATE_TIME_RE = /^(\d{4}-\d{2}-\d{2})?[T ]?(?:(\d{2}):\d{2}(?::\d{2}(?:\.\d+)?)?)?(Z|[-+]\d{2}:\d{2})?$/i;
|
|
25528
25227
|
class TomlDate extends Date {
|
|
25529
25228
|
#hasDate = false;
|
|
25530
25229
|
#hasTime = false;
|
|
@@ -25617,13 +25316,14 @@ class TomlDate extends Date {
|
|
|
25617
25316
|
let INT_REGEX = /^((0x[0-9a-fA-F](_?[0-9a-fA-F])*)|(([+-]|0[ob])?\d(_?\d)*))$/;
|
|
25618
25317
|
let FLOAT_REGEX = /^[+-]?\d(_?\d)*(\.\d(_?\d)*)?([eE][+-]?\d(_?\d)*)?$/;
|
|
25619
25318
|
let LEADING_ZERO = /^[+-]?0[0-9_]/;
|
|
25620
|
-
let ESCAPE_REGEX = /^[0-9a-f]{
|
|
25319
|
+
let ESCAPE_REGEX = /^[0-9a-f]{2,8}$/i;
|
|
25621
25320
|
let ESC_MAP = {
|
|
25622
25321
|
b: "\b",
|
|
25623
25322
|
t: " ",
|
|
25624
25323
|
n: "\n",
|
|
25625
25324
|
f: "\f",
|
|
25626
25325
|
r: "\r",
|
|
25326
|
+
e: "\x1B",
|
|
25627
25327
|
'"': '"',
|
|
25628
25328
|
"\\": "\\"
|
|
25629
25329
|
};
|
|
@@ -25658,8 +25358,8 @@ function parseString(str, ptr = 0, endPtr = str.length) {
|
|
|
25658
25358
|
}
|
|
25659
25359
|
if (isEscape) {
|
|
25660
25360
|
isEscape = false;
|
|
25661
|
-
if (c === "u" || c === "U") {
|
|
25662
|
-
let code = str.slice(ptr, ptr += c === "u" ? 4 : 8);
|
|
25361
|
+
if (c === "x" || c === "u" || c === "U") {
|
|
25362
|
+
let code = str.slice(ptr, ptr += c === "x" ? 2 : c === "u" ? 4 : 8);
|
|
25663
25363
|
if (!ESCAPE_REGEX.test(code)) {
|
|
25664
25364
|
throw new TomlError("invalid unicode escape", {
|
|
25665
25365
|
toml: str,
|
|
@@ -25750,24 +25450,14 @@ function parseValue(value, toml, ptr, integersAsBigInt) {
|
|
|
25750
25450
|
}
|
|
25751
25451
|
return date;
|
|
25752
25452
|
}
|
|
25753
|
-
function sliceAndTrimEndOf(str, startPtr, endPtr
|
|
25453
|
+
function sliceAndTrimEndOf(str, startPtr, endPtr) {
|
|
25754
25454
|
let value = str.slice(startPtr, endPtr);
|
|
25755
25455
|
let commentIdx = value.indexOf("#");
|
|
25756
25456
|
if (commentIdx > -1) {
|
|
25757
25457
|
skipComment(str, commentIdx);
|
|
25758
25458
|
value = value.slice(0, commentIdx);
|
|
25759
25459
|
}
|
|
25760
|
-
|
|
25761
|
-
if (!allowNewLines) {
|
|
25762
|
-
let newlineIdx = value.indexOf("\n", trimmed.length);
|
|
25763
|
-
if (newlineIdx > -1) {
|
|
25764
|
-
throw new TomlError("newlines are not allowed in inline tables", {
|
|
25765
|
-
toml: str,
|
|
25766
|
-
ptr: startPtr + newlineIdx
|
|
25767
|
-
});
|
|
25768
|
-
}
|
|
25769
|
-
}
|
|
25770
|
-
return [trimmed, commentIdx];
|
|
25460
|
+
return [value.trimEnd(), commentIdx];
|
|
25771
25461
|
}
|
|
25772
25462
|
function extractValue(str, ptr, end, depth, integersAsBigInt) {
|
|
25773
25463
|
if (depth === 0) {
|
|
@@ -25779,24 +25469,25 @@ function extractValue(str, ptr, end, depth, integersAsBigInt) {
|
|
|
25779
25469
|
let c = str[ptr];
|
|
25780
25470
|
if (c === "[" || c === "{") {
|
|
25781
25471
|
let [value, endPtr2] = c === "[" ? parseArray(str, ptr, depth, integersAsBigInt) : parseInlineTable(str, ptr, depth, integersAsBigInt);
|
|
25782
|
-
|
|
25783
|
-
|
|
25784
|
-
|
|
25785
|
-
|
|
25786
|
-
|
|
25472
|
+
if (end) {
|
|
25473
|
+
endPtr2 = skipVoid(str, endPtr2);
|
|
25474
|
+
if (str[endPtr2] === ",")
|
|
25475
|
+
endPtr2++;
|
|
25476
|
+
else if (str[endPtr2] !== end) {
|
|
25477
|
+
throw new TomlError("expected comma or end of structure", {
|
|
25787
25478
|
toml: str,
|
|
25788
|
-
ptr:
|
|
25479
|
+
ptr: endPtr2
|
|
25789
25480
|
});
|
|
25790
25481
|
}
|
|
25791
25482
|
}
|
|
25792
|
-
return [value,
|
|
25483
|
+
return [value, endPtr2];
|
|
25793
25484
|
}
|
|
25794
25485
|
let endPtr;
|
|
25795
25486
|
if (c === '"' || c === "'") {
|
|
25796
25487
|
endPtr = getStringEnd(str, ptr);
|
|
25797
25488
|
let parsed = parseString(str, ptr, endPtr);
|
|
25798
25489
|
if (end) {
|
|
25799
|
-
endPtr = skipVoid(str, endPtr
|
|
25490
|
+
endPtr = skipVoid(str, endPtr);
|
|
25800
25491
|
if (str[endPtr] && str[endPtr] !== "," && str[endPtr] !== end && str[endPtr] !== "\n" && str[endPtr] !== "\r") {
|
|
25801
25492
|
throw new TomlError("unexpected character encountered", {
|
|
25802
25493
|
toml: str,
|
|
@@ -25808,7 +25499,7 @@ function extractValue(str, ptr, end, depth, integersAsBigInt) {
|
|
|
25808
25499
|
return [parsed, endPtr];
|
|
25809
25500
|
}
|
|
25810
25501
|
endPtr = skipUntil(str, ptr, ",", end);
|
|
25811
|
-
let slice = sliceAndTrimEndOf(str, ptr, endPtr - +(str[endPtr - 1] === ",")
|
|
25502
|
+
let slice = sliceAndTrimEndOf(str, ptr, endPtr - +(str[endPtr - 1] === ","));
|
|
25812
25503
|
if (!slice[0]) {
|
|
25813
25504
|
throw new TomlError("incomplete key-value declaration: no value specified", {
|
|
25814
25505
|
toml: str,
|
|
@@ -25896,17 +25587,16 @@ function parseInlineTable(str, ptr, depth, integersAsBigInt) {
|
|
|
25896
25587
|
let res = {};
|
|
25897
25588
|
let seen = /* @__PURE__ */ new Set();
|
|
25898
25589
|
let c;
|
|
25899
|
-
let comma = 0;
|
|
25900
25590
|
ptr++;
|
|
25901
25591
|
while ((c = str[ptr++]) !== "}" && c) {
|
|
25902
|
-
|
|
25903
|
-
|
|
25904
|
-
|
|
25905
|
-
|
|
25906
|
-
|
|
25907
|
-
} else if (c === "
|
|
25908
|
-
|
|
25909
|
-
|
|
25592
|
+
if (c === ",") {
|
|
25593
|
+
throw new TomlError("expected value, found comma", {
|
|
25594
|
+
toml: str,
|
|
25595
|
+
ptr: ptr - 1
|
|
25596
|
+
});
|
|
25597
|
+
} else if (c === "#")
|
|
25598
|
+
ptr = skipComment(str, ptr);
|
|
25599
|
+
else if (c !== " " && c !== " " && c !== "\n" && c !== "\r") {
|
|
25910
25600
|
let k;
|
|
25911
25601
|
let t = res;
|
|
25912
25602
|
let hasOwn = false;
|
|
@@ -25935,15 +25625,8 @@ function parseInlineTable(str, ptr, depth, integersAsBigInt) {
|
|
|
25935
25625
|
seen.add(value);
|
|
25936
25626
|
t[k] = value;
|
|
25937
25627
|
ptr = valueEndPtr;
|
|
25938
|
-
comma = str[ptr - 1] === "," ? ptr - 1 : 0;
|
|
25939
25628
|
}
|
|
25940
25629
|
}
|
|
25941
|
-
if (comma) {
|
|
25942
|
-
throw new TomlError("trailing commas are not allowed in inline tables", {
|
|
25943
|
-
toml: str,
|
|
25944
|
-
ptr: comma
|
|
25945
|
-
});
|
|
25946
|
-
}
|
|
25947
25630
|
if (!c) {
|
|
25948
25631
|
throw new TomlError("unfinished table encountered", {
|
|
25949
25632
|
toml: str,
|
|
@@ -26274,13 +25957,14 @@ exports.ConfigPlugin = ConfigPlugin;
|
|
|
26274
25957
|
exports.ConfigPluginRegistry = ConfigPluginRegistry;
|
|
26275
25958
|
exports.DxtPathResolver = DxtPathResolver;
|
|
26276
25959
|
exports.EnvConfigPlugin = EnvConfigPlugin;
|
|
25960
|
+
exports.FlagInheritance = FlagInheritance;
|
|
26277
25961
|
exports.JsonConfigPlugin = JsonConfigPlugin;
|
|
26278
25962
|
exports.OutputSchemaPatterns = OutputSchemaPatterns;
|
|
26279
25963
|
exports.SimpleChalk = simpleChalk;
|
|
26280
25964
|
exports.TomlConfigPlugin = TomlConfigPlugin;
|
|
26281
|
-
exports.UI = index$2;
|
|
26282
25965
|
exports.YamlConfigPlugin = YamlConfigPlugin;
|
|
26283
25966
|
exports.absolutePath = absolutePath;
|
|
25967
|
+
exports.autoHelpHandler = autoHelpHandler;
|
|
26284
25968
|
exports.convertFlagToJsonSchemaProperty = convertFlagToJsonSchemaProperty;
|
|
26285
25969
|
exports.convertFlagsToJsonSchema = convertFlagsToJsonSchema;
|
|
26286
25970
|
exports.convertFlagsToZodSchema = convertFlagsToZodSchema;
|