Merge branch 'main' into accurate-cli-version
This commit is contained in:
commit
32ea112051
1 changed files with 3542 additions and 561 deletions
|
|
@ -19,6 +19,17 @@ import {
|
|||
} from "./client/index.js";
|
||||
import { handleError } from "./error-handler.js";
|
||||
import { createTransport, TransportOptions } from "./transport.js";
|
||||
import { awaitableLog } from "./utils/awaitable-log.js";
|
||||
|
||||
// JSON value type for CLI arguments
|
||||
type JsonValue =
|
||||
| string
|
||||
| number
|
||||
| boolean
|
||||
| null
|
||||
| undefined
|
||||
| JsonValue[]
|
||||
| { [key: string]: JsonValue };
|
||||
|
||||
import packageJson from "../package.json" with { type: "json" };
|
||||
|
||||
|
|
@ -26,17 +37,19 @@ type Args = {
|
|||
target: string[];
|
||||
method?: string;
|
||||
promptName?: string;
|
||||
promptArgs?: Record<string, string>;
|
||||
promptArgs?: Record<string, JsonValue>;
|
||||
uri?: string;
|
||||
logLevel?: LogLevel;
|
||||
toolName?: string;
|
||||
toolArg?: Record<string, string>;
|
||||
toolArg?: Record<string, JsonValue>;
|
||||
transport?: "sse" | "stdio" | "http";
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
|
||||
function createTransportOptions(
|
||||
target: string[],
|
||||
transport?: "sse" | "stdio" | "http",
|
||||
headers?: Record<string, string>,
|
||||
): TransportOptions {
|
||||
if (target.length === 0) {
|
||||
throw new Error(
|
||||
|
|
@ -83,11 +96,16 @@ function createTransportOptions(
|
|||
command: isUrl ? undefined : command,
|
||||
args: isUrl ? undefined : commandArgs,
|
||||
url: isUrl ? command : undefined,
|
||||
headers,
|
||||
};
|
||||
}
|
||||
|
||||
async function callMethod(args: Args): Promise<void> {
|
||||
const transportOptions = createTransportOptions(args.target, args.transport);
|
||||
const transportOptions = createTransportOptions(
|
||||
args.target,
|
||||
args.transport,
|
||||
args.headers,
|
||||
);
|
||||
const transport = createTransport(transportOptions);
|
||||
|
||||
const [, name = packageJson.name] = packageJson.name.split("/");
|
||||
|
|
@ -154,7 +172,7 @@ async function callMethod(args: Args): Promise<void> {
|
|||
);
|
||||
}
|
||||
|
||||
console.log(JSON.stringify(result, null, 2));
|
||||
await awaitableLog(JSON.stringify(result, null, 2));
|
||||
} finally {
|
||||
try {
|
||||
await disconnect(transport);
|
||||
|
|
@ -166,8 +184,8 @@ async function callMethod(args: Args): Promise<void> {
|
|||
|
||||
function parseKeyValuePair(
|
||||
value: string,
|
||||
previous: Record<string, string> = {},
|
||||
): Record<string, string> {
|
||||
previous: Record<string, JsonValue> = {},
|
||||
): Record<string, JsonValue> {
|
||||
const parts = value.split("=");
|
||||
const key = parts[0];
|
||||
const val = parts.slice(1).join("=");
|
||||
|
|
@ -178,7 +196,40 @@ function parseKeyValuePair(
|
|||
);
|
||||
}
|
||||
|
||||
return { ...previous, [key as string]: val };
|
||||
// Try to parse as JSON first
|
||||
let parsedValue: JsonValue;
|
||||
try {
|
||||
parsedValue = JSON.parse(val) as JsonValue;
|
||||
} catch {
|
||||
// If JSON parsing fails, keep as string
|
||||
parsedValue = val;
|
||||
}
|
||||
|
||||
return { ...previous, [key as string]: parsedValue };
|
||||
}
|
||||
|
||||
function parseHeaderPair(
|
||||
value: string,
|
||||
previous: Record<string, string> = {},
|
||||
): Record<string, string> {
|
||||
const colonIndex = value.indexOf(":");
|
||||
|
||||
if (colonIndex === -1) {
|
||||
throw new Error(
|
||||
`Invalid header format: ${value}. Use "HeaderName: Value" format.`,
|
||||
);
|
||||
}
|
||||
|
||||
const key = value.slice(0, colonIndex).trim();
|
||||
const val = value.slice(colonIndex + 1).trim();
|
||||
|
||||
if (key === "" || val === "") {
|
||||
throw new Error(
|
||||
`Invalid header format: ${value}. Use "HeaderName: Value" format.`,
|
||||
);
|
||||
}
|
||||
|
||||
return { ...previous, [key]: val };
|
||||
}
|
||||
|
||||
function parseArgs(): Args {
|
||||
|
|
@ -260,12 +311,24 @@ function parseArgs(): Args {
|
|||
}
|
||||
return value as "sse" | "http" | "stdio";
|
||||
},
|
||||
)
|
||||
//
|
||||
// HTTP headers
|
||||
//
|
||||
.option(
|
||||
"--header <headers...>",
|
||||
'HTTP headers as "HeaderName: Value" pairs (for HTTP/SSE transports)',
|
||||
parseHeaderPair,
|
||||
{},
|
||||
);
|
||||
|
||||
// Parse only the arguments before --
|
||||
program.parse(preArgs);
|
||||
|
||||
const options = program.opts() as Omit<Args, "target">;
|
||||
const options = program.opts() as Omit<Args, "target"> & {
|
||||
header?: Record<string, string>;
|
||||
};
|
||||
|
||||
let remainingArgs = program.args;
|
||||
|
||||
// Add back any arguments that came after --
|
||||
|
|
@ -280,6 +343,7 @@ function parseArgs(): Args {
|
|||
return {
|
||||
target: finalArgs,
|
||||
...options,
|
||||
headers: options.header, // commander.js uses 'header' field, map to 'headers'
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -291,6 +355,7 @@ async function main(): Promise<void> {
|
|||
try {
|
||||
const args = parseArgs();
|
||||
await callMethod(args);
|
||||
|
||||
// Explicitly exit to ensure process terminates in CI
|
||||
process.exit(0);
|
||||
} catch (error) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue